[Goodies-commits] r2070 - in xfce4-cellmodem-plugin/trunk: . panel-plugin

Alvaro Lopes alvieboy at xfce.org
Mon Sep 25 21:39:39 CEST 2006


Author: alvieboy
Date: 2006-09-25 19:39:23 +0000 (Mon, 25 Sep 2006)
New Revision: 2070

Added:
   xfce4-cellmodem-plugin/trunk/COPYING
   xfce4-cellmodem-plugin/trunk/Makefile.am
   xfce4-cellmodem-plugin/trunk/NEWS
   xfce4-cellmodem-plugin/trunk/README
   xfce4-cellmodem-plugin/trunk/autogen.sh
   xfce4-cellmodem-plugin/trunk/configure.ac
   xfce4-cellmodem-plugin/trunk/panel-plugin/
   xfce4-cellmodem-plugin/trunk/panel-plugin/Makefile.am
   xfce4-cellmodem-plugin/trunk/panel-plugin/big_leds.xpm
   xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.c
   xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.desktop.in.in
   xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.h
   xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem_options.h
   xfce4-cellmodem-plugin/trunk/panel-plugin/leds.c
   xfce4-cellmodem-plugin/trunk/panel-plugin/leds.h
   xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver.c
   xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver.h
   xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_fake.c
   xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_fake.h
   xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_generic.c
   xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_generic.h
   xfce4-cellmodem-plugin/trunk/panel-plugin/pin_helper.c
   xfce4-cellmodem-plugin/trunk/panel-plugin/pin_helper.h
   xfce4-cellmodem-plugin/trunk/panel-plugin/preferences.c
   xfce4-cellmodem-plugin/trunk/panel-plugin/preferences.h
Log:
Initial import for goodies tree

Added: xfce4-cellmodem-plugin/trunk/COPYING
===================================================================
--- xfce4-cellmodem-plugin/trunk/COPYING	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/COPYING	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */

Added: xfce4-cellmodem-plugin/trunk/Makefile.am
===================================================================
--- xfce4-cellmodem-plugin/trunk/Makefile.am	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/Makefile.am	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1 @@
+SUBDIRS = panel-plugin

Added: xfce4-cellmodem-plugin/trunk/NEWS
===================================================================
--- xfce4-cellmodem-plugin/trunk/NEWS	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/NEWS	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1 @@
+No news

Added: xfce4-cellmodem-plugin/trunk/README
===================================================================
--- xfce4-cellmodem-plugin/trunk/README	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/README	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1 @@
+Cell Modem monitor plugin for XFCE.

Added: xfce4-cellmodem-plugin/trunk/autogen.sh
===================================================================
--- xfce4-cellmodem-plugin/trunk/autogen.sh	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/autogen.sh	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# $Id: autogen.sh 1355 2006-04-24 21:01:13Z bountykiller $
+#
+# Copyright (c) 2002-2005
+#         The Xfce development team. All rights reserved.
+#
+# Written for Xfce by Benedikt Meurer <benny at xfce.org>.
+#
+
+(type xdt-autogen) >/dev/null 2>&1 || {
+  cat >&2 <<EOF
+autogen.sh: You don't seem to have the Xfce development tools installed on
+            your system, which are required to build this software.
+            Please install the xfce4-dev-tools package first, it is available
+            from http://www.xfce.org/.
+EOF
+  exit 1
+}
+
+exec xdt-autogen $@
+
+# vi:set ts=2 sw=2 et ai:
\ No newline at end of file


Property changes on: xfce4-cellmodem-plugin/trunk/autogen.sh
___________________________________________________________________
Name: svn:executable
   + *

