[Goodies-commits] r6501 - in xfce4-radio-plugin/trunk: . panel-plugin

Stefan Ott cockroach at xfce.org
Mon Jan 19 19:11:20 CET 2009


Author: cockroach
Date: 2009-01-19 18:11:20 +0000 (Mon, 19 Jan 2009)
New Revision: 6501

Added:
   xfce4-radio-plugin/trunk/panel-plugin/radio.c
   xfce4-radio-plugin/trunk/panel-plugin/radio.h
   xfce4-radio-plugin/trunk/panel-plugin/v4l1.c
   xfce4-radio-plugin/trunk/panel-plugin/v4l1.h
   xfce4-radio-plugin/trunk/panel-plugin/v4l2.c
   xfce4-radio-plugin/trunk/panel-plugin/v4l2.h
   xfce4-radio-plugin/trunk/panel-plugin/xfce4-radio.c
   xfce4-radio-plugin/trunk/panel-plugin/xfce4-radio.h
Removed:
   xfce4-radio-plugin/trunk/panel-plugin/radio.c
   xfce4-radio-plugin/trunk/panel-plugin/radio.h
Modified:
   xfce4-radio-plugin/trunk/
   xfce4-radio-plugin/trunk/NEWS
   xfce4-radio-plugin/trunk/panel-plugin/Makefile.am
Log:
Merged branch with gnomeradio includes



Property changes on: xfce4-radio-plugin/trunk
___________________________________________________________________
Modified: svn:mergeinfo
   - /xfce4-radio-plugin/branches/newpresets:6233-6254
   + /xfce4-radio-plugin/branches/newincludes:6308-6500
/xfce4-radio-plugin/branches/newpresets:6233-6254

Modified: xfce4-radio-plugin/trunk/NEWS
===================================================================
--- xfce4-radio-plugin/trunk/NEWS	2009-01-19 17:35:47 UTC (rev 6500)
+++ xfce4-radio-plugin/trunk/NEWS	2009-01-19 18:11:20 UTC (rev 6501)
@@ -1,6 +1,13 @@
 Get the latest version of this plugin at http://goodies.xfce.org/
 ===============================================================================
 
+v0.4.1 (19 Jan 2008):
+=====================
+ * The "let them worry about the details"-release
+ * We are now using the v4l/v4l2 functionality from gnomeradio
+ * Increased the default maximum signal strength value from 2 to 3
+ * Deactivated debug output on default builds
+
 v0.4.0 (03 Dec 2008):
 =====================
  * The "thanks for all the patches"-release

Modified: xfce4-radio-plugin/trunk/panel-plugin/Makefile.am
===================================================================
--- xfce4-radio-plugin/trunk/panel-plugin/Makefile.am	2009-01-19 17:35:47 UTC (rev 6500)
+++ xfce4-radio-plugin/trunk/panel-plugin/Makefile.am	2009-01-19 18:11:20 UTC (rev 6501)
@@ -2,11 +2,15 @@
 plugin_PROGRAMS = xfce4-radio-plugin
 
 xfce4_radio_plugin_SOURCES =						\
-	radio.c	radio.h
+	xfce4-radio.c xfce4-radio.h					\
+	radio.c radio.h							\
+	v4l1.c v4l1.h							\
+	v4l2.c v4l2.h
 
 xfce4_radio_plugin_CFLAGS =						\
 	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
-	@LIBXFCE4PANEL_CFLAGS@
+	@LIBXFCE4PANEL_CFLAGS@						\
+	-std=c99
 
 xfce4_radio_plugin_LDADD =						\
 	@LIBXFCE4PANEL_LIBS@
@@ -17,7 +21,7 @@
 # automake stage, we'll use sed to get the full path into the .desktop file.
 # We also need to let intltool merge the translated fields, so we add an
 # additional level of indirection: a <name>.desktop.in.in file.
-# 
+#
 desktop_in_in_files = radio.desktop.in.in
 desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in)
 

Copied: xfce4-radio-plugin/trunk/panel-plugin/radio.c (from rev 6500, xfce4-radio-plugin/branches/newincludes/panel-plugin/radio.c)
===================================================================
--- xfce4-radio-plugin/trunk/panel-plugin/radio.c	                        (rev 0)
+++ xfce4-radio-plugin/trunk/panel-plugin/radio.c	2009-01-19 18:11:20 UTC (rev 6501)
@@ -0,0 +1,157 @@
+/*
+ *  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 Library 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+
+#include "radio.h"
+#include "v4l1.h"
+#include "v4l2.h"
+
+static RadioDev *dev;
+
+/*
+ * These functions handle the radio device
+ */
+ 
+int radio_init(char *device, DriverType driver)
+{
+    int rv = -1;
+	if (dev) {
+		radio_stop();
+	}
+
+	switch (driver) {
+		case DRIVER_V4L2:
+			goto try_v4l2;
+		case DRIVER_ANY:
+		case DRIVER_V4L1:
+		default:
+			goto try_v4l1;
+	}
+
+try_v4l1:
+	dev = v4l1_radio_dev_new();
+	rv = dev->init (dev, device);
+	if (rv == 0) {
+        fprintf(stderr, "Initializing v4l1 failed\n");
+		dev->finalize (dev);
+		dev = NULL;
+		if (driver != DRIVER_ANY)
+			goto failure;
+	} else {
+		goto success;
+	}
+
+try_v4l2:
+	dev = v4l2_radio_dev_new();
+	rv = dev->init (dev, device);
+	if (rv == 0) {
+        fprintf(stderr, "Initializing v4l2 failed\n");
+		dev->finalize (dev);
+		dev = NULL;
+		if (driver != DRIVER_ANY)
+			goto failure;
+	} else {
+		goto success;
+	}
+
+success:
+	radio_unmute();
+failure:
+
+	return rv;
+}
+
+int radio_is_init(void)
+{
+	if (dev) return dev->is_init (dev);
+	else return 0;
+}
+
+void radio_stop(void)
+{
+	radio_mute();
+	
+	if (dev) dev->finalize (dev);
+}
+
+void radio_set_freq(float frequency)
+{
+	if (dev) dev->set_freq (dev, frequency);
+}
+
+void radio_unmute(void)
+{
+	if (dev) dev->mute (dev, 0);
+}
+
+void radio_mute(void)
+{
+	if (dev) dev->mute (dev, 1);
+}
+
+int radio_get_stereo(void)
+{
+	if (dev) return dev->get_stereo (dev);
+	else return -1;
+}
+
+int radio_get_signal(void)
+{
+	if (dev) return dev->get_signal (dev);
+	else return -1;
+}
+
+double radio_get_freq(void)
+{
+	if (dev) return dev->get_freq (dev);
+	return -1;
+}
+
+int radio_is_muted(void)
+{
+	if (dev) return dev->is_muted (dev);
+	return -1;
+}
+
+int radio_check_station(float freq)
+{
+	static int a, b;
+	static float last;
+	int signal;
+	
+	signal = radio_get_signal();
+	
+	if (last == 0.0f)
+		last = freq;
+	
+	if ((a + b + signal > 8) && (fabsf(freq - last) > 0.25f)) {
+		a = b = 0;
+		last = freq;
+		return 1;
+	}
+	a = b;
+	b = signal;
+	return 0;
+}
+

