summaryrefslogtreecommitdiff
path: root/gui/gdmchooser.c
diff options
context:
space:
mode:
Diffstat (limited to 'gui/gdmchooser.c')
-rw-r--r--gui/gdmchooser.c236
1 files changed, 176 insertions, 60 deletions
diff --git a/gui/gdmchooser.c b/gui/gdmchooser.c
index 87c8a192..b1c202be 100644
--- a/gui/gdmchooser.c
+++ b/gui/gdmchooser.c
@@ -54,12 +54,6 @@
#include "misc.h"
#include "gdmwm.h"
-/* set the DOING_GDM_DEVELOPMENT env variable if you want to
- * search for the glade file in the current dir and not the system
- * install dir, better then something you have to change
- * in the source and recompile */
-static gboolean DOING_GDM_DEVELOPMENT = FALSE;
-
static gboolean RUNNING_UNDER_GDM = FALSE;
typedef struct _GdmChooserHost GdmChooserHost;
@@ -69,6 +63,7 @@ struct _GdmChooserHost {
struct in_addr ia;
GdkPixbuf *picture;
gboolean willing;
+ int pos;
};
@@ -81,11 +76,15 @@ static gchar *xdm_address = NULL;
static gchar *client_address = NULL;
static gint connection_type = 0;
+/* if this is received, select that host automatically */
+struct in_addr *select_addr = NULL;
+
static void gdm_chooser_abort (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
static void gdm_chooser_warn (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
/* Exported for glade */
-gboolean gdm_chooser_cancel (void);
+void gdm_chooser_cancel (void);
+void gdm_chooser_add_host (void);
void gdm_chooser_manage (GtkButton *button, gpointer data);
void gdm_chooser_browser_select (GtkWidget *widget,
gint selected,
@@ -134,6 +133,7 @@ static gchar *GdmHostDefaultIcon;
static gchar *GdmGtkRC;
static gchar *GdmHosts;
static gboolean GdmBroadcast;
+static gboolean GdmAllowAdd;
static gchar *GdmBackgroundColor;
static int GdmBackgroundType;
enum {
@@ -143,7 +143,7 @@ enum {
};
static GladeXML *chooser_app;
-static GtkWidget *chooser, *manage, *rescan, *cancel;
+static GtkWidget *chooser, *manage, *rescan, *cancel, *add_entry;
static GtkWidget *status_label;
static GIOChannel *channel;
@@ -201,6 +201,7 @@ gdm_chooser_host_alloc (const char *hostname,
GList *hostl;
host = g_new0 (GdmChooserHost, 1);
+ host->pos = -1;
host->name = g_strdup (hostname);
host->desc = g_strdup (description);
memcpy (&host->ia, ia, sizeof (struct in_addr));
@@ -263,46 +264,34 @@ gdm_chooser_host_alloc (const char *hostname,
}
static void
-gdm_chooser_browser_update (void)
+gdm_chooser_browser_add_host (GdmChooserHost *host)
{
- GList *li;
- gboolean any;
-
- gnome_icon_list_freeze (GNOME_ICON_LIST (browser));
- gnome_icon_list_clear (GNOME_ICON_LIST (browser));
-
- any = FALSE;
- for (li = hosts; li != NULL; li = li->next) {
- GdmChooserHost *host = (GdmChooserHost *) li->data;
-
- if (host->willing) {
- /* FIXME: the \n doesn't actually propagate
- * since the icon list is a broken piece of horsedung */
- char *temp = g_strconcat (host->name, " \n",
- host->desc, NULL);
+ if (host->willing) {
+ /* FIXME: the \n doesn't actually propagate
+ * since the icon list is a broken piece of horsedung */
+ char *temp = g_strconcat (host->name, " \n",
+ host->desc, NULL);
+ host->pos =
gnome_icon_list_append_pixbuf (GNOME_ICON_LIST (browser),
host->picture,
NULL /* icon_filename */,
temp);
- g_free (temp);
- any = TRUE;
+ g_free (temp);
+
+ if (select_addr != NULL &&
+ memcmp (&host->ia, select_addr,
+ sizeof (struct in_addr)) == 0) {
+ gnome_icon_list_select_icon (GNOME_ICON_LIST (browser),
+ host->pos);
+ gtk_widget_grab_focus (manage);
}
+ select_addr = NULL;
}
- gnome_icon_list_thaw (GNOME_ICON_LIST (browser));
-
- if (any) {
- gtk_label_set_text (GTK_LABEL (status_label), _(active_network));
- } else {
- gtk_label_set_text (GTK_LABEL (status_label), _(empty_network));
- }
- gtk_widget_set_sensitive (GTK_WIDGET (manage), FALSE);
- gtk_widget_set_sensitive (GTK_WIDGET (rescan), TRUE);
gtk_widget_set_sensitive (GTK_WIDGET (browser), TRUE);
}
-
-static gboolean
+static GdmChooserHost *
gdm_host_known (struct in_addr *ia)
{
GList *li;
@@ -310,10 +299,10 @@ gdm_host_known (struct in_addr *ia)
for (li = hosts; li != NULL; li = li->next) {
GdmChooserHost *host = li->data;
if (memcmp (&host->ia, ia, sizeof (struct in_addr)) == 0) {
- return TRUE;
+ return host;
}
}
- return FALSE;
+ return NULL;
}
static gboolean
@@ -342,6 +331,7 @@ gdm_chooser_decode_packet (GIOChannel *source,
gchar *hostname = NULL;
gchar *status = NULL;
ARRAY8 auth, host, stat;
+ GdmChooserHost *gh;
if (! XdmcpFill (sockfd, &buf, (XdmcpNetaddr) &clnt_sa, &sa_len))
return TRUE;
@@ -390,14 +380,28 @@ gdm_chooser_decode_packet (GIOChannel *source,
}
}
- gdm_chooser_host_alloc (hostname,
- status,
- &clnt_sa.sin_addr,
- header.opcode == WILLING);
+ gh = gdm_host_known (&clnt_sa.sin_addr);
+ if (gh == NULL) {
+ gh = gdm_chooser_host_alloc (hostname,
+ status,
+ &clnt_sa.sin_addr,
+ header.opcode == WILLING);
- g_free (hostname);
- gdm_chooser_browser_update ();
+ gdm_chooser_browser_add_host (gh);
+ } else {
+ /* server changed it's mind */
+ if (header.opcode == WILLING &&
+ ! gh->willing) {
+ gh->willing = TRUE;
+ gdm_chooser_browser_add_host (gh);
+ }
+ /* hmmm what about the other change, just ignore
+ for now, it's kind of confusing to just remove
+ servers really */
+ }
+
+ g_free (hostname);
done:
if (header.opcode == WILLING) {
@@ -476,8 +480,19 @@ gdm_chooser_find_bcaddr (void)
static gboolean
chooser_scan_time_update (gpointer data)
{
+ GList *li;
scan_time_handler = 0;
- gdm_chooser_browser_update ();
+ for (li = hosts; li != NULL; li = li->next) {
+ GdmChooserHost *host = (GdmChooserHost *) li->data;
+ if (host->willing)
+ break;
+ }
+ if (li != NULL /* something was found */) {
+ gtk_label_set_text (GTK_LABEL (status_label), _(active_network));
+ } else {
+ gtk_label_set_text (GTK_LABEL (status_label), _(empty_network));
+ }
+ gtk_widget_set_sensitive (GTK_WIDGET (rescan), TRUE);
return FALSE;
}
@@ -528,6 +543,7 @@ gdm_chooser_xdmcp_discover (void)
GList *hl = hosts;
gtk_widget_set_sensitive (GTK_WIDGET (manage), FALSE);
+ gtk_widget_set_sensitive (GTK_WIDGET (rescan), FALSE);
gnome_icon_list_clear (GNOME_ICON_LIST (browser));
gtk_widget_set_sensitive (GTK_WIDGET (browser), FALSE);
gtk_label_set_text (GTK_LABEL (status_label),
@@ -716,8 +732,91 @@ gdm_chooser_choose_host (const char *hostname)
}
}
+void
+gdm_chooser_add_host (void)
+{
+ struct hostent *hostent;
+ struct sockaddr_in qa;
+ struct in_addr *ia;
+ GdmChooserHost *host;
+ struct sockaddr_in sock;
+ const char *name;
+
+ name = gtk_entry_get_text (GTK_ENTRY (add_entry));
+ if (ve_string_empty (name))
+ return;
+
+ if (strlen (name) == 8 &&
+ from_hex (name, (char *) &qa.sin_addr, strlen (name)) == 0)
+ qa.sin_family = AF_INET;
+ else if ((qa.sin_addr.s_addr = inet_addr (name)) != -1)
+ qa.sin_family = AF_INET;
+ else if ((hostent = gethostbyname (name)) != NULL
+ && hostent->h_addrtype == AF_INET
+ && hostent->h_length == 4) {
+ qa.sin_family = AF_INET;
+ memmove (&qa.sin_addr, hostent->h_addr, 4);
+ } else {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new
+ (GTK_WINDOW (chooser) /* parent */,
+ GTK_DIALOG_MODAL /* flags */,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ _("I cannot find the host \"%s\", "
+ "perhaps you have mistyped it."),
+ name);
+
+ if (RUNNING_UNDER_GDM)
+ gdm_wm_center_window (GTK_WINDOW (dialog));
+
+ gdm_wm_no_login_focus_push ();
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ gdm_wm_no_login_focus_pop ();
+ return; /* not a valid address */
+ }
+
+ sock.sin_family = AF_INET;
+ sock.sin_port = htons (XDM_UDP_PORT);
+
+ ia = g_new0 (struct in_addr, 1);
+ ia->s_addr = qa.sin_addr.s_addr;
+
+ host = gdm_host_known (ia);
+ if (host != NULL) {
+ if (host->pos >= 0) {
+ gnome_icon_list_select_icon (GNOME_ICON_LIST (browser),
+ host->pos);
+ gtk_widget_grab_focus (manage);
+ } else {
+ /* hmm, probably not willing, ping the host then for
+ good measure */
+ sock.sin_addr.s_addr = ia->s_addr;
+ XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock,
+ (int)sizeof (struct sockaddr_in));
+ }
+
+ /* empty the text entry to indicate success */
+ gtk_entry_set_text (GTK_ENTRY (add_entry), "");
+
+ g_free (ia);
+ return;
+ }
+
+ queryaddr = g_slist_append (queryaddr, ia);
+ select_addr = ia;
+
+ /* and send out the query */
+ sock.sin_addr.s_addr = ia->s_addr;
+ XdmcpFlush (sockfd, &querybuf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in));
-gboolean
+ /* empty the text entry to indicate success */
+ gtk_entry_set_text (GTK_ENTRY (add_entry), "");
+}
+
+void
gdm_chooser_cancel (void)
{
if (scan_time_handler > 0) {
@@ -729,8 +828,6 @@ gdm_chooser_cancel (void)
/* exit rather gtk_main_quit, it's just safer this way we don't
have to worry about random whackiness happening */
exit (EXIT_SUCCESS);
-
- return TRUE;
}
@@ -807,6 +904,8 @@ gdm_chooser_parse_config (void)
GdmBackgroundColor = gnome_config_get_string (GDM_KEY_BACKGROUNDCOLOR);
GdmBackgroundType = gnome_config_get_int (GDM_KEY_BACKGROUNDTYPE);
+ GdmAllowAdd = gnome_config_get_bool (GDM_KEY_ALLOWADD);
+
/* note that command line arguments will prevail over these */
GdmHosts = gnome_config_get_string (GDM_KEY_HOSTS);
GdmBroadcast = gnome_config_get_bool (GDM_KEY_BROADCAST);
@@ -886,7 +985,8 @@ display_chooser_information (void)
"\"Refresh\". When you have selected a host click "
"\"Connect\" to open a session to that machine."));
- gdm_wm_center_window (GTK_WINDOW (dialog));
+ if (RUNNING_UNDER_GDM)
+ gdm_wm_center_window (GTK_WINDOW (dialog));
gdm_wm_no_login_focus_push ();
gtk_dialog_run (GTK_DIALOG (dialog));
@@ -934,6 +1034,8 @@ gdm_chooser_gui_init (void)
GTK_TYPE_BUTTON);
status_label = glade_helper_get (chooser_app, "status_label",
GTK_TYPE_LABEL);
+ add_entry = glade_helper_get (chooser_app, "add_entry",
+ GTK_TYPE_ENTRY);
browser = glade_helper_get (chooser_app, "chooser_iconlist",
GNOME_TYPE_ICON_LIST);
@@ -947,6 +1049,12 @@ gdm_chooser_gui_init (void)
(gint) gdk_screen_width() * 0.4,
(gint) gdk_screen_height() * 0.6);
+ if ( ! GdmAllowAdd) {
+ GtkWidget *w = glade_helper_get (chooser_app, "add_hbox",
+ GTK_TYPE_HBOX);
+ gtk_widget_hide (w);
+ }
+
gdm_wm_center_window (GTK_WINDOW (chooser));
}
@@ -1059,8 +1167,6 @@ main (int argc, char *argv[])
int nextopt;
const char *gdm_version;
- if (g_getenv ("DOING_GDM_DEVELOPMENT") != NULL)
- DOING_GDM_DEVELOPMENT = TRUE;
if (g_getenv ("RUNNING_UNDER_GDM") != NULL)
RUNNING_UNDER_GDM = TRUE;
@@ -1086,17 +1192,20 @@ main (int argc, char *argv[])
}
/* Should be a watch already, but just in case */
- setup_cursor (GDK_WATCH);
+ if (RUNNING_UNDER_GDM)
+ setup_cursor (GDK_WATCH);
glade_init();
gdm_chooser_parse_config();
- gdm_wm_screen_init (GdmXineramaScreen);
+ if (RUNNING_UNDER_GDM)
+ gdm_wm_screen_init (GdmXineramaScreen);
gdm_version = g_getenv ("GDM_VERSION");
- if (gdm_version != NULL &&
+ if (RUNNING_UNDER_GDM &&
+ gdm_version != NULL &&
strcmp (gdm_version, VERSION) != 0) {
GtkWidget *dialog;
@@ -1127,7 +1236,8 @@ main (int argc, char *argv[])
gdm_chooser_gui_init();
gdm_chooser_signals_init();
- set_background ();
+ if (RUNNING_UNDER_GDM)
+ set_background ();
hosts = (char **)poptGetArgs (ctx);
/* when no hosts on the command line, take them from the config */
@@ -1155,10 +1265,12 @@ main (int argc, char *argv[])
gtk_widget_queue_resize (chooser);
gtk_widget_show_now (chooser);
- gdm_wm_center_window (GTK_WINDOW (chooser));
+ if (RUNNING_UNDER_GDM)
+ gdm_wm_center_window (GTK_WINDOW (chooser));
- /* can it ever happen that it'd be NULL here ??? */
- if (chooser->window != NULL) {
+ if (RUNNING_UNDER_GDM &&
+ /* can it ever happen that it'd be NULL here ??? */
+ chooser->window != NULL) {
gdm_wm_init (GDK_WINDOW_XWINDOW (chooser->window));
/* Run the focus, note that this will work no matter what
@@ -1167,7 +1279,11 @@ main (int argc, char *argv[])
gdm_wm_focus_window (GDK_WINDOW_XWINDOW (chooser->window));
}
- setup_cursor (GDK_LEFT_PTR);
+ if (RUNNING_UNDER_GDM)
+ setup_cursor (GDK_LEFT_PTR);
+
+ if (GdmAllowAdd)
+ gtk_widget_grab_focus (add_entry);
gtk_main();