mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Version 0.02
- Fixed compilation with only DEBUG_REMOTE=1. - Menus now use colors. - Support for "Red", "Green", "Yellow", "Blue" buttons. - Channels and Timers can now be added, deleted and moved. - Basic record/play file handling support (no actual record/playback yet).
This commit is contained in:
		
							
								
								
									
										12
									
								
								HISTORY
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								HISTORY
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
Video Disk Recorder OSM Revision History
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
2000-02-19: Version 0.01 (Initial revision).
 | 
			
		||||
 | 
			
		||||
2000-03-11: Version 0.02
 | 
			
		||||
 | 
			
		||||
- Fixed compilation with only DEBUG_REMOTE=1.
 | 
			
		||||
- Menus now use colors.
 | 
			
		||||
- Support for "Red", "Green", "Yellow", "Blue" buttons.
 | 
			
		||||
- Channels and Timers can now be added, deleted and moved.
 | 
			
		||||
- Basic record/play file handling support (no actual record/playback yet).
 | 
			
		||||
							
								
								
									
										11
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Makefile
									
									
									
									
									
								
							@@ -4,9 +4,9 @@
 | 
			
		||||
# See the main source file 'osm.c' for copyright information and
 | 
			
		||||
# how to reach the author.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
# $Id: Makefile 1.2 2000/03/05 13:51:57 kls Exp $
 | 
			
		||||
 | 
			
		||||
OBJS = config.o dvbapi.o interface.o menu.o osd.o remote.o tools.o osm.o
 | 
			
		||||
OBJS = config.o dvbapi.o interface.o menu.o osd.o recording.o remote.o tools.o osm.o
 | 
			
		||||
 | 
			
		||||
ifdef DEBUG_REMOTE
 | 
			
		||||
DEFINES += -DDEBUG_REMOTE
 | 
			
		||||
@@ -24,9 +24,10 @@ all: osm
 | 
			
		||||
config.o   : config.c config.h dvbapi.h interface.h tools.h
 | 
			
		||||
dvbapi.o   : dvbapi.c config.h dvbapi.h interface.h tools.h
 | 
			
		||||
interface.o: interface.c config.h dvbapi.h interface.h remote.h tools.h
 | 
			
		||||
menu.o     : menu.c config.h dvbapi.h interface.h menu.h osd.h tools.h
 | 
			
		||||
osd.o      : osd.c config.h interface.h osd.h tools.h
 | 
			
		||||
osm.o      : osm.c config.h dvbapi.h interface.h menu.h osd.h tools.h
 | 
			
		||||
menu.o     : menu.c config.h dvbapi.h interface.h menu.h osd.h recording.h tools.h
 | 
			
		||||
osd.o      : osd.c config.h dvbapi.h interface.h osd.h tools.h
 | 
			
		||||
osm.o      : osm.c config.h dvbapi.h interface.h menu.h osd.h recording.h tools.h
 | 
			
		||||
recording.o: recording.c config.h dvbapi.h interface.h recording.h tools.h
 | 
			
		||||
remote.o   : remote.c remote.h tools.h
 | 
			
		||||
tools.o    : tools.c tools.h
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								README
									
									
									
									
									
								
							@@ -36,10 +36,34 @@ about that driver). For example, if the DVB driver was
 | 
			
		||||
extracted into the directory /home/kls/vdr/DVB, then this
 | 
			
		||||
package should be extracted into /home/kls/vdr/OSM.
 | 
			
		||||
 | 
			
		||||
In order for the menu colors to work correctly you may want
 | 
			
		||||
to replace the function RGB2YUV() in DVB/driver/dvb.c with
 | 
			
		||||
 | 
			
		||||