Copied: xfce4-radio-plugin/trunk/panel-plugin/radio.h (from rev 6500, xfce4-radio-plugin/branches/newincludes/panel-plugin/radio.h)
===================================================================
--- xfce4-radio-plugin/trunk/panel-plugin/radio.h	                        (rev 0)
+++ xfce4-radio-plugin/trunk/panel-plugin/radio.h	2009-01-19 18:11:20 UTC (rev 6501)
@@ -0,0 +1,64 @@
+/*
+ *  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 Library 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 _RADIO_H
+#define _RADIO_H
+
+typedef struct _RadioDev RadioDev;
+struct _RadioDev
+{
+	int  (*init)       (RadioDev *dev, char *device);
+	int  (*is_init)    (RadioDev *dev);
+	void (*set_freq)   (RadioDev *dev, float freq);
+	void (*mute)       (RadioDev *dev, int   mute);
+	int  (*get_stereo) (RadioDev *dev);
+	int  (*get_signal) (RadioDev *dev);
+	double(*get_freq)  (RadioDev *dev);
+	int  (*is_muted)   (RadioDev *dev);
+	void (*finalize)   (RadioDev *dev);
+};
+
+typedef enum _DriverType DriverType;
+enum _DriverType
+{
+	DRIVER_ANY,
+	DRIVER_V4L1,
+	DRIVER_V4L2
+};
+
+int radio_init(char *device, DriverType type);
+
+int radio_is_init(void);
+
+void radio_stop(void);
+
+void radio_set_freq(float freq);
+
+int radio_check_station(float freq);
+
+void radio_unmute(void);
+
+void radio_mute(void);
+
+int radio_get_stereo(void);
+
+int radio_get_signal(void);
+
+double radio_get_freq(void);
+
+int radio_is_muted(void);
+
+#endif

Copied: xfce4-radio-plugin/trunk/panel-plugin/v4l1.c (from rev 6500, xfce4-radio-plugin/branches/newincludes/panel-plugin/v4l1.c)
===================================================================
--- xfce4-radio-plugin/trunk/panel-plugin/v4l1.c	                        (rev 0)
+++ xfce4-radio-plugin/trunk/panel-plugin/v4l1.c	2009-01-19 18:11:20 UTC (rev 6501)
@@ -0,0 +1,217 @@
+/*
+ *  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 Library 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+
+#include <linux/videodev.h>
+#include "radio.h"
+
+typedef struct _V4L1RadioDev V4L1RadioDev;
+struct _V4L1RadioDev
+{
+	struct _RadioDev parent;
+
+	int fd;
+	int freq_fact;
+};
+
+static int
+v4l1_radio_init(RadioDev *radio_dev, char *device)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+	struct video_tuner tuner;
+	
+	if ((dev->fd = open(device, O_RDONLY)) < 0)
+		return 0;
+	
+	tuner.tuner = 0;
+	if (ioctl (dev->fd, VIDIOCGTUNER, &tuner) < 0)
+		dev->freq_fact = 16;
+	else
+	{
+		if ((tuner.flags & VIDEO_TUNER_LOW) == 0)
+			dev->freq_fact = 16;
+		else
+			dev->freq_fact = 16000;
+	}
+	
+	return 1;
+}
+
+int v4l1_radio_is_init(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+	return (dev->fd >= 0);
+}
+
+static void
+v4l1_radio_set_freq(RadioDev *radio_dev, float freq)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+    int ifreq;
+
+    if (dev->fd<0)
+    	return;
+    
+	ifreq = (freq+1.0/32)*dev->freq_fact;
+#if 0
+	printf("Setting to %i (= %.2f)\n", ifreq, freq);
+#endif
+
+	/* FIXME: Do we need really need these checks? */
+	if ((freq > 108) || (freq < 65))
+		return;
+
+	assert ((freq <= 108) && (freq > 65));
+
+    if (ioctl(dev->fd, VIDIOCSFREQ, &ifreq) < 0)
+		perror ("VIDIOCSFREQ");
+}
+
+static void
+v4l1_radio_mute(RadioDev *radio_dev, int mute)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+    struct video_audio vid_aud;
+
+    if (dev->fd<0)
+    	return;
+
+    if (ioctl(dev->fd, VIDIOCGAUDIO, &vid_aud)) {
+		perror("VIDIOCGAUDIO");
+		memset (&vid_aud, 0, sizeof (struct video_audio));
+	}
+	if (mute) {
+    	vid_aud.flags |= VIDEO_AUDIO_MUTE;
+	} else {
+		vid_aud.volume = 0xFFFF;
+		vid_aud.flags &= ~VIDEO_AUDIO_MUTE;
+		vid_aud.mode = VIDEO_SOUND_STEREO;
+	}
+    if (ioctl(dev->fd, VIDIOCSAUDIO, &vid_aud))
+		perror("VIDIOCSAUDIO");
+}
+
+static int
+v4l1_radio_get_stereo(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+    struct video_audio va;
+    va.mode=-1;
+
+    if (dev->fd<0)
+    	return -1;
+    
+    if (ioctl (dev->fd, VIDIOCGAUDIO, &va) < 0)
+		return -1;
+	if (va.mode == VIDEO_SOUND_STEREO)
+		return 1;
+	else 
+		return 0;
+}
+
+static int
+v4l1_radio_get_signal(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+    struct video_tuner vt;
+    int signal;
+
+    if (dev->fd<0)
+    	return -1;
+
+    memset(&vt,0,sizeof(vt));
+    ioctl (dev->fd, VIDIOCGTUNER, &vt);
+    signal=vt.signal>>13;
+
+    return signal;
+}
+
+static double
+v4l1_radio_get_freq(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+	long freq;
+
+	if (dev->fd<0)
+		return -1;
+
+	if (ioctl (dev->fd, VIDIOCGFREQ, &freq))
+	{
+		perror ("VIDIOCGFREQ");
+		return -1;
+	}
+
+	return freq / (double) dev->freq_fact;
+}
+
+static int
+v4l1_radio_is_muted(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+	struct video_audio vid_aud;
+
+	if (dev->fd<0)
+		return -1;
+
+	if (ioctl (dev->fd, VIDIOCGAUDIO, &vid_aud)) {
+		perror ("VIDIOCGAUDIO");
+		return -1;
+	}
+
+	return (vid_aud.flags & VIDEO_AUDIO_MUTE);
+}
+
+static void
+v4l1_radio_finalize(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+	
+	if (dev->fd >= 0)
+		close(dev->fd);
+	free (dev);
+}
+
+RadioDev*
+v4l1_radio_dev_new (void)
+{
+    RadioDev *dev;
+	V4L1RadioDev *v4l1_dev;
+
+	v4l1_dev = malloc(sizeof(V4L1RadioDev));
+	v4l1_dev->fd = -1;
+	dev = (RadioDev*)v4l1_dev;
+
+	dev->init       = v4l1_radio_init;
+	dev->is_init    = v4l1_radio_is_init;
+	dev->set_freq   = v4l1_radio_set_freq;
+	dev->mute       = v4l1_radio_mute;
+	dev->get_stereo = v4l1_radio_get_stereo;
+	dev->get_signal = v4l1_radio_get_signal;
+	dev->get_freq   = v4l1_radio_get_freq;
+	dev->is_muted   = v4l1_radio_is_muted;
+	dev->finalize   = v4l1_radio_finalize;
+
+	return dev;
+}
+

