1
0
mirror of https://github.com/rofafor/vdr-plugin-femon.git synced 2023-10-10 11:36:53 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Rolf Ahrenberg
6ce0ca32bd Fixed device switching priority (Thanks to Andreas Brugger).
Fixed device switching back to the primary device.
2006-06-06 04:20:00 +03:00
Rolf Ahrenberg
74a2a1bbe7 Updated for vdr-1.4.0.
Modified APIVERSION code in Makefile.
Updated german translation (Thanks to Andreas Brachold).
2006-04-30 04:20:00 +03:00
Rolf Ahrenberg
bf85e32d0d Added STRIP option for Makefile (Thanks to Ville Skyttä).
Modified APIVERSION code in Makefile.
2006-04-23 04:20:00 +03:00
Rolf Ahrenberg
caf42f7ace Updated for vdr-1.3.47. 2006-04-20 04:20:00 +03:00
Rolf Ahrenberg
c2b1e5a187 Updated for vdr-1.3.44.
Minor Makefile changes.
Made all symbol data 'const'.
Added spanish translation (Thanks to Luis Palacios).
2006-03-08 04:20:00 +02:00
Rolf Ahrenberg
e90fe6065c Updated for vdr-1.3.42.
Added "SilverGreen" theme (Thanks to Rififi77 @ VDRPortal).
2006-02-06 04:20:00 +02:00
Rolf Ahrenberg
7ee255830a Updated for vdr-1.3.40.
Fixed a translation bug (Thanks to Antti Hartikainen).
Fixed AC3 header parsing bug (Thanks to Axel Katzur for reporting this one).
Fixed EgalsTry theme (Thanks to Uwe Hanke).
2006-01-25 04:20:00 +02:00
36 changed files with 405 additions and 162 deletions

39
HISTORY
View File

@@ -194,3 +194,42 @@ VDR Plugin 'femon' Revision History
- Added "Duotone" theme for 2bpp on screen displays.
- Fixed crash bug in femonreceiver.
- Fixed setup page bug (Thanks to Thomas G<>nther for reporting this one).
2006-01-25: Version 0.9.6
- Updated for vdr-1.3.40.
- Fixed a translation bug (Thanks to Antti Hartikainen).
- Fixed AC3 header parsing bug (Thanks to Axel Katzur for reporting this one).
- Fixed EgalsTry theme (Thanks to Uwe Hanke).
2006-02-06: Version 0.9.7
- Updated for vdr-1.3.42.
- Added "SilverGreen" theme (Thanks to Rififi77 @ VDRPortal).
2006-03-08: Version 0.9.8
- Updated for vdr-1.3.44.
- Minor Makefile changes.
- Made all symbol data 'const'.
- Added spanish translation (Thanks to Luis Palacios).
2006-04-20: Version 0.9.9
- Updated for vdr-1.3.47.
2006-04-23: Version 0.9.10
- Added STRIP option for Makefile (Thanks to Ville Skytt<74>).
- Modified APIVERSION code in Makefile.
2006-04-30: Version 1.0.0
- Updated for vdr-1.4.0.
- Modified APIVERSION code in Makefile.
- Updated german translation (Thanks to Andreas Brachold).
2006-06-06: Version 1.0.1
- Fixed device switching priority (Thanks to Andreas Brugger).
- Fixed device switching back to the primary device.

View File