Added: xfce4-cellmodem-plugin/trunk/configure.ac
===================================================================
--- xfce4-cellmodem-plugin/trunk/configure.ac	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/configure.ac	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,25 @@
+m4_define([cellmodem_version], [0.0.1])
+
+AC_INIT([xfce4-cellmodem-plugin], [cellmodem_version()],[alvieboy at alvie.com])
+
+
+CELLMODEM_VERSION=cellmodem_version()
+AM_INIT_AUTOMAKE([xfce4-cellmodem-plugin], [$CELLMODEM_VERSION])
+AM_CONFIG_HEADER([config.h])
+
+AM_MAINTAINER_MODE
+AC_ISC_POSIX
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_INTLTOOL
+
+AC_HEADER_STDC
+
+XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-1.0], [4.3.20])
+XDT_I18N([])
+
+AC_OUTPUT([
+Makefile
+panel-plugin/Makefile
+po/Makefile
+])

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/Makefile.am
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/Makefile.am	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/Makefile.am	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,46 @@
+plugindir = $(libexecdir)/xfce4/panel-plugins
+plugin_PROGRAMS = xfce4-cellmodem-plugin
+
+xfce4_cellmodem_plugin_CFLAGS = \
+        -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
+	@LIBXFCE4PANEL_CFLAGS@
+
+xfce4_cellmodem_plugin_LDFLAGS = \
+	@LIBXFCE4PANEL_LIBS@
+
+xfce4_cellmodem_plugin_SOURCES = \
+	cellmodem.c modem_driver.c \
+	modem_driver_fake.c \
+	modem_driver_generic.c \
+	preferences.c \
+	pin_helper.c \
+	leds.c
+
+noinst_HEADERS = \
+	cellmodem.h \
+	leds.h \
+	modem_driver_generic.h \
+	pin_helper.h \
+	cellmodem_options.h \
+	modem_driver_fake.h \
+	modem_driver.h \
+	preferences.h
+
+
+desktop_in_in_files = cellmodem.desktop.in.in
+desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in)
+	
+desktopdir = $(datadir)/xfce4/panel-plugins
+ at INTLTOOL_DESKTOP_RULE@
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+
+EXTRA_DIST = $(desktop_in_in_files)
+
+DISTCLEANFILES = $(desktop_DATA) $(desktop_in_files)
+	
+# get full path into .desktop file
+%.desktop.in: %.desktop.in.in
+	sed -e "s^@PLUGIN_PATH@^$(libexecdir)/xfce4/panel-plugins^" \
+		$< > $@
+
+

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/big_leds.xpm
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/big_leds.xpm	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/big_leds.xpm	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2001-2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ 
+/* XPM */
+static char * big_leds_xpm[] = {
+"48 8 175 2",
+"  	c None",
+". 	c #FF2A2A",
+"+ 	c #FF1111",
+"@ 	c #FF0101",
+"# 	c #FF0707",
+"$ 	c #55D452",
+"% 	c #41CF3E",
+"& 	c #35CB31",
+"* 	c #39CC35",
+"= 	c #84542F",
+"- 	c #794D2A",
+"; 	c #724727",
+"> 	c #754928",
+", 	c #E7C437",
+"' 	c #E4BD20",
+") 	c #E2BA19",
+"! 	c #E3BD21",
+"~ 	c #8042DE",
+"{ 	c #712CDA",
+"] 	c #6C24D9",
+"^ 	c #722CDA",
+"/ 	c #E937DA",
+"( 	c #E61FD6",
+"_ 	c #E617D5",
+": 	c #E720D6",
+"< 	c #FF5555",
+"[ 	c #FF7777",
+"} 	c #FF6060",
+"| 	c #FF1F1F",
+"1 	c #FF0000",
+"2 	c #77DC74",
+"3 	c #92E390",
+"4 	c #7FDF7D",
+"5 	c #4CD249",
+"6 	c #34CB30",
+"7 	c #986036",
+"8 	c #A86B3C",
+"9 	c #9D6438",
+"0 	c #80512D",
+"a 	c #EBCE59",
+"b 	c #EED46E",
+"c 	c #ECCF5B",
+"d 	c #E5C02A",
+"e 	c #E3BB1C",
+"f 	c #9663E4",
+"g 	c #A477E7",
+"h 	c #9865E4",
+"i 	c #7835DC",
+"j 	c #6E27DA",
+"k 	c #EC5AE1",
+"l 	c #EF6FE5",
+"m 	c #ED5CE1",
+"n 	c #E82AD8",
+"o 	c #E61AD6",
+"p 	c #FF3D3D",
+"q 	c #FF8A8A",
+"r 	c #FFCECE",
+"s 	c #FF9F9F",
+"t 	c #FF4545",
+"u 	c #FF0303",
+"v 	c #FF0606",
+"w 	c #64D861",
+"x 	c #A0E79F",
+"y 	c #D7F4D6",
+"z 	c #B1EBB0",
+"A 	c #6AD968",
+"B 	c #36CC32",
+"C 	c #8D5932",
+"D 	c #AF7140",
+"E 	c #BD885D",
+"F 	c #B67746",
+"G 	c #915C33",
+"H 	c #734828",
+"I 	c #EACB50",
+"J 	c #F1DD8B",
+"K 	c #F7ECC0",
+"L 	c #F3E29D",
+"M 	c #EACC50",
+"N 	c #E2BB1A",
+"O 	c #E3BC1F",
+"P 	c #915AE2",
+"Q 	c #B692EC",
+"R 	c #D8C5F4",
+"S 	c #C1A3EE",
+"T 	c #6D26D9",
+"U 	c #702ADA",
+"V 	c #EB51DF",
+"W 	c #F28CEA",
+"X 	c #F8C1F3",
+"Y 	c #F49EED",
+"Z 	c #EC51DF",
+"` 	c #E619D5",
+" .	c #E71DD6",
+"..	c #FF2828",
+"+.	c #FF8080",
+"@.	c #FFBBBB",
+"#.	c #FF9494",
+"$.	c #FF3F3F",
+"%.	c #FF0202",
+"&.	c #54D351",
+"*.	c #99E597",
+"=.	c #C8F0C7",
+"-.	c #A9E9A7",
+";.	c #65D863",
+">.	c #AB6D3E",
+",.	c #BD8151",
+"'.	c #B37342",
+").	c #8E5A32",
+"!.	c #734827",
+"~.	c #E9C742",
+"{.	c #F2DF94",
+"].	c #F9F1D2",
+"^.	c #F4E5A7",
+"/.	c #EBCD56",
+"(.	c #E3BB1B",
+"_.	c #884DE0",
+":.	c #BB9AED",
+"<.	c #E3D5F7",
+"[.	c #C8ADF0",
+"}.	c #9460E3",
+"|.	c #6E26D9",
+"1.	c #EA42DC",
+"2.	c #F395EB",
+"3.	c #FAD3F6",
+"4.	c #F5A8EF",
+"5.	c #EC57E0",
+"6.	c #E61AD5",
+"7.	c #FF0909",
+"8.	c #FF4C4C",
+"9.	c #FF1414",
+"0.	c #3BCD37",
+"a.	c #6FDA6D",
+"b.	c #43CF40",
+"c.	c #764A29",
+"d.	c #945E34",
+"e.	c #7B4D2B",
+"f.	c #E5BF27",
+"g.	c #ECD062",
+"h.	c #F0DA83",
+"i.	c #E7C334",
+"j.	c #7632DC",
+"k.	c #9C6BE5",
+"l.	c #B18BEA",
+"m.	c #7E3FDE",
+"n.	c #E727D7",
+"o.	c #ED62E2",
+"p.	c #F184E8",
+"q.	c #EF6FE4",
+"r.	c #E834DA",
+"s.	c #FF0404",
+"t.	c #FF0C0C",
+"u.	c #FF0505",
+"v.	c #37CC33",
+"w.	c #3ECE3A",
+"x.	c #38CC34",
+"y.	c #774B2A",
+"z.	c #744928",
+"A.	c #E4BE23",
+"B.	c #E6C231",
+"C.	c #E2BA1A",
+"D.	c #732EDB",
+"E.	c #7C3CDD",
+"F.	c #7633DB",
+"G.	c #6D25D9",
+"H.	c #6E27D9",
+"I.	c #E722D7",
+"J.	c #E831D9",
+"K.	c #E727D8",
+"L.	c #E618D5",
+"M.	c #38CC35",
+"N.	c #E2BB1B",
+"O.	c #E3BB1D",
+"P.	c #6F28DA",
+"Q.	c #E61DD6",
+"R.	c #E61CD6",
+"    . + @ #         $ % & *         = - ; >         , ' ) !         ~ { ] ^         / ( _ :     ",
+"  < [ } | 1 @     2 3 4 5 6 &     7 8 9 0 ; ;     a b c d ) e     f g h i ] j     k l m n _ o   ",
+"p q r s t u 1 v w x y z A B 6 * C D E F G H ; > I J K L M N ) O P Q R S P T ] U V W X Y Z ` _  .",
+"..+. at .#.$.%.1 1 &.*.=.-.;.& 6 6 = >.,.'.).!.; ; ~.{.].^./.(.) ) _.:.<.[.}.|.] ] 1.2.3.4.5.6._ _ ",
+"7.$.} 8.9.1 1 1 0.;.4 a.b.6 6 6 c.).9 d.e.; ; ; f.g.h.b i.) ) ) j.k.l.g m.] ] ] n.o.p.q.r._ _ _ ",
+"# s.t.v 1 1 1 u.* v.w.* 6 6 6 x.> H y.z.; ; ; z.e A.B.f.C.) ) e j D.E.F.G.] ] H.o I.J.K.L._ _ 6.",
+"  @ 1 1 1 1 @     & 6 6 6 6 &     ; ; ; ; ; ;     ) ) ) ) ) )     ] ] ] ] ] ]     _ _ _ _ _ _   ",
+"    v 1 1 v         * 6 6 M.        > ; ; z.      O N.) ) C.O.    U T ] ] G.P.    Q.` _ _ ` R.  "};

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.c
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.c	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.c	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,1506 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "cellmodem.h"
+#include "modem_driver.h"
+#include "preferences.h"
+#include "pin_helper.h"
+
+/* Prototypes */
+
+static gboolean cellmodem_t_send_at_command( cellmodem_t *monitor,
+					     modem_reply_callback_t callback,
+					     const gchar *command );
+static gboolean get_network_info( cellmodem_t *monitor );
+
+static void cellmodem_t_identify_network( cellmodem_t *monitor );
+void cellmodem_write_config(XfcePanelPlugin *plugin, cellmodem_t *monitor);
+static gboolean cellmodem_t_close_modem(cellmodem_t *monitor /*, gboolean failure */);
+static gboolean reschedule_open( cellmodem_t *monitor /*, gboolean failure */);
+static gboolean cellmodem_t_at_command_timeout( cellmodem_t *monitor );
+static void cellmodem_t_cancel_pending_at_command_timeout( cellmodem_t *monitor );
+static void cellmodem_t_get_quality( cellmodem_t *monitor );
+static void cellmodem_t_get_pin_status( cellmodem_t *monitor );
+static void cellmodem_t_send_pin( cellmodem_t *monitor, const gchar *pin );
+static void cellmodem_t_set_tooltip_info( cellmodem_t *monitor );
+
+
+
+/* End Proto */
+
+
+
+static void cellmodem_t_set_error( cellmodem_t *monitor )
+{
+    led_t_set_color( monitor->status_led, LED_RED );
+    led_t_set_flashing( monitor->status_led, TRUE );
+    led_t_set_color( monitor->network_led, LED_OFF );
+    led_t_set_flashing( monitor->network_led, FALSE );
+}
+
+static void cellmodem_t_set_ok( cellmodem_t *monitor )
+{
+    led_t_set_color( monitor->status_led, LED_GREEN );
+    led_t_set_flashing( monitor->status_led, FALSE );
+}
+
+static gboolean cellmodem_t_in_error_status( cellmodem_t *monitor )
+{
+    return monitor->modem_status == MODEM_ERROR;
+}
+
+static void cellmodem_t_switch_status( cellmodem_t *monitor,
+				      modem_status_t status )
+{
+    DEBUG("Switching modem status from %d to %d",
+          monitor->modem_status, status );
+
+    switch ( status ) {
+    case MODEM_ERROR:
+	cellmodem_t_set_error( monitor );
+        reschedule_open( monitor /*, TRUE*/ );
+	break;
+    case MODEM_WAIT_CSQ_RESPONSE:
+    case MODEM_WAIT_CPIN_RESPONSE:
+    case MODEM_WAIT_COPS_RESPONSE:
+    case MODEM_CLOSED:
+	//if ( cellmodem_t_in_error_status( monitor ) ) {
+            cellmodem_t_set_ok( monitor );
+	//}
+        /* Else skip */
+	break;
+    case MODEM_WAIT_CREG_RESPONSE:
+    case MODEM_WAIT_REGISTRATION:
+        break;
+    }
+
+    monitor->modem_status = status;
+}
+
+static void cellmodem_t_switch_network_status( cellmodem_t *monitor,
+					      registration_type_t status )
+{
+    switch (status) {
+    case REGISTRATION_UNKNOWN:
+	led_t_set_color( monitor->network_led, LED_YELLOW );
+	led_t_set_flashing( monitor->network_led, FALSE );
+	break;
+    case REGISTRATION_NOT_REGISTERED:
+	led_t_set_color( monitor->network_led, LED_RED );
+	led_t_set_flashing( monitor->network_led, TRUE );
+	break;
+    case REGISTRATION_REGISTERING:
+	led_t_set_color( monitor->network_led, LED_YELLOW );
+	led_t_set_flashing( monitor->network_led, TRUE );
+	break;
+    default:
+	led_t_set_color( monitor->network_led, LED_GREEN );
+	led_t_set_flashing( monitor->network_led, FALSE );
+    }
+
+    monitor->registration_status = status;
+}
+
+
+/*
+static void cellmodem_t_switch_status_i( cellmodem_t *monitor, modem_status_t status )
+{
+    monitor->modem_status = status;
+
+    if ( monitor->status_led == NULL )
+        return;
+
+    switch (status) {
+case MODEM_IDLE:
+    case MODEM_CLOSED:
+    case MODEM_OFFLINE:
+	led_t_set_color( monitor->status_led, LED_GREEN );
+	led_t_set_flashing( monitor->status_led, FALSE);
+
+	switch ( monitor->registration_status )
+	{
+	case REGISTRATION_REGISTERING:
+        case REGISTRATION_NOT_REGISTERED:
+	    led_t_set_color( monitor->network_led, LED_RED );
+	    led_t_set_flashing( monitor->network_led, TRUE);
+            break;
+	default:
+	    led_t_set_color( monitor->network_led, LED_GREEN );
+	    led_t_set_flashing( monitor->network_led, FALSE);
+	}
+
+	break;
+    case MODEM_ERROR:
+	led_t_set_color( monitor->status_led, LED_RED );
+	led_t_set_flashing( monitor->status_led, TRUE);
+	led_t_set_color( monitor->network_led, LED_OFF );
+        led_t_set_flashing( monitor->network_led, FALSE);
+
+
+	break;
+    }
+    cellmodem_t_set_tooltip_info( monitor );
+}
+*/
+/**
+ * @brief Check if buffer is an error reply from modem
+ *
+ * @param c The buffer to check
+ *
+ * @return TRUE if c starts with 'ERROR', FALSE otherwise
+ */
+
+static gboolean
+is_AT_error_reply( const gchar *c )
+{
+    return strcmp(c,"ERROR") == 0;
+}
+
+/**
+ * @brief Check if buffer is a success reply from modem
+ *
+ * @param c The buffer to check
+ *
+ * @return TRUE if c starts with 'OK', FALSE otherwise
+ */
+
+static gboolean
+is_AT_success_reply( const gchar *c )
+{
+    return strcmp(c,"OK") == 0;
+}
+/**
+ * @brief Remove leading characters from string
+ *
+ * This will remove all leading chars in string that match the parameter.
+ *
+ * @param buffer The string where to remove the characters
+ * @param c The character
+ *
+ * @return Nothing
+ */
+
+static void
+remove_leading_chars( char *buffer, char c )
+{
+    char *pos;
+    do {
+	pos = strchr( buffer, c);
+	if (pos)
+	    *pos=0;
+    } while (pos);
+}
+/**
+ * @brief Remove trailing characters from string
+ *
+ * This will remove all trailing chars in string that match the parameter.
+ *
+ * @param buffer The string where to remove the characters
+ * @param c The character
+ *
+ * @return Nothing
+ */
+
+static void
+remove_trailing_chars( char *buffer, char c )
+{
+    char *pos;
+    do {
+	pos = strchr( buffer, c);
+	if (pos)
+	    *pos=0;
+    } while (pos);
+}
+
+/**
+ * @brief Check if string is empty or contains only spaces
+ *
+ * @param buffer The string where to remove the characters
+ *
+ * @return TRUE if only space chars found, FALSE otherwise
+ */
+
+static gboolean
+is_only_spaces( const char *buffer )
+{
+    int i;
+
+    if ( strlen( buffer )==0 )
+	return TRUE;
+    
+    for (i=0; i<strlen(buffer); i++) {
+	if (buffer[i]!=' ')
+	    return FALSE;
+    }
+    return TRUE;
+}
+
+/**
+ * @brief [cellmodem_t method] Reset the internal RX buffer 
+ * @param monitor The cellmodem object
+ * @return Nothing
+ */
+
+static void cellmodem_t_reset_buffer( cellmodem_t *monitor )
+{
+    monitor->line_buffer_size = 0;
+}
+
+
+/*
+static void
+cellmodem_t_start_fetch_info( cellmodem_t *monitor )
+{
+    if (monitor->info_timeout_id >0 ) {
+        g_source_remove( monitor->info_timeout_id );
+        monitor->info_timeout_id=-1;
+    }
+    monitor->info_timeout_id = g_timeout_add(2 * 1000,
+					     (GSourceFunc) get_network_info,
+					     monitor
+					    );
+}
+
+*/
+
+/**
+ * @brief Set the plugin size
+ * DOCUMENT ME PLEASE
+ */
+
+static gboolean
+cellmodem_set_size(XfcePanelPlugin *plugin, int size, cellmodem_t *monitor)
+{
+    if (xfce_panel_plugin_get_orientation (plugin) == GTK_ORIENTATION_HORIZONTAL)
+    {
+	gtk_widget_set_size_request(GTK_WIDGET( monitor->qualpbar ),
+				    BORDER, size - 4);
+    }
+    else
+    {
+	gtk_widget_set_size_request(GTK_WIDGET( monitor->qualpbar ),
+				    size - 4, BORDER);
+    }
+    //setup_monitor(global, TRUE);
+
+    return TRUE;
+}
+
+
+/**
+ * @brief [cellmodem_t method] Setup the main widgets for the panel plugin
+ * @param monitor The cellmodem object
+ * @param destroy If true, destroy the already instanciated objects [will be deprecated]
+ */
+
+static void
+cellmodem_t_setup_widgets( cellmodem_t *monitor, gboolean destroy )
+{
+    monitor->status_led =
+	led_t_new();
+    monitor->network_led =
+	led_t_new();
+
+    led_t_set_color( monitor->status_led, LED_OFF );
+
+    led_t_set_color( monitor->network_led, LED_OFF );
+
+
+    /*   led_t_set_flashing( monitor->testled, TRUE );*/
+
+    GtkOrientation orientation =
+	xfce_panel_plugin_get_orientation(monitor->plugin);
+
+    monitor->tooltips = gtk_tooltips_new();
+    g_object_ref(monitor->tooltips);
+    gtk_object_sink(GTK_OBJECT(monitor->tooltips));
+
+    monitor->eventbox = gtk_event_box_new();
+    monitor->qualpbar = gtk_progress_bar_new();
+
+    if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+	gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(monitor->qualpbar),
+					 GTK_PROGRESS_BOTTOM_TO_TOP);
+
+	monitor->gbox = gtk_hbox_new(FALSE, 0);
+	monitor->box=gtk_hbox_new(FALSE, 0);
+    } else {
+	gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(monitor->qualpbar),
+					 GTK_PROGRESS_LEFT_TO_RIGHT);
+
+	monitor->gbox = gtk_vbox_new(FALSE, 0);
+	monitor->box=gtk_vbox_new(FALSE, 0);
+    }
+
+
+    gtk_container_set_border_width(GTK_CONTAINER(monitor->box), BORDER/2);
+
+    gtk_box_pack_start(GTK_BOX(monitor->box),
+		       GTK_WIDGET(monitor->qualpbar),
+		       FALSE, FALSE, 0);
+
+
+    /* LEDS */
+    GtkWidget *led_box;
+
+    if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+        led_box = gtk_vbox_new(FALSE,0);
+    } else {
+	led_box = gtk_hbox_new(FALSE,0);
+    }
+    
+
+    gtk_box_pack_start(GTK_BOX(led_box),
+		       GTK_WIDGET(monitor->status_led->image),
+		       FALSE, FALSE, 0);
+    gtk_widget_show( monitor->status_led->image );
+
+    gtk_box_pack_start(GTK_BOX(led_box),
+		       GTK_WIDGET(monitor->network_led->image),
+		       FALSE, FALSE, 0);
+    gtk_widget_show( monitor->network_led->image );
+
+    gtk_box_pack_start(GTK_BOX(monitor->box),
+                       led_box, FALSE,FALSE,0);
+
+    //gtk_container_set_border_width(GTK_CONTAINER(led_box), BORDER/2);
+    gtk_box_set_spacing(GTK_BOX(led_box), BORDER/4);
+
+
+    gtk_widget_show( led_box );
+
+    gtk_box_pack_start(GTK_BOX(monitor->gbox),
+		       GTK_WIDGET(monitor->box), FALSE, FALSE, 0);
+
+
+    gtk_widget_show( monitor->box );
+    gtk_widget_show( monitor->gbox );
+
+    gtk_widget_show( monitor->qualpbar );
+
+    gtk_container_add(GTK_CONTAINER(monitor->eventbox),
+		      GTK_WIDGET(monitor->gbox));
+
+    gtk_widget_show(monitor->eventbox);
+    gtk_widget_set_size_request(monitor->eventbox, -1, -1);
+
+}
+/**
+ * @brief [cellmodem_t CTOR] Create a new cellmodem object
+ * Creates the new cellmodem object, setting up some default values
+ *
+ * @param plugin The relevant XfcePanelPlugin
+ * @return The newly created cellmodem object
+ */
+
+static cellmodem_t *
+cellmodem_t_new(XfcePanelPlugin *plugin)
+{
+    cellmodem_t *monitor;
+
+    monitor = g_new0(cellmodem_t, 1);
+
+    monitor->plugin = plugin;
+
+    monitor->lastcmd = g_new( gchar, 128 );
+
+    monitor->options.modem_device = NULL;
+    monitor->options.critical_threshold = 20;
+    monitor->options.low_threshold = 40;
+    monitor->options.max_quality = MAX_QUAL;
+
+
+    /* Setup colors */
+
+    gdk_color_parse("#ff0000", &(monitor->red_color));
+    gdk_color_parse("#ffff00", &(monitor->yellow_color));
+    gdk_color_parse("#00ff00", &(monitor->green_color));
+
+    cellmodem_t_setup_widgets( monitor, FALSE );
+
+    cellmodem_t_switch_status( monitor, MODEM_ERROR );
+
+    cellmodem_t_switch_network_status(  monitor, REGISTRATION_UNKNOWN );
+
+    return monitor;
+}
+
+/**
+ * @brief [cellmodem_t member] Update tooltips according to status
+ *
+ * @param monitor The cellmodem object
+ */
+
+static void
+cellmodem_t_set_tooltip_info( cellmodem_t *monitor )
+{
+    gchar buffer[512];
+
+    gint qp = monitor->quality*100;
+    gint q = monitor->signal_strength;
+
+    if ( cellmodem_t_in_error_status ( monitor ) )
+    {
+        g_snprintf( buffer, 512, _("Modem not detected or modem error") );
+    }
+    else {
+	switch( monitor->registration_status )
+	{
+	case REGISTRATION_NOT_REGISTERED:
+	    g_snprintf(buffer, 512, _("Not registered"));
+	    break;
+	case REGISTRATION_REGISTERING:
+	    g_snprintf(buffer, 512, _("Registering"));
+	    break;
+	case REGISTRATION_GPRS:
+	    g_snprintf(buffer, 512, _("Registered [GPRS] to %s\nQuality: %d (%d%%)"), monitor->network, q,qp );
+            break;
+	case REGISTRATION_UMTS:
+	    g_snprintf(buffer, 512, _("Registered [UMTS] to %s\nQuality: %d (%d%%)"), monitor->network,q,qp );
+            break;
+	case REGISTRATION_HSDPA:
+	    g_snprintf(buffer, 512, _("Registered [HSDPA] to %s\nQuality: %d (%d%%)"), monitor->network,q,qp );
+	    break;
+	case REGISTRATION_UNKNOWN:
+	    g_snprintf(buffer, 512, _("Registered to %s\nQuality: %d (%d%%)"), monitor->network,q,qp);
+            break;
+	}
+    }
+
+    gtk_tooltips_set_tip (monitor->tooltips, monitor->eventbox, buffer, NULL);
+}
+
+
+/**
+ * @brief [cellmodem_t member] Set the quality bar color
+ *
+ * @param monitor The cellmodem object
+ * @param color The required GdkColor * color
+ */
+
+
+static void
+cellmodem_t_set_bar_color(cellmodem_t *monitor, GdkColor *color )
+{
+    gtk_widget_modify_bg( monitor->qualpbar, GTK_STATE_PRELIGHT, color );
+}
+
+/**
+ * @brief [cellmodem_t member] Update the progress bar
+ *
+ * @param monitor The cellmodem object
+ */
+
+
+static void
+cellmodem_t_update_progressbar( cellmodem_t *monitor )
+{
+    gint qual = (gint)(100.0*monitor->quality);
+
+    if ( monitor->registration_status == REGISTRATION_NOT_REGISTERED ) {
+	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(monitor->qualpbar), 0.0 );
+	cellmodem_t_set_bar_color( monitor, NULL );
+    }
+    else {
+
+	if( qual <= monitor->options.critical_threshold ) {
+	    cellmodem_t_set_bar_color( monitor, &(monitor->red_color) );
+	}
+	else if( qual <= monitor->options.low_threshold ) {
+	    cellmodem_t_set_bar_color( monitor, &(monitor->yellow_color) );
+	}
+	else {
+	    cellmodem_t_set_bar_color( monitor, &(monitor->green_color) );
+	}
+    }
+
+    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(monitor->qualpbar), monitor->quality );
+
+}
+/**
+ * @brief [cellmodem_t member] Update the monitors
+ *
+ * This will update the progressbar and the tooltips
+ *
+ * @param monitor The cellmodem object
+ */
+
+static void
+cellmodem_t_update_monitors( cellmodem_t *monitor )
+{
+    cellmodem_t_set_tooltip_info( monitor );
+    cellmodem_t_update_progressbar( monitor );
+}
+
+/**
+ * @brief [cellmodem_t DTOR] Destroy the cellmodem object
+ *
+ * @param monitor The cellmodem object
+ *
+ * @return Nothing
+ */
+
+static void
+cellmodem_t_delete(cellmodem_t *monitor)
+{
+    DEBUG("Destroying cellmodem object");
+    cellmodem_t_close_modem( monitor /*, TRUE*/ );
+
+    g_object_unref (monitor->tooltips);
+
+    g_free( monitor->lastcmd );
+
+    g_free(monitor);
+}
+
+/**
+ * @brief [cellmodem_t member] Close the modem channel
+ *
+ * @param monitor The cellmodem object
+ *
+ * @return TRUE if modem sucessfuly closed, FALSE if not opened or error
+ */
+
+static gboolean
+cellmodem_t_close_modem(cellmodem_t *monitor  /*, gboolean failure */)
+{
+    if (NULL == monitor->modem_instance)
+	return FALSE;
+
+    if (NULL == monitor->driver)
+	return FALSE;
+
+    DEBUG("Closing modem, driver at %p\n", monitor->driver);
+
+    monitor->driver->close(monitor->modem_instance);
+
+    DEBUG("Modem closed");
+    /*
+     if ( failure )
+	cellmodem_t_switch_status( monitor, MODEM_ERROR );
+    */
+    return TRUE;
+}
+
+static void pin_callback( const gchar *pin, void *pvt )
+{
+    cellmodem_t *monitor = (cellmodem_t *)pvt;
+
+    cellmodem_t_send_pin( monitor, pin );
+}
+
+static void
+cellmodem_t_request_pin( cellmodem_t *monitor )
+{
+    if ( monitor->options.ask_for_pin )
+	pin_helper_launch( GTK_WIDGET(monitor->plugin), pin_callback, monitor );
+    else {
+	cellmodem_t_switch_status( monitor, MODEM_CLOSED );
+
+	reschedule_open( monitor /*, FALSE*/ );
+	 /*
+	  led_t_set_color( monitor->status_led, LED_YELLOW );
+	  led_t_set_flashing( monitor->status_led, TRUE );
+	  */
+    }
+}
+
+
+/**
+ * @brief [cellmodem_t pseudo-member] Callback for registration request
+ *
+ * @param success TRUE if modem replied OK, FALSE otherwise
+ * @param response GString with modem response
+ * @param pvt Pointer to cellmodem object
+ *
+ * pvt will be deferenced to cellmodem object upon calling. No typechecking is done.
+ *
+ *
+ * @return Nothing
+ */
+
+static void
+cellmodem_t_registration_callback(gboolean success, GString *response, void *pvt)
+{
+    cellmodem_t *monitor = (cellmodem_t*)pvt;
+
+    if ( !success || response==NULL || response->str==NULL ) {
+	/* Error */
+	DEBUG("Modem error detected (%p)", pvt);
+	cellmodem_t_switch_status( monitor, MODEM_ERROR );
+	return;
+    }
+    DEBUG("Got registration callback: %s", response->str);
+    if ( strncmp( response->str ,"+CREG: ", 7 )==0 ) {
+
+	gchar *start = response->str + 7;
+	if ( strtok( start, ",") == NULL) {
+	    cellmodem_t_switch_status( monitor, MODEM_ERROR );
+	    return;
+	}
+	gchar *delim = strtok ( NULL, "," );
+
+	int i = atoi( delim );
+
+	DEBUG("Registration reply: %d", i);
+
+	switch (i) {
+	case 1:
+
+	    /* We only should switch status here after +COPS response */
+
+	    cellmodem_t_switch_network_status( monitor, REGISTRATION_UNKNOWN );
+	    break;
+	case 2:
+	    cellmodem_t_switch_network_status( monitor, REGISTRATION_REGISTERING );
+	    break;
+	default:
+	    cellmodem_t_switch_network_status( monitor, REGISTRATION_NOT_REGISTERED );
+            break;
+	}
+    } else {
+	DEBUG("Modem error in reply");
+	cellmodem_t_switch_status( monitor, MODEM_ERROR );
+    }
+
+    //cellmodem_t_set_tooltip_info( monitor );
+
+    if ( monitor->registration_status != REGISTRATION_NOT_REGISTERED  &&
+         monitor->registration_status != REGISTRATION_REGISTERING ) {
+
+	cellmodem_t_identify_network( monitor );
+
+    } else {
+	/* Check for PIN ????? */
+	// Ask pin.
+
+	//if (monitor->options.ask_for_pin)
+	cellmodem_t_get_pin_status( monitor );
+	/*else
+	 reschedule_open( monitor, FALSE );
+	 */
+    }
+}
+/**
+ * @brief [cellmodem_t pseudo-member] Callback for network id request
+ *
+ * @param success TRUE if modem replied OK, FALSE otherwise
+ * @param response GString with modem response
+ * @param pvt Pointer to cellmodem object
+ *
+ * pvt will be deferenced to cellmodem object upon calling. No typechecking is done.
+ *
+ * @return Nothing
+ */
+
+static void
+cellmodem_t_identify_callback(gboolean success, GString *response, void *pvt)
+{
+    cellmodem_t *monitor = (cellmodem_t*)pvt;
+
+    if ( !success || response==NULL || response->str==NULL ) {
+	/* Error */
+        DEBUG("Modem error detected (%p)", pvt);
+	cellmodem_t_switch_status( monitor, MODEM_ERROR );
+        reschedule_open( monitor );
+        return;
+    }
+
+    /* +COPS: 0,0,"Provider",2 */
+    if ( strncmp(response->str,"+COPS: ", 7 )==0 ) {
+	// Extract info
+	gchar *start = response->str + 7;
+	gchar *tok[64];
+	int i=0;
+
+	tok[i++] = strtok( start, ",");
+	while ( ( tok[i++]=strtok(NULL,",")) ) {};
+
+	DEBUG("Network: '%s'\n", tok[2]);
+	DEBUG("Network Type: '%s'\n", tok[3]);
+
+	if ( monitor->network )
+	    g_free( monitor->network );
+
+	if (tok[2][0]=='"') {
+	    monitor->network = g_strndup( tok[2]+1, strlen(tok[2])-2 );
+	} else {
+	    monitor->network = g_strdup( tok[2] );
+	}
+
+	if ( monitor->registration_status != REGISTRATION_NOT_REGISTERED )
+	{
+	    int type = atoi(tok[3]);
+
+	    switch (type) {
+	    case 0:
+		cellmodem_t_switch_network_status( monitor, REGISTRATION_GPRS );
+		break;
+	    case 2:
+		cellmodem_t_switch_network_status( monitor, REGISTRATION_UMTS );
+		break;
+	    default:
+		cellmodem_t_switch_network_status( monitor, REGISTRATION_UNKNOWN );
+	    }
+	}
+    } else {
+	cellmodem_t_switch_network_status( monitor, REGISTRATION_NOT_REGISTERED );
+
+        cellmodem_t_switch_status( monitor, MODEM_ERROR );
+	reschedule_open( monitor /*, TRUE*/ );
+        return;
+    }
+
+    cellmodem_t_get_quality( monitor );
+}
+
+/**
+ * @brief [cellmodem_t pseudo-member] Callback for PIN status request
+ *
+ * @param success TRUE if modem replied OK, FALSE otherwise
+ * @param response GString with modem response
+ * @param pvt Pointer to cellmodem object
+ *
+ * pvt will be deferenced to cellmodem object upon calling. No typechecking is done.
+ *
+ * @return Nothing
+ */
+
+static void
+cellmodem_t_pin_callback(gboolean success, GString *response, void *pvt)
+{
+    cellmodem_t *monitor = (cellmodem_t*)pvt;
+    gboolean failure = FALSE;
+
+    if ( !success || response==NULL || response->str==NULL ) {
+	/* Error */
+        DEBUG("Modem error detected (%p)", pvt);
+	cellmodem_t_switch_status( monitor, MODEM_ERROR );
+        reschedule_open( monitor );
+        return;
+    }
+
+    /* +CPIN: SIM PIN */
+    /* +CPIN: OK */
+
+    if ( strncmp(response->str,"+CPIN: ", 7 )==0 ) {
+	// Extract info
+	gchar *start = response->str + 7;
+	DEBUG("CPIN: '%s'", start);
+	if ( strncmp( start, "SIM PIN", 7) == 0) {
+	    /* If we can ask for pin, we do */
+
+	    if ( monitor->options.ask_for_pin ) {
+		cellmodem_t_request_pin( monitor );
+                return ;
+	    }
+	}
+	if ( strncmp( start, "OK", 2) == 0 )
+	{
+	    /* If we got here, we are registering. Do nothing, just
+	     reschedule open */
+	} else {
+            failure = TRUE;
+	}
+
+        /* Errors found ?? . */
+
+
+    }
+    if ( failure )
+        cellmodem_t_switch_status( monitor, MODEM_ERROR );
+
+    reschedule_open( monitor /*, failure */);
+}
+
+
+static void
+cellmodem_t_setpin_callback(gboolean success, GString *response, void *pvt)
+{
+    cellmodem_t *monitor = (cellmodem_t*)pvt;
+
+    if ( !success ) {
+	/* Error */
+        DEBUG("Modem error detected (%p)", pvt);
+	cellmodem_t_switch_status( monitor, MODEM_ERROR );
+        reschedule_open( monitor );
+        return;
+    }
+
+    /* TODO: We should recheck if PIN was accepted */
+
+
+
+    /* Just try to reopen. */
+
+    reschedule_open( monitor /*, FALSE*/ );
+}
+
+
+/**
+ * @brief [cellmodem_t pseudo-member] Callback for quality request
+ *
+ * @param success TRUE if modem replied OK, FALSE otherwise
+ * @param response GString with modem response
+ * @param pvt Pointer to cellmodem object
+ *
+ * pvt will be deferenced to cellmodem object upon calling. No typechecking is done.
+ *
+ * @return Nothing
+ */
+
+static void
+cellmodem_t_quality_callback(gboolean success, GString *response, void *pvt)
+{
+    cellmodem_t *monitor = (cellmodem_t*)pvt;
+
+    if ( strncmp( response->str ,"+CSQ: ", 6 )==0 ) {
+	// Extract info
+	gchar *start = response->str + 6;
+	if ( strtok( start, ",") == NULL) {
+	    // Error
+	    return;/* FALSE;*/
+	}
+	strtok ( NULL, "," );
+	DEBUG("Qual: '%s'\n", start );
+
+	int i = atoi( start );
+	monitor->signal_strength = i;
+	monitor->quality = (double)i/ (double)monitor->options.max_quality;
+	if (monitor->quality>1.0)
+	    monitor->quality=1.0;
+
+        cellmodem_t_update_monitors( monitor );
+    }
+    DEBUG("Got quality, restarting");
+    /* cellmodem_t_close_modem( monitor, FALSE ); - reschedule will close */
+    cellmodem_t_switch_status( monitor, MODEM_CLOSED );
+    reschedule_open( monitor /*, FALSE*/ );
+}
+
+/**
+ * @brief [cellmodem_t member] Request registration status from modem
+ *
+ * @param monitor The cellmodem object
+ *
+ * This is asynchronous. Pseudo-method "cellmodem_t_registration_callback" will
+ * be called when modem replies.
+ *
+ * @return Nothing
+ */
+
+static void
+cellmodem_t_is_registered( cellmodem_t *monitor )
+{
+    cellmodem_t_send_at_command(monitor, &cellmodem_t_registration_callback, "+CREG?" );
+    cellmodem_t_switch_status( monitor, MODEM_WAIT_CREG_RESPONSE );
+}
+
+/**
+ * @brief [cellmodem_t member] Request network id from modem
+ *
+ * @param monitor The cellmodem object
+ *
+ * This is asynchronous. Pseudo-method "cellmodem_t_identify_callback" will
+ * be called when modem replies.
+ *
+ * This should only be called when we are sure we are registered to some
+ * network, by using "cellmodem_t_is_registered".
+ *
+ * @return Nothing
+ */
+
+static void
+cellmodem_t_identify_network( cellmodem_t *monitor )
+{
+    cellmodem_t_send_at_command(monitor, &cellmodem_t_identify_callback, "+COPS?" );
+    cellmodem_t_switch_status( monitor, MODEM_WAIT_COPS_RESPONSE );
+
+}
+
+/**
+ * @brief [cellmodem_t member] Request signal quality from modem
+ *
+ * @param monitor The cellmodem object
+ *
+ * This is asynchronous. Pseudo-method "cellmodem_t_quality_callback" will
+ * be called when modem replies.
+ *
+ * This should only be called when we are sure we are registered to some
+ * network.
+ *
+ * @return Nothing
+ */
+
+static void
+cellmodem_t_get_quality( cellmodem_t *monitor )
+{
+    cellmodem_t_send_at_command(monitor, &cellmodem_t_quality_callback, "+CSQ" );
+    cellmodem_t_switch_status( monitor, MODEM_WAIT_CSQ_RESPONSE );
+}
+
+/**
+ * @brief [cellmodem_t member] Request PIN status from modem
+ *
+ * @param monitor The cellmodem object
+ *
+ * This is asynchronous. Pseudo-method "cellmodem_t_pin_callback" will
+ * be called when modem replies.
+ *
+ * This should only be called when we are sure we are NOT registered to some
+ * network.
+ *
+ * @return Nothing
+ */
+
+static void
+cellmodem_t_get_pin_status( cellmodem_t *monitor )
+{
+    cellmodem_t_send_at_command(monitor, &cellmodem_t_pin_callback, "+CPIN?" );
+    cellmodem_t_switch_status( monitor, MODEM_WAIT_CPIN_RESPONSE );
+
+}
+
+
+static void
+cellmodem_t_send_pin( cellmodem_t *monitor, const gchar *pin )
+{
+    GString *g = g_string_new("+CPIN=");
+    g_string_append( g, pin );
+    cellmodem_t_send_at_command(monitor, &cellmodem_t_setpin_callback, g->str );
+    g_string_free( g, TRUE );
+
+    cellmodem_t_switch_status( monitor, MODEM_WAIT_REGISTRATION );
+
+}
+
+
+/**
+ * @brief [cellmodem_t member] Handle modem response
+ *
+ * This method will dispatch the appropriate pseudo-member callback. The reply
+ * MUST be a single line replied from the modem. Call this function for each
+ * line you receive from modem.
+ *
+ * @param monitor The cellmodem object
+ * @param buffer The reply from modem
+ *
+ * @return TRUE [TBD when FALSE]
+ */
+
+static gboolean
+cellmodem_t_modem_handle_response( cellmodem_t *monitor, char *buffer )
+{
+    DEBUG("In handle response");
+
+    if ( monitor->resp.reply_callback == NULL ) {
+        DEBUG("No callback defined!!!!");
+        return TRUE; /* No registered listener. */
+    }
+    if ( monitor->resp.reply_buffer == NULL )
+    {
+	monitor->resp.reply_buffer = g_string_new( NULL ); // Initialize to NULL
+    }
+
+    /* Remove trailing \r and \n */
+
+    remove_leading_chars(buffer,'\n');
+    remove_leading_chars(buffer,'\r');
+    remove_trailing_chars(buffer,'\r');
+    remove_trailing_chars(buffer,'\n');
+
+    /* See if it is echo */
+
+    if ( strcmp( monitor->lastcmd , buffer ) == 0 ) {
+	DEBUG("Echo detected, skipping");
+	return TRUE;
+    }
+
+    /* Ignore empty lines */
+
+    if ( is_only_spaces( buffer ) ) {
+        DEBUG("Only spaces found in reply, skipping");
+	return TRUE;
+    }
+
+    DEBUG("Got response: '%s' command '%s'\n", buffer, monitor->lastcmd);
+
+    cellmodem_t_cancel_pending_at_command_timeout( monitor );
+
+    if ( is_AT_error_reply( buffer ) ) {
+
+	monitor->resp.reply_callback( FALSE,
+				     monitor->resp.reply_buffer,
+				     monitor->resp.reply_pvt );
+	DEBUG("Free reply data");
+
+        g_string_free( monitor->resp.reply_buffer, TRUE );
+        monitor->resp.reply_buffer = NULL;
+
+	//monitor->resp.reply_callback = NULL;
+        DEBUG("Done handling error");
+	return TRUE;
+    }
+
+    if ( is_AT_success_reply( buffer ) ) {
+        DEBUG("Got AT OK reply");
+	monitor->resp.reply_callback( TRUE,
+		       monitor->resp.reply_buffer,
+		       monitor->resp.reply_pvt );
+
+	g_string_free( monitor->resp.reply_buffer, TRUE );
+        monitor->resp.reply_buffer = NULL;
+
+	//monitor->resp.reply_callback = NULL;
+        
+	return TRUE;
+    }
+
+    g_string_append( monitor->resp.reply_buffer, buffer );
+    g_string_append( monitor->resp.reply_buffer, "\n" );
+
+    DEBUG("Finished handling");
+    return TRUE;
+}
+
+
+/**
+ * @brief [cellmodem_t pseudo-member] Handle modem response direcly from the driver
+ *
+ * The driver will call this pseudo-method when data arrives at the
+ * modem channel.
+ *
+ * @param chan The modem channel
+ * @param c The IO condition ( G_IO_IN )
+ * @param data The cellmodem object
+ *
+ * 'data' will be deferenced to cellmodem object. No typechecking is done.
+ *
+ * The reply from modem are handled by the appropriate method set up when
+ * "cellmodem_t_send_at_command" was called.
+ *
+ * @return TRUE if correctly handled, FALSE if not.
+ *
+ */
+
+
+static gboolean
+cellmodem_t_modem_callback(GIOChannel *chan, GIOCondition c, gpointer data )
+{
+    cellmodem_t *monitor = (cellmodem_t*)data;
+    /* Data ready */
+    DEBUG("Data from modem ready, IO cond %d, data %p", c, data);
+    gsize length;
+    GError *error = NULL;
+    GIOStatus status;
+    gboolean r;
+
+    if ( chan == NULL )
+    {
+	DEBUG("NULL channel!!!");
+        return FALSE;
+    }
+
+    DEBUG("Line buffer size before reading: %d", monitor->line_buffer_size);
+
+
+    status = g_io_channel_read_chars(
+				     chan,
+				     monitor->line_buffer + (monitor->line_buffer_size),
+				     8192-(monitor->line_buffer_size),
+				     &length,
+				     &error
+				    );
+    if ( status == G_IO_STATUS_AGAIN ) {
+        usleep(10000);
+	return TRUE;
+    }
+
+    if (status != G_IO_STATUS_NORMAL ) {
+	DEBUG("Error reading from modem");
+	//: '%s'\n",error->message );
+        cellmodem_t_switch_status( monitor, MODEM_ERROR );
+	cellmodem_t_close_modem( monitor /*, TRUE*/ );
+	return FALSE;
+    }
+
+
+    monitor->line_buffer_size+=length;
+    monitor->line_buffer[ monitor->line_buffer_size ] = 0;
+
+    DEBUG("Read %d bytes from modem: '%s'", length, monitor->line_buffer);
+    DEBUG("Buffer size now %d", monitor->line_buffer_size );
+    char *eol;
+    do {
+	eol = memchr( monitor->line_buffer, '\n', monitor->line_buffer_size);
+	DEBUG("EOL: from %p -> %p",monitor->line_buffer, eol);
+	if ( eol!=NULL ) {
+            DEBUG("Handling command from modem");
+	    size_t dist = eol-monitor->line_buffer;
+	    gchar * line = g_strndup( monitor->line_buffer, dist+1 );
+	    line[dist+1]=0;
+	    memmove(monitor->line_buffer, eol+1, (monitor->line_buffer_size)-dist-1 );
+	    monitor->line_buffer_size-=dist+1;
+	    DEBUG("Calling handle response");
+	    r = cellmodem_t_modem_handle_response( monitor, line );
+	    g_free( line );
+	    if (!r)
+		return r;
+	} else {
+	    DEBUG("No newline in modem reply, waiting");
+	}
+    } while (eol);
+    return TRUE;
+}
+
+/**
+ * @brief [cellmodem_t member] Send an AT (ATtention) command to modem
+ *
+ * @param monitor The cellmodem object
+ * @param callback The callback which is to be called when modem replies.
+ * @param command The AT command (without the 'AT' prefix and without CR/LF)
+ *
+ * This will call the modem driver to send the command to the modem. The pvt
+ * field will be set to the cellmodem object.
+ *
+ * @return TRUE if correctly sent, FALSE if not.
+ *
+ */
+
+static gboolean
+cellmodem_t_send_at_command( cellmodem_t *monitor,
+			    modem_reply_callback_t callback,
+			    const gchar *command  )
+{
+
+    monitor->resp.reply_callback = callback;
+    monitor->resp.reply_pvt = monitor;
+
+    DEBUG("Callback set to %p", callback );
+
+    snprintf(monitor->lastcmd, 128, "AT%s", command );
+
+    /* TODO - check if we already have a timeout */
+
+    monitor->at_timeout_id =
+	g_timeout_add( 1000,
+		      (GSourceFunc) cellmodem_t_at_command_timeout,
+		      monitor );
+
+    if ( monitor->driver->writeln(
+				  monitor->modem_instance,
+				  monitor->lastcmd
+				 ) == FALSE )
+    {
+	DEBUG("ERROR Command: '%s'\n", monitor->lastcmd );
+        cellmodem_t_switch_status( monitor, MODEM_ERROR );
+        cellmodem_t_close_modem( monitor /*, TRUE*/ );
+        return FALSE;
+    }
+    /* Remove CR LF */
+     //monitor->lastcmd[ strlen(monitor->lastcmd) - 2 ] = 0;
+
+    DEBUG("Sent command to modem: '%s'\n", monitor->lastcmd);
+    
+    return TRUE;
+}
+
+
+static gboolean
+cellmodem_t_at_command_timeout( cellmodem_t *monitor )
+{
+    monitor->at_timeout_id = -1;
+    DEBUG("Modem failed to reply");
+    cellmodem_t_switch_status( monitor, MODEM_ERROR );
+    reschedule_open( monitor /*, TRUE*/ );
+    return FALSE;
+}
+
+static void
+cellmodem_t_cancel_pending_at_command_timeout( cellmodem_t *monitor )
+{
+    if (monitor->at_timeout_id > 0) {
+        g_source_remove ( monitor->at_timeout_id );
+    }
+    monitor->at_timeout_id = -1;
+}
+
+
+static gboolean
+cellmodem_t_open_modem(cellmodem_t *monitor)
+{
+    if ( NULL == monitor->driver ) {
+	cellmodem_t_switch_status( monitor, MODEM_ERROR );
+	return FALSE;
+    }
+
+    if ( NULL == monitor->modem_instance ) {
+        cellmodem_t_switch_status( monitor, MODEM_ERROR );
+	return FALSE;
+    }
+
+    if ( monitor->driver->open( monitor->modem_instance,
+			        &monitor->options ) == FALSE )
+    {
+        DEBUG("Cannot open modem");
+        cellmodem_t_switch_status( monitor, MODEM_ERROR );
+	return FALSE;
+    }
+    /* cellmodem_t_switch_status( monitor, MODEM_IDLE ); */
+    cellmodem_t_reset_buffer( monitor );
+
+    monitor->driver->set_reader( monitor->modem_instance,
+				 cellmodem_t_modem_callback,
+				 monitor);
+
+    return TRUE;
+}
+
+
+static gboolean
+reschedule_open( cellmodem_t *monitor /*, gboolean failure*/ )
+{
+    cellmodem_t_close_modem( monitor /*, failure*/ );
+
+    if ( monitor->info_timeout_id > 0 )
+    {
+        g_source_remove( monitor->info_timeout_id );
+    }
+
+    monitor->info_timeout_id = g_timeout_add( OPEN_TIMEOUT,
+					     (GSourceFunc) get_network_info ,
+					     monitor );
+
+    return FALSE; /* Cancel this timer */
+}
+
+
+/**
+ * This will be called from a timer (but at startup)
+ */
+
+static gboolean
+get_network_info( cellmodem_t *monitor )
+{
+    DEBUG("Getting network info");
+    if ( cellmodem_t_open_modem( monitor ) != FALSE ) {
+
+	//    if ( monitor->modem_status == MODEM_IDLE ) {
+	cellmodem_t_is_registered( monitor );
+	return FALSE; /* Dont restart timer. */
+	//}
+    }
+    DEBUG("Cannot open modem");
+    cellmodem_t_switch_status( monitor, MODEM_ERROR );
+
+    return reschedule_open(monitor /*, FALSE*/ );
+}
+
+
+/*
+ Configuration stuff
+ */
+
+static void
+cellmodem_read_config(XfcePanelPlugin *plugin, cellmodem_t *monitor)
+{
+    char *file;
+    const char *text;
+    XfceRc *rc;
+
+    if (!(file = xfce_panel_plugin_lookup_rc_file (plugin))) {
+	DEBUG("No config file found\n");
+	return;
+    }
+
+    rc = xfce_rc_simple_open (file, TRUE);
+    g_free (file);
+
+    if (!rc) {
+	DEBUG("Cannot open config file\n");
+
+	return;
+    }
+
+    monitor->options.display_tooltip_info =
+	xfce_rc_read_bool_entry (rc, "display_tooltip_info", FALSE);
+
+
+    if ( NULL != monitor->options.modem_device )
+	    g_free( monitor->options.modem_device );
+
+    text =  xfce_rc_read_entry (rc, "modem_device", NULL);
+    if (NULL!=text && *text) {
+	monitor->options.modem_device = g_strdup (text);
+    } else {
+
+	monitor->options.modem_device = NULL;
+    }
+
+    if ( NULL != monitor->options.modem_driver )
+	g_free( monitor->options.modem_driver );
+
+    text =  xfce_rc_read_entry (rc, "modem_driver", NULL);
+    if (NULL!=text && *text) {
+	monitor->options.modem_driver = g_strdup (text);
+    } else {
+	monitor->options.modem_driver = NULL;
+    }
+
+
+    monitor->options.low_threshold = xfce_rc_read_int_entry( rc, "low_threshold", 40 );
+    monitor->options.critical_threshold = xfce_rc_read_int_entry( rc, "critical_threshold", 20 );
+    monitor->options.max_quality = xfce_rc_read_int_entry( rc, "max_quality", MAX_QUAL );
+
+
+    xfce_rc_close (rc);
+
+}
+
+
+void
+cellmodem_write_config(XfcePanelPlugin *plugin, cellmodem_t *monitor)
+{
+    XfceRc *rc;
+    char *file;
+
+    DEBUG("Saving configuration");
+
+    if (!(file = xfce_panel_plugin_save_location (plugin, TRUE))) {
+        DEBUG("Cannot save configuration!");
+	return;
+    }
+    
+    rc = xfce_rc_simple_open (file, FALSE);
+    g_free (file);
+
+
+    if (!rc) {
+        DEBUG("Cannot open configuration file to save!");
+	return;
+    }
+    
+    xfce_rc_write_bool_entry (rc, "display_tooltip_info",
+			      monitor->options.display_tooltip_info);
+
+    xfce_rc_write_entry (rc, "modem_device",
+			 monitor->options.modem_device );
+    xfce_rc_write_entry (rc, "modem_driver",
+			 monitor->options.modem_driver );
+
+    xfce_rc_write_int_entry( rc, "low_threshold", monitor->options.low_threshold );
+    xfce_rc_write_int_entry( rc, "critical_threshold", monitor->options.critical_threshold );
+    xfce_rc_write_int_entry( rc, "max_quality", monitor->options.max_quality );
+
+    DEBUG("Done saving configuration");
+    xfce_rc_close (rc);
+}
+
+
+void
+cellmodem_t_initialize_modem( cellmodem_t *monitor )
+{
+    DEBUG("Initializing modem");
+
+    cellmodem_t_switch_status( monitor, MODEM_ERROR );
+
+    if ( monitor->options.modem_driver == NULL ) {
+        DEBUG("No driver defined, skipping");
+	return;
+    }
+
+    /* TODO: Skip if we already have this driver loaded */
+
+    if ( monitor->driver != NULL && monitor->modem_instance != NULL ) {
+        DEBUG("Closing already created driver/instance");
+	monitor->driver->close( monitor->modem_instance );
+	monitor->driver->destroy( monitor->modem_instance );
+        monitor->modem_instance = NULL;
+    }
+
+    monitor->driver = NULL;
+
+    monitor->driver = find_driver_by_name( monitor->options.modem_driver );
+
+    if (monitor->driver==NULL) {
+	DEBUG("Cannot find that driver (%s)!!!", monitor->options.modem_driver);
+	cellmodem_t_switch_status( monitor, MODEM_ERROR );
+	return;
+    }
+
+    DEBUG("Modem driver at %p", monitor->driver);
+    monitor->modem_instance =
+	monitor->driver->create();
+
+    DEBUG("Modem instance created");
+
+    cellmodem_t_switch_status( monitor, MODEM_WAIT_CREG_RESPONSE );
+
+    get_network_info(monitor);
+
+}
+
+#ifdef DEBUG_ENABLED
+
+int init_logging()
+{
+    openlog("cellmodem", LOG_PID, LOG_USER );
+
+    return 0;
+}
+
+char logbuf[8192];
+
+#endif
+/* create the plugin */
+
+static void
+cellmodem_t_construct (XfcePanelPlugin *plugin)
+{
+    cellmodem_t *monitor;
+
+    xfce_textdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+#ifdef DEBUG_ENABLED
+    init_logging();
+#endif
+
+    DEBUG("Creating applet\n");
+    monitor = cellmodem_t_new (plugin);
+
+    DEBUG("Reading config\n");
+    cellmodem_read_config (plugin, monitor);
+    cellmodem_t_initialize_modem( monitor );
+
+    cellmodem_t_update_monitors( monitor );
+
+    g_signal_connect (plugin, "free-data", G_CALLBACK (cellmodem_t_delete), monitor);
+
+    g_signal_connect (plugin, "save", G_CALLBACK (cellmodem_write_config), monitor);
+    g_signal_connect (plugin, "size-changed", G_CALLBACK (cellmodem_set_size), monitor);
+
+    xfce_panel_plugin_menu_show_configure (plugin);
+    g_signal_connect (plugin, "configure-plugin", G_CALLBACK (cellmodem_create_options), monitor);
+
+    gtk_container_add(GTK_CONTAINER(plugin), monitor->eventbox);
+
+}
+
+XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL (cellmodem_t_construct);

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.desktop.in.in
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.desktop.in.in	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.desktop.in.in	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,8 @@
+[Xfce Panel]
+Type=X-XFCE-PanelPlugin
+Encoding=UTF-8
+_Name=Cellular Modem Monitor
+_Comment=Monitor line quality and type of Cellular Modems
+Icon=xfce-mouse
+X-XFCE-Exec=@PLUGIN_PATH@/xfce4-cellmodem-plugin
+

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.h
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.h	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem.h	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __CELLMODEM_H__
+#define __CELLMODEM_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "cellmodem.h"
+#include "modem_driver.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+
+#include "leds.h"
+
+#define DEBUG_ENABLED
+
+#ifdef DEBUG_ENABLED
+#include <syslog.h>
+
+extern int init_logging();
+extern char logbuf[8192];
+
+#endif
+
+/* Check every 10 seconds */
+
+#define OPEN_TIMEOUT (10000)
+
+
+
+#ifdef DEBUG_ENABLED
+#define DEBUG(x...) do { char *tmp=logbuf; tmp+=sprintf(logbuf,"%s [%d] : ", __FUNCTION__, __LINE__); \
+    tmp+=sprintf(tmp,x); \
+    sprintf(tmp,"\n"); \
+    syslog(LOG_DEBUG, "%s", logbuf ); \
+    } while (0)
+#else
+#define DEBUG(x...)
+#endif
+
+#define MAX_QUAL 20
+#define BORDER 8
+
+typedef void (*modem_reply_callback_t)( gboolean success, GString *response, void  *pvt);
+
+#if 0
+
+typedef enum {
+    MODEM_OFFLINE,
+    MODEM_IDLE,
+    MODEM_CLOSED,
+    MODEM_ERROR
+} modem_status_t;
+
+#endif
+
+
+typedef enum {
+    MODEM_ERROR,
+    MODEM_WAIT_CPIN_RESPONSE,
+    MODEM_WAIT_CREG_RESPONSE,
+    MODEM_WAIT_COPS_RESPONSE,
+    MODEM_WAIT_CSQ_RESPONSE,
+    MODEM_WAIT_REGISTRATION,
+    MODEM_CLOSED
+} modem_status_t;
+
+typedef enum {
+    REGISTRATION_UNKNOWN,
+    REGISTRATION_NOT_REGISTERED,
+    REGISTRATION_REGISTERING,
+    REGISTRATION_GPRS,
+    REGISTRATION_UMTS,
+    REGISTRATION_HSDPA
+} registration_type_t;
+
+
+typedef struct
+{
+    modem_reply_callback_t reply_callback;
+    void *reply_pvt;
+    GString *reply_buffer;
+} modem_response_data_t;
+
+typedef struct
+{
+    XfcePanelPlugin *plugin;
+    GtkTooltips     *tooltips;
+    GtkWidget       *eventbox;
+    GtkWidget       *box, *gbox;
+    GtkWidget       *qualpbar;
+    led_t           *status_led;
+    led_t           *network_led;
+    /* Colors */
+    GdkColor        red_color, yellow_color, green_color;
+    /* IO Stuff */
+    /*gint            modem_watcher_cb_id;*/
+//    GIOChannel      *modem_channel;
+    modem_driver_t  *driver;
+    modem_instance_t  *modem_instance;
+    gchar           line_buffer[8192];
+    size_t          line_buffer_size;
+
+
+    /* User options */
+    cellmodem_options_t options;
+
+
+    /* Modem stuff */
+    modem_status_t modem_status;
+    registration_type_t registration_status;
+    gfloat quality;
+    gint signal_strength;
+    gchar *lastcmd;
+    gchar *network;
+
+    modem_response_data_t resp;
+
+    gint info_timeout_id;
+    gint at_timeout_id;
+} cellmodem_t;
+
+
+
+#endif
+

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem_options.h
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem_options.h	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/cellmodem_options.h	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __CELLMODEM_OPTIONS_H__
+#define __CELLMODEM_OPTIONS_H__
+
+#include <glib.h>
+
+typedef struct
+{
+    gboolean  display_tooltip_info;
+    gchar     *modem_device;
+    gchar     *modem_driver;
+    gchar     *ppp_peer;
+    gboolean  ask_for_pin;
+    gint      low_threshold;
+    gint      critical_threshold;
+    gint      max_quality;
+} cellmodem_options_t;
+
+#endif

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/leds.c
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/leds.c	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/leds.c	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "leds.h"
+#include "big_leds.xpm"
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "cellmodem.h"
+
+static gboolean leds_initialized = FALSE;
+
+static GdkPixbuf *whole_leds;
+static GSList *flashing_leds;
+static gint flash_timer;
+
+static int led_h_size = 8;
+static int led_v_size = 8;
+
+#define NUMBER_OF_LEDS 4
+
+GdkPixbuf *pixleds[NUMBER_OF_LEDS];
+
+static gboolean initialize_leds()
+{
+    int i;
+
+    whole_leds = gdk_pixbuf_new_from_xpm_data( (const char**)big_leds_xpm );
+    if (whole_leds == NULL)
+	return FALSE;
+
+    // cut individual leds.
+
+    for (i=0; i<NUMBER_OF_LEDS; i++) {
+	pixleds[i] =
+	    gdk_pixbuf_new_subpixbuf( whole_leds,
+				     i*led_h_size,
+				     0,
+				     led_h_size,
+                                     led_v_size);
+    }
+
+    /* Initialize the list */
+
+    flashing_leds = NULL;
+
+    leds_initialized = TRUE;
+    return TRUE;
+}
+
+static gboolean do_flash_leds( gpointer data )
+{
+    g_slist_foreach( flashing_leds,
+		   (GFunc)led_t_flip_flash,
+                   NULL );
+
+    return TRUE;
+}
+
+
+void led_t_flip_flash( led_t *led, gpointer data )
+{
+    if ( ! led->flashing )
+	return;
+
+    led->flash_on = ~(led->flash_on);
+
+    if ( led->flash_on ) {
+	gtk_image_set_from_pixbuf( GTK_IMAGE(led->image), pixleds[ (int)led->color ]);
+    } else {
+	gtk_image_set_from_pixbuf( GTK_IMAGE(led->image), pixleds[ LED_OFF ]);
+    }
+}
+
+led_t *led_t_new()
+{
+    led_t *led = g_new0( led_t, 1 );
+
+    led->image = gtk_image_new();
+
+    if ( leds_initialized == FALSE )
+        initialize_leds();
+
+    return led;
+}
+
+void led_t_set_color( led_t *led, led_color_t color )
+{
+    led->color = color;
+    gtk_image_set_from_pixbuf( GTK_IMAGE(led->image), pixleds[ (int)color ]);
+}
+
+
+void led_t_set_flashing( led_t *led, gboolean flashing )
+{
+    if (  (led->flashing ^ flashing ) == 0 )
+	return; /* Already in that state */
+
+    led->flashing = flashing;
+
+    if ( flashing )
+    {
+	/* Add to the list */
+
+	flashing_leds = g_slist_append( flashing_leds,
+				       ( gpointer ) led );
+
+	if ( flash_timer <= 0 )
+	{
+	    flash_timer = g_timeout_add( 500,
+					(GSourceFunc) do_flash_leds,
+					NULL );
+	}
+    } else {
+	flashing_leds = g_slist_remove( flashing_leds,
+				       ( gconstpointer ) led );
+
+	if (g_slist_length( flashing_leds ) == 0) {
+            g_source_remove( flash_timer );
+            flash_timer = -1;
+	}
+	gtk_image_set_from_pixbuf( GTK_IMAGE(led->image), pixleds[ (int)led->color ]);
+    }
+
+}
+
+
+void  led_t_destroy( led_t *led )
+{
+    g_object_unref( G_OBJECT( led->image ) );
+    /* Remove from flashing list */
+    if (led->flashing) {
+        led_t_set_flashing( led, FALSE );
+    }
+    g_free( led );
+}
+

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/leds.h
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/leds.h	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/leds.h	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __LEDS_H__
+#define __LEDS_H__
+
+#include <gtk/gtk.h>
+
+typedef enum
+{
+    LED_OFF = 2,
+    LED_GREEN = 1,
+    LED_RED = 0,
+    LED_YELLOW = 3
+} led_color_t;
+
+typedef struct
+{
+    GtkWidget *image;
+    gboolean flashing;
+    led_color_t color;
+    gboolean flash_on;
+} led_t;
+
+
+
+led_t *led_t_new();
+void led_t_set_color( led_t *led, led_color_t color );
+void led_t_set_flashing( led_t *led, gboolean flashing );
+void led_t_destroy( led_t *led );
+void led_t_flip_flash( led_t *led , gpointer data );
+
+
+
+#endif

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver.c
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver.c	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver.c	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "modem_driver.h"
+#include <string.h>
+
+#ifdef HAVE_FAKE_MODEM
+#include "modem_driver_fake.h"
+#endif
+
+#include "modem_driver_generic.h"
+
+/**
+ * @brief Find the appropriate driver by its name
+ *
+ * @param name The driver's name
+ *
+ * @returns NULL if no driver found, the driver instance otherwise
+ *
+ */
+
+modem_driver_t *find_driver_by_name( const gchar *name )
+{
+    int idx;
+    for (idx=0; drivers[idx]; idx++) {
+	if ( strcmp( name, drivers[idx]->name )==0 )
+            return drivers[idx];
+    }
+    return NULL;
+}
+
+/**
+ * @brief Find the appropriate driver by its index
+ *
+ * @param name The driver's index (0...)
+ *
+ * @returns NULL if no driver found, the driver instance otherwise
+ * @bugs Currently no bound checking is done.
+ *
+ */
+
+modem_driver_t *find_driver_by_index( const int idx )
+{
+    /* TODO: Check bounds */
+
+    return drivers[idx];
+}
+
+/**
+ * @brief Find the appropriate driver index by its name
+ *
+ * @param name The driver's name
+ *
+ * @returns -1 if no driver found, the driver index in table otherwise
+ *
+ */
+
+int find_driver_index_by_name( const gchar *name )
+{
+    int idx;
+    for (idx=0; drivers[idx]; idx++) {
+	if ( strcmp( name, drivers[idx]->name )==0 )
+            return idx;
+    }
+    return -1;
+}
+
+/** The driver registry.
+ ** All drivers must register here, or they won't be visible.
+ */
+
+
+modem_driver_t *drivers[] = {
+    &modem_driver_generic,
+#ifdef HAVE_FAKE_MODEM
+    &modem_driver_fake,
+    NULL
+#endif
+};

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver.h
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver.h	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver.h	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MODEMDRIVER_H__
+#define __MODEMDRIVER_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define HAVE_FAKE_MODEM 1
+
+#include <glib.h>
+#include "cellmodem_options.h"
+
+typedef void * modem_instance_t;
+
+typedef struct modem_driver_t
+{
+    const gchar *name;
+    const gchar *description;
+
+    /* Methods */
+
+    modem_instance_t (*create)( );
+    gboolean (*open)( modem_instance_t instance, cellmodem_options_t *options );
+    gboolean (*writeln)( modem_instance_t instance, const gchar *data );
+    void (*close)( modem_instance_t instance );
+    gboolean (*set_reader)( modem_instance_t instance, GIOFunc reader, gpointer data );
+
+    void (*destroy)( modem_instance_t instance );
+
+} modem_driver_t;
+
+
+modem_driver_t *find_driver_by_name( const gchar *name );
+modem_driver_t *find_driver_by_index( const int idx );
+int find_driver_index_by_name( const gchar *name );
+
+extern modem_driver_t *drivers[];
+
+#endif

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_fake.c
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_fake.c	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_fake.c	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "modem_driver_fake.h"
+#include "cellmodem.h"
+#include <errno.h> /* Maybe non-portable */
+#include <sys/time.h>
+
+static guint32 get_current_time()
+{
+    // we should use g_date_get_julian();
+    struct timeval tv;
+    gettimeofday( &tv,NULL );
+    return tv.tv_sec;
+}
+
+static gboolean send_reply( struct fake_modem_t *modem )
+{
+    gsize written;
+    GError *error = NULL;
+    DEBUG("Sending modem reply: %s", modem->reply->str );
+    if ( g_io_channel_write_chars( modem->channel,
+				  modem->reply->str,
+				  strlen(modem->reply->str),
+				  &written,
+				  &error
+				 ) != G_IO_STATUS_NORMAL )
+    {
+	/* Close channel */
+        DEBUG("Error writing response, closing modem channel");
+	g_io_channel_unref( modem->channel );
+        modem->channel = NULL;
+	return FALSE;
+    }
+
+
+    g_io_channel_flush( modem->channel, &error );
+
+    /* TODO - Check also written bytes */
+
+    if ( modem->reader != NULL )
+	modem->reader( modem->channel, G_IO_IN, modem->reader_pvt );
+
+    return FALSE;
+}
+
+
+static gboolean queue_reply( struct fake_modem_t *modem )
+{
+    g_timeout_add(1,
+		  (GSourceFunc)send_reply,
+		  modem
+		 );
+    return TRUE;
+}
+
+
+static void
+reply_ok( struct fake_modem_t *modem, const gchar *string )
+{
+    g_string_append( modem->reply, string);
+    g_string_append( modem->reply, "\r\nOK\r\n" );
+    queue_reply( modem );
+}
+
+static gboolean fake_handle_command( struct fake_modem_t *modem, const char *data )
+{
+    const char *cmd;
+
+    if ( strlen( data ) < 3 ) {
+        DEBUG("Short command");
+        return queue_reply(modem);  /* Not AT command, too short */
+    }
+
+    if ( ! g_str_has_prefix( data, "AT") ) {
+        DEBUG("Not AT Command");
+        return queue_reply(modem); /* Not AT command */
+    }
+    cmd = data + 2;
+
+    DEBUG("Cmd: %s", cmd );
+
+    // Add newlines
+
+    g_string_append(modem->reply,"\r\n");
+
+    if ( strncmp( cmd, "+CREG?", 6)==0) {
+	DEBUG("PIN time: %u, this time %u", modem->pin_time, get_current_time() );
+	if ( modem->valid_pin )
+
+	    if (  get_current_time() > modem->pin_time + REGISTRATION_TIME ) {
+		reply_ok( modem, "+CREG: 0,1" );
+	    } else {
+		reply_ok( modem, "+CREG: 0,2" );
+	    }
+	else
+            reply_ok( modem, "+CREG: 0,0" );
+        return TRUE;
+    }
+    if ( strncmp( cmd, "+COPS?", 6)==0) {
+	reply_ok( modem,  "+COPS: 0,0,\"Testing network\",2" );
+        return TRUE;
+    }
+
+    if ( strncmp( cmd, "+CSQ", 4)==0) {
+	reply_ok( modem,  "+CSQ: 15,0" );
+        return TRUE;
+    }
+
+    if ( strncmp( cmd, "+CPIN?", 6)==0) {
+        if ( modem->valid_pin )
+	    reply_ok( modem,  "+CPIN: OK" );
+	else
+            reply_ok( modem,  "+CPIN: SIM PIN" );
+        return TRUE;
+    }
+
+    if ( strncmp( cmd, "+CPIN=", 6)==0) {
+	if (! modem->valid_pin) {
+            modem->pin_time = get_current_time();
+	}
+        modem->valid_pin = TRUE;
+	g_string_append( modem->reply, "OK\r\n" );
+	queue_reply( modem );
+	return TRUE;
+    }
+
+    /* Queue error for now */
+    g_string_append( modem->reply, "ERROR\r\n" );
+    queue_reply( modem );
+
+    return FALSE;
+}
+
+static gboolean fake_open( modem_instance_t instance, cellmodem_options_t *options  )
+{
+    /* Tricky - we need to set up a pipe
+     otherwise we won't be able to speak
+     with the core plugin */
+    struct fake_modem_t *modem = (struct fake_modem_t*)instance;
+    const gchar *tempdir = "/tmp";
+    GString *pipename;
+    GError *error = NULL;
+
+    DEBUG("Opening fake modem");
+
+    pid_t mypid = getpid();
+
+    pipename = g_string_new( "" );
+
+    g_string_printf( pipename, "%s/fakemodem-%d-pipe", tempdir, mypid );
+
+    if ( mkfifo( pipename->str, 0600 ) != 0 )
+    {
+        DEBUG("Cannot create pipe!!!");
+        g_string_free( pipename, TRUE );
+        return FALSE;
+    }
+
+    int fd = open( pipename->str, O_RDWR| O_EXCL);
+
+    if (fd<0) {
+	/* Unlink fifo */
+        DEBUG("Cannot open pipe!!!");
+	unlink(pipename->str);
+	g_string_free( pipename, TRUE );
+	return FALSE;
+    }
+
+    modem->channel = g_io_channel_unix_new( fd );
+
+    if ( modem->channel == NULL )
+    {
+        DEBUG("Cannot opem modem channel!!!");
+	while (close( fd )<0 && errno==EINTR );
+	unlink( pipename->str );
+	g_string_free( pipename, TRUE );
+	return FALSE;
+    }
+    g_io_channel_set_encoding( modem->channel, NULL, &error );
+    error=NULL;
+    g_io_channel_set_flags( modem->channel, G_IO_FLAG_NONBLOCK, &error );
+
+    g_io_channel_set_close_on_unref( modem->channel, TRUE );
+
+    unlink( pipename->str );  /* Not needed any more. The inode will stay there */
+    g_string_free( pipename, TRUE );
+
+    DEBUG("Modem opened (pipe)");
+
+    if ( ! options->ask_for_pin ) {
+	modem->valid_pin = TRUE;
+	if ( modem->pin_time == 0 )
+	    modem->pin_time = get_current_time(); /* So we can "register" */
+    }
+
+    return TRUE;
+}
+
+static void fake_close( modem_instance_t instance )
+{
+    struct fake_modem_t *modem = (struct fake_modem_t*)instance;
+
+    if ( modem == NULL ) {
+	DEBUG("Closing a NULL instance????");
+        return;
+    }
+    if ( modem->channel != NULL ) {
+	g_io_channel_unref( modem->channel );
+        modem->channel = NULL;
+    } else {
+        DEBUG("Modem channel already closed!");
+    }
+}
+
+static gboolean fake_writeln( modem_instance_t instance, const gchar *data )
+{
+    struct fake_modem_t *modem = (struct fake_modem_t*)instance;
+
+    /* Free up the string if already allocated */
+    if ( modem->reply != NULL )
+    {
+        g_string_free( modem->reply, TRUE );
+    }
+
+    if ( data == NULL )
+	return FALSE; /* NULL data, return error */
+
+    modem->reply = g_string_new( data ); /* For echoing the command */
+
+    DEBUG("Got command: %s", data );
+
+    return fake_handle_command( instance , data );
+
+}
+
+
+static gboolean fake_set_reader( modem_instance_t instance, GIOFunc reader, gpointer data )
+{
+    struct fake_modem_t *modem = (struct fake_modem_t*)instance;
+
+    modem->reader = reader;
+    modem->reader_pvt = data;
+
+    DEBUG("Data set to %p", data );
+
+    return TRUE;
+}
+
+static modem_instance_t fake_create( )
+{
+    struct fake_modem_t *modem = g_new( struct fake_modem_t , 1);
+    modem->reply = NULL;
+    modem->reader = NULL;
+
+    modem->valid_pin = FALSE;
+    modem->pin_time = 0;
+    return (modem_instance_t)modem;
+}
+
+static void fake_destroy( modem_instance_t modem )
+{
+    g_free( modem );
+}
+
+
+struct modem_driver_t modem_driver_fake =
+{
+    .name = "Testing Driver",
+    .description = "Simple Driver for Testing Purposes",
+    .open = &fake_open,
+    .close = &fake_close,
+    .writeln = &fake_writeln,
+    .set_reader = &fake_set_reader,
+    .create = &fake_create,
+    .destroy = &fake_destroy
+};

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_fake.h
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_fake.h	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_fake.h	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MODEMDRIVERFAKE_H__
+#define __MODEMDRIVERFAKE_H__
+
+#include "modem_driver.h"
+
+struct fake_modem_t
+{
+    GString *reply;
+    GIOFunc reader;
+    void *reader_pvt;
+    GIOChannel *channel;
+    gboolean valid_pin;
+    guint32 pin_time;
+};
+
+#define REGISTRATION_TIME 40 /* 40 seconds registration */
+
+extern struct modem_driver_t modem_driver_fake;
+
+#endif

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_generic.c
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_generic.c	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_generic.c	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "modem_driver_generic.h"
+#include "cellmodem.h"
+#include <errno.h> /* Maybe non-portable */
+#include <termios.h>
+
+
+static gboolean generic_open( modem_instance_t instance, cellmodem_options_t *options  )
+{
+    struct generic_modem_t *modem = (struct generic_modem_t*)instance;
+    GError *error = NULL;
+    struct termios tio;
+
+    DEBUG("Opening modem");
+    if ( options->modem_device == NULL ) {
+        DEBUG("Modem device is null, returning");
+	return FALSE;
+    }
+
+    int fd = open( options->modem_device, O_RDWR|O_EXCL);
+
+    if (fd<0) {
+        DEBUG("Cannot open modem!!!");
+	return FALSE;
+    }
+
+    tcgetattr( fd, &tio );
+
+    cfmakeraw( &tio );
+
+    tio.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | PARENB);
+    tio.c_cflag |= ( B115200 | CS8 | CREAD | CLOCAL );
+
+    tcsetattr( fd, TCSANOW , &tio);
+
+    modem->channel = g_io_channel_unix_new( fd );
+
+    if ( modem->channel == NULL )
+    {
+        DEBUG("Cannot opem modem channel!!!");
+	while (close( fd )<0 && errno==EINTR );
+	return FALSE;
+    }
+    g_io_channel_set_encoding( modem->channel, NULL, &error );
+    error=NULL;
+    g_io_channel_set_flags( modem->channel, G_IO_FLAG_NONBLOCK, &error );
+
+    g_io_channel_set_close_on_unref( modem->channel, TRUE );
+
+    DEBUG("Modem successfully opened");
+
+    return TRUE;
+}
+
+static void generic_close( modem_instance_t instance )
+{
+    struct generic_modem_t *modem = (struct generic_modem_t*)instance;
+
+    if ( modem == NULL ) {
+	DEBUG("Closing a NULL instance????");
+        return;
+    }
+    if ( modem->channel != NULL ) {
+	if ( modem->reader >= 0 ) {
+	    g_source_remove( modem->reader );
+            modem->reader = -1;
+	}
+
+	g_io_channel_unref( modem->channel );
+        modem->channel = NULL;
+    } else {
+        DEBUG("Modem channel already closed!");
+    }
+}
+
+static gboolean generic_writeln( modem_instance_t instance, const gchar *data )
+{
+    struct generic_modem_t *modem = (struct generic_modem_t*)instance;
+    gsize written, bytes_to_write, bw;
+    GError *error = NULL;
+    GString *g = g_string_new( data );
+
+    GIOStatus status;
+
+    if (modem==NULL) {
+	DEBUG("Null modem instance!");
+        return FALSE;
+    }
+
+    if (modem->channel==NULL) {
+	DEBUG("Null modem channel!");
+        return FALSE;
+    }
+
+    g_string_append( g, "\r\n" );
+
+    bytes_to_write = strlen( g->str );
+    written = 0;
+
+    DEBUG("Writing command to modem, size %d", bytes_to_write);
+
+    do {
+	status = g_io_channel_write_chars( modem->channel,
+					  g->str + written,
+					  bytes_to_write - written,
+					  &bw,
+					  &error
+					 );
+	DEBUG("Write status: %d, written %d", status, bw);
+	if ( status == G_IO_STATUS_AGAIN ) {
+            usleep(10000);
+            error = NULL;
+	} else {
+	    if (status == G_IO_STATUS_NORMAL) {
+		written += bw;
+                //bytes_to_write;
+	    } else {
+                break;
+	    }
+	}
+
+
+    } while ( status == G_IO_STATUS_AGAIN || written<bytes_to_write );
+
+    if ( status != G_IO_STATUS_NORMAL )
+    {
+
+
+	/* Close channel */
+	DEBUG("Error writing ro modem, closing modem channel");
+	if (error && error->message ) {
+	    DEBUG("Error message: '%s'", error->message );
+	}
+
+        g_string_free( g, TRUE );
+	g_io_channel_unref( modem->channel );
+	modem->channel = NULL;
+	return FALSE;
+    }
+
+    g_string_free( g, TRUE );
+
+    g_io_channel_flush( modem->channel, &error );
+
+    return TRUE;
+}
+
+
+static gboolean generic_set_reader( modem_instance_t instance, GIOFunc reader, gpointer data )
+{
+    struct generic_modem_t *modem = (struct generic_modem_t*)instance;
+
+    /*modem->reader = reader;
+    modem->reader_pvt = data;
+
+    DEBUG("Data set to %p", data );
+    */
+
+    if ( modem->reader >= 0)
+    {
+        g_source_remove( modem->reader );
+    }
+
+    modem->reader = g_io_add_watch( modem->channel,
+				   G_IO_IN,
+				   reader,
+				   data );
+
+    return TRUE;
+}
+
+static modem_instance_t generic_create( )
+{
+    struct generic_modem_t *modem = g_new( struct generic_modem_t , 1);
+    modem->reader = -1;
+    return (modem_instance_t)modem;
+}
+
+static void generic_destroy( modem_instance_t modem )
+{
+    g_free( modem );
+}
+
+
+struct modem_driver_t modem_driver_generic =
+{
+    .name = "Generic Driver",
+    .description = "Generic PCMCIA/PCCARD Driver",
+    .open = &generic_open,
+    .close = &generic_close,
+    .writeln = &generic_writeln,
+    .set_reader = &generic_set_reader,
+    .create = &generic_create,
+    .destroy = &generic_destroy
+};

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_generic.h
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_generic.h	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/modem_driver_generic.h	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MODEMDRIVERGENERIC_H__
+#define __MODEMDRIVERGENERIC_H__
+
+#include "modem_driver.h"
+
+struct generic_modem_t
+{
+    gint reader;
+//    void *reader_pvt;
+    GIOChannel *channel;
+};
+
+extern struct modem_driver_t modem_driver_generic;
+
+#endif

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/pin_helper.c
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/pin_helper.c	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/pin_helper.c	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "pin_helper.h"
+
+static void
+pin_helper_pin_entry_callback( GtkDialog *dlg, int response, pin_dialog_t *dialog )
+{
+    if ( response == GTK_RESPONSE_ACCEPT ) {
+
+	const gchar *pin = gtk_entry_get_text( GTK_ENTRY(dialog->entry) );
+
+	if (!pin || strlen(pin)!=4 )
+	{
+	    // Error.
+	    xfce_warn(_("Invalid PIN entered. PIN has 4 digits"));
+
+            return;
+	}
+
+        /* cellmodem_t_send_pin( dialog->monitor, pin ); */
+        dialog->cb( pin, dialog->pvt );
+
+
+    } else {
+	/*
+	 now what???????
+
+	 Wait for user to get to preferences again.
+
+	*/
+
+    }
+
+    gtk_widget_destroy( GTK_WIDGET(dlg) );
+    g_free( dialog );
+}
+
+void pin_helper_launch( GtkWidget *parent, pin_helper_callback cb, void *pvt )
+{
+    GtkWidget *vbox;
+    GtkWidget *label;
+    pin_dialog_t *dialog;
+
+    dialog = g_new0( pin_dialog_t, 1 );
+
+    dialog->pvt = pvt;
+    dialog->cb = cb;
+
+    dialog->dlg = gtk_dialog_new_with_buttons ( _("Enter PIN"),
+					       GTK_WINDOW( gtk_widget_get_toplevel( parent ) ),
+					       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+					       GTK_STOCK_OK,
+					       GTK_RESPONSE_ACCEPT,
+					       GTK_STOCK_CANCEL,
+					       GTK_RESPONSE_REJECT,
+					       NULL
+					      );
+
+    vbox = gtk_vbox_new( FALSE, BORDER );
+    gtk_widget_show( vbox );
+    label = gtk_label_new( _("Please enter PIN:") );
+    gtk_widget_show( label );
+
+    gtk_box_pack_start( GTK_BOX(vbox), label, FALSE, FALSE, 0 );
+
+    gtk_box_pack_start( GTK_BOX( GTK_DIALOG(dialog->dlg)->vbox ), vbox, FALSE, FALSE, 0);
+
+    dialog->entry = gtk_entry_new_with_max_length( 4 );
+    gtk_entry_set_visibility( GTK_ENTRY( dialog->entry ), FALSE );
+
+    gtk_widget_show( dialog->entry );
+
+    gtk_box_pack_start( GTK_BOX(vbox), dialog->entry, FALSE, FALSE, 0 );
+
+
+
+    /* Connect close and response */
+
+    g_signal_connect (dialog->dlg, "close", G_CALLBACK (gtk_widget_destroy), dialog);
+    g_signal_connect (dialog->dlg, "response", G_CALLBACK (pin_helper_pin_entry_callback), dialog);
+
+    gtk_widget_show( dialog->dlg );
+}

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/pin_helper.h
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/pin_helper.h	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/pin_helper.h	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __PIN_HELPER_H__
+#define __PIN_HELPER_H__
+
+#include "cellmodem.h"
+
+typedef void (*pin_helper_callback)( const gchar *pin, void *pvt );
+
+typedef struct pin_dialog_t
+{
+    GtkWidget *entry;
+    GtkWidget *dlg;
+    pin_helper_callback cb;
+    void *pvt;
+} pin_dialog_t;
+
+
+
+void pin_helper_launch( GtkWidget *parent, pin_helper_callback callback, void *pvt );
+
+
+#endif

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/preferences.c
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/preferences.c	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/preferences.c	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "preferences.h"
+#include "modem_driver.h"
+
+static void
+cellmodem_t_dialog_response( GtkWidget *dlg, int response, cellmodem_t *monitor )
+{
+    /* Set default driver if none is still defined */
+
+    if (monitor->options.modem_driver == NULL) {
+	monitor->options.modem_driver =
+	    g_strdup( find_driver_by_index( 0 )->name );
+	DEBUG("Setting driver to default entry ('%s')",
+              monitor->options.modem_driver );
+    }
+
+    gtk_widget_destroy (dlg);
+    xfce_panel_plugin_unblock_menu (monitor->plugin);
+
+    cellmodem_write_config (monitor->plugin, monitor);
+
+    /* Reconfigure everything */
+
+    cellmodem_t_initialize_modem( monitor );
+}
+
+
+static void
+update_dialog( cellmodem_dialog_t *dialog )
+{
+    int idx;
+    cellmodem_t *monitor = dialog->monitor;
+
+    if ( monitor->options.modem_device != NULL )
+	gtk_entry_set_text( GTK_ENTRY(dialog->device_entry),
+			   monitor->options.modem_device);
+
+    if (monitor->options.modem_driver != NULL) {
+	idx = find_driver_index_by_name( monitor->options.modem_driver );
+    } else {
+	idx=0;
+    //    monitor->options.modem_driver = find_driver_by_index( idx );
+
+    }
+
+    if (idx<=0)
+	idx=0;
+
+    gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->driver_entry),idx);
+
+
+
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->low_entry),
+			      monitor->options.low_threshold);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->critical_entry),
+			      monitor->options.critical_threshold);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->maxqual_entry),
+			      monitor->options.max_quality);
+
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->ask_pin_entry),
+				 monitor->options.ask_for_pin);
+
+}
+
+
+static void
+cb_device_entry_changed(GtkEntry *entry, cellmodem_dialog_t *dialog)
+{
+    if ( dialog->monitor->options.modem_device != NULL )
+	g_free( dialog->monitor->options.modem_device );
+
+    dialog->monitor->options.modem_device = NULL;
+            
+    const gchar *text =
+	gtk_entry_get_text( entry );
+
+    if ( text && strlen( text ) > 0 ) {
+	dialog->monitor->options.modem_device = g_strdup( text );
+	DEBUG("Modem device: '%s'", text);
+    }
+}
+
+
+static void
+cb_pin_entry_toggled(GtkToggleButton *entry, cellmodem_dialog_t *dialog)
+{
+    dialog->monitor->options.ask_for_pin = gtk_toggle_button_get_active(entry);
+}
+
+static void
+cb_driver_entry_changed(GtkComboBox *combo, cellmodem_dialog_t *dialog)
+{
+    modem_driver_t *driver;
+    int idx;
+
+    if ( dialog->monitor->options.modem_driver != NULL )
+	g_free( dialog->monitor->options.modem_driver );
+
+    dialog->monitor->options.modem_driver = NULL;
+
+    idx = gtk_combo_box_get_active( combo );
+
+
+    driver = find_driver_by_index( idx );
+
+    if (!driver)
+	return; /* ????? */
+
+    dialog->monitor->options.modem_driver = g_strdup( driver->name );
+}
+
+
+static void
+cb_maxqual_entry_changed(GtkSpinButton *button, cellmodem_dialog_t *dialog)
+{
+    dialog->monitor->options.max_quality =
+	gtk_spin_button_get_value_as_int( button );
+    DEBUG("Max qual: %d",
+	  dialog->monitor->options.max_quality);
+}
+
+static void
+cb_low_entry_changed(GtkSpinButton *button, cellmodem_dialog_t *dialog)
+{
+    dialog->monitor->options.low_threshold =
+        gtk_spin_button_get_value_as_int( button );
+}
+
+static void
+cb_critical_entry_changed(GtkSpinButton *button, cellmodem_dialog_t *dialog)
+{
+    dialog->monitor->options.critical_threshold =
+        gtk_spin_button_get_value_as_int( button );
+}
+
+void
+cellmodem_create_options(XfcePanelPlugin *plugin, cellmodem_t *monitor)
+{
+    GtkWidget *dlg;
+    GtkWidget *header;
+    GtkWidget *vbox;
+    GtkWidget *vbox2;
+    GtkSizeGroup *sizegr;
+    GtkWidget *hbox;
+    GtkWidget *label;
+
+    cellmodem_dialog_t *dialog;
+
+    dialog = g_new0(cellmodem_dialog_t, 1);
+
+    dialog->monitor = monitor;
+
+    xfce_panel_plugin_block_menu (plugin);
+    
+    dlg = gtk_dialog_new_with_buttons (_("Configure Cell Modem Monitor"),
+                GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (plugin))),
+                GTK_DIALOG_DESTROY_WITH_PARENT |
+                GTK_DIALOG_NO_SEPARATOR,
+                GTK_STOCK_CLOSE, GTK_RESPONSE_OK,
+                NULL);
+    
+    g_signal_connect (dlg, "response", G_CALLBACK (cellmodem_t_dialog_response),
+                      monitor);
+
+
+    /* The header - this was most copied from other sources*/
+
+    header = xfce_create_header (NULL, _("Cellular Modem Monitor"));
+    gtk_widget_set_size_request (GTK_BIN (header)->child, -1, 32);
+    gtk_container_set_border_width (GTK_CONTAINER (header), BORDER - 2);
+    gtk_widget_show (header);
+    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), header,
+                        FALSE, TRUE, 0);
+
+    /* Our own Vbox, so we can have a border */
+
+    vbox = gtk_vbox_new(FALSE, BORDER);
+    gtk_container_set_border_width (GTK_CONTAINER (vbox), BORDER - 2);
+    gtk_widget_show(vbox);
+    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), vbox,
+                        TRUE, TRUE, 0);
+
+    /* Saw this nice one in other plugin */
+    sizegr = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+#define MAKEHBOX( name ) \
+    name = gtk_hbox_new(FALSE, BORDER); \
+    gtk_widget_show(name);\
+    gtk_box_pack_start(GTK_BOX(vbox), name, FALSE, FALSE, 0)
+
+#define MAKELABEL( name, text ) \
+    name = gtk_label_new(text); \
+    gtk_size_group_add_widget(sizegr, name); \
+    gtk_misc_set_alignment(GTK_MISC(name), 0, 0.5); \
+    gtk_widget_show( name )
+
+
+    MAKEHBOX( hbox );
+    MAKELABEL( label, _("Modem driver:") );
+    gtk_box_pack_start( GTK_BOX(hbox), label, 0, FALSE, FALSE );
+    /* Create a combo with the drivers */
+
+    dialog->driver_entry = gtk_combo_box_new_text();
+
+
+    int idx;
+
+    for (idx=0; drivers[idx]; idx++)
+    {
+	gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->driver_entry), drivers[idx]->description);
+    }
+
+    gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->driver_entry),0);
+
+    gtk_box_pack_start( GTK_BOX(hbox), dialog->driver_entry, 0, FALSE, FALSE );
+    gtk_widget_show( dialog->driver_entry );
+
+    g_signal_connect(dialog->driver_entry, "changed", G_CALLBACK(cb_driver_entry_changed), dialog);
+
+    MAKEHBOX( hbox );
+    MAKELABEL( label, _("Modem device:") );
+
+    gtk_box_pack_start( GTK_BOX(hbox), label, 0, FALSE, FALSE );
+   
+    dialog->device_entry = gtk_entry_new();
+    gtk_widget_show(dialog->device_entry);
+    gtk_box_pack_start(GTK_BOX(hbox), dialog->device_entry, FALSE, FALSE, 0);
+
+    g_signal_connect(dialog->device_entry, "changed", G_CALLBACK(cb_device_entry_changed), dialog);
+
+
+
+    MAKEHBOX( hbox );
+    MAKELABEL( label, _("Maximum quality:") );
+    gtk_box_pack_start( GTK_BOX(hbox), label, 0, FALSE, FALSE );
+
+    dialog->maxqual_entry = gtk_spin_button_new_with_range(1, 100, 1);
+    gtk_widget_show(dialog->maxqual_entry);
+    gtk_box_pack_start(GTK_BOX(hbox), dialog->maxqual_entry, FALSE, FALSE, 0);
+
+    g_signal_connect(dialog->maxqual_entry, "value-changed", G_CALLBACK(cb_maxqual_entry_changed), dialog);
+
+
+    MAKEHBOX( hbox );
+    MAKELABEL( label, _("Low quality percentage:") );
+    gtk_box_pack_start( GTK_BOX(hbox), label, 0, FALSE, FALSE );
+
+    dialog->low_entry = gtk_spin_button_new_with_range(1, 100, 1);
+    gtk_widget_show(dialog->low_entry);
+    gtk_box_pack_start(GTK_BOX(hbox), dialog->low_entry, FALSE, FALSE, 0);
+
+    g_signal_connect(dialog->low_entry, "value-changed", G_CALLBACK(cb_low_entry_changed), dialog);
+
+    MAKEHBOX( hbox );
+    MAKELABEL( label, _("Critical quality percentage:") );
+    gtk_box_pack_start( GTK_BOX(hbox), label, 0, FALSE, FALSE );
+
+    dialog->critical_entry = gtk_spin_button_new_with_range(1, 100, 1);
+    gtk_widget_show(dialog->critical_entry);
+    gtk_box_pack_start(GTK_BOX(hbox), dialog->critical_entry, FALSE, FALSE, 0);
+
+    g_signal_connect(dialog->critical_entry, "value-changed", G_CALLBACK(cb_critical_entry_changed), dialog);
+
+
+    /* Toggle buttons. */
+
+    MAKEHBOX( hbox );
+
+    vbox2 = gtk_vbox_new(FALSE, 0);
+    gtk_widget_show(vbox2);
+    gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 0);
+
+    dialog->ask_pin_entry = gtk_check_button_new_with_mnemonic( _("Ask for PIN if needed") );
+    gtk_box_pack_start( GTK_BOX(hbox), dialog->ask_pin_entry, 0, FALSE, FALSE );
+    gtk_widget_show( dialog->ask_pin_entry );
+
+    g_signal_connect(dialog->ask_pin_entry, "toggled", G_CALLBACK(cb_pin_entry_toggled), dialog);
+
+
+
+
+    update_dialog( dialog );
+
+
+    gtk_widget_show( dlg );
+}

Added: xfce4-cellmodem-plugin/trunk/panel-plugin/preferences.h
===================================================================
--- xfce4-cellmodem-plugin/trunk/panel-plugin/preferences.h	                        (rev 0)
+++ xfce4-cellmodem-plugin/trunk/panel-plugin/preferences.h	2006-09-25 19:39:23 UTC (rev 2070)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2006 Alvaro Lopes <alvieboy at alvie.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __PREFERENCES_H__
+#define __PREFERENCES_H__
+
+#include "cellmodem.h"
+
+typedef struct
+{
+    GtkWidget *device_entry;
+    GtkWidget *driver_entry;
+    GtkWidget *low_entry;
+    GtkWidget *critical_entry;
+    GtkWidget *maxqual_entry;
+    GtkWidget *ask_pin_entry;
+    cellmodem_t *monitor;
+} cellmodem_dialog_t;
+
+void
+cellmodem_create_options(XfcePanelPlugin *plugin, cellmodem_t *monitor);
+
+#endif




More information about the Goodies-commits mailing list