mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Faster OSD by using bitmap
This commit is contained in:
parent
b4faf3787a
commit
6a50f37f25
7
HISTORY
7
HISTORY
@ -204,6 +204,11 @@ Video Disk Recorder Revision History
|
|||||||
is no stdin in daemon mode, so KBD makes no sense - plus it sometimes
|
is no stdin in daemon mode, so KBD makes no sense - plus it sometimes
|
||||||
crashed).
|
crashed).
|
||||||
|
|
||||||
2000-09-21: Version 0.65
|
2000-10-01: Version 0.65
|
||||||
|
|
||||||
- Modified LIRC interface to better handle repeat function (by Carsten Koch).
|
- Modified LIRC interface to better handle repeat function (by Carsten Koch).
|
||||||
|
- Faster OSD by first writing into a bitmap and then sending the entire bitmap
|
||||||
|
to the DVB driver at once (requires the patch 'dvb.c.071.diff' to be applied
|
||||||
|
against the version 0.71 DVB driver file 'dvb.c').
|
||||||
|
- When switching channels the channel is now immediately displayed, and the
|
||||||
|
current/next information is shown as soon as it becomes available.
|
||||||
|
19
INSTALL
19
INSTALL
@ -15,18 +15,22 @@ If you have the DVB driver source in a different location
|
|||||||
you will have to change the definition of DVBDIR in the
|
you will have to change the definition of DVBDIR in the
|
||||||
Makefile.
|
Makefile.
|
||||||
|
|
||||||
This program requires the card driver version 0.05 or higher
|
This program requires the card driver version 0.71 or higher
|
||||||
to work properly. If you are using driver version 0.7 you need
|
to work properly. Currently you need to load the dvb.o module with
|
||||||
to load the dvb.o module with option outstream=0, so your insmod
|
option outstream=0, so your insmod statement should read
|
||||||
statement should read 'insmod dvb.o outstream=0'. This is currently
|
'insmod dvb.o outstream=0'. This is necessary because 'vdr' works
|
||||||
necessary because 'vdr' works with AV_PES data and will change
|
with AV_PES data and will change once it has been modified to work
|
||||||
once it has been modified to work directly with MPEG2.
|
directly with MPEG2. You also need to apply the patch 'dvb.c.071.diff'
|
||||||
|
for the On Screen Display to work properly.
|
||||||
|
|
||||||
After extracting the package, change into the VDR directory
|
After extracting the package, change into the VDR directory
|
||||||
and type 'make'. This should produce an executable file
|
and type 'make'. This should produce an executable file
|
||||||
named 'vdr', which can be run after the DVB driver has been
|
named 'vdr', which can be run after the DVB driver has been
|
||||||
installed.
|
installed.
|
||||||
|
|
||||||
|
IMPORTANT: See "Configuration files" below for information on how
|
||||||
|
========= to set up the configuration files at the proper location!
|
||||||
|
|
||||||
The 'vdr' program can be controlled via the PC keyboard or
|
The 'vdr' program can be controlled via the PC keyboard or
|
||||||
an infrared remote control unit. Define the REMOTE macro to one of the
|
an infrared remote control unit. Define the REMOTE macro to one of the
|
||||||
following values 'make' call to activate the respective control mode:
|
following values 'make' call to activate the respective control mode:
|
||||||
@ -115,7 +119,8 @@ Configuration files:
|
|||||||
There are three configuration files that hold information about
|
There are three configuration files that hold information about
|
||||||
channels, remote control keys and timers. By default these files are
|
channels, remote control keys and timers. By default these files are
|
||||||
assumed to be located in the video directory, but a different directory
|
assumed to be located in the video directory, but a different directory
|
||||||
can be used with the '-c' option.
|
can be used with the '-c' option. For starters just copy all *.conf files from
|
||||||
|
the VDR directory into your video directory.
|
||||||
|
|
||||||
The configuration files can be edited with any text editor, or will be written
|
The configuration files can be edited with any text editor, or will be written
|
||||||
by the 'vdr' program if any changes are made inside the on-screen menus.
|
by the 'vdr' program if any changes are made inside the on-screen menus.
|
||||||
|
55
Makefile
55
Makefile
@ -4,12 +4,15 @@
|
|||||||
# See the main source file 'vdr.c' for copyright information and
|
# See the main source file 'vdr.c' for copyright information and
|
||||||
# how to reach the author.
|
# how to reach the author.
|
||||||
#
|
#
|
||||||
# $Id: Makefile 1.11 2000/09/20 17:01:57 kls Exp $
|
# $Id: Makefile 1.12 2000/10/01 14:27:12 kls Exp $
|
||||||
|
|
||||||
DVBDIR = ../DVB
|
DVBDIR = ../DVB
|
||||||
|
|
||||||
INCLUDES = -I$(DVBDIR)/driver
|
INCLUDES = -I$(DVBDIR)/driver
|
||||||
OBJS = config.o dvbapi.o eit.o interface.o menu.o osd.o recording.o remote.o svdrp.o tools.o vdr.o videodir.o
|
OBJS = config.o dvbapi.o dvbosd.o eit.o font.o interface.o menu.o osd.o\
|
||||||
|
recording.o remote.o svdrp.o tools.o vdr.o videodir.o
|
||||||
|
|
||||||
|
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
|
||||||
|
|
||||||
ifndef REMOTE
|
ifndef REMOTE
|
||||||
REMOTE = KBD
|
REMOTE = KBD
|
||||||
@ -21,26 +24,52 @@ ifdef DEBUG_OSD
|
|||||||
DEFINES += -DDEBUG_OSD
|
DEFINES += -DDEBUG_OSD
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
all: vdr
|
||||||
|
font: genfontfile fontosd.c
|
||||||
|
@echo "font file created."
|
||||||
|
|
||||||
|
# Implicit rules:
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
g++ -g -O2 -Wall -m486 -c $(DEFINES) $(INCLUDES) $<
|
g++ -g -O2 -Wall -m486 -c $(DEFINES) $(INCLUDES) $<
|
||||||
|
|
||||||
all: vdr
|
# Dependencies:
|
||||||
|
|
||||||
config.o : config.c config.h dvbapi.h eit.h interface.h svdrp.h tools.h
|
config.o : config.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h svdrp.h tools.h
|
||||||
dvbapi.o : dvbapi.c config.h dvbapi.h interface.h svdrp.h tools.h videodir.h
|
dvbapi.o : dvbapi.c config.h dvbapi.h dvbosd.h font.h interface.h svdrp.h tools.h videodir.h
|
||||||
|
dvbosd.o : dvbosd.c dvbosd.h font.h tools.h
|
||||||
eit.o : eit.c eit.h tools.h
|
eit.o : eit.c eit.h tools.h
|
||||||
interface.o: interface.c config.h dvbapi.h eit.h interface.h remote.h svdrp.h tools.h
|
font.o : font.c font.h fontosd.c tools.h
|
||||||
menu.o : menu.c config.h dvbapi.h interface.h menu.h osd.h recording.h svdrp.h tools.h
|
interface.o: interface.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h tools.h
|
||||||
osd.o : osd.c config.h dvbapi.h interface.h osd.h svdrp.h tools.h
|
menu.o : menu.c config.h dvbapi.h dvbosd.h font.h interface.h menu.h osd.h recording.h svdrp.h tools.h
|
||||||
recording.o: recording.c config.h dvbapi.h interface.h recording.h svdrp.h tools.h videodir.h
|
osd.o : osd.c config.h dvbapi.h dvbosd.h font.h interface.h osd.h svdrp.h tools.h
|
||||||
remote.o : remote.c config.h dvbapi.h remote.h tools.h
|
recording.o: recording.c config.h dvbapi.h dvbosd.h font.h interface.h recording.h svdrp.h tools.h videodir.h
|
||||||
svdrp.o : svdrp.c config.h dvbapi.h interface.h svdrp.h tools.h
|
remote.o : remote.c config.h dvbapi.h dvbosd.h font.h remote.h tools.h
|
||||||
|
svdrp.o : svdrp.c config.h dvbapi.h dvbosd.h font.h interface.h svdrp.h tools.h
|
||||||
tools.o : tools.c tools.h
|
tools.o : tools.c tools.h
|
||||||
vdr.o : vdr.c config.h dvbapi.h interface.h menu.h osd.h recording.h svdrp.h tools.h videodir.h
|
vdr.o : vdr.c config.h dvbapi.h dvbosd.h font.h interface.h menu.h osd.h recording.h svdrp.h tools.h videodir.h
|
||||||
videodir.o : videodir.c tools.h videodir.h
|
videodir.o : videodir.c tools.h videodir.h
|
||||||
|
|
||||||
|
# The main program:
|
||||||
|
|
||||||
vdr: $(OBJS)
|
vdr: $(OBJS)
|
||||||
g++ -g -O2 $(OBJS) -lncurses -ljpeg -o vdr
|
g++ -g -O2 $(OBJS) -lncurses -ljpeg -o vdr
|
||||||
|
|
||||||
|
# The font file:
|
||||||
|
|
||||||
|
fontosd.c:
|
||||||
|
genfontfile "cFont::tPixelData FontOsd" $(OSDFONT) > $@
|
||||||
|
|
||||||
|
# The font file generator:
|
||||||
|
|
||||||
|
genfontfile.o: genfontfile.c
|
||||||
|
gcc -O2 -c $<
|
||||||
|
genfontfile: genfontfile.o
|
||||||
|
gcc -o $@ -L/usr/X11R6/lib $< -lX11
|
||||||
|
|
||||||
|
# Housekeeping:
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm $(OBJS) vdr
|
-rm -f $(OBJS) vdr genfontfile genfontfile.o
|
||||||
|
CLEAN: clean
|
||||||
|
-rm -f fontosd.c
|
||||||
|
4
config.h
4
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.h 1.21 2000/09/17 09:08:13 kls Exp $
|
* $Id: config.h 1.22 2000/10/01 14:14:18 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
@ -17,7 +17,7 @@
|
|||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define VDRVERSION "0.64"
|
#define VDRVERSION "0.65"
|
||||||
|
|
||||||
#define MaxBuffer 10000
|
#define MaxBuffer 10000
|
||||||
|
|
||||||
|
33
dvbapi.c
33
dvbapi.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbapi.c 1.27 2000/09/17 12:45:55 kls Exp $
|
* $Id: dvbapi.c 1.28 2000/10/03 10:13:51 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
@ -19,6 +19,7 @@ extern "C" {
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "dvbapi.h"
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "videodir.h"
|
#include "videodir.h"
|
||||||
@ -1087,6 +1088,8 @@ cDvbApi::cDvbApi(const char *FileName)
|
|||||||
start_color();
|
start_color();
|
||||||
leaveok(stdscr, true);
|
leaveok(stdscr, true);
|
||||||
window = NULL;
|
window = NULL;
|
||||||
|
#else
|
||||||
|
osd = NULL;
|
||||||
#endif
|
#endif
|
||||||
lastProgress = lastTotal = -1;
|
lastProgress = lastTotal = -1;
|
||||||
replayTitle = NULL;
|
replayTitle = NULL;
|
||||||
@ -1488,8 +1491,9 @@ void cDvbApi::Open(int w, int h)
|
|||||||
d *= lineHeight;
|
d *= lineHeight;
|
||||||
int x = (720 - MenuColumns * charWidth) / 2; //TODO PAL vs. NTSC???
|
int x = (720 - MenuColumns * charWidth) / 2; //TODO PAL vs. NTSC???
|
||||||
int y = (576 - MenuLines * lineHeight) / 2 + d;
|
int y = (576 - MenuLines * lineHeight) / 2 + d;
|
||||||
Cmd(OSD_Open, 4, x, y, x + w - 1, y + h - 1);
|
osd = new cDvbOsd(videoDev, x, y, x + w - 1, y + h - 1, 4);
|
||||||
#define SETCOLOR(n, r, g, b, o) Cmd(OSD_SetColor, n, r, g, b, o)
|
#define SETCOLOR(n, r, g, b, o) Cmd(OSD_SetColor, n, r, g, b, o)
|
||||||
|
SETCOLOR(clrTransparent, 0x00, 0x00, 0x00, 0);
|
||||||
#endif
|
#endif
|
||||||
SETCOLOR(clrBackground, 0x00, 0x00, 0x00, 127); // background 50% gray
|
SETCOLOR(clrBackground, 0x00, 0x00, 0x00, 127); // background 50% gray
|
||||||
SETCOLOR(clrBlack, 0x00, 0x00, 0x00, 255);
|
SETCOLOR(clrBlack, 0x00, 0x00, 0x00, 255);
|
||||||
@ -1512,7 +1516,8 @@ void cDvbApi::Close(void)
|
|||||||
window = 0;
|
window = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Cmd(OSD_Close);
|
delete osd;
|
||||||
|
osd = NULL;
|
||||||
#endif
|
#endif
|
||||||
lastProgress = lastTotal = -1;
|
lastProgress = lastTotal = -1;
|
||||||
}
|
}
|
||||||
@ -1523,7 +1528,7 @@ void cDvbApi::Clear(void)
|
|||||||
SetColor(clrBackground, clrBackground);
|
SetColor(clrBackground, clrBackground);
|
||||||
Fill(0, 0, cols, rows, clrBackground);
|
Fill(0, 0, cols, rows, clrBackground);
|
||||||
#else
|
#else
|
||||||
Cmd(OSD_Clear);
|
osd->Clear();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1539,7 +1544,7 @@ void cDvbApi::Fill(int x, int y, int w, int h, eDvbColor color)
|
|||||||
}
|
}
|
||||||
wsyncup(window); // shouldn't be necessary because of 'syncok()', but w/o it doesn't work
|
wsyncup(window); // shouldn't be necessary because of 'syncok()', but w/o it doesn't work
|
||||||
#else
|
#else
|
||||||
Cmd(OSD_FillBlock, color, x * charWidth, y * lineHeight, (x + w) * charWidth - 1, (y + h) * lineHeight - 1);
|
osd->Fill(x * charWidth, y * lineHeight, (x + w) * charWidth - 1, (y + h) * lineHeight - 1, color);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1557,7 +1562,15 @@ void cDvbApi::Text(int x, int y, const char *s, eDvbColor colorFg, eDvbColor col
|
|||||||
wmove(window, y, x); // ncurses wants 'y' before 'x'!
|
wmove(window, y, x); // ncurses wants 'y' before 'x'!
|
||||||
waddstr(window, s);
|
waddstr(window, s);
|
||||||
#else
|
#else
|
||||||
Cmd(OSD_Text, (int(colorBg) << 16) | colorFg, x * charWidth, y * lineHeight, 1, 0, s);
|
osd->Text(x * charWidth, y * lineHeight, s, colorFg, colorBg);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDvbApi::Flush(void)
|
||||||
|
{
|
||||||
|
#ifndef DEBUG_OSD
|
||||||
|
if (osd)
|
||||||
|
osd->Flush();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1567,11 +1580,13 @@ bool cDvbApi::ShowProgress(bool Initial)
|
|||||||
|
|
||||||
if (GetIndex(&Current, &Total)) {
|
if (GetIndex(&Current, &Total)) {
|
||||||
if (Initial) {
|
if (Initial) {
|
||||||
|
Clear();
|
||||||
if (replayTitle)
|
if (replayTitle)
|
||||||
Text(0, 0, replayTitle);
|
Text(0, 0, replayTitle);
|
||||||
}
|
}
|
||||||
if (Total != lastTotal)
|
if (Total != lastTotal)
|
||||||
Text(-7, 2, cIndexFile::Str(Total));
|
Text(-7, 2, cIndexFile::Str(Total));
|
||||||
|
Flush();
|
||||||
#ifdef DEBUG_OSD
|
#ifdef DEBUG_OSD
|
||||||
int p = cols * Current / Total;
|
int p = cols * Current / Total;
|
||||||
Fill(0, 1, p, 1, clrGreen);
|
Fill(0, 1, p, 1, clrGreen);
|
||||||
@ -1597,12 +1612,14 @@ bool cDvbApi::ShowProgress(bool Initial)
|
|||||||
color = clrWhite;
|
color = clrWhite;
|
||||||
}
|
}
|
||||||
if (lastProgress < 0)
|
if (lastProgress < 0)
|
||||||
Cmd(OSD_FillBlock, clrWhite, 0, y1, w - 1, y2);
|
osd->Fill(0, y1, w - 1, y2, clrWhite);
|
||||||
Cmd(OSD_FillBlock, color, x1, y1, x2, y2);
|
osd->Fill(x1, y1, x2, y2, color);
|
||||||
lastProgress = p;
|
lastProgress = p;
|
||||||
}
|
}
|
||||||
|
Flush();
|
||||||
#endif
|
#endif
|
||||||
Text(0, 2, cIndexFile::Str(Current));
|
Text(0, 2, cIndexFile::Str(Current));
|
||||||
|
Flush();
|
||||||
lastTotal = Total;
|
lastTotal = Total;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
22
dvbapi.h
22
dvbapi.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbapi.h 1.16 2000/09/17 12:15:05 kls Exp $
|
* $Id: dvbapi.h 1.17 2000/10/01 14:28:49 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBAPI_H
|
#ifndef __DVBAPI_H
|
||||||
@ -20,6 +20,7 @@ typedef unsigned char __u8;
|
|||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dvb.h>
|
#include <dvb.h>
|
||||||
|
#include "dvbosd.h"
|
||||||
|
|
||||||
// Overlay facilities
|
// Overlay facilities
|
||||||
#define MAXCLIPRECTS 100
|
#define MAXCLIPRECTS 100
|
||||||
@ -30,22 +31,6 @@ typedef struct CRect {
|
|||||||
#define MenuLines 15
|
#define MenuLines 15
|
||||||
#define MenuColumns 40
|
#define MenuColumns 40
|
||||||
|
|
||||||
enum eDvbColor { clrBackground,
|
|
||||||
#ifndef DEBUG_OSD
|
|
||||||
clrOBSOLETE, //FIXME apparently color '1' can't be used as FgColor with e.g. clrRed as BgColor???
|
|
||||||
clrBlack,
|
|
||||||
#else
|
|
||||||
clrBlack = clrBackground,
|
|
||||||
#endif
|
|
||||||
clrRed,
|
|
||||||
clrGreen,
|
|
||||||
clrYellow,
|
|
||||||
clrBlue,
|
|
||||||
clrMagenta,
|
|
||||||
clrCyan,
|
|
||||||
clrWhite,
|
|
||||||
};
|
|
||||||
|
|
||||||
class cDvbApi {
|
class cDvbApi {
|
||||||
private:
|
private:
|
||||||
int videoDev;
|
int videoDev;
|
||||||
@ -106,6 +91,8 @@ private:
|
|||||||
enum { MaxColorPairs = 16 };
|
enum { MaxColorPairs = 16 };
|
||||||
int colorPairs[MaxColorPairs];
|
int colorPairs[MaxColorPairs];
|
||||||
void SetColor(eDvbColor colorFg, eDvbColor colorBg = clrBackground);
|
void SetColor(eDvbColor colorFg, eDvbColor colorBg = clrBackground);
|
||||||
|
#else
|
||||||
|
cDvbOsd *osd;
|
||||||
#endif
|
#endif
|
||||||
int cols, rows;
|
int cols, rows;
|
||||||
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
||||||
@ -116,6 +103,7 @@ public:
|
|||||||
void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground);
|
void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground);
|
||||||
void ClrEol(int x, int y, eDvbColor color = clrBackground);
|
void ClrEol(int x, int y, eDvbColor color = clrBackground);
|
||||||
void Text(int x, int y, const char *s, eDvbColor colorFg = clrWhite, eDvbColor colorBg = clrBackground);
|
void Text(int x, int y, const char *s, eDvbColor colorFg = clrWhite, eDvbColor colorBg = clrBackground);
|
||||||
|
void Flush(void);
|
||||||
|
|
||||||
// Progress Display facilities
|
// Progress Display facilities
|
||||||
|
|
||||||
|
175
dvbosd.c
Normal file
175
dvbosd.c
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* dvbosd.c: Interface to the DVB On Screen Display
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: dvbosd.c 1.1 2000/10/03 10:10:28 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dvbosd.h"
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/unistd.h>
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
// --- cBitmap ---------------------------------------------------------------
|
||||||
|
|
||||||
|
cBitmap::cBitmap(int Width, int Height)
|
||||||
|
{
|
||||||
|
width = Width;
|
||||||
|
height = Height;
|
||||||
|
bitmap = NULL;
|
||||||
|
font = NULL;
|
||||||
|
if (width > 0 && height > 0) {
|
||||||
|
bitmap = new char[width * height];
|
||||||
|
if (bitmap) {
|
||||||
|
Clean();
|
||||||
|
memset(bitmap, clrTransparent, width * height);
|
||||||
|
SetFont(fontOsd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR: can't allocate bitmap!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR: illegal bitmap parameters (%d, %d)!", width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
cBitmap::~cBitmap()
|
||||||
|
{
|
||||||
|
delete font;
|
||||||
|
delete bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cBitmap::SetFont(eDvbFont Font)
|
||||||
|
{
|
||||||
|
delete font;
|
||||||
|
font = new cFont(Font);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cBitmap::Dirty(void)
|
||||||
|
{
|
||||||
|
return dirtyX2 >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cBitmap::Clean(void)
|
||||||
|
{
|
||||||
|
dirtyX1 = width;
|
||||||
|
dirtyY1 = height;
|
||||||
|
dirtyX2 = -1;
|
||||||
|
dirtyY2 = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cBitmap::SetPixel(int x, int y, eDvbColor Color)
|
||||||
|
{
|
||||||
|
if (bitmap) {
|
||||||
|
if (0 <= x && x < width && 0 <= y && y < height) {
|
||||||
|
if (bitmap[width * y + x] != Color) {
|
||||||
|
bitmap[width * y + x] = Color;
|
||||||
|
if (dirtyX1 > x) dirtyX1 = x;
|
||||||
|
if (dirtyY1 > y) dirtyY1 = y;
|
||||||
|
if (dirtyX2 < x) dirtyX2 = x;
|
||||||
|
if (dirtyY2 < y) dirtyY2 = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
|
||||||
|
{
|
||||||
|
if (bitmap) {
|
||||||
|
int h = font->Height(s);
|
||||||
|
while (s && *s) {
|
||||||
|
const cFont::tCharData *CharData = font->CharData(*s++);
|
||||||
|
for (int row = 0; row < h; row++) {
|
||||||
|
cFont::tPixelData PixelData = CharData->lines[row];
|
||||||
|
for (int col = CharData->width; col-- > 0; ) {
|
||||||
|
SetPixel(x + col, y + row, (PixelData & 1) ? ColorFg : ColorBg);
|
||||||
|
PixelData >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x += CharData->width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cBitmap::Fill(int x1, int y1, int x2, int y2, eDvbColor Color)
|
||||||
|
{
|
||||||
|
if (bitmap) {
|
||||||
|
for (int y = y1; y <= y2; y++)
|
||||||
|
for (int x = x1; x <= x2; x++)
|
||||||
|
SetPixel(x, y, Color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cBitmap::Clear(void)
|
||||||
|
{
|
||||||
|
Fill(0, 0, width - 1, height - 1, clrBackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cDvbOsd ---------------------------------------------------------------
|
||||||
|
|
||||||
|
cDvbOsd::cDvbOsd(int VideoDev, int x1, int y1, int x2, int y2, int Bpp)
|
||||||
|
:cBitmap(x2 - x1 + 1, y2 - y1 + 1)
|
||||||
|
{
|
||||||
|
videoDev = VideoDev;
|
||||||
|
if (videoDev >= 0)
|
||||||
|
Cmd(OSD_Open, Bpp, x1, y1, x2, y2);
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR: illegal video device handle (%d)!", videoDev);
|
||||||
|
}
|
||||||
|
|
||||||
|
cDvbOsd::~cDvbOsd()
|
||||||
|
{
|
||||||
|
if (videoDev >= 0)
|
||||||
|
Cmd(OSD_Close);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data)
|
||||||
|
{
|
||||||
|
if (videoDev >= 0) {
|
||||||
|
struct drawcmd dc;
|
||||||
|
dc.cmd = cmd;
|
||||||
|
dc.color = color;
|
||||||
|
dc.x0 = x0;
|
||||||
|
dc.y0 = y0;
|
||||||
|
dc.x1 = x1;
|
||||||
|
dc.y1 = y1;
|
||||||
|
dc.data = (void *)data;
|
||||||
|
ioctl(videoDev, VIDIOCSOSDCOMMAND, &dc);
|
||||||
|
usleep(10); // XXX Workaround for a driver bug (cInterface::DisplayChannel() displayed texts at wrong places
|
||||||
|
// XXX and sometimes the OSD was no longer displayed).
|
||||||
|
// XXX Increase the value if the problem still persists on your particular system.
|
||||||
|
// TODO Check if this is still necessary with driver versions after 0.7.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDvbOsd::Flush(void)
|
||||||
|
{
|
||||||
|
if (Dirty()) {
|
||||||
|
//XXX Workaround: apparently the bitmap sent to the driver always has to be a multiple
|
||||||
|
//XXX of 8 bits wide, and (dx * dy) also has to be a multiple of 8.
|
||||||
|
//TODO Fix driver (should be able to handle any size bitmaps!)
|
||||||
|
while ((dirtyX1 > 0 || dirtyX2 < width - 1) && ((dirtyX2 - dirtyX1) & 7) != 7) {
|
||||||
|
if (dirtyX2 < width - 1)
|
||||||
|
dirtyX2++;
|
||||||
|
else if (dirtyX1 > 0)
|
||||||
|
dirtyX1--;
|
||||||
|
}
|
||||||
|
while ((dirtyY1 > 0 || dirtyY2 < height - 1) && (((dirtyX2 - dirtyX1 + 1) * (dirtyY2 - dirtyY1 + 1) / 2) & 7) != 0) {
|
||||||
|
if (dirtyY2 < height - 1)
|
||||||
|
dirtyY2++;
|
||||||
|
else if (dirtyY1 > 0)
|
||||||
|
dirtyY1--;
|
||||||
|
}
|
||||||
|
while ((dirtyX1 > 0 || dirtyX2 < width - 1) && (((dirtyX2 - dirtyX1 + 1) * (dirtyY2 - dirtyY1 + 1) / 2) & 7) != 0) {
|
||||||
|
if (dirtyX2 < width - 1)
|
||||||
|
dirtyX2++;
|
||||||
|
else if (dirtyX1 > 0)
|
||||||
|
dirtyX1--;
|
||||||
|
}
|
||||||
|
Cmd(OSD_SetBlock, width, dirtyX1, dirtyY1, dirtyX2, dirtyY2, &bitmap[dirtyY1 * width + dirtyX1]);
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
74
dvbosd.h
Normal file
74
dvbosd.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* dvbosd.h: Interface to the DVB On Screen Display
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: dvbosd.h 1.1 2000/10/01 15:00:00 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DVBOSD_H
|
||||||
|
#define __DVBOSD_H
|
||||||
|
|
||||||
|
// FIXME: these should be defined in ../DVB/driver/dvb.h!!!
|
||||||
|
typedef unsigned int __u32;
|
||||||
|
typedef unsigned short __u16;
|
||||||
|
typedef unsigned char __u8;
|
||||||
|
|
||||||
|
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
||||||
|
#include <ncurses.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dvb.h>
|
||||||
|
#include "font.h"
|
||||||
|
|
||||||
|
enum eDvbColor {
|
||||||
|
#ifndef DEBUG_OSD
|
||||||
|
clrTransparent,
|
||||||
|
#endif
|
||||||
|
clrBackground,
|
||||||
|
#ifdef DEBUG_OSD
|
||||||
|
clrTransparent = clrBackground,
|
||||||
|
clrBlack = clrBackground,
|
||||||
|
#else
|
||||||
|
clrBlack,
|
||||||
|
#endif
|
||||||
|
clrRed,
|
||||||
|
clrGreen,
|
||||||
|
clrYellow,
|
||||||
|
clrBlue,
|
||||||
|
clrMagenta,
|
||||||
|
clrCyan,
|
||||||
|
clrWhite,
|
||||||
|
};
|
||||||
|
|
||||||
|
class cBitmap {
|
||||||
|
private:
|
||||||
|
cFont *font;
|
||||||
|
protected:
|
||||||
|
int width, height;
|
||||||
|
char *bitmap;
|
||||||
|
int dirtyX1, dirtyY1, dirtyX2, dirtyY2;
|
||||||
|
void Clean(void);
|
||||||
|
public:
|
||||||
|
cBitmap(int Width, int Height);
|
||||||
|
virtual ~cBitmap();
|
||||||
|
void SetFont(eDvbFont Font);
|
||||||
|
bool Dirty(void);
|
||||||
|
void SetPixel(int x, int y, eDvbColor Color);
|
||||||
|
void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground);
|
||||||
|
void Fill(int x1, int y1, int x2, int y2, eDvbColor Color);
|
||||||
|
void Clear(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class cDvbOsd : public cBitmap {
|
||||||
|
private:
|
||||||
|
int videoDev;
|
||||||
|
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
||||||
|
public:
|
||||||
|
cDvbOsd(int VideoDev, int x1, int y1, int x2, int y2, int Bpp);
|
||||||
|
~cDvbOsd();
|
||||||
|
void Flush(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__DVBOSD_H
|
6
eit.c
6
eit.c
@ -13,7 +13,7 @@
|
|||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* $Id: eit.c 1.3 2000/09/17 15:23:05 kls Exp $
|
* $Id: eit.c 1.4 2000/10/01 14:09:05 kls Exp $
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "eit.h"
|
#include "eit.h"
|
||||||
@ -424,9 +424,8 @@ int cEIT::SetProgramNumber(unsigned short pnr)
|
|||||||
evtRunning.bIsValid = false;
|
evtRunning.bIsValid = false;
|
||||||
evtNext.bIsValid = false;
|
evtNext.bIsValid = false;
|
||||||
uProgramNumber = pnr;
|
uProgramNumber = pnr;
|
||||||
return GetEIT();
|
|
||||||
}
|
}
|
||||||
return (IsValid() ? 1 : -1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** retrieves the string for the running title */
|
/** retrieves the string for the running title */
|
||||||
@ -503,6 +502,7 @@ char * cEIT::GetNextTime()
|
|||||||
/** */
|
/** */
|
||||||
bool cEIT::IsValid()
|
bool cEIT::IsValid()
|
||||||
{
|
{
|
||||||
|
GetEIT();
|
||||||
return (evtRunning.bIsValid && evtNext.bIsValid);
|
return (evtRunning.bIsValid && evtNext.bIsValid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
41
font.c
Normal file
41
font.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* font.c: Font handling for the DVB On Screen Display
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: font.c 1.1 2000/10/01 15:01:49 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "font.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
#include "fontosd.c"
|
||||||
|
|
||||||
|
cFont::cFont(eDvbFont Font)//XXX
|
||||||
|
{
|
||||||
|
switch (Font) {
|
||||||
|
default:
|
||||||
|
case fontOsd: for (int i = 0; i < NUMCHARS; i++)
|
||||||
|
data[i] = (tCharData *)&FontOsd[i < 32 ? 0 : i - 32];
|
||||||
|
break;
|
||||||
|
// TODO others...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cFont::Width(const char *s)
|
||||||
|
{
|
||||||
|
int w = 0;
|
||||||
|
while (s && *s)
|
||||||
|
w += Width(*s++);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cFont::Height(const char *s)
|
||||||
|
{
|
||||||
|
int h = 0;
|
||||||
|
if (s && *s)
|
||||||
|
h = Height(*s); // all characters have the same height!
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
40
font.h
Normal file
40
font.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* font.h: Font handling for the DVB On Screen Display
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: font.h 1.1 2000/10/01 15:00:35 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FONT_H
|
||||||
|
#define __FONT_H
|
||||||
|
|
||||||
|
enum eDvbFont {
|
||||||
|
fontOsd,
|
||||||
|
/* TODO as soon as we have the font files...
|
||||||
|
fontTtxSmall,
|
||||||
|
fontTtxLarge,
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
class cFont {
|
||||||
|
public:
|
||||||
|
enum { NUMCHARS = 256 };
|
||||||
|
typedef unsigned long tPixelData;
|
||||||
|
struct tCharData {
|
||||||
|
tPixelData width, height;
|
||||||
|
tPixelData lines[1];
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
const tCharData *data[NUMCHARS];
|
||||||
|
public:
|
||||||
|
cFont(eDvbFont Font);
|
||||||
|
int Width(unsigned char c) { return data[c]->width; }
|
||||||
|
int Width(const char *s);
|
||||||
|
int Height(unsigned char c) { return data[c]->height; }
|
||||||
|
int Height(const char *s);
|
||||||
|
const tCharData *CharData(unsigned char c) { return data[c]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__FONT_H
|
378
genfontfile.c
Normal file
378
genfontfile.c
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
/* Copyright (c) Mark J. Kilgard, 1997. */
|
||||||
|
|
||||||
|
/* This program is freely distributable without licensing fees and is
|
||||||
|
provided without guarantee or warrantee expressed or implied. This
|
||||||
|
program is -not- in the public domain. */
|
||||||
|
|
||||||
|
/* X compile line: cc -o gentexfont gentexfont.c -lX11 */
|
||||||
|
|
||||||
|
/* 2000-10-01: Stripped down the original code to get a simple bitmap C-code generator */
|
||||||
|
/* for use with the VDR project (see http://www.cadsoft.de/people/kls/vdr) */
|
||||||
|
/* Renamed the file 'genfontfile.c' since it no longer generates 'tex' data */
|
||||||
|
/* Klaus Schmidinger (kls@cadsoft.de) */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned short c; /* Potentially support 16-bit glyphs. */
|
||||||
|
unsigned char width;
|
||||||
|
unsigned char height;
|
||||||
|
signed char xoffset;
|
||||||
|
signed char yoffset;
|
||||||
|
signed char advance;
|
||||||
|
char dummy; /* Space holder for alignment reasons. */
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
} TexGlyphInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
short width;
|
||||||
|
short height;
|
||||||
|
short xoffset;
|
||||||
|
short yoffset;
|
||||||
|
short advance;
|
||||||
|
unsigned char *bitmap;
|
||||||
|
} PerGlyphInfo, *PerGlyphInfoPtr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int min_char;
|
||||||
|
int max_char;
|
||||||
|
int max_ascent;
|
||||||
|
int max_descent;
|
||||||
|
PerGlyphInfo glyph[1];
|
||||||
|
} FontInfo, *FontInfoPtr;
|
||||||
|
|
||||||
|
Display *dpy;
|
||||||
|
FontInfoPtr fontinfo;
|
||||||
|
|
||||||
|
/* #define REPORT_GLYPHS */
|
||||||
|
#ifdef REPORT_GLYPHS
|
||||||
|
#define DEBUG_GLYPH4(msg,a,b,c,d) printf(msg,a,b,c,d)
|
||||||
|
#define DEBUG_GLYPH(msg) printf(msg)
|
||||||
|
#else
|
||||||
|
#define DEBUG_GLYPH4(msg,a,b,c,d) { /* nothing */ }
|
||||||
|
#define DEBUG_GLYPH(msg) { /* nothing */ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_GLYPHS_PER_GRAB 512 /* this is big enough for 2^9 glyph
|
||||||
|
character sets */
|
||||||
|
|
||||||
|
FontInfoPtr
|
||||||
|
SuckGlyphsFromServer(Display * dpy, Font font)
|
||||||
|
{
|
||||||
|
Pixmap offscreen;
|
||||||
|
XFontStruct *fontinfo;
|
||||||
|
XImage *image;
|
||||||
|
GC xgc;
|
||||||
|
XGCValues values;
|
||||||
|
int numchars;
|
||||||
|
int width, height, pixwidth;
|
||||||
|
int i, j;
|
||||||
|
XCharStruct *charinfo;
|
||||||
|
XChar2b character;
|
||||||
|
unsigned char *bitmapData;
|
||||||
|
int x, y;
|
||||||
|
int spanLength;
|
||||||
|
int charWidth, charHeight, maxSpanLength;
|
||||||
|
int grabList[MAX_GLYPHS_PER_GRAB];
|
||||||
|
int glyphsPerGrab = MAX_GLYPHS_PER_GRAB;
|
||||||
|
int numToGrab, thisglyph;
|
||||||
|
FontInfoPtr myfontinfo;
|
||||||
|
|
||||||
|
fontinfo = XQueryFont(dpy, font);
|
||||||
|
if (!fontinfo)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
numchars = fontinfo->max_char_or_byte2 - fontinfo->min_char_or_byte2 + 1;
|
||||||
|
if (numchars < 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
myfontinfo = (FontInfoPtr) malloc(sizeof(FontInfo) + (numchars - 1) * sizeof(PerGlyphInfo));
|
||||||
|
if (!myfontinfo)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
myfontinfo->min_char = fontinfo->min_char_or_byte2;
|
||||||
|
myfontinfo->max_char = fontinfo->max_char_or_byte2;
|
||||||
|
myfontinfo->max_ascent = fontinfo->max_bounds.ascent;
|
||||||
|
myfontinfo->max_descent = fontinfo->max_bounds.descent;
|
||||||
|
|
||||||
|
width = fontinfo->max_bounds.rbearing - fontinfo->min_bounds.lbearing;
|
||||||
|
height = fontinfo->max_bounds.ascent + fontinfo->max_bounds.descent;
|
||||||
|
|
||||||
|
maxSpanLength = (width + 7) / 8;
|
||||||
|
/* Be careful determining the width of the pixmap; the X protocol allows
|
||||||
|
pixmaps of width 2^16-1 (unsigned short size) but drawing coordinates
|
||||||
|
max out at 2^15-1 (signed short size). If the width is too large, we
|
||||||
|
need to limit the glyphs per grab. */
|
||||||
|
if ((glyphsPerGrab * 8 * maxSpanLength) >= (1 << 15)) {
|
||||||
|
glyphsPerGrab = (1 << 15) / (8 * maxSpanLength);
|
||||||
|
}
|
||||||
|
pixwidth = glyphsPerGrab * 8 * maxSpanLength;
|
||||||
|
offscreen = XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)),
|
||||||
|
pixwidth, height, 1);
|
||||||
|
|
||||||
|
values.font = font;
|
||||||
|
values.background = 0;
|
||||||
|
values.foreground = 0;
|
||||||
|
xgc = XCreateGC(dpy, offscreen, GCFont | GCBackground | GCForeground, &values);
|
||||||
|
|
||||||
|
XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height);
|
||||||
|
XSetForeground(dpy, xgc, 1);
|
||||||
|
|
||||||
|
numToGrab = 0;
|
||||||
|
if (fontinfo->per_char == NULL) {
|
||||||
|
charinfo = &(fontinfo->min_bounds);
|
||||||
|
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||||
|
charHeight = charinfo->ascent + charinfo->descent;
|
||||||
|
spanLength = (charWidth + 7) / 8;
|
||||||
|
}
|
||||||
|
for (i = 0; i < numchars; i++) {
|
||||||
|
if (fontinfo->per_char != NULL) {
|
||||||
|
charinfo = &(fontinfo->per_char[i]);
|
||||||
|
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||||
|
charHeight = charinfo->ascent + charinfo->descent;
|
||||||
|
if (charWidth == 0 || charHeight == 0) {
|
||||||
|
/* Still must move raster pos even if empty character */
|
||||||
|
myfontinfo->glyph[i].width = 0;
|
||||||
|
myfontinfo->glyph[i].height = 0;
|
||||||
|
myfontinfo->glyph[i].xoffset = 0;
|
||||||
|
myfontinfo->glyph[i].yoffset = 0;
|
||||||
|
myfontinfo->glyph[i].advance = charinfo->width;
|
||||||
|
myfontinfo->glyph[i].bitmap = NULL;
|
||||||
|
goto PossiblyDoGrab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grabList[numToGrab] = i;
|
||||||
|
|
||||||
|
/* XXX is this right for large fonts? */
|
||||||
|
character.byte2 = (i + fontinfo->min_char_or_byte2) & 255;
|
||||||
|
character.byte1 = (i + fontinfo->min_char_or_byte2) >> 8;
|
||||||
|
|
||||||
|
/* XXX we could use XDrawImageString16 which would also paint the backing
|
||||||
|
|
||||||
|
rectangle but X server bugs in some scalable font rasterizers makes it
|
||||||
|
|
||||||
|
more effective to do XFillRectangles to clear the pixmap and
|
||||||
|
XDrawImage16 for the text. */
|
||||||
|
XDrawString16(dpy, offscreen, xgc,
|
||||||
|
-charinfo->lbearing + 8 * maxSpanLength * numToGrab,
|
||||||
|
charinfo->ascent, &character, 1);
|
||||||
|
|
||||||
|
numToGrab++;
|
||||||
|
|
||||||
|
PossiblyDoGrab:
|
||||||
|
|
||||||
|
if (numToGrab >= glyphsPerGrab || i == numchars - 1) {
|
||||||
|
image = XGetImage(dpy, offscreen,
|
||||||
|
0, 0, pixwidth, height, 1, XYPixmap);
|
||||||
|
for (j = 0; j < numToGrab; j++) {
|
||||||
|
thisglyph = grabList[j];
|
||||||
|
if (fontinfo->per_char != NULL) {
|
||||||
|
charinfo = &(fontinfo->per_char[thisglyph]);
|
||||||
|
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||||
|
charHeight = charinfo->ascent + charinfo->descent;
|
||||||
|
spanLength = (charWidth + 7) / 8;
|
||||||
|
}
|
||||||
|
bitmapData = calloc(height * spanLength, sizeof(char));
|
||||||
|
if (!bitmapData)
|
||||||
|
goto FreeFontAndReturn;
|
||||||
|
DEBUG_GLYPH4("index %d, glyph %d (%d by %d)\n",
|
||||||
|
j, thisglyph + fontinfo->min_char_or_byte2, charWidth, charHeight);
|
||||||
|
for (y = 0; y < charHeight; y++) {
|
||||||
|
for (x = 0; x < charWidth; x++) {
|
||||||
|
/* XXX The algorithm used to suck across the font ensures that
|
||||||
|
each glyph begins on a byte boundary. In theory this would
|
||||||
|
make it convienent to copy the glyph into a byte oriented
|
||||||
|
bitmap. We actually use the XGetPixel function to extract
|
||||||
|
each pixel from the image which is not that efficient. We
|
||||||
|
could either do tighter packing in the pixmap or more
|
||||||
|
efficient extraction from the image. Oh well. */
|
||||||
|
if (XGetPixel(image, j * maxSpanLength * 8 + x, charHeight - 1 - y)) {
|
||||||
|
DEBUG_GLYPH("x");
|
||||||
|
bitmapData[y * spanLength + x / 8] |= (1 << (x & 7));
|
||||||
|
} else {
|
||||||
|
DEBUG_GLYPH(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_GLYPH("\n");
|
||||||
|
}
|
||||||
|
myfontinfo->glyph[thisglyph].width = charWidth;
|
||||||
|
myfontinfo->glyph[thisglyph].height = charHeight;
|
||||||
|
myfontinfo->glyph[thisglyph].xoffset = charinfo->lbearing;
|
||||||
|
myfontinfo->glyph[thisglyph].yoffset = -charinfo->descent;
|
||||||
|
myfontinfo->glyph[thisglyph].advance = charinfo->width;
|
||||||
|
myfontinfo->glyph[thisglyph].bitmap = bitmapData;
|
||||||
|
}
|
||||||
|
XDestroyImage(image);
|
||||||
|
numToGrab = 0;
|
||||||
|
/* do we need to clear the offscreen pixmap to get more? */
|
||||||
|
if (i < numchars - 1) {
|
||||||
|
XSetForeground(dpy, xgc, 0);
|
||||||
|
XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height);
|
||||||
|
XSetForeground(dpy, xgc, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFreeGC(dpy, xgc);
|
||||||
|
XFreePixmap(dpy, offscreen);
|
||||||
|
return myfontinfo;
|
||||||
|
|
||||||
|
FreeFontAndReturn:
|
||||||
|
XDestroyImage(image);
|
||||||
|
XFreeGC(dpy, xgc);
|
||||||
|
XFreePixmap(dpy, offscreen);
|
||||||
|
for (j = i - 1; j >= 0; j--) {
|
||||||
|
if (myfontinfo->glyph[j].bitmap)
|
||||||
|
free(myfontinfo->glyph[j].bitmap);
|
||||||
|
}
|
||||||
|
free(myfontinfo);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
printGlyph(FontInfoPtr font, int c)
|
||||||
|
{
|
||||||
|
PerGlyphInfoPtr glyph;
|
||||||
|
unsigned char *bitmapData;
|
||||||
|
int width, height, spanLength;
|
||||||
|
int x, y, l;
|
||||||
|
char buf[1000], *b;
|
||||||
|
|
||||||
|
if (c < font->min_char || c > font->max_char) {
|
||||||
|
fprintf(stderr, "out of range glyph\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glyph = &font->glyph[c - font->min_char];
|
||||||
|
bitmapData = glyph->bitmap;
|
||||||
|
width = glyph->width;
|
||||||
|
spanLength = (width + 7) / 8;
|
||||||
|
height = glyph->height;
|
||||||
|
|
||||||
|
printf(" { // %d\n", c);
|
||||||
|
printf(" %d, %d,\n", glyph->advance, font->max_ascent + font->max_descent);
|
||||||
|
for (y = 0; y < font->max_ascent - glyph->yoffset - height; y++) {
|
||||||
|
printf(" 0x%08X, // ", 0);
|
||||||
|
for (x = 0; x < glyph->xoffset + width || x < glyph->advance; x++)
|
||||||
|
putchar('.');
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
for (y = height; y-- > 0;) {
|
||||||
|
l = 0;
|
||||||
|
b = buf;
|
||||||
|
for (x = 0; x < glyph->xoffset; x++)
|
||||||
|
*b++ = '.';
|
||||||
|
if (bitmapData) {
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
if (bitmapData[y * spanLength + x / 8] & (1 << (x & 7))) {
|
||||||
|
*b++ = '*';
|
||||||
|
l |= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*b++ = '.';
|
||||||
|
l <<= 1;
|
||||||
|
}
|
||||||
|
for (x = 0; x < glyph->advance - width - glyph->xoffset; x++) {
|
||||||
|
*b++ = '.';
|
||||||
|
l <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*b = 0;
|
||||||
|
printf(" 0x%08X, // %s\n", l, buf);
|
||||||
|
}
|
||||||
|
for (y = 0; y < font->max_descent + glyph->yoffset; y++) {
|
||||||
|
printf(" 0x%08X, // ", 0);
|
||||||
|
for (x = 0; x < glyph->xoffset + width || x < glyph->advance; x++)
|
||||||
|
putchar('.');
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
printf(" },\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getMetric(FontInfoPtr font, int c, TexGlyphInfo * tgi)
|
||||||
|
{
|
||||||
|
PerGlyphInfoPtr glyph;
|
||||||
|
unsigned char *bitmapData;
|
||||||
|
|
||||||
|
tgi->c = c;
|
||||||
|
if (c < font->min_char || c > font->max_char) {
|
||||||
|
tgi->width = 0;
|
||||||
|
tgi->height = 0;
|
||||||
|
tgi->xoffset = 0;
|
||||||
|
tgi->yoffset = 0;
|
||||||
|
tgi->dummy = 0;
|
||||||
|
tgi->advance = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glyph = &font->glyph[c - font->min_char];
|
||||||
|
bitmapData = glyph->bitmap;
|
||||||
|
if (bitmapData) {
|
||||||
|
tgi->width = glyph->width;
|
||||||
|
tgi->height = glyph->height;
|
||||||
|
tgi->xoffset = glyph->xoffset;
|
||||||
|
tgi->yoffset = glyph->yoffset;
|
||||||
|
} else {
|
||||||
|
tgi->width = 0;
|
||||||
|
tgi->height = 0;
|
||||||
|
tgi->xoffset = 0;
|
||||||
|
tgi->yoffset = 0;
|
||||||
|
}
|
||||||
|
tgi->dummy = 0;
|
||||||
|
tgi->advance = glyph->advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
TexGlyphInfo tgi;
|
||||||
|
int usageError = 0;
|
||||||
|
char *varname, *fontname;
|
||||||
|
XFontStruct *xfont;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argc == 3) {
|
||||||
|
varname = argv[1];
|
||||||
|
fontname = argv[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
usageError = 1;
|
||||||
|
|
||||||
|
if (usageError) {
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "usage: genfontfile variable_name X_font_name\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dpy = XOpenDisplay(NULL);
|
||||||
|
if (!dpy) {
|
||||||
|
fprintf(stderr, "could not open display\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* find an OpenGL-capable RGB visual with depth buffer */
|
||||||
|
xfont = XLoadQueryFont(dpy, fontname);
|
||||||
|
if (!xfont) {
|
||||||
|
fprintf(stderr, "could not get load X font: %s\n", fontname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fontinfo = SuckGlyphsFromServer(dpy, xfont->fid);
|
||||||
|
if (!fontinfo) {
|
||||||
|
fprintf(stderr, "could not get font glyphs\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s[][%d] = {\n", varname, fontinfo->max_ascent + fontinfo->max_descent + 2);
|
||||||
|
for (c = 32; c < 256; c++) {
|
||||||
|
getMetric(fontinfo, c, &tgi);
|
||||||
|
printGlyph(fontinfo, c);
|
||||||
|
}
|
||||||
|
printf(" };\n");
|
||||||
|
return 0;
|
||||||
|
}
|
29
interface.c
29
interface.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: interface.c 1.19 2000/09/19 17:41:23 kls Exp $
|
* $Id: interface.c 1.20 2000/10/02 16:23:53 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
@ -69,6 +69,8 @@ unsigned int cInterface::GetCh(bool Wait)
|
|||||||
|
|
||||||
eKeys cInterface::GetKey(bool Wait)
|
eKeys cInterface::GetKey(bool Wait)
|
||||||
{
|
{
|
||||||
|
if (open)
|
||||||
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
if (SVDRP)
|
if (SVDRP)
|
||||||
SVDRP->Process();
|
SVDRP->Process();
|
||||||
eKeys Key = keyFromWait != kNone ? keyFromWait : Keys.Get(GetCh(Wait));
|
eKeys Key = keyFromWait != kNone ? keyFromWait : Keys.Get(GetCh(Wait));
|
||||||
@ -84,6 +86,8 @@ void cInterface::PutKey(eKeys Key)
|
|||||||
eKeys cInterface::Wait(int Seconds, bool KeepChar)
|
eKeys cInterface::Wait(int Seconds, bool KeepChar)
|
||||||
{
|
{
|
||||||
eKeys Key = kNone;
|
eKeys Key = kNone;
|
||||||
|
if (open)
|
||||||
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
RcIo.Flush(500);
|
RcIo.Flush(500);
|
||||||
if (cFile::AnyFileReady(-1, Seconds * 1000))
|
if (cFile::AnyFileReady(-1, Seconds * 1000))
|
||||||
Key = GetKey();
|
Key = GetKey();
|
||||||
@ -326,15 +330,8 @@ eKeys cInterface::DisplayChannel(int Number, const char *Name, bool WithInfo)
|
|||||||
if (Number)
|
if (Number)
|
||||||
RcIo.Number(Number);
|
RcIo.Number(Number);
|
||||||
if (Name && !Recording()) {
|
if (Name && !Recording()) {
|
||||||
char *RunningTitle = "", *RunningSubtitle = "", *NextTitle = "", *NextSubtitle = "";
|
Open(MenuColumns, 5);
|
||||||
int Lines = 0;
|
cDvbApi::PrimaryDvbApi->Fill(0, 0, MenuColumns, 1, clrBackground);
|
||||||
if (Number && WithInfo && EIT.IsValid()) {
|
|
||||||
if (*(RunningTitle = EIT.GetRunningTitle())) Lines++;
|
|
||||||
if (*(RunningSubtitle = EIT.GetRunningSubtitle())) Lines++;
|
|
||||||
if (*(NextTitle = EIT.GetNextTitle())) Lines++;
|
|
||||||
if (*(NextSubtitle = EIT.GetNextSubtitle())) Lines++;
|
|
||||||
}
|
|
||||||
Open(MenuColumns, Lines + 1);
|
|
||||||
int BufSize = MenuColumns + 1;
|
int BufSize = MenuColumns + 1;
|
||||||
char buffer[BufSize];
|
char buffer[BufSize];
|
||||||
if (Number)
|
if (Number)
|
||||||
@ -346,10 +343,21 @@ eKeys cInterface::DisplayChannel(int Number, const char *Name, bool WithInfo)
|
|||||||
struct tm *now = localtime(&t);
|
struct tm *now = localtime(&t);
|
||||||
snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min);
|
snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min);
|
||||||
Write(-5, 0, buffer);
|
Write(-5, 0, buffer);
|
||||||
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
|
|
||||||
|
char *RunningTitle = "", *RunningSubtitle = "", *NextTitle = "", *NextSubtitle = "";
|
||||||
|
int Lines = 0;
|
||||||
|
if (Number && WithInfo && EIT.IsValid()) {
|
||||||
|
if (*(RunningTitle = EIT.GetRunningTitle())) Lines++;
|
||||||
|
if (*(RunningSubtitle = EIT.GetRunningSubtitle())) Lines++;
|
||||||
|
if (*(NextTitle = EIT.GetNextTitle())) Lines++;
|
||||||
|
if (*(NextSubtitle = EIT.GetNextSubtitle())) Lines++;
|
||||||
|
}
|
||||||
if (Lines > 0) {
|
if (Lines > 0) {
|
||||||
const int t = 6;
|
const int t = 6;
|
||||||
int w = MenuColumns - t;
|
int w = MenuColumns - t;
|
||||||
int l = 1;
|
int l = 1;
|
||||||
|
cDvbApi::PrimaryDvbApi->Fill(0, 1, MenuColumns, Lines, clrBackground);
|
||||||
if (*RunningTitle) {
|
if (*RunningTitle) {
|
||||||
Write(0, l, EIT.GetRunningTime(), clrYellow, clrBackground);
|
Write(0, l, EIT.GetRunningTime(), clrYellow, clrBackground);
|
||||||
snprintf(buffer, BufSize, "%.*s", w, RunningTitle); Write(t, l, buffer, clrCyan, clrBackground);
|
snprintf(buffer, BufSize, "%.*s", w, RunningTitle); Write(t, l, buffer, clrCyan, clrBackground);
|
||||||
@ -367,6 +375,7 @@ eKeys cInterface::DisplayChannel(int Number, const char *Name, bool WithInfo)
|
|||||||
if (*NextSubtitle) {
|
if (*NextSubtitle) {
|
||||||
snprintf(buffer, BufSize, "%.*s", w, NextSubtitle); Write(t, l, buffer, clrCyan, clrBackground);
|
snprintf(buffer, BufSize, "%.*s", w, NextSubtitle); Write(t, l, buffer, clrCyan, clrBackground);
|
||||||
}
|
}
|
||||||
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
}
|
}
|
||||||
eKeys Key = Wait(5, true);
|
eKeys Key = Wait(5, true);
|
||||||
if (Key == kOk)
|
if (Key == kOk)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* recording.h: Recording file handling
|
* recording.c: Recording file handling
|
||||||
*
|
*
|
||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.c 1.15 2000/07/29 14:08:17 kls Exp $
|
* $Id: recording.c 1.16 2000/10/03 10:33:40 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
3
tools.c
3
tools.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.c 1.19 2000/09/19 17:55:09 kls Exp $
|
* $Id: tools.c 1.20 2000/09/29 16:19:28 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -17,7 +17,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
3
tools.h
3
tools.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.h 1.15 2000/09/17 07:58:19 kls Exp $
|
* $Id: tools.h 1.16 2000/09/29 16:19:31 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -13,6 +13,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user