@@ -3,6 +3,15 @@
#
# $Id$
# Debugging on/off
#FEMON_DEBUG = 1
# NTSC on/off
#FEMON_NTSC = 1
# Strip debug symbols? Set eg. to /bin/true if not
STRIP = strip
# The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin.
# By default the main source file also carries this name.
@@ -11,7 +20,7 @@ PLUGIN = femon
### The version number of this plugin (taken from the main source file):
VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).h | awk '{ print $$6 }' | sed -e 's/[";]//g')
VERSION = $(shell grep 'static const char VERSION\[\] *=' $(PLUGIN).h | awk '{ print $$6 }' | sed -e 's/[";]//g')
### The C++ compiler and options:
@@ -20,7 +29,6 @@ CXXFLAGS ?= -fPIC -g -O2 -Wall -Woverloaded-virtual
### The directory environment:
DVBDIR = ../../../../DVB
VDRDIR = ../../..
LIBDIR = ../../lib
TMPDIR = /tmp
@@ -29,9 +37,9 @@ TMPDIR = /tmp
-include $(VDRDIR)/Make.config
### The version number of VDR (taken from VDR's "config.h"):
### The version number of VDR's plugin API (taken from VDR's "config.h"):
VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
### The name of the distribution archive:
@@ -40,16 +48,16 @@ PACKAGE = vdr-$(ARCHIVE)
### Includes and Defines (add further entries here):
INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
INCLUDES += -I$(VDRDIR)/include
DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
ifdef FEMON_NTSC
DEFINES += -DFEMON_NTSC
DEFINES += -DNTSC
endif
ifdef FEMON_DEBUG
DEFINES += -DFEMON_DEBUG
DEFINES += -DDEBUG
endif
.PHONY: all all-redirect
@@ -79,10 +87,10 @@ all: libvdr-$(PLUGIN).so
libvdr-$(PLUGIN).so: $(OBJS)
$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
ifndef FEMON_DEBUG
strip $(LIBDIR)/$@.$(VDRVERSION)
@$(STRIP) $@
endif
@cp $@ $(LIBDIR)/$@.$(APIVERSION)
dist: clean
@-rm -rf $(TMPDIR)/$(ARCHIVE)

View File

@@ -15,8 +15,8 @@
#include "femontools.h"
#include "femon.h"
#if defined(VDRVERSNUM) && VDRVERSNUM < 10336
#error "You don't exist! Go away! Upgrade yourself!"
#if defined(APIVERSNUM) && APIVERSNUM < 10400
#error "VDR-1.4.0 API version or greater is required!"
#endif
cPluginFemon::cPluginFemon()
@@ -236,6 +236,7 @@ cMenuFemonSetup::cMenuFemonSetup(void)
themes[eFemonThemeEnigma] = tr("Enigma");
themes[eFemonThemeEgalsTry] = tr("EgalsTry");
themes[eFemonThemeDuotone] = tr("Duotone");
themes[eFemonThemeSilverGreen] = tr("SilverGreen");
data = femonConfig;
Setup();

View File

@@ -11,9 +11,9 @@
#include <vdr/plugin.h>
static const char *VERSION = "0.9.5";
static const char *DESCRIPTION = "DVB Signal Information Monitor (OSD)";
static const char *MAINMENUENTRY = "Signal Information";
static const char VERSION[] = "1.0.1";
static const char DESCRIPTION[] = "DVB Signal Information Monitor (OSD)";
static const char MAINMENUENTRY[] = "Signal Information";
class cPluginFemon : public cPlugin {
public:
@@ -27,6 +27,8 @@ public:
virtual bool Start(void);
virtual void Stop(void);
virtual void Housekeeping(void);
virtual void MainThreadHook(void) {}
virtual cString Active(void) { return NULL; }
virtual const char *MainMenuEntry(void) { return (femonConfig.hidemenu ? NULL : tr(MAINMENUENTRY)); }
virtual cOsdObject *MainMenuAction(void);
virtual cMenuSetupPage *SetupMenu(void);

View File

@@ -24,7 +24,7 @@ cFemonConfig::cFemonConfig(void)
calcinterval = 20;
syslogoutput = 0;
showcasystem = 0;
#ifdef FEMON_NTSC
#ifdef NTSC
osdheight = 420;
#else
osdheight = 480;
@@ -96,6 +96,7 @@ const cFemonTheme femonTheme[eFemonThemeMaxNumber] =
},
{
// eFemonThemeEgalsTry
4, // bpp
0xCA2B1B9E, // clrBackground
0xDFBEBAC3, // clrTitleBackground
0xFF280249, // clrTitleText
@@ -110,11 +111,23 @@ const cFemonTheme femonTheme[eFemonThemeMaxNumber] =
2, // bpp
0x7F000000, // clrBackground
0xFFFCFCFC, // clrTitleBackground
0x7F000000, // clrTitleText
0xFFFCFCFC, // clrActiveText
0x7F000000, // clrTitleText
0xFFFCFCFC, // clrActiveText
0xFFFCFCFC, // clrInactiveText
0xFFFC1414, // clrRed
0xFFFCFCFC, // clrYellow
0xFFFCFCFC, // clrGreen
},
{
// eFemonThemeSilverGreen
4, // bpp
0xD9526470, // clrBackground
0xD9293841, // clrTitleBackground
0xFFB3BDCA, // clrTitleText
0xFFCE7B00, // clrActiveText
0xFFB3BDCA, // clrInactiveText
0xFF992900, // clrRed
0xFFCE7B00, // clrYellow
0xFF336600, // clrGreen
},
};

