aboutsummaryrefslogtreecommitdiffstats
path: root/applets/mb-applet-wireless.c
diff options
context:
space:
mode:
Diffstat (limited to 'applets/mb-applet-wireless.c')
-rw-r--r--applets/mb-applet-wireless.c511
1 files changed, 511 insertions, 0 deletions
diff --git a/applets/mb-applet-wireless.c b/applets/mb-applet-wireless.c
new file mode 100644
index 0000000..9f62cf6
--- /dev/null
+++ b/applets/mb-applet-wireless.c
@@ -0,0 +1,511 @@
+/*
+ * miniwave - Tiny 820.11 wireless
+ *
+ * Note: you can use themes from http://www.eskil.org/wavelan-applet/
+ *
+ * originally based on wmwave
+ *
+ * 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., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <libmb/mb.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(text) gettext(text)
+#else
+# define _(text) (text)
+#endif
+
+#define HAVE_LINUX_WIRELESS_H 1
+
+#ifdef HAVE_LINUX_WIRELESS_H
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <netdb.h> /* gethostbyname, getnetbyname */
+#include <linux/if_arp.h> /* For ARPHRD_ETHER */
+#include <linux/socket.h> /* For AF_INET & struct sockaddr */
+#include <sys/socket.h> /* For struct sockaddr_in */
+#include <linux/wireless.h>
+
+#endif
+
+#ifdef MB_HAVE_PNG
+#define IMG_EXT "png"
+#else
+#define IMG_EXT "xpm"
+#endif
+
+static int LastImg = 0;
+
+enum {
+ MW_BROKE = 1,
+ MW_NO_LINK,
+ MW_SIG_1_40,
+ MW_SIG_41_60,
+ MW_SIG_61_80,
+ MW_SIG_80_100,
+};
+
+#define MW_BROKE_IMG "broken-0." IMG_EXT
+#define MW_NO_LINK_IMG "no-link-0." IMG_EXT
+#define MW_SIG_1_40_IMG "signal-1-40." IMG_EXT
+#define MW_SIG_41_60_IMG "signal-41-60." IMG_EXT
+#define MW_SIG_61_80_IMG "signal-61-80." IMG_EXT
+#define MW_SIG_80_100_IMG "signal-81-100." IMG_EXT
+
+static char *ImgLookup[64] = {
+ MW_BROKE_IMG,
+ MW_NO_LINK_IMG,
+ MW_SIG_1_40_IMG,
+ MW_SIG_41_60_IMG,
+ MW_SIG_61_80_IMG,
+ MW_SIG_80_100_IMG,
+
+};
+
+static char *ThemeName = NULL;
+static MBPixbuf *pb;
+static MBPixbufImage *Imgs[6] = { 0,0,0,0,0,0 },
+ *ImgsScaled[6] = { 0,0,0,0,0,0 };
+static int CurImg = MW_BROKE;
+
+struct {
+
+ char iface[5];
+ char status[3];
+ float link;
+ float level;
+ float noise;
+ int nwid;
+ int crypt;
+ int misc;
+ int mode;
+
+} Mwd;
+
+#define HAVE_LINUX_WIRELESS_H 1
+
+#ifdef HAVE_LINUX_WIRELESS_H
+
+typedef struct iw_range iwrange;
+typedef struct iw_param iwparam;
+typedef struct iw_freq iwfreq;
+typedef struct iw_priv_args iwprivargs;
+typedef struct sockaddr sockaddr;
+
+typedef struct iw_info
+{
+
+ char name[IFNAMSIZ]; /* Wireless/protocol name */
+ int has_nwid;
+ iwparam nwid; /* Network ID */
+ int has_freq;
+ float freq; /* Frequency/channel */
+ int has_sens;
+ iwparam sens; /* sensitivity */
+ int has_key;
+ unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */
+ int key_size; /* Number of bytes */
+ int key_flags; /* Various flags */
+ int has_essid;
+ int essid_on;
+ char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID */
+ int has_nickname;
+ char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */
+ int has_ap_addr;
+ sockaddr ap_addr; /* Access point address */
+ int has_bitrate;
+ iwparam bitrate; /* Bit rate in bps */
+ int has_rts;
+ iwparam rts; /* RTS threshold in bytes */
+ int has_frag;
+ iwparam frag; /* Fragmentation threshold in bytes */
+ int has_mode;
+ int mode; /* Operation mode */
+ int has_power;
+ iwparam power; /* Power management parameters */
+#if 0
+ /* Stats */
+ iwstats stats;
+ int has_stats;
+ iwrange range;
+ int has_range;
+#endif
+} InterfaceInfo;
+
+InterfaceInfo ExtendedIWInfo;
+
+int
+get_extented_iw_info(InterfaceInfo *indata)
+{
+ InterfaceInfo *wdata = indata;
+ struct iwreq request;
+ int netsock_fd = -1;
+
+
+ strcpy( wdata->name, Mwd.iface );
+
+ /* open socket */
+
+ netsock_fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ if (netsock_fd == -1) return -1;
+
+ /* network name */
+
+ strcpy ( request.ifr_name, wdata->name);
+ request.u.essid.pointer = (caddr_t) wdata->essid;
+ request.u.essid.length = IW_ESSID_MAX_SIZE + 1;
+ request.u.essid.flags = 0;
+
+ if ( ioctl (netsock_fd, SIOCGIWESSID, &request) >= 0)
+ {
+ wdata->has_essid = 1;
+ wdata->essid_on = request.u.data.flags;
+ }
+ else wdata->has_essid = 0;
+
+#if 0 /* Stuff possibly breaks on some cards */
+
+ /* station name */
+
+ strcpy ( request.ifr_name, wdata->name);
+ request.u.essid.pointer = (caddr_t) wdata->nickname;
+ request.u.essid.length=0;
+ request.u.essid.flags=0;
+
+ if ( ioctl (netsock_fd, SIOCGIWNICKN, &request) < 0)
+ {
+ wdata->nickname[0] = '\0';
+ }
+
+ /* mode */
+
+ strcpy ( request.ifr_name, wdata->name);
+
+ if ( ioctl (netsock_fd, SIOCGIWMODE, &request) >= 0)
+ {
+ if ((request.u.mode < 6) && (request.u.mode >= 0))
+ wdata->mode = request.u.mode;
+ }
+
+ /* enc settings (on/off and key) */
+
+ wdata->has_key = 0;
+ strcpy ( request.ifr_name, wdata->name);
+ request.u.data.pointer = (caddr_t) wdata->key;
+ request.u.data.length=0;
+ request.u.data.flags=0;
+
+ if ( ioctl (netsock_fd, SIOCGIWENCODE, &request) >= 0)
+ {
+ wdata->has_key = 1;
+ wdata->key_size = request.u.data.length;
+ wdata->key_flags = request.u.data.flags;
+ }
+
+ /* power savings */
+
+ strcpy(request.ifr_name, wdata->name);
+ request.u.power.flags = 0;
+
+ if(ioctl(netsock_fd, SIOCGIWPOWER, &request) >= 0)
+ {
+ wdata->has_power = 1;
+ memcpy(&(wdata->power), &(request.u.power), sizeof(iwparam));
+ }
+
+ /* access point mac address */
+
+ strcpy(request.ifr_name, wdata->name);
+
+ if(ioctl(netsock_fd, SIOCGIWAP, &request) >= 0)
+ {
+ wdata->has_ap_addr = 1;
+ memcpy(&(wdata->ap_addr), &(request.u.ap_addr), sizeof (sockaddr));
+ }
+
+#endif
+
+ /* pack it up and spit it out */
+
+ close (netsock_fd);
+
+ return 0;
+}
+
+#endif
+
+Bool
+update_wireless(void) {
+ FILE *wireless; // File handle for /proc/net/wireless
+ int count;
+ char line[255];
+
+ Mwd.link = 0;
+ Mwd.level = 0;
+ Mwd.noise = 0;
+ Mwd.nwid = 0;
+ Mwd.crypt = 0;
+ Mwd.misc = 0;
+
+ if ((wireless = fopen ("/proc/net/wireless", "r")) != NULL)
+ {
+ fgets(line,sizeof(line),wireless);
+ fgets(line,sizeof(line),wireless);
+ if (fgets(line,sizeof(line),wireless) == NULL) {
+ Mwd.mode = 0;
+ Mwd.iface[0]=0;
+ } else {
+ sscanf(line,"%s %s %f %f %f %d %d %d",
+ Mwd.iface, Mwd.status, &Mwd.link, &Mwd.level,
+ &Mwd.noise, &Mwd.nwid, &Mwd.crypt, &Mwd.misc);
+ for(count=0;(count<strlen(line)) && (line[count]==0x20);count++);
+ strncpy(Mwd.iface,&line[count],5);
+ Mwd.iface[4]=0;
+ Mwd.mode = 1;
+ }
+ fclose(wireless);
+ }
+ else
+ {
+ fprintf (stderr, "miniwave: Wirless device /proc/net/wireless not found\nEnable radio networking and recompile your kernel\n");
+ return False;
+ }
+ return True;
+}
+
+void
+paint_callback (MBTrayApp *app, Drawable drw )
+{
+
+ MBPixbufImage *img_backing = NULL;
+
+ if (update_wireless())
+ {
+ if (Mwd.mode)
+ {
+ /* res->percent = (int)rint ((log (link) / log (92)) * 100.0); ? */
+ if (Mwd.link > 0 && Mwd.link < 41)
+ CurImg = MW_SIG_1_40;
+ else if (Mwd.link > 40 && Mwd.link < 61)
+ CurImg = MW_SIG_41_60;
+ else if (Mwd.link > 60 && Mwd.link < 81)
+ CurImg = MW_SIG_61_80;
+ else if (Mwd.link > 80)
+ CurImg = MW_SIG_80_100;
+ else
+ CurImg = MW_NO_LINK;
+ }
+ else CurImg = MW_NO_LINK;
+ }
+ else CurImg = MW_BROKE;
+
+ if (LastImg == CurImg) return;
+
+ img_backing = mb_tray_app_get_background (app, pb);
+
+ mb_pixbuf_img_copy_composite(pb, img_backing,
+ ImgsScaled[CurImg], 0, 0,
+ mb_pixbuf_img_get_width(ImgsScaled[0]),
+ mb_pixbuf_img_get_height(ImgsScaled[0]),
+ mb_tray_app_tray_is_vertical(app) ?
+ (mb_pixbuf_img_get_width(img_backing)-mb_pixbuf_img_get_width(ImgsScaled[0]))/2 : 0,
+ mb_tray_app_tray_is_vertical(app) ? 0 :
+ (mb_pixbuf_img_get_height(img_backing)-mb_pixbuf_img_get_height(ImgsScaled[0]))/2 );
+
+ mb_pixbuf_img_render_to_drawable(pb, img_backing, drw, 0, 0);
+
+ mb_pixbuf_img_free( pb, img_backing );
+
+ LastImg = CurImg;
+}
+
+
+void
+load_icons(MBTrayApp *app)
+{
+ int i;
+ char *icon_path;
+
+ for (i=0; i<6; i++)
+ {
+ if (Imgs[i] != NULL) mb_pixbuf_img_free(pb, Imgs[i]);
+ icon_path = mb_dot_desktop_icon_get_full_path (ThemeName,
+ 32,
+ ImgLookup[i]);
+
+ if (icon_path == NULL
+ || !(Imgs[i] = mb_pixbuf_img_new_from_file(pb, icon_path)))
+ {
+ fprintf(stderr, "minivol: failed to load icon\n" );
+ exit(1);
+ }
+
+ free(icon_path);
+ }
+
+}
+
+void
+resize_callback (MBTrayApp *app, int w, int h )
+{
+ int i;
+ int base_width = mb_pixbuf_img_get_width(Imgs[0]);
+ int base_height = mb_pixbuf_img_get_height(Imgs[0]);
+ int scale_width = base_width, scale_height = base_height;
+ Bool want_resize = True;
+
+ if (mb_tray_app_tray_is_vertical(app) && w < base_width)
+ {
+
+ scale_width = w;
+ scale_height = ( base_height * w ) / base_width;
+
+ want_resize = False;
+ }
+ else if (!mb_tray_app_tray_is_vertical(app) && h < base_height)
+ {
+ scale_height = h;
+ scale_width = ( base_width * h ) / base_height;
+ want_resize = False;
+ }
+
+ if (w < base_width && h < base_height
+ && ( scale_height > h || scale_width > w))
+ {
+ /* Something is really wrong to get here */
+ scale_height = h; scale_width = w;
+ want_resize = False;
+ }
+
+ if (want_resize) /* we only request a resize is absolutely needed */
+ {
+ LastImg = 0;
+ mb_tray_app_request_size (app, scale_width, scale_height);
+ }
+
+ for (i=0; i<6; i++)
+ {
+ if (ImgsScaled[i] != NULL) mb_pixbuf_img_free(pb, ImgsScaled[i]);
+ ImgsScaled[i] = mb_pixbuf_img_scale(pb, Imgs[i],
+ scale_width, scale_height);
+ }
+
+}
+
+void
+button_callback (MBTrayApp *app, int x, int y, Bool is_released )
+{
+ char tray_msg[256];
+
+ if (!is_released) return;
+
+ if (Mwd.mode)
+ {
+ if (get_extented_iw_info(&ExtendedIWInfo) == 0)
+ {
+ sprintf(tray_msg,
+ "%s:\n"
+ " Network: %s\n"
+ " Link %.1f\n Level %.1f\n Noise %.1f\n",
+ Mwd.iface,
+ ExtendedIWInfo.has_essid ? ExtendedIWInfo.essid : "Unkown",
+ Mwd.link, Mwd.level, Mwd.noise );
+ }
+ else
+ {
+ sprintf(tray_msg, _("%s:\n Link %.1f\n Level %.1f\n Noise %.1f\n"),
+ Mwd.iface, Mwd.link, Mwd.level, Mwd.noise );
+ }
+ }
+ else
+ sprintf(tray_msg, _("No wireless cards detected\n"));
+
+ mb_tray_app_tray_send_message(app, tray_msg, 5000);
+
+}
+
+void
+theme_callback (MBTrayApp *app, char *theme_name)
+{
+ if (!theme_name) return;
+ if (ThemeName) free(ThemeName);
+
+ LastImg = 0; /* Make sure paint gets updated */
+
+ ThemeName = strdup(theme_name);
+ load_icons(app);
+ resize_callback (app, mb_tray_app_width(app), mb_tray_app_width(app) );
+}
+
+void
+timeout_callback ( MBTrayApp *app )
+{
+ mb_tray_app_repaint (app);
+}
+
+int
+main( int argc, char *argv[])
+{
+ MBTrayApp *app = NULL;
+ struct timeval tv;
+
+#if ENABLE_NLS
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, DATADIR "/locale");
+ bind_textdomain_codeset (PACKAGE, "UTF-8");
+ textdomain (PACKAGE);
+#endif
+
+ memset(&ExtendedIWInfo, 0, sizeof(InterfaceInfo));
+
+ app = mb_tray_app_new ( _("Wireless Monitor"),
+ resize_callback,
+ paint_callback,
+ &argc,
+ &argv );
+
+ pb = mb_pixbuf_new(mb_tray_app_xdisplay(app),
+ mb_tray_app_xscreen(app));
+
+ memset(&tv,0,sizeof(struct timeval));
+ tv.tv_sec = 2;
+
+ load_icons(app);
+
+ mb_tray_app_set_timeout_callback (app, timeout_callback, &tv);
+
+ mb_tray_app_set_button_callback (app, button_callback );
+
+ mb_tray_app_set_theme_change_callback (app, theme_callback );
+
+ mb_tray_app_set_icon(app, pb, Imgs[3]);
+
+ mb_tray_app_main (app);
+
+ return 1;
+}
+
+
+