static u32 RGB2YUV(u16 R, u16 G, u16 B)
 | 
			
		||||
{
 | 
			
		||||
        u16 y, u, v;
 | 
			
		||||
        u16 Y, Cr, Cb;
 | 
			
		||||
 | 
			
		||||
        y = R * 77 + G * 150 + B * 29;  // Luma=0.299R+0.587G+0.114B 0..65535
 | 
			
		||||
        u = 2048+B * 8 -(y>>5);    // Cr 0..4095
 | 
			
		||||
        v = 2048+R * 8 -(y>>5);    // Cb 0..4095
 | 
			
		||||
 | 
			
		||||
        Y = y >> 8;
 | 
			
		||||
        Cb= u >> 4;
 | 
			
		||||
        Cr= v >> 4;
 | 
			
		||||
 | 
			
		||||
        return Cr|(Cb<<16)|(Y<<8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
(this may no longer be necessary with driver versions after 0.03c).
 | 
			
		||||
 | 
			
		||||
After extracting the package, change into the OSM directory
 | 
			
		||||
and type 'make'. This should produce an executable file
 | 
			
		||||
named 'osm', which can be run after the DVB driver has been
 | 
			
		||||
installed.
 | 
			
		||||
installed. There may be several warnings about "implicit declaration
 | 
			
		||||
of function `int asprintf(...)'" during the compilation, which I was
 | 
			
		||||
unable to avoid (anybody know how to avoid them?). Just ignore them,
 | 
			
		||||
the program will work, anyway.
 | 
			
		||||
 | 
			
		||||
There are two macros you can use to customize the 'osm' program
 | 
			
		||||
at compile time. Adding "DEBUG_REMOTE=1" to the 'make' call
 | 
			
		||||
@@ -75,10 +99,10 @@ this package contains the codes for the "d-box" remote control unit.
 | 
			
		||||
If you want to use a different remote control unit, simply delete
 | 
			
		||||
the file 'keys.conf' and restart the 'osm' program. The program will
 | 
			
		||||
then start a key learning session in which it first attempts to determine
 | 
			
		||||
the basic data tranfer mode and timing of your remote control unit,
 | 
			
		||||
the basic data transfer mode and timing of your remote control unit,
 | 
			
		||||
and then will ask you to press one key after the other so that it can
 | 
			
		||||
learn the various key codes. You will at least need to provide an "Up"
 | 
			
		||||
and a "Down" key, so that you can switch channels. The rest os the key
 | 
			
		||||
and a "Down" key, so that you can switch channels. The rest of the key
 | 
			
		||||
definitions is optional, but the more keys you define, the more you
 | 
			
		||||
will be able to navigate through the menus.
 | 
			
		||||
 | 
			
		||||
@@ -97,9 +121,6 @@ confirms any changes (or switches to a channel in the "Channels" menu).
 | 
			
		||||
The "Back" key goes back one level in the menu structure, discarding
 | 
			
		||||
any changes that might have been made in the current menu.
 | 
			
		||||
 | 
			
		||||
In the "Channels" menu, the current channel can be edited by pressing
 | 
			
		||||
the "Right" key.
 | 
			
		||||
 | 
			
		||||
In the "Timers" menu, the current timer can be enabled or disabled with
 | 
			
		||||
the "Right" or "Left" key, respectively (enabled timers are marked with ">").
 | 
			
		||||
"Ok" here opens the "Edit timer" menu.
 | 
			
		||||
@@ -110,6 +131,9 @@ character as in "[R]TL"), selecting the desired character position with
 | 
			
		||||
"Left" and "Right", and changing the character with the "Up" and "Down"
 | 
			
		||||
keys. "Ok" then confirms the changes.
 | 
			
		||||
 | 
			
		||||
The "Red", "Green", "Yellow" and "Blue" buttons have special meanings
 | 
			
		||||
in the various menus and are listed at the bottom of the on-screen-display.
 | 
			
		||||
 | 
			
		||||
At any point in the menu system, pressing the "Menu" key again will
 | 
			
		||||
immediately leave the menu system.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								TODO
									
									
									
									
									
								
							@@ -1,13 +1,12 @@
 | 
			
		||||
TODO list for the Video Disk Recorder project
 | 
			
		||||
---------------------------------------------
 | 
			
		||||
 | 
			
		||||
* Implement a way to add and delete channels and timers.
 | 
			
		||||
* Implement recording to disk and playback from disk.
 | 
			
		||||
* Implement disk file management (delete old/viewed files to make
 | 
			
		||||
  room for new recordings if necessary).
 | 
			
		||||
* Make it work with two DVB-S PCI cards to allow simultaneous
 | 
			
		||||
  recording of one programme, while replaying another programme
 | 
			
		||||
  (or maybe the same one, but time delayed).
 | 
			
		||||
  Maybe we can do this with only a single card, if the card
 | 
			
		||||
  driver/firmware allows simultaneuos record/playback?
 | 
			
		||||
* Implement "on-disk editing" to allow "cutting out" of certain
 | 
			
		||||
  scenes in order to archive them (or, reversely, cut out
 | 
			
		||||
  commercial breaks).
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ B1:12722:h:1:22000:601:602
 | 
			
		||||
ARD Online-Kanal:12722:h:1:22000:8191:701
 | 
			
		||||
Premiere World Promo:11798:h:1:27500:255:256
 | 
			
		||||
TV Niepokalanow:11876:h:1:27500:305:321
 | 
			
		||||
test card:11876:h:1:27500:306:322
 | 
			
		||||
test card:11798:h:1:27500:511:512
 | 
			
		||||
Mosaico:11934:v:1:27500:165:100
 | 
			
		||||
Andalucia TV:11934:v:1:27500:166:104
 | 
			
		||||
TVC Internacional:11934:v:1:27500:167:108
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										118
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								config.c
									
									
									
									
									
								
							@@ -4,37 +4,40 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: config.c 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: config.c 1.2 2000/03/05 16:14:27 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include "dvbapi.h"
 | 
			
		||||
#include "interface.h"
 | 
			
		||||
 | 
			
		||||
// -- cKeys ------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
 | 
			
		||||
                    { kUp,    "Up",    0 },
 | 
			
		||||
                    { kDown,  "Down",  0 },
 | 
			
		||||
                    { kMenu,  "Menu",  0 },
 | 
			
		||||
                    { kOk,    "Ok",    0 },
 | 
			
		||||
                    { kBack,  "Back",  0 },
 | 
			
		||||
                    { kLeft,  "Left",  0 },
 | 
			
		||||
                    { kRight, "Right", 0 },
 | 
			
		||||
                    { k0,     "0",     0 },
 | 
			
		||||
                    { k1,     "1",     0 },
 | 
			
		||||
                    { k2,     "2",     0 },
 | 
			
		||||
                    { k3,     "3",     0 },
 | 
			
		||||
                    { k4,     "4",     0 },
 | 
			
		||||
                    { k5,     "5",     0 },
 | 
			
		||||
                    { k6,     "6",     0 },
 | 
			
		||||
                    { k7,     "7",     0 },
 | 
			
		||||
                    { k8,     "8",     0 },
 | 
			
		||||
                    { k9,     "9",     0 },
 | 
			
		||||
                    { kNone,  "",      0 },
 | 
			
		||||
                    { kUp,     "Up",     0 },
 | 
			
		||||
                    { kDown,   "Down",   0 },
 | 
			
		||||
                    { kMenu,   "Menu",   0 },
 | 
			
		||||
                    { kOk,     "Ok",     0 },
 | 
			
		||||
                    { kBack,   "Back",   0 },
 | 
			
		||||
                    { kLeft,   "Left",   0 },
 | 
			
		||||
                    { kRight,  "Right",  0 },
 | 
			
		||||
                    { k0,      "0",      0 },
 | 
			
		||||
                    { k1,      "1",      0 },
 | 
			
		||||
                    { k2,      "2",      0 },
 | 
			
		||||
                    { k3,      "3",      0 },
 | 
			
		||||
                    { k4,      "4",      0 },
 | 
			
		||||
                    { k5,      "5",      0 },
 | 
			
		||||
                    { k6,      "6",      0 },
 | 
			
		||||
                    { k7,      "7",      0 },
 | 
			
		||||
                    { k8,      "8",      0 },
 | 
			
		||||
                    { k9,      "9",      0 },
 | 
			
		||||
                    { kRed,    "Red",    0 },
 | 
			
		||||
                    { kGreen,  "Green",  0 },
 | 
			
		||||
                    { kYellow, "Yellow", 0 },
 | 
			
		||||
                    { kBlue,   "Blue",   0 },
 | 
			
		||||
                    { kNone,   "",       0 },
 | 
			
		||||
                  };
 | 
			
		||||
 | 
			
		||||
cKeys::cKeys(void)
 | 
			
		||||
@@ -160,6 +163,17 @@ cChannel::cChannel(void)
 | 
			
		||||
  *name = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cChannel::cChannel(const cChannel *Channel)
 | 
			
		||||
{
 | 
			
		||||
  strcpy(name,   Channel ? Channel->name         : "Pro7");
 | 
			
		||||
  frequency    = Channel ? Channel->frequency    : 12480;
 | 
			
		||||
  polarization = Channel ? Channel->polarization : 'v';
 | 
			
		||||
  diseqc       = Channel ? Channel->diseqc       : 1;
 | 
			
		||||
  srate        = Channel ? Channel->srate        : 27500;
 | 
			
		||||
  vpid         = Channel ? Channel->vpid         : 255;
 | 
			
		||||
  apid         = Channel ? Channel->apid         : 256;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cChannel::Parse(char *s)
 | 
			
		||||
{
 | 
			
		||||
  char *buffer = NULL;
 | 
			
		||||
@@ -203,6 +217,17 @@ bool cChannel::SwitchTo(int i)
 | 
			
		||||
 | 
			
		||||
cTimer::cTimer(void)
 | 
			
		||||
{
 | 
			
		||||
  startTime = stopTime = 0;
 | 
			
		||||
  recording = false;
 | 
			
		||||
  active = 1;
 | 
			
		||||
  channel = CurrentChannel + 1;
 | 
			
		||||
  day = 1; //XXX today!
 | 
			
		||||
  start = 0; //XXX now!
 | 
			
		||||
  stop = 0; //XXX now + 2h!
 | 
			
		||||
//TODO VPS???
 | 
			
		||||
  quality = 'H';
 | 
			
		||||
  priority = 99;
 | 
			
		||||
  lifetime = 99;
 | 
			
		||||
  *file = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -211,6 +236,13 @@ int cTimer::TimeToInt(int t)
 | 
			
		||||
  return (t / 100 * 60 + t % 100) * 60;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
time_t cTimer::Day(time_t t)
 | 
			
		||||
{
 | 
			
		||||
  struct tm d = *localtime(&t);
 | 
			
		||||
  d.tm_hour = d.tm_min = d.tm_sec = 0;
 | 
			
		||||
  return mktime(&d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cTimer::ParseDay(char *s)
 | 
			
		||||
{
 | 
			
		||||
  char *tail;
 | 
			
		||||
@@ -270,13 +302,17 @@ bool cTimer::Save(FILE *f)
 | 
			
		||||
  return fprintf(f, "%d:%d:%s:%d:%d:%c:%d:%d:%s\n", active, channel, PrintDay(day), start, stop, quality, priority, lifetime, file) > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cTimer::IsSingleEvent(void)
 | 
			
		||||
{
 | 
			
		||||
  return (day & 0x80000000) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cTimer::Matches(void)
 | 
			
		||||
{
 | 
			
		||||
  if (active) {
 | 
			
		||||
     time_t t = time(NULL);
 | 
			
		||||
     struct tm *now = localtime(&t);
 | 
			
		||||
     int weekday = now->tm_wday == 0 ? 6 : now->tm_wday - 1; // we start with monday==0!
 | 
			
		||||
     int current = (now->tm_hour * 60 + now->tm_min) * 60 + now->tm_sec;
 | 
			
		||||
     struct tm now = *localtime(&t);
 | 
			
		||||
     int weekday = now.tm_wday == 0 ? 6 : now.tm_wday - 1; // we start with monday==0!
 | 
			
		||||
     int begin = TimeToInt(start);
 | 
			
		||||
     int end   = TimeToInt(stop);
 | 
			
		||||
     bool twoDays = (end < begin);
 | 
			
		||||
@@ -291,20 +327,44 @@ bool cTimer::Matches(void)
 | 
			
		||||
              yesterdayMatches = true;
 | 
			
		||||
           }
 | 
			
		||||
        }
 | 
			
		||||
     else if (day == now->tm_mday)
 | 
			
		||||
     else if (day == now.tm_mday)
 | 
			
		||||
        todayMatches = true;
 | 
			
		||||
     else if (twoDays) {
 | 
			
		||||
        t -= 86400;
 | 
			
		||||
        now = localtime(&t);
 | 
			
		||||
        if (day == now->tm_mday)
 | 
			
		||||
        time_t ty = t - SECSINDAY;
 | 
			
		||||
        if (day == localtime(&ty)->tm_mday)
 | 
			
		||||
           yesterdayMatches = true;
 | 
			
		||||
        }
 | 
			
		||||
     return (todayMatches && current >= begin && (current <= end || twoDays))
 | 
			
		||||
            || (twoDays && yesterdayMatches && current <= end);
 | 
			
		||||
     if (todayMatches || (twoDays && yesterdayMatches)) {
 | 
			
		||||
        startTime = Day(t - (yesterdayMatches ? SECSINDAY : 0)) + begin;
 | 
			
		||||
        stopTime  = startTime + (twoDays ? SECSINDAY - begin + end : end - begin);
 | 
			
		||||
        }
 | 
			
		||||
     else
 | 
			
		||||
        startTime = stopTime = 0;
 | 
			
		||||
     return startTime <= t && t <= stopTime;
 | 
			
		||||
     }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
time_t cTimer::StartTime(void)
 | 
			
		||||
{ 
 | 
			
		||||
  if (!startTime)
 | 
			
		||||
     Matches();
 | 
			
		||||
  return startTime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
time_t cTimer::StopTime(void)
 | 
			
		||||
{ 
 | 
			
		||||
  if (!stopTime)
 | 
			
		||||
     Matches();
 | 
			
		||||
  return stopTime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTimer::SetRecording(bool Recording)
 | 
			
		||||
{
 | 
			
		||||
  recording = Recording;
 | 
			
		||||
  isyslog(LOG_INFO, "timer %d %s", Index() + 1, recording ? "start" : "stop");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cTimer *cTimer::GetMatch(void)
 | 
			
		||||
{
 | 
			
		||||
  cTimer *t = (cTimer *)Timers.First();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								config.h
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: config.h 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: config.h 1.2 2000/03/05 14:58:23 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __CONFIG_H
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
 | 
			
		||||
#define MaxBuffer 1000
 | 
			
		||||
@@ -25,6 +26,10 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
 | 
			
		||||
             kLeft,
 | 
			
		||||
             kRight,
 | 
			
		||||
             k0, k1, k2, k3, k4, k5, k6, k7, k8, k9,
 | 
			
		||||
             kRed,
 | 
			
		||||
             kGreen,
 | 
			
		||||
             kYellow,
 | 
			
		||||
             kBlue,
 | 
			
		||||
             kNone
 | 
			
		||||
           };
 | 
			
		||||
 | 
			
		||||
@@ -60,6 +65,7 @@ public:
 | 
			
		||||
  int vpid;
 | 
			
		||||
  int apid;
 | 
			
		||||
  cChannel(void);
 | 
			
		||||
  cChannel(const cChannel *Channel);
 | 
			
		||||
  bool Parse(char *s);
 | 
			
		||||
  bool Save(FILE *f);
 | 
			
		||||
  bool Switch(void);
 | 
			
		||||
@@ -67,8 +73,11 @@ public:
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
class cTimer : public cListObject {
 | 
			
		||||
private:
 | 
			
		||||
  time_t startTime, stopTime;
 | 
			
		||||
public:
 | 
			
		||||
  enum { MaxFileName = 256 };
 | 
			
		||||
  bool recording;
 | 
			
		||||
  int active;
 | 
			
		||||
  int channel;
 | 
			
		||||
  int day;
 | 
			
		||||
@@ -82,9 +91,14 @@ public:
 | 
			
		||||
  cTimer(void);
 | 
			
		||||
  bool Parse(char *s);
 | 
			
		||||
  bool Save(FILE *f);
 | 
			
		||||
  bool IsSingleEvent(void);
 | 
			
		||||
  bool Matches(void);
 | 
			
		||||
  time_t StartTime(void);
 | 
			
		||||
  time_t StopTime(void);
 | 
			
		||||
  void SetRecording(bool Recording);
 | 
			
		||||
  static cTimer *GetMatch(void);
 | 
			
		||||
  static int TimeToInt(int t);
 | 
			
		||||
  static time_t Day(time_t t);
 | 
			
		||||
  static int ParseDay(char *s);
 | 
			
		||||
  static char *PrintDay(int d);
 | 
			
		||||
  };
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										168
									
								
								dvbapi.c
									
									
									
									
									
								
							
							
						
						
									
										168
									
								
								dvbapi.c
									
									
									
									
									
								
							@@ -4,20 +4,14 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: dvbapi.c 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: dvbapi.c 1.2 2000/03/11 10:39:09 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// FIXME: these should be defined in ../DVB/driver/dvb.h!!!
 | 
			
		||||
typedef unsigned int u32;
 | 
			
		||||
typedef unsigned short u16;
 | 
			
		||||
typedef unsigned char u8;
 | 
			
		||||
 | 
			
		||||
#include "dvbapi.h"
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include "../DVB/driver/dvb.h"
 | 
			
		||||
#include "interface.h"
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
 | 
			
		||||
@@ -60,6 +54,7 @@ bool DvbSetChannel(int FrequencyMHz, char Polarization, int Diseqc, int Srate, i
 | 
			
		||||
 | 
			
		||||
cDvbRecorder::cDvbRecorder(void)
 | 
			
		||||
{
 | 
			
		||||
  recording = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDvbRecorder::~cDvbRecorder()
 | 
			
		||||
@@ -67,18 +62,41 @@ cDvbRecorder::~cDvbRecorder()
 | 
			
		||||
  Stop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cDvbRecorder::Recording(void)
 | 
			
		||||
{
 | 
			
		||||
  return recording;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cDvbRecorder::Record(const char *FileName, char Quality)
 | 
			
		||||
{
 | 
			
		||||
  isyslog(LOG_INFO, "record %s (%c)", FileName, Quality);
 | 
			
		||||
  return true;
 | 
			
		||||
  if (MakeDirs(FileName)) {
 | 
			
		||||
     FILE *f = fopen(FileName, "a");
 | 
			
		||||
     if (f) {
 | 
			
		||||
        fprintf(f, "%s, %c\n", FileName, Quality);
 | 
			
		||||
        fclose(f);
 | 
			
		||||
        recording = true;
 | 
			
		||||
        // TODO
 | 
			
		||||
        Interface.Error("Recording not yet implemented!");
 | 
			
		||||
        return true;
 | 
			
		||||
        }
 | 
			
		||||
     else {
 | 
			
		||||
        Interface.Error("Can't write to file!");
 | 
			
		||||
        return false;
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  // TODO
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cDvbRecorder::Play(const char *FileName, int Frame)
 | 
			
		||||
{
 | 
			
		||||
  isyslog(LOG_INFO, "play %s (%d)", FileName, Frame);
 | 
			
		||||
  // TODO
 | 
			
		||||
  if (!recording) {
 | 
			
		||||
     isyslog(LOG_INFO, "play %s (%d)", FileName, Frame);
 | 
			
		||||
     // TODO
 | 
			
		||||
     Interface.Error("Playback not yet implemented!");
 | 
			
		||||
     return true;
 | 
			
		||||
     }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -106,6 +124,7 @@ bool cDvbRecorder::Pause(void)
 | 
			
		||||
void cDvbRecorder::Stop(void)
 | 
			
		||||
{
 | 
			
		||||
  isyslog(LOG_INFO, "stop");
 | 
			
		||||
  recording = false;
 | 
			
		||||
  // TODO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -116,9 +135,57 @@ int cDvbRecorder::Frame(void)
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------------------------------------------
 | 
			
		||||
// --- cDvbOsd ---------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
static void DvbOsdCmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, void *data = NULL)
 | 
			
		||||
cDvbOsd::cDvbOsd(void)
 | 
			
		||||
{
 | 
			
		||||
  cols = rows = 0;
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  memset(&colorPairs, 0, sizeof(colorPairs));
 | 
			
		||||
  initscr();
 | 
			
		||||
  start_color();
 | 
			
		||||
  keypad(stdscr, TRUE);
 | 
			
		||||
  nonl();
 | 
			
		||||
  cbreak();
 | 
			
		||||
  noecho();
 | 
			
		||||
  timeout(1000);
 | 
			
		||||
  leaveok(stdscr, TRUE);
 | 
			
		||||
  window = stdscr;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef DEBUG_REMOTE
 | 
			
		||||
  initscr();
 | 
			
		||||
  keypad(stdscr, TRUE);
 | 
			
		||||
  nonl();
 | 
			
		||||
  cbreak();
 | 
			
		||||
  noecho();
 | 
			
		||||
  timeout(1000);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDvbOsd::~cDvbOsd()
 | 
			
		||||
{
 | 
			
		||||
  Close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
void cDvbOsd::SetColor(eDvbColor colorFg, eDvbColor colorBg)
 | 
			
		||||
{
 | 
			
		||||
  int color = (colorBg << 16) | colorFg | 0x80000000;
 | 
			
		||||
  for (int i = 0; i < MaxColorPairs; i++) {
 | 
			
		||||
      if (!colorPairs[i]) {
 | 
			
		||||
         colorPairs[i] = color;
 | 
			
		||||
         init_pair(i + 1, colorFg, colorBg);
 | 
			
		||||
         wattrset(window, COLOR_PAIR(i + 1));
 | 
			
		||||
         break;
 | 
			
		||||
         }
 | 
			
		||||
      else if (color == colorPairs[i]) {
 | 
			
		||||
         wattrset(window, COLOR_PAIR(i + 1));
 | 
			
		||||
         break;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data)
 | 
			
		||||
{
 | 
			
		||||
  int v = open(VIDEODEVICE, O_RDWR);
 | 
			
		||||
 | 
			
		||||
@@ -130,37 +197,88 @@ static void DvbOsdCmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, in
 | 
			
		||||
     dc.y0    = y0;
 | 
			
		||||
     dc.x1    = x1;
 | 
			
		||||
     dc.y1    = y1;
 | 
			
		||||
     dc.data  = data;
 | 
			
		||||
     dc.data  = (void *)data;
 | 
			
		||||
     ioctl(v, VIDIOCSOSDCOMMAND, &dc);
 | 
			
		||||
     close(v);
 | 
			
		||||
     }
 | 
			
		||||
  else
 | 
			
		||||
     Interface.Error("can't open VIDEODEVICE");//XXX
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void DvbOsdOpen(int x, int y, int w, int h)
 | 
			
		||||
void cDvbOsd::Open(int w, int h)
 | 
			
		||||
{
 | 
			
		||||
  DvbOsdCmd(OSD_Open, 1, x, y, x + w - 1, y + h - 1);
 | 
			
		||||
  DvbOsdCmd(OSD_SetColor, 0,   0,   0,   0, 127); // background 50% gray
 | 
			
		||||
  DvbOsdCmd(OSD_SetColor, 1, 255, 255, 255, 255); // text white
 | 
			
		||||
  cols = w;
 | 
			
		||||
  rows = h;
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  //XXX size...
 | 
			
		||||
  #define B2C(b) (((b) * 1000) / 255)
 | 
			
		||||
  #define SETCOLOR(n, r, g, b, o) init_color(n, B2C(r), B2C(g), B2C(b))
 | 
			
		||||
#else
 | 
			
		||||
  w *= charWidth;
 | 
			
		||||
  h *= lineHeight;
 | 
			
		||||
  int x = (720 - w) / 2; //TODO PAL vs. NTSC???
 | 
			
		||||
  int y = (576 - h) / 2;
 | 
			
		||||
  Cmd(OSD_Open, 4, x, y, x + w - 1, y + h - 1);
 | 
			
		||||
  #define SETCOLOR(n, r, g, b, o) Cmd(OSD_SetColor, n, r, g, b, o)
 | 
			
		||||
#endif
 | 
			
		||||
  SETCOLOR(clrBackground, 0x00, 0x00, 0x00, 127); // background 50% gray
 | 
			
		||||
  SETCOLOR(clrBlack,      0x00, 0x00, 0x00, 255);
 | 
			
		||||
  SETCOLOR(clrRed,        0xFC, 0x14, 0x14, 255);
 | 
			
		||||
  SETCOLOR(clrGreen,      0x24, 0xFC, 0x24, 255);
 | 
			
		||||
  SETCOLOR(clrYellow,     0xFC, 0xC0, 0x24, 255);
 | 
			
		||||
  SETCOLOR(clrBlue,       0x00, 0x00, 0xFC, 255);
 | 
			
		||||
  SETCOLOR(clrCyan,       0x00, 0xFC, 0xFC, 255);
 | 
			
		||||
  SETCOLOR(clrMagenta,    0xB0, 0x00, 0xFC, 255);
 | 
			
		||||
  SETCOLOR(clrWhite,      0xFC, 0xFC, 0xFC, 255);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DvbOsdClose(void)
 | 
			
		||||
void cDvbOsd::Close(void)
 | 
			
		||||
{
 | 
			
		||||
  DvbOsdCmd(OSD_Close);
 | 
			
		||||
#ifndef DEBUG_OSD
 | 
			
		||||
  Cmd(OSD_Close);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DvbOsdClear(void)
 | 
			
		||||
void cDvbOsd::Clear(void)
 | 
			
		||||
{
 | 
			
		||||
  DvbOsdCmd(OSD_Clear);
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  SetColor(clrBackground, clrBackground);
 | 
			
		||||
  Fill(0, 0, cols, rows, clrBackground);
 | 
			
		||||
#else
 | 
			
		||||
  Cmd(OSD_Clear);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DvbOsdClrEol(int x, int y)
 | 
			
		||||
void cDvbOsd::Fill(int x, int y, int w, int h, eDvbColor color)
 | 
			
		||||
{
 | 
			
		||||
  DvbOsdCmd(OSD_FillBlock, 0, x, y * DvbOsdLineHeight, x + 490, (y + 1) * DvbOsdLineHeight);//XXX
 | 
			
		||||
  if (x < 0) x = cols + x;
 | 
			
		||||
  if (y < 0) y = rows + y;
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  SetColor(color, color);
 | 
			
		||||
  for (int r = 0; r < h; r++) {
 | 
			
		||||
      wmove(window, y + r, x); // ncurses wants 'y' before 'x'!
 | 
			
		||||
      whline(window, ' ', w);
 | 
			
		||||
      }
 | 
			
		||||
#else
 | 
			
		||||
  Cmd(OSD_FillBlock, color, x * charWidth, y * lineHeight, (x + w) * charWidth - 1, (y + h) * lineHeight - 1);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DvbOsdText(int x, int y, char *s)
 | 
			
		||||
void cDvbOsd::ClrEol(int x, int y, eDvbColor color)
 | 
			
		||||
{
 | 
			
		||||
  DvbOsdCmd(OSD_Text, 1, x, y, 1, 0, s);
 | 
			
		||||
  Fill(x, y, cols - x, 1, color);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cDvbOsd::Text(int x, int y, const char *s, eDvbColor colorFg, eDvbColor colorBg)
 | 
			
		||||
{
 | 
			
		||||
  if (x < 0) x = cols + x;
 | 
			
		||||
  if (y < 0) y = rows + y;
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  SetColor(colorFg, colorBg);
 | 
			
		||||
  wmove(window, y, x); // ncurses wants 'y' before 'x'!
 | 
			
		||||
  waddstr(window, s);
 | 
			
		||||
#else
 | 
			
		||||
  Cmd(OSD_Text, (int(colorBg) << 16) | colorFg, x * charWidth, y * lineHeight, 1, 0, s);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										70
									
								
								dvbapi.h
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								dvbapi.h
									
									
									
									
									
								
							@@ -4,23 +4,51 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: dvbapi.h 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: dvbapi.h 1.2 2000/03/06 19:47:20 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __DVBAPI_H
 | 
			
		||||
#define __DVBAPI_H
 | 
			
		||||
 | 
			
		||||
const int DvbOsdCharWidth  = 12; //XXX
 | 
			
		||||
const int DvbOsdLineHeight = 25;
 | 
			
		||||
// 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(DEBUG_REMOTE)
 | 
			
		||||
#include <ncurses.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "../DVB/driver/dvb.h"
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
               };
 | 
			
		||||
                  
 | 
			
		||||
extern const char *DvbQuality; // Low, Medium, High
 | 
			
		||||
 | 
			
		||||
bool DvbSetChannel(int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid);
 | 
			
		||||
 | 
			
		||||
class cDvbRecorder {
 | 
			
		||||
private:
 | 
			
		||||
  bool recording;
 | 
			
		||||
public:
 | 
			
		||||
  cDvbRecorder(void);
 | 
			
		||||
  ~cDvbRecorder();
 | 
			
		||||
  bool Recording(void);
 | 
			
		||||
       // Returns true if this recorder is currently recording, false if it
 | 
			
		||||
       // is playing back or does nothing.
 | 
			
		||||
  bool Record(const char *FileName, char Quality);
 | 
			
		||||
       // Starts recording the current channel into the given file, with the
 | 
			
		||||
       // given quality level. Any existing file will be overwritten.
 | 
			
		||||
@@ -30,8 +58,9 @@ public:
 | 
			
		||||
  bool Play(const char *FileName, int Frame = 0);
 | 
			
		||||
       // Starts playback of the given file, at the optional Frame (default
 | 
			
		||||
       // is the beginning of the file). If Frame is beyond the last recorded
 | 
			
		||||
       // frame in the file, or if it is negative, playback will be positioned
 | 
			
		||||
       // to the last frame in the file and will do an implicit Pause() there.
 | 
			
		||||
       // frame in the file (or if it is negative), playback will be positioned
 | 
			
		||||
       // to the last frame in the file (or the frame with the absolute value of
 | 
			
		||||
       // Frame) and will do an implicit Pause() there.
 | 
			
		||||
       // If there is already a playback session active, it will be stopped
 | 
			
		||||
       // and the new file or frame (which may be in the same file) will
 | 
			
		||||
       // be played back.
 | 
			
		||||
@@ -56,10 +85,29 @@ public:
 | 
			
		||||
       // The very first frame has the number 1.
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
void DvbOsdOpen(int x, int y, int w, int h);
 | 
			
		||||
void DvbOsdClose(void);
 | 
			
		||||
void DvbOsdClear(void);
 | 
			
		||||
void DvbOsdClrEol(int x, int y);
 | 
			
		||||
void DvbOsdText(int x, int y, char *s);
 | 
			
		||||
 | 
			
		||||
class cDvbOsd {
 | 
			
		||||
private:
 | 
			
		||||
  enum { charWidth  = 12, // average character width
 | 
			
		||||
         lineHeight = 27  // smallest text height
 | 
			
		||||
       };
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  WINDOW *window;
 | 
			
		||||
  enum { MaxColorPairs = 16 };
 | 
			
		||||
  int colorPairs[MaxColorPairs];
 | 
			
		||||
  void SetColor(eDvbColor colorFg, eDvbColor colorBg = clrBackground);
 | 
			
		||||
#else
 | 
			
		||||
  void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
 | 
			
		||||
#endif
 | 
			
		||||
  int cols, rows;
 | 
			
		||||
public:
 | 
			
		||||
  cDvbOsd(void);
 | 
			
		||||
  ~cDvbOsd();
 | 
			
		||||
  void Open(int w, int h);
 | 
			
		||||
  void Close(void);
 | 
			
		||||
  void Clear(void);
 | 
			
		||||
  void Fill(int x, int y, int w, int h, 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);
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
#endif //__DVBAPI_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										202
									
								
								interface.c
									
									
									
									
									
								
							
							
						
						
									
										202
									
								
								interface.c
									
									
									
									
									
								
							@@ -4,20 +4,21 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: interface.c 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: interface.c 1.2 2000/03/06 19:45:03 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "interface.h"
 | 
			
		||||
#include <ncurses.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include "dvbapi.h"
 | 
			
		||||
#include "remote.h"
 | 
			
		||||
 | 
			
		||||
#define MenuLines   15
 | 
			
		||||
#define MenuColumns 40
 | 
			
		||||
 | 
			
		||||
#ifndef DEBUG_REMOTE
 | 
			
		||||
cRcIo RcIo("/dev/ttyS1");//XXX
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
WINDOW *window;
 | 
			
		||||
cDvbOsd DvbOsd; //XXX member of cInterface???
 | 
			
		||||
 | 
			
		||||
cInterface Interface;
 | 
			
		||||
 | 
			
		||||
@@ -25,16 +26,6 @@ cInterface::cInterface(void)
 | 
			
		||||
{
 | 
			
		||||
  open = 0;
 | 
			
		||||
  cols[0] = 0;
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  initscr();
 | 
			
		||||
  keypad(stdscr, TRUE);
 | 
			
		||||
  nonl();
 | 
			
		||||
  cbreak();
 | 
			
		||||
  noecho();
 | 
			
		||||
  leaveok(stdscr, TRUE);
 | 
			
		||||
  window = stdscr;
 | 
			
		||||
#else
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::Init(void)
 | 
			
		||||
@@ -46,24 +37,14 @@ void cInterface::Init(void)
 | 
			
		||||
 | 
			
		||||
void cInterface::Open(void)
 | 
			
		||||
{
 | 
			
		||||
  if (!open++) {
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
#else
 | 
			
		||||
//TODO
 | 
			
		||||
     DvbOsdOpen(100, 100, 500, 400);
 | 
			
		||||
#endif
 | 
			
		||||
     }
 | 
			
		||||
  if (!open++)
 | 
			
		||||
     DvbOsd.Open(MenuColumns, MenuLines);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::Close(void)
 | 
			
		||||
{
 | 
			
		||||
  if (!--open) {
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
#else
 | 
			
		||||
//TODO
 | 
			
		||||
     DvbOsdClose();
 | 
			
		||||
#endif
 | 
			
		||||
     }
 | 
			
		||||
  if (!--open)
 | 
			
		||||
     DvbOsd.Close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int cInterface::GetCh(void)
 | 
			
		||||
@@ -71,9 +52,9 @@ unsigned int cInterface::GetCh(void)
 | 
			
		||||
#ifdef DEBUG_REMOTE
 | 
			
		||||
  return getch();
 | 
			
		||||
#else
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  wrefresh(window);//XXX
 | 
			
		||||
#endif
 | 
			
		||||
//XXX #ifdef DEBUG_OSD
 | 
			
		||||
//XXX   wrefresh(window);//XXX
 | 
			
		||||
//XXX #endif
 | 
			
		||||
  unsigned int Command;
 | 
			
		||||
  return RcIo.GetCommand(&Command) ? Command : 0;
 | 
			
		||||
#endif
 | 
			
		||||
@@ -84,16 +65,28 @@ eKeys cInterface::GetKey(void)
 | 
			
		||||
  return Keys.Get(GetCh());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eKeys cInterface::Wait(int Seconds)
 | 
			
		||||
{
 | 
			
		||||
  int t0 = time_ms();
 | 
			
		||||
 | 
			
		||||
  while (time_ms() - t0 < Seconds * 1000) {
 | 
			
		||||
        eKeys Key = GetKey();
 | 
			
		||||
        if (Key != kNone)
 | 
			
		||||
           return Key;
 | 
			
		||||
        }
 | 
			
		||||
  return kNone;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::Clear(void)
 | 
			
		||||
{
 | 
			
		||||
  if (open) {
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
     wclear(window);
 | 
			
		||||
#else
 | 
			
		||||
//TODO
 | 
			
		||||
     DvbOsdClear();
 | 
			
		||||
#endif
 | 
			
		||||
     }
 | 
			
		||||
  if (open)
 | 
			
		||||
     DvbOsd.Clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::ClearEol(int x, int y, eDvbColor Color)
 | 
			
		||||
{
 | 
			
		||||
  if (open)
 | 
			
		||||
     DvbOsd.ClrEol(x, y, Color);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::SetCols(int *c)
 | 
			
		||||
@@ -105,34 +98,22 @@ void cInterface::SetCols(int *c)
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::Write(int x, int y, char *s)
 | 
			
		||||
void cInterface::Write(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor)
 | 
			
		||||
{
 | 
			
		||||
  if (open) {
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
     wmove(window, y, x); // ncurses wants 'y' before 'x'!
 | 
			
		||||
     waddstr(window, s);
 | 
			
		||||
#else
 | 
			
		||||
     DvbOsdText(x * DvbOsdCharWidth, y * DvbOsdLineHeight, s);
 | 
			
		||||
#endif
 | 
			
		||||
     }
 | 
			
		||||
  if (open)
 | 
			
		||||
     DvbOsd.Text(x, y, s, FgColor, BgColor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::WriteText(int x, int y, char *s, bool Current)
 | 
			
		||||
void cInterface::WriteText(int x, int y, const char *s, bool Current)
 | 
			
		||||
{
 | 
			
		||||
  if (open) {
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
     wmove(window, y, x); // ncurses wants 'y' before 'x'!
 | 
			
		||||
     wclrtoeol(window);//XXX
 | 
			
		||||
#else
 | 
			
		||||
//TODO
 | 
			
		||||
     DvbOsdClrEol(x * DvbOsdCharWidth, y);//XXX
 | 
			
		||||
#endif
 | 
			
		||||
     Write(x, y, Current ? "*" : " ");
 | 
			
		||||
     x++;
 | 
			
		||||
     eDvbColor FgColor = Current ? clrBlack : clrWhite;
 | 
			
		||||
     eDvbColor BgColor = Current ? clrCyan : clrBackground;
 | 
			
		||||
     ClearEol(x, y, BgColor);
 | 
			
		||||
     int col = 0;
 | 
			
		||||
     for (;;) {
 | 
			
		||||
         char *t = strchr(s, '\t');
 | 
			
		||||
         char *p = s;
 | 
			
		||||
         const char *t = strchr(s, '\t');
 | 
			
		||||
         const char *p = s;
 | 
			
		||||
         char buf[1000];
 | 
			
		||||
         if (t && col < MaxCols && cols[col] > 0) {
 | 
			
		||||
            unsigned int n = t - s;
 | 
			
		||||
@@ -143,7 +124,7 @@ void cInterface::WriteText(int x, int y, char *s, bool Current)
 | 
			
		||||
            p = buf;
 | 
			
		||||
            s = t + 1;
 | 
			
		||||
            }
 | 
			
		||||
         Write(x, y, p);
 | 
			
		||||
         Write(x, y, p, FgColor, BgColor);
 | 
			
		||||
         if (p == s)
 | 
			
		||||
            break;
 | 
			
		||||
         x += cols[col++];
 | 
			
		||||
@@ -151,38 +132,74 @@ void cInterface::WriteText(int x, int y, char *s, bool Current)
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::Info(char *s)
 | 
			
		||||
void cInterface::Title(const char *s)
 | 
			
		||||
{
 | 
			
		||||
  int x = (MenuColumns - strlen(s)) / 2;
 | 
			
		||||
  if (x < 0)
 | 
			
		||||
     x = 0;
 | 
			
		||||
  ClearEol(0, 0, clrCyan);
 | 
			
		||||
  Write(x, 0, s, clrBlack, clrCyan);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::Status(const char *s, eDvbColor FgColor, eDvbColor BgColor)
 | 
			
		||||
{
 | 
			
		||||
  ClearEol(0, -3, s ? BgColor : clrBackground);
 | 
			
		||||
  if (s)
 | 
			
		||||
     Write(0, -3, s, FgColor, BgColor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::Info(const char *s)
 | 
			
		||||
{
 | 
			
		||||
  Open();
 | 
			
		||||
  isyslog(LOG_ERR, s);
 | 
			
		||||
  WriteText(0, 11, s);//TODO
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  wrefresh(window);//XXX
 | 
			
		||||
#endif
 | 
			
		||||
  sleep(1);
 | 
			
		||||
  WriteText(0, 11, "");//TODO
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  wrefresh(window);//XXX
 | 
			
		||||
#endif
 | 
			
		||||
  isyslog(LOG_INFO, s);
 | 
			
		||||
  Status(s, clrWhite, clrGreen);
 | 
			
		||||
  Wait();
 | 
			
		||||
  Status(NULL);
 | 
			
		||||
  Close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::Error(char *s)
 | 
			
		||||
void cInterface::Error(const char *s)
 | 
			
		||||
{
 | 
			
		||||
  Open();
 | 
			
		||||
  esyslog(LOG_ERR, s);
 | 
			
		||||
  WriteText(0, 12, s);//TODO
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  wrefresh(window);//XXX
 | 
			
		||||
#endif
 | 
			
		||||
  sleep(1);
 | 
			
		||||
  WriteText(0, 12, "");//TODO
 | 
			
		||||
#ifdef DEBUG_OSD
 | 
			
		||||
  wrefresh(window);//XXX
 | 
			
		||||
#endif
 | 
			
		||||
  Status(s, clrWhite, clrRed);
 | 
			
		||||
  Wait();
 | 
			
		||||
  Status(NULL);
 | 
			
		||||
  Close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cInterface::Confirm(const char *s)
 | 
			
		||||
{
 | 
			
		||||
  Open();
 | 
			
		||||
  isyslog(LOG_INFO, "confirm: %s", s);
 | 
			
		||||
  Status(s, clrBlack, clrGreen);
 | 
			
		||||
  bool result = Wait(10) == kOk;
 | 
			
		||||
  Status(NULL);
 | 
			
		||||
  Close();
 | 
			
		||||
  isyslog(LOG_INFO, "%sconfirmed", result ? "" : "not ");
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor)
 | 
			
		||||
{
 | 
			
		||||
  if (open && Text) {
 | 
			
		||||
     const int w = MenuColumns / 4;
 | 
			
		||||
     int l = (w - strlen(Text)) / 2;
 | 
			
		||||
     if (l < 0)
 | 
			
		||||
        l = 0;
 | 
			
		||||
     DvbOsd.Fill(Index * w, -1, w, 1, BgColor);
 | 
			
		||||
     DvbOsd.Text(Index * w + l, -1, Text, FgColor, BgColor);
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::Help(const char *Red, const char *Green, const char *Yellow, const char *Blue)
 | 
			
		||||
{
 | 
			
		||||
  HelpButton(0, Red,    clrBlack, clrRed);
 | 
			
		||||
  HelpButton(1, Green,  clrBlack, clrGreen);
 | 
			
		||||
  HelpButton(2, Yellow, clrBlack, clrYellow);
 | 
			
		||||
  HelpButton(3, Blue,   clrWhite, clrBlue);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::QueryKeys(void)
 | 
			
		||||
{
 | 
			
		||||
  Keys.Clear();
 | 
			
		||||
@@ -205,8 +222,8 @@ void cInterface::QueryKeys(void)
 | 
			
		||||
         WriteText(1, 5, "RC code detected!");
 | 
			
		||||
         WriteText(1, 6, "Do not press any key...");
 | 
			
		||||
         RcIo.Flush(3);
 | 
			
		||||
         WriteText(1, 5, "");
 | 
			
		||||
         WriteText(1, 6, "");
 | 
			
		||||
         ClearEol(0, 5);
 | 
			
		||||
         ClearEol(0, 6);
 | 
			
		||||
         break;
 | 
			
		||||
         }
 | 
			
		||||
#endif
 | 
			
		||||
@@ -229,8 +246,8 @@ void cInterface::QueryKeys(void)
 | 
			
		||||
                 case kDown: if (k > Keys.keys + 1) {
 | 
			
		||||
                                WriteText(1, 5, "Press 'Up' to confirm");
 | 
			
		||||
                                WriteText(1, 6, "Press 'Down' to continue");
 | 
			
		||||
                                WriteText(1, 7, "");
 | 
			
		||||
                                WriteText(1, 8, "");
 | 
			
		||||
                                ClearEol(0, 7);
 | 
			
		||||
                                ClearEol(0, 8);
 | 
			
		||||
                                for (;;) {
 | 
			
		||||
                                    eKeys key = GetKey();
 | 
			
		||||
                                    if (key == kUp) {
 | 
			
		||||
@@ -238,7 +255,7 @@ void cInterface::QueryKeys(void)
 | 
			
		||||
                                       return;
 | 
			
		||||
                                       }
 | 
			
		||||
                                    else if (key == kDown) {
 | 
			
		||||
                                       WriteText(1, 6, "");
 | 
			
		||||
                                       ClearEol(0, 6);
 | 
			
		||||
                                       break;
 | 
			
		||||
                                       }
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -255,17 +272,18 @@ void cInterface::QueryKeys(void)
 | 
			
		||||
        if (k > Keys.keys)
 | 
			
		||||
           WriteText(1, 7, "(press 'Up' to go back)");
 | 
			
		||||
        else
 | 
			
		||||
           WriteText(1, 7, "");
 | 
			
		||||
           ClearEol(0, 7);
 | 
			
		||||
        if (k > Keys.keys + 1)
 | 
			
		||||
           WriteText(1, 8, "(press 'Down' to end key definition)");
 | 
			
		||||
        else
 | 
			
		||||
           WriteText(1, 8, "");
 | 
			
		||||
           ClearEol(0, 8);
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::LearnKeys(void)
 | 
			
		||||
{
 | 
			
		||||
  isyslog(LOG_INFO, "learning keys");
 | 
			
		||||
  Open();
 | 
			
		||||
  for (;;) {
 | 
			
		||||
      Clear();
 | 
			
		||||
      QueryKeys();
 | 
			
		||||
@@ -277,19 +295,19 @@ void cInterface::LearnKeys(void)
 | 
			
		||||
          eKeys key = GetKey();
 | 
			
		||||
          if (key == kUp) {
 | 
			
		||||
             Keys.Save();
 | 
			
		||||
             Clear();
 | 
			
		||||
             Close();
 | 
			
		||||
             return;
 | 
			
		||||
             }
 | 
			
		||||
          else if (key == kDown) {
 | 
			
		||||
             Keys.Load();
 | 
			
		||||
             Clear();
 | 
			
		||||
             Close();
 | 
			
		||||
             return;
 | 
			
		||||
             }
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cInterface::DisplayChannel(int Number, char *Name)
 | 
			
		||||
void cInterface::DisplayChannel(int Number, const char *Name)
 | 
			
		||||
{
 | 
			
		||||
//TODO
 | 
			
		||||
#ifndef DEBUG_REMOTE
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								interface.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								interface.h
									
									
									
									
									
								
							@@ -4,13 +4,14 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: interface.h 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: interface.h 1.2 2000/02/27 14:54:02 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __INTERFACE_H
 | 
			
		||||
#define __INTERFACE_H
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "dvbapi.h"
 | 
			
		||||
 | 
			
		||||
class cInterface {
 | 
			
		||||
public:
 | 
			
		||||
@@ -20,7 +21,8 @@ private:
 | 
			
		||||
  int cols[MaxCols];
 | 
			
		||||
  unsigned int GetCh(void);
 | 
			
		||||
  void QueryKeys(void);
 | 
			
		||||
  void Write(int x, int y, char *s);
 | 
			
		||||
  void HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor);
 | 
			
		||||
  eKeys Wait(int Seconds = 1);
 | 
			
		||||
public:
 | 
			
		||||
  cInterface(void);
 | 
			
		||||
  void Init(void);
 | 
			
		||||
@@ -28,12 +30,18 @@ public:
 | 
			
		||||
  void Close(void);
 | 
			
		||||
  eKeys GetKey(void);
 | 
			
		||||
  void Clear(void);
 | 
			
		||||
  void ClearEol(int x, int y, eDvbColor Color = clrBackground);
 | 
			
		||||
  void SetCols(int *c);
 | 
			
		||||
  void WriteText(int x, int y, char *s, bool Current = false);
 | 
			
		||||
  void Info(char *s);
 | 
			
		||||
  void Error(char *s);
 | 
			
		||||
  void Write(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
 | 
			
		||||
  void WriteText(int x, int y, const char *s, bool Current = false);
 | 
			
		||||
  void Title(const char *s);
 | 
			
		||||
  void Status(const char *s, eDvbColor FgColor = clrBlack, eDvbColor BgColor = clrCyan);
 | 
			
		||||
  void Info(const char *s);
 | 
			
		||||
  void Error(const char *s);
 | 
			
		||||
  bool Confirm(const char *s);
 | 
			
		||||
  void Help(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
 | 
			
		||||
  void LearnKeys(void);
 | 
			
		||||
  void DisplayChannel(int Number, char *Name);
 | 
			
		||||
  void DisplayChannel(int Number, const char *Name);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
extern cInterface Interface;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								keys-pc.conf
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								keys-pc.conf
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -17,3 +17,7 @@ Right	000045E2
 | 
			
		||||
7	00000FE2
 | 
			
		||||
8	000077E2
 | 
			
		||||
9	000037E2
 | 
			
		||||
Red	000025E2
 | 
			
		||||
Green	00002AE2
 | 
			
		||||
Yellow	00005AE2
 | 
			
		||||
Blue	00000000
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										454
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										454
									
								
								menu.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: menu.c 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: menu.c 1.2 2000/03/05 15:37:31 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "menu.h"
 | 
			
		||||
@@ -13,8 +13,9 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "dvbapi.h"
 | 
			
		||||
#include "recording.h"
 | 
			
		||||
 | 
			
		||||
const char *FileNameChars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789/-.# ";//TODO more?
 | 
			
		||||
const char *FileNameChars = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789-.# ";
 | 
			
		||||
 | 
			
		||||
// --- cMenuEditItem ---------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@@ -59,7 +60,7 @@ protected:
 | 
			
		||||
  virtual void Set(void);
 | 
			
		||||
public:
 | 
			
		||||
  cMenuEditIntItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX);
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuEditIntItem::cMenuEditIntItem(const char *Name, int *Value, int Min, int Max)
 | 
			
		||||
@@ -78,11 +79,11 @@ void cMenuEditIntItem::Set(void)
 | 
			
		||||
  SetValue(buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuEditIntItem::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuEditIntItem::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  eOSStatus status = cMenuEditItem::ProcessKey(Key);
 | 
			
		||||
  eOSState state = cMenuEditItem::ProcessKey(Key);
 | 
			
		||||
 | 
			
		||||
  if (status == osUnknown) {
 | 
			
		||||
  if (state == osUnknown) {
 | 
			
		||||
     int newValue;
 | 
			
		||||
     if (k0 <= Key && Key <= k9) {
 | 
			
		||||
        if (fresh) {
 | 
			
		||||
@@ -100,14 +101,14 @@ eOSStatus cMenuEditIntItem::ProcessKey(eKeys Key)
 | 
			
		||||
        fresh = true;
 | 
			
		||||
        }
 | 
			
		||||
     else
 | 
			
		||||
        return status;
 | 
			
		||||
        return state;
 | 
			
		||||
     if ((!fresh || min <= newValue) && newValue <= max) {
 | 
			
		||||
        *value = newValue;
 | 
			
		||||
        Set();
 | 
			
		||||
        }
 | 
			
		||||
     status = osContinue;
 | 
			
		||||
     state = osContinue;
 | 
			
		||||
     }
 | 
			
		||||
  return status;
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuEditBoolItem -----------------------------------------------------
 | 
			
		||||
@@ -167,7 +168,7 @@ protected:
 | 
			
		||||
  virtual void Set(void);
 | 
			
		||||
public:
 | 
			
		||||
  cMenuEditDayItem(const char *Name, int *Value);
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
int cMenuEditDayItem::days[] ={ cTimer::ParseDay("M------"),
 | 
			
		||||
@@ -205,7 +206,7 @@ void cMenuEditDayItem::Set(void)
 | 
			
		||||
  SetValue(cTimer::PrintDay(*value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuEditDayItem::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuEditDayItem::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  switch (Key) {
 | 
			
		||||
    case kLeft:  if (d > 0)
 | 
			
		||||
@@ -252,7 +253,7 @@ protected:
 | 
			
		||||
  virtual void Set(void);
 | 
			
		||||
public:
 | 
			
		||||
  cMenuEditTimeItem(const char *Name, int *Value);
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuEditTimeItem::cMenuEditTimeItem(const char *Name, int *Value)
 | 
			
		||||
@@ -272,11 +273,11 @@ void cMenuEditTimeItem::Set(void)
 | 
			
		||||
  SetValue(buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuEditTimeItem::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuEditTimeItem::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  eOSStatus status = cMenuEditItem::ProcessKey(Key);
 | 
			
		||||
  eOSState state = cMenuEditItem::ProcessKey(Key);
 | 
			
		||||
 | 
			
		||||
  if (status == osUnknown) {
 | 
			
		||||
  if (state == osUnknown) {
 | 
			
		||||
     if (k0 <= Key && Key <= k9) {
 | 
			
		||||
        if (fresh || pos > 3) {
 | 
			
		||||
           pos = 0;
 | 
			
		||||
@@ -324,12 +325,12 @@ eOSStatus cMenuEditTimeItem::ProcessKey(eKeys Key)
 | 
			
		||||
        fresh = true;
 | 
			
		||||
        }
 | 
			
		||||
     else
 | 
			
		||||
        return status;
 | 
			
		||||
        return state;
 | 
			
		||||
     *value = hh * 100 + mm;
 | 
			
		||||
     Set();
 | 
			
		||||
     status = osContinue;
 | 
			
		||||
     state = osContinue;
 | 
			
		||||
     }
 | 
			
		||||
  return status;
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuEditChrItem ------------------------------------------------------
 | 
			
		||||
@@ -343,7 +344,7 @@ private:
 | 
			
		||||
public:
 | 
			
		||||
  cMenuEditChrItem(const char *Name, char *Value, const char *Allowed);
 | 
			
		||||
  ~cMenuEditChrItem();
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuEditChrItem::cMenuEditChrItem(const char *Name, char *Value, const char *Allowed)
 | 
			
		||||
@@ -369,11 +370,11 @@ void cMenuEditChrItem::Set(void)
 | 
			
		||||
  SetValue(buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuEditChrItem::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuEditChrItem::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  eOSStatus status = cMenuEditItem::ProcessKey(Key);
 | 
			
		||||
  eOSState state = cMenuEditItem::ProcessKey(Key);
 | 
			
		||||
 | 
			
		||||
  if (status == osUnknown) {
 | 
			
		||||
  if (state == osUnknown) {
 | 
			
		||||
     if (Key == kLeft) {
 | 
			
		||||
        if (current > allowed)
 | 
			
		||||
           current--;
 | 
			
		||||
@@ -383,12 +384,12 @@ eOSStatus cMenuEditChrItem::ProcessKey(eKeys Key)
 | 
			
		||||
           current++;
 | 
			
		||||
        }
 | 
			
		||||
     else
 | 
			
		||||
        return status;
 | 
			
		||||
        return state;
 | 
			
		||||
     *value = *current;
 | 
			
		||||
     Set();
 | 
			
		||||
     status = osContinue;
 | 
			
		||||
     state = osContinue;
 | 
			
		||||
     }
 | 
			
		||||
  return status;
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuEditStrItem ------------------------------------------------------
 | 
			
		||||
@@ -404,7 +405,7 @@ private:
 | 
			
		||||
public:
 | 
			
		||||
  cMenuEditStrItem(const char *Name, char *Value, int Length, const char *Allowed);
 | 
			
		||||
  ~cMenuEditStrItem();
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuEditStrItem::cMenuEditStrItem(const char *Name, char *Value, int Length, const char *Allowed)
 | 
			
		||||
@@ -449,7 +450,7 @@ char cMenuEditStrItem::Inc(char c, bool Up)
 | 
			
		||||
  return *p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuEditStrItem::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  switch (Key) {
 | 
			
		||||
    case kLeft:  if (pos > 0) {
 | 
			
		||||
@@ -492,11 +493,11 @@ private:
 | 
			
		||||
  cChannel data;
 | 
			
		||||
public:
 | 
			
		||||
  cMenuEditChannel(int Index);
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuEditChannel::cMenuEditChannel(int Index)
 | 
			
		||||
:cOsdMenu("Edit channel", 14)
 | 
			
		||||
:cOsdMenu("Edit Channel", 14)
 | 
			
		||||
{
 | 
			
		||||
  channel = Channels.Get(Index);
 | 
			
		||||
  if (channel) {
 | 
			
		||||
@@ -511,19 +512,19 @@ cMenuEditChannel::cMenuEditChannel(int Index)
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuEditChannel::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuEditChannel::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  eOSStatus status = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
  eOSState state = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
 | 
			
		||||
  if (status == osUnknown) {
 | 
			
		||||
  if (state == osUnknown) {
 | 
			
		||||
     if (Key == kOk) {
 | 
			
		||||
        if (channel)
 | 
			
		||||
           *channel = data;
 | 
			
		||||
        Channels.Save();
 | 
			
		||||
        status = osBack;
 | 
			
		||||
        state = osBack;
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  return status;
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuChannelItem ------------------------------------------------------
 | 
			
		||||
@@ -535,6 +536,7 @@ private:
 | 
			
		||||
public:
 | 
			
		||||
  cMenuChannelItem(int Index, cChannel *Channel);
 | 
			
		||||
  virtual void Set(void);
 | 
			
		||||
  void SetIndex(int Index);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuChannelItem::cMenuChannelItem(int Index, cChannel *Channel)
 | 
			
		||||
@@ -551,12 +553,24 @@ void cMenuChannelItem::Set(void)
 | 
			
		||||
  SetText(buffer, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMenuChannelItem::SetIndex(int Index)
 | 
			
		||||
{
 | 
			
		||||
  index = Index;
 | 
			
		||||
  Set();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuChannels ---------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
class cMenuChannels : public cOsdMenu {
 | 
			
		||||
protected:
 | 
			
		||||
  eOSState Switch(void);
 | 
			
		||||
  eOSState Edit(void);
 | 
			
		||||
  eOSState New(void);
 | 
			
		||||
  eOSState Del(void);
 | 
			
		||||
  virtual void Move(int From, int To);
 | 
			
		||||
public:
 | 
			
		||||
  cMenuChannels(void);
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuChannels::cMenuChannels(void)
 | 
			
		||||
@@ -570,26 +584,124 @@ cMenuChannels::cMenuChannels(void)
 | 
			
		||||
        Add(new cMenuChannelItem(i, channel), i == CurrentChannel);
 | 
			
		||||
        i++;
 | 
			
		||||
        }
 | 
			
		||||
  SetHelp("Edit", "New", "Delete", "Mark");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuChannels::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuChannels::Switch(void)
 | 
			
		||||
{
 | 
			
		||||
  eOSStatus status = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
  cChannel *ch = Channels.Get(Current());
 | 
			
		||||
  if (ch)
 | 
			
		||||
     ch->Switch();
 | 
			
		||||
  return osEnd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  if (status == osUnknown) {
 | 
			
		||||
eOSState cMenuChannels::Edit(void)
 | 
			
		||||
{
 | 
			
		||||
  if (HasSubMenu() || Count() == 0)
 | 
			
		||||
     return osContinue;
 | 
			
		||||
  isyslog(LOG_INFO, "editing timer %d", Current() + 1);
 | 
			
		||||
  return AddSubMenu(new cMenuEditChannel(Current()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cMenuChannels::New(void)
 | 
			
		||||
{
 | 
			
		||||
  if (HasSubMenu())
 | 
			
		||||
     return osContinue;
 | 
			
		||||
  cChannel *channel = new cChannel(Channels.Get(Current()));
 | 
			
		||||
  Channels.Add(channel);
 | 
			
		||||
  Add(new cMenuChannelItem(channel->Index()/*XXX*/, channel), true);
 | 
			
		||||
  Channels.Save();
 | 
			
		||||
  isyslog(LOG_INFO, "channel %d added", channel->Index() + 1);
 | 
			
		||||
  return AddSubMenu(new cMenuEditChannel(Current()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cMenuChannels::Del(void)
 | 
			
		||||
{
 | 
			
		||||
  if (Count() > 0) {
 | 
			
		||||
     int Index = Current();
 | 
			
		||||
     // Check if there is a timer using this channel:
 | 
			
		||||
     for (cTimer *ti = Timers.First(); ti; ti = (cTimer *)ti->Next()) {
 | 
			
		||||
         if (ti->channel == Index + 1) {
 | 
			
		||||
            Interface.Error("Channel is being used by a timer!");
 | 
			
		||||
            return osContinue;
 | 
			
		||||
            }
 | 
			
		||||
         }
 | 
			
		||||
     if (Interface.Confirm("Delete Channel?")) {
 | 
			
		||||
        // Move and renumber the channels:
 | 
			
		||||
        Channels.Del(Channels.Get(Index));
 | 
			
		||||
        cOsdMenu::Del(Index);
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        for (cMenuChannelItem *ci = (cMenuChannelItem *)First(); ci; ci = (cMenuChannelItem *)ci->Next())
 | 
			
		||||
            ci->SetIndex(i++);
 | 
			
		||||
        Channels.Save();
 | 
			
		||||
        isyslog(LOG_INFO, "channel %d deleted", Index + 1);
 | 
			
		||||
        // Fix the timers:
 | 
			
		||||
        bool TimersModified = false;
 | 
			
		||||
        Index++; // user visible channel numbers start with '1'
 | 
			
		||||
        for (cTimer *ti = Timers.First(); ti; ti = (cTimer *)ti->Next()) {
 | 
			
		||||
            int OldChannel = ti->channel;
 | 
			
		||||
            if (ti->channel > Index)
 | 
			
		||||
               ti->channel--;
 | 
			
		||||
            if (ti->channel != OldChannel) {
 | 
			
		||||
               TimersModified = true;
 | 
			
		||||
               isyslog(LOG_INFO, "timer %d: channel changed from %d to %d", ti->Index() + 1, OldChannel, ti->channel);
 | 
			
		||||
               }
 | 
			
		||||
            }
 | 
			
		||||
        if (TimersModified)
 | 
			
		||||
           Timers.Save();
 | 
			
		||||
        Display();
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  return osContinue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMenuChannels::Move(int From, int To)
 | 
			
		||||
{
 | 
			
		||||
  // Move and renumber the channels:
 | 
			
		||||
  Channels.Move(From, To);
 | 
			
		||||
  cOsdMenu::Move(From, To);
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  for (cMenuChannelItem *ci = (cMenuChannelItem *)First(); ci; ci = (cMenuChannelItem *)ci->Next())
 | 
			
		||||
      ci->SetIndex(i++);
 | 
			
		||||
  Channels.Save();
 | 
			
		||||
  isyslog(LOG_INFO, "channel %d moved to %d", From + 1, To + 1);
 | 
			
		||||
  // Fix the timers:
 | 
			
		||||
  bool TimersModified = false;
 | 
			
		||||
  From++; // user visible channel numbers start with '1'
 | 
			
		||||
  To++;
 | 
			
		||||
  for (cTimer *ti = Timers.First(); ti; ti = (cTimer *)ti->Next()) {
 | 
			
		||||
      int OldChannel = ti->channel;
 | 
			
		||||
      if (ti->channel == From)
 | 
			
		||||
         ti->channel = To;
 | 
			
		||||
      else if (ti->channel > From && ti->channel <= To)
 | 
			
		||||
         ti->channel--;
 | 
			
		||||
      else if (ti->channel < From && ti->channel >= To)
 | 
			
		||||
         ti->channel++;
 | 
			
		||||
      if (ti->channel != OldChannel) {
 | 
			
		||||
         TimersModified = true;
 | 
			
		||||
         isyslog(LOG_INFO, "timer %d: channel changed from %d to %d", ti->Index() + 1, OldChannel, ti->channel);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
  if (TimersModified)
 | 
			
		||||
     Timers.Save();
 | 
			
		||||
  Display();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cMenuChannels::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  eOSState state = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
 | 
			
		||||
  if (state == osUnknown) {
 | 
			
		||||
     switch (Key) {
 | 
			
		||||
       //TODO need to block this if we are already editing a channel!
 | 
			
		||||
       case kRight: return AddSubMenu(new cMenuEditChannel(Current()));
 | 
			
		||||
       case kOk:    {
 | 
			
		||||
                      cChannel *ch = Channels.Get(Current());
 | 
			
		||||
                      if (ch)
 | 
			
		||||
                         ch->Switch();
 | 
			
		||||
                      return osEnd;
 | 
			
		||||
                    }
 | 
			
		||||
       case kOk:     return Switch();
 | 
			
		||||
       case kRed:    return Edit();
 | 
			
		||||
       case kGreen:  return New();
 | 
			
		||||
       case kYellow: return Del();
 | 
			
		||||
       case kBlue:   Mark(); break;
 | 
			
		||||
       default: break;
 | 
			
		||||
       }
 | 
			
		||||
     }
 | 
			
		||||
  return status;
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuEditTimer --------------------------------------------------------
 | 
			
		||||
@@ -600,11 +712,11 @@ private:
 | 
			
		||||
  cTimer data;
 | 
			
		||||
public:
 | 
			
		||||
  cMenuEditTimer(int Index);
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuEditTimer::cMenuEditTimer(int Index)
 | 
			
		||||
:cOsdMenu("Edit timer", 10)
 | 
			
		||||
:cOsdMenu("Edit Timer", 10)
 | 
			
		||||
{
 | 
			
		||||
  timer = Timers.Get(Index);
 | 
			
		||||
  if (timer) {
 | 
			
		||||
@@ -622,21 +734,23 @@ cMenuEditTimer::cMenuEditTimer(int Index)
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuEditTimer::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuEditTimer::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  eOSStatus status = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
  eOSState state = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
 | 
			
		||||
  if (status == osUnknown) {
 | 
			
		||||
  if (state == osUnknown) {
 | 
			
		||||
     if (Key == kOk) {
 | 
			
		||||
        if (!*data.file)
 | 
			
		||||
           strcpy(data.file, "unnamed");
 | 
			
		||||
        if (timer && memcmp(timer, &data, sizeof(data)) != 0) {
 | 
			
		||||
           *timer = data;
 | 
			
		||||
           Timers.Save();
 | 
			
		||||
           isyslog(LOG_INFO, "timer %d modified (%s)", timer->Index() + 1, timer->active ? "active" : "inactive");
 | 
			
		||||
           }
 | 
			
		||||
        status = osBack;
 | 
			
		||||
        state = osBack;
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  return status;
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuTimerItem --------------------------------------------------------
 | 
			
		||||
@@ -660,27 +774,34 @@ cMenuTimerItem::cMenuTimerItem(int Index, cTimer *Timer)
 | 
			
		||||
void cMenuTimerItem::Set(void)
 | 
			
		||||
{
 | 
			
		||||
  char *buffer = NULL;
 | 
			
		||||
  asprintf(&buffer, "%d\t%c\t%d\t%s\t%02d:%02d\t%02d:%02d", index + 1,
 | 
			
		||||
  asprintf(&buffer, "%c\t%d\t%s\t%02d:%02d\t%02d:%02d\t%s",
 | 
			
		||||
                    timer->active ? '>' : ' ', 
 | 
			
		||||
                    timer->channel, 
 | 
			
		||||
                    timer->PrintDay(timer->day), 
 | 
			
		||||
                    timer->start / 100,
 | 
			
		||||
                    timer->start % 100,
 | 
			
		||||
                    timer->stop / 100,
 | 
			
		||||
                    timer->stop % 100); // user visible timer numbers start with '1'
 | 
			
		||||
                    timer->stop % 100,
 | 
			
		||||
                    timer->file);
 | 
			
		||||
  SetText(buffer, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuTimer ------------------------------------------------------------
 | 
			
		||||
// --- cMenuTimers -----------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
class cMenuTimer : public cOsdMenu {
 | 
			
		||||
class cMenuTimers : public cOsdMenu {
 | 
			
		||||
private:
 | 
			
		||||
  eOSState Activate(bool On);
 | 
			
		||||
  eOSState Edit(void);
 | 
			
		||||
  eOSState New(void);
 | 
			
		||||
  eOSState Del(void);
 | 
			
		||||
  virtual void Move(int From, int To);
 | 
			
		||||
public:
 | 
			
		||||
  cMenuTimer(void);
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  cMenuTimers(void);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuTimer::cMenuTimer(void)
 | 
			
		||||
:cOsdMenu("Timer", 3, 2, 4, 10, 6)
 | 
			
		||||
cMenuTimers::cMenuTimers(void)
 | 
			
		||||
:cOsdMenu("Timer", 2, 4, 10, 6, 6)
 | 
			
		||||
{
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  cTimer *timer;
 | 
			
		||||
@@ -689,34 +810,190 @@ cMenuTimer::cMenuTimer(void)
 | 
			
		||||
        Add(new cMenuTimerItem(i, timer));
 | 
			
		||||
        i++;
 | 
			
		||||
        }
 | 
			
		||||
  SetHelp("Edit", "New", "Delete", "Mark");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuTimer::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuTimers::Activate(bool On)
 | 
			
		||||
{
 | 
			
		||||
  eOSStatus status = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
  cTimer *timer = Timers.Get(Current());
 | 
			
		||||
  if (timer && timer->active != On) {
 | 
			
		||||
     timer->active = On;
 | 
			
		||||
     RefreshCurrent();
 | 
			
		||||
     DisplayCurrent(true);
 | 
			
		||||
     isyslog(LOG_INFO, "timer %d %sactivated", timer->Index() + 1, timer->active ? "" : "de");
 | 
			
		||||
     Timers.Save();
 | 
			
		||||
     }
 | 
			
		||||
  return osContinue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  if (status == osUnknown) {
 | 
			
		||||
eOSState cMenuTimers::Edit(void)
 | 
			
		||||
{
 | 
			
		||||
  if (HasSubMenu() || Count() == 0)
 | 
			
		||||
     return osContinue;
 | 
			
		||||
  isyslog(LOG_INFO, "editing timer %d", Current() + 1);
 | 
			
		||||
  return AddSubMenu(new cMenuEditTimer(Current()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cMenuTimers::New(void)
 | 
			
		||||
{
 | 
			
		||||
  if (HasSubMenu())
 | 
			
		||||
     return osContinue;
 | 
			
		||||
  cTimer *timer = new cTimer;
 | 
			
		||||
  Timers.Add(timer);
 | 
			
		||||
  Add(new cMenuTimerItem(timer->Index()/*XXX*/, timer), true);
 | 
			
		||||
  Timers.Save();
 | 
			
		||||
  isyslog(LOG_INFO, "timer %d added", timer->Index() + 1);
 | 
			
		||||
  return AddSubMenu(new cMenuEditTimer(Current()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cMenuTimers::Del(void)
 | 
			
		||||
{
 | 
			
		||||
  // Check if this timer is active:
 | 
			
		||||
  int Index = Current();
 | 
			
		||||
  cTimer *ti = Timers.Get(Index);
 | 
			
		||||
  if (ti) {
 | 
			
		||||
     if (!ti->recording) {
 | 
			
		||||
        if (Interface.Confirm("Delete Timer?")) {
 | 
			
		||||
           Timers.Del(Timers.Get(Index));
 | 
			
		||||
           cOsdMenu::Del(Index);
 | 
			
		||||
           Timers.Save();
 | 
			
		||||
           Display();
 | 
			
		||||
           isyslog(LOG_INFO, "timer %d deleted", Index + 1);
 | 
			
		||||
           }
 | 
			
		||||
        }
 | 
			
		||||
     else
 | 
			
		||||
        Interface.Error("Timer is recording!");
 | 
			
		||||
     }
 | 
			
		||||
  return osContinue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMenuTimers::Move(int From, int To)
 | 
			
		||||
{
 | 
			
		||||
  Timers.Move(From, To);
 | 
			
		||||
  cOsdMenu::Move(From, To);
 | 
			
		||||
  Timers.Save();
 | 
			
		||||
  Display();
 | 
			
		||||
  isyslog(LOG_INFO, "timer %d moved to %d", From + 1, To + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cMenuTimers::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  eOSState state = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
 | 
			
		||||
  if (state == osUnknown) {
 | 
			
		||||
     switch (Key) {
 | 
			
		||||
       //TODO need to block this if we are already editing a channel!
 | 
			
		||||
       case kOk: return AddSubMenu(new cMenuEditTimer(Current()));
 | 
			
		||||
       //TODO new timer
 | 
			
		||||
       //TODO delete timer
 | 
			
		||||
       case kLeft:
 | 
			
		||||
       case kRight: 
 | 
			
		||||
            {
 | 
			
		||||
              cTimer *timer = Timers.Get(Current());
 | 
			
		||||
              if (timer) {
 | 
			
		||||
                 timer->active = (Key == kRight);
 | 
			
		||||
                 isyslog(LOG_INFO, "timer %d %sactivated", timer->Index() + 1, timer->active ? "" : "de");
 | 
			
		||||
                 RefreshCurrent();
 | 
			
		||||
                 DisplayCurrent(true);
 | 
			
		||||
                 Timers.Save();
 | 
			
		||||
                 }
 | 
			
		||||
            }
 | 
			
		||||
       case kRight:  return Activate(Key == kRight);
 | 
			
		||||
       case kOk:
 | 
			
		||||
       case kRed:    return Edit();
 | 
			
		||||
       case kGreen:  return New();
 | 
			
		||||
       case kYellow: return Del();
 | 
			
		||||
       case kBlue:   Mark(); break;
 | 
			
		||||
       default: break;
 | 
			
		||||
       }
 | 
			
		||||
     }
 | 
			
		||||
  return status;
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuRecordingItem ----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
class cMenuRecordingItem : public cOsdItem {
 | 
			
		||||
public:
 | 
			
		||||
  cRecording *recording;
 | 
			
		||||
  cMenuRecordingItem(cRecording *Recording);
 | 
			
		||||
  virtual void Set(void);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuRecordingItem::cMenuRecordingItem(cRecording *Recording)
 | 
			
		||||
{
 | 
			
		||||
  recording = Recording;
 | 
			
		||||
  Set();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMenuRecordingItem::Set(void)
 | 
			
		||||
{
 | 
			
		||||
  char *buffer = NULL;
 | 
			
		||||
  struct tm *t = localtime(&recording->start);
 | 
			
		||||
  asprintf(&buffer, "%02d.%02d.%04d\t%02d:%02d\t%s",
 | 
			
		||||
                    t->tm_mday,
 | 
			
		||||
                    t->tm_mon + 1,
 | 
			
		||||
                    t->tm_year + 1900,
 | 
			
		||||
                    t->tm_hour,
 | 
			
		||||
                    t->tm_min,
 | 
			
		||||
                    recording->name);
 | 
			
		||||
  SetText(buffer, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuRecordings -------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
class cMenuRecordings : public cOsdMenu {
 | 
			
		||||
private:
 | 
			
		||||
  cRecordings Recordings;
 | 
			
		||||
  eOSState Play(void);
 | 
			
		||||
  eOSState Del(void);
 | 
			
		||||
public:
 | 
			
		||||
  cMenuRecordings(void);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
cMenuRecordings::cMenuRecordings(void)
 | 
			
		||||
:cOsdMenu("Recordings", 11, 6)
 | 
			
		||||
{
 | 
			
		||||
  if (Recordings.Load()) {
 | 
			
		||||
     cRecording *recording = Recordings.First();
 | 
			
		||||
     while (recording) {
 | 
			
		||||
           Add(new cMenuRecordingItem(recording));
 | 
			
		||||
           recording = Recordings.Next(recording);
 | 
			
		||||
           }
 | 
			
		||||
     }
 | 
			
		||||
  SetHelp("Play", NULL/*XXX"Resume"*/, "Delete");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cMenuRecordings::Play(void)
 | 
			
		||||
{
 | 
			
		||||
  cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
 | 
			
		||||
  if (ri) {
 | 
			
		||||
//XXX what if this recording's file is currently in use???
 | 
			
		||||
     if (ri->recording->Play())
 | 
			
		||||
        return osEnd;
 | 
			
		||||
     }
 | 
			
		||||
  return osContinue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cMenuRecordings::Del(void)
 | 
			
		||||
{
 | 
			
		||||
  cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
 | 
			
		||||
  if (ri) {
 | 
			
		||||
//XXX what if this recording's file is currently in use???
 | 
			
		||||
//XXX     if (!ti->recording) {
 | 
			
		||||
        if (Interface.Confirm("Delete Recording?")) {
 | 
			
		||||
           if (ri->recording->Delete()) {
 | 
			
		||||
              cOsdMenu::Del(Current());
 | 
			
		||||
              Display();
 | 
			
		||||
              }
 | 
			
		||||
           else
 | 
			
		||||
              Interface.Error("Error while deleting recording!");
 | 
			
		||||
           }
 | 
			
		||||
//XXX        }
 | 
			
		||||
//XXX     else
 | 
			
		||||
//XXX        Interface.Error("Timer is recording!");
 | 
			
		||||
     }
 | 
			
		||||
  return osContinue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cMenuRecordings::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  eOSState state = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
 | 
			
		||||
  if (state == osUnknown) {
 | 
			
		||||
     switch (Key) {
 | 
			
		||||
       case kOk:
 | 
			
		||||
       case kRed:    return Play();
 | 
			
		||||
       case kYellow: return Del();
 | 
			
		||||
       default: break;
 | 
			
		||||
       }
 | 
			
		||||
     }
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMenuMain -------------------------------------------------------------
 | 
			
		||||
@@ -724,22 +1001,21 @@ eOSStatus cMenuTimer::ProcessKey(eKeys Key)
 | 
			
		||||
cMenuMain::cMenuMain(void)
 | 
			
		||||
:cOsdMenu("Main")
 | 
			
		||||
{
 | 
			
		||||
  //TODO
 | 
			
		||||
  Add(new cOsdItem("Channels",   osChannels));
 | 
			
		||||
  Add(new cOsdItem("Timer",      osTimer));
 | 
			
		||||
  Add(new cOsdItem("Recordings", osRecordings));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cMenuMain::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cMenuMain::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  eOSStatus status = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
  eOSState state = cOsdMenu::ProcessKey(Key);
 | 
			
		||||
 | 
			
		||||
  switch (status) {
 | 
			
		||||
    case osChannels: return AddSubMenu(new cMenuChannels);
 | 
			
		||||
    case osTimer:    return AddSubMenu(new cMenuTimer);
 | 
			
		||||
    //TODO Replay
 | 
			
		||||
  switch (state) {
 | 
			
		||||
    case osChannels:   return AddSubMenu(new cMenuChannels);
 | 
			
		||||
    case osTimer:      return AddSubMenu(new cMenuTimers);
 | 
			
		||||
    case osRecordings: return AddSubMenu(new cMenuRecordings);
 | 
			
		||||
    default: break;
 | 
			
		||||
    }
 | 
			
		||||
  return status;
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								menu.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								menu.h
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: menu.h 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: menu.h 1.2 2000/03/05 10:57:27 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _MENU_H
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
class cMenuMain : public cOsdMenu {
 | 
			
		||||
public:
 | 
			
		||||
  cMenuMain(void);
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
#endif //_MENU_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										131
									
								
								osd.c
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								osd.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: osd.c 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: osd.c 1.2 2000/02/27 17:23:07 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "osd.h"
 | 
			
		||||
@@ -13,19 +13,19 @@
 | 
			
		||||
 | 
			
		||||
// --- cOsdItem --------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
cOsdItem::cOsdItem(eOSStatus Status)
 | 
			
		||||
cOsdItem::cOsdItem(eOSState State)
 | 
			
		||||
{
 | 
			
		||||
  text = NULL;
 | 
			
		||||
  offset = -1;
 | 
			
		||||
  status = Status;
 | 
			
		||||
  state = State;
 | 
			
		||||
  fresh = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cOsdItem::cOsdItem(char *Text, eOSStatus Status)
 | 
			
		||||
cOsdItem::cOsdItem(char *Text, eOSState State)
 | 
			
		||||
{
 | 
			
		||||
  text = NULL;
 | 
			
		||||
  offset = -1;
 | 
			
		||||
  status = Status;
 | 
			
		||||
  state = State;
 | 
			
		||||
  fresh = false;
 | 
			
		||||
  SetText(Text);
 | 
			
		||||
}
 | 
			
		||||
@@ -52,24 +52,27 @@ void cOsdItem::Display(int Offset, bool Current)
 | 
			
		||||
     Interface.WriteText(0, offset + 2, text, Current);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cOsdItem::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cOsdItem::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  return Key == kOk ? status : osUnknown;
 | 
			
		||||
  return Key == kOk ? state : osUnknown;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cOsdMenu --------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
cOsdMenu::cOsdMenu(char *Title, int c0, int c1, int c2, int c3, int c4)
 | 
			
		||||
{
 | 
			
		||||
  visible = false;
 | 
			
		||||
  title = strdup(Title);
 | 
			
		||||
  cols[0] = c0;
 | 
			
		||||
  cols[1] = c1;
 | 
			
		||||
  cols[2] = c2;
 | 
			
		||||
  cols[3] = c3;
 | 
			
		||||
  cols[4] = c4;
 | 
			
		||||
  first = count = 0;
 | 
			
		||||
  current = -1;
 | 
			
		||||
  first = 0;
 | 
			
		||||
  current = marked = -1;
 | 
			
		||||
  subMenu = NULL;
 | 
			
		||||
  helpRed = helpGreen = helpYellow = helpBlue = NULL;
 | 
			
		||||
  status = NULL;
 | 
			
		||||
  Interface.Open();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -77,40 +80,72 @@ cOsdMenu::~cOsdMenu()
 | 
			
		||||
{
 | 
			
		||||
  delete title;
 | 
			
		||||
  delete subMenu;
 | 
			
		||||
  delete status;
 | 
			
		||||
  Interface.Clear();
 | 
			
		||||
  Interface.Close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cOsdMenu::SetStatus(const char *s)
 | 
			
		||||
{
 | 
			
		||||
  delete status;
 | 
			
		||||
  status = s ? strdup(s) : NULL;
 | 
			
		||||
  if (visible)
 | 
			
		||||
     Interface.Status(status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cOsdMenu::SetHelp(const char *Red, const char *Green, const char *Yellow, const char *Blue)
 | 
			
		||||
{
 | 
			
		||||
  // strings are NOT copied - must be constants!!!
 | 
			
		||||
  helpRed    = Red;
 | 
			
		||||
  helpGreen  = Green;
 | 
			
		||||
  helpYellow = Yellow;
 | 
			
		||||
  helpBlue   = Blue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cOsdMenu::Del(int Index)
 | 
			
		||||
{
 | 
			
		||||
  cList<cOsdItem>::Del(Get(Index));
 | 
			
		||||
  if (current == Count())
 | 
			
		||||
     current--;
 | 
			
		||||
  if (Index == first && first > 0)
 | 
			
		||||
     first--;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cOsdMenu::Add(cOsdItem *Item, bool Current)
 | 
			
		||||
{
 | 
			
		||||
  cList<cOsdItem>::Add(Item);
 | 
			
		||||
  count++;
 | 
			
		||||
  if (Current && current < 0)
 | 
			
		||||
  if (Current)
 | 
			
		||||
     current = Item->Index();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cOsdMenu::Display(void)
 | 
			
		||||
{
 | 
			
		||||
  visible = true;
 | 
			
		||||
  Interface.Clear();
 | 
			
		||||
  Interface.SetCols(cols);
 | 
			
		||||
  Interface.WriteText(0, 0, title);
 | 
			
		||||
  if (current < 0 && count)
 | 
			
		||||
     current = 0; // just for safety - there HAS to be a current item!
 | 
			
		||||
  int n = 0;
 | 
			
		||||
  if (current - first >= MAXOSDITEMS) {
 | 
			
		||||
     first = current - MAXOSDITEMS / 2;
 | 
			
		||||
     if (first + MAXOSDITEMS > count)
 | 
			
		||||
        first = count - MAXOSDITEMS;
 | 
			
		||||
     if (first < 0)
 | 
			
		||||
        first = 0;
 | 
			
		||||
  Interface.Title(title);
 | 
			
		||||
  Interface.Help(helpRed, helpGreen, helpYellow, helpBlue);
 | 
			
		||||
  int count = Count();
 | 
			
		||||
  if (count > 0) {
 | 
			
		||||
     if (current < 0)
 | 
			
		||||
        current = 0; // just for safety - there HAS to be a current item!
 | 
			
		||||
     int n = 0;
 | 
			
		||||
     if (current - first >= MAXOSDITEMS) {
 | 
			
		||||
        first = current - MAXOSDITEMS / 2;
 | 
			
		||||
        if (first + MAXOSDITEMS > count)
 | 
			
		||||
           first = count - MAXOSDITEMS;
 | 
			
		||||
        if (first < 0)
 | 
			
		||||
           first = 0;
 | 
			
		||||
        }
 | 
			
		||||
     for (int i = first; i < count; i++) {
 | 
			
		||||
         cOsdItem *item = Get(i);
 | 
			
		||||
         if (item)
 | 
			
		||||
            item->Display(i - first, i == current);
 | 
			
		||||
         if (++n == MAXOSDITEMS) //TODO get this from Interface!!!
 | 
			
		||||
            break;
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
  for (int i = first; i < count; i++) {
 | 
			
		||||
      cOsdItem *item = Get(i);
 | 
			
		||||
      if (item)
 | 
			
		||||
         item->Display(i - first, i == current);
 | 
			
		||||
      if (++n == MAXOSDITEMS) //TODO get this from Interface!!!
 | 
			
		||||
         break;
 | 
			
		||||
      }
 | 
			
		||||
  Interface.Status(status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cOsdMenu::RefreshCurrent(void)
 | 
			
		||||
@@ -144,6 +179,7 @@ void cOsdMenu::CursorUp(void)
 | 
			
		||||
 | 
			
		||||
void cOsdMenu::CursorDown(void)
 | 
			
		||||
{
 | 
			
		||||
  int count = Count();
 | 
			
		||||
  if (current < count - 1) {
 | 
			
		||||
     DisplayCurrent(false);
 | 
			
		||||
     if (++current >= first + MAXOSDITEMS) {
 | 
			
		||||
@@ -157,7 +193,15 @@ void cOsdMenu::CursorDown(void)
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cOsdMenu::AddSubMenu(cOsdMenu *SubMenu)
 | 
			
		||||
void cOsdMenu::Mark(void)
 | 
			
		||||
{
 | 
			
		||||
  if (Count() && marked < 0) {
 | 
			
		||||
     marked = current;
 | 
			
		||||
     SetStatus("Up/Dn for new location - OK to move");
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cOsdMenu::AddSubMenu(cOsdMenu *SubMenu)
 | 
			
		||||
{
 | 
			
		||||
  delete subMenu;
 | 
			
		||||
  subMenu = SubMenu;
 | 
			
		||||
@@ -165,31 +209,40 @@ eOSStatus cOsdMenu::AddSubMenu(cOsdMenu *SubMenu)
 | 
			
		||||
  return osContinue; // convenience return value (see cMenuMain)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSStatus cOsdMenu::ProcessKey(eKeys Key)
 | 
			
		||||
eOSState cOsdMenu::ProcessKey(eKeys Key)
 | 
			
		||||
{
 | 
			
		||||
  if (subMenu) {
 | 
			
		||||
     eOSStatus status = subMenu->ProcessKey(Key);
 | 
			
		||||
     if (status == osBack) {
 | 
			
		||||
     eOSState state = subMenu->ProcessKey(Key);
 | 
			
		||||
     if (state == osBack) {
 | 
			
		||||
        delete subMenu;
 | 
			
		||||
        subMenu = NULL;
 | 
			
		||||
        RefreshCurrent();
 | 
			
		||||
        Display();
 | 
			
		||||
        status = osContinue;
 | 
			
		||||
        state = osContinue;
 | 
			
		||||
        }
 | 
			
		||||
     return status;
 | 
			
		||||
     return state;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
  cOsdItem *item = Get(current);
 | 
			
		||||
  if (item) {
 | 
			
		||||
     eOSStatus status = item->ProcessKey(Key);
 | 
			
		||||
     if (status != osUnknown)
 | 
			
		||||
        return status;
 | 
			
		||||
  if (marked < 0 && item) {
 | 
			
		||||
     eOSState state = item->ProcessKey(Key);
 | 
			
		||||
     if (state != osUnknown)
 | 
			
		||||
        return state;
 | 
			
		||||
     }
 | 
			
		||||
  switch (Key) {
 | 
			
		||||
    case kUp:   CursorUp();   break;
 | 
			
		||||
    case kDown: CursorDown(); break;
 | 
			
		||||
    case kBack: return osBack;
 | 
			
		||||
    default: return osUnknown;
 | 
			
		||||
    case kOk:   if (marked >= 0) {
 | 
			
		||||
                   SetStatus(NULL);
 | 
			
		||||
                   if (marked != current)
 | 
			
		||||
                      Move(marked, current);
 | 
			
		||||
                   marked = -1;
 | 
			
		||||
                   break;
 | 
			
		||||
                   }
 | 
			
		||||
                // else run into default
 | 
			
		||||
    default: if (marked < 0)
 | 
			
		||||
                return osUnknown;
 | 
			
		||||
    }
 | 
			
		||||
  return osContinue;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										42
									
								
								osd.h
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								osd.h
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: osd.h 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: osd.h 1.2 2000/03/05 11:33:11 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __OSD_H
 | 
			
		||||
@@ -16,53 +16,61 @@
 | 
			
		||||
 | 
			
		||||
#define MAXOSDITEMS 9
 | 
			
		||||
 | 
			
		||||
enum eOSStatus { osUnknown,
 | 
			
		||||
                 osContinue,
 | 
			
		||||
                 osProcessed,
 | 
			
		||||
                 osChannels,
 | 
			
		||||
                 osTimer,
 | 
			
		||||
                 osRecordings,
 | 
			
		||||
                 osBack,
 | 
			
		||||
                 osEnd,
 | 
			
		||||
               };
 | 
			
		||||
enum eOSState { osUnknown,
 | 
			
		||||
                osContinue,
 | 
			
		||||
                osProcessed,
 | 
			
		||||
                osChannels,
 | 
			
		||||
                osTimer,
 | 
			
		||||
                osRecordings,
 | 
			
		||||
                osBack,
 | 
			
		||||
                osEnd,
 | 
			
		||||
              };
 | 
			
		||||
 | 
			
		||||
class cOsdItem : public cListObject {
 | 
			
		||||
private:
 | 
			
		||||
  char *text;
 | 
			
		||||
  int offset;
 | 
			
		||||
  eOSStatus status;
 | 
			
		||||
  eOSState state;
 | 
			
		||||
protected:
 | 
			
		||||
  bool fresh;
 | 
			
		||||
public:
 | 
			
		||||
  cOsdItem(eOSStatus Status = osUnknown);
 | 
			
		||||
  cOsdItem(char *Text, eOSStatus Status = osUnknown);
 | 
			
		||||
  cOsdItem(eOSState State = osUnknown);
 | 
			
		||||
  cOsdItem(char *Text, eOSState State = osUnknown);
 | 
			
		||||
  virtual ~cOsdItem();
 | 
			
		||||
  void SetText(char *Text, bool Copy = true);
 | 
			
		||||
  char *Text(void) { return text; }
 | 
			
		||||
  void Display(int Offset = -1, bool Current = false);
 | 
			
		||||
  virtual void Set(void) {}
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
class cOsdMenu : public cList<cOsdItem> {
 | 
			
		||||
private:
 | 
			
		||||
  char *title;
 | 
			
		||||
  int cols[cInterface::MaxCols];
 | 
			
		||||
  int first, current, count;
 | 
			
		||||
  int first, current, marked;
 | 
			
		||||
  cOsdMenu *subMenu;
 | 
			
		||||
  const char *helpRed, *helpGreen, *helpYellow, *helpBlue;
 | 
			
		||||
  const char *status;
 | 
			
		||||
protected:
 | 
			
		||||
  bool visible;
 | 
			
		||||
  void RefreshCurrent(void);
 | 
			
		||||
  void DisplayCurrent(bool Current);
 | 
			
		||||
  void CursorUp(void);
 | 
			
		||||
  void CursorDown(void);
 | 
			
		||||
  eOSStatus AddSubMenu(cOsdMenu *SubMenu);
 | 
			
		||||
  void Mark(void);
 | 
			
		||||
  eOSState AddSubMenu(cOsdMenu *SubMenu);
 | 
			
		||||
  bool HasSubMenu(void) { return subMenu; }
 | 
			
		||||
  void SetStatus(const char *s);
 | 
			
		||||
  void SetHelp(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
 | 
			
		||||
  virtual void Del(int Index);
 | 
			
		||||
public:
 | 
			
		||||
  cOsdMenu(char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0);
 | 
			
		||||
  virtual ~cOsdMenu();
 | 
			
		||||
  int Current(void) { return current; }
 | 
			
		||||
  void Add(cOsdItem *Item, bool Current = false);
 | 
			
		||||
  void Display(void);
 | 
			
		||||
  virtual eOSStatus ProcessKey(eKeys Key);
 | 
			
		||||
  virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
#endif //__OSD_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										57
									
								
								osm.c
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								osm.c
									
									
									
									
									
								
							@@ -22,13 +22,13 @@
 | 
			
		||||
 *
 | 
			
		||||
 * The project's page is at http://www.cadsoft.de/people/kls/vdr
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: osm.c 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: osm.c 1.2 2000/03/05 17:18:15 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "dvbapi.h"
 | 
			
		||||
#include "interface.h"
 | 
			
		||||
#include "menu.h"
 | 
			
		||||
#include "recording.h"
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_REMOTE
 | 
			
		||||
@@ -52,39 +52,39 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
  cMenuMain *Menu = NULL;
 | 
			
		||||
  cTimer *Timer = NULL;
 | 
			
		||||
  cDvbRecorder *Recorder = NULL;
 | 
			
		||||
  cRecording *Recording = NULL;
 | 
			
		||||
 | 
			
		||||
  for (;;) {
 | 
			
		||||
      //TODO check for free disk space and delete files if necessary/possible
 | 
			
		||||
      //     in case there is an ongoing recording
 | 
			
		||||
      if (!Timer && (Timer = cTimer::GetMatch()) != NULL) {
 | 
			
		||||
      AssertFreeDiskSpace();
 | 
			
		||||
      if (!Recording && !Timer && (Timer = cTimer::GetMatch()) != NULL) {
 | 
			
		||||
         DELETENULL(Menu);
 | 
			
		||||
         // make sure the timer won't be deleted:
 | 
			
		||||
         Timer->SetRecording(true);
 | 
			
		||||
         // switch to channel:
 | 
			
		||||
         isyslog(LOG_INFO, "timer %d start", Timer->Index() + 1);
 | 
			
		||||
         delete Menu;
 | 
			
		||||
         Menu = NULL;
 | 
			
		||||
         cChannel::SwitchTo(Timer->channel - 1);
 | 
			
		||||
         ChannelLocked = true;
 | 
			
		||||
         // start recording:
 | 
			
		||||
         delete Recorder;
 | 
			
		||||
         Recorder = new cDvbRecorder;
 | 
			
		||||
         //TODO special filename handling!!!
 | 
			
		||||
         if (!Recorder->Record(Timer->file, Timer->quality)) {
 | 
			
		||||
            delete Recorder;
 | 
			
		||||
            Recorder = NULL;
 | 
			
		||||
            }
 | 
			
		||||
         Recording = new cRecording(Timer);
 | 
			
		||||
         if (!Recording->Record())
 | 
			
		||||
            DELETENULL(Recording);
 | 
			
		||||
         }
 | 
			
		||||
      if (Timer) {
 | 
			
		||||
         if (!Timer->Matches()) {
 | 
			
		||||
            // stop recording:
 | 
			
		||||
            if (Recorder)
 | 
			
		||||
               Recorder->Stop();
 | 
			
		||||
            // end timer:
 | 
			
		||||
            ChannelLocked = false;
 | 
			
		||||
            isyslog(LOG_INFO, "timer %d stop", Timer->Index() + 1);
 | 
			
		||||
            Timer = NULL;
 | 
			
		||||
            //TODO switch back to the previous channel???
 | 
			
		||||
            //TODO clear single event timer???
 | 
			
		||||
      if (Timer && !Timer->Matches()) {
 | 
			
		||||
         // stop recording:
 | 
			
		||||
         if (Recording) {
 | 
			
		||||
            Recording->Stop();
 | 
			
		||||
            DELETENULL(Recording);
 | 
			
		||||
            }
 | 
			
		||||
         // release channel and timer:
 | 
			
		||||
         ChannelLocked = false;
 | 
			
		||||
         Timer->SetRecording(false);
 | 
			
		||||
         // clear single event timer:
 | 
			
		||||
         if (Timer->IsSingleEvent()) {
 | 
			
		||||
            DELETENULL(Menu); // must make sure no menu uses it
 | 
			
		||||
            isyslog(LOG_INFO, "deleting timer %d", Timer->Index() + 1);
 | 
			
		||||
            Timers.Del(Timer);
 | 
			
		||||
            Timers.Save();
 | 
			
		||||
            }
 | 
			
		||||
         Timer = NULL;
 | 
			
		||||
         }
 | 
			
		||||
      eKeys key = Interface.GetKey();
 | 
			
		||||
      if (Menu) {
 | 
			
		||||
@@ -92,8 +92,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
           default: if (key != kMenu)
 | 
			
		||||
                       break;
 | 
			
		||||
           case osBack:
 | 
			
		||||
           case osEnd: delete Menu;
 | 
			
		||||
                       Menu = NULL;
 | 
			
		||||
           case osEnd: DELETENULL(Menu);
 | 
			
		||||
                       break;
 | 
			
		||||
           }
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										238
									
								
								recording.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								recording.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,238 @@
 | 
			
		||||
/*
 | 
			
		||||
 * recording.h: Recording file handling
 | 
			
		||||
 *
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: recording.c 1.1 2000/03/05 17:16:22 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "recording.h"
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "interface.h"
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
 | 
			
		||||
#define RECEXT       ".rec"
 | 
			
		||||
#define DELEXT       ".del"
 | 
			
		||||
#define DATAFORMAT   "%4d-%02d-%02d.%02d:%02d.%c.%02d.%02d" RECEXT
 | 
			
		||||
#define NAMEFORMAT   "%s/%s/" DATAFORMAT
 | 
			
		||||
 | 
			
		||||
#define FINDCMD      "find %s -type f -name '%s'"
 | 
			
		||||
 | 
			
		||||
#define DFCMD        "df -m %s"
 | 
			
		||||
#define MINDISKSPACE 1024 // MB
 | 
			
		||||
 | 
			
		||||
const char *BaseDir = "/video";//XXX
 | 
			
		||||
 | 
			
		||||
cDvbRecorder *Recorder = NULL;
 | 
			
		||||
 | 
			
		||||
static bool LowDiskSpace(void)
 | 
			
		||||
{
 | 
			
		||||
  //TODO Find a simpler way to determine the amount of free disk space!
 | 
			
		||||
  bool result = true;
 | 
			
		||||
  char *cmd = NULL;
 | 
			
		||||
  asprintf(&cmd, DFCMD, BaseDir);
 | 
			
		||||
  FILE *p = popen(cmd, "r");
 | 
			
		||||
  if (p) {
 | 
			
		||||
     char *s;
 | 
			
		||||
     while ((s = readline(p)) != NULL) {
 | 
			
		||||
           if (*s == '/') {
 | 
			
		||||
              int available;
 | 
			
		||||
              sscanf(s, "%*s %*d %*d %d", &available);
 | 
			
		||||
              result = available < MINDISKSPACE;
 | 
			
		||||
              break;
 | 
			
		||||
              }
 | 
			
		||||
           }
 | 
			
		||||
     pclose(p);
 | 
			
		||||
     }
 | 
			
		||||
  else
 | 
			
		||||
     esyslog(LOG_ERR, "ERROR: can't open pipe for cmd '%s'", cmd);
 | 
			
		||||
  delete cmd;
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AssertFreeDiskSpace(void)
 | 
			
		||||
{
 | 
			
		||||
  // With every call to this function we try to actually remove
 | 
			
		||||
  // a file, or mark a file for removal ("delete" it), so that
 | 
			
		||||
  // it will get removed during the next call.
 | 
			
		||||
  if (Recorder && Recorder->Recording() && LowDiskSpace()) {
 | 
			
		||||
     // Remove the oldest file that has been "deleted":
 | 
			
		||||
     cRecordings Recordings;
 | 
			
		||||
     if (Recordings.Load(true)) {
 | 
			
		||||
        cRecording *r = Recordings.First();
 | 
			
		||||
        cRecording *r0 = r;
 | 
			
		||||
        while (r) {
 | 
			
		||||
              if (r->start < r0->start)
 | 
			
		||||
                 r0 = r;
 | 
			
		||||
              r = Recordings.Next(r);
 | 
			
		||||
              }
 | 
			
		||||
        if (r0 && r0->Remove())
 | 
			
		||||
           return;
 | 
			
		||||
        }
 | 
			
		||||
     // No "deleted" files to remove, so let's see if we can delete a recording:
 | 
			
		||||
     if (Recordings.Load(false)) {
 | 
			
		||||
        cRecording *r = Recordings.First();
 | 
			
		||||
        cRecording *r0 = NULL;
 | 
			
		||||
        while (r) {
 | 
			
		||||
              if ((time(NULL) - r->start) / SECSINDAY > r->lifetime) {
 | 
			
		||||
                 if (r0) {
 | 
			
		||||
                    if (r->priority < r0->priority)
 | 
			
		||||
                       r0 = r;
 | 
			
		||||
                    }
 | 
			
		||||
                 else
 | 
			
		||||
                    r0 = r;
 | 
			
		||||
                 }
 | 
			
		||||
              r = Recordings.Next(r);
 | 
			
		||||
              }
 | 
			
		||||
        if (r0 && r0->Delete())
 | 
			
		||||
           return;
 | 
			
		||||
        }
 | 
			
		||||
     // Unable to free disk space, but there's nothing we can do about that...
 | 
			
		||||
     //TODO maybe a log entry - but make sure it doesn't come too often
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cRecording ------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
cRecording::cRecording(const char *Name, time_t Start, char Quality, int Priority, int LifeTime)
 | 
			
		||||
{
 | 
			
		||||
  fileName = NULL;
 | 
			
		||||
  name = strdup(Name);
 | 
			
		||||
  start = Start;
 | 
			
		||||
  quality = Quality;
 | 
			
		||||
  priority = Priority;
 | 
			
		||||
  lifetime = LifeTime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cRecording::cRecording(cTimer *Timer)
 | 
			
		||||
{
 | 
			
		||||
  fileName = NULL;
 | 
			
		||||
  name = strdup(Timer->file);
 | 
			
		||||
  start = Timer->StartTime();
 | 
			
		||||
  quality = Timer->quality;
 | 
			
		||||
  priority = Timer->priority;
 | 
			
		||||
  lifetime = Timer->lifetime;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cRecording::cRecording(const char *FileName)
 | 
			
		||||
{
 | 
			
		||||
  fileName = strdup(FileName);
 | 
			
		||||
  FileName += strlen(BaseDir) + 1;
 | 
			
		||||
  char *p = strrchr(FileName, '/');
 | 
			
		||||
 | 
			
		||||
  name = NULL;
 | 
			
		||||
  if (p) {
 | 
			
		||||
     time_t now = time(NULL);
 | 
			
		||||
     struct tm t = *localtime(&now); // this initializes the time zone in 't'
 | 
			
		||||
     if (8 == sscanf(p + 1, DATAFORMAT, &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &quality, &priority, &lifetime)) {
 | 
			
		||||
        t.tm_year -= 1900;
 | 
			
		||||
        t.tm_mon--;
 | 
			
		||||
        t.tm_sec = 0;
 | 
			
		||||
        start = mktime(&t);
 | 
			
		||||
        name = new char[p - FileName + 1];
 | 
			
		||||
        strncpy(name, FileName, p - FileName);
 | 
			
		||||
        name[p - FileName] = 0;
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cRecording::~cRecording()
 | 
			
		||||
{
 | 
			
		||||
  delete fileName;
 | 
			
		||||
  delete name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *cRecording::FileName(void)
 | 
			
		||||
{
 | 
			
		||||
  if (!fileName) {
 | 
			
		||||
     struct tm *t = localtime(&start);
 | 
			
		||||
     asprintf(&fileName, NAMEFORMAT, BaseDir, name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, quality, priority, lifetime);
 | 
			
		||||
     }
 | 
			
		||||
  return fileName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cRecording::Delete(void)
 | 
			
		||||
{
 | 
			
		||||
  bool result = true;
 | 
			
		||||
  char *NewName = strdup(FileName());
 | 
			
		||||
  char *ext = strrchr(NewName, '.');
 | 
			
		||||
  if (strcmp(ext, RECEXT) == 0) {
 | 
			
		||||
     strncpy(ext, DELEXT, strlen(ext));
 | 
			
		||||
     isyslog(LOG_INFO, "deleting recording %s", FileName());
 | 
			
		||||
     if (rename(FileName(), NewName) == -1) {
 | 
			
		||||
        esyslog(LOG_ERR, "ERROR: %s", strerror(errno));
 | 
			
		||||
        result = false;
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  delete NewName;
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cRecording::Remove(void)
 | 
			
		||||
{
 | 
			
		||||
  bool result = true;
 | 
			
		||||
  isyslog(LOG_INFO, "removing recording %s", FileName());
 | 
			
		||||
  if (remove(FileName()) == -1) {
 | 
			
		||||
     esyslog(LOG_ERR, "ERROR: %s", strerror(errno));
 | 
			
		||||
     result = false;
 | 
			
		||||
     }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cRecording::AssertRecorder(void)
 | 
			
		||||
{
 | 
			
		||||
  if (!Recorder || !Recorder->Recording()) {
 | 
			
		||||
     if (!Recorder)
 | 
			
		||||
        Recorder = new cDvbRecorder;
 | 
			
		||||
     return true;
 | 
			
		||||
     }
 | 
			
		||||
  Interface.Error("Recorder is in use!");
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cRecording::Record(void)
 | 
			
		||||
{
 | 
			
		||||
  return AssertRecorder() && Recorder->Record(FileName(), quality);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cRecording::Play(void)
 | 
			
		||||
{
 | 
			
		||||
  return AssertRecorder() && Recorder->Play(FileName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cRecording::Stop(void)
 | 
			
		||||
{
 | 
			
		||||
  if (Recorder)
 | 
			
		||||
     Recorder->Stop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cRecordings -----------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
bool cRecordings::Load(bool Deleted)
 | 
			
		||||
{
 | 
			
		||||
  Clear();
 | 
			
		||||
  bool result = false;
 | 
			
		||||
  char *cmd = NULL;
 | 
			
		||||
  asprintf(&cmd, FINDCMD, BaseDir, Deleted ? "*" DELEXT : "*" RECEXT);
 | 
			
		||||
  FILE *p = popen(cmd, "r");
 | 
			
		||||
  if (p) {
 | 
			
		||||
     char *s;
 | 
			
		||||
     while ((s = readline(p)) != NULL) {
 | 
			
		||||
           cRecording *r = new cRecording(s);
 | 
			
		||||
           if (r->name)
 | 
			
		||||
              Add(r);
 | 
			
		||||
           else
 | 
			
		||||
              delete r;
 | 
			
		||||
           }
 | 
			
		||||
     pclose(p);
 | 
			
		||||
     result = Count() > 0;
 | 
			
		||||
     }
 | 
			
		||||
  else
 | 
			
		||||
     Interface.Error("Error while opening pipe!");
 | 
			
		||||
  delete cmd;
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										56
									
								
								recording.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								recording.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
/*
 | 
			
		||||
 * recording.h: Recording file handling
 | 
			
		||||
 *
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: recording.h 1.1 2000/03/05 15:57:27 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __RECORDING_H
 | 
			
		||||
#define __RECORDING_H
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "dvbapi.h"
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
 | 
			
		||||
extern cDvbRecorder *Recorder;
 | 
			
		||||
 | 
			
		||||
void AssertFreeDiskSpace(void);
 | 
			
		||||
 | 
			
		||||
class cRecording : public cListObject {
 | 
			
		||||
private:
 | 
			
		||||
  bool AssertRecorder(void);
 | 
			
		||||
public:
 | 
			
		||||
  char *name;
 | 
			
		||||
  char *fileName;
 | 
			
		||||
  time_t start;
 | 
			
		||||
  char quality;
 | 
			
		||||
  int priority;
 | 
			
		||||
  int lifetime;
 | 
			
		||||
  cRecording(const char *Name, time_t Start, char Quality, int Priority, int LifeTime);
 | 
			
		||||
  cRecording(cTimer *Timer);
 | 
			
		||||
  cRecording(const char *FileName);
 | 
			
		||||
  ~cRecording();
 | 
			
		||||
  const char *FileName(void);
 | 
			
		||||
  bool Delete(void);
 | 
			
		||||
       // Changes the file name so that it will no longer be visible in the OSM
 | 
			
		||||
       // Returns false in case of error
 | 
			
		||||
  bool Remove(void);
 | 
			
		||||
       // Actually removes the file from the disk
 | 
			
		||||
       // Returns false in case of error
 | 
			
		||||
  bool Record(void);
 | 
			
		||||
       // Starts recording of the file
 | 
			
		||||
  bool Play(void);
 | 
			
		||||
       // Starts playback of the file
 | 
			
		||||
  void Stop(void);
 | 
			
		||||
       // Stops recording or playback of the file
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
class cRecordings : public cList<cRecording> {
 | 
			
		||||
public:
 | 
			
		||||
  bool Load(bool Deleted = false);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
#endif //__RECORDING_H
 | 
			
		||||
							
								
								
									
										11
									
								
								timers.conf
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								timers.conf
									
									
									
									
									
								
							@@ -1,9 +1,6 @@
 | 
			
		||||
1:2:-----S-:2210:2320:H:99:99:Wochenshow
 | 
			
		||||
1:3:M------:2125:2205:H:99:99:Neues
 | 
			
		||||
1:2:-----S-:2205:2320:H:99:99:Wochenshow
 | 
			
		||||
0:15:M------:2125:2205:H:99:99:Neues
 | 
			
		||||
1:15:MTWTF--:1828:1901:M:10:5:nano
 | 
			
		||||
1:2:-----S-:1737:1827:H:99:99:kls/StarTrek/DS9
 | 
			
		||||
1:3:M------:2110:2230:H:99:99:SevenDays
 | 
			
		||||
1:3:---T---:2215:2300:H:99:99:SwItch
 | 
			
		||||
0:1:1:0:0:H:99:99:#
 | 
			
		||||
0:1:1:0:0:H:99:99:#
 | 
			
		||||
0:1:1:0:0:L:0:5:#
 | 
			
		||||
1:3:---T---:2215:2300:H:99:99:Switch
 | 
			
		||||
1:14:------S:2210:2255:H:99:99:Olli
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										71
									
								
								tools.c
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								tools.c
									
									
									
									
									
								
							@@ -4,13 +4,30 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: tools.c 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: tools.c 1.2 2000/03/05 14:33:58 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
#define MaxBuffer 1000
 | 
			
		||||
 | 
			
		||||
char *readline(FILE *f)
 | 
			
		||||
{
 | 
			
		||||
  static char buffer[MaxBuffer];
 | 
			
		||||
  if (fgets(buffer, sizeof(buffer), f) > 0) {
 | 
			
		||||
     int l = strlen(buffer) - 1;
 | 
			
		||||
     if (l >= 0 && buffer[l] == '\n')
 | 
			
		||||
        buffer[l] = 0;
 | 
			
		||||
     return buffer;
 | 
			
		||||
     }
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int time_ms(void)
 | 
			
		||||
{
 | 
			
		||||
  struct timeval t;
 | 
			
		||||
@@ -19,6 +36,30 @@ int time_ms(void)
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MakeDirs(const char *FileName)
 | 
			
		||||
{
 | 
			
		||||
  bool result = true;
 | 
			
		||||
  char *s = strdup(FileName);
 | 
			
		||||
  char *p = s;
 | 
			
		||||
  if (*p == '/')
 | 
			
		||||
     p++;
 | 
			
		||||
  while ((p = strchr(p, '/')) != NULL) {
 | 
			
		||||
        *p = 0;
 | 
			
		||||
        struct stat fs;
 | 
			
		||||
        if (stat(s, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
 | 
			
		||||
           isyslog(LOG_INFO, "creating directory %s", s);
 | 
			
		||||
           if (mkdir(s, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) {
 | 
			
		||||
              esyslog(LOG_ERR, "ERROR while creating directory %s: %s", s, strerror(errno));
 | 
			
		||||
              result = false;
 | 
			
		||||
              break;
 | 
			
		||||
              }
 | 
			
		||||
           }
 | 
			
		||||
        *p++ = '/';
 | 
			
		||||
        }
 | 
			
		||||
  delete s;
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cListObject -----------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
cListObject::cListObject(void)
 | 
			
		||||
@@ -42,6 +83,7 @@ void cListObject::Unlink(void)
 | 
			
		||||
     next->prev = prev;
 | 
			
		||||
  if (prev)
 | 
			
		||||
     prev->next = next;
 | 
			
		||||
  next = prev = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cListObject::Index(void)
 | 
			
		||||
@@ -92,6 +134,33 @@ void cListBase::Del(cListObject *Object)
 | 
			
		||||
  delete Object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cListBase::Move(int From, int To)
 | 
			
		||||
{
 | 
			
		||||
  Move(Get(From), Get(To));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cListBase::Move(cListObject *From, cListObject *To)
 | 
			
		||||
{
 | 
			
		||||
  if (From && To) {
 | 
			
		||||
     if (From->Index() < To->Index())
 | 
			
		||||
        To = To->Next();
 | 
			
		||||
     if (From == objects)
 | 
			
		||||
        objects = From->Next();
 | 
			
		||||
     if (From == lastObject)
 | 
			
		||||
        lastObject = From->Prev();
 | 
			
		||||
     From->Unlink();
 | 
			
		||||
     if (To) {
 | 
			
		||||
        if (To->Prev())
 | 
			
		||||
           To->Prev()->Append(From);
 | 
			
		||||
        From->Append(To);
 | 
			
		||||
        }
 | 
			
		||||
     else
 | 
			
		||||
        lastObject->Append(From);
 | 
			
		||||
     if (!From->Prev())
 | 
			
		||||
        objects = From;
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cListBase::Clear(void)
 | 
			
		||||
{
 | 
			
		||||
  while (objects) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								tools.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								tools.h
									
									
									
									
									
								
							@@ -4,12 +4,13 @@
 | 
			
		||||
 * See the main source file 'osm.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: tools.h 1.1 2000/02/19 13:36:48 kls Exp $
 | 
			
		||||
 * $Id: tools.h 1.2 2000/03/05 16:14:05 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __TOOLS_H
 | 
			
		||||
#define __TOOLS_H
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
 | 
			
		||||
//TODO
 | 
			
		||||
@@ -17,6 +18,14 @@
 | 
			
		||||
#define esyslog syslog
 | 
			
		||||
#define isyslog syslog
 | 
			
		||||
 | 
			
		||||
#define SECSINDAY  86400
 | 
			
		||||
 | 
			
		||||
#define DELETENULL(p) (delete (p), p = NULL)
 | 
			
		||||
 | 
			
		||||
char *readline(FILE *f);
 | 
			
		||||
int time_ms(void);
 | 
			
		||||
bool MakeDirs(const char *FileName);
 | 
			
		||||
 | 
			
		||||
class cListObject {
 | 
			
		||||
private:
 | 
			
		||||
  cListObject *prev, *next;
 | 
			
		||||
@@ -38,6 +47,8 @@ public:
 | 
			
		||||
  virtual ~cListBase();
 | 
			
		||||
  void Add(cListObject *Object);
 | 
			
		||||
  void Del(cListObject *Object);
 | 
			
		||||
  void Move(int From, int To);
 | 
			
		||||
  void Move(cListObject *From, cListObject *To);
 | 
			
		||||
  void Clear(void);
 | 
			
		||||
  cListObject *Get(int Index);
 | 
			
		||||
  int Count(void);
 | 
			
		||||
@@ -47,8 +58,7 @@ template<class T> class cList : public cListBase {
 | 
			
		||||
public:
 | 
			
		||||
  T *Get(int Index) { return (T *)cListBase::Get(Index); }
 | 
			
		||||
  T *First(void) { return (T *)objects; }
 | 
			
		||||
  T *Next(T *object) { return (T *)object->Next(); }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
int time_ms(void);
 | 
			
		||||
 | 
			
		||||
#endif //__TOOLS_H
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user