Skip to content

Commit 69fda06

Browse files
committed
first draft of nulldevice
1 parent 2621f4c commit 69fda06

8 files changed

+184
-3
lines changed

HISTORY

+2
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,5 @@ VDR Plugin 'dbus2vdr' Revision History
240240
2016-02-13: Version 28
241241
- add device interface
242242

243+
2016-03-04: Version 29
244+
- add nulldevice as no-op primary device

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
5656

5757
### The object files (add further files here):
5858

59-
OBJS = $(PLUGIN).o channel.o connection.o device.o epg.o helper.o mainloop.o network.o object.o osd.o plugin.o recording.o remote.o sd-daemon.o setup.o shutdown.o skin.o status.o timer.o vdr.o
59+
OBJS = $(PLUGIN).o channel.o connection.o device.o epg.o helper.o mainloop.o network.o nulldevice.o object.o osd.o plugin.o recording.o remote.o sd-daemon.o setup.o shutdown.o skin.o status.o timer.o vdr.o
6060
SWOBJS = libvdr-exitpipe.o libvdr-i18n.o libvdr-thread.o libvdr-tools.o shutdown-wrapper.o
6161

6262
### The main target:

README

+7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ Commandline Arguments
7777
--no-mainloop
7878
don't start GMainLoop
7979
(don't use this option if you don't understand)
80+
--nulldevice[=force]
81+
creates an output device, which does nothing
82+
can be activated to suspend in/output of DVB streams
83+
if "force" dbus2vdr will set this device as primary device on startup
8084

8185
Interface "channel"
8286
-------------------
@@ -99,6 +103,9 @@ Interface "device"
99103
- get current primary device
100104
vdr-dbus-send.sh /Devices device.GetPrimary
101105

106+
- get index of the nulldevice (-1 if not created)
107+
vdr-dbus-send.sh /Devices device.GetNullDevice
108+
102109
- request switch to primary device
103110
vdr-dbus-send.sh /Devices device.RequestPrimary int32:index
104111

dbus2vdr.c

+26-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "helper.h"
2121
#include "mainloop.h"
2222
#include "network.h"
23+
#include "nulldevice.h"
2324
#include "plugin.h"
2425
#include "osd.h"
2526
#include "recording.h"
@@ -38,7 +39,7 @@
3839
#include "avahi-helper.h"
3940

4041

41-
static const char *VERSION = "28";
42+
static const char *VERSION = "29";
4243
static const char *DESCRIPTION = trNOOP("control vdr via D-Bus");
4344
static const char *MAINMENUENTRY = NULL;
4445

@@ -153,6 +154,8 @@ class cPluginDbus2vdr : public cPlugin {
153154
bool _enable_system;
154155
bool _enable_session;
155156
bool _enable_network;
157+
bool _enable_nulldevice;
158+
bool _force_nulldevice;
156159
bool _first_main_thread;
157160

158161
cDBusMainLoop *_main_loop;
@@ -201,6 +204,8 @@ cPluginDbus2vdr::cPluginDbus2vdr(void)
201204
_enable_system = true;
202205
_enable_session = false;
203206
_enable_network = false;
207+
_enable_nulldevice = false;
208+
_force_nulldevice = false;
204209
_first_main_thread = true;
205210
_main_loop = NULL;
206211
_system_bus = NULL;
@@ -271,6 +276,10 @@ const char *cPluginDbus2vdr::CommandLineHelp(void)
271276
" enable network support for peer2peer communication\n"
272277
" a local dbus-daemon has to be started manually\n"
273278
" it has to store its address at $PLUGINDIR/network-address.conf\n"
279+
" --nulldevice[=force]\n"
280+
" create a primary device which does nothing\n"
281+
" useful to suspend in- and output\n"
282+
" may force vdr to set this device as primary device on startup\n"
274283
" --log=n\n"
275284
" set plugin's loglevel\n";
276285
}
@@ -288,13 +297,14 @@ bool cPluginDbus2vdr::ProcessArgs(int argc, char *argv[])
288297
{"systemd", no_argument, 0, 's' | 0x400},
289298
{"network", no_argument, 0, 'n'},
290299
{"no-mainloop", no_argument, 0, 'n' | 0x100},
300+
{"nulldevice", optional_argument, 0, 'd'},
291301
{"log", required_argument, 0, 'l'},
292302
{0, 0, 0, 0}
293303
};
294304