View File

@@ -56,6 +56,7 @@ enum eFemonThemes
eFemonThemeEnigma,
eFemonThemeEgalsTry,
eFemonThemeDuotone,
eFemonThemeSilverGreen,
eFemonThemeMaxNumber
};

View File

@@ -11,7 +11,7 @@ PLUGIN = femonclient
### The version number of this plugin (taken from the main source file):
VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
VERSION = $(shell grep 'static const char VERSION\[\] *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
### The C++ compiler and options:
@@ -20,27 +20,26 @@ CXXFLAGS ?= -fPIC -g -O2 -Wall -Woverloaded-virtual
### The directory environment:
DVBDIR = ../../../../DVB
VDRDIR = ../../..
LIBDIR = ../../lib
VDRDIR = ../../../..
LIBDIR = ../../../lib
TMPDIR = /tmp
### Allow user defined options to overwrite defaults:
-include $(VDRDIR)/Make.config
### The version number of VDR (taken from VDR's "config.h"):
### The version number of VDR's plugin API (taken from VDR's "config.h"):
VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
### The name of the distribution archive:
ARCHIVE = svcintf-$(VERSION)
ARCHIVE = $(PLUGIN)-$(VERSION)
PACKAGE = vdr-$(ARCHIVE)
### Includes and Defines (add further entries here):
INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -I$(VDRDIR)/PLUGINS/src/femon/
INCLUDES += -I$(VDRDIR)/include -I$(VDRDIR)/PLUGINS/src/femon/
DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
@@ -68,7 +67,7 @@ all: libvdr-$(PLUGIN).so
libvdr-$(PLUGIN).so: $(PLUGIN).o
$(CXX) $(CXXFLAGS) -shared $(PLUGIN).o -o $@
@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
@cp $@ $(LIBDIR)/$@.$(APIVERSION)
dist: clean
@-rm -rf $(TMPDIR)/$(ARCHIVE)

View File

@@ -11,9 +11,9 @@
#include <vdr/plugin.h>
#include "femonservice.h"
static const char *VERSION = "0.0.1";
static const char *DESCRIPTION = "Femon client";
static const char *MAINMENUENTRY = "Show frontend statistic on console";
static const char VERSION[] = "0.0.1";
static const char DESCRIPTION[] = "Femon client";
static const char MAINMENUENTRY[] = "Show frontend statistic on console";
class cPluginFemonClient : public cPlugin {
public:

File diff suppressed because it is too large Load Diff

View File

@@ -594,7 +594,7 @@ void cFemonOsd::DrawInfoWindow(void)
break;
default:
snprintf(buf, sizeof(buf), "%s #%d - %s", tr("Terrestial Card"), cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name);
snprintf(buf, sizeof(buf), "%s #%d - %s", tr("Terrestrial Card"), cDevice::ActualDevice()->CardIndex(), m_FrontendInfo.name);
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), buf, femonTheme[femonConfig.theme].clrActiveText, femonTheme[femonConfig.theme].clrBackground, m_Font);
offset += OSDROWHEIGHT;
m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Frequency"), femonTheme[femonConfig.theme].clrInactiveText, femonTheme[femonConfig.theme].clrBackground, m_Font);
@@ -995,24 +995,26 @@ void cFemonOsd::SetAudioTrack(int Index, const char * const *Tracks)
bool cFemonOsd::DeviceSwitch(int direction)
{
Dprintf("%s()\n", __PRETTY_FUNCTION__);
int device = cDevice::ActualDevice()->DeviceNumber();
int device = cDevice::ActualDevice()->DeviceNumber();
direction = sgn(direction);
if (device >= 0) {
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
for (int i = 0; i < cDevice::NumDevices() - 1; i++) {
for (int i = 0; i < cDevice::NumDevices() - 1; i++) {
if (direction) {
if (++device >= cDevice::NumDevices()) device = 0;
if (++device >= cDevice::NumDevices())
device = 0;
}
else {
if (--device < 0) device = cDevice::NumDevices() - 1;
if (--device < 0)
device = cDevice::NumDevices() - 1;
}
if (cDevice::GetDevice(device)->ProvidesChannel(channel)) {
if (cDevice::GetDevice(device)->ProvidesChannel(channel, 0)) {
Dprintf("%s(%d) device(%d)\n", __PRETTY_FUNCTION__, direction, device);
// here should be added some checks, if the device is really available (i.e. not recording)
cStatus::MsgChannelSwitch(cDevice::PrimaryDevice(), 0);
cControl::Shutdown();
cDevice::GetDevice(device)->SwitchChannel(channel, true);
// does this work with primary devices ?
if (cDevice::GetDevice(device) == cDevice::PrimaryDevice())
cDevice::GetDevice(device)->ForceTransferMode();
cControl::Launch(new cTransferControl(cDevice::GetDevice(device), channel->Vpid(), channel->Apids(), channel->Dpids(), channel->Spids()));
cStatus::MsgChannelSwitch(cDevice::PrimaryDevice(), channel->Number());
return (true);

View File

@@ -230,20 +230,71 @@ void cFemonReceiver::GetAC3Info(uint8_t *mbuf, int count)
m_AC3FrameSize <<= 1;
m_AC3BitStreamMode = (headr[3] & 7);
m_AC3AudioCodingMode = (headr[4] & 0xE0) >> 5;
if ((m_AC3AudioCodingMode & 0x01) && (m_AC3AudioCodingMode != 0x01)) // if 3 front channels
if ((m_AC3AudioCodingMode & 0x01) && (m_AC3AudioCodingMode != 0x01)) {
// 3 front channels
m_AC3CenterMixLevel = (headr[4] & 0x18) >> 3;
else
if (m_AC3AudioCodingMode & 0x04) {
// a surround channel exists
m_AC3SurroundMixLevel = (headr[4] & 0x06) >> 1;
if (m_AC3AudioCodingMode == 0x02) {
// if in 2/0 mode
m_AC3DolbySurroundMode = ((headr[4] & 0x01) << 1) | ((headr[5] & 0x80) >> 7);
m_AC3LfeOn = (headr[5] & 0x40) >> 6;
m_AC3DialogLevel = (headr[5] & 0x3e) >> 1;
}
else {
m_AC3DolbySurroundMode = FR_NOTVALID;
m_AC3LfeOn = (headr[4] & 0x01);
m_AC3DialogLevel = (headr[5] & 0xF8) >> 3;
}
}
else {
m_AC3SurroundMixLevel = FR_NOTVALID;
if (m_AC3AudioCodingMode == 0x02) {
// if in 2/0 mode
m_AC3DolbySurroundMode = (headr[4] & 0x06) >> 1;
m_AC3LfeOn = (headr[4] & 0x01);
m_AC3DialogLevel = (headr[5] & 0xF8) >> 3;
}
else {
m_AC3DolbySurroundMode = FR_NOTVALID;
m_AC3LfeOn = (headr[4] & 0x04) >> 2;
m_AC3DialogLevel = (headr[4] & 0x03) << 3 | ((headr[5] & 0xE0) >> 5);
}
}
}
else {
m_AC3CenterMixLevel = FR_NOTVALID;
if (m_AC3AudioCodingMode & 0x04) // if a surround channel exists
m_AC3SurroundMixLevel = (headr[4] & 0x06) >> 1;
else
m_AC3SurroundMixLevel = FR_NOTVALID;
if (m_AC3AudioCodingMode == 0x02) // if in 2/0 mode
m_AC3DolbySurroundMode = ((headr[4] & 1) << 1) | ((headr[5] & 0x80) >> 7);
else
m_AC3DolbySurroundMode = FR_NOTVALID;
m_AC3LfeOn = (headr[5] & 0x40) >> 6;
m_AC3DialogLevel = (headr[5] & 0x3e) >> 1;
if (m_AC3AudioCodingMode & 0x04) {
// a surround channel exists
m_AC3SurroundMixLevel = (headr[4] & 0x18) >> 3;
if (m_AC3AudioCodingMode == 0x02) {
// if in 2/0 mode
m_AC3DolbySurroundMode = (headr[4] & 0x06) >> 1;
m_AC3LfeOn = (headr[4] & 0x01);
m_AC3DialogLevel = (headr[5] & 0xF8) >> 3;
}
else {
m_AC3DolbySurroundMode = FR_NOTVALID;
m_AC3LfeOn = (headr[4] & 0x04) >> 2;
m_AC3DialogLevel = (headr[4] & 0x03) << 3 | ((headr[5] & 0xE0) >> 5);
}
}
else {
m_AC3SurroundMixLevel = FR_NOTVALID;
if (m_AC3AudioCodingMode == 0x02) {
// if in 2/0 mode
m_AC3DolbySurroundMode = (headr[4] & 0x18) >> 3;
m_AC3LfeOn = (headr[4] & 0x04) >> 2;
m_AC3DialogLevel = (headr[4] & 0x03) << 3 | ((headr[5] & 0xE0) >> 5);
}
else {
m_AC3DolbySurroundMode = FR_NOTVALID;
m_AC3LfeOn = (headr[4] & 0x10) >> 4;
m_AC3DialogLevel = ((headr[4] & 0x0F) << 1) | ((headr[5] & 0x80) >> 7);
}
}
}
}
void cFemonReceiver::Activate(bool On)

View File

@@ -12,7 +12,7 @@
#include <stdint.h>
#include <vdr/tools.h>
#ifdef FEMON_DEBUG
#ifdef DEBUG
#define Dprintf(x...) printf(x);
#else
#define Dprintf(x...) ;

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * ar11_xpm[] = {
static const char *const ar11_xpm[] = {
"26 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * ar169_xpm[] = {
static const char *const ar169_xpm[] = {
"38 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * ar2211_xpm[] = {
static const char *const ar2211_xpm[] = {
"52 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * ar43_xpm[] = {
static const char *const ar43_xpm[] = {
"31 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * carrier_xpm[] = {
static const char *const carrier_xpm[] = {
"96 19 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * device_xpm[] = {
static const char *const device_xpm[] = {
"14 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * dolbydigital_xpm[] = {
static const char *const dolbydigital_xpm[] = {
"31 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * dolbydigital20_xpm[] = {
static const char *const dolbydigital20_xpm[] = {
"55 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * dolbydigital51_xpm[] = {
static const char *const dolbydigital51_xpm[] = {
"51 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * five_xpm[] = {
static const char *const five_xpm[] = {
"15 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * four_xpm[] = {
static const char *const four_xpm[] = {
"15 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * lock_xpm[] = {
static const char *const lock_xpm[] = {
"96 19 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * monoleft_xpm[] = {
static const char *const monoleft_xpm[] = {
"17 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * monoright_xpm[] = {
static const char *const monoright_xpm[] = {
"17 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * ntsc_xpm[] = {
static const char *const ntsc_xpm[] = {
"19 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * one_xpm[] = {
static const char *const one_xpm[] = {
"15 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * pal_xpm[] = {
static const char *const pal_xpm[] = {
"18 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * signal_xpm[] = {
static const char *const signal_xpm[] = {
"96 19 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * stereo_xpm[] = {
static const char *const stereo_xpm[] = {
"17 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * sync_xpm[] = {
static const char *const sync_xpm[] = {
"96 19 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * three_xpm[] = {
static const char *const three_xpm[] = {
"15 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * two_xpm[] = {
static const char *const two_xpm[] = {
"15 18 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * viterbi_xpm[] = {
static const char *const viterbi_xpm[] = {
"96 19 2 1",
". c #FFFFFF",
"+ c #000000",

View File

@@ -1,5 +1,5 @@
/* XPM */
static char * zero_xpm[] = {
static const char *const zero_xpm[] = {
"15 18 2 1",
". c #FFFFFF",
"+ c #000000",