1 /* Copyright (c) 2003,2004 Benedikt Meurer <benny@xfce.org>
2  * Copyright (c) 2010 Florian Rivoal <frivoal@xfce.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 
30 #include <gdk/gdk.h>
31 #include <gtk/gtk.h>
32 
33 #include <libxfce4util/libxfce4util.h>
34 #include <libxfce4ui/libxfce4ui.h>
35 #include <libxfce4panel/libxfce4panel.h>
36 
37 #include "wi.h"
38 
39 #include <string.h>
40 #include <ctype.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <ifaddrs.h>
44 
45 #define BORDER 8
46 typedef struct
47 {
48   gchar *interface;
49   struct wi_device *device;
50   guint timer_id;
51 
52   guint state;
53 
54   gboolean autohide;
55   gboolean autohide_missing;
56   gboolean signal_colors;
57   gboolean show_icon;
58 
59   int size;
60   GtkOrientation orientation;
61 
62   GtkWidget *box;
63   GtkWidget *ebox;
64   GtkWidget *image;
65   GtkWidget *signal;
66   GtkWidget *tooltip_text;
67 #if GTK_CHECK_VERSION (3, 16, 0)
68   GtkCssProvider *css_provider;
69 #endif
70 
71   XfcePanelPlugin *plugin;
72 
73 } t_wavelan;
74 
75 static void wavelan_set_size(XfcePanelPlugin* plugin, int size, t_wavelan *wavelan);
76 static void wavelan_set_orientation(XfcePanelPlugin* plugin, GtkOrientation orientation, t_wavelan *wavelan);
77 
78 static void
wavelan_set_state(t_wavelan * wavelan,gint state)79 wavelan_set_state(t_wavelan *wavelan, gint state)
80 {
81   GdkRGBA color;
82   gchar signal_color_bad[] = "#e00000";
83   gchar signal_color_weak[] = "#e05200";
84   gchar signal_color_good[] = "#e6ff00";
85   gchar signal_color_strong[] = "#06c500";
86 #if GTK_CHECK_VERSION (3, 16, 0)
87   gchar *css, *color_str;
88 #if GTK_CHECK_VERSION (3, 20, 0)
89   gchar * cssminsizes = "min-width: 4px; min-height: 0px";
90   if(gtk_orientable_get_orientation(GTK_ORIENTABLE(wavelan->signal)) == GTK_ORIENTATION_HORIZONTAL)
91     cssminsizes = "min-width: 0px; min-height: 4px";
92 #endif
93 #endif
94 
95   /* state = 0 -> no link, =-1 -> error */
96   DBG ("Entered wavelan_set_state, state = %d", state);
97 
98   if(state > 100)
99     state = 100;
100 
101   wavelan->state = state;
102 
103   if (state >= 1)
104    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(wavelan->signal), (gdouble) state / 100);
105   else
106    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(wavelan->signal), 0.0);
107 
108   if (wavelan->signal_colors) {
109      /* set color */
110    if (state > 75)
111     gdk_rgba_parse(&color, signal_color_strong);
112    else if (state > 50)
113     gdk_rgba_parse(&color, signal_color_good);
114    else if (state > 25)
115     gdk_rgba_parse(&color, signal_color_weak);
116    else
117     gdk_rgba_parse(&color, signal_color_bad);
118 
119 #if GTK_CHECK_VERSION (3, 16, 0)
120      color_str = gdk_rgba_to_string(&color);
121 #if GTK_CHECK_VERSION (3, 20, 0)
122      css = g_strdup_printf("progressbar trough { %s } \
123                             progressbar progress { %s ; background-color: %s; background-image: none; }",
124                            cssminsizes, cssminsizes,
125 #else
126      css = g_strdup_printf(".progressbar { background-color: %s; background-image: none; }",
127 #endif
128                            color_str);
129      g_free(color_str);
130 #else
131      gtk_widget_override_background_color(GTK_WIDGET(wavelan->signal),
132                              GTK_STATE_PRELIGHT,
133                              &color);
134      gtk_widget_override_background_color(GTK_WIDGET(wavelan->signal),
135                              GTK_STATE_SELECTED,
136                              &color);
137      gtk_widget_override_color(GTK_WIDGET(wavelan->signal),
138                              GTK_STATE_SELECTED,
139                              &color);
140 #endif
141   } else {
142 #if GTK_CHECK_VERSION (3, 20, 0)
143      /* only set size... */
144      css = g_strdup_printf("progressbar trough { %s } \
145                             progressbar progress { %s }",
146                            cssminsizes, cssminsizes);
147 #endif
148   }
149 
150 #if GTK_CHECK_VERSION (3, 16, 0)
151   gtk_css_provider_load_from_data (wavelan->css_provider, css, strlen(css), NULL);
152   g_free(css);
153 #endif
154 
155   /* hide icon */
156   if (wavelan->show_icon)
157     gtk_widget_show(wavelan->image);
158   else
159     gtk_widget_hide(wavelan->image);
160 
161   /* hide if no network & autohide or if no card found */
162   if (wavelan->autohide && state == 0)
163     gtk_widget_hide(wavelan->ebox);
164   else if (wavelan->autohide_missing && state == -1)
165     gtk_widget_hide(wavelan->ebox);
166   else
167     gtk_widget_show(wavelan->ebox);
168 }
169 
170 static gboolean
wavelan_timer(gpointer data)171 wavelan_timer(gpointer data)
172 {
173   struct wi_stats stats;
174   char *tip = NULL;
175   t_wavelan *wavelan = (t_wavelan *)data;
176 
177   TRACE ("Entered wavelan_timer");
178 
179   if (wavelan->device != NULL) {
180     int result;
181 
182     if ((result = wi_query(wavelan->device, &stats)) != WI_OK) {
183       TRACE ("result = %d", result);
184       /* reset quality indicator */
185       if (result == WI_NOCARRIER) {
186         tip = g_strdup(_("No carrier signal"));
187         wavelan_set_state(wavelan, 0);
188       }
189       else {
190         /* set error */
191         tip = g_strdup(_(wi_strerror(result)));
192         wavelan_set_state(wavelan, -1);
193       }
194     }
195     else {
196       /*
197        * Usual formula is: qual = 4 * (signal - noise)
198        * where noise is typically about -96dBm, but we don't have
199        * the actual noise value here, so approximate one.
200        */
201       if (strcmp(stats.ws_qunit, "dBm") == 0)
202         wavelan_set_state(wavelan, 4 * (stats.ws_quality - (-96)));
203       else
204         wavelan_set_state(wavelan, stats.ws_quality);
205 
206       if (strlen(stats.ws_netname) > 0)
207         /* Translators: net_name: quality quality_unit at rate Mb/s*/
208         tip = g_strdup_printf(_("%s: %d%s at %dMb/s"), stats.ws_netname, stats.ws_quality, stats.ws_qunit, stats.ws_rate);
209       else
210         /* Translators: quality quality_unit at rate Mb/s*/
211         tip = g_strdup_printf(_("%d%s at %dMb/s"), stats.ws_quality, stats.ws_qunit, stats.ws_rate);
212     }
213   }
214   else {
215     tip = g_strdup(_("No device configured"));
216     wavelan_set_state(wavelan, -1);
217   }
218 
219   /* set new tooltip */
220   if (tip != NULL) {
221     gtk_label_set_text(GTK_LABEL(wavelan->tooltip_text), tip);
222     g_free(tip);
223   }
224 
225   /* keep the timeout running */
226   return(TRUE);
227 }
228 
229 static void
wavelan_reset(t_wavelan * wavelan)230 wavelan_reset(t_wavelan *wavelan)
231 {
232   TRACE ("Entered wavelan_reset");
233 
234   if (wavelan->timer_id != 0) {
235     g_source_remove(wavelan->timer_id);
236     wavelan->timer_id = 0;
237   }
238 
239   if (wavelan->device != NULL) {
240     wi_close(wavelan->device);
241     wavelan->device = NULL;
242   }
243   TRACE ("Using interface %s", wavelan->interface);
244   if (wavelan->interface != NULL) {
245     /* open the WaveLAN device */
246     if ((wavelan->device = wi_open(wavelan->interface)) != NULL) {
247       /* register the update timer */
248       TRACE ("Opened device");
249       wavelan->timer_id = g_timeout_add_seconds(1, wavelan_timer, wavelan);
250     }
251   }
252 }
253 
254 /* query installed devices */
255 static GList*
wavelan_query_interfaces(void)256 wavelan_query_interfaces (void)
257 {
258   GList *interfaces = NULL;
259   struct ifaddrs *ifaddr, *ifa;
260 
261   TRACE ("Entered wavelan_query_interface");
262 
263   if (getifaddrs(&ifaddr) == -1) {
264     return NULL;
265   }
266   for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
267     if (ifa->ifa_addr == NULL)
268       continue;
269 #if defined(AF_LINK) /* BSD */
270     if (ifa->ifa_addr->sa_family == AF_LINK)
271 #elif defined(AF_PACKET) /* linux */
272     if (ifa->ifa_addr->sa_family == AF_PACKET)
273 #else
274 #error "couldnt find a way to get address family on your system"
275 #endif
276       interfaces = g_list_append (interfaces, g_strdup (ifa->ifa_name));
277   }
278   freeifaddrs(ifaddr);
279   return interfaces;
280 }
281 
282 static void
wavelan_read_config(XfcePanelPlugin * plugin,t_wavelan * wavelan)283 wavelan_read_config(XfcePanelPlugin *plugin, t_wavelan *wavelan)
284 {
285   char *file;
286   XfceRc *rc;
287   const char *s;
288 
289   TRACE ("Entered wavelan_read_config");
290 
291   if ((file = xfce_panel_plugin_lookup_rc_file (plugin)) != NULL)
292   {
293     rc = xfce_rc_simple_open (file, TRUE);
294     g_free (file);
295 
296     if (rc != NULL)
297     {
298       if ((s = xfce_rc_read_entry (rc, "Interface", NULL)) != NULL)
299       {
300         wavelan->interface = g_strdup (s);
301       }
302 
303       wavelan->autohide = xfce_rc_read_bool_entry (rc, "Autohide", FALSE);
304       wavelan->autohide_missing = xfce_rc_read_bool_entry(rc, "AutohideMissing", FALSE);
305       wavelan->signal_colors = xfce_rc_read_bool_entry(rc, "SignalColors", FALSE);
306       wavelan->show_icon = xfce_rc_read_bool_entry(rc, "ShowIcon", FALSE);
307     }
308   }
309 
310   if (wavelan->interface == NULL) {
311     GList *interfaces = wavelan_query_interfaces();
312     wavelan->interface = g_list_first(interfaces)->data;
313     g_list_free(interfaces);
314   }
315 
316   wavelan_reset(wavelan);
317 }
318 
tooltip_cb(GtkWidget * widget,gint x,gint y,gboolean keyboard,GtkTooltip * tooltip,t_wavelan * wavelan)319 static gboolean tooltip_cb( GtkWidget *widget, gint x, gint y, gboolean keyboard, GtkTooltip * tooltip, t_wavelan *wavelan)
320 {
321 	gtk_tooltip_set_custom( tooltip, wavelan->tooltip_text );
322 	return TRUE;
323 }
324 
325 static t_wavelan *
wavelan_new(XfcePanelPlugin * plugin)326 wavelan_new(XfcePanelPlugin *plugin)
327 {
328   t_wavelan *wavelan;
329 
330   TRACE ("Entered wavelan_new");
331 
332 	wavelan = g_new0(t_wavelan, 1);
333 
334   wavelan->autohide = FALSE;
335   wavelan->autohide_missing = FALSE;
336 
337   wavelan->signal_colors = TRUE;
338   wavelan->show_icon = TRUE;
339   wavelan->state = -2;
340 
341   wavelan->plugin = plugin;
342 
343   wavelan->ebox = gtk_event_box_new();
344   gtk_widget_set_has_tooltip(wavelan->ebox, TRUE);
345   gtk_event_box_set_visible_window(GTK_EVENT_BOX(wavelan->ebox), FALSE);
346   gtk_event_box_set_above_child(GTK_EVENT_BOX(wavelan->ebox), TRUE);
347   g_signal_connect(wavelan->ebox, "query-tooltip", G_CALLBACK(tooltip_cb), wavelan);
348   xfce_panel_plugin_add_action_widget(plugin, wavelan->ebox);
349   gtk_container_add(GTK_CONTAINER(plugin), wavelan->ebox);
350 
351   wavelan->tooltip_text = gtk_label_new(NULL);
352   g_object_ref( wavelan->tooltip_text );
353 
354   /* create box for img & progress bar */
355   wavelan->box = gtk_box_new(wavelan->orientation, 0);
356 
357   /* setup progressbar */
358   wavelan->signal = gtk_progress_bar_new();
359 #if GTK_CHECK_VERSION (3, 16, 0)
360   wavelan->css_provider = gtk_css_provider_new ();
361   gtk_style_context_add_provider (
362       GTK_STYLE_CONTEXT (gtk_widget_get_style_context (GTK_WIDGET (wavelan->signal))),
363       GTK_STYLE_PROVIDER (wavelan->css_provider),
364       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
365 #endif
366   wavelan->image = GTK_WIDGET(xfce_panel_image_new_from_source("network-wireless"));
367 
368   gtk_box_pack_start(GTK_BOX(wavelan->box), GTK_WIDGET(wavelan->image), FALSE, FALSE, 0);
369   gtk_box_pack_start(GTK_BOX(wavelan->box), GTK_WIDGET(wavelan->signal), FALSE, FALSE, 0);
370 
371 
372   wavelan_set_size(plugin, xfce_panel_plugin_get_size (plugin), wavelan);
373   wavelan_set_orientation(plugin, xfce_panel_plugin_get_orientation (plugin),  wavelan);
374   gtk_widget_show_all(wavelan->box);
375   gtk_container_add(GTK_CONTAINER(wavelan->ebox), GTK_WIDGET(wavelan->box));
376   gtk_widget_show_all(wavelan->ebox);
377 
378   wavelan_read_config(plugin, wavelan);
379 
380   wavelan_set_state(wavelan, wavelan->state);
381 
382   return(wavelan);
383 }
384 
385 static void
wavelan_free(XfcePanelPlugin * plugin,t_wavelan * wavelan)386 wavelan_free(XfcePanelPlugin* plugin, t_wavelan *wavelan)
387 {
388   TRACE ("Entered wavelan_free");
389 
390   /* free tooltips */
391   g_object_unref(G_OBJECT(wavelan->tooltip_text));
392 
393   g_source_remove(wavelan->timer_id);
394 
395   /* free the device info */
396   if (wavelan->device != NULL)
397     wi_close(wavelan->device);
398 
399   if (wavelan->interface != NULL)
400     g_free(wavelan->interface);
401 
402   g_free(wavelan);
403 }
404 
405 static void
wavelan_write_config(XfcePanelPlugin * plugin,t_wavelan * wavelan)406 wavelan_write_config(XfcePanelPlugin *plugin, t_wavelan *wavelan)
407 {
408   char *file;
409   XfceRc *rc;
410 
411   TRACE ("Entered wavelan_write_config");
412 
413   if (!(file = xfce_panel_plugin_save_location (plugin, TRUE)))
414   {
415     return;
416   }
417 
418   rc = xfce_rc_simple_open (file, FALSE);
419 
420   g_free (file);
421 
422   if (!rc)
423     return;
424 
425   if (wavelan->interface)
426   {
427     xfce_rc_write_entry (rc, "Interface", wavelan->interface);
428   }
429   xfce_rc_write_bool_entry (rc, "Autohide", wavelan->autohide);
430   xfce_rc_write_bool_entry (rc, "AutohideMissing", wavelan->autohide_missing);
431   xfce_rc_write_bool_entry (rc, "SignalColors", wavelan->signal_colors);
432   xfce_rc_write_bool_entry (rc, "ShowIcon", wavelan->show_icon);
433 
434   xfce_rc_close(rc);
435 
436 }
437 
438 static void
wavelan_set_orientation(XfcePanelPlugin * plugin,GtkOrientation orientation,t_wavelan * wavelan)439 wavelan_set_orientation(XfcePanelPlugin* plugin, GtkOrientation orientation, t_wavelan *wavelan)
440 {
441   DBG("wavelan_set_orientation(%d)", orientation);
442   wavelan->orientation = orientation;
443   gtk_orientable_set_orientation(GTK_ORIENTABLE(wavelan->box), orientation);
444   gtk_orientable_set_orientation(GTK_ORIENTABLE(wavelan->signal), !orientation);
445   gtk_progress_bar_set_inverted(GTK_PROGRESS_BAR(wavelan->signal), (orientation == GTK_ORIENTATION_HORIZONTAL));
446   if (orientation == GTK_ORIENTATION_HORIZONTAL)
447    gtk_widget_set_size_request(wavelan->ebox, -1, wavelan->size);
448   else
449    gtk_widget_set_size_request(wavelan->ebox, wavelan->size, -1);
450   wavelan_set_state(wavelan, wavelan->state);
451 }
452 
453 static void
wavelan_set_size(XfcePanelPlugin * plugin,int size,t_wavelan * wavelan)454 wavelan_set_size(XfcePanelPlugin* plugin, int size, t_wavelan *wavelan)
455 {
456   int border_width, image_size;
457   DBG("wavelan_set_size(%d)", size);
458   size /= xfce_panel_plugin_get_nrows(plugin);
459   xfce_panel_plugin_set_small (plugin, TRUE);
460   border_width = size > 26 ? 2 : 1;
461   wavelan->size = size;
462   image_size = wavelan->size - (2 * border_width);
463   xfce_panel_image_set_size(XFCE_PANEL_IMAGE(wavelan->image), image_size);
464   gtk_container_set_border_width(GTK_CONTAINER(wavelan->box), border_width);
465   if (wavelan->orientation == GTK_ORIENTATION_HORIZONTAL)
466    gtk_widget_set_size_request(wavelan->ebox, -1, wavelan->size);
467   else
468    gtk_widget_set_size_request(wavelan->ebox, wavelan->size, -1);
469 }
470 
471 /* interface changed callback */
472 static void
wavelan_interface_changed(GtkEntry * entry,t_wavelan * wavelan)473 wavelan_interface_changed(GtkEntry *entry, t_wavelan *wavelan)
474 {
475     if (wavelan->interface != NULL)
476           g_free(wavelan->interface);
477     wavelan->interface = g_strdup(gtk_entry_get_text(entry));
478     wavelan_reset(wavelan);
479 }
480 
481 /* autohide toggled callback */
482 static void
wavelan_autohide_changed(GtkToggleButton * button,t_wavelan * wavelan)483 wavelan_autohide_changed(GtkToggleButton *button, t_wavelan *wavelan)
484 {
485   TRACE ("Entered wavelan_autohide_changed");
486   wavelan->autohide = gtk_toggle_button_get_active(button);
487   wavelan_set_state(wavelan, wavelan->state);
488 }
489 
490 /* autohide on missing callback */
491 static void
wavelan_autohide_missing_changed(GtkToggleButton * button,t_wavelan * wavelan)492 wavelan_autohide_missing_changed(GtkToggleButton *button, t_wavelan *wavelan)
493 {
494   TRACE ("Entered wavelan_autohide_missing_changed");
495   wavelan->autohide_missing = gtk_toggle_button_get_active(button);
496   wavelan_set_state(wavelan, wavelan->state);
497 }
498 
499 /* show icon callback */
500 static void
wavelan_show_icon_changed(GtkToggleButton * button,t_wavelan * wavelan)501 wavelan_show_icon_changed(GtkToggleButton *button, t_wavelan *wavelan)
502 {
503   TRACE ("Entered wavelan_show_icon_changed");
504   wavelan->show_icon = gtk_toggle_button_get_active(button);
505   wavelan_set_state(wavelan, wavelan->state);
506 }
507 
508 /* signal colors callback */
509 static void
wavelan_signal_colors_changed(GtkToggleButton * button,t_wavelan * wavelan)510 wavelan_signal_colors_changed(GtkToggleButton *button, t_wavelan *wavelan)
511 {
512   TRACE ("Entered wavelan_signal_colors_changed");
513   wavelan->signal_colors = gtk_toggle_button_get_active(button);
514   wavelan_set_state(wavelan, wavelan->state);
515 }
516 
517 static void
wavelan_dialog_response(GtkWidget * dlg,int response,t_wavelan * wavelan)518 wavelan_dialog_response (GtkWidget *dlg, int response, t_wavelan *wavelan)
519 {
520     g_object_set_data (G_OBJECT (wavelan->plugin), "dialog", NULL);
521 
522     gtk_widget_destroy (dlg);
523 /*    xfce_panel_plugin_unblock_menu (wavelan->plugin); */
524     wavelan_write_config (wavelan->plugin, wavelan);
525 }
526 
527 /* options dialog */
528 static void
wavelan_create_options(XfcePanelPlugin * plugin,t_wavelan * wavelan)529 wavelan_create_options (XfcePanelPlugin *plugin, t_wavelan *wavelan)
530 {
531   GtkWidget *dlg, *hbox, *label, *interface, *vbox, *autohide;
532   GtkWidget *autohide_missing, *warn_label, *signal_colors, *show_icon;
533   GtkWidget *combo;
534   GList     *interfaces, *lp;
535 
536   TRACE ("Entered wavelan_create_options");
537 
538   dlg = xfce_titled_dialog_new_with_buttons (_("Wavelan Plugin Options"),
539               GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (plugin))),
540               GTK_DIALOG_DESTROY_WITH_PARENT,
541               "gtk-close",
542               GTK_RESPONSE_OK,
543               NULL);
544 
545   gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER);
546   gtk_window_set_icon_name (GTK_WINDOW (dlg), "network-wireless");
547 
548   g_signal_connect (dlg, "response", G_CALLBACK (wavelan_dialog_response),
549                     wavelan);
550 
551   xfce_titled_dialog_set_subtitle (XFCE_TITLED_DIALOG (dlg), _("Properties"));
552 
553   vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
554   gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
555   gtk_widget_show(vbox);
556   gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area(GTK_DIALOG (dlg))), vbox,
557                       TRUE, TRUE, 0);
558 
559   hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
560   gtk_widget_show(hbox);
561 
562   label = gtk_label_new(_("Interface"));
563   gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
564   gtk_widget_show(label);
565 
566   interfaces = wavelan_query_interfaces ();
567   combo = gtk_combo_box_text_new_with_entry ();
568   for (lp = interfaces; lp != NULL; lp = lp->next)
569     gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), lp->data);
570   gtk_widget_show (combo);
571   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
572 
573   interface = gtk_bin_get_child (GTK_BIN (combo));
574   if (wavelan->interface != NULL)
575     gtk_entry_set_text(GTK_ENTRY(interface), wavelan->interface);
576   g_signal_connect(interface, "changed", G_CALLBACK(wavelan_interface_changed),
577       wavelan);
578   gtk_widget_show(interface);
579 
580   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
581   gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 0);
582 
583   hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
584   gtk_widget_show(hbox);
585   autohide = gtk_check_button_new_with_mnemonic(_("_Autohide when offline"));
586   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(autohide), wavelan->autohide);
587   g_signal_connect(autohide, "toggled", G_CALLBACK(wavelan_autohide_changed),
588       wavelan);
589   gtk_widget_show(autohide);
590   gtk_box_pack_start(GTK_BOX(hbox), autohide, TRUE, TRUE, 0);
591   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
592 
593   hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
594   gtk_widget_show(hbox);
595   autohide_missing = gtk_check_button_new_with_mnemonic(_("Autohide when no _hardware present"));
596   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(autohide_missing),
597       wavelan->autohide_missing);
598   g_signal_connect(autohide_missing, "toggled",
599       G_CALLBACK(wavelan_autohide_missing_changed), wavelan);
600   gtk_widget_show(autohide_missing);
601   gtk_box_pack_start(GTK_BOX(hbox), autohide_missing, TRUE, TRUE, 0);
602   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
603 
604   hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
605   gtk_widget_set_margin_start (GTK_WIDGET (hbox), 12);
606   gtk_widget_show(hbox);
607   warn_label = gtk_label_new(_("Note: This will make it difficult to remove or configure the plugin if there is no device detected."));
608   gtk_label_set_line_wrap(GTK_LABEL(warn_label), TRUE);
609   gtk_label_set_xalign (GTK_LABEL (warn_label), 0.0f);
610   gtk_widget_show(warn_label);
611   gtk_box_pack_start(GTK_BOX(hbox), warn_label, TRUE, TRUE, 0);
612   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
613 
614   hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
615   gtk_widget_show(hbox);
616   signal_colors = gtk_check_button_new_with_mnemonic(_("Enable sig_nal quality colors"));
617   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(signal_colors),
618       wavelan->signal_colors);
619   g_signal_connect(signal_colors, "toggled",
620       G_CALLBACK(wavelan_signal_colors_changed), wavelan);
621   gtk_widget_show(signal_colors);
622   gtk_box_pack_start(GTK_BOX(hbox), signal_colors, TRUE, TRUE, 0);
623   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
624 
625   hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
626   gtk_widget_show(hbox);
627   show_icon = gtk_check_button_new_with_mnemonic(_("Show _icon"));
628   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_icon),
629       wavelan->show_icon);
630   g_signal_connect(show_icon, "toggled",
631       G_CALLBACK(wavelan_show_icon_changed), wavelan);
632   gtk_widget_show(show_icon);
633   gtk_box_pack_start(GTK_BOX(hbox), show_icon, TRUE, TRUE, 0);
634   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
635 
636   for (lp = interfaces; lp != NULL; lp = lp ->next)
637     g_free (lp->data);
638   g_list_free (interfaces);
639 
640   gtk_widget_show (dlg);
641 
642 }
643 
644 static void
wavelan_show_about(XfcePanelPlugin * plugin,t_wavelan * wavelan)645 wavelan_show_about (XfcePanelPlugin *plugin, t_wavelan *wavelan)
646 {
647    GdkPixbuf *icon;
648    const gchar *auth[] = { "Benedikt Meurer <benny at xfce.org>", "Florian Rivoal <frivoal@xfce.org>", NULL };
649    icon = xfce_panel_pixbuf_from_source("network-wireless", NULL, 32);
650    gtk_show_about_dialog(NULL,
651       "logo", icon,
652       "license", xfce_get_license_text (XFCE_LICENSE_TEXT_BSD),
653       "version", PACKAGE_VERSION,
654       "program-name", PACKAGE_NAME,
655       "comments", _("View the status of a wireless network"),
656       "website", "https://docs.xfce.org/panel-plugins/xfce4-wavelan-plugin",
657       "copyright", "Copyright (c) 2003-2004 Benedikt Meurer\n",
658       "authors", auth, NULL);
659 
660    if(icon)
661       g_object_unref(G_OBJECT(icon));
662 }
663 
664 static void
wavelan_construct(XfcePanelPlugin * plugin)665 wavelan_construct (XfcePanelPlugin *plugin)
666 {
667   t_wavelan *wavelan = wavelan_new(plugin);
668 
669   TRACE ("Entered wavelan_construct");
670 
671   xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
672 
673   g_signal_connect (plugin, "orientation-changed",
674                     G_CALLBACK (wavelan_set_orientation), wavelan);
675 
676   g_signal_connect (plugin, "size-changed",
677                     G_CALLBACK (wavelan_set_size), wavelan);
678 
679   g_signal_connect (plugin, "free-data",
680                     G_CALLBACK (wavelan_free), wavelan);
681 
682   g_signal_connect (plugin, "save",
683                     G_CALLBACK (wavelan_write_config), wavelan);
684 
685   xfce_panel_plugin_menu_show_configure (plugin);
686   g_signal_connect (plugin, "configure-plugin",
687                     G_CALLBACK (wavelan_create_options), wavelan);
688 
689   xfce_panel_plugin_menu_show_about(plugin);
690   g_signal_connect (plugin, "about", G_CALLBACK (wavelan_show_about), wavelan);
691 }
692 
693 #if 0
694 int main(int argc, char** argv)
695 {
696 	struct wi_device *device;
697 	struct wi_stats stats;
698 	if ((device = wi_open(argv[1])) == NULL)
699 		errx(1, "failed to open %s\n", argv[1]);
700 
701 
702 	if (wi_query(device, &stats) != WI_OK)
703 		errx(2, "wi_query failed\n");
704 
705 	printf("NWID:%s, quality:%d%%, rate:%dMb/s\n", stats.ws_netname, stats.ws_quality, stats.ws_rate);
706 	wi_close(device);
707 	return 0;
708 }
709 #else
710 XFCE_PANEL_PLUGIN_REGISTER(wavelan_construct);
711 #endif
712