summaryrefslogtreecommitdiffstats
path: root/kradio3/plugins/v4lradio
diff options
context:
space:
mode:
Diffstat (limited to 'kradio3/plugins/v4lradio')
-rw-r--r--kradio3/plugins/v4lradio/Makefile.am18
-rw-r--r--kradio3/plugins/v4lradio/linux/videodev.h432
-rw-r--r--kradio3/plugins/v4lradio/linux/videodev2.h940
-rw-r--r--kradio3/plugins/v4lradio/po/Makefile.am3
-rw-r--r--kradio3/plugins/v4lradio/po/de.po362
-rw-r--r--kradio3/plugins/v4lradio/po/ru.po362
-rw-r--r--kradio3/plugins/v4lradio/v4lcfg_interfaces.cpp193
-rw-r--r--kradio3/plugins/v4lradio/v4lcfg_interfaces.h151
-rw-r--r--kradio3/plugins/v4lradio/v4lradio-configuration-ui.ui966
-rw-r--r--kradio3/plugins/v4lradio/v4lradio-configuration.cpp648
-rw-r--r--kradio3/plugins/v4lradio/v4lradio-configuration.h147
-rw-r--r--kradio3/plugins/v4lradio/v4lradio.cpp1621
-rw-r--r--kradio3/plugins/v4lradio/v4lradio.h265
13 files changed, 6108 insertions, 0 deletions
diff --git a/kradio3/plugins/v4lradio/Makefile.am b/kradio3/plugins/v4lradio/Makefile.am
new file mode 100644
index 0000000..093d346
--- /dev/null
+++ b/kradio3/plugins/v4lradio/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = po .
+
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+
+libkradio_LTLIBRARIES = libv4lradio.la
+libv4lradio_la_SOURCES = v4lcfg_interfaces.cpp v4lradio-configuration.cpp \
+ v4lradio-configuration-ui.ui v4lradio.cpp
+libv4lradio_la_LDFLAGS = -module -avoid-version $(KDE_RPATH) $(all_libraries)
+
+noinst_HEADERS = v4lcfg_interfaces.h v4lradio-configuration.h v4lradio.h
+
+#messages: rc.cpp
+# $(XGETTEXT) *.cpp *.h -o po/kradio-v4lradio.pot
+
+messages: rc.cpp
+ $(EXTRACTRC) *.rc *.ui >> rc.cpp
+ $(XGETTEXT) rc.cpp *.h *.cpp -o po/kradio-v4lradio.pot
diff --git a/kradio3/plugins/v4lradio/linux/videodev.h b/kradio3/plugins/v4lradio/linux/videodev.h
new file mode 100644
index 0000000..e16a8a8
--- /dev/null
+++ b/kradio3/plugins/v4lradio/linux/videodev.h
@@ -0,0 +1,432 @@
+#ifndef __LINUX_VIDEODEV_H
+#define __LINUX_VIDEODEV_H
+
+#include <linux/types.h>
+#include <linux/version.h>
+//#include <linux/device.h>
+
+//#define HAVE_V4L2 1
+//#include <linux/videodev2.h>
+
+#ifdef __KERNEL__
+
+#include <linux/poll.h>
+#include <linux/mm.h>
+
+struct video_device
+{
+ /* device info */
+ struct device *dev;
+ char name[32];
+ int type; /* v4l1 */
+ int type2; /* v4l2 */
+ int hardware;
+ int minor;
+
+ /* device ops + callbacks */
+ struct file_operations *fops;
+ void (*release)(struct video_device *vfd);
+
+
+#if 1 /* to be removed in 2.7.x */
+ /* obsolete -- fops->owner is used instead */
+ struct module *owner;
+ /* dev->driver_data will be used instead some day.
+ * Use the video_{get|set}_drvdata() helper functions,
+ * so the switch over will be transparent for you.
+ * Or use {pci|usb}_{get|set}_drvdata() directly. */
+ void *priv;
+#endif
+
+ /* for videodev.c intenal usage -- please don't touch */
+ int users; /* video_exclusive_{open|close} ... */
+ struct semaphore lock; /* ... helper function uses these */
+ char devfs_name[64]; /* devfs */
+ struct class_device class_dev; /* sysfs */
+};
+
+#define VIDEO_MAJOR 81
+
+#define VFL_TYPE_GRABBER 0
+#define VFL_TYPE_VBI 1
+#define VFL_TYPE_RADIO 2
+#define VFL_TYPE_VTX 3
+
+extern int video_register_device(struct video_device *, int type, int nr);
+extern void video_unregister_device(struct video_device *);
+extern struct video_device* video_devdata(struct file*);
+
+#define to_video_device(cd) container_of(cd, struct video_device, class_dev)
+static inline void
+video_device_create_file(struct video_device *vfd,
+ struct class_device_attribute *attr)
+{
+ class_device_create_file(&vfd->class_dev, attr);
+}
+
+/* helper functions to alloc / release struct video_device, the
+ later can be used for video_device->release() */
+struct video_device *video_device_alloc(void);
+void video_device_release(struct video_device *vfd);
+
+/* helper functions to access driver private data. */
+static inline void *video_get_drvdata(struct video_device *dev)
+{
+ return dev->priv;
+}
+
+static inline void video_set_drvdata(struct video_device *dev, void *data)
+{
+ dev->priv = data;
+}
+
+extern int video_exclusive_open(struct inode *inode, struct file *file);
+extern int video_exclusive_release(struct inode *inode, struct file *file);
+extern int video_usercopy(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg,
+ int (*func)(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg));
+#endif /* __KERNEL__ */
+
+#define VID_TYPE_CAPTURE 1 /* Can capture */
+#define VID_TYPE_TUNER 2 /* Can tune */
+#define VID_TYPE_TELETEXT 4 /* Does teletext */
+#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
+#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
+#define VID_TYPE_CLIPPING 32 /* Can clip */
+#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
+#define VID_TYPE_SCALES 128 /* Scalable */
+#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
+#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
+#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
+#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
+#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
+#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
+
+struct video_capability
+{
+ char name[32];
+ int type;
+ int channels; /* Num channels */
+ int audios; /* Num audio devices */
+ int maxwidth; /* Supported width */
+ int maxheight; /* And height */
+ int minwidth; /* Supported width */
+ int minheight; /* And height */
+};
+
+
+struct video_channel
+{
+ int channel;
+ char name[32];
+ int tuners;
+ __u32 flags;
+#define VIDEO_VC_TUNER 1 /* Channel has a tuner */
+#define VIDEO_VC_AUDIO 2 /* Channel has audio */
+ __u16 type;
+#define VIDEO_TYPE_TV 1
+#define VIDEO_TYPE_CAMERA 2
+ __u16 norm; /* Norm set by channel */
+};
+
+struct video_tuner
+{
+ int tuner;
+ char name[32];
+ unsigned long rangelow, rangehigh; /* Tuner range */
+ __u32 flags;
+#define VIDEO_TUNER_PAL 1
+#define VIDEO_TUNER_NTSC 2
+#define VIDEO_TUNER_SECAM 4
+#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
+#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */
+#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
+#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */
+#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */
+ __u16 mode; /* PAL/NTSC/SECAM/OTHER */
+#define VIDEO_MODE_PAL 0
+#define VIDEO_MODE_NTSC 1
+#define VIDEO_MODE_SECAM 2
+#define VIDEO_MODE_AUTO 3
+ __u16 signal; /* Signal strength 16bit scale */
+};
+
+struct video_picture
+{
+ __u16 brightness;
+ __u16 hue;
+ __u16 colour;
+ __u16 contrast;
+ __u16 whiteness; /* Black and white only */
+ __u16 depth; /* Capture depth */
+ __u16 palette; /* Palette in use */
+#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
+#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
+#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
+#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
+#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
+#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
+#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
+#define VIDEO_PALETTE_YUYV 8
+#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
+#define VIDEO_PALETTE_YUV420 10
+#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
+#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
+#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
+#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
+#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
+#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
+#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
+#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
+};
+
+struct video_audio
+{
+ int audio; /* Audio channel */
+ __u16 volume; /* If settable */
+ __u16 bass, treble;
+ __u32 flags;
+#define VIDEO_AUDIO_MUTE 1
+#define VIDEO_AUDIO_MUTABLE 2
+#define VIDEO_AUDIO_VOLUME 4
+#define VIDEO_AUDIO_BASS 8
+#define VIDEO_AUDIO_TREBLE 16
+#define VIDEO_AUDIO_BALANCE 32
+ char name[16];
+#define VIDEO_SOUND_MONO 1
+#define VIDEO_SOUND_STEREO 2
+#define VIDEO_SOUND_LANG1 4
+#define VIDEO_SOUND_LANG2 8
+ __u16 mode;
+ __u16 balance; /* Stereo balance */
+ __u16 step; /* Step actual volume uses */
+};
+
+struct video_clip
+{
+ __s32 x,y;
+ __s32 width, height;
+ struct video_clip *next; /* For user use/driver use only */
+};
+
+struct video_window
+{
+ __u32 x,y; /* Position of window */
+ __u32 width,height; /* Its size */
+ __u32 chromakey;
+ __u32 flags;
+ struct video_clip *clips; /* Set only */
+ int clipcount;
+#define VIDEO_WINDOW_INTERLACE 1
+#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
+#define VIDEO_CLIP_BITMAP -1
+/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
+#define VIDEO_CLIPMAP_SIZE (128 * 625)
+};
+
+struct video_capture
+{
+ __u32 x,y; /* Offsets into image */
+ __u32 width, height; /* Area to capture */
+ __u16 decimation; /* Decimation divider */
+ __u16 flags; /* Flags for capture */
+#define VIDEO_CAPTURE_ODD 0 /* Temporal */
+#define VIDEO_CAPTURE_EVEN 1
+};
+
+struct video_buffer
+{
+ void *base;
+ int height,width;
+ int depth;
+ int bytesperline;
+};
+
+struct video_mmap
+{
+ unsigned int frame; /* Frame (0 - n) for double buffer */
+ int height,width;
+ unsigned int format; /* should be VIDEO_PALETTE_* */
+};
+
+struct video_key
+{
+ __u8 key[8];
+ __u32 flags;
+};
+
+
+#define VIDEO_MAX_FRAME 32
+
+struct video_mbuf
+{
+ int size; /* Total memory to map */
+ int frames; /* Frames */
+ int offsets[VIDEO_MAX_FRAME];
+};
+
+
+#define VIDEO_NO_UNIT (-1)
+
+
+struct video_unit
+{
+ int video; /* Video minor */
+ int vbi; /* VBI minor */
+ int radio; /* Radio minor */
+ int audio; /* Audio minor */
+ int teletext; /* Teletext minor */
+};
+
+struct vbi_format {
+ __u32 sampling_rate; /* in Hz */
+ __u32 samples_per_line;
+ __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */
+ __s32 start[2]; /* starting line for each frame */
+ __u32 count[2]; /* count of lines for each frame */
+ __u32 flags;
+#define VBI_UNSYNC 1 /* can distingues between top/bottom field */
+#define VBI_INTERLACED 2 /* lines are interlaced */
+};
+
+/* video_info is biased towards hardware mpeg encode/decode */
+/* but it could apply generically to any hardware compressor/decompressor */
+struct video_info
+{
+ __u32 frame_count; /* frames output since decode/encode began */
+ __u32 h_size; /* current unscaled horizontal size */
+ __u32 v_size; /* current unscaled veritcal size */
+ __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */
+ __u32 picture_type; /* current picture type */
+ __u32 temporal_reference; /* current temporal reference */
+ __u8 user_data[256]; /* user data last found in compressed stream */
+ /* user_data[0] contains user data flags, user_data[1] has count */
+};
+
+/* generic structure for setting playback modes */
+struct video_play_mode
+{
+ int mode;
+ int p1;
+ int p2;
+};
+
+/* for loading microcode / fpga programming */
+struct video_code
+{
+ char loadwhat[16]; /* name or tag of file being passed */
+ int datasize;
+ __u8 *data;
+};
+
+#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */
+#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */
+#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */
+#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */
+#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */
+#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */
+#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */
+#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */
+#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */
+#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
+#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */
+#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */
+#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */
+#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */
+#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */
+#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */
+#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */
+#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */
+#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */
+#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */
+#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */
+#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */
+#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */
+#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */
+#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */
+#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */
+#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */
+#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */
+#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */
+
+
+#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */
+
+/* VIDIOCSWRITEMODE */
+#define VID_WRITE_MPEG_AUD 0
+#define VID_WRITE_MPEG_VID 1
+#define VID_WRITE_OSD 2
+#define VID_WRITE_TTX 3
+#define VID_WRITE_CC 4
+#define VID_WRITE_MJPEG 5
+
+/* VIDIOCSPLAYMODE */
+#define VID_PLAY_VID_OUT_MODE 0
+ /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */
+#define VID_PLAY_GENLOCK 1
+ /* p1: 0 = OFF, 1 = ON */
+ /* p2: GENLOCK FINE DELAY value */
+#define VID_PLAY_NORMAL 2
+#define VID_PLAY_PAUSE 3
+#define VID_PLAY_SINGLE_FRAME 4
+#define VID_PLAY_FAST_FORWARD 5
+#define VID_PLAY_SLOW_MOTION 6
+#define VID_PLAY_IMMEDIATE_NORMAL 7
+#define VID_PLAY_SWITCH_CHANNELS 8
+#define VID_PLAY_FREEZE_FRAME 9
+#define VID_PLAY_STILL_MODE 10
+#define VID_PLAY_MASTER_MODE 11
+ /* p1: see below */
+#define VID_PLAY_MASTER_NONE 1
+#define VID_PLAY_MASTER_VIDEO 2
+#define VID_PLAY_MASTER_AUDIO 3
+#define VID_PLAY_ACTIVE_SCANLINES 12
+ /* p1 = first active; p2 = last active */
+#define VID_PLAY_RESET 13
+#define VID_PLAY_END_MARK 14
+
+
+
+#define VID_HARDWARE_BT848 1
+#define VID_HARDWARE_QCAM_BW 2
+#define VID_HARDWARE_PMS 3
+#define VID_HARDWARE_QCAM_C 4
+#define VID_HARDWARE_PSEUDO 5
+#define VID_HARDWARE_SAA5249 6
+#define VID_HARDWARE_AZTECH 7
+#define VID_HARDWARE_SF16MI 8
+#define VID_HARDWARE_RTRACK 9
+#define VID_HARDWARE_ZOLTRIX 10
+#define VID_HARDWARE_SAA7146 11
+#define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */
+#define VID_HARDWARE_RTRACK2 13
+#define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */
+#define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */
+#define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */
+#define VID_HARDWARE_BROADWAY 17 /* Broadway project */
+#define VID_HARDWARE_GEMTEK 18
+#define VID_HARDWARE_TYPHOON 19
+#define VID_HARDWARE_VINO 20 /* SGI Indy Vino */
+#define VID_HARDWARE_CADET 21 /* Cadet radio */
+#define VID_HARDWARE_TRUST 22 /* Trust FM Radio */
+#define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */
+#define VID_HARDWARE_CPIA 24
+#define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */
+#define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */
+#define VID_HARDWARE_OV511 27
+#define VID_HARDWARE_ZR356700 28 /* Zoran 36700 series */
+#define VID_HARDWARE_W9966 29
+#define VID_HARDWARE_SE401 30 /* SE401 USB webcams */
+#define VID_HARDWARE_PWC 31 /* Philips webcams */
+#define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */
+#define VID_HARDWARE_CPIA2 33
+#define VID_HARDWARE_VICAM 34
+#define VID_HARDWARE_SF16FMR2 35
+#endif /* __LINUX_VIDEODEV_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/kradio3/plugins/v4lradio/linux/videodev2.h b/kradio3/plugins/v4lradio/linux/videodev2.h
new file mode 100644
index 0000000..c41831a
--- /dev/null
+++ b/kradio3/plugins/v4lradio/linux/videodev2.h
@@ -0,0 +1,940 @@
+#ifndef __LINUX_VIDEODEV2_H
+#define __LINUX_VIDEODEV2_H
+/*
+ * Video for Linux Two
+ *
+ * Header file for v4l or V4L2 drivers and applications, for
+ * Linux kernels 2.2.x or 2.4.x.
+ *
+ * See http://bytesex.org/v4l/ for API specs and other
+ * v4l2 documentation.
+ *
+ * Author: Bill Dirks <bdirks@pacbell.net>
+ * Justin Schoeman
+ * et al.
+ */
+
+#include <asm/types.h>
+#ifdef __KERNEL__
+#include <linux/time.h> /* need struct timeval */
+#endif
+
+/*
+ * M I S C E L L A N E O U S
+ */
+
+/* Four-character-code (FOURCC) */
+#define v4l2_fourcc(a,b,c,d)\
+ (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+
+/*
+ * E N U M S
+ */
+enum v4l2_field {
+ V4L2_FIELD_ANY = 0, /* driver can choose from none,
+ top, bottom, interlaced
+ depending on whatever it thinks
+ is approximate ... */
+ V4L2_FIELD_NONE = 1, /* this device has no fields ... */
+ V4L2_FIELD_TOP = 2, /* top field only */
+ V4L2_FIELD_BOTTOM = 3, /* bottom field only */
+ V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
+ V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one
+ buffer, top-bottom order */
+ V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */
+ V4L2_FIELD_ALTERNATE = 7 /* both fields alternating into
+ separate buffers */
+};
+#define V4L2_FIELD_HAS_TOP(field) \
+ ((field) == V4L2_FIELD_TOP ||\
+ (field) == V4L2_FIELD_INTERLACED ||\
+ (field) == V4L2_FIELD_SEQ_TB ||\
+ (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTTOM(field) \
+ ((field) == V4L2_FIELD_BOTTOM ||\
+ (field) == V4L2_FIELD_INTERLACED ||\
+ (field) == V4L2_FIELD_SEQ_TB ||\
+ (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTH(field) \
+ ((field) == V4L2_FIELD_INTERLACED ||\
+ (field) == V4L2_FIELD_SEQ_TB ||\
+ (field) == V4L2_FIELD_SEQ_BT)
+
+enum v4l2_buf_type {
+ V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
+ V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
+ V4L2_BUF_TYPE_VBI_CAPTURE = 4,
+ V4L2_BUF_TYPE_VBI_OUTPUT = 5,
+ V4L2_BUF_TYPE_PRIVATE = 0x80
+};
+
+enum v4l2_ctrl_type {
+ V4L2_CTRL_TYPE_INTEGER = 1,
+ V4L2_CTRL_TYPE_BOOLEAN = 2,
+ V4L2_CTRL_TYPE_MENU = 3,
+ V4L2_CTRL_TYPE_BUTTON = 4
+};
+
+enum v4l2_tuner_type {
+ V4L2_TUNER_RADIO = 1,
+ V4L2_TUNER_ANALOG_TV = 2
+};
+
+enum v4l2_memory {
+ V4L2_MEMORY_MMAP = 1,
+ V4L2_MEMORY_USERPTR = 2,
+ V4L2_MEMORY_OVERLAY = 3
+};
+
+/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
+enum v4l2_colorspace {
+ /* ITU-R 601 -- broadcast NTSC/PAL */
+ V4L2_COLORSPACE_SMPTE170M = 1,
+
+ /* 1125-Line (US) HDTV */
+ V4L2_COLORSPACE_SMPTE240M = 2,
+
+ /* HD and modern captures. */
+ V4L2_COLORSPACE_REC709 = 3,
+
+ /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
+ V4L2_COLORSPACE_BT878 = 4,
+
+ /* These should be useful. Assume 601 extents. */
+ V4L2_COLORSPACE_470_SYSTEM_M = 5,
+ V4L2_COLORSPACE_470_SYSTEM_BG = 6,
+
+ /* I know there will be cameras that send this. So, this is
+ * unspecified chromaticities and full 0-255 on each of the
+ * Y'CbCr components
+ */
+ V4L2_COLORSPACE_JPEG = 7,
+
+ /* For RGB colourspaces, this is probably a good start. */
+ V4L2_COLORSPACE_SRGB = 8
+};
+
+enum v4l2_priority {
+ V4L2_PRIORITY_UNSET = 0, /* not initialized */
+ V4L2_PRIORITY_BACKGROUND = 1,
+ V4L2_PRIORITY_INTERACTIVE = 2,
+ V4L2_PRIORITY_RECORD = 3,
+ V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE
+};
+
+struct v4l2_rect {
+ __s32 left;
+ __s32 top;
+ __s32 width;
+ __s32 height;
+};
+
+struct v4l2_fract {
+ __u32 numerator;
+ __u32 denominator;
+};
+
+/*
+ * D R I V E R C A P A B I L I T I E S
+ */
+struct v4l2_capability
+{
+ __u8 driver[16]; /* i.e. "bttv" */
+ __u8 card[32]; /* i.e. "Hauppauge WinTV" */
+ __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */
+ __u32 version; /* should use KERNEL_VERSION() */
+ __u32 capabilities; /* Device capabilities */
+ __u32 reserved[4];
+};
+
+/* Values for 'capabilities' field */
+#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
+#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
+#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
+#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a VBI capture device */
+#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a VBI output device */
+#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
+
+#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
+#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
+#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
+
+#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
+#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
+#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
+
+/*
+ * V I D E O I M A G E F O R M A T
+ */
+
+struct v4l2_pix_format
+{
+ __u32 width;
+ __u32 height;
+ __u32 pixelformat;
+ enum v4l2_field field;
+ __u32 bytesperline; /* for padding, zero if unused */
+ __u32 sizeimage;
+ enum v4l2_colorspace colorspace;
+ __u32 priv; /* private data, depends on pixelformat */
+};
+
+/* Pixel format FOURCC depth Description */
+#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */
+#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */
+#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */
+#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */
+#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */
+#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3') /* 24 BGR-8-8-8 */
+#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3') /* 24 RGB-8-8-8 */
+#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */
+#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */
+#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */
+#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */
+#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */
+#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16 YVU422 planar */
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16 YVU411 planar */
+#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */
+
+/* two planes -- one Y, one Cr + Cb interleaved */
+#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2') /* 12 Y/CbCr 4:2:0 */
+#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1') /* 12 Y/CrCb 4:2:0 */
+
+/* The following formats are not defined in the V4L2 specification */
+#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */
+#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */
+#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */
+
+/* compressed formats */
+#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */
+#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G') /* JFIF JPEG */
+#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d') /* 1394 */
+#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G') /* MPEG */
+
+/* Vendor-specific formats */
+#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
+
+/*
+ * F O R M A T E N U M E R A T I O N
+ */
+struct v4l2_fmtdesc
+{
+ __u32 index; /* Format number */
+ enum v4l2_buf_type type; /* buffer type */
+ __u32 flags;
+ __u8 description[32]; /* Description string */
+ __u32 pixelformat; /* Format fourcc */
+ __u32 reserved[4];
+};
+
+#define V4L2_FMT_FLAG_COMPRESSED 0x0001
+
+
+/*
+ * T I M E C O D E
+ */
+struct v4l2_timecode
+{
+ __u32 type;
+ __u32 flags;
+ __u8 frames;
+ __u8 seconds;
+ __u8 minutes;
+ __u8 hours;
+ __u8 userbits[4];
+};
+
+/* Type */
+#define V4L2_TC_TYPE_24FPS 1
+#define V4L2_TC_TYPE_25FPS 2
+#define V4L2_TC_TYPE_30FPS 3
+#define V4L2_TC_TYPE_50FPS 4
+#define V4L2_TC_TYPE_60FPS 5
+
+/* Flags */
+#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */
+#define V4L2_TC_FLAG_COLORFRAME 0x0002
+#define V4L2_TC_USERBITS_field 0x000C
+#define V4L2_TC_USERBITS_USERDEFINED 0x0000
+#define V4L2_TC_USERBITS_8BITCHARS 0x0008
+/* The above is based on SMPTE timecodes */
+
+
+/*
+ * C O M P R E S S I O N P A R A M E T E R S
+ */
+#if 0
+/* ### generic compression settings don't work, there is too much
+ * ### codec-specific stuff. Maybe reuse that for MPEG codec settings
+ * ### later ... */
+struct v4l2_compression
+{
+ __u32 quality;
+ __u32 keyframerate;
+ __u32 pframerate;
+ __u32 reserved[5];
+
+/* what we'll need for MPEG, extracted from some postings on
+ the v4l list (Gert Vervoort, PlasmaJohn).
+
+system stream:
+ - type: elementary stream(ES), packatised elementary stream(s) (PES)
+ program stream(PS), transport stream(TS)
+ - system bitrate
+ - PS packet size (DVD: 2048 bytes, VCD: 2324 bytes)
+ - TS video PID
+ - TS audio PID
+ - TS PCR PID
+ - TS system information tables (PAT, PMT, CAT, NIT and SIT)
+ - (MPEG-1 systems stream vs. MPEG-2 program stream (TS not supported
+ by MPEG-1 systems)
+
+audio:
+ - type: MPEG (+Layer I,II,III), AC-3, LPCM
+ - bitrate
+ - sampling frequency (DVD: 48 Khz, VCD: 44.1 KHz, 32 kHz)
+ - Trick Modes? (ff, rew)
+ - Copyright
+ - Inverse Telecine
+
+video:
+ - picturesize (SIF, 1/2 D1, 2/3 D1, D1) and PAL/NTSC norm can be set
+ through excisting V4L2 controls
+ - noise reduction, parameters encoder specific?
+ - MPEG video version: MPEG-1, MPEG-2
+ - GOP (Group Of Pictures) definition:
+ - N: number of frames per GOP
+ - M: distance between reference (I,P) frames
+ - open/closed GOP
+ - quantiser matrix: inter Q matrix (64 bytes) and intra Q matrix (64 bytes)
+ - quantiser scale: linear or logarithmic
+ - scanning: alternate or zigzag
+ - bitrate mode: CBR (constant bitrate) or VBR (variable bitrate).
+ - target video bitrate for CBR
+ - target video bitrate for VBR
+ - maximum video bitrate for VBR - min. quantiser value for VBR
+ - max. quantiser value for VBR
+ - adaptive quantisation value
+ - return the number of bytes per GOP or bitrate for bitrate monitoring
+
+*/
+};
+#endif
+
+struct v4l2_jpegcompression
+{
+ int quality;
+
+ int APPn; /* Number of APP segment to be written,
+ * must be 0..15 */
+ int APP_len; /* Length of data in JPEG APPn segment */
+ char APP_data[60]; /* Data in the JPEG APPn segment. */
+
+ int COM_len; /* Length of data in JPEG COM segment */
+ char COM_data[60]; /* Data in JPEG COM segment */
+
+ __u32 jpeg_markers; /* Which markers should go into the JPEG
+ * output. Unless you exactly know what
+ * you do, leave them untouched.
+ * Inluding less markers will make the
+ * resulting code smaller, but there will
+ * be fewer aplications which can read it.
+ * The presence of the APP and COM marker
+ * is influenced by APP_len and COM_len
+ * ONLY, not by this property! */
+
+#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
+#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
+#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
+#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
+#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
+ * allways use APP0 */
+};
+
+
+/*
+ * M E M O R Y - M A P P I N G B U F F E R S
+ */
+struct v4l2_requestbuffers
+{
+ __u32 count;
+ enum v4l2_buf_type type;
+ enum v4l2_memory memory;
+ __u32 reserved[2];
+};
+
+struct v4l2_buffer
+{
+ __u32 index;
+ enum v4l2_buf_type type;
+ __u32 bytesused;
+ __u32 flags;
+ enum v4l2_field field;
+ struct timeval timestamp;
+ struct v4l2_timecode timecode;
+ __u32 sequence;
+
+ /* memory location */
+ enum v4l2_memory memory;
+ union {
+ __u32 offset;
+ unsigned long userptr;
+ } m;
+ __u32 length;
+
+ __u32 reserved[2];
+};
+
+/* Flags for 'flags' field */
+#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */
+#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */
+#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */
+#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
+#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
+#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
+#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
+
+/*
+ * O V E R L A Y P R E V I E W
+ */
+struct v4l2_framebuffer
+{
+ __u32 capability;
+ __u32 flags;
+/* FIXME: in theory we should pass something like PCI device + memory
+ * region + offset instead of some physical address */
+ void* base;
+ struct v4l2_pix_format fmt;
+};
+/* Flags for the 'capability' field. Read only */
+#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
+#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
+#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
+#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
+/* Flags for the 'flags' field. */
+#define V4L2_FBUF_FLAG_PRIMARY 0x0001
+#define V4L2_FBUF_FLAG_OVERLAY 0x0002
+#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
+
+struct v4l2_clip
+{
+ struct v4l2_rect c;
+ struct v4l2_clip *next;
+};
+
+struct v4l2_window
+{
+ struct v4l2_rect w;
+ enum v4l2_field field;
+ __u32 chromakey;
+ struct v4l2_clip *clips;
+ __u32 clipcount;
+ void *bitmap;
+};
+
+
+/*
+ * C A P T U R E P A R A M E T E R S
+ */
+struct v4l2_captureparm
+{
+ __u32 capability; /* Supported modes */
+ __u32 capturemode; /* Current mode */
+ struct v4l2_fract timeperframe; /* Time per frame in .1us units */
+ __u32 extendedmode; /* Driver-specific extensions */
+ __u32 readbuffers; /* # of buffers for read */
+ __u32 reserved[4];
+};
+/* Flags for 'capability' and 'capturemode' fields */
+#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */
+#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */
+
+struct v4l2_outputparm
+{
+ __u32 capability; /* Supported modes */
+ __u32 outputmode; /* Current mode */
+ struct v4l2_fract timeperframe; /* Time per frame in seconds */
+ __u32 extendedmode; /* Driver-specific extensions */
+ __u32 writebuffers; /* # of buffers for write */
+ __u32 reserved[4];
+};
+
+/*
+ * I N P U T I M A G E C R O P P I N G
+ */
+
+struct v4l2_cropcap {
+ enum v4l2_buf_type type;
+ struct v4l2_rect bounds;
+ struct v4l2_rect defrect;
+ struct v4l2_fract pixelaspect;
+};
+
+struct v4l2_crop {
+ enum v4l2_buf_type type;
+ struct v4l2_rect c;
+};
+
+/*
+ * A N A L O G V I D E O S T A N D A R D
+ */
+
+typedef unsigned long long v4l2_std_id;
+
+/* one bit for each */
+#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
+#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
+#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
+#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
+#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
+#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
+#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
+#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
+
+#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
+#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
+#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
+#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
+
+#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
+#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
+
+#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
+#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
+#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
+#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
+#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
+#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
+#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
+
+/* ATSC/HDTV */
+#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
+#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
+
+/* some common needed stuff */
+#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
+ V4L2_STD_PAL_B1 |\
+ V4L2_STD_PAL_G)
+#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
+ V4L2_STD_PAL_D1 |\
+ V4L2_STD_PAL_K)
+#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
+ V4L2_STD_PAL_DK |\
+ V4L2_STD_PAL_H |\
+ V4L2_STD_PAL_I)
+#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
+ V4L2_STD_NTSC_M_JP)
+#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
+ V4L2_STD_SECAM_D |\
+ V4L2_STD_SECAM_G |\
+ V4L2_STD_SECAM_H |\
+ V4L2_STD_SECAM_K |\
+ V4L2_STD_SECAM_K1 |\
+ V4L2_STD_SECAM_L)
+
+#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
+ V4L2_STD_PAL_60 |\
+ V4L2_STD_NTSC)
+#define V4L2_STD_625_50 (V4L2_STD_PAL |\
+ V4L2_STD_PAL_N |\
+ V4L2_STD_PAL_Nc |\
+ V4L2_STD_SECAM)
+
+#define V4L2_STD_UNKNOWN 0
+#define V4L2_STD_ALL (V4L2_STD_525_60 |\
+ V4L2_STD_625_50)
+
+struct v4l2_standard
+{
+ __u32 index;
+ v4l2_std_id id;
+ __u8 name[24];
+ struct v4l2_fract frameperiod; /* Frames, not fields */
+ __u32 framelines;
+ __u32 reserved[4];
+};
+
+
+/*
+ * V I D E O I N P U T S
+ */
+struct v4l2_input
+{
+ __u32 index; /* Which input */
+ __u8 name[32]; /* Label */
+ __u32 type; /* Type of input */
+ __u32 audioset; /* Associated audios (bitfield) */
+ __u32 tuner; /* Associated tuner */
+ v4l2_std_id std;
+ __u32 status;
+ __u32 reserved[4];
+};
+/* Values for the 'type' field */
+#define V4L2_INPUT_TYPE_TUNER 1
+#define V4L2_INPUT_TYPE_CAMERA 2
+
+/* field 'status' - general */
+#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */
+#define V4L2_IN_ST_NO_SIGNAL 0x00000002
+#define V4L2_IN_ST_NO_COLOR 0x00000004
+
+/* field 'status' - analog */
+#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */
+#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */
+
+/* field 'status' - digital */
+#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */
+#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */
+#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */
+
+/* field 'status' - VCR and set-top box */
+#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */
+#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
+#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
+
+/*
+ * V I D E O O U T P U T S
+ */
+struct v4l2_output
+{
+ __u32 index; /* Which output */
+ __u8 name[32]; /* Label */
+ __u32 type; /* Type of output */
+ __u32 audioset; /* Associated audios (bitfield) */
+ __u32 modulator; /* Associated modulator */
+ v4l2_std_id std;
+ __u32 reserved[4];
+};
+/* Values for the 'type' field */
+#define V4L2_OUTPUT_TYPE_MODULATOR 1
+#define V4L2_OUTPUT_TYPE_ANALOG 2
+#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
+
+/*
+ * C O N T R O L S
+ */
+struct v4l2_control
+{
+ __u32 id;
+ __s32 value;
+};
+
+/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
+struct v4l2_queryctrl
+{
+ __u32 id;
+ enum v4l2_ctrl_type type;
+ __u8 name[32]; /* Whatever */
+ __s32 minimum; /* Note signedness */
+ __s32 maximum;
+ __s32 step;
+ __s32 default_value;
+ __u32 flags;
+ __u32 reserved[2];
+};
+
+/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
+struct v4l2_querymenu
+{
+ __u32 id;
+ __u32 index;
+ __u8 name[32]; /* Whatever */
+ __u32 reserved;
+};
+
+/* Control flags */
+#define V4L2_CTRL_FLAG_DISABLED 0x0001
+#define V4L2_CTRL_FLAG_GRABBED 0x0002
+
+/* Control IDs defined by V4L2 */
+#define V4L2_CID_BASE 0x00980900
+/* IDs reserved for driver specific controls */
+#define V4L2_CID_PRIVATE_BASE 0x08000000
+
+#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
+#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
+#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
+#define V4L2_CID_HUE (V4L2_CID_BASE+3)
+#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
+#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6)
+#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7)
+#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
+#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
+#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
+#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11)
+#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
+#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
+#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
+#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15)
+#define V4L2_CID_GAMMA (V4L2_CID_BASE+16)
+#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */
+#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17)
+#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18)
+#define V4L2_CID_GAIN (V4L2_CID_BASE+19)
+#define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
+#define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
+#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
+#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */
+
+/*
+ * T U N I N G
+ */
+struct v4l2_tuner
+{
+ __u32 index;
+ __u8 name[32];
+ enum v4l2_tuner_type type;
+ __u32 capability;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 rxsubchans;
+ __u32 audmode;
+ __s32 signal;
+ __s32 afc;
+ __u32 reserved[4];
+};
+
+struct v4l2_modulator
+{
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 txsubchans;
+ __u32 reserved[4];
+};
+
+/* Flags for the 'capability' field */
+#define V4L2_TUNER_CAP_LOW 0x0001
+#define V4L2_TUNER_CAP_NORM 0x0002
+#define V4L2_TUNER_CAP_STEREO 0x0010
+#define V4L2_TUNER_CAP_LANG2 0x0020
+#define V4L2_TUNER_CAP_SAP 0x0020
+#define V4L2_TUNER_CAP_LANG1 0x0040
+
+/* Flags for the 'rxsubchans' field */
+#define V4L2_TUNER_SUB_MONO 0x0001
+#define V4L2_TUNER_SUB_STEREO 0x0002
+#define V4L2_TUNER_SUB_LANG2 0x0004
+#define V4L2_TUNER_SUB_SAP 0x0004
+#define V4L2_TUNER_SUB_LANG1 0x0008
+
+/* Values for the 'audmode' field */
+#define V4L2_TUNER_MODE_MONO 0x0000
+#define V4L2_TUNER_MODE_STEREO 0x0001
+#define V4L2_TUNER_MODE_LANG2 0x0002
+#define V4L2_TUNER_MODE_SAP 0x0002
+#define V4L2_TUNER_MODE_LANG1 0x0003
+
+struct v4l2_frequency
+{
+ __u32 tuner;
+ enum v4l2_tuner_type type;
+ __u32 frequency;
+ __u32 reserved[8];
+};
+
+/*
+ * A U D I O
+ */
+struct v4l2_audio
+{
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 mode;
+ __u32 reserved[2];
+};
+/* Flags for the 'capability' field */
+#define V4L2_AUDCAP_STEREO 0x00001
+#define V4L2_AUDCAP_AVL 0x00002
+
+/* Flags for the 'mode' field */
+#define V4L2_AUDMODE_AVL 0x00001
+
+struct v4l2_audioout
+{
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 mode;
+ __u32 reserved[2];
+};
+
+/*
+ * D A T A S E R V I C E S ( V B I )
+ *
+ * Data services API by Michael Schimek
+ */
+
+struct v4l2_vbi_format
+{
+ __u32 sampling_rate; /* in 1 Hz */
+ __u32 offset;
+ __u32 samples_per_line;
+ __u32 sample_format; /* V4L2_PIX_FMT_* */
+ __s32 start[2];
+ __u32 count[2];
+ __u32 flags; /* V4L2_VBI_* */
+ __u32 reserved[2]; /* must be zero */
+};
+
+/* VBI flags */
+#define V4L2_VBI_UNSYNC (1<< 0)
+#define V4L2_VBI_INTERLACED (1<< 1)
+
+
+/*
+ * A G G R E G A T E S T R U C T U R E S
+ */
+
+/* Stream data format
+ */
+struct v4l2_format
+{
+ enum v4l2_buf_type type;
+ union
+ {
+ struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
+ struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
+ struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
+ __u8 raw_data[200]; // user-defined
+ } fmt;
+};
+
+
+/* Stream type-dependent parameters
+ */
+struct v4l2_streamparm
+{
+ enum v4l2_buf_type type;
+ union
+ {
+ struct v4l2_captureparm capture;
+ struct v4l2_outputparm output;
+ __u8 raw_data[200]; /* user-defined */
+ } parm;
+};
+
+
+
+/*
+ * I O C T L C O D E S F O R V I D E O D E V I C E S
+ *
+ */
+#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability)
+#define VIDIOC_RESERVED _IO ('V', 1)
+#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
+#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
+#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
+#if 0
+#define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression)
+#define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression)
+#endif
+#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
+#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
+#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
+#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer)
+#define VIDIOC_OVERLAY _IOW ('V', 14, int)
+#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer)
+#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer)
+#define VIDIOC_STREAMON _IOW ('V', 18, int)
+#define VIDIOC_STREAMOFF _IOW ('V', 19, int)
+#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm)
+#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm)
+#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id)
+#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id)
+#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard)
+#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input)
+#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control)
+#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control)
+#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner)
+#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner)
+#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio)
+#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio)
+#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl)
+#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu)
+#define VIDIOC_G_INPUT _IOR ('V', 38, int)
+#define VIDIOC_S_INPUT _IOWR ('V', 39, int)
+#define VIDIOC_G_OUTPUT _IOR ('V', 46, int)
+#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int)
+#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output)
+#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout)
+#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout)
+#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator)
+#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator)
+#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency)
+#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency)
+#define VIDIOC_CROPCAP _IOR ('V', 58, struct v4l2_cropcap)
+#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop)
+#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop)
+#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression)
+#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression)
+#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)
+#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio)
+#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout)
+#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
+#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority)
+
+/* for compatibility, will go away some day */
+#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
+#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm)
+#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control)
+#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio)
+#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout)
+
+#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
+
+
+#ifdef __KERNEL__
+/*
+ *
+ * V 4 L 2 D R I V E R H E L P E R A P I
+ *
+ * Some commonly needed functions for drivers (v4l2-common.o module)
+ */
+#include <linux/fs.h>
+
+/* Video standard functions */
+extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
+extern int v4l2_video_std_construct(struct v4l2_standard *vs,
+ int id, char *name);
+
+/* prority handling */
+struct v4l2_prio_state {
+ atomic_t prios[4];
+};
+int v4l2_prio_init(struct v4l2_prio_state *global);
+int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
+ enum v4l2_priority new);
+int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
+int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local);
+enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
+int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local);
+
+/* names for fancy debug output */
+extern char *v4l2_field_names[];
+extern char *v4l2_type_names[];
+extern char *v4l2_ioctl_names[];
+
+/* Compatibility layer interface -- v4l1-compat module */
+typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg);
+int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
+ int cmd, void *arg, v4l2_kioctl driver_ioctl);
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_VIDEODEV2_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/kradio3/plugins/v4lradio/po/Makefile.am b/kradio3/plugins/v4lradio/po/Makefile.am
new file mode 100644
index 0000000..6f04af2
--- /dev/null
+++ b/kradio3/plugins/v4lradio/po/Makefile.am
@@ -0,0 +1,3 @@
+
+PACKAGE = kradio-v4lradio
+POFILES = AUTO
diff --git a/kradio3/plugins/v4lradio/po/de.po b/kradio3/plugins/v4lradio/po/de.po
new file mode 100644
index 0000000..718cb19
--- /dev/null
+++ b/kradio3/plugins/v4lradio/po/de.po
@@ -0,0 +1,362 @@
+# translation of de.po to
+# translation of kradio-v4lradio.po to
+# This file is put in the public domain.
+#
+# Ernst Martin Witte <emw@nocabal.de>, 2006.
+msgid ""
+msgstr ""
+"Project-Id-Version: de\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2006-11-11 18:43+0100\n"
+"PO-Revision-Date: 2006-11-06 00:24+0100\n"
+"Last-Translator: Ernst Martin Witte <emw@nocabal.de>\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#. i18n: file v4lradio-configuration-ui.ui line 16
+#: rc.cpp:3 rc.cpp:90 v4lradio-configuration-ui.cpp:328
+#, no-c-format
+msgid "SetupDialogGeneral"
+msgstr "SetupDialogGeneral"
+
+#. i18n: file v4lradio-configuration-ui.ui line 37
+#: rc.cpp:6 rc.cpp:93 v4lradio-configuration-ui.cpp:344
+#, no-c-format
+msgid "Devices"
+msgstr "Geräte"
+
+#. i18n: file v4lradio-configuration-ui.ui line 68
+#: rc.cpp:9 rc.cpp:96 v4lradio-configuration-ui.cpp:329
+#, no-c-format
+msgid "Playback Mixer Device"
+msgstr "Wiedergabe Mixer"
+
+#. i18n: file v4lradio-configuration-ui.ui line 76
+#: rc.cpp:12 rc.cpp:99 v4lradio-configuration-ui.cpp:330
+#, no-c-format
+msgid "Playback Mixer Channel"
+msgstr "Wiedergabe Mixerkanal"
+
+#. i18n: file v4lradio-configuration-ui.ui line 169
+#: rc.cpp:15 rc.cpp:102 v4lradio-configuration-ui.cpp:331
+#, no-c-format
+msgid "Radio Device"
+msgstr "Radio Gerät"
+
+#. i18n: file v4lradio-configuration-ui.ui line 196
+#: rc.cpp:19 rc.cpp:106 v4lradio-configuration-ui.cpp:333
+#, no-c-format
+msgid "Capture Mixer Device"
+msgstr "Aufnahme Mixer"
+
+#. i18n: file v4lradio-configuration-ui.ui line 217
+#: rc.cpp:22 rc.cpp:109 v4lradio-configuration-ui.cpp:334
+#, no-c-format
+msgid "Capture Mixer Channel"
+msgstr "Aufnahme Mixerkanal"
+
+#. i18n: file v4lradio-configuration-ui.ui line 249
+#: rc.cpp:25 rc.cpp:112 v4lradio-configuration-ui.cpp:336
+#, no-c-format
+msgid "test"
+msgstr "test"
+
+#. i18n: file v4lradio-configuration-ui.ui line 269
+#: rc.cpp:28 rc.cpp:115 v4lradio-configuration-ui.cpp:337
+#, no-c-format
+msgid "unknown v4l device"
+msgstr "Unbekanntes V4L-Gerät"
+
+#. i18n: file v4lradio-configuration-ui.ui line 315
+#: rc.cpp:31 rc.cpp:118 v4lradio-configuration-ui.cpp:338
+#, no-c-format
+msgid "Use active pla&yback by capturing"
+msgstr "Aktive &Wiedergabe verwenden (Aufgenommenes abspielen)"
+
+#. i18n: file v4lradio-configuration-ui.ui line 318
+#: rc.cpp:34 rc.cpp:121 v4lradio-configuration-ui.cpp:339
+#, no-c-format
+msgid "Alt+Y"
+msgstr "Alt+Y"
+
+#. i18n: file v4lradio-configuration-ui.ui line 334
+#: rc.cpp:37 rc.cpp:124 v4lradio-configuration-ui.cpp:340
+#, no-c-format
+msgid "Mute Play&back Channel on Power Off"
+msgstr "Wiedergabekanal beim Abschalten des Radios stummschalten"
+
+#. i18n: file v4lradio-configuration-ui.ui line 337
+#: rc.cpp:40 rc.cpp:127 v4lradio-configuration-ui.cpp:341
+#, no-c-format
+msgid "Alt+B"
+msgstr "Alt+B"
+
+#. i18n: file v4lradio-configuration-ui.ui line 353
+#: rc.cpp:43 rc.cpp:130 v4lradio-configuration-ui.cpp:342
+#, no-c-format
+msgid "Set Playback Channel Volume to &Zero on Power Off"
+msgstr "Wiedergabelautstärke beim Abschalten des Radios auf 0 setzen"
+
+#. i18n: file v4lradio-configuration-ui.ui line 356
+#: rc.cpp:46 rc.cpp:133 v4lradio-configuration-ui.cpp:343
+#, no-c-format
+msgid "Alt+Z"
+msgstr "Alt+Z"
+
+#. i18n: file v4lradio-configuration-ui.ui line 394
+#: rc.cpp:52 rc.cpp:139 v4lradio-configuration-ui.cpp:345
+#, no-c-format
+msgid "to"
+msgstr "bis"
+
+#. i18n: file v4lradio-configuration-ui.ui line 413
+#. i18n: file v4lradio-configuration-ui.ui line 443
+#. i18n: file v4lradio-configuration-ui.ui line 479
+#. i18n: file v4lradio-configuration-ui.ui line 413
+#. i18n: file v4lradio-configuration-ui.ui line 443
+#. i18n: file v4lradio-configuration-ui.ui line 479
+#: rc.cpp:55 rc.cpp:58 rc.cpp:64 rc.cpp:142 rc.cpp:145 rc.cpp:151
+#: v4lradio-configuration-ui.cpp:346 v4lradio-configuration-ui.cpp:347
+#: v4lradio-configuration-ui.cpp:349
+#, no-c-format
+msgid " kHz"
+msgstr " kHz"
+
+#. i18n: file v4lradio-configuration-ui.ui line 460
+#: rc.cpp:61 rc.cpp:148 v4lradio-configuration-ui.cpp:348
+#, no-c-format
+msgid "minimum signal quality"
+msgstr "Mindest-Signalpegel"
+
+#. i18n: file v4lradio-configuration-ui.ui line 499
+#: rc.cpp:67 rc.cpp:154 v4lradio-configuration-ui.cpp:350
+#, no-c-format
+msgid "station scan step"
+msgstr "Sendersuchschrittweite"
+
+#. i18n: file v4lradio-configuration-ui.ui line 507
+#: rc.cpp:70 rc.cpp:157 v4lradio-configuration-ui.cpp:351
+#, no-c-format
+msgid "allowed frequency range"
+msgstr "erlaubter Frequenzbereich"
+
+#. i18n: file v4lradio-configuration-ui.ui line 566
+#: rc.cpp:75 rc.cpp:162 v4lradio-configuration-ui.cpp:359
+#, no-c-format
+msgid "V4L Mixer Controls"
+msgstr "V4L Mixersteuerung"
+
+#. i18n: file v4lradio-configuration-ui.ui line 594
+#: rc.cpp:78 rc.cpp:165 v4lradio-configuration-ui.cpp:355
+#, no-c-format
+msgid "volume"
+msgstr "Lautstärke"
+
+#. i18n: file v4lradio-configuration-ui.ui line 684
+#: rc.cpp:81 rc.cpp:168 v4lradio-configuration-ui.cpp:356
+#, no-c-format
+msgid "treble"
+msgstr "Höhen"
+
+#. i18n: file v4lradio-configuration-ui.ui line 774
+#: rc.cpp:84 rc.cpp:171 v4lradio-configuration-ui.cpp:357
+#, no-c-format
+msgid "bass"
+msgstr "Tiefen"
+
+#. i18n: file v4lradio-configuration-ui.ui line 861
+#: rc.cpp:87 rc.cpp:174 v4lradio-configuration-ui.cpp:358
+#, no-c-format
+msgid "balance"
+msgstr "Balance"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Ernst Martin Witte"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "emw@nocabal.de"
+
+#: v4lradio-configuration.cpp:443
+msgid "any ( * )"
+msgstr "Alle ( * )"
+
+#: v4lradio-configuration.cpp:445
+msgid "Radio Device Selection"
+msgstr "Auswahl der Radio-Gerätedatei"
+
+#: v4lradio-configuration.cpp:448
+msgid "Select Radio Device"
+msgstr "Wählen Sie die Radio-Gerätedatei aus"
+
+#: v4lradio.cpp:56
+msgid "Support for V4L(2) Radio Devices"
+msgstr "Unterstützung für V4L(2)-Radiogeräte"
+
+#: v4lradio.cpp:61
+msgid "Video For Linux Plugin"
+msgstr "Video für Linux (V4L) Plugin"
+
+#: v4lradio.cpp:659
+msgid "invalid frequency %1"
+msgstr "ungültige Frequenz: %1"
+
+#: v4lradio.cpp:680 v4lradio.cpp:1358 v4lradio.cpp:1507
+msgid "don't known how to handle V4L-version %1"
+msgstr "Keine Ahnung, wie die V4L-Version %1 behandelt werden soll"
+
+#: v4lradio.cpp:686
+msgid "error setting frequency to %1 (%2)"
+msgstr "Fehler (%2) beim Einstellen der Frequenz auf %1."
+
+#: v4lradio.cpp:1004
+msgid ""
+"Device %1 does exist but is not readable/writable. Please check device "
+"permissions."
+msgstr ""
+"Das Gerät %1 existiert, ist aber nicht lesbar/schreibbar. Bitte überprüfen "
+"Sie die Einstellung der Zugriffsrechte für das Gerät."
+
+#: v4lradio.cpp:1014
+msgid "Could not find an accessible v4l(2) radio device."
+msgstr "Kann kein verwendbares V4L(2)-Radiogerät finden."
+
+#: v4lradio.cpp:1077
+msgid "V4L Radio"
+msgstr "V4L Radio"
+
+#: v4lradio.cpp:1078
+msgid "V4L Radio Options"
+msgstr "Optionen des V4L-Radios"
+
+#: v4lradio.cpp:1088
+msgid ""
+"V4L/V4L2 Plugin for KRadio.<P>Provides Support for V4L/V4L2 based Radio "
+"Cards<P>"
+msgstr ""
+"V4L/V4L2-Plugin für KRadio.<P>Dieses Plugin bindet vom V4L/V4L2-Treiber "
+"unterstützte Radio-Karten in KRadio ein.<P>"
+
+#: v4lradio.cpp:1103
+msgid "V4L/V4L2"
+msgstr "V4L/V4L2"
+
+#: v4lradio.cpp:1104
+msgid "V4L/V4L2 Plugin"
+msgstr "V4L/V4L2-Plugin"
+
+#: v4lradio.cpp:1135
+msgid "Cannot open radio device %1"
+msgstr "Die Radiogerätedatei %1 kann nicht geöffnet werden"
+
+#: v4lradio.cpp:1186
+msgid "cannot open %1"
+msgstr "%1 kann nicht geöffnet werden"
+
+#: v4lradio.cpp:1210
+msgid "audio caps = %1"
+msgstr "Audio-Fähigkeiten: %1"
+
+#: v4lradio.cpp:1224
+msgid "error reading V4L1 caps"
+msgstr "Fehler beim Lesen der V4L1-Fähigkeiten"
+
+#: v4lradio.cpp:1233
+msgid "V4L2 - Version: %1"
+msgstr "V4L2 - Version: %1"
+
+#: v4lradio.cpp:1253
+msgid "V4L2: Querying mute control failed"
+msgstr "V4L2: Die Abfrage des Stummschaltungs-Reglers schlug fehl"
+
+#: v4lradio.cpp:1260
+msgid "V4L2: Querying volume control failed"
+msgstr "V4L2: Die Abfrage des Lautstärke-Reglers schlug fehl"
+
+#: v4lradio.cpp:1268
+msgid "V4L2: Querying treble control failed"
+msgstr "V4L2: Die Abfrage des Höhen-Reglers schlug fehl"
+
+#: v4lradio.cpp:1276
+msgid "V4L2: Querying bass control failed"
+msgstr "V4L2: Die Abfrage des Bass-Reglers schlug fehl"
+
+#: v4lradio.cpp:1284
+msgid "V4L2: Querying balance control failed"
+msgstr "V4L2: Die Abfrage des Balance-Reglers schlug fehl"
+
+#: v4lradio.cpp:1288
+msgid "V4LRadio::readV4LCaps: Reading V4L2 caps failed"
+msgstr "V4LRadio::readV4LCaps: Das Lesen der V4L2-Fähigkeiten schlug fehl"
+
+#: v4lradio.cpp:1292
+msgid "V4L %1 detected"
+msgstr "V4L %1 wurde gefunden"
+
+#: v4lradio.cpp:1294
+msgid "V4L not detected"
+msgstr "Das Radiogerät unterstützt V4L nicht"
+
+#: v4lradio.cpp:1297
+msgid "Radio is mutable"
+msgstr "Das Radio kann stummgeschaltet werden"
+
+#: v4lradio.cpp:1297
+msgid "Radio is not mutable"
+msgstr "Das Radio kann nicht stummgeschaltet werden"
+
+#: v4lradio.cpp:1298
+msgid "Radio has Volume Control"
+msgstr "Das Radio hat einen Lautstärkeregler"
+
+#: v4lradio.cpp:1298
+msgid "Radio has no Volume Control"
+msgstr "Das Radio hat keinen Lautstärkeregler"
+
+#: v4lradio.cpp:1299
+msgid "Radio has Bass Control"
+msgstr "Das Radio hat einen Bass-Regler"
+
+#: v4lradio.cpp:1299
+msgid "Radio has no Bass Control"
+msgstr "Das Radio hat keinen Bass-Regler"
+
+#: v4lradio.cpp:1300
+msgid "Radio has Treble Control"
+msgstr "Das Radio hat einen Höhen-Regler"
+
+#: v4lradio.cpp:1300
+msgid "Radio has no Treble Control"
+msgstr "Das Radio hat keinen Bass-Regler"
+
+#: v4lradio.cpp:1365
+msgid "cannot get tuner info (error %1)"
+msgstr "Tuner-Informationen können nicht gelesen werden (Fehler %1)"
+
+#: v4lradio.cpp:1409
+msgid "error setting %1: %2"
+msgstr "Fehler %2 beim Setzen von %1"
+
+#: v4lradio.cpp:1417
+msgid "error reading %1: %2"
+msgstr "Fehler %2 beim Lesen von %1"
+
+#: v4lradio.cpp:1513
+msgid "error updating radio audio info (%1): %2"
+msgstr "Fehler %2 beim Updaten der Audio-Informationen (%1)"
+
+#: v4lradio.cpp:1514
+msgid "write"
+msgstr "Schreiben"
+
+#: v4lradio.cpp:1514
+msgid "read"
+msgstr "Lesen"
diff --git a/kradio3/plugins/v4lradio/po/ru.po b/kradio3/plugins/v4lradio/po/ru.po
new file mode 100644
index 0000000..dc57522
--- /dev/null
+++ b/kradio3/plugins/v4lradio/po/ru.po
@@ -0,0 +1,362 @@
+# translation of ru.po to
+# translation of kradio-v4lradio.po to
+# This file is put in the public domain.
+# Алексей Кузнецов <Alexey.Kouznetsov@GMail.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ru\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2006-11-11 18:43+0100\n"
+"PO-Revision-Date: 2006-11-08 11:59+0300\n"
+"Last-Translator: Алексей Кузнецов <Alexey.Kouznetsov@GMail.com>\n"
+"Language-Team: <ru@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.10\n"
+
+#. i18n: file v4lradio-configuration-ui.ui line 16
+#: rc.cpp:3 rc.cpp:90 v4lradio-configuration-ui.cpp:328
+#, no-c-format
+msgid "SetupDialogGeneral"
+msgstr "SetupDialogGeneral"
+
+#. i18n: file v4lradio-configuration-ui.ui line 37
+#: rc.cpp:6 rc.cpp:93 v4lradio-configuration-ui.cpp:344
+#, no-c-format
+msgid "Devices"
+msgstr "Устройства"
+
+#. i18n: file v4lradio-configuration-ui.ui line 68
+#: rc.cpp:9 rc.cpp:96 v4lradio-configuration-ui.cpp:329
+#, no-c-format
+msgid "Playback Mixer Device"
+msgstr "Устройство воспроизведения"
+
+#. i18n: file v4lradio-configuration-ui.ui line 76
+#: rc.cpp:12 rc.cpp:99 v4lradio-configuration-ui.cpp:330
+#, no-c-format
+msgid "Playback Mixer Channel"
+msgstr "Канал воспроизведения"
+
+#. i18n: file v4lradio-configuration-ui.ui line 169
+#: rc.cpp:15 rc.cpp:102 v4lradio-configuration-ui.cpp:331
+#, no-c-format
+msgid "Radio Device"
+msgstr "Устройство радио"
+
+#. i18n: file v4lradio-configuration-ui.ui line 196
+#: rc.cpp:19 rc.cpp:106 v4lradio-configuration-ui.cpp:333
+#, no-c-format
+msgid "Capture Mixer Device"
+msgstr "Устройство записи"
+
+#. i18n: file v4lradio-configuration-ui.ui line 217
+#: rc.cpp:22 rc.cpp:109 v4lradio-configuration-ui.cpp:334
+#, no-c-format
+msgid "Capture Mixer Channel"
+msgstr "Канал записи"
+
+#. i18n: file v4lradio-configuration-ui.ui line 249
+#: rc.cpp:25 rc.cpp:112 v4lradio-configuration-ui.cpp:336
+#, no-c-format
+msgid "test"
+msgstr "проверка"
+
+#. i18n: file v4lradio-configuration-ui.ui line 269
+#: rc.cpp:28 rc.cpp:115 v4lradio-configuration-ui.cpp:337
+#, no-c-format
+msgid "unknown v4l device"
+msgstr "неизвестно"
+
+#. i18n: file v4lradio-configuration-ui.ui line 315
+#: rc.cpp:31 rc.cpp:118 v4lradio-configuration-ui.cpp:338
+#, no-c-format
+msgid "Use active pla&yback by capturing"
+msgstr "Захватывать звук и затем проигрывать его"
+
+#. i18n: file v4lradio-configuration-ui.ui line 318
+#: rc.cpp:34 rc.cpp:121 v4lradio-configuration-ui.cpp:339
+#, no-c-format
+msgid "Alt+Y"
+msgstr "Alt+Y"
+
+#. i18n: file v4lradio-configuration-ui.ui line 334
+#: rc.cpp:37 rc.cpp:124 v4lradio-configuration-ui.cpp:340
+#, no-c-format
+msgid "Mute Play&back Channel on Power Off"
+msgstr "Выключать звук на канале воспроизведения при выходе"
+
+#. i18n: file v4lradio-configuration-ui.ui line 337
+#: rc.cpp:40 rc.cpp:127 v4lradio-configuration-ui.cpp:341
+#, no-c-format
+msgid "Alt+B"
+msgstr "Alt+B"
+
+#. i18n: file v4lradio-configuration-ui.ui line 353
+#: rc.cpp:43 rc.cpp:130 v4lradio-configuration-ui.cpp:342
+#, no-c-format
+msgid "Set Playback Channel Volume to &Zero on Power Off"
+msgstr "Устанавливать &нулевую громкость воспроизведения при выходе"
+
+#. i18n: file v4lradio-configuration-ui.ui line 356
+#: rc.cpp:46 rc.cpp:133 v4lradio-configuration-ui.cpp:343
+#, no-c-format
+msgid "Alt+Z"
+msgstr "Alt+Z"
+
+#. i18n: file v4lradio-configuration-ui.ui line 394
+#: rc.cpp:52 rc.cpp:139 v4lradio-configuration-ui.cpp:345
+#, no-c-format
+msgid "to"
+msgstr "до"
+
+#. i18n: file v4lradio-configuration-ui.ui line 413
+#. i18n: file v4lradio-configuration-ui.ui line 443
+#. i18n: file v4lradio-configuration-ui.ui line 479
+#. i18n: file v4lradio-configuration-ui.ui line 413
+#. i18n: file v4lradio-configuration-ui.ui line 443
+#. i18n: file v4lradio-configuration-ui.ui line 479
+#: rc.cpp:55 rc.cpp:58 rc.cpp:64 rc.cpp:142 rc.cpp:145 rc.cpp:151
+#: v4lradio-configuration-ui.cpp:346 v4lradio-configuration-ui.cpp:347
+#: v4lradio-configuration-ui.cpp:349
+#, no-c-format
+msgid " kHz"
+msgstr " кГц"
+
+#. i18n: file v4lradio-configuration-ui.ui line 460
+#: rc.cpp:61 rc.cpp:148 v4lradio-configuration-ui.cpp:348
+#, no-c-format
+msgid "minimum signal quality"
+msgstr "Минимальный уровень сигнала"
+
+#. i18n: file v4lradio-configuration-ui.ui line 499
+#: rc.cpp:67 rc.cpp:154 v4lradio-configuration-ui.cpp:350
+#, no-c-format
+msgid "station scan step"
+msgstr "Шаг изменения частоты при поиске"
+
+#. i18n: file v4lradio-configuration-ui.ui line 507
+#: rc.cpp:70 rc.cpp:157 v4lradio-configuration-ui.cpp:351
+#, no-c-format
+msgid "allowed frequency range"
+msgstr "Допустимый частотный диапазон:\tот"
+
+#. i18n: file v4lradio-configuration-ui.ui line 566
+#: rc.cpp:75 rc.cpp:162 v4lradio-configuration-ui.cpp:359
+#, no-c-format
+msgid "V4L Mixer Controls"
+msgstr "Аппаратные регуляторы V4l"
+
+#. i18n: file v4lradio-configuration-ui.ui line 594
+#: rc.cpp:78 rc.cpp:165 v4lradio-configuration-ui.cpp:355
+#, no-c-format
+msgid "volume"
+msgstr "Громкость"
+
+#. i18n: file v4lradio-configuration-ui.ui line 684
+#: rc.cpp:81 rc.cpp:168 v4lradio-configuration-ui.cpp:356
+#, no-c-format
+msgid "treble"
+msgstr "ВЧ"
+
+#. i18n: file v4lradio-configuration-ui.ui line 774
+#: rc.cpp:84 rc.cpp:171 v4lradio-configuration-ui.cpp:357
+#, no-c-format
+msgid "bass"
+msgstr "НЧ"
+
+#. i18n: file v4lradio-configuration-ui.ui line 861
+#: rc.cpp:87 rc.cpp:174 v4lradio-configuration-ui.cpp:358
+#, no-c-format
+msgid "balance"
+msgstr "Стереобаланс"
+
+#: _translatorinfo.cpp:1
+msgid ""
+"_: NAME OF TRANSLATORS\n"
+"Your names"
+msgstr "Алексей Кузнецов"
+
+#: _translatorinfo.cpp:3
+msgid ""
+"_: EMAIL OF TRANSLATORS\n"
+"Your emails"
+msgstr "Alexey.Kouznetsov@GMail.com"
+
+#: v4lradio-configuration.cpp:443
+msgid "any ( * )"
+msgstr "Все ( * )"
+
+#: v4lradio-configuration.cpp:445
+msgid "Radio Device Selection"
+msgstr "Выбор устройства радио"
+
+#: v4lradio-configuration.cpp:448
+msgid "Select Radio Device"
+msgstr "Выберите устройство радиоприёмника"
+
+#: v4lradio.cpp:56
+msgid "Support for V4L(2) Radio Devices"
+msgstr "Поддержка устройств V4l(2)"
+
+#: v4lradio.cpp:61
+msgid "Video For Linux Plugin"
+msgstr "Модуль \"Видео для linux\""
+
+#: v4lradio.cpp:659
+msgid "invalid frequency %1"
+msgstr "Неправильная частота %1"
+
+#: v4lradio.cpp:680 v4lradio.cpp:1358 v4lradio.cpp:1507
+msgid "don't known how to handle V4L-version %1"
+msgstr "Не знаю что делать с версией V4l \"%1\""
+
+#: v4lradio.cpp:686
+msgid "error setting frequency to %1 (%2)"
+msgstr "Ошибка установки частоты %1 (%2)"
+
+#: v4lradio.cpp:1004
+msgid ""
+"Device %1 does exist but is not readable/writable. Please check device "
+"permissions."
+msgstr ""
+"Устройство %1 недоступно для чтения/записи. Проверьте права на устройство, а "
+"также не использует ли его другая программа."
+
+#: v4lradio.cpp:1014
+msgid "Could not find an accessible v4l(2) radio device."
+msgstr "Не найти доступное устройство V4l(2)."
+
+#: v4lradio.cpp:1077
+msgid "V4L Radio"
+msgstr "Радио V4l"
+
+#: v4lradio.cpp:1078
+msgid "V4L Radio Options"
+msgstr "Параметры устройства V4l"
+
+#: v4lradio.cpp:1088
+msgid ""
+"V4L/V4L2 Plugin for KRadio.<P>Provides Support for V4L/V4L2 based Radio "
+"Cards<P>"
+msgstr ""
+"Модуль V4l/V4l2 для KRadio. <P> Предоставляет поддержку плат радио, "
+"совместимых с V4l/V4l2<P>"
+
+#: v4lradio.cpp:1103
+msgid "V4L/V4L2"
+msgstr "V4L/V4LV2"
+
+#: v4lradio.cpp:1104
+msgid "V4L/V4L2 Plugin"
+msgstr "Модуль V4L/V4L2"
+
+#: v4lradio.cpp:1135
+msgid "Cannot open radio device %1"
+msgstr "Не могу открыть устройство радио: %1"
+
+#: v4lradio.cpp:1186
+msgid "cannot open %1"
+msgstr "Не могу открыть %1"
+
+#: v4lradio.cpp:1210
+msgid "audio caps = %1"
+msgstr "возможности звука = %1"
+
+#: v4lradio.cpp:1224
+msgid "error reading V4L1 caps"
+msgstr "Ошибка чтения возможностей V4l1"
+
+#: v4lradio.cpp:1233
+msgid "V4L2 - Version: %1"
+msgstr "Версия V4l2: %1"
+
+#: v4lradio.cpp:1253
+msgid "V4L2: Querying mute control failed"
+msgstr "V4L2: Не могу обратиться к выключателю звука платы"
+
+#: v4lradio.cpp:1260
+msgid "V4L2: Querying volume control failed"
+msgstr "V4L2: Не могу обратиться к регулятору громкости"
+
+#: v4lradio.cpp:1268
+msgid "V4L2: Querying treble control failed"
+msgstr "V4L2: Не могу обратиться к регулятору верхних частот"
+
+#: v4lradio.cpp:1276
+msgid "V4L2: Querying bass control failed"
+msgstr "V4L2: Не могу обратиться к регулятору нижних частот"
+
+#: v4lradio.cpp:1284
+msgid "V4L2: Querying balance control failed"
+msgstr "V4L2: Не могу обратиться к регулятору стереобаланса"
+
+#: v4lradio.cpp:1288
+msgid "V4LRadio::readV4LCaps: Reading V4L2 caps failed"
+msgstr "V4LRadio::readV4LCaps:Не могу узнать возможности устройства"
+
+#: v4lradio.cpp:1292
+msgid "V4L %1 detected"
+msgstr "Найдено устройство V4L: %1"
+
+#: v4lradio.cpp:1294
+msgid "V4L not detected"
+msgstr "Устройств V4L не обнаружено"
+
+#: v4lradio.cpp:1297
+msgid "Radio is mutable"
+msgstr "Радио не поддерживает выключения звука"
+
+#: v4lradio.cpp:1297
+msgid "Radio is not mutable"
+msgstr "Радио поддерживает выключение звука"
+
+#: v4lradio.cpp:1298
+msgid "Radio has Volume Control"
+msgstr "Есть регулировка громкости"
+
+#: v4lradio.cpp:1298
+msgid "Radio has no Volume Control"
+msgstr "Регулировки громкости нет"
+
+#: v4lradio.cpp:1299
+msgid "Radio has Bass Control"
+msgstr "Есть регулировка НЧ"
+
+#: v4lradio.cpp:1299
+msgid "Radio has no Bass Control"
+msgstr "Регулировки НЧ нет"
+
+#: v4lradio.cpp:1300
+msgid "Radio has Treble Control"
+msgstr "Есть регулировка ВЧ"
+
+#: v4lradio.cpp:1300
+msgid "Radio has no Treble Control"
+msgstr "Регулировки ВЧ нет"
+
+#: v4lradio.cpp:1365
+msgid "cannot get tuner info (error %1)"
+msgstr "Не могу получить информацию о тюнере (код ошибки %1)"
+
+#: v4lradio.cpp:1409
+msgid "error setting %1: %2"
+msgstr "Ошибка установки %1: %2"
+
+#: v4lradio.cpp:1417
+msgid "error reading %1: %2"
+msgstr "Ошибка чтения %1: %2"
+
+#: v4lradio.cpp:1513
+msgid "error updating radio audio info (%1): %2"
+msgstr "Ошибка %1: %2"
+
+#: v4lradio.cpp:1514
+msgid "write"
+msgstr "запись"
+
+#: v4lradio.cpp:1514
+msgid "read"
+msgstr "чтение"
diff --git a/kradio3/plugins/v4lradio/v4lcfg_interfaces.cpp b/kradio3/plugins/v4lradio/v4lcfg_interfaces.cpp
new file mode 100644
index 0000000..c679c76
--- /dev/null
+++ b/kradio3/plugins/v4lradio/v4lcfg_interfaces.cpp
@@ -0,0 +1,193 @@
+/***************************************************************************
+ v4lradio_interfaces.cpp - description
+ -------------------
+ begin : Sam Jun 21 2003
+ copyright : (C) 2003 by Martin Witte
+ email : witte@kawo1.rwth-aachen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include <linux/soundcard.h>
+#include "v4lcfg_interfaces.h"
+
+///////////////////////////////////////////////////////////////////////
+
+V4LCaps::V4LCaps()
+ : version(0),
+ description(QString::null),
+ hasMute(false),
+ hasVolume(false),
+ minVolume(0),
+ maxVolume(65535),
+ hasTreble(false),
+ minTreble(0),
+ maxTreble(65535),
+ hasBass(false),
+ minBass(0),
+ maxBass(65535),
+ hasBalance(false),
+ minBalance(0),
+ maxBalance(65535)
+{
+}
+
+
+V4LCaps::V4LCaps(const V4LCaps &c)
+ : version(c.version),
+ description(c.description),
+ hasMute(c.hasMute),
+ hasVolume(c.hasVolume),
+ minVolume(c.minVolume),
+ maxVolume(c.maxVolume),
+ hasTreble(c.hasTreble),
+ minTreble(c.minTreble),
+ maxTreble(c.maxTreble),
+ hasBass(c.hasBass),
+ minBass(c.minBass),
+ maxBass(c.maxBass),
+ hasBalance(c.hasBalance),
+ minBalance(c.minBalance),
+ maxBalance(c.maxBalance)
+{
+}
+
+
+// IV4LCfg
+
+IF_IMPL_SENDER ( IV4LCfg::notifyRadioDeviceChanged(const QString &s),
+ noticeRadioDeviceChanged(s)
+ )
+IF_IMPL_SENDER ( IV4LCfg::notifyPlaybackMixerChanged(const QString &s, const QString &Channel),
+ noticePlaybackMixerChanged(s, Channel)
+ )
+IF_IMPL_SENDER ( IV4LCfg::notifyCaptureMixerChanged(const QString &s, const QString &Channel),
+ noticeCaptureMixerChanged(s, Channel)
+ )
+IF_IMPL_SENDER ( IV4LCfg::notifyDeviceVolumeChanged(float v),
+ noticeDeviceVolumeChanged(v)
+ )
+IF_IMPL_SENDER ( IV4LCfg::notifyCapabilitiesChanged(const V4LCaps &c),
+ noticeCapabilitiesChanged(c)
+ )
+
+IF_IMPL_SENDER ( IV4LCfg::notifyActivePlaybackChanged(bool a),
+ noticeActivePlaybackChanged(a)
+ )
+
+IF_IMPL_SENDER ( IV4LCfg::notifyMuteOnPowerOffChanged(bool a),
+ noticeMuteOnPowerOffChanged(a)
+ )
+
+IF_IMPL_SENDER ( IV4LCfg::notifyVolumeZeroOnPowerOffChanged(bool a),
+ noticeVolumeZeroOnPowerOffChanged(a)
+ )
+// IV4LCfgClient
+
+IF_IMPL_SENDER ( IV4LCfgClient::sendRadioDevice (const QString &s),
+ setRadioDevice(s)
+ )
+IF_IMPL_SENDER ( IV4LCfgClient::sendPlaybackMixer(const QString &s, const QString &ch),
+ setPlaybackMixer(s, ch)
+ )
+IF_IMPL_SENDER ( IV4LCfgClient::sendCaptureMixer(const QString &s, const QString &ch),
+ setCaptureMixer(s, ch)
+ )
+IF_IMPL_SENDER ( IV4LCfgClient::sendDeviceVolume(float v),
+ setDeviceVolume(v)
+ )
+
+IF_IMPL_SENDER ( IV4LCfgClient::sendActivePlayback(bool a),
+ setActivePlayback(a)
+ )
+
+IF_IMPL_SENDER ( IV4LCfgClient::sendMuteOnPowerOff(bool a),
+ setMuteOnPowerOff(a)
+ )
+
+IF_IMPL_SENDER ( IV4LCfgClient::sendVolumeZeroOnPowerOff(bool a),
+ setVolumeZeroOnPowerOff(a)
+ )
+
+static QString defaultRDev("/dev/radio");
+// static QString defaultMDev("/dev/mixer");
+
+IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryRadioDevice (),
+ getRadioDevice(),
+ defaultRDev
+ )
+IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryPlaybackMixerID (),
+ getPlaybackMixerID(),
+ QString::null
+ )
+IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryCaptureMixerID (),
+ getCaptureMixerID(),
+ QString::null
+ )
+
+static const QString channel_line("Line");
+IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryPlaybackMixerChannel(),
+ getPlaybackMixerChannel(),
+ channel_line
+ )
+IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryCaptureMixerChannel(),
+ getCaptureMixerChannel(),
+ channel_line
+ )
+IF_IMPL_QUERY ( float IV4LCfgClient::queryDeviceVolume (),
+ getDeviceVolume(),
+ 0.0
+ )
+IF_IMPL_QUERY ( V4LCaps IV4LCfgClient::queryCapabilities(QString dev),
+ getCapabilities(dev),
+ V4LCaps()
+ )
+
+IF_IMPL_QUERY ( bool IV4LCfgClient::queryActivePlayback(),
+ getActivePlayback(),
+ false
+ )
+
+IF_IMPL_QUERY ( bool IV4LCfgClient::queryMuteOnPowerOff(),
+ getMuteOnPowerOff(),
+ false
+ )
+
+IF_IMPL_QUERY ( bool IV4LCfgClient::queryVolumeZeroOnPowerOff(),
+ getVolumeZeroOnPowerOff(),
+ false
+ )
+
+void IV4LCfgClient::noticeConnectedI (cmplInterface *, bool /*pointer_valid*/)
+{
+ noticeRadioDeviceChanged(queryRadioDevice());
+ noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel());
+ noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel());
+ noticeDeviceVolumeChanged(queryDeviceVolume());
+ noticeCapabilitiesChanged(queryCapabilities());
+ noticeActivePlaybackChanged(queryActivePlayback());
+ noticeMuteOnPowerOffChanged(queryMuteOnPowerOff());
+ noticeVolumeZeroOnPowerOffChanged(queryVolumeZeroOnPowerOff());
+}
+
+
+void IV4LCfgClient::noticeDisconnectedI (cmplInterface *, bool /*pointer_valid*/)
+{
+ noticeRadioDeviceChanged(queryRadioDevice());
+ noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel());
+ noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel());
+ noticeDeviceVolumeChanged(queryDeviceVolume());
+ noticeCapabilitiesChanged(queryCapabilities());
+ noticeActivePlaybackChanged(queryActivePlayback());
+ noticeMuteOnPowerOffChanged(queryMuteOnPowerOff());
+ noticeVolumeZeroOnPowerOffChanged(queryVolumeZeroOnPowerOff());
+}
+
+
diff --git a/kradio3/plugins/v4lradio/v4lcfg_interfaces.h b/kradio3/plugins/v4lradio/v4lcfg_interfaces.h
new file mode 100644
index 0000000..f2e1032
--- /dev/null
+++ b/kradio3/plugins/v4lradio/v4lcfg_interfaces.h
@@ -0,0 +1,151 @@
+/***************************************************************************
+ v4lradio_interfaces.h - description
+ -------------------
+ begin : Sam Jun 21 2003
+ copyright : (C) 2003 by Martin Witte
+ email : witte@kawo1.rwth-aachen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KRADIO_V4LCFG_INTERFACES_H
+#define KRADIO_V4LCFG_INTERFACES_H
+
+#include "../../src/include/interfaces.h"
+#include "math.h"
+
+struct V4LCaps
+{
+ int version;
+ QString description;
+
+ bool hasMute;
+
+ bool hasVolume;
+ int minVolume, maxVolume;
+ bool hasTreble;
+ int minTreble, maxTreble;
+ bool hasBass;
+ int minBass, maxBass;
+ bool hasBalance;
+ int minBalance, maxBalance;
+
+ V4LCaps();
+ V4LCaps(const V4LCaps &);
+
+ float volumeStep() const { return 1.0 / (float)(maxVolume - minVolume); }
+ float trebleStep() const { return 1.0 / (float)(maxTreble - minTreble); }
+ float bassStep() const { return 1.0 / (float)(maxBass - minBass); }
+ float balanceStep() const { return 1.0 / (float)(maxBalance - minBalance); }
+
+ void setVolume (int min, int max) { hasVolume = true; minVolume = min; maxVolume = max; }
+ void setTreble (int min, int max) { hasTreble = true; minTreble = min; maxTreble = max; }
+ void setBass (int min, int max) { hasBass = true; minBass = min; maxBass = max; }
+ void setBalance(int min, int max) { hasBalance = true; minBalance = min; maxBalance = max; }
+
+ void unsetVolume () { hasVolume = false; minVolume = 0; maxVolume = 65535; }
+ void unsetTreble () { hasTreble = false; minTreble = 0; maxTreble = 65535; }
+ void unsetBass () { hasBass = false; minBass = 0; maxBass = 65535; }
+ void unsetBalance() { hasBalance = false; minBalance = 0; maxBalance = 65535; }
+
+ int intGetVolume (float f) const { return (int)rint(minVolume + (maxVolume - minVolume ) * f); }
+ int intGetTreble (float f) const { return (int)rint(minTreble + (maxTreble - minTreble ) * f); }
+ int intGetBass (float f) const { return (int)rint(minBass + (maxBass - minBass ) * f); }
+ int intGetBalance(float f) const { return (int)rint(minBalance + (maxBalance - minBalance) / 2.0 * (1.0 + f)); }
+
+ float floatGetVolume (int i) const { return (float)(i - minVolume) * volumeStep(); }
+ float floatGetTreble (int i) const { return (float)(i - minTreble) * trebleStep(); }
+ float floatGetBass (int i) const { return (float)(i - minBass ) * bassStep(); }
+ float floatGetBalance(int i) const { return (float)(i - minBalance) * balanceStep() * 2.0 - 1.0; }
+};
+
+
+
+INTERFACE(IV4LCfg, IV4LCfgClient)
+{
+public:
+ IF_CON_DESTRUCTOR(IV4LCfg, -1)
+
+RECEIVERS:
+ IF_RECEIVER( setRadioDevice (const QString &s) )
+ IF_RECEIVER( setPlaybackMixer(const QString &soundStreamClientID, const QString &ch) )
+ IF_RECEIVER( setCaptureMixer (const QString &soundStreamClientID, const QString &ch) )
+ IF_RECEIVER( setDeviceVolume(float v) )
+ IF_RECEIVER( setActivePlayback(bool a) )
+ IF_RECEIVER( setMuteOnPowerOff(bool m) )
+ IF_RECEIVER( setVolumeZeroOnPowerOff(bool m) )
+
+SENDERS:
+ IF_SENDER ( notifyRadioDeviceChanged (const QString &s) )
+ IF_SENDER ( notifyPlaybackMixerChanged(const QString &soundStreamClientID, const QString &Channel) )
+ IF_SENDER ( notifyCaptureMixerChanged (const QString &soundStreamClientID, const QString &Channel) )
+ IF_SENDER ( notifyDeviceVolumeChanged (float v) )
+ IF_SENDER ( notifyCapabilitiesChanged (const V4LCaps &) )
+ IF_SENDER ( notifyActivePlaybackChanged (bool a) )
+ IF_SENDER ( notifyMuteOnPowerOffChanged (bool a) )
+ IF_SENDER ( notifyVolumeZeroOnPowerOffChanged (bool a) )
+
+ANSWERS:
+ IF_ANSWER ( const QString &getRadioDevice () const )
+ IF_ANSWER ( const QString &getPlaybackMixerID () const )
+ IF_ANSWER ( const QString &getCaptureMixerID () const )
+ IF_ANSWER ( const QString &getPlaybackMixerChannel() const )
+ IF_ANSWER ( const QString &getCaptureMixerChannel() const )
+ IF_ANSWER ( float getDeviceVolume() const )
+ IF_ANSWER ( V4LCaps getCapabilities(QString dev = QString::null) const )
+ IF_ANSWER ( bool getActivePlayback() const )
+ IF_ANSWER ( bool getMuteOnPowerOff() const )
+ IF_ANSWER ( bool getVolumeZeroOnPowerOff() const )
+};
+
+
+
+INTERFACE(IV4LCfgClient, IV4LCfg)
+{
+public:
+ IF_CON_DESTRUCTOR(IV4LCfgClient, 1)
+
+SENDERS:
+ IF_SENDER ( sendRadioDevice (const QString &s) )
+ IF_SENDER ( sendPlaybackMixer(const QString &soundStreamClientID, const QString &ch) )
+ IF_SENDER ( sendCaptureMixer (const QString &soundStreamClientID, const QString &ch) )
+ IF_SENDER ( sendDeviceVolume(float v) )
+ IF_SENDER ( sendActivePlayback(bool a) )
+ IF_SENDER ( sendMuteOnPowerOff(bool a) )
+ IF_SENDER ( sendVolumeZeroOnPowerOff(bool a) )
+
+RECEIVERS:
+ IF_RECEIVER( noticeRadioDeviceChanged(const QString &s) )
+ IF_RECEIVER( noticePlaybackMixerChanged(const QString &soundStreamClientID, const QString &Channel) )
+ IF_RECEIVER( noticeCaptureMixerChanged (const QString &soundStreamClientID, const QString &Channel) )
+ IF_RECEIVER( noticeDeviceVolumeChanged(float v) )
+ IF_RECEIVER( noticeCapabilitiesChanged(const V4LCaps &) )
+ IF_RECEIVER( noticeActivePlaybackChanged(bool a) )
+ IF_RECEIVER( noticeMuteOnPowerOffChanged(bool a) )
+ IF_RECEIVER( noticeVolumeZeroOnPowerOffChanged(bool a) )
+
+QUERIES:
+ IF_QUERY ( const QString &queryRadioDevice () )
+ IF_QUERY ( const QString &queryPlaybackMixerID () )
+ IF_QUERY ( const QString &queryCaptureMixerID () )
+ IF_QUERY ( const QString &queryPlaybackMixerChannel() )
+ IF_QUERY ( const QString &queryCaptureMixerChannel() )
+ IF_QUERY ( float queryDeviceVolume() )
+ IF_QUERY ( V4LCaps queryCapabilities(QString dev = QString::null) )
+ IF_QUERY ( bool queryActivePlayback() )
+ IF_QUERY ( bool queryMuteOnPowerOff() )
+ IF_QUERY ( bool queryVolumeZeroOnPowerOff() )
+
+RECEIVERS:
+ virtual void noticeConnectedI (cmplInterface *, bool /*pointer_valid*/);
+ virtual void noticeDisconnectedI (cmplInterface *, bool /*pointer_valid*/);
+};
+
+#endif
diff --git a/kradio3/plugins/v4lradio/v4lradio-configuration-ui.ui b/kradio3/plugins/v4lradio/v4lradio-configuration-ui.ui
new file mode 100644
index 0000000..2cc4cfd
--- /dev/null
+++ b/kradio3/plugins/v4lradio/v4lradio-configuration-ui.ui
@@ -0,0 +1,966 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>V4LRadioConfigurationUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>V4LRadioConfigurationUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>512</width>
+ <height>357</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>SetupDialogGeneral</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>kTabWidget1</cstring>
+ </property>
+ <property name="currentPage">
+ <number>0</number>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Devices</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>spacer18_3_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>labelPlaybackMixerDevice</cstring>
+ </property>
+ <property name="text">
+ <string>Playback Mixer Device</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>labelPlaybackMixerChannel</cstring>
+ </property>
+ <property name="text">
+ <string>Playback Mixer Channel</string>
+ </property>
+ </widget>
+ <spacer row="2" column="2">
+ <property name="name">
+ <cstring>spacer18_3_4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="3" column="2">
+ <property name="name">
+ <cstring>spacer18_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="4" column="2">
+ <property name="name">
+ <cstring>spacer18_3_4_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="5" column="2">
+ <property name="name">
+ <cstring>spacer18_3_5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer18_3_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>152</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>labelRadioDevice</cstring>
+ </property>
+ <property name="text">
+ <string>Radio Device</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="0" column="2">
+ <property name="name">
+ <cstring>buttonSelectRadioDevice</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="iconSet">
+ <iconset>"fileopen"</iconset>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>labelCaptureMixerDevice</cstring>
+ </property>
+ <property name="text">
+ <string>Capture Mixer Device</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="5" column="1">
+ <property name="name">
+ <cstring>comboCaptureMixerChannel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>labelCaptureMixerChannel</cstring>
+ </property>
+ <property name="text">
+ <string>Capture Mixer Channel</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="4" column="1">
+ <property name="name">
+ <cstring>comboCaptureMixerDevice</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="3" column="1">
+ <property name="name">
+ <cstring>comboPlaybackMixerChannel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="2" column="1">
+ <item>
+ <property name="text">
+ <string>test</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>comboPlaybackMixerDevice</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>labelDescription</cstring>
+ </property>
+ <property name="text">
+ <string>unknown v4l device</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>editRadioDevice</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <spacer row="9" column="1">
+ <property name="name">
+ <cstring>spacer15</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>5</width>
+ <height>5</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="6" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>m_checkboxActivePlayback</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Use active pla&amp;yback by capturing</string>
+ </property>
+ <property name="accel">
+ <string>Alt+Y</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="7" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>m_checkboxMuteOnPowerOff</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Mute Play&amp;back Channel on Power Off</string>
+ </property>
+ <property name="accel">
+ <string>Alt+B</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="8" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>m_checkboxVolumeZeroOnPowerOff</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Set Playback Channel Volume to &amp;Zero on Power Off</string>
+ </property>
+ <property name="accel">
+ <string>Alt+Z</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Options</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="2">
+ <property name="name">
+ <cstring>layout37</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelFrequencyRange</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>to</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>editMaxFrequency</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> kHz</string>
+ </property>
+ <property name="maxValue">
+ <number>300000</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="lineStep">
+ <number>1000</number>
+ </property>
+ <property name="value">
+ <number>300000</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>editScanStep</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> kHz</string>
+ </property>
+ <property name="maxValue">
+ <number>500</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>labelSignalMinQuality</cstring>
+ </property>
+ <property name="text">
+ <string>minimum signal quality</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>editMinFrequency</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> kHz</string>
+ </property>
+ <property name="maxValue">
+ <number>2999999</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="lineStep">
+ <number>1000</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>labelScanStep</cstring>
+ </property>
+ <property name="text">
+ <string>station scan step</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>labelMinMaxFrequency</cstring>
+ </property>
+ <property name="text">
+ <string>allowed frequency range</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>editSignalMinQuality</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="value">
+ <number>75</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="2">
+ <property name="name">
+ <cstring>textLabel1_4_2</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <spacer row="3" column="1">
+ <property name="name">
+ <cstring>spacer16</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>5</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>V4L Mixer Controls</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout35</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelDeviceVolume</cstring>
+ </property>
+ <property name="text">
+ <string>volume</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout34</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer42</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>sliderDeviceVolume</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer43</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="KDoubleNumInput">
+ <property name="name">
+ <cstring>editDeviceVolume</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout35_2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelTreble</cstring>
+ </property>
+ <property name="text">
+ <string>treble</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout34_2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer42_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>sliderTreble</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer43_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="KDoubleNumInput">
+ <property name="name">
+ <cstring>editTreble</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="2">
+ <property name="name">
+ <cstring>layout35_2_2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelBass</cstring>
+ </property>
+ <property name="text">
+ <string>bass</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout34_2_3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer42_2_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>sliderBass</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer43_2_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="KDoubleNumInput">
+ <property name="name">
+ <cstring>editBass</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="3">
+ <property name="name">
+ <cstring>layout51</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>labelBalance</cstring>
+ </property>
+ <property name="text">
+ <string>balance</string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer40</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>33</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>sliderBalance</cstring>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="maxValue">
+ <number>65535</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer41</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>33</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KDoubleNumInput">
+ <property name="name">
+ <cstring>editBalance</cstring>
+ </property>
+ <property name="minValue">
+ <number>-1</number>
+ </property>
+ <property name="maxValue">
+ <number>1</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<tabstops>
+ <tabstop>editRadioDevice</tabstop>
+ <tabstop>buttonSelectRadioDevice</tabstop>
+ <tabstop>comboPlaybackMixerChannel</tabstop>
+ <tabstop>editMinFrequency</tabstop>
+ <tabstop>editMaxFrequency</tabstop>
+ <tabstop>editSignalMinQuality</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in implementation">kiconloader.h</include>
+ <include location="global" impldecl="in implementation">knuminput.h</include>
+</includes>
+<pixmapfunction>SmallIconSet</pixmapfunction>
+<layoutdefaults spacing="6" margin="0"/>
+<includehints>
+ <includehint>ktabwidget.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+</includehints>
+</UI>
diff --git a/kradio3/plugins/v4lradio/v4lradio-configuration.cpp b/kradio3/plugins/v4lradio/v4lradio-configuration.cpp
new file mode 100644
index 0000000..f7472fc
--- /dev/null
+++ b/kradio3/plugins/v4lradio/v4lradio-configuration.cpp
@@ -0,0 +1,648 @@
+/***************************************************************************
+ v4lradio-configuration.cpp - description
+ -------------------
+ begin : Fre Jun 20 2003
+ copyright : (C) 2003 by Martin Witte
+ email : witte@kawo1.rwth-aachen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/soundcard.h>
+
+#include <qspinbox.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <qfile.h>
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qcheckbox.h>
+
+#include <kfiledialog.h>
+#include <knuminput.h>
+#include <klocale.h>
+#include <ktabwidget.h>
+
+#include "../../src/include/utils.h"
+#include "../../src/include/gui_list_helper.h"
+#include "v4lradio-configuration.h"
+#include "v4lradio.h"
+
+V4LRadioConfiguration::V4LRadioConfiguration (QWidget *parent, SoundStreamID ssid)
+ : V4LRadioConfigurationUI(parent),
+ m_SoundStreamID(ssid),
+ m_ignoreGUIChanges(false),
+ m_myControlChange(0),
+ m_orgTreble(-1),
+ m_orgBass(-1),
+ m_orgBalance(-2),
+ m_orgDeviceVolume(-1),
+ m_PlaybackMixerHelper(comboPlaybackMixerDevice, StringListHelper::SORT_BY_DESCR),
+ m_CaptureMixerHelper (comboCaptureMixerDevice, StringListHelper::SORT_BY_DESCR),
+ m_PlaybackChannelHelper(comboPlaybackMixerChannel),
+ m_CaptureChannelHelper (comboCaptureMixerChannel)
+{
+ QObject::connect(buttonSelectRadioDevice, SIGNAL(clicked()),
+ this, SLOT(selectRadioDevice()));
+ editRadioDevice->installEventFilter(this);
+ QObject::connect(editMinFrequency, SIGNAL(valueChanged(int)),
+ this, SLOT(guiMinFrequencyChanged(int)));
+ QObject::connect(editMaxFrequency, SIGNAL(valueChanged(int)),
+ this, SLOT(guiMaxFrequencyChanged(int)));
+
+ QObject::connect(editDeviceVolume, SIGNAL(valueChanged(double)),
+ this, SLOT(slotDeviceVolumeChanged(double)));
+ QObject::connect(editTreble, SIGNAL(valueChanged(double)),
+ this, SLOT(slotTrebleChanged(double)));
+ QObject::connect(editBass, SIGNAL(valueChanged(double)),
+ this, SLOT(slotBassChanged(double)));
+ QObject::connect(editBalance, SIGNAL(valueChanged(double)),
+ this, SLOT(slotBalanceChanged(double)));
+
+ QObject::connect(sliderDeviceVolume, SIGNAL(valueChanged(int)),
+ this, SLOT(slotDeviceVolumeChanged(int)));
+ QObject::connect(sliderTreble, SIGNAL(valueChanged(int)),
+ this, SLOT(slotTrebleChanged(int)));
+ QObject::connect(sliderBass, SIGNAL(valueChanged(int)),
+ this, SLOT(slotBassChanged(int)));
+ QObject::connect(sliderBalance, SIGNAL(valueChanged(int)),
+ this, SLOT(slotBalanceChanged(int)));
+
+ QObject::connect(comboPlaybackMixerDevice, SIGNAL(activated(int)),
+ this, SLOT(slotComboPlaybackMixerSelected(int)));
+ QObject::connect(comboCaptureMixerDevice, SIGNAL(activated(int)),
+ this, SLOT(slotComboCaptureMixerSelected(int)));
+
+ sliderBalance->installEventFilter(this);
+}
+
+
+V4LRadioConfiguration::~V4LRadioConfiguration ()
+{
+}
+
+
+bool V4LRadioConfiguration::connectI (Interface *i)
+{
+ bool a = IV4LCfgClient::connectI(i);
+ bool b = IFrequencyRadioClient::connectI(i);
+ bool c = IRadioDeviceClient::connectI(i);
+ bool d = ISoundStreamClient::connectI(i);
+ return a || b || c || d;
+}
+
+
+bool V4LRadioConfiguration::disconnectI (Interface *i)
+{
+ bool a = IV4LCfgClient::disconnectI(i);
+ bool b = IFrequencyRadioClient::disconnectI(i);
+ bool c = IRadioDeviceClient::disconnectI(i);
+ bool d = ISoundStreamClient::disconnectI(i);
+ return a || b || c || d;
+}
+
+void V4LRadioConfiguration::noticeConnectedI (ISoundStreamServer *s, bool pointer_valid)
+{
+ ISoundStreamClient::noticeConnectedI(s, pointer_valid);
+ if (s && pointer_valid) {
+ s->register4_notifyTrebleChanged(this);
+ s->register4_notifyBassChanged(this);
+ s->register4_notifyBalanceChanged(this);
+ s->register4_notifySignalMinQualityChanged(this);
+
+ s->register4_notifyPlaybackChannelsChanged(this);
+ s->register4_notifyCaptureChannelsChanged(this);
+ s->register4_notifySoundStreamCreated(this);
+ }
+}
+
+void V4LRadioConfiguration::noticeConnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid)
+{
+ if (i && pointer_valid && i->supportsPlayback()) {
+ const QString &org_mid = queryPlaybackMixerID();
+ bool org_present = m_PlaybackMixerHelper.contains(org_mid);
+ const QString &mid = org_present ? m_PlaybackMixerHelper.getCurrentItem() : org_mid;
+ const QString &org_ch = queryPlaybackMixerChannel();
+ const QString &ch = org_present ? m_PlaybackChannelHelper.getCurrentText() : org_ch;
+ noticePlaybackMixerChanged(mid, ch);
+ }
+ if (i && pointer_valid && i->supportsCapture()) {
+ const QString &org_mid = queryCaptureMixerID();
+ bool org_present = m_CaptureMixerHelper.contains(org_mid);
+ const QString &mid = org_present ? m_CaptureMixerHelper.getCurrentItem() : org_mid;
+ const QString &org_ch = queryCaptureMixerChannel();
+ const QString &ch = org_present ? m_CaptureChannelHelper.getCurrentText() : org_ch;
+ noticeCaptureMixerChanged(mid, ch);
+ }
+}
+
+
+void V4LRadioConfiguration::noticeDisconnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid)
+{
+ if (i && pointer_valid && i->supportsPlayback()) {
+ noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel());
+ }
+ if (i && pointer_valid && i->supportsCapture()) {
+ noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel());
+ }
+}
+
+// IV4LCfgClient
+
+bool V4LRadioConfiguration::noticeRadioDeviceChanged(const QString &s)
+{
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+
+ editRadioDevice->setText(s);
+
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticePlaybackMixerChanged(const QString &_mixer_id, const QString &Channel)
+{
+ QString mixer_id = _mixer_id;
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+
+ m_PlaybackMixerHelper.setData(getPlaybackClientDescriptions());
+ m_PlaybackMixerHelper.setCurrentItem(mixer_id);
+ mixer_id = m_PlaybackMixerHelper.getCurrentItem();
+
+ ISoundStreamClient *mixer = getSoundStreamClientWithID(mixer_id);
+ if (mixer) {
+ m_PlaybackChannelHelper.setData(mixer->getPlaybackChannels());
+ m_PlaybackChannelHelper.setCurrentText(m_PlaybackChannelHelper.contains(Channel) ? Channel : queryPlaybackMixerChannel());
+ }
+ labelPlaybackMixerChannel->setEnabled(mixer != NULL);
+ comboPlaybackMixerChannel->setEnabled(mixer != NULL);
+
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeCaptureMixerChanged(const QString &_mixer_id, const QString &Channel)
+{
+ QString mixer_id = _mixer_id;
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+
+ m_CaptureMixerHelper.setData(getCaptureClientDescriptions());
+ m_CaptureMixerHelper.setCurrentItem(mixer_id);
+ mixer_id = m_CaptureMixerHelper.getCurrentItem();
+
+ ISoundStreamClient *mixer = getSoundStreamClientWithID(mixer_id);
+ if (mixer) {
+ m_CaptureChannelHelper.setData(mixer->getCaptureChannels());
+ m_CaptureChannelHelper.setCurrentText(m_CaptureChannelHelper.contains(Channel) ? Channel : queryCaptureMixerChannel());
+ }
+ labelCaptureMixerChannel->setEnabled(mixer != NULL);
+ comboCaptureMixerChannel->setEnabled(mixer != NULL);
+
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeDeviceVolumeChanged(float v)
+{
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+ v = v > 1 ? 1 : v;
+ v = v < 0 ? 0 : v;
+
+ if (!m_myControlChange)
+ m_orgDeviceVolume = v;
+
+ editDeviceVolume ->setValue(v);
+ sliderDeviceVolume->setValue(m_caps.maxVolume - m_caps.intGetVolume(v));
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeCapabilitiesChanged(const V4LCaps &c)
+{
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+
+ labelDeviceVolume ->setEnabled(c.hasVolume);
+ editDeviceVolume ->setEnabled(c.hasVolume);
+ editDeviceVolume ->setRange(0, 1, c.volumeStep(), false);
+ sliderDeviceVolume->setMinValue(0);
+ sliderDeviceVolume->setMaxValue(c.maxVolume - c.minVolume);
+ sliderDeviceVolume->setEnabled(c.hasVolume);
+
+ labelTreble ->setEnabled(c.hasTreble);
+ editTreble ->setEnabled(c.hasTreble);
+ editTreble ->setRange(0, 1, c.trebleStep(), false);
+ sliderTreble->setMinValue(0);
+ sliderTreble->setMaxValue(c.maxTreble - c.minTreble);
+ sliderTreble->setEnabled(c.hasTreble);
+
+ labelBass ->setEnabled(c.hasBass);
+ editBass ->setEnabled(c.hasBass);
+ editBass ->setRange(0, 1, c.bassStep(), false);
+ sliderBass->setMinValue(0);
+ sliderBass->setMaxValue(c.maxBass - c.minBass);
+ sliderBass->setEnabled(c.hasBass);
+
+ labelBalance ->setEnabled(c.hasBalance);
+ editBalance ->setEnabled(c.hasBalance);
+ editBalance ->setRange(-1, 1, c.balanceStep(), false);
+ sliderBalance->setMinValue(0);
+ sliderBalance->setMaxValue(c.maxBalance - c.minBalance);
+ sliderBalance->setEnabled(c.hasBalance);
+
+ m_caps = c;
+
+ float tmp = 0;
+ noticeDeviceVolumeChanged(queryDeviceVolume());
+
+ queryTreble(m_SoundStreamID, tmp);
+ noticeTrebleChanged(m_SoundStreamID, tmp);
+
+ queryBass(m_SoundStreamID, tmp);
+ noticeBassChanged(m_SoundStreamID, tmp);
+
+ queryBalance(m_SoundStreamID, tmp);
+ noticeBalanceChanged(m_SoundStreamID, tmp);
+
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+bool V4LRadioConfiguration::noticeActivePlaybackChanged(bool a)
+{
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+ m_checkboxActivePlayback->setChecked(a);
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+bool V4LRadioConfiguration::noticeMuteOnPowerOffChanged(bool a)
+{
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+ m_checkboxMuteOnPowerOff->setChecked(a);
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+bool V4LRadioConfiguration::noticeVolumeZeroOnPowerOffChanged(bool a)
+{
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+ m_checkboxVolumeZeroOnPowerOff->setChecked(a);
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+// IRadioDeviceClient
+
+bool V4LRadioConfiguration::noticeDescriptionChanged (const QString &s, const IRadioDevice */*sender*/)
+{
+ labelDescription->setText(s);
+ return true;
+}
+
+
+// IFrequencyRadioClient
+
+bool V4LRadioConfiguration::noticeFrequencyChanged(float /*f*/, const RadioStation */*s*/)
+{
+ return false; // we don't care
+}
+
+
+bool V4LRadioConfiguration::noticeMinMaxFrequencyChanged(float min, float max)
+{
+ editMinFrequency->setValue((int)rint(min*1000));
+ editMaxFrequency->setValue((int)rint(max*1000));
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeDeviceMinMaxFrequencyChanged(float min, float max)
+{
+ editMinFrequency->setMinValue((int)rint(min*1000));
+ editMaxFrequency->setMaxValue((int)rint(max*1000));
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeScanStepChanged(float s)
+{
+ editScanStep->setValue((int)rint(s * 1000));
+ return true;
+}
+
+
+// IRadioSoundClient
+
+bool V4LRadioConfiguration::noticeTrebleChanged(SoundStreamID id, float t)
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+ t = t > 1 ? 1 : t;
+ t = t < 0 ? 0 : t;
+
+ if (!m_myControlChange)
+ m_orgTreble = t;
+
+ editTreble ->setValue (t);
+ sliderTreble->setValue(m_caps.maxTreble - m_caps.intGetTreble(t));
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeBassChanged(SoundStreamID id, float b)
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+ b = b > 1 ? 1 : b;
+ b = b < 0 ? 0 : b;
+
+ if (!m_myControlChange)
+ m_orgBass = b;
+
+ editBass ->setValue(b);
+ sliderBass->setValue(m_caps.maxBass - m_caps.intGetBass(b));
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeBalanceChanged(SoundStreamID id, float b)
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ bool old = m_ignoreGUIChanges;
+ m_ignoreGUIChanges = true;
+ b = b > 1 ? 1 : b;
+ b = b < -1 ? -1 : b;
+
+ if (!m_myControlChange)
+ m_orgBalance = b;
+
+ editBalance ->setValue(b);
+ sliderBalance->setValue(m_caps.intGetBalance(b));
+ m_ignoreGUIChanges = old;
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeSignalMinQualityChanged(SoundStreamID id, float q)
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ editSignalMinQuality->setValue((int)rint(q * 100));
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeSoundStreamCreated(SoundStreamID id)
+{
+ if (id.HasSamePhysicalID(m_SoundStreamID)) {
+ m_SoundStreamID = id;
+ }
+ return true;
+}
+
+
+// GUI Slots
+
+
+void V4LRadioConfiguration::selectRadioDevice()
+{
+ KFileDialog fd("/dev/",
+ i18n("any ( * )").ascii(),
+ this,
+ i18n("Radio Device Selection").ascii(),
+ TRUE);
+ fd.setMode(KFile::File | KFile::ExistingOnly);
+ fd.setCaption (i18n("Select Radio Device"));
+
+ if (fd.exec() == QDialog::Accepted) {
+ editRadioDevice->setText(fd.selectedFile());
+ }
+}
+
+
+bool V4LRadioConfiguration::eventFilter(QObject *o, QEvent *e)
+{
+ if (e->type() == QEvent::FocusOut && o == editRadioDevice) {
+ slotEditRadioDeviceChanged();
+ }
+ if (e->type() == QEvent::MouseButtonDblClick && o == sliderBalance) {
+ slotBalanceCenter();
+ }
+ return false;
+}
+
+
+void V4LRadioConfiguration::slotEditRadioDeviceChanged()
+{
+ if (m_ignoreGUIChanges) return;
+ const QString &s = editRadioDevice->text();
+ if (s != queryRadioDevice() || !queryIsPowerOn()) {
+ V4LCaps c = queryCapabilities(s);
+ noticeDescriptionChanged(c.description);
+ } else {
+ noticeDescriptionChanged(queryDescription());
+ }
+}
+
+
+void V4LRadioConfiguration::slotComboPlaybackMixerSelected(int /*idx*/)
+{
+ if (m_ignoreGUIChanges) return;
+ QString id = m_PlaybackMixerHelper.getCurrentItem();
+ noticePlaybackMixerChanged(id, queryPlaybackMixerChannel());
+}
+
+
+void V4LRadioConfiguration::slotComboCaptureMixerSelected(int /*idx*/)
+{
+ if (m_ignoreGUIChanges) return;
+ QString id = m_CaptureMixerHelper.getCurrentItem();
+ noticeCaptureMixerChanged(id, queryCaptureMixerChannel());
+}
+
+
+void V4LRadioConfiguration::slotOK()
+{
+ sendMinFrequency(((float)editMinFrequency->value()) / 1000.0);
+ sendMaxFrequency(((float)editMaxFrequency->value()) / 1000.0);
+ sendSignalMinQuality(m_SoundStreamID, editSignalMinQuality->value() * 0.01);
+ sendRadioDevice(editRadioDevice->text());
+ sendScanStep(((float)editScanStep->value()) / 1000.0);
+
+ sendCaptureMixer (m_CaptureMixerHelper.getCurrentItem(),
+ m_CaptureChannelHelper.getCurrentText());
+ sendPlaybackMixer(m_PlaybackMixerHelper.getCurrentItem(),
+ m_PlaybackChannelHelper.getCurrentText());
+
+ sendActivePlayback(m_checkboxActivePlayback->isChecked());
+ sendMuteOnPowerOff(m_checkboxMuteOnPowerOff->isChecked());
+ sendVolumeZeroOnPowerOff(m_checkboxVolumeZeroOnPowerOff->isChecked());
+
+ queryTreble (m_SoundStreamID, m_orgTreble);
+ queryBass (m_SoundStreamID, m_orgBass);
+ queryBalance(m_SoundStreamID, m_orgBalance);
+ m_orgDeviceVolume = queryDeviceVolume();
+}
+
+
+void V4LRadioConfiguration::slotCancel()
+{
+ noticeRadioDeviceChanged(queryRadioDevice());
+ noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel());
+ noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel());
+ noticeMinMaxFrequencyChanged(queryMinFrequency(), queryMaxFrequency());
+ noticeActivePlaybackChanged(queryActivePlayback());
+ noticeMuteOnPowerOffChanged(queryMuteOnPowerOff());
+ noticeVolumeZeroOnPowerOffChanged(queryVolumeZeroOnPowerOff());
+
+ float q = 0;
+ querySignalMinQuality(m_SoundStreamID, q);
+ noticeSignalMinQualityChanged(m_SoundStreamID, q);
+ noticeScanStepChanged(queryScanStep());
+
+ sendTreble (m_SoundStreamID, m_orgTreble);
+ sendBass (m_SoundStreamID, m_orgBass);
+ sendBalance (m_SoundStreamID, m_orgBalance);
+ sendDeviceVolume(m_orgDeviceVolume);
+}
+
+
+void V4LRadioConfiguration::guiMinFrequencyChanged(int v)
+{
+ editMaxFrequency->setMinValue(v);
+}
+
+
+void V4LRadioConfiguration::guiMaxFrequencyChanged(int v)
+{
+ editMinFrequency->setMaxValue(v);
+}
+
+void V4LRadioConfiguration::slotDeviceVolumeChanged (double v) // for KDoubleNumInput, 0.0..1.0
+{
+ if (m_ignoreGUIChanges) return;
+ ++m_myControlChange;
+ sendDeviceVolume(v);
+ --m_myControlChange;
+}
+
+void V4LRadioConfiguration::slotTrebleChanged (double t) // for KDoubleNumInput, 0.0..1.0
+{
+ if (m_ignoreGUIChanges) return;
+ ++m_myControlChange;
+ sendTreble(m_SoundStreamID, t);
+ --m_myControlChange;
+}
+
+void V4LRadioConfiguration::slotBassChanged (double b) // for KDoubleNumInput, 0.0..1.0
+{
+ if (m_ignoreGUIChanges) return;
+ ++m_myControlChange;
+ sendBass(m_SoundStreamID, b);
+ --m_myControlChange;
+}
+
+void V4LRadioConfiguration::slotBalanceChanged(double b) // for KDoubleNumInput, -1.0..1.0
+{
+ if (m_ignoreGUIChanges) return;
+ ++m_myControlChange;
+ sendBalance(m_SoundStreamID, b);
+ --m_myControlChange;
+}
+
+
+void V4LRadioConfiguration::slotDeviceVolumeChanged (int v)
+{
+ if (m_ignoreGUIChanges) return;
+ ++m_myControlChange;
+ sendDeviceVolume(m_caps.floatGetVolume(m_caps.maxVolume - v));
+ --m_myControlChange;
+}
+
+void V4LRadioConfiguration::slotTrebleChanged (int t)
+{
+ if (m_ignoreGUIChanges) return;
+ ++m_myControlChange;
+ sendTreble(m_SoundStreamID, m_caps.floatGetTreble(m_caps.maxTreble - t));
+ --m_myControlChange;
+}
+
+void V4LRadioConfiguration::slotBassChanged (int b)
+{
+ if (m_ignoreGUIChanges) return;
+ ++m_myControlChange;
+ sendBass(m_SoundStreamID, m_caps.floatGetBass(m_caps.maxBass - b));
+ --m_myControlChange;
+}
+
+void V4LRadioConfiguration::slotBalanceChanged(int b)
+{
+ if (m_ignoreGUIChanges) return;
+ ++m_myControlChange;
+ sendBalance(m_SoundStreamID, m_caps.floatGetBalance(b));
+ --m_myControlChange;
+}
+
+
+void V4LRadioConfiguration::slotBalanceCenter()
+{
+ if (m_ignoreGUIChanges) return;
+ ++m_myControlChange;
+ sendBalance(m_SoundStreamID, 0);
+ --m_myControlChange;
+}
+
+
+bool V4LRadioConfiguration::noticePlaybackChannelsChanged(const QString & client_id, const QStringList &/*channels*/)
+{
+ if (m_PlaybackMixerHelper.getCurrentItem() == client_id) {
+ noticePlaybackMixerChanged(client_id, m_PlaybackChannelHelper.getCurrentText());
+ }
+ return true;
+}
+
+
+bool V4LRadioConfiguration::noticeCaptureChannelsChanged (const QString & client_id, const QStringList &/*channels*/)
+{
+ if (m_CaptureMixerHelper.getCurrentItem() == client_id) {
+ noticeCaptureMixerChanged(client_id, m_CaptureChannelHelper.getCurrentText());
+ }
+ return true;
+}
+
+
+
+#include "v4lradio-configuration.moc"
diff --git a/kradio3/plugins/v4lradio/v4lradio-configuration.h b/kradio3/plugins/v4lradio/v4lradio-configuration.h
new file mode 100644
index 0000000..bf41b54
--- /dev/null
+++ b/kradio3/plugins/v4lradio/v4lradio-configuration.h
@@ -0,0 +1,147 @@
+/***************************************************************************
+ v4lradio-configuration.h - description
+ -------------------
+ begin : Fre Jun 20 2003
+ copyright : (C) 2003 by Martin Witte
+ email : witte@kawo1.rwth-aachen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KRADIO_V4LRADIO_CONFIGURATION_H
+#define KRADIO_V4LRADIO_CONFIGURATION_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "../../src/include/radiodevice_interfaces.h"
+#include "../../src/include/soundstreamclient_interfaces.h"
+#include "../../src/include/gui_list_helper.h"
+
+#include "v4lradio-configuration-ui.h"
+#include "v4lcfg_interfaces.h"
+
+class V4LRadio;
+class QWidget;
+
+class V4LRadioConfiguration : public V4LRadioConfigurationUI,
+ public IV4LCfgClient,
+ public IFrequencyRadioClient,
+ public ISoundStreamClient,
+ public IRadioDeviceClient
+{
+Q_OBJECT
+public :
+ V4LRadioConfiguration (QWidget *parent, SoundStreamID id);
+ ~V4LRadioConfiguration ();
+
+ bool connectI (Interface *i);
+ bool disconnectI (Interface *i);
+
+ void noticeConnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid);
+ void noticeDisconnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid);
+
+// IV4LCfgClient
+
+RECEIVERS:
+ bool noticeRadioDeviceChanged(const QString &s);
+ bool noticePlaybackMixerChanged(const QString &soundStreamClientID, const QString &Channel);
+ bool noticeCaptureMixerChanged (const QString &soundStreamClientID, const QString &Channel);
+ bool noticeDeviceVolumeChanged(float v);
+ bool noticeCapabilitiesChanged(const V4LCaps &c);
+ bool noticeActivePlaybackChanged(bool a);
+ bool noticeMuteOnPowerOffChanged(bool a);
+ bool noticeVolumeZeroOnPowerOffChanged(bool a);
+
+// IRadioDeviceClient
+
+RECEIVERS:
+ bool noticePowerChanged (bool /*on*/, const IRadioDevice */*sender = NULL*/) { return false; }
+ bool noticeStationChanged (const RadioStation &, const IRadioDevice */*sender = NULL*/) { return false; }
+ bool noticeDescriptionChanged (const QString &, const IRadioDevice *sender = NULL);
+
+ bool noticeCurrentSoundStreamIDChanged(SoundStreamID /*id*/, const IRadioDevice */*sender*/) { return false; }
+
+// IFrequencyRadioClient
+
+RECEIVERS:
+ bool noticeFrequencyChanged(float f, const RadioStation *s);
+ bool noticeMinMaxFrequencyChanged(float min, float max);
+ bool noticeDeviceMinMaxFrequencyChanged(float min, float max);
+ bool noticeScanStepChanged(float s);
+
+// ISoundStreamClient
+
+RECEIVERS:
+ void noticeConnectedI (ISoundStreamServer *s, bool pointer_valid);
+
+ bool noticeTrebleChanged(SoundStreamID id, float t);
+ bool noticeBassChanged(SoundStreamID id, float b);
+ bool noticeBalanceChanged(SoundStreamID id, float b);
+ bool noticeSignalMinQualityChanged(SoundStreamID id, float q);
+
+ bool noticePlaybackChannelsChanged(const QString & /*client_id*/, const QStringList &/*channels*/);
+ bool noticeCaptureChannelsChanged (const QString & /*client_id*/, const QStringList &/*channels*/);
+ bool noticeSoundStreamCreated(SoundStreamID /*id*/);
+
+
+protected:
+
+ bool eventFilter(QObject *o, QEvent *e);
+
+protected slots:
+
+ void selectRadioDevice();
+ void slotEditRadioDeviceChanged();
+ void slotComboPlaybackMixerSelected(int idx);
+ void slotComboCaptureMixerSelected(int idx);
+
+ void slotOK();
+ void slotCancel();
+
+ void guiMinFrequencyChanged(int v);
+ void guiMaxFrequencyChanged(int v);
+
+ void slotDeviceVolumeChanged (double v); // for KDoubleNumInput, 0.0..1.0
+ void slotTrebleChanged (double t); // for KDoubleNumInput, 0.0..1.0
+ void slotBassChanged (double b); // for KDoubleNumInput, 0.0..1.0
+ void slotBalanceChanged(double b); // for KDoubleNumInput, -1.0..1.0
+
+ void slotDeviceVolumeChanged (int v); // for slider, 0..65535
+ void slotTrebleChanged (int t); // for slider, 0..65535
+ void slotBassChanged (int b); // for slider, 0..65535
+ void slotBalanceChanged(int b); // for slider, 0..65535
+ void slotBalanceCenter ();
+
+protected:
+
+ SoundStreamID m_SoundStreamID;
+
+ bool m_ignoreGUIChanges;
+
+ int m_myControlChange;
+ float m_orgTreble,
+ m_orgBass,
+ m_orgBalance,
+ m_orgDeviceVolume;
+
+ V4LCaps m_caps;
+
+ typedef GUIListHelper<QComboBox, QString> StringListHelper;
+ typedef GUISimpleListHelper<QComboBox> ChannelListHelper;
+
+ StringListHelper m_PlaybackMixerHelper,
+ m_CaptureMixerHelper;
+ ChannelListHelper m_PlaybackChannelHelper,
+ m_CaptureChannelHelper;
+};
+
+#endif
diff --git a/kradio3/plugins/v4lradio/v4lradio.cpp b/kradio3/plugins/v4lradio/v4lradio.cpp
new file mode 100644
index 0000000..fb1ee9f
--- /dev/null
+++ b/kradio3/plugins/v4lradio/v4lradio.cpp
@@ -0,0 +1,1621 @@
+/***************************************************************************
+ v4lradio.cpp - description
+ -------------------
+ begin : Don Mr 8 21:57:17 CET 2001
+ copyright : (C) 2002-2005 by Ernst Martin Witte
+ email : witte@kawo1.rwth-aachen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#ifdef HAVE_V4L2
+#include "linux/videodev2.h"
+#endif
+#include "linux/videodev.h"
+#include <linux/soundcard.h>
+
+#include <string.h> // memcpy needed
+
+#include <qlayout.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qvaluelist.h>
+
+#include <kconfig.h>
+#include <kiconloader.h>
+#include <kdialogbase.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+
+#include "../../src/include/aboutwidget.h"
+#include "../../src/include/utils.h"
+#include "v4lradio.h"
+#include "v4lradio-configuration.h"
+
+#include "../../src/include/debug-profiler.h"
+
+struct _lrvol { unsigned char l, r; short dummy; };
+
+///////////////////////////////////////////////////////////////////////
+
+PLUGIN_LIBRARY_FUNCTIONS(V4LRadio, "kradio-v4lradio", i18n("Support for V4L(2) Radio Devices"));
+
+///////////////////////////////////////////////////////////////////////
+
+V4LRadio::V4LRadio(const QString &name)
+ : PluginBase(name, i18n("Video For Linux Plugin")),
+ m_treble(0.5),
+ m_bass(0.5),
+ m_balance(0),
+ m_deviceVolume(0.9),
+ m_muted(false),
+ m_signalQuality(0),
+ m_stereo(false),
+ m_minQuality(0.75),
+ m_minFrequency(87.0),
+ m_maxFrequency(108.0),
+ m_lastMinDevFrequency(87.0),
+ m_lastMaxDevFrequency(108.0),
+
+ m_defaultPlaybackVolume(0.5),
+
+ m_scanStep(0.05),
+
+ m_radioDev("/dev/radio0"),
+ m_radio_fd(-1),
+ m_useOldV4L2Calls(true),
+ m_pollTimer(this),
+
+ m_blockReadTuner(false),
+ m_blockReadAudio(false),
+
+ m_SoundStreamID(createNewSoundStream(false)),
+ m_PlaybackMixerID(QString::null),
+ m_CaptureMixerID(QString::null),
+ m_PlaybackMixerChannel(QString::null),
+ m_CaptureMixerChannel(QString::null),
+ m_ActivePlayback(false),
+ m_MuteOnPowerOff(false),
+ m_VolumeZeroOnPowerOff(false),
+ m_restorePowerOn(false)
+{
+ QObject::connect (&m_pollTimer, SIGNAL(timeout()), this, SLOT(poll()));
+ m_pollTimer.start(333);
+
+ m_audio = new video_audio;
+ bzero(m_audio, sizeof(video_audio));
+ m_tuner = new video_tuner;
+ bzero(m_tuner, sizeof(video_tuner));
+#ifdef HAVE_V4L2
+ m_tuner2 = new v4l2_tuner;
+ bzero(m_tuner2, sizeof(v4l2_tuner));
+#endif
+ m_caps.version = 0;
+
+ m_seekHelper = new FrequencySeekHelper(*this);
+ m_seekHelper->connectI(this);
+}
+
+
+V4LRadio::~V4LRadio()
+{
+ setPower(false);
+
+ if (m_seekHelper)
+ delete m_seekHelper;
+
+ if (m_audio) delete m_audio;
+ if (m_tuner) delete m_tuner;
+#ifdef HAVE_V4L2
+ if (m_tuner2) delete m_tuner2;
+#endif
+}
+
+
+bool V4LRadio::connectI (Interface *i)
+{
+ bool a = IRadioDevice::connectI(i);
+ bool b = ISeekRadio::connectI(i);
+ bool c = IFrequencyRadio::connectI(i);
+ bool d = IV4LCfg::connectI(i);
+ bool e = PluginBase::connectI(i);
+ bool f = ISoundStreamClient::connectI(i);
+ return a || b || c || d || e || f;
+}
+
+
+bool V4LRadio::disconnectI (Interface *i)
+{
+ bool a = IRadioDevice::disconnectI(i);
+ bool b = ISeekRadio::disconnectI(i);
+ bool c = IFrequencyRadio::disconnectI(i);
+ bool d = IV4LCfg::disconnectI(i);
+ bool e = PluginBase::disconnectI(i);
+ bool f = ISoundStreamClient::disconnectI(i);
+ m_seekHelper->disconnectI(i);
+ return a || b || c || d || e || f;
+}
+
+
+void V4LRadio::noticeConnectedI (ISoundStreamServer *s, bool pointer_valid)
+{
+ ISoundStreamClient::noticeConnectedI(s, pointer_valid);
+ if (s && pointer_valid) {
+ m_seekHelper->connectI(s);
+
+ s->register4_queryPlaybackVolume(this);
+ s->register4_sendTreble(this);
+ s->register4_sendBass(this);
+ s->register4_sendBalance(this);
+ s->register4_sendMute(this);
+ s->register4_sendUnmute(this);
+ s->register4_sendSignalMinQuality(this);
+ s->register4_sendStereo(this);
+
+ s->register4_queryTreble(this);
+ s->register4_queryBass(this);
+ s->register4_queryBalance(this);
+ s->register4_querySignalQuality(this);
+ s->register4_querySignalMinQuality(this);
+ s->register4_queryHasGoodQuality(this);
+ s->register4_queryIsStereo(this);
+ s->register4_queryIsMuted(this);
+
+
+ s->register4_sendPlaybackVolume(this);
+ s->register4_sendCaptureVolume(this);
+
+ s->register4_sendStopCapture(this);
+
+ s->register4_querySoundStreamDescription(this);
+ s->register4_querySoundStreamRadioStation(this);
+ s->register4_queryEnumerateSoundStreams(this);
+
+ notifySoundStreamCreated(m_SoundStreamID);
+ }
+}
+
+void V4LRadio::noticeConnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid)
+{
+ if (i && pointer_valid && i->getSoundStreamClientID() == m_PlaybackMixerID) {
+ setPlaybackMixer(m_PlaybackMixerID, m_PlaybackMixerChannel);
+ }
+ if (i && pointer_valid && i->getSoundStreamClientID() == m_CaptureMixerID) {
+ setCaptureMixer(m_CaptureMixerID, m_CaptureMixerChannel);
+ }
+}
+
+// IRadioDevice methods
+
+bool V4LRadio::setPower (bool on)
+{
+ return on ? powerOn() : powerOff();
+}
+
+void V4LRadio::searchMixers(ISoundStreamClient **playback_mixer, ISoundStreamClient **capture_mixer)
+{
+ if (playback_mixer) {
+ *playback_mixer = getSoundStreamClientWithID(m_PlaybackMixerID);
+ if (!*playback_mixer) {
+ QPtrList<ISoundStreamClient> playback_mixers = queryPlaybackMixers();
+ if (!playback_mixers.isEmpty())
+ *playback_mixer = playback_mixers.first();
+ }
+ }
+ if (capture_mixer) {
+ *capture_mixer = getSoundStreamClientWithID(m_CaptureMixerID);
+ if (!*capture_mixer) {
+ QPtrList<ISoundStreamClient> capture_mixers = queryCaptureMixers();
+ if (!capture_mixers.isEmpty())
+ *capture_mixer = capture_mixers.first();
+ }
+ }
+}
+
+
+bool V4LRadio::powerOn ()
+{
+ if (isPowerOn())
+ return true;
+
+ radio_init();
+
+ if (isPowerOn()) {
+ ISoundStreamClient *playback_mixer = NULL,
+ *capture_mixer = NULL;
+
+ searchMixers(&playback_mixer, &capture_mixer);
+
+ if (playback_mixer)
+ playback_mixer->preparePlayback(m_SoundStreamID, m_PlaybackMixerChannel, m_ActivePlayback, false);
+ if (capture_mixer)
+ capture_mixer->prepareCapture(m_SoundStreamID, m_CaptureMixerChannel);
+
+ sendStartPlayback(m_SoundStreamID);
+ float tmp_vol = 0;
+ queryPlaybackVolume(m_SoundStreamID, tmp_vol);
+ if (tmp_vol < 0.005)
+ sendPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume);
+
+ if (m_ActivePlayback) {
+ SoundFormat sf;
+ sendStartCaptureWithFormat(m_SoundStreamID, sf, sf);
+ }
+
+ unmute(m_SoundStreamID);
+ notifyPowerChanged(true);
+ }
+
+ return true;
+}
+
+
+bool V4LRadio::powerOff ()
+{
+ if (! isPowerOn())
+ return true;
+
+ queryPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume);
+ if (m_MuteOnPowerOff)
+ sendMute(m_SoundStreamID, true);
+ if (m_VolumeZeroOnPowerOff)
+ sendPlaybackVolume(m_SoundStreamID, 0.0);
+ mute(m_SoundStreamID);
+ radio_done();
+
+ sendStopPlayback(m_SoundStreamID);
+ sendStopCapture(m_SoundStreamID);
+ closeSoundStream(m_SoundStreamID);
+ m_SoundStreamID = createNewSoundStream(m_SoundStreamID, false);
+ notifySoundStreamCreated(m_SoundStreamID);
+
+ if (isPowerOff()) {
+ notifyPowerChanged(false);
+ }
+
+ return true;
+}
+
+
+bool V4LRadio::activateStation(const RadioStation &rs)
+{
+ const FrequencyRadioStation *frs = dynamic_cast<const FrequencyRadioStation*>(&rs);
+ if (frs == NULL)
+ return false;
+
+ if (setFrequency(frs->frequency())) {
+ m_currentStation = *frs;
+
+ if (frs->initialVolume() > 0)
+ setPlaybackVolume(m_SoundStreamID, frs->initialVolume());
+
+ return true;
+ }
+
+ return false;
+}
+
+
+
+bool V4LRadio::isPowerOn() const
+{
+ return m_radio_fd >= 0;
+}
+
+
+bool V4LRadio::isPowerOff() const
+{
+ return m_radio_fd < 0;
+}
+
+
+SoundStreamID V4LRadio::getSoundStreamID() const
+{
+ return m_SoundStreamID;
+}
+
+
+const RadioStation &V4LRadio::getCurrentStation() const
+{
+ return m_currentStation;
+}
+
+
+const QString &V4LRadio::getDescription() const
+{
+ return m_caps.description;
+}
+
+
+SoundStreamID V4LRadio::getCurrentSoundStreamID() const
+{
+ return m_SoundStreamID;
+}
+
+
+
+
+bool V4LRadio::setTreble (SoundStreamID id, float t)
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ if (t > 1.0) t = 1.0;
+ if (t < 0) t = 0.0;
+ if ((int)rint(m_treble*65535) != (int)rint(t*65535)) {
+ m_treble = t;
+ writeAudioInfo();
+ notifyTrebleChanged(id, t);
+ }
+ return true;
+}
+
+
+bool V4LRadio::setBass (SoundStreamID id, float b)
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ if (b > 1.0) b = 1.0;
+ if (b < 0) b = 0.0;
+ if ((int)rint(m_bass*65535) != (int)rint(b*65535)) {
+ m_bass = b;
+ writeAudioInfo();
+ notifyBassChanged(id, b);
+ }
+
+ return true;
+}
+
+
+bool V4LRadio::setBalance (SoundStreamID id, float b)
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ if (b > +1.0) b = +1.0;
+ if (b < -1.0) b = -1.0;
+ if ((int)rint(m_balance*32767) != (int)rint(b*32767)) {
+ m_balance = b;
+ writeAudioInfo();
+ notifyBalanceChanged(id, b);
+ }
+ return true;
+}
+
+
+bool V4LRadio::setDeviceVolume (float v)
+{
+ if (v > 1.0) v = 1.0;
+ if (v < 0) v = 0;
+ if ((int)rint(m_deviceVolume*65535) != (int)rint(v*65535)) {
+ m_deviceVolume = v;
+ writeAudioInfo();
+ notifyDeviceVolumeChanged(v);
+ }
+ return true;
+}
+
+
+bool V4LRadio::mute (SoundStreamID id, bool mute)
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ if (m_muted != mute) {
+ m_muted = mute;
+ bool r = writeAudioInfo();
+ if (r)
+ notifyMuted(id, m_muted);
+ return r;
+ }
+ return false;
+}
+
+
+bool V4LRadio::unmute (SoundStreamID id, bool unmute)
+{
+ return mute(id, !unmute);
+}
+
+
+bool V4LRadio::setSignalMinQuality (SoundStreamID id, float mq)
+{
+ if (id != m_SoundStreamID)
+ return false;
+ if (rint(mq*100) == rint(m_minQuality*100))
+ return true;
+
+ m_minQuality = mq;
+ notifySignalMinQualityChanged(id, m_minQuality);
+ return true;
+}
+
+
+bool V4LRadio::setStereo(SoundStreamID /*id*/, bool /*b*/)
+{
+ // FIXME if possible
+ return false; // we can't do that currently, not even switch stereo to mono
+}
+
+
+
+
+bool V4LRadio::getTreble (SoundStreamID id, float &t) const
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ readAudioInfo();
+ t = m_treble;
+ return true;
+}
+
+
+bool V4LRadio::getBass (SoundStreamID id, float &b) const
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ readAudioInfo();
+ b = m_bass;
+ return true;
+}
+
+
+bool V4LRadio::getBalance (SoundStreamID id, float &b) const
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ readAudioInfo();
+ b = m_balance;
+ return true;
+}
+
+
+float V4LRadio::getDeviceVolume () const
+{
+ readAudioInfo();
+ return m_deviceVolume;
+}
+
+
+
+bool V4LRadio::getSignalMinQuality(SoundStreamID id, float &q) const
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ q = m_minQuality;
+ return true;
+}
+
+
+bool V4LRadio::getSignalQuality(SoundStreamID id, float &q) const
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ readTunerInfo();
+ q = m_signalQuality;
+ return true;
+}
+
+
+bool V4LRadio::hasGoodQuality(SoundStreamID id, bool &good) const
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ float q = 0;
+ if (getSignalQuality(id, q))
+ good = q >= m_minQuality;
+ return true;
+}
+
+
+bool V4LRadio::isStereo(SoundStreamID id, bool &s) const
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ readAudioInfo();
+ s = m_stereo;
+ return true;
+}
+
+
+bool V4LRadio::isMuted(SoundStreamID id, bool &m) const
+{
+ if (id != m_SoundStreamID)
+ return false;
+
+ readAudioInfo();
+ m = m_muted;
+ return true;
+}
+
+
+// ISeekRadio
+
+bool V4LRadio::toBeginning()
+{
+ setFrequency(getMinFrequency());
+ return true;
+}
+
+bool V4LRadio::toEnd()
+{
+ setFrequency(getMaxFrequency());
+ return true;
+}
+
+bool V4LRadio::startSeekUp()
+{
+ return startSeek(true);
+}
+
+bool V4LRadio::startSeekDown()
+{
+ return startSeek(false);
+}
+
+bool V4LRadio::startSeek(bool up)
+{
+ if (isPowerOn() && m_seekHelper) {
+ m_seekHelper->start(m_SoundStreamID, up ? SeekHelper::up : SeekHelper::down);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool V4LRadio::stopSeek()
+{
+ if (m_seekHelper) m_seekHelper->stop();
+ return true;
+}
+
+bool V4LRadio::isSeekRunning() const
+{
+ if (m_seekHelper)
+ return m_seekHelper->isRunning();
+ else
+ return false;
+}
+
+
+bool V4LRadio::isSeekUpRunning() const
+{
+ if (m_seekHelper)
+ return m_seekHelper->isRunningUp();
+ else
+ return false;
+}
+
+
+bool V4LRadio::isSeekDownRunning() const
+{
+ if (m_seekHelper)
+ return m_seekHelper->isRunningDown();
+ else
+ return false;
+}
+
+float V4LRadio::getProgress () const
+{
+ float min = getMinFrequency();
+ float max = getMaxFrequency();
+
+ return (getFrequency() - min) / (max - min);
+}
+
+
+// IFrequencyRadio
+
+bool V4LRadio::setFrequency(float freq)
+{
+// if (isSeekRunning())
+// stopSeek();
+
+ if (m_currentStation.frequency() == freq) {
+ return true;
+ }
+
+ float minf = getMinFrequency();
+ float maxf = getMaxFrequency();
+
+ if (isPowerOn()) {
+
+ bool oldMute = false;
+ isMuted(m_SoundStreamID, oldMute);
+ if (!oldMute && !m_ActivePlayback)
+ mute(m_SoundStreamID);
+
+
+ if (!m_tunercache.valid) readTunerInfo();
+ float df = m_tunercache.deltaF;
+
+ unsigned long lfreq = (unsigned long) rint(freq / df);
+
+ if (freq > maxf || freq < minf) {
+ logError("V4LRadio::setFrequency: " +
+ i18n("invalid frequency %1").arg(QString().setNum(freq)));
+ if (!oldMute && !m_ActivePlayback)
+ unmute(m_SoundStreamID);
+ return false;
+ }
+
+ int r = -1;
+ if (m_caps.version == 1) {
+ r = ioctl(m_radio_fd, VIDIOCSFREQ, &lfreq);
+ }
+#ifdef HAVE_V4L2
+ else if (m_caps.version == 2) {
+ v4l2_frequency tmp;
+ tmp.tuner = 0;
+ tmp.type = V4L2_TUNER_RADIO;
+ tmp.frequency = lfreq;
+ r = ioctl(m_radio_fd, VIDIOC_S_FREQUENCY, &tmp);
+ }
+#endif
+ else {
+ logError("V4LRadio::setFrequency: " +
+ i18n("don't known how to handle V4L-version %1")
+ .arg(m_caps.version));
+ }
+
+ if (r) {
+ logError("V4LRadio::setFrequency: " +
+ i18n("error setting frequency to %1 (%2)")
+ .arg(QString().setNum(freq))
+ .arg(QString().setNum(r)));
+ // unmute the old radio with the old radio station
+ if (!oldMute && !m_ActivePlayback)
+ unmute(m_SoundStreamID);
+ return false;
+ }
+
+ // unmute this radio device, because we now have the current
+ // radio station
+ if (!oldMute && !m_ActivePlayback)
+ unmute(m_SoundStreamID);
+ }
+
+ m_currentStation.setFrequency(freq);
+ notifyFrequencyChanged(freq, &m_currentStation);
+ notifyStationChanged(m_currentStation);
+ notifyProgress((freq - minf) / (maxf - minf));
+ notifySoundStreamChanged(m_SoundStreamID);
+ return true;
+}
+
+
+bool V4LRadio::setMinFrequency (float minF)
+{
+ float oldm = getMinFrequency();
+ m_minFrequency = minF;
+
+ float newm = getMinFrequency();
+ if (oldm != newm)
+ notifyMinMaxFrequencyChanged(newm, getMaxFrequency());
+
+ return true;
+}
+
+
+bool V4LRadio::setMaxFrequency (float maxF)
+{
+ float oldm = getMaxFrequency();
+ m_maxFrequency = maxF;
+
+ float newm = getMaxFrequency();
+ if (oldm != newm)
+ notifyMinMaxFrequencyChanged(getMinFrequency(), newm);
+
+ return true;
+}
+
+
+bool V4LRadio::setScanStep(float s)
+{
+ float old = m_scanStep;
+ m_scanStep = s;
+
+ if (old != s) notifyScanStepChanged(m_scanStep);
+ return true;
+}
+
+
+float V4LRadio::getFrequency() const
+{
+ return m_currentStation.frequency();
+}
+
+
+float V4LRadio::getMinFrequency() const
+{
+ return m_minFrequency ? m_minFrequency : getMinDeviceFrequency();
+}
+
+
+float V4LRadio::getMaxFrequency() const
+{
+ return m_maxFrequency ? m_maxFrequency : getMaxDeviceFrequency();
+}
+
+
+float V4LRadio::getMinDeviceFrequency() const
+{
+ if (!m_tunercache.valid)
+ readTunerInfo();
+
+ return m_tunercache.minF;
+}
+
+
+float V4LRadio::getMaxDeviceFrequency() const
+{
+ if (!m_tunercache.valid)
+ readTunerInfo();
+
+ return m_tunercache.maxF;
+}
+
+
+float V4LRadio::getScanStep() const
+{
+ return m_scanStep;
+}
+
+
+
+// IV4LCfg methods
+
+bool V4LRadio::setRadioDevice(const QString &s)
+{
+ if (m_radioDev != s) {
+ bool p = isPowerOn();
+ powerOff();
+ m_radioDev = s;
+
+ m_caps = readV4LCaps(m_radioDev);
+ notifyRadioDeviceChanged(m_radioDev);
+ notifyDescriptionChanged(m_caps.description);
+ notifyCapabilitiesChanged(m_caps);
+ setPower(p);
+ }
+ return true;
+}
+
+
+bool V4LRadio::setPlaybackMixer(const QString &soundStreamClientID, const QString &ch)
+{
+ bool change = m_PlaybackMixerID != soundStreamClientID || m_PlaybackMixerChannel != ch;
+ m_PlaybackMixerID = soundStreamClientID;
+ m_PlaybackMixerChannel = ch;
+
+
+ if (isPowerOn()) {
+ queryPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume);
+ sendStopPlayback(m_SoundStreamID);
+ sendReleasePlayback(m_SoundStreamID);
+ }
+
+ ISoundStreamClient *playback_mixer = NULL;
+ searchMixers(&playback_mixer, NULL);
+ if (playback_mixer)
+ playback_mixer->preparePlayback(m_SoundStreamID, m_PlaybackMixerChannel, m_ActivePlayback, false);
+
+ if (isPowerOn()) {
+ sendStartPlayback(m_SoundStreamID);
+ sendPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume);
+ if (m_ActivePlayback) {
+ SoundFormat sf;
+ sendStartCaptureWithFormat(m_SoundStreamID, sf, sf);
+ }
+ }
+
+ if (change)
+ notifyPlaybackMixerChanged(soundStreamClientID, ch);
+
+ return true;
+}
+
+
+bool V4LRadio::setCaptureMixer(const QString &soundStreamClientID, const QString &ch)
+{
+ bool change = m_PlaybackMixerID != soundStreamClientID || m_PlaybackMixerChannel != ch;
+ m_CaptureMixerID = soundStreamClientID;
+ m_CaptureMixerChannel = ch;
+
+ bool r = false;
+ SoundFormat sf;
+ queryIsCaptureRunning(m_SoundStreamID, r, sf);
+
+ float v = 0;
+ if (isPowerOn() && r) {
+ queryCaptureVolume(m_SoundStreamID, v);
+ sendStopCapture(m_SoundStreamID);
+ sendReleaseCapture(m_SoundStreamID);
+ }
+
+ ISoundStreamClient *capture_mixer = NULL;
+ searchMixers(NULL, &capture_mixer);
+ if (capture_mixer)
+ capture_mixer->prepareCapture(m_SoundStreamID, m_CaptureMixerChannel);
+
+ if (isPowerOn() && r) {
+ sendStartCaptureWithFormat(m_SoundStreamID, sf, sf);
+ sendCaptureVolume(m_SoundStreamID, v);
+ }
+
+ if (change)
+ notifyCaptureMixerChanged(soundStreamClientID, ch);
+
+ return true;
+}
+
+
+V4LCaps V4LRadio::getCapabilities(QString dev) const
+{
+ if (dev.isNull()) {
+ return m_caps;
+ } else {
+ return readV4LCaps(dev);
+ }
+}
+
+
+bool V4LRadio::setActivePlayback(bool a)
+{
+ if (a == m_ActivePlayback)
+ return true;
+
+
+ if (isPowerOn()) {
+ queryPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume);
+ sendStopPlayback(m_SoundStreamID);
+ sendReleasePlayback(m_SoundStreamID);
+ if (m_ActivePlayback) {
+ sendStopCapture(m_SoundStreamID);
+ }
+ }
+
+ m_ActivePlayback = a;
+
+ ISoundStreamClient *playback_mixer = NULL;
+ searchMixers(&playback_mixer, NULL);
+ if (playback_mixer)
+ playback_mixer->preparePlayback(m_SoundStreamID, m_PlaybackMixerChannel, m_ActivePlayback, false);
+
+ if (isPowerOn()) {
+ sendStartPlayback(m_SoundStreamID);
+ sendPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume);
+ if (m_ActivePlayback) {
+ SoundFormat sf;
+ sendStartCaptureWithFormat(m_SoundStreamID, sf, sf);
+ }
+ }
+
+ // FIXME: restart playback/capture
+ notifyActivePlaybackChanged(m_ActivePlayback);
+
+ return true;
+}
+
+bool V4LRadio::setMuteOnPowerOff(bool a)
+{
+ if (a != m_MuteOnPowerOff) {
+ m_MuteOnPowerOff = a;
+ notifyMuteOnPowerOffChanged(m_MuteOnPowerOff);
+ }
+ return true;
+}
+
+bool V4LRadio::setVolumeZeroOnPowerOff(bool a)
+{
+ if (a != m_VolumeZeroOnPowerOff) {
+ m_VolumeZeroOnPowerOff = a;
+ notifyVolumeZeroOnPowerOffChanged(m_VolumeZeroOnPowerOff);
+ }
+ return true;
+}
+
+// PluginBase methods
+
+void V4LRadio::saveState (KConfig *config) const
+{
+ config->setGroup(QString("v4lradio-") + name());
+
+ config->writeEntry("RadioDev", m_radioDev);
+
+ config->writeEntry("PlaybackMixerID", m_PlaybackMixerID);
+ config->writeEntry("PlaybackMixerChannel", m_PlaybackMixerChannel);
+ config->writeEntry("CaptureMixerID", m_CaptureMixerID);
+ config->writeEntry("CaptureMixerChannel", m_CaptureMixerChannel);
+
+ config->writeEntry("fMinOverride", m_minFrequency);
+ config->writeEntry("fMaxOverride", m_maxFrequency);
+ config->writeEntry("fLastDevMin", m_lastMinDevFrequency);
+ config->writeEntry("fLastDevMax", m_lastMaxDevFrequency);
+
+ config->writeEntry("defaultPlaybackVolume", m_defaultPlaybackVolume);
+
+ config->writeEntry("signalMinQuality", m_minQuality);
+
+ config->writeEntry("scanStep", m_scanStep);
+
+ config->writeEntry("Frequency", m_currentStation.frequency());
+ config->writeEntry("Treble", m_treble);
+ config->writeEntry("Bass", m_bass);
+ config->writeEntry("Balance", m_balance);
+ config->writeEntry("DeviceVolume", m_deviceVolume);
+
+ config->writeEntry("PowerOn", isPowerOn());
+ config->writeEntry("UseOldV4L2Calls", m_useOldV4L2Calls);
+
+ config->writeEntry("ActivePlayback", m_ActivePlayback);
+ config->writeEntry("MuteOnPowerOff", m_MuteOnPowerOff);
+ config->writeEntry("VolumeZeroOnPowerOff", m_VolumeZeroOnPowerOff);
+}
+
+
+void V4LRadio::restoreState (KConfig *config)
+{
+ BlockProfiler p("V4LRadio::restoreState");
+
+ config->setGroup(QString("v4lradio-") + name());
+
+ QString base_devname = "/dev/radio";
+
+ QStringList testlist (base_devname );
+ for (int i = 0; i < 9; ++i)
+ testlist.append(base_devname + QString::number(i));
+
+ QString found_devname(QString::null);
+ for (QValueListConstIterator<QString> it = testlist.begin(); it != testlist.end(); ++it) {
+ QFile f(*it);
+ if (f.exists()) {
+ QFileInfo info(f);
+ if (info.isReadable() && info.isWritable()) {
+ found_devname = *it;
+ break;
+ }
+ else {
+ if (found_devname.isNull())
+ found_devname = *it;
+ logWarning(i18n("Device %1 does exist but is not readable/writable. Please check device permissions.").arg(*it));
+ }
+ }
+ }
+
+ QString default_devname = found_devname.isNull() ? base_devname : found_devname;
+
+ QString devname = config->readEntry ("RadioDev", default_devname);
+
+ if (found_devname.isNull() && devname == default_devname) {
+ logError(i18n("Could not find an accessible v4l(2) radio device."));
+ }
+
+ setRadioDevice(devname);
+
+ QString PlaybackMixerID = config->readEntry ("PlaybackMixerID", QString::null);
+ QString PlaybackMixerChannel = config->readEntry ("PlaybackMixerChannel", "Line");
+
+ QString CaptureMixerID = config->readEntry ("CaptureMixerID", QString::null);
+ QString CaptureMixerChannel = config->readEntry ("CaptureMixerChannel", "Line");
+
+ m_ActivePlayback = config->readBoolEntry("ActivePlayback", false);
+ m_MuteOnPowerOff = config->readBoolEntry("MuteOnPowerOff", false);
+ m_VolumeZeroOnPowerOff = config->readBoolEntry("VolumeZeroOnPowerOff", false);
+
+ m_lastMinDevFrequency = config->readDoubleNumEntry ("fLastDevMin", 65.0);
+ m_lastMaxDevFrequency = config->readDoubleNumEntry ("fLastDevMax", 108.0);
+ m_minFrequency = config->readDoubleNumEntry ("fMinOverride", m_lastMinDevFrequency);
+ m_maxFrequency = config->readDoubleNumEntry ("fMaxOverride", m_lastMaxDevFrequency);
+
+ m_minQuality = config->readDoubleNumEntry ("signalMinQuality", 0.75);
+ m_scanStep = config->readDoubleNumEntry ("scanStep", 0.05);
+ m_defaultPlaybackVolume = config->readDoubleNumEntry ("defaultPlaybackVolume", 0.5);
+
+ setPlaybackMixer(PlaybackMixerID, PlaybackMixerChannel);
+ setCaptureMixer (CaptureMixerID, CaptureMixerChannel);
+ notifyDeviceMinMaxFrequencyChanged(m_lastMinDevFrequency, m_lastMaxDevFrequency);
+ notifyMinMaxFrequencyChanged(m_minFrequency, m_maxFrequency);
+ notifySignalMinQualityChanged(m_SoundStreamID, m_minQuality);
+ notifyScanStepChanged(m_scanStep);
+ notifyActivePlaybackChanged(m_ActivePlayback);
+ notifyMuteOnPowerOffChanged(m_MuteOnPowerOff);
+ notifyVolumeZeroOnPowerOffChanged(m_VolumeZeroOnPowerOff);
+
+ BlockProfiler p2("V4LRadio::restoreState2");
+
+ setFrequency(config->readDoubleNumEntry("Frequency", 88));
+ m_restorePowerOn = config->readBoolEntry ("PowerOn", false);
+
+ BlockProfiler p3("V4LRadio::restoreState3");
+
+ setTreble (m_SoundStreamID, config->readDoubleNumEntry("Treble", 0.5));
+ setBass (m_SoundStreamID, config->readDoubleNumEntry("Bass", 0.5));
+ setBalance (m_SoundStreamID, config->readDoubleNumEntry("Balance", 0.0));
+ setDeviceVolume( config->readDoubleNumEntry("DeviceVolume", 0.9));
+
+ m_useOldV4L2Calls = config->readBoolEntry("UseOldV4L2Calls", true);
+
+ if (isPowerOff())
+ notifyPlaybackVolumeChanged(m_SoundStreamID, m_defaultPlaybackVolume);
+}
+
+void V4LRadio::startPlugin()
+{
+ PluginBase::startPlugin();
+ setPower(m_restorePowerOn);
+}
+
+ConfigPageInfo V4LRadio::createConfigurationPage()
+{
+ V4LRadioConfiguration *v4lconf = new V4LRadioConfiguration(NULL, m_SoundStreamID);
+ connectI(v4lconf);
+ return ConfigPageInfo (v4lconf,
+ i18n("V4L Radio"),
+ i18n("V4L Radio Options"),
+ "package_utilities");
+}
+
+
+AboutPageInfo V4LRadio::createAboutPage()
+{
+ KAboutData aboutData("kradio",
+ NULL,
+ NULL,
+ I18N_NOOP("V4L/V4L2 Plugin for KRadio."
+ "<P>"
+ "Provides Support for V4L/V4L2 based Radio Cards"
+ "<P>"),
+ 0,
+ //KAboutData::License_GPL,
+ "(c) 2002-2005 Martin Witte, Klas Kalass",
+ 0,
+ "http://sourceforge.net/projects/kradio",
+ 0);
+ aboutData.addAuthor("Martin Witte", "", "witte@kawo1.rwth-aachen.de");
+ aboutData.addAuthor("Klas Kalass", "", "klas.kalass@gmx.de");
+
+ return AboutPageInfo(
+ new KRadioAboutWidget(aboutData, KRadioAboutWidget::AbtTabbed),
+ i18n("V4L/V4L2"),
+ i18n("V4L/V4L2 Plugin"),
+ "package_utilities"
+ );
+}
+
+////////////////////////////////////////
+// anything else
+
+void V4LRadio::radio_init()
+{
+ if (isSeekRunning())
+ stopSeek();
+
+ m_caps = readV4LCaps(m_radioDev);
+ notifyCapabilitiesChanged(m_caps);
+ notifyDescriptionChanged(m_caps.description);
+
+/* m_mixer_fd = open(m_mixerDev, O_RDONLY);
+ if (m_mixer_fd < 0) {
+ radio_done();
+
+ logError("V4LRadio::radio_init: " +
+ i18n("Cannot open mixer device %1").arg(m_mixerDev));
+ return;
+ }
+*/
+ m_radio_fd = open(m_radioDev.ascii(), O_RDONLY);
+ if (m_radio_fd < 0) {
+ radio_done();
+
+ logError("V4LRadio::radio_init: " +
+ i18n("Cannot open radio device %1").arg(m_radioDev));
+ return;
+ }
+
+ readTunerInfo();
+ writeAudioInfo(); // set tuner-audio config as used last time
+ readAudioInfo(); // reread tuner-audio and read-only flags (e.g. stereo)
+
+ // restore frequency
+ float old = getFrequency();
+ m_currentStation.setFrequency(0);
+ setFrequency(old);
+
+ // read volume level from mixer
+ // FIXME: do we still need this
+/* float v = 0;
+ getVolume(m_SoundStreamID, v)
+ setVolume (m_SoundStreamID, v);*/
+}
+
+
+void V4LRadio::radio_done()
+{
+ if (isSeekRunning())
+ stopSeek();
+
+ if (m_radio_fd >= 0) close (m_radio_fd);
+// if (m_mixer_fd >= 0) close (m_mixer_fd);
+
+ m_radio_fd = -1;
+// m_mixer_fd = -1;
+}
+
+
+
+
+
+#define CAPS_NAME_LEN 127
+V4LCaps V4LRadio::readV4LCaps(const QString &device) const
+{
+ char buffer[CAPS_NAME_LEN+1];
+ int r;
+ int fd;
+
+ V4LCaps c;
+ c.description = device;
+
+ fd = open(device.ascii(), O_RDONLY);
+
+ if (fd < 0) {
+ logError("V4LRadio::readV4LCaps: " +
+ i18n("cannot open %1").arg(device));
+ return c;
+ }
+
+ video_capability caps;
+ r = ioctl(fd, VIDIOCGCAP, &caps);
+ if (r == 0) {
+ c.version = 1;
+
+ size_t l = sizeof(caps.name);
+ l = l < CAPS_NAME_LEN ? l : CAPS_NAME_LEN;
+ memcpy(buffer, caps.name, l);
+ buffer[l] = 0;
+ c.description = buffer;
+
+ c.hasMute = false;
+ c.unsetVolume();
+ c.unsetTreble();
+ c.unsetBass();
+ c.unsetBalance();
+
+ video_audio audiocaps;
+ if (0 == ioctl(fd, VIDIOCGAUDIO, &audiocaps)) {
+ logDebug("V4LRadio::readV4LCaps: " +
+ i18n("audio caps = %1").arg(QString().setNum(audiocaps.flags)));
+ if ((audiocaps.flags & VIDEO_AUDIO_MUTABLE) != 0)
+ c.hasMute = true;
+ if ((audiocaps.flags & VIDEO_AUDIO_VOLUME) != 0)
+ c.setVolume (0, 65535);
+ if ((audiocaps.flags & VIDEO_AUDIO_TREBLE) != 0)
+ c.setTreble (0, 65535);
+ if ((audiocaps.flags & VIDEO_AUDIO_BASS) != 0)
+ c.setBass (0, 65535);
+ // at least my driver has support for balance, but the bit is not set ...
+ c.setBalance(0, 65535);
+ }
+ } else {
+ logError("V4LRadio::readV4LCaps: " +
+ i18n("error reading V4L1 caps"));
+ }
+
+#ifdef HAVE_V4L2
+ v4l2_capability caps2;
+ r = ioctl(fd, VIDIOC_QUERYCAP, &caps2);
+ if (r == 0) {
+ c.version = 2;
+
+ logDebug(i18n("V4L2 - Version: %1").arg(QString().sprintf("%08X", caps2.version)));
+
+ size_t l = sizeof(caps.name);
+ l = l < CAPS_NAME_LEN ? l : CAPS_NAME_LEN;
+ memcpy(buffer, caps.name, l);
+ buffer[l] = 0;
+ // c.description = buffer;
+
+ v4l2_queryctrl ctrl;
+
+ c.hasMute = false;
+ c.unsetVolume();
+ c.unsetTreble();
+ c.unsetBass();
+ c.unsetBalance();
+
+ ctrl.id = V4L2_CID_AUDIO_MUTE;
+ if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl))
+ c.hasMute = !(ctrl.flags & V4L2_CTRL_FLAG_DISABLED);
+ else
+ logError(i18n("V4L2: Querying mute control failed"));
+
+ ctrl.id = V4L2_CID_AUDIO_VOLUME;
+ if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl)) {
+ if (!(ctrl.flags & V4L2_CTRL_FLAG_DISABLED))
+ c.setVolume(ctrl.minimum, ctrl.maximum);
+ } else {
+ logError(i18n("V4L2: Querying volume control failed"));
+ }
+
+ ctrl.id = V4L2_CID_AUDIO_TREBLE;
+ if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl)) {
+ if (!(ctrl.flags & V4L2_CTRL_FLAG_DISABLED))
+ c.setTreble(ctrl.minimum, ctrl.maximum);
+ } else {
+ logError(i18n("V4L2: Querying treble control failed"));
+ }
+
+ ctrl.id = V4L2_CID_AUDIO_BASS;
+ if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl)) {
+ if (!(ctrl.flags & V4L2_CTRL_FLAG_DISABLED))
+ c.setBass(ctrl.minimum, c.maxBass = ctrl.maximum);
+ } else {
+ logError(i18n("V4L2: Querying bass control failed"));
+ }
+
+ ctrl.id = V4L2_CID_AUDIO_BALANCE;
+ if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl)) {
+ if (!(ctrl.flags & V4L2_CTRL_FLAG_DISABLED))
+ c.setBalance(ctrl.minimum, ctrl.maximum);
+ } else {
+ logError(i18n("V4L2: Querying balance control failed"));
+ }
+
+ } else {
+ logWarning(i18n("V4LRadio::readV4LCaps: Reading V4L2 caps failed"));
+ }
+#endif
+ if (c.version > 0) {
+ logInfo(i18n("V4L %1 detected").arg(c.version));
+ } else {
+ logError(i18n("V4L not detected"));
+ }
+
+ logInfo(c.hasMute ? i18n("Radio is mutable") : i18n("Radio is not mutable"));
+ logInfo(c.hasVolume ? i18n("Radio has Volume Control") : i18n("Radio has no Volume Control"));
+ logInfo(c.hasBass ? i18n("Radio has Bass Control") : i18n("Radio has no Bass Control"));
+ logInfo(c.hasTreble ? i18n("Radio has Treble Control") : i18n("Radio has no Treble Control"));
+
+ close(fd);
+ return c;
+}
+
+
+bool V4LRadio::readTunerInfo() const
+{
+ if (m_blockReadTuner) return true;
+
+ float oldq = m_signalQuality;
+ float oldminf = m_tunercache.minF;
+ float oldmaxf = m_tunercache.maxF;
+
+ if (!m_tunercache.valid) {
+ m_tunercache.minF = m_lastMinDevFrequency;
+ m_tunercache.maxF = m_lastMaxDevFrequency;
+ m_tunercache.deltaF = 1.0/16.0;
+ m_tunercache.valid = true;
+ }
+
+ int r = 0;
+ if (isPowerOn()) {
+
+ // v4l1
+ if (m_caps.version == 1) {
+
+ r = ioctl(m_radio_fd, VIDIOCGTUNER, m_tuner);
+
+ if (r == 0) {
+ if ((m_tuner->flags & VIDEO_TUNER_LOW) != 0)
+ m_tunercache.deltaF = 1.0 / 16000.0;
+ m_tunercache.minF = float(m_tuner->rangelow) * m_tunercache.deltaF;
+ m_tunercache.maxF = float(m_tuner->rangehigh) * m_tunercache.deltaF;
+ m_tunercache.valid = true;
+ m_signalQuality = float(m_tuner->signal) / 32767.0;
+
+ }
+ }
+#ifdef HAVE_V4L2
+ // v4l2
+ else if (m_caps.version == 2) {
+
+ r = ioctl(m_radio_fd, VIDIOC_G_TUNER, m_tuner2);
+
+ if (r == 0) {
+ if ((m_tuner2->capability & V4L2_TUNER_CAP_LOW) != 0)
+ m_tunercache.deltaF = 1.0 / 16000.0;
+ m_tunercache.minF = float(m_tuner2->rangelow) * m_tunercache.deltaF;
+ m_tunercache.maxF = float(m_tuner2->rangehigh) * m_tunercache.deltaF;
+ m_tunercache.valid = true;
+ m_signalQuality = float(m_tuner2->signal) / 32767.0;
+ }
+ }
+#endif
+ else {
+ logError("V4LRadio::readTunerInfo: " +
+ i18n("don't known how to handle V4L-version %1")
+ .arg(QString().setNum(m_caps.version)));
+ }
+
+ if (r != 0) {
+ m_signalQuality = 0;
+ logError("V4LRadio::readTunerInfo: " +
+ i18n("cannot get tuner info (error %1)").arg(QString().setNum(r)));
+ }
+ } else {
+ m_signalQuality = 0;
+ }
+
+ // prevent loops, if noticeXYZ-method is reading my state
+ m_blockReadTuner = true;
+
+ if (oldminf != m_tunercache.minF || oldmaxf != m_tunercache.maxF)
+ notifyDeviceMinMaxFrequencyChanged(m_tunercache.minF, m_tunercache.maxF);
+ m_lastMinDevFrequency = m_tunercache.minF;
+ m_lastMaxDevFrequency = m_tunercache.maxF;
+
+ if ( ! m_minFrequency && (oldminf != m_tunercache.minF)
+ || ! m_maxFrequency && (oldmaxf != m_tunercache.maxF))
+ notifyMinMaxFrequencyChanged(getMinFrequency(), getMaxFrequency());
+
+
+ if (m_signalQuality != oldq)
+ notifySignalQualityChanged(m_SoundStreamID, m_signalQuality);
+ if ( (m_signalQuality >= m_minQuality) != (oldq >= m_minQuality))
+ notifySignalQualityBoolChanged(m_SoundStreamID, m_signalQuality > m_minQuality);
+
+ m_blockReadTuner = false;
+
+ return true;
+}
+
+
+
+#define V4L2_S_CTRL(what,val) \
+ { ctl.value = (val); \
+ ctl.id = (what); \
+ /* Problem: Current V4L2 development has changed the IOCTL-IDs for VIDIOC_S_CTRL */ \
+ /* => we must du "try and error" to figure out what version we should use */ \
+ r = ioctl (m_radio_fd, m_useOldV4L2Calls ? VIDIOC_S_CTRL_OLD : VIDIOC_S_CTRL, &ctl); \
+ /* in case this did not work, try the other version of the call */ \
+ if (r) { \
+ r = ioctl (m_radio_fd, !m_useOldV4L2Calls ? VIDIOC_S_CTRL_OLD : VIDIOC_S_CTRL, &ctl); \
+ if (!r) m_useOldV4L2Calls = !m_useOldV4L2Calls; \
+ } \
+ x = x ? x : r; \
+ if (r) \
+ logError(i18n("error setting %1: %2").arg(#what).arg(QString().setNum(r))); \
+ }
+
+#define V4L2_G_CTRL(what) \
+ { ctl.id = (what); \
+ r = ioctl (m_radio_fd, VIDIOC_G_CTRL, &ctl); \
+ x = x ? x : r; \
+ if (r) \
+ logError(i18n("error reading %1: %2").arg(#what).arg(QString().setNum(r))); \
+ }
+
+
+bool V4LRadio::updateAudioInfo(bool write) const
+{
+ if (m_blockReadAudio && !write)
+ return true;
+
+ bool oldStereo = m_stereo;
+ bool oldMute = m_muted;
+ int iOldDeviceVolume = m_caps.intGetVolume (m_deviceVolume);
+ int iOldTreble = m_caps.intGetTreble (m_treble);
+ int iOldBass = m_caps.intGetBass (m_bass);
+ int iOldBalance = m_caps.intGetBalance(m_balance);
+
+ if (isPowerOn()) {
+ int r = 0;
+ if (m_caps.version == 1) {
+ m_audio->audio = 0;
+ if (m_muted) m_audio->flags |= VIDEO_AUDIO_MUTE;
+ else m_audio->flags &= ~VIDEO_AUDIO_MUTE;
+
+ m_audio->volume = m_caps.intGetVolume (m_deviceVolume);
+ m_audio->treble = m_caps.intGetTreble (m_treble);
+ m_audio->bass = m_caps.intGetBass (m_bass);
+ m_audio->balance = m_caps.intGetBalance(m_balance);
+
+ r = ioctl(m_radio_fd, write ? VIDIOCSAUDIO : VIDIOCGAUDIO, m_audio);
+
+ m_stereo = (r == 0) && ((m_audio->mode & VIDEO_SOUND_STEREO) != 0);
+
+ m_muted = m_caps.hasMute &&
+ ((r != 0) || ((m_audio->flags & VIDEO_AUDIO_MUTE) != 0));
+
+ /* Some drivers seem to set volumes to zero if they are muted.
+ Thus we do not reload them if radio is muted */
+ if (!m_muted && !write) {
+ m_deviceVolume = m_caps.hasVolume && !r ? m_caps.floatGetVolume (m_audio->volume) : 1;
+ m_treble = m_caps.hasTreble && !r ? m_caps.floatGetTreble (m_audio->treble) : 1;
+ m_bass = m_caps.hasBass && !r ? m_caps.floatGetBass (m_audio->bass) : 1;
+ m_balance = m_caps.hasBalance && !r ? m_caps.floatGetBalance(m_audio->balance) : 0;
+ }
+ }
+#ifdef HAVE_V4L2
+ else if (m_caps.version == 2) {
+ v4l2_control ctl;
+ int x = 0; // x stores first ioctl error
+ if (write) {
+ if (m_caps.hasMute)
+ V4L2_S_CTRL(V4L2_CID_AUDIO_MUTE, m_muted);
+ if (m_caps.hasTreble)
+ V4L2_S_CTRL(V4L2_CID_AUDIO_TREBLE, m_caps.intGetTreble(m_treble));
+ if (m_caps.hasBass)
+ V4L2_S_CTRL(V4L2_CID_AUDIO_BASS, m_caps.intGetBass(m_bass));
+ if (m_caps.hasBalance)
+ V4L2_S_CTRL(V4L2_CID_AUDIO_BALANCE, m_caps.intGetBalance(m_balance));
+ if (m_caps.hasVolume)
+ V4L2_S_CTRL(V4L2_CID_AUDIO_VOLUME, m_caps.intGetVolume(m_deviceVolume));
+ } else {
+ if (m_caps.hasMute)
+ V4L2_G_CTRL(V4L2_CID_AUDIO_MUTE);
+ m_muted = m_caps.hasMute && ((r != 0) || ctl.value);
+
+ /* Some drivers seem to set volumes to zero if they are muted.
+ Thus we do not reload them if radio is muted */
+ if (!m_muted) {
+ if (m_caps.hasVolume)
+ V4L2_G_CTRL(V4L2_CID_AUDIO_VOLUME);
+ m_deviceVolume = m_caps.hasVolume && !r ? m_caps.floatGetVolume (ctl.value) : 1;
+ if (m_caps.hasTreble)
+ V4L2_G_CTRL(V4L2_CID_AUDIO_TREBLE);
+ m_treble = m_caps.hasTreble && !r ? m_caps.floatGetTreble (ctl.value) : 1;
+ if (m_caps.hasBass)
+ V4L2_G_CTRL(V4L2_CID_AUDIO_BASS);
+ m_bass = m_caps.hasBass && !r ? m_caps.floatGetBass (ctl.value) : 1;
+ if (m_caps.hasBalance)
+ V4L2_G_CTRL(V4L2_CID_AUDIO_BALANCE);
+ m_balance = m_caps.hasBalance&& !r ? m_caps.floatGetBalance(ctl.value) : 0;
+ }
+
+ r = ioctl (m_radio_fd, VIDIOC_G_TUNER, m_tuner2);
+ m_stereo = (r == 0) && ((m_tuner2->rxsubchans & V4L2_TUNER_SUB_STEREO) != 0);
+ x = x ? x : r;
+ }
+ r = x; // store first error back to r, used below for error message
+ }
+#endif
+ else {
+ logError("V4LRadio::updateAudioInfo: " +
+ i18n("don't known how to handle V4L-version %1")
+ .arg(QString().setNum(m_caps.version)));
+ }
+
+ if (r) {
+ logError("V4LRadio::updateAudioInfo: " +
+ i18n("error updating radio audio info (%1): %2")
+ .arg(write ? i18n("write") : i18n("read"))
+ .arg(QString().setNum(r)));
+ return false;
+ }
+ }
+
+ // prevent loops, if noticeXYZ-method is reading my state
+ bool oldBlock = m_blockReadAudio;
+ m_blockReadAudio = true;
+
+ // send notifications
+
+ if (oldStereo != m_stereo)
+ notifyStereoChanged(m_SoundStreamID, m_stereo);
+ if (oldMute != m_muted)
+ notifyMuted(m_SoundStreamID, m_muted);
+ if (iOldDeviceVolume != m_caps.intGetVolume(m_deviceVolume))
+ notifyDeviceVolumeChanged(m_deviceVolume);
+ if (iOldTreble != m_caps.intGetTreble(m_treble))
+ notifyTrebleChanged(m_SoundStreamID, m_treble);
+ if (iOldBass != m_caps.intGetBass(m_bass))
+ notifyBassChanged(m_SoundStreamID, m_bass);
+ if (iOldBalance != m_caps.intGetBalance(m_balance))
+ notifyBalanceChanged(m_SoundStreamID, m_balance);
+
+ m_blockReadAudio = oldBlock;
+
+ return isPowerOn();
+}
+
+
+
+
+void V4LRadio::poll()
+{
+ readTunerInfo();
+ readAudioInfo();
+}
+
+
+bool V4LRadio::setPlaybackVolume(SoundStreamID id, float volume)
+{
+ if (isPowerOff() && id == m_SoundStreamID) {
+ m_defaultPlaybackVolume = min(max(volume, 0.0), 1.0);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool V4LRadio::getPlaybackVolume(SoundStreamID id, float &volume) const
+{
+ if (isPowerOff() && id == m_SoundStreamID) {
+ volume = m_defaultPlaybackVolume;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+
+bool V4LRadio::getSoundStreamDescription(SoundStreamID id, QString &descr) const
+{
+ if (id == m_SoundStreamID) {
+ descr = name() + " - " + m_currentStation.name();
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+
+bool V4LRadio::getSoundStreamRadioStation(SoundStreamID id, const RadioStation *&rs) const
+{
+ if (id == m_SoundStreamID) {
+ rs = &m_currentStation;
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+
+bool V4LRadio::enumerateSoundStreams(QMap<QString, SoundStreamID> &list) const
+{
+ if (m_SoundStreamID.isValid()) {
+ QString tmp = QString::null;
+ getSoundStreamDescription(m_SoundStreamID, tmp);
+ list[tmp] = m_SoundStreamID;
+ return true;
+ }
+ return false;
+}
+
+
+// bool V4LRadio::stopCapture(SoundStreamID id)
+// {
+// if (id.isValid() && id == m_SoundStreamID && m_ActivePlayback) {
+// sendStopPlayback(id);
+// return true;
+// }
+// return false;
+// }
+
+#include "v4lradio.moc"
diff --git a/kradio3/plugins/v4lradio/v4lradio.h b/kradio3/plugins/v4lradio/v4lradio.h
new file mode 100644
index 0000000..4b86cb5
--- /dev/null
+++ b/kradio3/plugins/v4lradio/v4lradio.h
@@ -0,0 +1,265 @@
+/***************************************************************************
+ v4lradio.h - description
+ -------------------
+ begin : Jan 2002
+ copyright : (C) 2002-2005 Ernst Martin Witte, Klas Kalass
+ email : witte@kawo1.rwth-aachen.de, klas@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef KRADIO_V4LRADIO_H
+#define KRADIO_V4LRADIO_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qtimer.h>
+
+#include "../../src/include/radiodevice_interfaces.h"
+#include "../../src/include/plugins.h"
+#include "../../src/include/frequencyradiostation.h"
+#include "../../src/include/frequencyseekhelper.h"
+#include "../../src/include/soundstreamclient_interfaces.h"
+#include "v4lcfg_interfaces.h"
+
+
+struct video_tuner;
+struct video_audio;
+#ifdef HAVE_V4L2
+struct v4l2_tuner;
+#endif
+
+class V4LRadio : public QObject,
+ public PluginBase,
+ public IRadioDevice,
+// public IRadioSound,
+ public ISeekRadio,
+ public IFrequencyRadio,
+ public ISoundStreamClient,
+ public IV4LCfg
+{
+Q_OBJECT
+public:
+ V4LRadio (const QString &name);
+ virtual ~V4LRadio ();
+
+ virtual bool connectI (Interface *);
+ virtual bool disconnectI (Interface *);
+
+ virtual QString pluginClassName() const { return "V4LRadio"; }
+
+ virtual const QString &name() const { return PluginBase::name(); }
+ virtual QString &name() { return PluginBase::name(); }
+
+ // PluginBase
+
+public:
+ virtual void saveState (KConfig *) const;
+ virtual void restoreState (KConfig *);
+ virtual void startPlugin();
+
+ virtual ConfigPageInfo createConfigurationPage();
+ virtual AboutPageInfo createAboutPage();
+
+ // IRadioDevice methods
+
+RECEIVERS:
+ virtual bool setPower(bool p);
+ virtual bool powerOn();
+ virtual bool powerOff();
+ virtual bool activateStation(const RadioStation &rs);
+
+ANSWERS:
+ virtual bool isPowerOn() const;
+ virtual bool isPowerOff() const;
+ virtual SoundStreamID getSoundStreamID() const;
+ virtual const RadioStation & getCurrentStation() const;
+ virtual const QString & getDescription() const;
+ virtual SoundStreamID getCurrentSoundStreamID() const;
+
+
+ // ISeekRadio
+
+RECEIVERS:
+ virtual bool toBeginning();
+ virtual bool toEnd();
+ virtual bool startSeek (bool up);
+ virtual bool startSeekUp();
+ virtual bool startSeekDown();
+ virtual bool stopSeek();
+
+ANSWERS:
+ virtual bool isSeekRunning() const;
+ virtual bool isSeekUpRunning() const;
+ virtual bool isSeekDownRunning() const;
+ virtual float getProgress () const;
+
+
+ // IFrequencyRadio
+
+RECEIVERS:
+ virtual bool setFrequency(float f);
+ virtual bool setMinFrequency(float mf);
+ virtual bool setMaxFrequency(float mf);
+ virtual bool setScanStep(float s);
+
+ANSWERS:
+ virtual float getFrequency() const;
+ virtual float getMinFrequency() const;
+ virtual float getMinDeviceFrequency() const;
+ virtual float getMaxFrequency() const;
+ virtual float getMaxDeviceFrequency() const;
+ virtual float getScanStep() const;
+
+
+ // ISoundStreamClient: mixer functions
+
+
+RECEIVERS:
+ void noticeConnectedI (ISoundStreamServer *s, bool pointer_valid);
+ void noticeConnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid);
+
+ bool setTreble (SoundStreamID, float v);
+ bool setBass (SoundStreamID, float v);
+ bool setBalance (SoundStreamID, float v);
+ bool mute (SoundStreamID, bool mute = true);
+ bool unmute (SoundStreamID, bool unmute = true);
+ bool setSignalMinQuality(SoundStreamID, float q);
+ bool setStereo(SoundStreamID, bool s);
+
+ bool getTreble(SoundStreamID, float &v) const;
+ bool getBass (SoundStreamID, float &v) const;
+ bool getBalance (SoundStreamID, float &b) const;
+ bool getSignalQuality(SoundStreamID, float &q) const;
+ bool getSignalMinQuality(SoundStreamID, float &q) const;
+ bool hasGoodQuality(SoundStreamID, bool &) const;
+ bool isStereo(SoundStreamID, bool &s) const;
+ bool isMuted(SoundStreamID, bool &m) const;
+
+ // ISoundStreamClient: generic stream handling (broadcasts)
+
+RECEIVERS:
+
+ bool getSoundStreamDescription(SoundStreamID id, QString &descr) const;
+ bool getSoundStreamRadioStation(SoundStreamID id, const RadioStation *&rs) const;
+ bool enumerateSoundStreams(QMap<QString, SoundStreamID> &list) const;
+
+// bool stopCapture(SoundStreamID id); // if active playback also call stopPlayback
+
+
+ // IV4LCfg
+RECEIVERS:
+ bool setRadioDevice (const QString &s);
+ bool setPlaybackMixer(const QString &soundStreamClientID, const QString &ch);
+ bool setCaptureMixer (const QString &soundStreamClientID, const QString &ch);
+ bool setDeviceVolume (float v);
+ bool setActivePlayback(bool a);
+ bool setMuteOnPowerOff(bool a);
+ bool setVolumeZeroOnPowerOff(bool a);
+
+ // if the radio is powered off, we will handle the volume by changing m_defaultPlaybackVolume
+ bool setPlaybackVolume(SoundStreamID id, float volume);
+ bool getPlaybackVolume(SoundStreamID id, float &volume) const;
+
+ANSWERS:
+ const QString &getRadioDevice () const { return m_radioDev; }
+ const QString &getPlaybackMixerID () const { return m_PlaybackMixerID; }
+ const QString &getCaptureMixerID () const { return m_CaptureMixerID; }
+ const QString &getPlaybackMixerChannel() const { return m_PlaybackMixerChannel; }
+ const QString &getCaptureMixerChannel () const { return m_CaptureMixerChannel; }
+ float getDeviceVolume () const;
+ V4LCaps getCapabilities(QString dev = QString::null) const;
+
+ bool getActivePlayback() const { return m_ActivePlayback; }
+ bool getMuteOnPowerOff() const { return m_MuteOnPowerOff; }
+ bool getVolumeZeroOnPowerOff() const { return m_VolumeZeroOnPowerOff; }
+
+ // anything else
+
+protected slots:
+ void poll();
+
+protected:
+ V4LCaps readV4LCaps(const QString &device) const;
+ void radio_init();
+ void radio_done();
+
+ bool readTunerInfo() const;
+ bool updateAudioInfo(bool write) const;
+ bool readAudioInfo() const { return updateAudioInfo(false); }
+ bool writeAudioInfo() const { return updateAudioInfo(true); }
+
+ void searchMixers(ISoundStreamClient **playback_mixer, ISoundStreamClient **capture_mixer);
+
+protected:
+
+ FrequencyRadioStation m_currentStation;
+ mutable float m_treble;
+ mutable float m_bass;
+ mutable float m_balance;
+ mutable float m_deviceVolume;
+ mutable bool m_muted;
+ mutable float m_signalQuality;
+ mutable bool m_stereo;
+
+ float m_minQuality;
+ float m_minFrequency;
+ float m_maxFrequency;
+ mutable float m_lastMinDevFrequency;
+ mutable float m_lastMaxDevFrequency;
+
+ float m_defaultPlaybackVolume;
+
+ FrequencySeekHelper *m_seekHelper;
+ float m_scanStep;
+
+ V4LCaps m_caps;
+ QString m_radioDev;
+ int m_radio_fd;
+
+ mutable bool m_useOldV4L2Calls;
+
+
+ mutable struct video_audio *m_audio;
+ mutable struct video_tuner *m_tuner;
+#ifdef HAVE_V4L2
+ mutable struct v4l2_tuner *m_tuner2;
+#endif
+
+ QTimer m_pollTimer;
+
+ struct TunerCache {
+ bool valid;
+ float deltaF;
+ float minF, maxF;
+ TunerCache() { valid = false; deltaF = minF = maxF = 0; }
+ };
+ mutable struct TunerCache m_tunercache;
+
+
+ mutable bool m_blockReadTuner,
+ m_blockReadAudio;
+
+ SoundStreamID m_SoundStreamID;
+ QString m_PlaybackMixerID;
+ QString m_CaptureMixerID;
+ QString m_PlaybackMixerChannel;
+ QString m_CaptureMixerChannel;
+
+ bool m_ActivePlayback;
+ bool m_MuteOnPowerOff;
+ bool m_VolumeZeroOnPowerOff;
+
+ bool m_restorePowerOn;
+};
+
+#endif