Fix the menu refreshing while receiving new scans.
#include <libintl.h>
#include "dhcpcd.h"
+#include "queue.h"
#define PACKAGE "dhcpcd-gtk"
# define _unused
#endif
+typedef struct wi_menu {
+ TAILQ_ENTRY(wi_menu) next;
+ DHCPCD_WI_SCAN *scan;
+ GtkWidget *menu;
+ GtkWidget *ssid;
+ GtkWidget *icon;
+ GtkWidget *bar;
+} WI_MENU;
+typedef TAILQ_HEAD(wi_menu_head, wi_menu) WI_MENUS;
+
typedef struct wi_scan {
+ TAILQ_ENTRY(wi_scan) next;
DHCPCD_IF *interface;
- GtkWidget *menu;
DHCPCD_WI_SCAN *scans;
- struct wi_scan *next;
+
+ GtkWidget *ifmenu;
+ WI_MENUS menus;
} WI_SCAN;
-extern WI_SCAN *wi_scans;
+typedef TAILQ_HEAD(wi_scan_head, wi_scan) WI_SCANS;
+extern WI_SCANS wi_scans;
WI_SCAN * wi_scan_find(DHCPCD_WI_SCAN *);
void notify_close(void);
-void dhcpcd_prefs_show(DHCPCD_CONNECTION *con);
-void dhcpcd_prefs_abort(void);
-void dhcpcd_menu_abort(void);
+void prefs_show(DHCPCD_CONNECTION *con);
+void prefs_abort(void);
+void menu_abort(void);
+void wpa_abort(void);
bool wpa_configure(DHCPCD_WPA *, DHCPCD_WI_SCAN *);
};
static struct watch *watches;
-WI_SCAN *wi_scans;
+WI_SCANS wi_scans;
static gboolean dhcpcd_try_open(gpointer data);
static gboolean dhcpcd_wpa_try_open(gpointer data);
WI_SCAN *w;
DHCPCD_WI_SCAN *dw;
- for (w = wi_scans; w; w = w->next) {
+ TAILQ_FOREACH(w, &wi_scans, next) {
for (dw = w->scans; dw; dw = dw->next)
if (dw == scan)
- break;
- if (dw)
- return w;
+ return w;
}
return NULL;
}
gtk_status_icon_set_from_icon_name(status_icon,
"network-offline");
gtk_status_icon_set_tooltip_text(status_icon, msg);
- dhcpcd_prefs_abort();
- dhcpcd_menu_abort();
- while (wi_scans) {
- w = wi_scans->next;
- dhcpcd_wi_scans_free(wi_scans->scans);
- g_free(wi_scans);
- wi_scans = w;
+ prefs_abort();
+ menu_abort();
+ wpa_abort();
+ while ((w = TAILQ_FIRST(&wi_scans))) {
+ TAILQ_REMOVE(&wi_scans, w, next);
+ dhcpcd_wi_scans_free(w->scans);
+ g_free(w);
}
dhcpcd_unwatch(-1, con);
g_timeout_add(DHCPCD_RETRYOPEN, dhcpcd_try_open, con);
if (scans == NULL && errno)
g_warning("%s: %s", i->ifname, strerror(errno));
errno = lerrno;
- for (w = wi_scans; w; w = w->next)
+ TAILQ_FOREACH(w, &wi_scans, next) {
if (w->interface == i)
break;
+ }
if (w == NULL) {
w = g_malloc(sizeof(*w));
w->interface = i;
- w->menu = NULL;
- w->next = wi_scans;
- wi_scans = w;
+ w->scans = scans;
+ w->ifmenu = NULL;
+ TAILQ_INIT(&w->menus);
+ TAILQ_INSERT_TAIL(&wi_scans, w, next);
} else {
txt = NULL;
msg = N_("New Access Point");
g_free(txt);
}
menu_update_scans(w, scans);
- dhcpcd_wi_scans_free(w->scans);
}
- w->scans = scans;
}
static void
notify_init(PACKAGE);
#endif
+ TAILQ_INIT(&wi_scans);
g_message(_("Connecting ..."));
con = dhcpcd_new();
if (con == NULL) {
static GtkWidget *menu;
static bool ifmenu;
-typedef struct wi_menu {
- DHCPCD_IF *interface;
- DHCPCD_WI_SCAN *scan;
-
- GtkWidget *menu;
- GtkWidget *ssid;
- GtkWidget *icon;
- GtkWidget *bar;
-} WI_MENU;
-static GList *wi_menus;
-
static void
on_pref(_unused GObject *o, gpointer data)
{
- dhcpcd_prefs_show((DHCPCD_CONNECTION *)data);
+ prefs_show((DHCPCD_CONNECTION *)data);
}
static void
on_quit(void)
{
+ wpa_abort();
gtk_main_quit();
}
}
static void
-update_item(WI_MENU *m, DHCPCD_WI_SCAN *scan)
+update_item(WI_SCAN *wi, WI_MENU *m, DHCPCD_WI_SCAN *scan)
{
const char *icon;
double perc;
+ m->scan = scan;
+
+ g_object_set_data(G_OBJECT(m->menu), "dhcpcd_wi_scan", scan);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(m->menu),
+ (wi->interface->up &&
+ g_strcmp0(wi->interface->ssid, scan->ssid)));
+
gtk_label_set_text(GTK_LABEL(m->ssid), scan->ssid);
if (scan->flags[0] == '\0')
icon = "network-wireless";
}
static WI_MENU *
-create_menu(GtkWidget *m, WI_SCAN *scan, DHCPCD_WI_SCAN *wis)
+create_menu(GtkWidget *m, WI_SCAN *wis, DHCPCD_WI_SCAN *scan)
{
WI_MENU *wim;
GtkWidget *box;
char *tip;
wim = g_malloc(sizeof(*wim));
- wim->interface = scan->interface;
- wim->scan = wis;
+ wim->scan = scan;
wim->menu = gtk_check_menu_item_new();
gtk_check_menu_item_set_draw_as_radio(
GTK_CHECK_MENU_ITEM(wim->menu), true);
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
gtk_container_add(GTK_CONTAINER(wim->menu), box);
- wim->ssid = gtk_label_new(wis->ssid);
+ wim->ssid = gtk_label_new(scan->ssid);
gtk_box_pack_start(GTK_BOX(box), wim->ssid, TRUE, TRUE, 0);
- if (g_strcmp0(wis->ssid, scan->interface->ssid) == 0)
+ if (wis->interface->up &&
+ g_strcmp0(scan->ssid, wis->interface->ssid) == 0)
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(wim->menu), true);
- if (wis->flags[0] == '\0')
+ if (scan->flags[0] == '\0')
icon = "network-wireless";
else
icon = "network-wireless-encrypted";
wim->bar = gtk_progress_bar_new();
gtk_widget_set_size_request(wim->bar, 100, -1);
gtk_box_pack_end(GTK_BOX(box), wim->bar, FALSE, TRUE, 0);
- perc = wis->strength.value / 100.0;
+ perc = scan->strength.value / 100.0;
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(wim->bar), perc);
- if (wis->flags[0] == '\0')
- gtk_widget_set_tooltip_text(wim->menu, wis->bssid);
+ if (scan->flags[0] == '\0')
+ gtk_widget_set_tooltip_text(wim->menu, scan->bssid);
else {
- tip = g_strconcat(wis->bssid, " ", wis->flags, NULL);
+ tip = g_strconcat(scan->bssid, " ", scan->flags, NULL);
gtk_widget_set_tooltip_text(wim->menu, tip);
g_free(tip);
}
- g_signal_connect(G_OBJECT(wim->menu), "activate",
+ g_signal_connect(G_OBJECT(wim->menu), "toggled",
G_CALLBACK(ssid_hook), NULL);
- g_object_set_data(G_OBJECT(wim->menu), "dhcpcd_wi_scan", wis);
+ g_object_set_data(G_OBJECT(wim->menu), "dhcpcd_wi_scan", scan);
gtk_menu_shell_append(GTK_MENU_SHELL(m), wim->menu);
return wim;
void
menu_update_scans(WI_SCAN *wi, DHCPCD_WI_SCAN *scans)
{
- GList *item, *next;
- WI_MENU *wim;
+ WI_MENU *wim, *win;
DHCPCD_WI_SCAN *s;
bool found, added;
- item = wi_menus;
- while (item) {
- next = item->next;
- wim = (WI_MENU *)item->data;
- if (wim->interface != wi->interface)
- goto cont;
+ if (menu == NULL) {
+ dhcpcd_wi_scans_free(wi->scans);
+ wi->scans = scans;
+ return;
+ }
+
+ TAILQ_FOREACH_SAFE(wim, &wi->menus, next, win) {
found = false;
for (s = scans; s; s = s->next) {
if (memcmp(wim->scan->bssid, s->bssid,
sizeof(s->bssid)) == 0)
{
found = true;
- update_item(wim, s);
+ update_item(wi, wim, s);
}
}
if (!found) {
+ TAILQ_REMOVE(&wi->menus, wim, next);
g_message("removed %s", wim->scan->ssid);
gtk_widget_destroy(wim->menu);
+ g_free(wim->scan);
g_free(wim);
- wi_menus = g_list_delete_link(wi_menus, item);
}
-cont:
- item = next;
}
added = false;
for (s = scans; s; s = s->next) {
found = false;
- for (item = wi_menus; item; item = item->next) {
- wim = (WI_MENU *)item->data;
+ TAILQ_FOREACH(wim, &wi->menus, next) {
if (memcmp(wim->scan->bssid, s->bssid,
sizeof(s->bssid)) == 0)
{
}
if (!found) {
added = true;
- wim = create_menu(wi->menu, wi, s);
+ wim = create_menu(wi->ifmenu, wi, s);
+ TAILQ_INSERT_TAIL(&wi->menus, wim, next);
gtk_widget_show_all(wim->menu);
g_message("added %s", wim->scan->ssid);
- wi_menus = g_list_append(wi_menus, wim);
}
}
- if (added) {
- gtk_widget_hide(wi->menu);
- gtk_menu_popup(GTK_MENU(wi->menu), NULL, NULL,
- gtk_status_icon_position_menu, sicon,
- 1, gtk_get_current_event_time());
- gtk_widget_show(wi->menu);
+
+ dhcpcd_wi_scans_free(wi->scans);
+ wi->scans = scans;
+
+ if (added && gtk_widget_get_visible(wi->ifmenu)) {
+// gtk_widget_hide(wi->ifmenu);
+// gtk_menu_popup(GTK_MENU(wi->ifmenu), NULL, NULL,
+// gtk_status_icon_position_menu, sicon,
+// 1, gtk_get_current_event_time());
+// gtk_widget_show(wi->ifmenu);
}
}
static GtkWidget *
-add_scans(WI_SCAN *scan)
+add_scans(WI_SCAN *wi)
{
GtkWidget *m;
DHCPCD_WI_SCAN *wis;
WI_MENU *wim;
- if (scan->scans == NULL)
+ if (wi->scans == NULL)
return NULL;
m = gtk_menu_new();
- for (wis = scan->scans; wis; wis = wis->next) {
- wim = create_menu(m, scan, wis);
- wi_menus = g_list_append(wi_menus, wim);
+ for (wis = wi->scans; wis; wis = wis->next) {
+ wim = create_menu(m, wi, wis);
+ TAILQ_INSERT_TAIL(&wi->menus, wim, next);
}
+
return m;
}
void
-dhcpcd_menu_abort(void)
+menu_abort(void)
{
+ WI_SCAN *wis;
+ WI_MENU *wim;
- while (wi_menus) {
- g_free(wi_menus->data);
- wi_menus = g_list_delete_link(wi_menus, wi_menus);
+ TAILQ_FOREACH(wis, &wi_scans, next) {
+ wis->ifmenu = NULL;
+ while ((wim = TAILQ_FIRST(&wis->menus))) {
+ TAILQ_REMOVE(&wis->menus, wim, next);
+ g_free(wim);
+ }
}
if (menu != NULL) {
static void
on_activate(GtkStatusIcon *icon)
{
- WI_SCAN *w;
+ WI_SCAN *w, *l;
GtkWidget *item, *image;
sicon = icon;
notify_close();
- dhcpcd_menu_abort();
- if (wi_scans == NULL)
+ prefs_abort();
+ menu_abort();
+
+ if ((w = TAILQ_FIRST(&wi_scans)) == NULL)
return;
- if (wi_scans->next) {
+
+ if ((l = TAILQ_LAST(&wi_scans, wi_scan_head)) && l != w) {
menu = gtk_menu_new();
ifmenu = true;
- for (w = wi_scans; w; w = w->next) {
+ TAILQ_FOREACH(w, &wi_scans, next) {
item = gtk_image_menu_item_new_with_label(
w->interface->ifname);
image = gtk_image_new_from_icon_name(
gtk_image_menu_item_set_image(
GTK_IMAGE_MENU_ITEM(item), image);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
- w->menu = add_scans(w);
+ w->ifmenu = add_scans(w);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),
- w->menu);
+ w->ifmenu);
}
- } else if (wi_scans->scans) {
+ } else {
ifmenu = false;
- wi_scans->menu = menu = add_scans(wi_scans);
- } else
- menu = NULL;
-
- if (menu) {
- gtk_widget_show_all(GTK_WIDGET(menu));
- gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
- gtk_status_icon_position_menu, icon,
- 1, gtk_get_current_event_time());
+ w->ifmenu = menu = add_scans(w);
}
+
+ gtk_widget_show_all(GTK_WIDGET(menu));
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
+ gtk_status_icon_position_menu, icon,
+ 1, gtk_get_current_event_time());
}
static void
}
static GSList *
-list_ssids(WI_SCAN *scans)
+list_ssids(WI_SCANS *scans)
{
GSList *list, *l;
WI_SCAN *w;
DHCPCD_WI_SCAN *wis;
list = NULL;
- for (w = scans; w; w = w->next) {
+ TAILQ_FOREACH(w, scans, next) {
for (wis = w->scans; wis; wis = wis->next) {
for (l = list; l; l = l->next)
if (g_strcmp0((const char *)l->data,
if (g_strcmp0(block, "interface") == 0)
new_names = list_interfaces(con);
else
- new_names = list_ssids(wi_scans);
+ new_names = list_ssids(&wi_scans);
n = 0;
for (l = new_names; l; l = l->next) {
}
static void
-dhcpcd_prefs_close(void)
+prefs_close(void)
{
if (dialog != NULL) {
gtk_widget_destroy(dialog);
}
void
-dhcpcd_prefs_abort(void)
+prefs_abort(void)
{
g_free(name);
name = NULL;
- dhcpcd_prefs_close();
+ prefs_close();
}
#if GTK_MAJOR_VERSION == 2
#endif
void
-dhcpcd_prefs_show(DHCPCD_CONNECTION *con)
+prefs_show(DHCPCD_CONNECTION *con)
{
GtkWidget *dialog_vbox, *hbox, *vbox, *table, *w;
GtkListStore *store;
w = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
gtk_box_pack_end(GTK_BOX(hbox), w, false, false, 0);
g_signal_connect(G_OBJECT(w), "clicked",
- G_CALLBACK(dhcpcd_prefs_close), NULL);
+ G_CALLBACK(prefs_close), NULL);
blocks_on_change(blocks, con);
show_config(NULL);
--- /dev/null
+/* $NetBSD: queue.h,v 1.65 2013/12/25 17:19:34 christos Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef COMPAT_QUEUE_H
+#define COMPAT_QUEUE_H
+
+#include <sys/queue.h>
+/*
+ * Tail queue definitions.
+ */
+#ifndef TAILQ_END
+#define TAILQ_END(head) (NULL)
+#endif
+
+#ifndef TAILQ_HEAD
+#define _TAILQ_HEAD(name, type, qual) \
+struct name { \
+ qual type *tqh_first; /* first element */ \
+ qual type *qual *tqh_last; /* addr of last next element */ \
+}
+#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { TAILQ_END(head), &(head).tqh_first }
+
+#define _TAILQ_ENTRY(type, qual) \
+struct { \
+ qual type *tqe_next; /* next element */ \
+ qual type *qual *tqe_prev; /* address of previous next element */\
+}
+#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
+#endif /* !TAILQ_HEAD */
+
+/*
+ * Tail queue access methods.
+ */
+#ifndef TAILQ_FIRST
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+#define TAILQ_EMPTY(head) (TAILQ_FIRST(head) == TAILQ_END(head))
+#endif /* !TAILQ_FIRST */
+
+#ifndef TAILQ_FOREACH
+#define TAILQ_FOREACH(var, head, field) \
+ for ((var) = ((head)->tqh_first); \
+ (var) != TAILQ_END(head); \
+ (var) = ((var)->field.tqe_next))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));\
+ (var) != TAILQ_END(head); \
+ (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+#endif /* !TAILQ_FOREACH */
+
+#ifndef TAILQ_INIT
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = TAILQ_END(head); \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != TAILQ_END(head))\
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.tqe_next = TAILQ_END(head); \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != \
+ TAILQ_END(head)) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ if (((elm)->field.tqe_next) != TAILQ_END(head)) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+} while (/*CONSTCOND*/0)
+#endif /* !TAILQ_INIT */
+
+#ifndef TAILQ_REPLACE
+#define TAILQ_REPLACE(head, elm, elm2, field) do { \
+ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != \
+ TAILQ_END(head)) \
+ (elm2)->field.tqe_next->field.tqe_prev = \
+ &(elm2)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm2)->field.tqe_next; \
+ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
+ *(elm2)->field.tqe_prev = (elm2); \
+} while (/*CONSTCOND*/0)
+#endif /* !TAILQ_REPLACE */
+
+#ifndef TAILQ_FOREACH_SAFE
+#define TAILQ_FOREACH_SAFE(var, head, field, next) \
+ for ((var) = TAILQ_FIRST(head); \
+ (var) != TAILQ_END(head) && \
+ ((next) = TAILQ_NEXT(var, field), 1); (var) = (next))
+
+#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var) != TAILQ_END(head) && \
+ ((prev) = TAILQ_PREV((var), headname, field), 1); (var) = (prev))
+#endif /* !TAILQ_FOREACH_SAFE */
+
+#ifndef TAILQ_CONCAT
+#define TAILQ_CONCAT(head1, head2, field) do { \
+ if (!TAILQ_EMPTY(head2)) { \
+ *(head1)->tqh_last = (head2)->tqh_first; \
+ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ TAILQ_INIT((head2)); \
+ } \
+} while (/*CONSTCOND*/0)
+#endif /* !TAILQ_CONCAT */
+
+#endif /* !COMAPT_QUEUE_H */
#include "dhcpcd-gtk.h"
+static GtkWidget *wpa_dialog, *wpa_err;
+
static void
-wpa_dialog(const char *title, const char *txt)
+wpa_show_err(const char *title, const char *txt)
{
- GtkWidget *dialog;
- dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
+ if (wpa_err)
+ gtk_widget_destroy(wpa_err);
+ wpa_err = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", txt);
- gtk_window_set_title(GTK_WINDOW(dialog), title);
- gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_destroy(dialog);
+ gtk_window_set_title(GTK_WINDOW(wpa_err), title);
+ gtk_dialog_run(GTK_DIALOG(wpa_err));
+ gtk_widget_destroy(wpa_err);
}
static void
onEnter(_unused GtkWidget *widget, gpointer *data)
{
+
gtk_dialog_response(GTK_DIALOG(data), GTK_RESPONSE_ACCEPT);
}
+void
+wpa_abort(void)
+{
+
+ if (wpa_err) {
+ gtk_widget_destroy(wpa_err);
+ wpa_err = NULL;
+ }
+ if (wpa_dialog) {
+ gtk_widget_destroy(wpa_dialog);
+ wpa_dialog = NULL;
+ }
+}
+
bool
wpa_configure(DHCPCD_WPA *wpa, DHCPCD_WI_SCAN *scan)
{
DHCPCD_WI_SCAN s;
- GtkWidget *dialog, *label, *psk, *vbox, *hbox;
+ GtkWidget *label, *psk, *vbox, *hbox;
const char *var, *errt;
int result;
bool retval;
memcpy(&s, scan, sizeof(s));
s.next = NULL;
- dialog = gtk_dialog_new_with_buttons(s.ssid,
+ if (wpa_dialog)
+ gtk_widget_destroy(wpa_dialog);
+
+ wpa_dialog = gtk_dialog_new_with_buttons(s.ssid,
NULL,
GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
NULL);
- gtk_window_set_resizable(GTK_WINDOW(dialog), false);
- gtk_window_set_icon_name(GTK_WINDOW(dialog),
+ gtk_window_set_resizable(GTK_WINDOW(wpa_dialog), false);
+ gtk_window_set_icon_name(GTK_WINDOW(wpa_dialog),
"network-wireless-encrypted");
- gtk_dialog_set_default_response(GTK_DIALOG(dialog),
+ gtk_dialog_set_default_response(GTK_DIALOG(wpa_dialog),
GTK_RESPONSE_ACCEPT);
- vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ vbox = gtk_dialog_get_content_area(GTK_DIALOG(wpa_dialog));
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
label = gtk_label_new(_("Pre Shared Key:"));
psk = gtk_entry_new();
gtk_entry_set_max_length(GTK_ENTRY(psk), 130);
g_signal_connect(G_OBJECT(psk), "activate",
- G_CALLBACK(onEnter), dialog);
+ G_CALLBACK(onEnter), wpa_dialog);
gtk_box_pack_start(GTK_BOX(hbox), psk, true, true, 0);
gtk_container_add(GTK_CONTAINER(vbox), hbox);
- gtk_widget_show_all(dialog);
+ gtk_widget_show_all(wpa_dialog);
again:
- result = gtk_dialog_run(GTK_DIALOG(dialog));
+ result = gtk_dialog_run(GTK_DIALOG(wpa_dialog));
retval = false;
if (result == GTK_RESPONSE_ACCEPT) {
break;
}
if (!retval) {
- wpa_dialog(_("Error enabling network"), errt);
+ wpa_show_err(_("Error enabling network"), errt);
goto again;
}
}
- gtk_widget_destroy(dialog);
+ if (wpa_dialog) {
+ gtk_widget_destroy(wpa_dialog);
+ wpa_dialog = NULL;
+ }
return retval;
}