Copied: xfce4-radio-plugin/trunk/panel-plugin/v4l1.h (from rev 6500, xfce4-radio-plugin/branches/newincludes/panel-plugin/v4l1.h)
===================================================================
--- xfce4-radio-plugin/trunk/panel-plugin/v4l1.h	                        (rev 0)
+++ xfce4-radio-plugin/trunk/panel-plugin/v4l1.h	2009-01-19 18:11:20 UTC (rev 6501)
@@ -0,0 +1,25 @@
+/*
+ *  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 Library 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 _V4L1_H
+#define _V4L1_H
+
+#include <radio.h>
+
+RadioDev* v4l1_radio_dev_new (void);
+
+#endif
+

Copied: xfce4-radio-plugin/trunk/panel-plugin/v4l2.c (from rev 6500, xfce4-radio-plugin/branches/newincludes/panel-plugin/v4l2.c)
===================================================================
--- xfce4-radio-plugin/trunk/panel-plugin/v4l2.c	                        (rev 0)
+++ xfce4-radio-plugin/trunk/panel-plugin/v4l2.c	2009-01-19 18:11:20 UTC (rev 6501)
@@ -0,0 +1,244 @@
+/*
+ *  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 Library 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+
+#include <linux/videodev2.h>
+#include "v4l2.h"
+
+typedef struct _V4L2RadioDev V4L2RadioDev;
+struct _V4L2RadioDev
+{
+	struct _RadioDev parent;
+
+	int fd;
+	int freq_fact;
+	int radio_rangelow;
+	int radio_rangehigh;
+};
+
+static int
+v4l2_radio_init(RadioDev *radio_dev, char *device)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_capability caps;
+	struct v4l2_tuner tuner;
+	
+	if ((dev->fd = open(device, O_RDONLY))< 0)
+		goto err;
+	
+	/* does this device provide a tuner? */
+	memset(&caps, 0, sizeof(caps));
+	if (ioctl(dev->fd, VIDIOC_QUERYCAP, &caps) < 0) {
+		perror("VIDIOC_QUERYCAP");
+		goto err;
+	}
+	if ((caps.capabilities & V4L2_CAP_TUNER) == 0) {
+		fprintf(stderr, "Not a radio tuner\n");
+		goto err;
+	}
+
+	/* check the tuner */
+	memset(&tuner, 0, sizeof(tuner));
+	tuner.index = 0;
+	if (ioctl(dev->fd, VIDIOC_G_TUNER, &tuner) < 0) {
+		perror("VIDIOC_G_TUNER");
+		goto err;
+	}
+	if (tuner.type != V4L2_TUNER_RADIO) {
+		fprintf(stderr, "Not a radio tuner\n");
+		goto err;
+	}
+	/* Does this tuner expect data in 62.5Hz or 62.5kHz multiples? */
+	dev->radio_rangelow = tuner.rangelow;
+	dev->radio_rangehigh = tuner.rangehigh;
+	if ((tuner.capability & V4L2_TUNER_CAP_LOW) != 0)
+		dev->freq_fact = 16000;
+	else
+		dev->freq_fact = 16;
+	
+	return 1;
+
+ err:
+	if (dev->fd >= 0)
+		close(dev->fd);
+	dev->fd = -1;
+	return 0;
+}
+
+static int
+v4l2_radio_is_init(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	return (dev->fd >= 0);
+}
+
+static void
+v4l2_radio_set_freq(RadioDev *radio_dev, float frequency)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_frequency freq;
+
+	if (dev->fd<0)
+		return;
+
+	memset(&freq, 0, sizeof(freq));
+	freq.tuner = 0;
+	freq.type = V4L2_TUNER_RADIO;
+	freq.frequency = frequency * dev->freq_fact;
+
+	if (freq.frequency < dev->radio_rangelow ||
+	    freq.frequency > dev->radio_rangehigh)
+		return;
+	if (ioctl(dev->fd, VIDIOC_S_FREQUENCY, &freq) < 0)
+		perror("VIDIOC_S_FREQUENCY");
+}
+
+static void
+v4l2_radio_mute(RadioDev *radio_dev, int mute)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_control control;
+
+	if (dev->fd<0)
+		return;
+
+	memset(&control, 0, sizeof(control));
+	control.id = V4L2_CID_AUDIO_MUTE;
+	control.value = mute;
+	if (ioctl(dev->fd, VIDIOC_S_CTRL, &control) < 0)
+		perror("VIDIOC_S_CTRL");
+}
+
+static int
+v4l2_radio_get_stereo(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_tuner tuner;
+
+	if (dev->fd<0)
+		return -1;
+
+	memset(&tuner, 0, sizeof(tuner));
+	tuner.index = 0;
+	if (ioctl(dev->fd, VIDIOC_G_TUNER, &tuner) < 0) {
+		perror("VIDIOC_G_TUNER");
+		return -1;
+	}
+
+	return tuner.audmode == V4L2_TUNER_MODE_STEREO;
+}
+
+static int
+v4l2_radio_get_signal(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_tuner tuner;
+
+	if (dev->fd<0)
+		return -1;
+
+	memset(&tuner, 0, sizeof(tuner));
+	tuner.index = 0;
+	if (ioctl(dev->fd, VIDIOC_G_TUNER, &tuner) < 0) {
+		perror("VIDIOC_G_TUNER");
+		return -1;
+	}
+
+	return tuner.signal >> 13;
+}
+
+static double
+v4l2_radio_get_freq(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_frequency freq;
+
+	if (dev->fd<0)
+		return -1;
+
+	memset(&freq, 0, sizeof(freq));
+	freq.tuner = 0;
+	freq.type = V4L2_TUNER_RADIO;
+
+	if (ioctl (dev->fd, VIDIOC_G_FREQUENCY, &freq) < 0)
+	{
+		perror ("VIDIOC_G_FREQUENCY");
+		return -1;
+	}
+	double result = freq.frequency / (double) dev->freq_fact;
+	return round(result * 100) / 100;
+}
+
+static int
+v4l2_radio_is_muted(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_control control;
+
+	if (dev->fd<0)
+		return -1;
+
+	memset(&control, 0, sizeof(control));
+	control.id = V4L2_CID_AUDIO_MUTE;
+
+	if (ioctl (dev->fd, VIDIOC_G_CTRL, &control) < 0) {
+		perror ("VIDIOC_S_CTRL");
+		return -1;
+	}
+	return control.value;
+}
+
+static void
+v4l2_radio_finalize(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	
+	if (dev->fd >= 0)
+		close(dev->fd);
+	free (dev);
+}
+
+RadioDev*
+v4l2_radio_dev_new (void)
+{
+    RadioDev *dev;
+	V4L2RadioDev *v4l2_dev;
+
+	v4l2_dev = malloc (sizeof (V4L2RadioDev));
+	v4l2_dev->fd = -1;
+
+	dev = (RadioDev*)v4l2_dev;
+	dev->init       = v4l2_radio_init;
+	dev->is_init    = v4l2_radio_is_init;
+	dev->set_freq   = v4l2_radio_set_freq;
+	dev->mute       = v4l2_radio_mute;
+	dev->get_stereo = v4l2_radio_get_stereo;
+	dev->get_signal = v4l2_radio_get_signal;
+	dev->get_freq   = v4l2_radio_get_freq;
+	dev->finalize   = v4l2_radio_finalize;
+	dev->is_muted   = v4l2_radio_is_muted;
+
+	return dev;
+}
+

