Migrate to LightDM 0.9 API and rename to lightdm-gtk-builder-greeter.
authorHong Jen Yee (PCMan) <pcman.tw@gmail.com>
Thu, 18 Aug 2011 09:09:58 +0000 (17:09 +0800)
committerHong Jen Yee (PCMan) <pcman.tw@gmail.com>
Thu, 18 Aug 2011 09:09:58 +0000 (17:09 +0800)
* Language selection is currently broken due to limitation of lightdm.

configure.ac
data/Makefile.am
data/lightdm-gtk-builder-greeter.conf [new file with mode: 0644]
data/lightdm-gtk-builder-greeter.desktop.in [new file with mode: 0644]
data/themes/Industrial/greeter.ui
data/themes/Industrial/index.theme.in
src/Makefile.am
src/ldm-gtk-builder-greeter.c [deleted file]
src/lightdm-gtk-builder-greeter.c [new file with mode: 0644]
src/xml-purge.c [deleted file]

index aa70e15..713410d 100644 (file)
@@ -4,7 +4,7 @@
 prog_name = ldm-gtk-builder-greeter
 
 AC_PREREQ([2.63])
-AC_INIT([ldm-gtk-builder-greeter], [0.1.0], [http://lxde.org/])
+AC_INIT([ldm-gtk-builder-greeter], [0.2.0], [http://lxde.org/])
 AM_INIT_AUTOMAKE([-Wall -Werror foreign])
 
 AC_CONFIG_HEADERS([config.h])
@@ -38,7 +38,7 @@ AC_SUBST(GTK_CFLAGS)
 AC_SUBST(GTK_LIBS)
 
 # Check for LightDM Greeter library
-ldm_modules="liblightdm-gobject-0"
+ldm_modules="liblightdm-gobject-1"
 PKG_CHECK_MODULES(LIGHTDM_GOBJECT, [$ldm_modules])
 AC_SUBST(LIGHTDM_GOBJECT_CFLAGS)
 AC_SUBST(LIGHTDM_GOBJECT_LIBS)
index 6d474ec..027cd96 100644 (file)
@@ -3,7 +3,17 @@ NULL=
 SUBDIRS= \
        $(NULL)
 
-themedir=$(LIGHTDM_THEMEDIR)/Industrial
+xgreetersdir = $(datadir)/xgreeters
+xgreeters_in_files = \
+       lightdm-gtk-builder-greeter.desktop
+       $(NULL)
+xgreeters_DATA = $(xgreeters_in_files:.desktop.in=.desktop)
+@INTLTOOL_DESKTOP_RULE@
+
+configdir = $(sysconfdir)/lightdm
+config_DATA = lightdm-gtk-builder-greeter.conf
+
+themedir=$(datadir)/lightdm-gtk-builder-greeter/themes/Industrial
 theme_DATA= \
        themes/Industrial/greeter.ui \
        themes/Industrial/login.png \
@@ -26,5 +36,8 @@ glade_DATA=
 endif
 
 EXTRA_DIST= \
+       $(xgreeters_DATA) \
+       $(config_DATA) \
+       $(theme_DATA) \
        $(glade_DATA) \
        $(NULL)
diff --git a/data/lightdm-gtk-builder-greeter.conf b/data/lightdm-gtk-builder-greeter.conf
new file mode 100644 (file)
index 0000000..b785a03
--- /dev/null
@@ -0,0 +1,3 @@
+[greeter]
+theme=Industrial
+gtk_theme=Clearlooks
diff --git a/data/lightdm-gtk-builder-greeter.desktop.in b/data/lightdm-gtk-builder-greeter.desktop.in
new file mode 100644 (file)
index 0000000..61a0024
--- /dev/null
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=LightDM GTK+ Builder Greeter
+Comment=This runs the GTK+ greeter, it should only be run from LightDM
+Exec=lightdm-gtk-builder-greeter
+Type=Application
index 5d45f03..f37df1f 100644 (file)
@@ -49,7 +49,7 @@
                     <child>
                       <object class="GtkLabel" id="prompt">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes">User:</property>
+                        <property name="label" translatable="yes">login:</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
index 9510158..43d96aa 100644 (file)
@@ -3,7 +3,3 @@ name=Industrial
 description=The Industrial Theme ported from gdm
 author=Jakub Steiner <jimmac@ximian.com>;Hong Jen Yee(PCMan) <pcman.tw@gmail.com>
 license=GPL
-engine=custom
-session=gnome
-command=@prefix@/libexec/ldm-gtk-builder-greeter
-gtk_theme=Clearlooks
index 8bf84fa..6cfeff1 100644 (file)
@@ -2,27 +2,27 @@ NULL=
 
 AM_CPPFLAGS = \
        -I$(srcdir) \
-       -DPACKAGE_DATA_DIR=\""$(datadir)/ldm-gtk-builder-greeter"\" \
-       -DPACKAGE_UI_DIR=\""$(datadir)/ldm-gtk-builder-greeter/ui"\" \
+       -DCONFIG_DIR=\""$(sysconfdir)/lightdm"\" \
+       -DPACKAGE_DATA_DIR=\""$(datadir)/lightdm-gtk-builder-greeter"\" \
        -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
        $(NULL)
 
-libexec_PROGRAMS = ldm-gtk-builder-greeter
-ldm_gtk_builder_greeter_SOURCES = \
-       ldm-gtk-builder-greeter.c \
+sbin_PROGRAMS = lightdm-gtk-builder-greeter
+lightdm_gtk_builder_greeter_SOURCES = \
+       lightdm-gtk-builder-greeter.c \
        ldm-alignment.c ldm-alignment.h \
        ldm-layout.c ldm-layout.h \
        ldm-background.c ldm-background.h \
        $(NULL)
 
-ldm_gtk_builder_greeter_CFLAGS = \
+lightdm_gtk_builder_greeter_CFLAGS = \
        $(GTK_CFLAGS) \
        $(LIGHTDM_GOBJECT_CFLAGS) \
        -Wl,--export-dynamic \
        -Werror-implicit-function-declaration \
        $(NULL)
 
-ldm_gtk_builder_greeter_LDADD = \
+lightdm_gtk_builder_greeter_LDADD = \
        $(GTK_LIBS) \
        $(LIGHTDM_GOBJECT_LIBS) \
        $(INTLLIBS) \
@@ -61,9 +61,3 @@ libldmwidget_la_LDFLAGS = \
        $(NULL)
 
 endif
-
-# Little program to optimize size of xml files
-noinst_PROGRAMS=xml-purge
-xml_purge_SOURCES=$(top_srcdir)/src/xml-purge.c
-xml_purge_CFLAGS=$(GTK_CFLAGS)
-xml_purge_LDADD=$(GTK_LIBS)
diff --git a/src/ldm-gtk-builder-greeter.c b/src/ldm-gtk-builder-greeter.c
deleted file mode 100644 (file)
index e50ee6e..0000000
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- *      ldm-gtk-builder-greeter.c
- *
- *      Copyright 2010 PCMan <pcman.tw@gmail.com>
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- *      MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <lightdm/greeter.h>
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <glib/gstdio.h>
-#include <time.h>
-
-static char* test_dir = NULL;
-static LdmGreeter *greeter = NULL;
-static char* theme_dir = NULL;
-
-static GtkWidget* win;
-static GtkWidget* prompt;
-static GtkWidget* login_entry;
-
-static GtkWidget* user_list;
-
-static GtkWidget* sessions_combo;
-static GtkWidget* lang_combo;
-
-static GtkWidget* exit_btn;
-
-static GtkWidget* exit_menu;
-
-static GOptionEntry option_entries[] =
-{
-    {"test-dir", 't', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_FILENAME, &test_dir, "Test theme dir", "<dir>"},
-    { NULL }
-};
-
-
-static void on_show_prompt(LdmGreeter *greeter, gchar* text, gpointer user_data)
-{
-    gtk_widget_set_sensitive(login_entry, TRUE);
-    gtk_entry_set_visibility(GTK_ENTRY(login_entry), FALSE);
-    gtk_entry_set_text(GTK_ENTRY(login_entry), "");
-    gtk_label_set_text(GTK_LABEL(prompt), text);
-    gtk_widget_grab_focus(login_entry);
-}
-
-static void set_session (const char *session)
-{
-    GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(sessions_combo));
-    GtkTreeIter iter;
-    if (gtk_tree_model_get_iter_first(model, &iter))
-    {
-        do
-        {
-            LdmSession *s;
-            gtk_tree_model_get(model, &iter, 1, &s, -1);
-            if(g_strcmp0(ldm_session_get_key(s), session) == 0)
-            {
-                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(sessions_combo), &iter);
-                break;
-            }
-        }
-        while (gtk_tree_model_iter_next(model, &iter));
-    }
-}
-
-static const char* get_lang()
-{
-    GtkTreeIter it;
-    if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(lang_combo), &it))
-    {
-        LdmLanguage* lang;
-        GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(lang_combo));
-        gtk_tree_model_get(model, &it, 1, &lang, -1);
-        if(lang)
-            g_object_unref(lang);
-        return ldm_language_get_code(lang);
-    }
-    return NULL;
-}
-
-static void set_lang(const char *lang)
-{
-    GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(lang_combo));
-    GtkTreeIter iter;
-    if (gtk_tree_model_get_iter_first(model, &iter))
-    {
-        do
-        {
-            LdmLanguage *language;
-            gtk_tree_model_get(model, &iter, 1, &language, -1);
-            if(g_strcmp0(ldm_language_get_code(language), lang) == 0)
-            {
-                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(lang_combo), &iter);
-                break;
-            }
-        }
-        while (gtk_tree_model_iter_next(model, &iter));
-    } 
-}
-
-static void on_authentication_complete(LdmGreeter *greeter, gpointer user_data)
-{
-    if(ldm_greeter_get_is_authenticated(greeter))
-    {
-        GtkTreeIter it;
-        const char* user = ldm_greeter_get_authentication_user(greeter);
-        const char* session_name = NULL;
-        const char* language = NULL;
-
-        /* get selected session */
-        if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(sessions_combo), &it))
-        {
-            LdmSession* session;
-            GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(sessions_combo));
-            gtk_tree_model_get(model, &it, 1, &session, -1);
-            if(session)
-            {
-                session_name = ldm_session_get_key(session);
-                g_object_unref(session);
-            }
-        }
-
-        if(!session_name)
-            session_name = ldm_greeter_get_default_session(greeter);
-
-        /* do login */
-        ldm_greeter_login(greeter, user, session_name, get_lang());
-    }
-    else /* login failed, ask for username again */
-    {
-        gtk_label_set_text(GTK_LABEL(prompt), _("User:"));
-        gtk_widget_set_sensitive(login_entry, TRUE);
-        gtk_entry_set_text(GTK_ENTRY(login_entry), "");
-        gtk_entry_set_visibility(GTK_ENTRY(login_entry), TRUE);
-        gtk_widget_grab_focus(login_entry);
-        set_session(ldm_greeter_get_default_session(greeter));
-        set_lang(ldm_greeter_get_default_language(greeter));
-    }
-}
-
-static void on_timed_login(LdmGreeter *greeter, const gchar *username, gpointer user_data)
-{
-    ldm_greeter_login (greeter, ldm_greeter_get_timed_login_user(greeter), ldm_greeter_get_default_session(greeter), get_lang());
-}
-
-static void on_quit()
-{
-    gtk_main_quit();
-}
-
-static void on_screen_size_changed(GdkScreen* scr, GtkWindow* win)
-{
-    gtk_window_resize( win, gdk_screen_get_width(scr), gdk_screen_get_height(scr) );
-}
-
-static gboolean on_combobox_entry_button_release(GtkWidget* w, GdkEventButton* evt, GtkComboBox* combo)
-{
-    gboolean shown;
-    g_object_get(combo, "popup-shown", &shown, NULL);
-    if( shown )
-        gtk_combo_box_popdown(combo);
-    else
-        gtk_combo_box_popup(combo);
-    return FALSE;
-}
-
-static void fix_combobox_entry(GtkWidget* combo)
-{
-    GtkWidget* edit = gtk_bin_get_child(GTK_BIN(combo));
-    gtk_editable_set_editable( (GtkEditable*)edit, FALSE );
-    GTK_WIDGET_UNSET_FLAGS(edit, GTK_CAN_FOCUS);
-    g_signal_connect(edit, "button-release-event", G_CALLBACK(on_combobox_entry_button_release), combo);
-}
-
-static gboolean on_timeout(GtkLabel* label)
-{
-    char buf[128];
-    time_t t;
-    struct tm* tmbuf;
-    time(&t);
-    tmbuf = localtime(&t);
-    strftime(buf, 128, "%c", tmbuf);
-    gtk_label_set_text(label, buf);
-    return TRUE;
-}
-
-static void load_sessions()
-{
-    GtkTreeIter it, active_it = {0};
-    const char* default_session = ldm_greeter_get_default_session(greeter);
-    const GList* sessions = ldm_greeter_get_sessions(greeter);
-    const GList* l;
-    GtkListStore* list = gtk_list_store_new(2, G_TYPE_STRING, LDM_TYPE_SESSION);
-
-    for(l = sessions; l; l=l->next)
-    {
-        LdmSession* session = LDM_SESSION(l->data);
-        const char* name = ldm_session_get_name(session);
-        gtk_list_store_insert_with_values(list, &it, -1, 0, name, 1, session, -1);
-        if(g_strcmp0(ldm_session_get_key(session), default_session) == 0)
-            active_it = it;
-    }
-
-    gtk_combo_box_set_model( GTK_COMBO_BOX(sessions_combo), GTK_TREE_MODEL(list) );
-    gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(sessions_combo), 0);
-    if( active_it.stamp )
-        gtk_combo_box_set_active_iter(GTK_COMBO_BOX(sessions_combo), &active_it);
-    else
-        gtk_combo_box_set_active(GTK_COMBO_BOX(sessions_combo), 0);
-
-    g_object_unref(list);
-}
-
-static void load_langs()
-{
-    GtkTreeIter it, active_it = {0};
-    const char* default_lang = ldm_greeter_get_default_language(greeter);
-    const GList* langs = ldm_greeter_get_languages(greeter);
-    const GList* l;
-    GtkListStore* list = gtk_list_store_new(2, G_TYPE_STRING, LDM_TYPE_LANGUAGE);
-    g_debug("def: %s", default_lang);
-    for(l = langs; l; l=l->next)
-    {
-        LdmLanguage* lang = LDM_LANGUAGE(l->data);
-        const char* name = ldm_language_get_name(lang);
-        const char* territory = ldm_language_get_territory(lang);
-        const char* code = ldm_language_get_code(lang);
-        char* title = g_strdup_printf("%s (%s)\t%s", name, territory, code);
-        gtk_list_store_insert_with_values(list, &it, -1, 0, title, 1, lang, -1);
-        g_free(title);
-        if(g_strcmp0(code, default_lang) == 0)
-            active_it = it;
-    }
-
-    gtk_combo_box_set_model( GTK_COMBO_BOX(lang_combo), GTK_TREE_MODEL(list) );
-    gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(lang_combo), 0);
-    if( active_it.stamp )
-        gtk_combo_box_set_active_iter(GTK_COMBO_BOX(lang_combo), &active_it);
-    else
-        gtk_combo_box_set_active(GTK_COMBO_BOX(lang_combo), 0);
-
-    g_object_unref(list);
-}
-
-static void on_exit_btn_clicked(GtkButton* btn, GtkMenu* menu)
-{
-    gtk_menu_popup(menu, NULL, NULL, NULL, btn, 1, gtk_get_current_event_time());
-}
-
-static void load_exit_btn()
-{
-    GtkWidget* menu = gtk_menu_new();
-    GtkWidget* item;
-    if(ldm_greeter_get_can_suspend(greeter))
-    {
-        item = gtk_menu_item_new_with_label(_("Suspend"));
-        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-        g_signal_connect_swapped(item, "activate", G_CALLBACK(ldm_greeter_suspend), greeter);
-    }
-    if(ldm_greeter_get_can_hibernate(greeter))
-    {
-        item = gtk_menu_item_new_with_label(_("Hibernate"));
-        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-        g_signal_connect_swapped(item, "activate", G_CALLBACK(ldm_greeter_hibernate), greeter);
-    }
-    if(ldm_greeter_get_can_restart(greeter))
-    {
-        item = gtk_menu_item_new_with_label(_("Restart"));
-        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-        g_signal_connect_swapped(item, "activate", G_CALLBACK(ldm_greeter_restart), greeter);
-    }
-    g_debug("ldm_greeter_get_can_shutdown(greeter) = %d", ldm_greeter_get_can_shutdown(greeter));
-    if(ldm_greeter_get_can_shutdown(greeter))
-    {
-        item = gtk_menu_item_new_with_label(_("Shutdown"));
-        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-        g_signal_connect_swapped(item, "activate", G_CALLBACK(ldm_greeter_shutdown), greeter);
-    }
-    gtk_widget_show_all(menu);
-    g_signal_connect_swapped(exit_btn, "destroy", G_CALLBACK(gtk_widget_destroy), menu);
-    g_signal_connect(exit_btn, "clicked", G_CALLBACK(on_exit_btn_clicked), menu);
-}
-
-static void on_login_entry_activate(GtkEntry* entry, gpointer user_data)
-{
-    if(ldm_greeter_get_authentication_user(greeter))
-    {
-        const char* passwd = gtk_entry_get_text(entry);
-        if(passwd && *passwd)
-        {
-            ldm_greeter_provide_secret(greeter, passwd);
-            gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE);
-        }
-    }
-    else
-    {
-        const char* user = gtk_entry_get_text(entry);
-        if(user && *user)
-        {
-            gchar *language, *layout, *session;
-            if(ldm_greeter_get_user_defaults(greeter, user, &language, &layout, &session))
-            {
-                set_lang (language);
-                set_session (session);
-                g_free(language);
-                g_free(layout);
-                g_free(session);
-            }
-            ldm_greeter_start_authentication(greeter, user);
-            gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE);
-        }
-    }
-}
-
-static gboolean show_ui()
-{
-    GError* err = NULL;
-    GdkScreen* scr;
-    GtkWidget* w;
-    GdkCursor* cursor;
-
-    /* we don't want to use the theme mechanism provided by lightdm. */
-    GtkBuilder* builder = gtk_builder_new();
-    char* file = g_build_filename(theme_dir, "greeter.ui", NULL);
-
-    if(!gtk_builder_add_from_file(builder, file, &err))
-    {
-        g_debug("%s", err->message);
-        return FALSE;
-    }
-
-    win = GTK_WIDGET (gtk_builder_get_object(builder, "win"));
-    scr = gtk_widget_get_screen(win);
-    g_signal_connect(scr, "size-changed", G_CALLBACK(on_screen_size_changed), win);
-
-    prompt = (GtkWidget*)gtk_builder_get_object(builder, "prompt");
-    login_entry = (GtkWidget*)gtk_builder_get_object(builder, "login_entry");
-    g_signal_connect(login_entry, "activate", G_CALLBACK(on_login_entry_activate), NULL);
-#if 0
-    user_list = (GtkWidget*)gtk_builder_get_object(builder, "user_list");
-
-    if(user_list)
-    {
-        /* the user select a username from the list */
-        if(GTK_IS_VBOX(user_list))
-            load_user_list();
-        else
-            g_error("Bug: user_list should be a GtkVBox object");
-
-    }
-    else if(login_entry)
-    {
-        /* the user type username and password manually */
-        g_signal_connect(login_entry, "activate", G_CALLBACK(on_entry_activate), NULL);
-    }
-#endif
-
-    sessions_combo = (GtkWidget*)gtk_builder_get_object(builder, "sessions");
-    gtk_widget_set_name(sessions_combo, "sessions");
-    fix_combobox_entry(sessions_combo);
-    load_sessions();
-
-    lang_combo = (GtkWidget*)gtk_builder_get_object(builder, "lang");
-    gtk_widget_set_name(lang_combo, "lang_combo");
-    fix_combobox_entry(lang_combo);
-    load_langs();
-
-    if( w = (GtkWidget*)gtk_builder_get_object(builder, "time") )
-    {
-        guint timeout = g_timeout_add(1000, (GSourceFunc)on_timeout, w);
-        g_signal_connect_swapped(w, "destroy",
-            G_CALLBACK(g_source_remove), GUINT_TO_POINTER(timeout));
-        on_timeout((GtkLabel*)w);
-        gtk_widget_set_name(w, "time");
-    }
-
-    exit_btn = (GtkWidget*)gtk_builder_get_object(builder, "exit_btn");
-    load_exit_btn();
-
-    g_object_unref(builder);
-
-    gtk_window_set_decorated(GTK_WINDOW(win), FALSE);
-    gtk_window_set_default_size( GTK_WINDOW(win), gdk_screen_get_width(scr), gdk_screen_get_height(scr) );
-
-    gtk_window_present( GTK_WINDOW(win) );
-
-    cursor = gdk_cursor_new(GDK_LEFT_PTR);
-    gdk_window_set_cursor(gdk_screen_get_root_window(scr), cursor);
-    gdk_cursor_unref(cursor);
-
-    return TRUE;
-}
-
-#include <signal.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-static void sigterm_cb (int signum)
-{
-    exit(0);
-}
-
-static void
-on_connected(LdmGreeter *greeter)
-{
-    if(test_dir)
-    {
-        g_free(theme_dir);
-        theme_dir = test_dir;
-    }
-    else
-    {
-        theme_dir = g_path_get_dirname(ldm_greeter_get_theme(greeter));
-        g_debug("theme_dir = %s", theme_dir);
-    }
-
-    if(theme_dir)
-    {
-        char* gtkrc = g_build_filename(theme_dir, "gtkrc", NULL);
-        gtk_rc_parse(gtkrc);
-        g_debug("gtkrc: %s", gtkrc);
-        g_free(gtkrc);
-    }
-
-    char* gtk_theme = ldm_greeter_get_string_property(greeter, "gtk_theme");
-    if(gtk_theme)
-        g_object_set(gtk_settings_get_default(), "gtk-theme-name", gtk_theme, NULL);
-
-    /* create GUI */
-    if(!show_ui())
-        return 1;
-}
-
-
-int main(int argc, char** argv)
-{
-    GError* err = NULL;
-
-    /* gettext support */
-#ifdef ENABLE_NLS
-    bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
-    bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
-    textdomain ( GETTEXT_PACKAGE );
-#endif
-
-    /* initialize GTK+ and parse the command line arguments */
-    if( G_UNLIKELY( ! gtk_init_with_args( &argc, &argv, "", option_entries, GETTEXT_PACKAGE, &err ) ) )
-    {
-        g_print( "Error: %s\n", err->message );
-        return 1;
-    }
-
-    signal (SIGTERM, sigterm_cb);
-
-    g_type_init();
-    greeter = ldm_greeter_new();
-
-    if(!ldm_greeter_connect_to_server(greeter))
-    {
-        g_print("Error: unable to connect to lightdm deamon.\n");
-        return 1;
-    }
-
-    g_signal_connect(greeter, "connected", G_CALLBACK(on_connected), NULL);  
-    g_signal_connect(greeter, "show-prompt", G_CALLBACK(on_show_prompt), NULL);
-    g_signal_connect(greeter, "authentication-complete", G_CALLBACK(on_authentication_complete), NULL);
-    g_signal_connect(greeter, "timed-login", G_CALLBACK(on_timed_login), NULL);
-    g_signal_connect(greeter, "quit", G_CALLBACK(on_quit), NULL);
-
-    gtk_main();
-
-    return 0;
-}
diff --git a/src/lightdm-gtk-builder-greeter.c b/src/lightdm-gtk-builder-greeter.c
new file mode 100644 (file)
index 0000000..e3416a2
--- /dev/null
@@ -0,0 +1,553 @@
+/*
+ *      ldm-gtk-builder-greeter.c
+ *
+ *      Copyright 2010 - 2011 PCMan <pcman.tw@gmail.com>
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <lightdm.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <time.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+static char* test_dir = NULL;
+static LightDMGreeter *greeter = NULL;
+static char* theme_dir = NULL;
+
+static GtkWidget* win;
+static GtkWidget* prompt;
+static GtkWidget* login_entry;
+
+static GtkWidget* user_list;
+
+static GtkWidget* sessions_combo;
+static GtkWidget* lang_combo;
+
+static GtkWidget* exit_btn;
+
+static GtkWidget* exit_menu;
+
+static GOptionEntry option_entries[] =
+{
+    {"test-dir", 't', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_FILENAME, &test_dir, "Test theme dir", "<dir>"},
+    { NULL }
+};
+
+
+static void on_show_message(LightDMGreeter *greeter, gchar* text,
+                           LightDMMessageType type, gpointer user_data)
+{
+    g_debug("message: %d: %s", type, text);
+}
+
+static void on_show_prompt(LightDMGreeter *greeter, gchar* text,
+                           LightDMPromptType type, gpointer user_data)
+{
+    gtk_label_set_text(GTK_LABEL(prompt), text);
+    gtk_entry_set_text(GTK_ENTRY(login_entry), "");
+    gtk_widget_set_sensitive(login_entry, TRUE);
+    gtk_widget_grab_focus(login_entry);
+
+    gtk_entry_set_visibility(GTK_ENTRY(login_entry),
+                             type != LIGHTDM_PROMPT_TYPE_SECRET);
+}
+
+static void set_session (const char *session)
+{
+    GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(sessions_combo));
+    GtkTreeIter iter;
+    if(session && gtk_tree_model_get_iter_first(model, &iter))
+    {
+        do
+        {
+            char* key;
+            gtk_tree_model_get(model, &iter, 1, &key, -1);
+            if(g_strcmp0(key, session) == 0)
+            {
+                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(sessions_combo), &iter);
+                g_free(key);
+                break;
+            }
+            g_free(key);
+        }
+        while (gtk_tree_model_iter_next(model, &iter));
+    }
+    g_debug("FIXME: set_session failed to find session named: %s", session);
+}
+
+static const char* get_lang()
+{
+    GtkTreeIter it;
+    if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(lang_combo), &it))
+    {
+        LightDMLanguage* lang;
+        GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(lang_combo));
+        gtk_tree_model_get(model, &it, 1, &lang, -1);
+        if(lang)
+            g_object_unref(lang);
+        return lightdm_language_get_code(lang);
+    }
+    return NULL;
+}
+
+static void set_lang(const char *lang)
+{
+    GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(lang_combo));
+    GtkTreeIter iter;
+    if (gtk_tree_model_get_iter_first(model, &iter))
+    {
+        do
+        {
+            LightDMLanguage *language;
+            gtk_tree_model_get(model, &iter, 1, &language, -1);
+            if(g_strcmp0(lightdm_language_get_code(language), lang) == 0)
+            {
+                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(lang_combo), &iter);
+                break;
+            }
+        }
+        while (gtk_tree_model_iter_next(model, &iter));
+    }
+}
+
+static void authenticate_user(const gchar *username)
+{
+    LightDMUser *user;
+    user = lightdm_user_list_get_user_by_name(lightdm_user_list_get_instance(), username);
+    if(user)
+        set_session(lightdm_user_get_session(user));
+    else
+        set_session(NULL);
+    lightdm_greeter_authenticate(greeter, username);
+}
+
+static gchar *get_selected_session()
+{
+    GtkTreeIter it;
+    char* session = NULL;
+    if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(sessions_combo), &it))
+    {
+        GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(sessions_combo));
+        gtk_tree_model_get(model, &it, 1, &session, -1);
+    }
+    return session;
+}
+
+static void start_session(void)
+{
+    gchar *session = get_selected_session();
+    const char* user_name = lightdm_greeter_get_authentication_user(greeter);
+    LightDMUser* user;
+    GError* err = NULL;
+    char* dmrc_path;
+    GKeyFile* dmrc;
+
+#if 0
+    /* LightDM has no API for setting default session/language for users.
+     * However, its settings are loaded from ~/.dmrc.
+     * So let's write our values to ~/.dmrc.
+     * For details about .dmrc, see:
+     * http://library.gnome.org/admin/gdm/stable/configuration.html.en */
+
+    /* If LightDM supports this, we don't have to do the hack here. */
+
+    user = lightdm_user_list_get_user_by_name(lightdm_user_list_get_instance(),
+                                              user_name);
+    dmrc = g_key_file_new();
+    dmrc_path = g_build_filename(lightdm_user_get_home_directory(user), ".dmrc", NULL);
+    g_key_file_load_from_file(dmrc, dmrc_path,
+                              G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS,
+                              NULL);
+    g_key_file_set_string(dmrc, "Desktop", "Language", language);
+    g_key_file_free(dmrc);
+#endif
+
+    if(!lightdm_greeter_start_session_sync(greeter, session, &err))
+    {
+        // set_message_label (_("Failed to start session"));
+        g_error_free(err);
+        authenticate_user(lightdm_greeter_get_authentication_user(greeter));
+    }
+    g_free(session);
+}
+
+static void on_authentication_complete(LightDMGreeter *greeter, gpointer user_data)
+{
+    gtk_entry_set_text(GTK_ENTRY(login_entry), "");
+
+    if(lightdm_greeter_get_is_authenticated(greeter))
+    {
+        start_session();
+    }
+    else /* login failed, ask for username again */
+    {
+        lightdm_greeter_authenticate(greeter, NULL);
+    }
+}
+
+static void on_autologin_timer_expired(LightDMGreeter *greeter, gpointer user_data)
+{
+    if(lightdm_greeter_get_autologin_guest_hint(greeter))
+        lightdm_greeter_authenticate_as_guest(greeter);
+    else if (lightdm_greeter_get_autologin_user_hint(greeter))
+        authenticate_user(lightdm_greeter_get_autologin_user_hint(greeter));
+}
+
+static void on_screen_size_changed(GdkScreen* scr, GtkWindow* win)
+{
+    gtk_window_resize( win, gdk_screen_get_width(scr), gdk_screen_get_height(scr) );
+}
+
+static gboolean on_combobox_entry_button_release(GtkWidget* w, GdkEventButton* evt, GtkComboBox* combo)
+{
+    gboolean shown;
+    g_object_get(combo, "popup-shown", &shown, NULL);
+    if( shown )
+        gtk_combo_box_popdown(combo);
+    else
+        gtk_combo_box_popup(combo);
+    return FALSE;
+}
+
+static void fix_combobox_entry(GtkWidget* combo)
+{
+    GtkWidget* edit = gtk_bin_get_child(GTK_BIN(combo));
+    gtk_editable_set_editable( (GtkEditable*)edit, FALSE );
+    GTK_WIDGET_UNSET_FLAGS(edit, GTK_CAN_FOCUS);
+    g_signal_connect(edit, "button-release-event", G_CALLBACK(on_combobox_entry_button_release), combo);
+}
+
+static gboolean on_timeout(GtkLabel* label)
+{
+    char buf[128];
+    time_t t;
+    struct tm* tmbuf;
+    time(&t);
+    tmbuf = localtime(&t);
+    strftime(buf, 128, "%c", tmbuf);
+    gtk_label_set_text(label, buf);
+    return TRUE;
+}
+
+static void load_sessions()
+{
+    GtkTreeIter it, active_it = {0};
+    const char* default_session = lightdm_greeter_get_default_session_hint(greeter);
+    const GList* sessions = lightdm_get_sessions();
+    const GList* l;
+    GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
+
+    for(l = sessions; l; l=l->next)
+    {
+        LightDMSession* session = LIGHTDM_SESSION(l->data);
+        const char* name = lightdm_session_get_name(session);
+        const char* key = lightdm_session_get_key(session);
+        gtk_list_store_insert_with_values(store, &it, -1,
+                                          0, name,
+                                          1, key, -1);
+        if(g_strcmp0(key, default_session) == 0)
+            active_it = it;
+    }
+
+    gtk_combo_box_set_model(GTK_COMBO_BOX(sessions_combo), GTK_TREE_MODEL(store));
+    gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(sessions_combo), 0);
+    if( active_it.stamp )
+        gtk_combo_box_set_active_iter(GTK_COMBO_BOX(sessions_combo), &active_it);
+    else
+        gtk_combo_box_set_active(GTK_COMBO_BOX(sessions_combo), 0);
+
+    g_object_unref(store);
+}
+
+static void load_langs()
+{
+    GtkTreeIter it, active_it = {0};
+    const LightDMLanguage* default_lang = lightdm_get_language();
+    const GList* langs = lightdm_get_languages();
+    const GList* l;
+    GtkListStore* list = gtk_list_store_new(2, G_TYPE_STRING, LIGHTDM_TYPE_LANGUAGE);
+    g_debug("def: %s", default_lang);
+    for(l = langs; l; l=l->next)
+    {
+        LightDMLanguage* lang = LIGHTDM_LANGUAGE(l->data);
+        const char* name = lightdm_language_get_name(lang);
+        const char* territory = lightdm_language_get_territory(lang);
+        const char* code = lightdm_language_get_code(lang);
+        char* title = g_strdup_printf("%s (%s)\t%s", name, territory, code);
+        gtk_list_store_insert_with_values(list, &it, -1, 0, title, 1, lang, -1);
+        g_free(title);
+        if(default_lang == lang)
+            active_it = it;
+    }
+
+    gtk_combo_box_set_model( GTK_COMBO_BOX(lang_combo), GTK_TREE_MODEL(list) );
+    gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(lang_combo), 0);
+    if( active_it.stamp )
+        gtk_combo_box_set_active_iter(GTK_COMBO_BOX(lang_combo), &active_it);
+    else
+        gtk_combo_box_set_active(GTK_COMBO_BOX(lang_combo), 0);
+
+    g_object_unref(list);
+}
+
+static void on_exit_btn_clicked(GtkButton* btn, GtkMenu* menu)
+{
+    gtk_menu_popup(menu, NULL, NULL, NULL, btn, 1, gtk_get_current_event_time());
+}
+
+static void load_exit_btn()
+{
+    GtkWidget* menu = gtk_menu_new();
+    GtkWidget* item;
+    if(lightdm_get_can_suspend())
+    {
+        item = gtk_menu_item_new_with_label(_("Suspend"));
+        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+        g_signal_connect_swapped(item, "activate", G_CALLBACK(lightdm_suspend), greeter);
+    }
+    if(lightdm_get_can_hibernate())
+    {
+        item = gtk_menu_item_new_with_label(_("Hibernate"));
+        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+        g_signal_connect_swapped(item, "activate", G_CALLBACK(lightdm_hibernate), greeter);
+    }
+    if(lightdm_get_can_restart())
+    {
+        item = gtk_menu_item_new_with_label(_("Restart"));
+        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+        g_signal_connect_swapped(item, "activate", G_CALLBACK(lightdm_restart), greeter);
+    }
+    g_debug("lightdm_get_can_shutdown() = %d", lightdm_get_can_shutdown());
+    if(lightdm_get_can_shutdown())
+    {
+        item = gtk_menu_item_new_with_label(_("Shutdown"));
+        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+        g_signal_connect_swapped(item, "activate", G_CALLBACK(lightdm_shutdown), greeter);
+    }
+    gtk_widget_show_all(menu);
+    g_signal_connect_swapped(exit_btn, "destroy", G_CALLBACK(gtk_widget_destroy), menu);
+    g_signal_connect(exit_btn, "clicked", G_CALLBACK(on_exit_btn_clicked), menu);
+}
+
+static void on_login_entry_activate(GtkEntry* entry, gpointer user_data)
+{
+    gtk_widget_set_sensitive (GTK_WIDGET(entry), FALSE);
+    // set_message_label ("");
+
+    if (lightdm_greeter_get_is_authenticated(greeter))
+        start_session();
+    else if(lightdm_greeter_get_in_authentication (greeter))
+        lightdm_greeter_respond(greeter, gtk_entry_get_text(entry));
+    else
+        authenticate_user(lightdm_greeter_get_authentication_user(greeter));
+}
+
+static gboolean show_ui()
+{
+    GError* err = NULL;
+    GdkScreen* scr;
+    GtkWidget* w;
+    GdkCursor* cursor;
+
+    /* we don't want to use the theme mechanism provided by lightdm. */
+    GtkBuilder* builder = gtk_builder_new();
+    char* file = g_build_filename(theme_dir, "greeter.ui", NULL);
+
+    if(!gtk_builder_add_from_file(builder, file, &err))
+    {
+        g_debug("%s", err->message);
+        return FALSE;
+    }
+
+    win = GTK_WIDGET (gtk_builder_get_object(builder, "win"));
+    scr = gtk_widget_get_screen(win);
+    g_signal_connect(scr, "size-changed", G_CALLBACK(on_screen_size_changed), win);
+
+    prompt = (GtkWidget*)gtk_builder_get_object(builder, "prompt");
+    login_entry = (GtkWidget*)gtk_builder_get_object(builder, "login_entry");
+    g_signal_connect(login_entry, "activate", G_CALLBACK(on_login_entry_activate), NULL);
+#if 0
+    user_list = (GtkWidget*)gtk_builder_get_object(builder, "user_list");
+
+    if(user_list)
+    {
+        /* the user select a username from the list */
+        if(GTK_IS_VBOX(user_list))
+            load_user_list();
+        else
+            g_error("Bug: user_list should be a GtkVBox object");
+
+    }
+    else if(login_entry)
+    {
+        /* the user type username and password manually */
+        g_signal_connect(login_entry, "activate", G_CALLBACK(on_entry_activate), NULL);
+    }
+#endif
+
+    sessions_combo = (GtkWidget*)gtk_builder_get_object(builder, "sessions");
+    gtk_widget_set_name(sessions_combo, "sessions");
+    fix_combobox_entry(sessions_combo);
+    load_sessions();
+
+    lang_combo = (GtkWidget*)gtk_builder_get_object(builder, "lang");
+    gtk_widget_set_name(lang_combo, "lang_combo");
+    fix_combobox_entry(lang_combo);
+    load_langs();
+
+    if( w = (GtkWidget*)gtk_builder_get_object(builder, "time") )
+    {
+        guint timeout = g_timeout_add(1000, (GSourceFunc)on_timeout, w);
+        g_signal_connect_swapped(w, "destroy",
+            G_CALLBACK(g_source_remove), GUINT_TO_POINTER(timeout));
+        on_timeout((GtkLabel*)w);
+        gtk_widget_set_name(w, "time");
+    }
+
+    exit_btn = (GtkWidget*)gtk_builder_get_object(builder, "exit_btn");
+    load_exit_btn();
+
+    g_object_unref(builder);
+
+    gtk_window_set_decorated(GTK_WINDOW(win), FALSE);
+    gtk_window_set_default_size( GTK_WINDOW(win), gdk_screen_get_width(scr), gdk_screen_get_height(scr) );
+
+    gtk_window_present( GTK_WINDOW(win) );
+
+    cursor = gdk_cursor_new(GDK_LEFT_PTR);
+    gdk_window_set_cursor(gdk_screen_get_root_window(scr), cursor);
+    gdk_cursor_unref(cursor);
+
+    return TRUE;
+}
+
+static void on_sigterm(int sig)
+{
+    exit(0);
+}
+
+int main(int argc, char** argv)
+{
+    GError* err = NULL;
+    GKeyFile* kf;
+    char* greeter_theme_name;
+    char* widget_theme_name;
+
+    /* gettext support */
+#ifdef ENABLE_NLS
+    bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
+    bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
+    textdomain ( GETTEXT_PACKAGE );
+#endif
+
+    /* initialize GTK+ and parse the command line arguments */
+    if(G_UNLIKELY(!gtk_init_with_args(&argc, &argv, "", option_entries, GETTEXT_PACKAGE, &err)))
+    {
+        g_print( "Error: %s\n", err->message );
+        return 1;
+    }
+
+    signal(SIGTERM, on_sigterm);
+
+    greeter = lightdm_greeter_new();
+    g_signal_connect(greeter, "show-prompt", G_CALLBACK(on_show_prompt), NULL);
+    g_signal_connect(greeter, "show-message", G_CALLBACK(on_show_message), NULL);
+    g_signal_connect(greeter, "authentication-complete", G_CALLBACK(on_authentication_complete), NULL);
+    g_signal_connect(greeter, "autologin-timer-expired", G_CALLBACK(on_autologin_timer_expired), NULL);
+
+    if(!lightdm_greeter_connect_sync(greeter, NULL))
+    {
+        g_print("Error: unable to connect to lightdm deamon.\n");
+        return 1;
+    }
+
+    /* load global greeter config */
+    kf = g_key_file_new();
+    if(g_key_file_load_from_file(kf, CONFIG_DIR "/lightdm-gtk-builder-greeter.conf",
+                                 0, NULL))
+    {
+        greeter_theme_name = g_key_file_get_string(kf, "greeter", "theme", NULL);
+        widget_theme_name = g_key_file_get_string(kf, "greeter", "gtk_theme", NULL);
+        if(widget_theme_name)
+        {
+            /* FIXME: shouldn't this be set in gtkrc instead? */
+            g_object_set(gtk_settings_get_default(), "gtk-theme-name",
+                         widget_theme_name, NULL);
+            g_free(widget_theme_name);
+        }
+    }
+    else
+        greeter_theme_name = g_strdup("default");
+
+    g_key_file_free(kf);
+
+    /* Set default cursor */
+    gdk_window_set_cursor (gdk_get_default_root_window(), gdk_cursor_new(GDK_LEFT_PTR));
+
+    if(test_dir)
+    {
+        g_free(theme_dir);
+        theme_dir = test_dir;
+    }
+    else
+    {
+        theme_dir = g_build_filename(PACKAGE_DATA_DIR "/themes",
+                                     greeter_theme_name, NULL);
+    }
+g_debug("theme dir: %s", theme_dir);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+    /* NOTE: this piece of code is not yet tested */
+    char* gtkcss = g_build_filename(theme_dir, "gtk.css", NULL);
+    GtkCssProvider *css = gtk_css_provider_new();
+    gtk_css_provider_load_from_path(css, gtkcss, NULL);
+    g_free(gtkcss);
+    gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
+                                            GTK_STYLE_PROVIDER(css),
+                                            GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+    g_object_unref(css);
+#else
+     /* GTK+ 2.x */
+    char* gtkrc = g_build_filename(theme_dir, "gtkrc", NULL);
+    gtk_rc_parse(gtkrc);
+    g_free(gtkrc);
+#endif
+
+    /* create GUI */
+    if(!show_ui())
+        return 1;
+
+    /* FIXME: should we honor this config value and show a user list if it's FALSE?
+     * IMO, whether to show user list or not is theme specific.
+     * For now, we do not support user list. */
+    /* if (lightdm_greeter_get_hide_users_hint (greeter)) */
+    lightdm_greeter_authenticate(greeter, NULL);
+
+    gtk_main();
+
+    g_object_unref(greeter);
+
+    return 0;
+}
diff --git a/src/xml-purge.c b/src/xml-purge.c
deleted file mode 100644 (file)
index 9fc8525..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <glib.h>
-
-#define IS_BLANK(ch)   strchr(" \t\n\r", ch)
-
-static void purge_file( const char* file )
-{
-       char* buf, *pbuf;
-       int in_tag = 0, in_quote = 0;
-       FILE* fo;
-
-    if(!g_file_get_contents(file, &buf, NULL, NULL))
-        exit(1);
-
-       fo = fopen( file, "w" );
-       if( ! fo )
-               goto error;
-
-       for( pbuf = buf; *pbuf; ++pbuf )
-       {
-               if( in_tag > 0 )
-               {
-                       if( in_quote )
-                       {
-                               if( *pbuf == '\"' )
-                                       in_quote = 0;
-                       }
-                       else
-                       {
-                               if( *pbuf == '\"' )
-                                       ++in_quote;
-                               if( ! in_quote && IS_BLANK(*pbuf) )     /* skip unnecessary blanks */
-                               {
-                                       do{
-                                               ++pbuf;
-                                       }while( IS_BLANK( *pbuf ) );
-
-                                       if( *pbuf != '>' )
-                                               fputc( ' ', fo );
-                                       --pbuf;
-                                       continue;
-                               }
-                       }
-                       if( *pbuf == '>' )
-                               --in_tag;
-                       fputc( *pbuf, fo );
-               }
-               else
-               {
-                       if( *pbuf == '<' )
-                       {
-                               if( 0 == strncmp( pbuf, "<!--", 4 ) )   /* skip comments */
-                               {
-                                       pbuf = strstr( pbuf, "-->" );
-                                       if( ! pbuf )
-                                               goto error;
-                                       pbuf += 2;
-                                       continue;
-                               }
-                               ++in_tag;
-                               fputc( '<', fo );
-                       }
-                       else
-                       {
-                               char* tmp = pbuf;
-                               while( *tmp && IS_BLANK( *tmp ) && *tmp != '<' )
-                                       ++tmp;
-                               if( *tmp == '<' )       /* all cdata are blank characters */
-                                       pbuf = tmp - 1;
-                               else /* not blank, keep the cdata */
-                               {
-                                       if( tmp == pbuf )
-                                               fputc( *pbuf, fo );
-                                       else
-                                       {
-                                               fwrite( pbuf, 1, tmp - pbuf, fo );
-                                               pbuf = tmp - 1;
-                                       }
-                               }
-                       }
-               }
-       }
-       
-       fclose( fo );
-
-error:
-       free( buf );
-}
-
-int main( int argc, char** argv )
-{
-       int i;
-       if( argc < 2 )
-               return 1;
-
-       for( i = 1; i < argc; ++i )
-               purge_file( argv[ i] );
-
-       return 0;
-}