295305
while (true) {
296306
int option_index = 0;
297-
int c = getopt_long(argc, argv, "l:nop:s:uw:", options, &option_index);
307+
int c = getopt_long(argc, argv, "d:l:nop:s:uw:", options, &option_index);
298308
if (c == -1)
299309
break;
300310
switch (c) {
@@ -361,6 +371,14 @@ bool cPluginDbus2vdr::ProcessArgs(int argc, char *argv[])
361371
isyslog("dbus2vdr: disable mainloop");
362372
break;
363373
}
374+
case 'd':
375+
{
376+
_enable_nulldevice = true;
377+
if (optarg)
378+
_force_nulldevice = true;
379+
isyslog("dbus2vdr: enable %snulldevice", _force_nulldevice ? "and force " : "");
380+
break;
381+
}
364382
}
365383
}
366384
return true;
@@ -380,6 +398,12 @@ bool cPluginDbus2vdr::Initialize(void)
380398
else
381399
dbus2vdr_Busname = cString::sprintf("%s", DBUS_VDR_BUSNAME);
382400
#endif
401+
if (_enable_nulldevice) {
402+
cNullDevice *nulldev = new cNullDevice();
403+
cDBusDevices::_nulldeviceIndex = nulldev->CardIndex();
404+
if (_force_nulldevice)
405+
cDBusDevices::SetPrimaryDeviceRequest(cDBusDevices::_nulldeviceIndex);
406+
}
383407
return true;
384408
}
385409

device.c

+13
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
int cDBusDevices::_requestedPrimaryDevice = -1;
99
cMutex cDBusDevices::_requestedPrimaryDeviceMutex;
10+
int cDBusDevices::_nulldeviceIndex = -1;
1011

1112
void cDBusDevices::SetPrimaryDeviceRequest(int index)
1213
{
@@ -37,6 +38,9 @@ namespace cDBusDevicesHelper
3738
" <arg name=\"isPrimary\" type=\"b\" direction=\"out\"/>\n"
3839
" <arg name=\"name\" type=\"s\" direction=\"out\"/>\n"
3940
" </method>\n"
41+
" <method name=\"GetNullDevice\">\n"
42+
" <arg name=\"index\" type=\"i\" direction=\"out\"/>\n"
43+
" </method>\n"
4044
" <method name=\"RequestPrimary\">\n"
4145
" <arg name=\"index\" type=\"i\" direction=\"in\"/>\n"
4246
" </method>\n"
@@ -82,6 +86,14 @@ namespace cDBusDevicesHelper
8286
g_variant_builder_unref(builder);
8387
}
8488