Copied: xfce4-radio-plugin/trunk/panel-plugin/v4l2.h (from rev 6500, xfce4-radio-plugin/branches/newincludes/panel-plugin/v4l2.h)
===================================================================
--- xfce4-radio-plugin/trunk/panel-plugin/v4l2.h	                        (rev 0)
+++ xfce4-radio-plugin/trunk/panel-plugin/v4l2.h	2009-01-19 18:11:20 UTC (rev 6501)
@@ -0,0 +1,25 @@
+/*
+ *  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 Library 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 _V4L2_H
+#define _V4L2_H
+
+#include <radio.h>
+
+RadioDev* v4l2_radio_dev_new (void);
+
+#endif
+

Copied: xfce4-radio-plugin/trunk/panel-plugin/xfce4-radio.c (from rev 6500, xfce4-radio-plugin/branches/newincludes/panel-plugin/xfce4-radio.c)
===================================================================
--- xfce4-radio-plugin/trunk/panel-plugin/xfce4-radio.c	                        (rev 0)
+++ xfce4-radio-plugin/trunk/panel-plugin/xfce4-radio.c	2009-01-19 18:11:20 UTC (rev 6501)
@@ -0,0 +1,1299 @@
+/*
+ * radio plugin for Xfce4.
+ *
+ * Copyright (c) 2006-2008 Stefan Ott, All rights reserved.
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "xfce4-radio.h"
+
+#include "radio.h"
+#include "v4l1.h"
+#include "v4l2.h"
+
+#include <libxfcegui4/dialogs.h>
+#include <libxfcegui4/xfce-exec.h>
+#include <libxfce4util/libxfce4util.h>
+#include <gdk/gdkkeysyms.h>
+
+static gboolean
+update_signal_bar (radio_gui* data)
+{
+	if (!data->on || !data->show_signal)
+	{
+		gtk_widget_hide (data->signal_bar);
+		data->signal_timeout_id = 0;
+		return FALSE;
+	}
+	else
+	{
+		gtk_widget_show (data->signal_bar);
+		double signal = radio_get_signal ();
+
+		if (signal > data->max_signal_strength)
+			data->max_signal_strength = signal;
+
+		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR
+			(data->signal_bar), signal / data->max_signal_strength);
+
+		GdkColor color;
+		if (signal == 1)
+			gdk_color_parse (COLOR_SIGNAL_LOW, &color);
+		else if (signal == data->max_signal_strength)
+			gdk_color_parse (COLOR_SIGNAL_HIGH, &color);
+		else
+			gdk_color_parse (COLOR_SIGNAL_MED, &color);
+
+		gtk_widget_modify_bg (data->signal_bar, GTK_STATE_PRELIGHT,
+								&color);
+		if (data->signal_timeout_id == 0)
+		{
+			data->signal_timeout_id = g_timeout_add(500,
+					(GtkFunction) update_signal_bar,
+							(gpointer) data);
+		}
+		return TRUE;
+	}
+}
+
+#define make_preset_finder(name, arg, search_arg, get_col, get_var,	\
+						free, comparison)	\
+	static gboolean							\
+	find_preset_by_##name (GtkTreeModel *model,			\
+			search_arg,					\
+			GtkTreeIter *search_iter)			\
+	{								\
+		arg;							\
+		GtkTreeIter iter;					\
+		gboolean valid;						\
+		valid = gtk_tree_model_get_iter_first (model, &iter);	\
+		while (valid)						\
+		{							\
+			gtk_tree_model_get (model, &iter,		\
+					get_col, get_var, -1);		\
+			if (comparison) {				\
+				*search_iter = iter;			\
+				return TRUE;				\
+			}						\
+			free;						\
+			valid = gtk_tree_model_iter_next (model, &iter);\
+		}							\
+		return FALSE;						\
+	}								\
+
+make_preset_finder (freq, gint freq, gint search_freq, 1, &freq, freq = 0,
+							freq == search_freq);
+make_preset_finder (name, gchar *name, const gchar *search_name, 0, &name,
+				g_free(name), strcmp (name, search_name) == 0);
+
+static void
+update_tooltip (radio_gui* data)
+{
+	GtkWidget* ebox = data->ebox;
+	GtkTreeIter iter;
+	gchar *name;
+
+	GtkTreeModel *presets = GTK_TREE_MODEL (data->presets);
+	if (find_preset_by_freq (presets, data->freq, &iter))
+	{
+		gtk_tree_model_get (presets, &iter, 0, &name, -1);
+	}
+	else
+	{
+		name = g_strdup_printf ("%5.1f", (float) data->freq / 100);
+	}
+
+	gtk_tooltips_set_tip (data->tooltips, ebox, name, NULL);
+
+	g_free (name);
+}
+
+static void
+update_label (radio_gui* data)
+{
+	gchar *label;
+
+	if (data->on)
+	{
+		label = g_strdup_printf ("%5.1f", ((float) data->freq) / 100);
+		update_tooltip (data);
+	}
+	else
+	{
+		label = g_strdup (_("- off -"));
+	}
+
+	gtk_label_set_label (GTK_LABEL (data->label), label);
+
+	g_free (label);
+}
+
+static gboolean
+update_radio (radio_gui *data)
+{
+	// We could just remove the timer, but then we would have to make sure
+	// to re-add it at all the appropriate places, thus we don't.
+	if (!data->auto_update_display)
+		return TRUE;
+
+	if (radio_is_muted())
+	{
+		if (data->on)
+		{
+			// Radio is off, we thought it was on
+			if (data->show_signal)
+				gtk_widget_hide (data->signal_bar);
+			data->on = FALSE;
+		}
+	}
+	else
+	{
+		if (!data->on)
+		{
+			// Radio is on, we thought it was off
+			gtk_tooltips_enable (data->tooltips);
+			data->on = TRUE;
+		}
+		data->freq = radio_get_freq () * 100;
+		DBG ("Updating frequency to %d", data->freq);
+	}
+	update_label (data);
+	update_signal_bar (data);
+
+	return TRUE;
+}
+
+static void
+xfce4_radio_tune (radio_gui* data)
+{
+	double freq = data->freq / 100.0;
+	radio_set_freq (freq);
+	DBG ("Tuning to %f", freq);
+
+	update_label (data);
+	update_signal_bar (data);
+
+	write_config (data, FALSE);
+}
+
+static gboolean
+xfce4_radio_start (radio_gui* data)
+{
+	DBG("Starting");
+	if (!radio_init (data->device, DRIVER_V4L2))
+	{
+		GtkWindow* win = GTK_WINDOW (gtk_widget_get_toplevel(
+								data->box));
+		GtkWidget* warn = gtk_message_dialog_new (win, 0,
+			GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+			_("Error opening radio device"));
+		gtk_dialog_run (GTK_DIALOG (warn));
+		gtk_widget_destroy (warn);
+		return FALSE;
+	}
+
+	if (strcmp(data->startup_command, "") != 0)
+	{
+		xfce_exec(data->startup_command, FALSE, FALSE, NULL);
+	}
+	xfce4_radio_tune (data);
+	gtk_tooltips_enable (data->tooltips);
+	return TRUE;
+}
+
+static void
+xfce4_radio_stop (radio_gui* data)
+{
+	radio_mute ();
+	gtk_tooltips_disable (data->tooltips);
+
+	if (data->show_signal) gtk_widget_hide (data->signal_bar);
+
+	if (strcmp (data->shutdown_command, "") != 0)
+	{
+		xfce_exec (data->shutdown_command, FALSE, FALSE, NULL);
+	}
+}
+
+static gint
+parse_freq (const gchar *freq_char)
+{
+	gint mult, decimal_int;
+
+	gint freq_int = 100 * atoi (freq_char);
+
+	gchar *decimals = strstr (freq_char, ".");
+	if (decimals)
+		decimals++;
+	else
+	{
+		// In some languages, a comma can be used instead of a point
+		decimals = strstr (freq_char, ",");
+		if (decimals)
+			decimals++;
+		else
+			decimals = "0";
+	}
+
+	decimal_int = atoi (decimals);
+
+	if (decimal_int < 10)
+		mult = 10;
+	else if (decimal_int < 100)
+		mult = 1;
+	else
+		mult = 0;
+
+	freq_int += mult * decimal_int;
+
+	return freq_int;
+}
+
+static gboolean
+parse_freq_and_tune (const char* freq_char, radio_gui* data)
+{
+	int freq_int = parse_freq (freq_char);
+	DBG ("Parsed frequency %d", freq_int);
+
+	if (freq_int >= FREQ_MIN && freq_int <= FREQ_MAX)
+	{
+		data->freq = freq_int;
+		xfce4_radio_tune (data);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static void
+radio_tune_gui (GtkEditable *menu_item, void *pointer)
+{
+	radio_gui* data = (radio_gui*) pointer;
+	GtkWindow* win = GTK_WINDOW (gtk_widget_get_toplevel (data->box));
+	GtkWidget* dialog = gtk_dialog_new_with_buttons (_("Tune radio"),
+				NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
+				GTK_STOCK_OK, GTK_RESPONSE_OK,
+				GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+	GtkWidget* box = GTK_DIALOG (dialog)->vbox;
+
+	GtkWidget* label = gtk_label_new (_("Frequency [MHz]:"));
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+
+	GtkWidget* freq = gtk_entry_new_with_max_length (5);
+	gtk_widget_show (freq);
+	gtk_box_pack_start (GTK_BOX (box), freq, FALSE, FALSE, 0);
+
+	int retval;
+	for (;;)
+	{
+		retval = gtk_dialog_run (GTK_DIALOG (dialog));
+
+		if (	retval == GTK_RESPONSE_CANCEL ||
+			retval == GTK_RESPONSE_DELETE_EVENT ||
+			retval == GTK_RESPONSE_NONE) {
+				break;
+		}
+
+		const char* freq_char = gtk_entry_get_text (GTK_ENTRY (freq));
+		if (parse_freq_and_tune (freq_char, data)) break;
+
+		GtkWidget* warn = gtk_message_dialog_new (win, 0,
+					GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+						_("Illegal frequency."));
+		gtk_dialog_run (GTK_DIALOG (warn));
+		gtk_widget_destroy (warn);
+	}
+	gtk_widget_destroy (dialog);
+}
+
+static XfceRc *
+get_config_rc ()
+{
+	char *file;
+	XfceRc *rc;
+
+	// Take data from a clearly defined place RADIO_CONFIG
+	file = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, RADIO_CONFIG,
+									TRUE);
+
+	if (G_UNLIKELY (!file))
+		return NULL;
+
+	rc = xfce_rc_simple_open (file, FALSE);
+	g_free (file);
+
+	return rc;
+}
+
+static void
+select_preset (GtkEditable* menu_item, radio_gui *data)
+{
+	GtkWidget* label = gtk_bin_get_child (GTK_BIN (menu_item));
+	const gchar* text = gtk_label_get_text (GTK_LABEL (label));
+	GtkTreeModel *presets = GTK_TREE_MODEL(data->presets);
+	GtkTreeIter iter;
+
+	if (find_preset_by_name (presets, text, &iter))
+	{
+		gtk_tree_model_get (presets, &iter, 1, &data->freq, -1);
+		xfce4_radio_tune (data);
+	}
+}
+
+static gboolean
+mouse_click (GtkWidget* src, GdkEventButton *event, radio_gui* data)
+{
+	if (event->button == 1)
+	{
+		if (!data->on)
+			data->on = xfce4_radio_start (data);
+		else
+		{
+			data->on = FALSE;
+			xfce4_radio_stop (data);
+		}
+	}
+	else if (event->button == 2 && data->on)
+	{
+		GtkWidget* menu = gtk_menu_new ();
+		GtkWidget* item = gtk_menu_item_new_with_label (_("Presets"));
+		gtk_widget_show (item);
+		gtk_menu_append (menu, item);
+		gtk_widget_set_sensitive (item, FALSE);
+
+		GtkWidget* separator = gtk_separator_menu_item_new ();
+		gtk_widget_show (separator);
+		gtk_container_add (GTK_CONTAINER (menu), separator);
+		gtk_widget_set_sensitive (separator, FALSE);
+
+		gchar *name;
+		GtkTreeModel *presets = GTK_TREE_MODEL(data->presets);
+		GtkTreeIter iter;
+
+		gboolean valid = gtk_tree_model_get_iter_first (presets, &iter);
+		while (valid)
+		{
+			gtk_tree_model_get (presets, &iter, 0, &name, -1);
+			item = gtk_menu_item_new_with_label (name);
+			gtk_widget_show (item);
+			g_free (name);
+			gtk_menu_shell_append (GTK_MENU_SHELL(menu), item);
+			g_signal_connect (GTK_WIDGET (item), "activate",
+					G_CALLBACK (select_preset), data);
+			valid = gtk_tree_model_iter_next (presets, &iter);
+		}
+
+		separator = gtk_separator_menu_item_new ();
+		gtk_widget_show (separator);
+		gtk_container_add (GTK_CONTAINER (menu), separator);
+		gtk_widget_set_sensitive (separator, FALSE);
+
+		item = gtk_menu_item_new_with_label (_("Tune to frequency"));
+		gtk_widget_show (item);
+		gtk_menu_append (menu, item);
+		g_signal_connect (GTK_WIDGET (item), "activate",
+					G_CALLBACK (radio_tune_gui), data);
+
+		gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
+				event->button, event->time);
+	}
+	update_label (data);
+	update_signal_bar (data);
+	return event->button != 3;
+}
+
+static void
+mouse_scroll(GtkWidget* src, GdkEventScroll *event, radio_gui* data)
+{
+	GtkTreePath *path;
+	GtkTreeIter iter, iter1;
+	GtkTreeModel *presets;
+
+	if (!data->on)
+		return;
+
+	int direction = event->direction == GDK_SCROLL_UP ? -1 : 1;
+	if (data->scroll == CHANGE_FREQ) {
+		data->freq += direction * FREQ_STEP;
+		if (data->freq > FREQ_MAX) data->freq = FREQ_MIN;
+		if (data->freq < FREQ_MIN) data->freq = FREQ_MAX;
+		xfce4_radio_tune (data);
+	}
+	else if (data->scroll == CHANGE_PRESET)
+	{
+		presets = GTK_TREE_MODEL(data->presets);
+		if (!find_preset_by_freq (presets, data->freq, &iter))
+		{
+			// tune to first preset, if it exists
+			if (!gtk_tree_model_get_iter_first (presets, &iter))
+				return;
+
+			gtk_tree_model_get (presets, &iter,
+					1, &data->freq, -1);
+			xfce4_radio_tune (data);
+			return;
+		}
+		// preset found
+		if (direction == 1)
+		{
+			if (!gtk_tree_model_iter_next (presets, &iter))
+				return;
+			gtk_tree_model_get (presets, &iter, 1, &data->freq, -1);
+			xfce4_radio_tune (data);
+		}
+		else
+		{
+			path = gtk_tree_model_get_path (presets, &iter);
+
+			if (!gtk_tree_path_prev (path))
+				return;
+
+			gtk_tree_model_get_iter (presets, &iter1, path);
+			gtk_tree_path_free (path);
+			gtk_tree_model_get (presets, &iter1,
+					1, &data->freq, -1);
+			xfce4_radio_tune (data);
+		}
+	}
+}
+
+static radio_gui *
+create_gui ()
+{
+	radio_gui* gui;
+	gui = g_new (radio_gui, 1);
+
+	gui->ebox = gtk_event_box_new ();
+	gtk_widget_show (gui->ebox);
+	g_signal_connect (GTK_WIDGET (gui->ebox), "button_press_event",
+						G_CALLBACK (mouse_click), gui);
+	g_signal_connect (GTK_WIDGET (gui->ebox), "scroll_event",
+						G_CALLBACK (mouse_scroll), gui);
+
+	gui->signal_bar = gtk_progress_bar_new ();
+	gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (gui->signal_bar),
+						GTK_PROGRESS_LEFT_TO_RIGHT);
+
+	gui->box = gtk_vbox_new (FALSE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (gui->box), BORDER / 2);
+	gtk_widget_show (gui->box);
+
+	gui->label = gtk_label_new ("");
+	gtk_widget_show (gui->label);
+
+	gtk_box_pack_start (GTK_BOX (gui->box), gui->label, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (gui->box), gui->signal_bar, FALSE, FALSE,
+									0);
+
+	gtk_container_add (GTK_CONTAINER (gui->ebox), gui->box);
+
+	gui->max_signal_strength = 3;
+
+	return gui;
+}
+
+static void
+free_presets (radio_gui *data)
+{
+	g_object_unref (data->presets);
+}
+
+static void
+radio_free (XfcePanelPlugin *plugin, radio_gui *data)
+{
+	if (data->on) xfce4_radio_stop (data);
+	free_presets (data);
+	g_free (data);
+
+	if (data->signal_timeout_id)
+		g_source_remove(data->signal_timeout_id);
+	if (data->radio_timeout_id)
+		g_source_remove(data->radio_timeout_id);
+}
+
+static radio_gui *
+plugin_control_new (XfcePanelPlugin *plugin)
+{
+	radio_gui* plugin_data = create_gui();
+
+	plugin_data->plugin = plugin;
+
+	plugin_data->on = FALSE;
+	plugin_data->freq = FREQ_INIT;
+	strcpy(plugin_data->device, "/dev/radio0");
+
+	plugin_data->show_signal = TRUE;
+	plugin_data->auto_update_display = TRUE;
+	plugin_data->presets = NULL;
+	plugin_data->presets = NULL;
+	plugin_data->scroll = CHANGE_FREQ;
+	plugin_data->signal_timeout_id = 0;
+	plugin_data->radio_timeout_id = g_timeout_add(2000,
+			(GtkFunction)update_radio, (gpointer)plugin_data);
+	plugin_data->tooltips = gtk_tooltips_new();
+	plugin_data->startup_command[0] = '\0';
+	plugin_data->shutdown_command[0] = '\0';
+
+	update_label(plugin_data);
+
+	gtk_container_add (GTK_CONTAINER (plugin), plugin_data->ebox);
+
+	return plugin_data;
+}
+
+static void
+radio_startup_command_changed (GtkEditable* editable, void *pointer)
+{
+	radio_gui* data = (radio_gui*) pointer;
+	const char* command = gtk_entry_get_text (GTK_ENTRY (editable));
+	strncpy (data->startup_command, command, MAX_COMMAND_LENGTH);
+}
+
+static void
+radio_shutdown_command_changed (GtkEditable* editable, void *pointer)
+{
+	radio_gui* data = (radio_gui*) pointer;
+	const char* command = gtk_entry_get_text (GTK_ENTRY (editable));
+	strncpy (data->shutdown_command, command, MAX_COMMAND_LENGTH);
+}
+
+static void
+radio_device_changed (GtkEditable* editable, void *pointer)
+{
+	radio_gui* data = (radio_gui*) pointer;
+	const char* device = gtk_entry_get_text (GTK_ENTRY (editable));
+	strncpy (data->device, device, MAX_DEVICE_NAME_LENGTH);
+}
+
+static void
+radio_show_signal_changed (GtkEditable* editable, void *pointer)
+{
+	radio_gui* data = (radio_gui*) pointer;
+	data->show_signal = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
+								(editable));
+	update_signal_bar (data);
+}
+
+static void
+radio_auto_update_display_changed (GtkEditable* editable, void *pointer)
+{
+	radio_gui* data = (radio_gui*) pointer;
+	data->auto_update_display = gtk_toggle_button_get_active
+						(GTK_TOGGLE_BUTTON (editable));
+}
+
+static void
+radio_scroll_type_changed (GtkEditable* button, void *pointer)
+{
+	radio_gui* data = (radio_gui*) pointer;
+	gboolean frq = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
+
+	if (frq)
+	{
+		data->scroll = CHANGE_FREQ;
+	}
+	else
+	{
+		data->scroll = CHANGE_PRESET;
+	}
+}
+
+static void
+radio_plugin_dialog_response (GtkWidget *dialog, int response, radio_gui *data)
+{
+	gtk_widget_destroy (dialog);
+	xfce_panel_plugin_unblock_menu (data->plugin);
+	write_config (data, TRUE);
+}
+
+static void
+cell_float_to_text_cb (	GtkTreeViewColumn *tree_column,
+			GtkCellRenderer *cell,
+			GtkTreeModel *tree_model,
+			GtkTreeIter *iter,
+			gpointer data)
+{
+	gint f;
+	gchar *text;
+
+	// Get the double value from the model
+	gtk_tree_model_get (tree_model, iter, 1, &f, -1);
+	// Now we can format the value ourselves
+	text = g_strdup_printf ("%.2f", f / 100.0);
+	g_object_set (cell, "text", text, NULL);
+	g_free (text);
+}
+
+static void
+add_button_clicked_cb (GtkWidget *widget, GtkTreeSelection *selection)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+
+	radio_gui *data = g_object_get_data(G_OBJECT(selection), "data");
+
+	gtk_tree_selection_get_selected (selection, &model, &iter);
+	gtk_list_store_append (GTK_LIST_STORE(model), &iter);
+	gtk_list_store_set    (GTK_LIST_STORE(model), &iter,
+				0, _("unnamed"),
+				1, data->freq, -1);
+	gtk_tree_selection_select_iter (selection, &iter);
+	write_config (data, TRUE);
+}
+
+static void
+del_button_clicked_cb (GtkWidget *widget, GtkTreeSelection *selection)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+
+	radio_gui *data = g_object_get_data(G_OBJECT(selection), "data");
+
+	if (gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		if (gtk_list_store_remove(GTK_LIST_STORE(model), &iter))
+		{
+			gtk_tree_selection_select_iter(selection,&iter);
+		}
+	}
+	write_config (data, TRUE);
+	update_tooltip (data);
+}
+
+static void
+up_button_clicked_cb (GtkWidget *widget, GtkTreeSelection *selection)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+
+	radio_gui *data = g_object_get_data(G_OBJECT(selection), "data");
+
+	if (gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
+		if (gtk_tree_path_prev (path))
+		{
+			GtkTreeIter iter1 = iter;
+			gtk_tree_model_get_iter (model, &iter1, path);
+			gtk_list_store_swap (GTK_LIST_STORE (model),
+					&iter, &iter1);
+		}
+		gtk_tree_path_free (path);
+	}
+	write_config (data, TRUE);
+	// update_tooltip shows the first preset with the currently tuned
+	// frequency. If you have multiple entries with the same frequency,
+	// moving them up or down changes which one is shown in the tooltip
+	update_tooltip (data);
+}
+
+static void
+down_button_clicked_cb (GtkWidget *widget, GtkTreeSelection *selection)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+
+	radio_gui *data = g_object_get_data(G_OBJECT(selection), "data");
+
+	if (gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		GtkTreeIter iter1 = iter;
+		if (gtk_tree_model_iter_next (model, &iter1))
+		{
+			gtk_list_store_swap (GTK_LIST_STORE (model),
+					&iter, &iter1);
+		}
+	}
+	write_config (data, TRUE);
+	// See up_button_clicked_cb
+	update_tooltip (data);
+}
+
+static gboolean
+list_view_key_press_event_cb (GtkWidget *widget, GdkEventKey *event,
+							GtkTreeSelection *data)
+{
+	if (event->keyval == GDK_Delete)
+		del_button_clicked_cb(widget, data);
+	if (event->keyval == GDK_Insert)
+		add_button_clicked_cb(widget, data);
+
+	return FALSE;
+}
+
+static void
+name_cell_edited_cb (GtkCellRendererText *cellrenderertext, gchar *path_str,
+						gchar *new_val, radio_gui *data)
+{
+	GtkTreeIter iter;
+	gboolean valid;
+
+	GtkListStore *presets = data->presets;
+	valid = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(presets),
+			&iter, path_str);
+	g_return_if_fail (valid == TRUE);
+
+	gtk_list_store_set (presets, &iter, 0, new_val, -1);
+	write_config (data, TRUE);
+	update_tooltip (data);
+}
+
+static void
+freq_cell_edited_cb (GtkCellRendererText *cellrenderertext, gchar *path_str,
+						gchar *new_val, radio_gui *data)
+{
+	GtkTreeIter iter;
+	gboolean valid;
+	gint value;
+
+	value = parse_freq (new_val);
+
+	if (value < FREQ_MIN) value = FREQ_MIN;
+	if (value > FREQ_MAX) value = FREQ_MAX;
+
+	GtkListStore *presets = data->presets;
+	valid = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(presets),
+			&iter, path_str);
+	g_return_if_fail (valid == TRUE);
+
+	gtk_list_store_set (presets, &iter, 1, value, -1);
+	write_config (data, TRUE);
+	update_tooltip (data);
+}
+
+static void
+radio_plugin_create_options (XfcePanelPlugin *plugin, radio_gui *data)
+{
+	DBG("%d", data->freq);
+	GtkWidget *table;
+	GtkWidget *label;
+	GtkWidget *hbox;
+	GtkWidget *dialog;
+
+	GSList *show_signal_group = NULL;	// signal strength:
+	GtkWidget *signal_show;			//  - show
+	GtkWidget *signal_hide;			//  - hide
+	GSList *auto_update_display_group = NULL;// auto update display:
+	GtkWidget *auto_update_display_yes;	//  - show
+	GtkWidget *auto_update_display_no;	//  - hide
+	GtkWidget *startup_command_entry;	// post-down command
+	GtkWidget *shutdown_command_entry;	// post-down command
+	GtkWidget *device_entry;		// v4l-device
+	GSList *scroll_group = NULL;		// scroll action:
+	GtkWidget *frequency_button;		//  - change frequency
+	GtkWidget *preset_button;		//  - change preset
+	GtkWidget *preset_box;
+	GtkWidget *button_box;
+	GtkWidget *notebook;
+	GtkWidget *label_properties;
+	GtkWidget *label_presets;
+	GtkWidget *scrolled_window;
+	GtkWidget *list_view;
+	GtkTreeSelection *selection;
+	GtkCellRenderer *cellrenderer;
+	GtkTreeViewColumn *list_column;
+
+	xfce_panel_plugin_block_menu (plugin);
+
+	dialog = gtk_dialog_new_with_buttons (_("Properties"),
+		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);
+
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 2);
+
+	g_signal_connect (dialog, "response",
+			G_CALLBACK (radio_plugin_dialog_response), data);
+
+	list_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(data->presets));
+	gtk_widget_set_size_request(list_view, 200, 150);
+	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list_view), FALSE);
+	gtk_widget_show(list_view);
+
+	cellrenderer = gtk_cell_renderer_text_new();
+	g_object_set (G_OBJECT (cellrenderer),
+		"mode", GTK_CELL_RENDERER_MODE_EDITABLE,
+		"editable", TRUE, NULL);
+	list_column = gtk_tree_view_column_new_with_attributes
+					(NULL, cellrenderer, "text", 0, NULL);
+	gtk_tree_view_column_set_min_width(list_column, 300);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), list_column);
+	g_signal_connect(GTK_OBJECT(cellrenderer), "edited",
+			GTK_SIGNAL_FUNC(name_cell_edited_cb), (gpointer)data);
+
+	cellrenderer = gtk_cell_renderer_text_new();
+	g_object_set (G_OBJECT (cellrenderer),
+		"mode", GTK_CELL_RENDERER_MODE_EDITABLE,
+		"editable", TRUE, \
+		"xalign", 1.0f, NULL);
+	list_column = gtk_tree_view_column_new_with_attributes
+			(NULL, cellrenderer, "text", 1, NULL);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), list_column);
+	gtk_tree_view_column_set_cell_data_func (list_column, cellrenderer,
+						cell_float_to_text_cb,
+						NULL, NULL);
+	g_signal_connect(GTK_OBJECT(cellrenderer), "edited",
+			GTK_SIGNAL_FUNC(freq_cell_edited_cb), (gpointer)data);
+
+	button_box = gtk_hbox_new(FALSE, 0);
+
+	GtkWidget *add_button  = gtk_button_new_from_stock(GTK_STOCK_ADD);
+	GtkWidget *del_button  = gtk_button_new_from_stock(GTK_STOCK_DELETE);
+	GtkWidget *up_button   = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
+	GtkWidget *down_button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
+
+	gtk_box_pack_end(GTK_BOX(button_box), del_button, FALSE, FALSE, 0);
+	gtk_box_pack_end(GTK_BOX(button_box), add_button, FALSE, FALSE, 0);
+	gtk_box_pack_end(GTK_BOX(button_box), up_button,  FALSE, FALSE, 0);
+	gtk_box_pack_end(GTK_BOX(button_box), down_button,FALSE, FALSE, 0);
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
+	gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+	g_object_set_data(G_OBJECT(selection), "data", data);
+
+	g_signal_connect(GTK_OBJECT(add_button), "clicked",
+		GTK_SIGNAL_FUNC( add_button_clicked_cb), selection);
+	g_signal_connect(GTK_OBJECT(del_button), "clicked",
+		GTK_SIGNAL_FUNC( del_button_clicked_cb), selection);
+	g_signal_connect(GTK_OBJECT(up_button), "clicked",
+		GTK_SIGNAL_FUNC(up_button_clicked_cb), selection);
+	g_signal_connect(GTK_OBJECT(down_button), "clicked",
+		GTK_SIGNAL_FUNC(down_button_clicked_cb), selection);
+	g_signal_connect(GTK_OBJECT(list_view), "key-press-event",
+		GTK_SIGNAL_FUNC(list_view_key_press_event_cb), selection);
+
+	scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+	gtk_container_add(GTK_CONTAINER(scrolled_window), list_view);
+	gtk_scrolled_window_set_shadow_type(
+					GTK_SCROLLED_WINDOW(scrolled_window),
+					GTK_SHADOW_IN);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+					GTK_POLICY_AUTOMATIC,
+					GTK_POLICY_AUTOMATIC);
+	gtk_widget_show(scrolled_window);
+
+	preset_box = gtk_vbox_new(FALSE, 4);
+	gtk_box_pack_start(GTK_BOX(preset_box), scrolled_window,
+			TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(preset_box), button_box,
+			FALSE, FALSE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER(preset_box), 4);
+	gtk_widget_show_all (preset_box);
+
+	table = gtk_table_new(4, 2, FALSE);
+	gtk_container_set_border_width (GTK_CONTAINER(table), 4);
+	gtk_widget_show(table);
+
+	notebook = gtk_notebook_new ();
+	gtk_notebook_set_tab_pos (GTK_NOTEBOOK(notebook), GTK_POS_TOP);
+	gtk_notebook_set_show_tabs (GTK_NOTEBOOK(notebook), TRUE);
+	label_properties = gtk_label_new (_("Properties"));
+	label_presets =	gtk_label_new (_("Presets"));
+	gtk_notebook_append_page (GTK_NOTEBOOK(notebook), preset_box,
+								label_presets);
+	gtk_notebook_append_page (GTK_NOTEBOOK(notebook), table,
+							label_properties);
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), notebook,
+								TRUE, TRUE, 0);
+	gtk_widget_show (notebook);
+
+	// V4L device
+	label = gtk_label_new (_("V4L device"));
+	gtk_widget_show (label);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL,
+								0, 0, 0);
+	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+	// Show the signal strength
+	label = gtk_label_new (_("Display signal strength"));
+	gtk_widget_show (label);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL,
+								0, 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (hbox);
+	gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 1, 2, GTK_FILL,
+							GTK_FILL, 0, 0);
+
+	signal_show = gtk_radio_button_new_with_label (NULL, _("yes"));
+	gtk_widget_show (signal_show);
+	gtk_box_pack_start (GTK_BOX (hbox), signal_show, FALSE, FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (signal_show),
+							show_signal_group);
+	show_signal_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON
+							(signal_show));
+
+	signal_hide = gtk_radio_button_new_with_label (show_signal_group,
+								_("no"));
+	gtk_widget_show (signal_hide);
+
+	gtk_box_pack_start (GTK_BOX (hbox), signal_hide, FALSE, FALSE, 0);
+
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (signal_show),
+							data->show_signal);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (signal_hide),
+							!data->show_signal);
+
+	// Auto-update the display
+	label = gtk_label_new (_("Synchronize state with the card"));
+	gtk_widget_show (label);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_FILL,
+								0, 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (hbox);
+	gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 2, 3, GTK_FILL,
+							GTK_FILL, 0, 0);
+	auto_update_display_yes = gtk_radio_button_new_with_label (NULL,
+								_("yes"));
+	gtk_widget_show (auto_update_display_yes);
+	gtk_box_pack_start (GTK_BOX (hbox), auto_update_display_yes, FALSE,
+								FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (auto_update_display_yes),
+						auto_update_display_group);
+	auto_update_display_group = gtk_radio_button_get_group
+				(GTK_RADIO_BUTTON (auto_update_display_yes));
+
+	auto_update_display_no = gtk_radio_button_new_with_label
+					(auto_update_display_group, _("no"));
+	gtk_widget_show (auto_update_display_no);
+
+	gtk_box_pack_start (GTK_BOX (hbox), auto_update_display_no, FALSE,
+								FALSE, 0);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
+			(auto_update_display_yes), data->auto_update_display);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
+			(auto_update_display_no), !data->auto_update_display);
+
+	// Post-startup command
+	label = gtk_label_new (_("Execute command after startup"));
+	gtk_widget_show (label);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5, GTK_FILL,
+								0, 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+	startup_command_entry = gtk_entry_new_with_max_length
+							(MAX_COMMAND_LENGTH);
+	gtk_entry_set_text (GTK_ENTRY (startup_command_entry),
+							data->startup_command);
+	gtk_widget_show (startup_command_entry);
+	gtk_table_attach (GTK_TABLE (table), startup_command_entry, 1, 2, 4, 5,
+					GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+	// Post-shutdown command
+	label = gtk_label_new (_("Execute command after shutdown"));
+	gtk_widget_show (label);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 5, 6, GTK_FILL,
+								0, 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+	shutdown_command_entry = gtk_entry_new_with_max_length
+							(MAX_COMMAND_LENGTH);
+	gtk_entry_set_text (GTK_ENTRY (shutdown_command_entry),
+							data->shutdown_command);
+	gtk_widget_show (shutdown_command_entry);
+	gtk_table_attach (GTK_TABLE (table), shutdown_command_entry, 1, 2, 5, 6,
+					GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+	// Mouse-scrolling
+	label = gtk_label_new (_("Mouse scrolling changes"));
+	gtk_widget_show (label);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, GTK_FILL,
+								0, 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (hbox);
+	gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 3, 4, GTK_FILL,
+							GTK_FILL, 0, 0);
+
+	frequency_button = gtk_radio_button_new_with_label (NULL,
+							_("frequency"));
+	gtk_widget_show (frequency_button);
+	gtk_box_pack_start (GTK_BOX (hbox), frequency_button, FALSE, FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (frequency_button),
+								scroll_group);
+	scroll_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON
+							(frequency_button));
+
+	preset_button = gtk_radio_button_new_with_label (NULL, _("preset"));
+	gtk_widget_show (preset_button);
+	gtk_box_pack_start (GTK_BOX (hbox), preset_button, FALSE, FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (preset_button),
+								scroll_group);
+	scroll_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON
+							(preset_button));
+
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (frequency_button),
+						data->scroll == CHANGE_FREQ);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (preset_button),
+						data->scroll == CHANGE_PRESET);
+
+	device_entry = gtk_entry_new_with_max_length (MAX_DEVICE_NAME_LENGTH);
+	gtk_entry_set_text (GTK_ENTRY (device_entry), data->device);
+	gtk_widget_show (device_entry);
+	gtk_table_attach (GTK_TABLE(table), device_entry, 1, 2, 0, 1,
+					GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+	g_signal_connect ((gpointer) startup_command_entry, "changed",
+			G_CALLBACK (radio_startup_command_changed), data);
+	g_signal_connect ((gpointer) shutdown_command_entry, "changed",
+			G_CALLBACK (radio_shutdown_command_changed), data);
+	g_signal_connect ((gpointer) device_entry, "changed",
+			G_CALLBACK (radio_device_changed), data);
+	g_signal_connect (G_OBJECT (signal_show), "toggled",
+			G_CALLBACK (radio_show_signal_changed), data);
+	g_signal_connect (G_OBJECT (auto_update_display_yes), "toggled",
+			G_CALLBACK (radio_auto_update_display_changed), data);
+	g_signal_connect (G_OBJECT (frequency_button), "toggled",
+			G_CALLBACK (radio_scroll_type_changed), data);
+
+	gtk_widget_show (dialog);
+}
+
+static void
+radio_plugin_set_size (XfcePanelPlugin *plugin, int size, radio_gui *data)
+{
+	gtk_widget_set_size_request (data->signal_bar, size - BORDER, BORDER);
+}
+
+static void
+write_config_signal (XfcePanelPlugin *plugin, radio_gui *data)
+{
+	write_config (data, TRUE);
+}
+
+static void
+write_config (radio_gui *data, gboolean save_presets)
+{
+	XfceRc *rc;
+	int i;
+
+	if (!(rc = get_config_rc ()))
+		return;
+
+	xfce_rc_set_group	(rc, "radio plugin");
+
+	xfce_rc_write_entry	(rc, "dev", data->device);
+	xfce_rc_write_entry	(rc, "startup_cmd", data->startup_command);
+	xfce_rc_write_entry	(rc, "shutdown_cmd", data->shutdown_command);
+
+	xfce_rc_write_int_entry	(rc, "frq", data->freq);
+	xfce_rc_write_int_entry	(rc, "scroll", data->scroll);
+	xfce_rc_write_bool_entry(rc, "show_signal", data->show_signal);
+	xfce_rc_write_bool_entry(rc, "update_display",
+						data->auto_update_display);
+
+	if (!save_presets)
+	{
+		xfce_rc_close (rc);
+		return;
+	}
+
+	gchar *name;
+	gint freq;
+	GtkTreeIter iter;
+	GtkTreeModel *presets = GTK_TREE_MODEL(data->presets);
+	gboolean valid = gtk_tree_model_get_iter_first (presets, &iter);
+
+	// We start at 10 since there seems to be a problem loading keys which
+	// are only 1 char long
+	i = 10;
+	while (valid)
+	{
+		if (i == 10)
+		{
+			xfce_rc_delete_group (rc, PRESET_NAMES, FALSE);
+			xfce_rc_delete_group (rc, PRESET_FREQS, FALSE);
+		}
+
+		gtk_tree_model_get (presets, &iter, 0, &name, 1, &freq, -1);
+		gchar *key = g_strdup_printf ("%d", i);
+		DBG("freq=%d, name=%s", freq, name);
+
+		xfce_rc_set_group (rc, PRESET_NAMES);
+		xfce_rc_write_entry (rc, key, name);
+		xfce_rc_set_group (rc, PRESET_FREQS);
+		xfce_rc_write_int_entry (rc, key, freq);
+
+		g_free (name);
+		g_free (key);
+		i++;
+		valid = gtk_tree_model_iter_next (presets, &iter);
+	}
+	xfce_rc_close (rc);
+}
+
+static void
+import_old_config (XfcePanelPlugin *plugin, radio_gui *data)
+{
+	const char *value;
+	char *file;
+	XfceRc *rc;
+
+	// Abort if there's nothing to be imported
+	if (!(file = xfce_panel_plugin_lookup_rc_file (plugin)))
+		return;
+
+	DBG ("Importing data from old conig file %s", file);
+
+	rc = xfce_rc_simple_open (file, TRUE);
+	g_free (file);
+
+	if (!rc)
+		return;
+
+	xfce_rc_set_group (rc, "radio plugin");
+
+	data->freq = xfce_rc_read_int_entry (rc, "frq", FREQ_INIT);
+	data->scroll = xfce_rc_read_int_entry (rc, "scroll", CHANGE_FREQ);
+	data->show_signal = xfce_rc_read_bool_entry (rc, "show_signal", TRUE);
+
+	if ((value = xfce_rc_read_entry (rc, "dev", NULL)) && *value)
+		strncpy (data->device, value, MAX_DEVICE_NAME_LENGTH);
+	if ((value = xfce_rc_read_entry (rc, "startup_cmd", NULL)) && *value)
+		strncpy (data->startup_command, value, MAX_COMMAND_LENGTH);
+	if ((value = xfce_rc_read_entry (rc, "shutdown_cmd", NULL)) && *value)
+		strncpy (data->shutdown_command, value, MAX_COMMAND_LENGTH);
+
+	GtkTreeIter iter;
+	GtkListStore *presets = data->presets;
+
+	gchar** entries = xfce_rc_get_entries (rc, "presets");
+	if (entries != NULL)
+	{
+		gchar **entry;
+		entry = entries;
+
+		xfce_rc_set_group (rc, "presets");
+
+		while (*entry)
+		{
+			if ((value = xfce_rc_read_entry (rc, *entry, NULL))
+								&& *value)
+			{
+				gint vfreq = atoi (*entry);
+				const gchar *vname = value;
+
+				DBG("freq=%d, name=%s", vfreq, vname);
+
+				gtk_list_store_append (presets, &iter);
+				gtk_list_store_set (presets, &iter, 0, vname,
+								1, vfreq, -1);
+			}
+			entry++;
+		}
+	}
+	g_strfreev (entries);
+	xfce_rc_close (rc);
+
+	write_config (data, TRUE);
+}
+
+static void
+read_config (XfcePanelPlugin *plugin, radio_gui *data)
+{
+	const char *value;
+	XfceRc *rc;
+
+	if (!(rc = get_config_rc ()))
+		return;
+
+	xfce_rc_set_group (rc, "radio plugin");
+
+	data->freq = xfce_rc_read_int_entry (rc, "frq", FREQ_INIT);
+	data->scroll = xfce_rc_read_int_entry (rc, "scroll", CHANGE_FREQ);
+	data->show_signal = xfce_rc_read_bool_entry (rc, "show_signal", TRUE);
+	data->auto_update_display = xfce_rc_read_bool_entry
+						(rc, "update_display", TRUE);
+
+	if ((value = xfce_rc_read_entry (rc, "dev", NULL)) && *value)
+		strncpy (data->device, value, MAX_DEVICE_NAME_LENGTH);
+
+	if ((value = xfce_rc_read_entry (rc, "startup_cmd", NULL)) && *value)
+		strncpy (data->startup_command, value, MAX_COMMAND_LENGTH);
+
+	if ((value = xfce_rc_read_entry (rc, "shutdown_cmd", NULL)) && *value)
+		strncpy (data->shutdown_command, value, MAX_COMMAND_LENGTH);
+
+	GtkTreeIter iter;
+	g_return_if_fail (data->presets == NULL);
+	data->presets = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+	GtkListStore *presets = data->presets;
+
+	gchar** names = xfce_rc_get_entries (rc, PRESET_NAMES);
+	gchar** freqs = xfce_rc_get_entries (rc, PRESET_FREQS);
+
+	if (names == NULL || freqs == NULL) {
+		import_old_config (plugin, data);
+		xfce_rc_close (rc);
+		return;
+	}
+	gchar **ename = names;
+	gchar **efreq = freqs;
+
+	while (*ename || *efreq)
+	{
+		xfce_rc_set_group (rc, PRESET_NAMES);
+		const gchar *vname = xfce_rc_read_entry (rc, *ename,
+							_(DEFAULT_NAME));
+		xfce_rc_set_group (rc, PRESET_FREQS);
+		gint vfreq = xfce_rc_read_int_entry (rc, *efreq, FREQ_MIN);
+		DBG("freq=%d, name=%s", vfreq, vname);
+
+		gtk_list_store_append (presets, &iter);
+		gtk_list_store_set (presets, &iter, 0, vname, 1, vfreq, -1);
+		ename++; efreq++;
+	}
+	g_strfreev (names);
+	g_strfreev (freqs);
+	xfce_rc_close (rc);
+}
+
+static void
+radio_plugin_construct (XfcePanelPlugin *plugin)
+{
+	xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+	radio_gui *data = plugin_control_new (plugin);
+	read_config (plugin, data);
+
+	xfce_panel_plugin_menu_show_configure (plugin);
+
+	g_signal_connect (plugin, "configure-plugin",
+			G_CALLBACK (radio_plugin_create_options), data);
+	g_signal_connect (plugin, "size-changed", G_CALLBACK
+						(radio_plugin_set_size), data);
+	g_signal_connect (plugin, "free-data", G_CALLBACK (radio_free), data);
+	g_signal_connect (plugin, "save", G_CALLBACK (write_config_signal),
+									data);
+}
+
+XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL (radio_plugin_construct);

Copied: xfce4-radio-plugin/trunk/panel-plugin/xfce4-radio.h (from rev 6500, xfce4-radio-plugin/branches/newincludes/panel-plugin/xfce4-radio.h)
===================================================================
--- xfce4-radio-plugin/trunk/panel-plugin/xfce4-radio.h	                        (rev 0)
+++ xfce4-radio-plugin/trunk/panel-plugin/xfce4-radio.h	2009-01-19 18:11:20 UTC (rev 6501)
@@ -0,0 +1,96 @@
+/*
+ * radio plugin for Xfce4.
+ *
+ * Copyright 2006-2008 Stefan Ott, All rights reserved.
+ *
+ * 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 _XFCE4_RADIO_H
+#define _XFCE4_RADIO_H
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <fcntl.h>
+
+#include <sys/ioctl.h>
+#include <linux/videodev.h>
+
+#include <libxfce4panel/xfce-panel-plugin.h>
+
+#define FREQ_MIN		8750
+#define FREQ_MAX		10800
+#define FREQ_INIT		10795
+#define FREQ_STEP		10
+
+#define MAX_LABEL_LENGTH	7
+#define MAX_DEVICE_NAME_LENGTH	32
+#define MAX_COMMAND_LENGTH	512
+
+#define COLOR_SIGNAL_LOW	"#ff0000"
+#define COLOR_SIGNAL_MED	"#ffff00"
+#define COLOR_SIGNAL_HIGH	"#00ff00"
+
+#define BORDER 8
+
+#define DEFAULT_NAME "unnamed"
+#define PRESET_NAMES "preset_names"
+#define PRESET_FREQS "preset_freqs"
+
+const char RADIO_CONFIG[] = "xfce4/panel/radio.rc";
+
+typedef enum {
+	CHANGE_FREQ,
+	CHANGE_PRESET
+} mouse_scroll_reaction;
+
+struct radio_preset_st {
+	int			freq;
+	gchar			*name;
+	struct radio_preset_st*	next;
+};
+
+typedef struct radio_preset_st radio_preset;
+
+typedef struct {
+	GtkWidget*		box;
+	GtkWidget*		ebox;
+	GtkWidget*		label;
+	GtkWidget*		signal_bar;
+	GtkTooltips*		tooltips;
+
+	int			signal_timeout_id;
+	int			radio_timeout_id;
+
+	gboolean		on;
+	gboolean		show_signal;
+	gboolean		auto_update_display;
+	int			freq;
+	char			device [MAX_DEVICE_NAME_LENGTH];
+	char			startup_command [MAX_COMMAND_LENGTH];
+	char			shutdown_command [MAX_COMMAND_LENGTH];
+	GtkListStore*		presets;
+	mouse_scroll_reaction	scroll;
+
+	// this seems to be card specific and we can't seem to get the maximum
+	// possible value for a given card from v4l
+	double			max_signal_strength;
+
+	XfcePanelPlugin		*plugin;
+} radio_gui;
+
+static void read_config (XfcePanelPlugin *, radio_gui *);
+static void write_config (radio_gui *i, gboolean);
+#endif




More information about the Goodies-commits mailing list