89+
static void GetNullDevice(cDBusObject *Object, GVariant *Parameters, GDBusMethodInvocation *Invocation)
90+
{
91+
GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("(i)"));
92+
g_variant_builder_add(Variant, "i", cDBusDevices::_nulldeviceIndex);
93+
g_dbus_method_invocation_return_value(Invocation, g_variant_builder_end(builder));
94+
g_variant_builder_unref(builder);
95+
}
96+
8597
static void RequestPrimary(cDBusObject *Object, GVariant *Parameters, GDBusMethodInvocation *Invocation)
8698
{
8799
gint32 index = -1;
@@ -113,6 +125,7 @@ cDBusDevices::cDBusDevices(void)
113125
:cDBusObject("/Devices", cDBusDevicesHelper::_xmlNodeInfo)
114126
{
115127
AddMethod("GetPrimary", cDBusDevicesHelper::GetPrimary);
128+
AddMethod("GetNullDevice", cDBusDevicesHelper::GetNullDevice);
116129
AddMethod("RequestPrimary", cDBusDevicesHelper::RequestPrimary);
117130
AddMethod("List", cDBusDevicesHelper::List);
118131
}

device.h

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class cDBusDevices : public cDBusObject
1111
static int _requestedPrimaryDevice;
1212

1313
public:
14+
static int _nulldeviceIndex;
1415
static void SetPrimaryDeviceRequest(int index);
1516
static int RequestedPrimaryDevice(bool clear);
1617

nulldevice.c

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include "nulldevice.h"
2+
3+
#include <vdr/osd.h>
4+
#include <vdr/player.h>
5+
6+
class cNullOsd : public cOsd {
7+
public:
8+
cNullOsd(int Left, int Top, uint Level) : cOsd(Left, Top, Level) {}
9+
virtual ~cNullOsd() {}
10+
11+
virtual cPixmap *CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null) { return NULL; }
12+
virtual void DestroyPixmap(cPixmap *Pixmap) {}
13+
virtual void DrawImage(const cPoint &Point, const cImage &Image) {}
14+
virtual void DrawImage(const cPoint &Point, int ImageHandle) {}
15+
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas) { return oeOk; }
16+
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas) { return oeOk; }
17+
virtual void SaveRegion(int x1, int y1, int x2, int y2) {}
18+
virtual void RestoreRegion(void) {}
19+
virtual eOsdError SetPalette(const cPalette &Palette, int Area) { return oeOk; }
20+
virtual void DrawPixel(int x, int y, tColor Color) {}
21+
virtual void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool ReplacePalette = false, bool Overlay = false) {}
22+
virtual void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault) {}
23+
virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color) {}
24+
virtual void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants = 0) {}
25+
virtual void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type) {}
26+
virtual void Flush(void) {}
27+
};
28+
29+
class cNullOsdProvider : public cOsdProvider {
30+
protected:
31+
virtual cOsd *CreateOsd(int Left, int Top, uint Level) { return new cNullOsd(Left, Top, Level); }
32+
virtual bool ProvidesTrueColor(void) { return true; }
33+
virtual int StoreImageData(const cImage &Image) { return 0; }
34+
virtual void DropImageData(int ImageHandle) {}
35+
36+
public:
37+
cNullOsdProvider() : cOsdProvider() {}
38+
virtual ~cNullOsdProvider() {}
39+
};
40+
41+
42+
class cNullPlayer : public cPlayer {
43+
public:
44+
cNullPlayer(void);
45+
virtual ~cNullPlayer(void);
46+
};
47+
48+
cNullPlayer::cNullPlayer(void)
49+
{
50+
}
51+
52+
cNullPlayer::~cNullPlayer()
53+
{
54+
Detach();
55+
}
56+
57+
58+
class cNullControl : public cControl {
59+
public:
60+
static cNullPlayer *Player;
61+
62+
virtual void Hide(void) {}
63+
64+
cNullControl(void);
65+
66+
virtual ~cNullControl(void);
67+
};
68+
69+
cNullPlayer *cNullControl::Player;
70+
71+
cNullControl::cNullControl(void)
72+
:cControl(Player = new cNullPlayer)
73+
{
74+
}
75+
76+
cNullControl::~cNullControl()
77+
{
78+
delete Player;
79+
Player = NULL;
80+
}
81+
82+
83+
void cNullDevice::MakePrimaryDevice(bool On)
84+
{
85+
cDevice::MakePrimaryDevice(On);
86+
if (On) {
87+
new cNullOsdProvider();
88+
if (cNullControl::Player != NULL) {
89+
cControl::Launch(new cNullControl());
90+
cControl::Attach();
91+
}
92+
}
93+
else if (cNullControl::Player)
94+
cControl::Shutdown();
95+
}

nulldevice.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef __DBUS2VDR_NULLDEVICE_H
2+
#define __DBUS2VDR_NULLDEVICE_H
3+
4+
#include <vdr/device.h>
5+
6+
class cNullDevice : public cDevice
7+
{
8+
public:
9+
cNullDevice() : cDevice() {}
10+
virtual ~cNullDevice() {}
11+
12+
virtual bool Ready(void) { return true; }
13+
14+
virtual cString DeviceType(void) const { return "null"; }
15+
virtual cString DeviceName(void) const { return "nulldevice"; }
16+
virtual bool HasDecoder(void) const { return true; }
17+
virtual bool AvoidRecording(void) const { return true; }
18+
19+
virtual bool SetPlayMode(ePlayMode PlayMode) { return true; }
20+
virtual int PlayVideo(const uchar *Data, int Length) { return Length; }
21+
22+
virtual int PlayAudio(const uchar *Data, int Length, uchar Id) { return Length; }
23+
24+
virtual int PlayTsVideo(const uchar *Data, int Length) { return Length; }
25+
virtual int PlayTsAudio(const uchar *Data, int Length) { return Length; }
26+
virtual int PlayTsSubtitle(const uchar *Data, int Length) { return Length; }
27+
28+
virtual int PlayPes(const uchar *Data, int Length, bool VideoOnly = false) { return Length; }
29+
virtual int PlayTs(const uchar *Data, int Length, bool VideoOnly = false) { return Length; }
30+
31+
virtual bool Poll(cPoller &Poller, int TimeoutMs = 0) { return true; }
32+
virtual bool Flush(int TimeoutMs = 0) { return true; }
33+
bool Start(void) {return true;}
34+
35+
protected:
36+
virtual void MakePrimaryDevice(bool On);
37+
};
38+
39+
#endif

0 commit comments

Comments
 (0)