Logo Search packages:      
Sourcecode: vdr-plugin-console version File versions

engine.h

/*
 * console.h: A plugin for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id: engine.h,v 1.1 2004/10/24 12:57:09 chelli-guest Exp $
 */


#ifndef __ENGINE_H__
#define __ENGINE_H__


#include <sys/ioctl.h>
#include <termios.h>

#include <vdr/tools.h>
#include <vdr/remote.h>

#include "ipc.h"


#define CONSOLE_DEBUG( xx )
//#define CONSOLE_DEBUG( xx ) xx;


// This program will be used to realize a console.
// Be carefull! If your VDR runs as root, then every
// user can kill your machine if you don't protect
// the cnsoles.
// So the default is "/bin/login".

#ifdef CONSOLE_USE_SHELL_INSTEAD_LOGIN
#define PROG_FOR_CONSOLE "/bin/sh"
#else
#define PROG_FOR_CONSOLE "/bin/login"
#endif




// With the small font there are many cells possible
#define CONSOLE_MAXCOLS 100
#define CONSOLE_MAXROWS 50

#define INPUT_BUFSIZE 1024




// define used keys

#define BS  '\010'      // Backspace
#define HT  '\011'      // Horizontal Tab
#define LF  '\012'      // Line Feed
#define VT  '\013'      // Vertical Tab
#define FF  '\014'      // Form Feed
#define CR  '\015'      // Carriage Return
#define SO  '\016'      // Shift out
#define SI  '\017'      // Shift in

#define CAN '\030'      // Cancel
#define SUB '\032'      // Substitude
#define ESC '\033'      // Escape


// New keys that are not specified through keys.h
// Be carefull! It could be that these keys will
// be used some day from VDR itself.
#define kRefresh 1002








enum eConScreenState {
  eCssNormal = 0,
  eCssEscape,
  eCssEscapeParameter,
  eCssEscapeSingleCode,
  eCssSelectCharSetG0,
  eCssSelectCharSetG1
};



struct sConScreenChar {

  sConScreenChar()
  : ch          (' '),
    foreColor   (0),
    backColor   (0),

    Bold        (false),
    Underscore  (false),
    Blink       (false),
    Inverted    (false),
    Concealed   (false),
    useFore     (false),
    useBack     (false)
  {}
  
  sConScreenChar( unsigned char Ch, const sConScreenChar& attr )
  : ch          (Ch),
    foreColor   (attr.foreColor),
    backColor   (attr.backColor),

    Bold        (attr.Bold),
    Underscore  (attr.Underscore),
    Blink       (attr.Blink),
    Inverted    (attr.Inverted),
    Concealed   (attr.Concealed),
    useFore     (attr.useFore),
    useBack     (attr.useBack)
  {}
  
  unsigned char ch;
  
  unsigned char foreColor : 4;
  unsigned char backColor : 4;
  
  bool Bold : 1;
  bool Underscore : 1;
  bool Blink : 1;
  bool Inverted : 1;
  bool Concealed : 1;
  bool useFore : 1;
  bool useBack : 1;
};



struct sConScreenCursorPos {

  sConScreenCursorPos( int X, int Y, const sConScreenChar& Attributes, bool ModeOrigin, sConScreenCursorPos* Prev )
  : x            (X), 
    y            (Y), 
    attributes   (Attributes),
    modeOrigin   (ModeOrigin),
    prev         (Prev)
  {}

  int x, y;
  sConScreenChar attributes;
  bool modeOrigin;

  sConScreenCursorPos* prev;
};




class cTerminalEmulation
{
private:
  int _w, _h;
  sConScreenChar* _screen[ CONSOLE_MAXROWS ];

  int _curX, _curY;
  sConScreenCursorPos* _curPosSaved;

  int _scrollRegionTop, _scrollRegionBottom;

  bool _modeCurVisible;
  bool _modeOrigin;
  bool _modeWrapAround;
  bool _modeInsert;
  bool _modeNewLine;

  eConScreenState _state;

  int* _escapeParams;
  int _escapeParamsCount;

  bool _changed, _bell;

  sConScreenChar _defaultChar;

  int _tabs[ CONSOLE_MAXCOLS ];

  cMutex _mutex;
  bool _wantRefreshEvent;

  unsigned char _charSet[ 256 ];

  int _fd;

private:
  void Changed();

  void Clear( int fromX = 0, int fromY = 0, int toX = -1, int toY = -1 );
  void ScrollUp( int Count = 1 ) { ScrollUp( Count, _scrollRegionTop ); }
  void ScrollUp( int Count, int FromLine );
  void ScrollDown( int Count = 1 ) { ScrollDown( Count, _scrollRegionTop ); }
  void ScrollDown( int Count, int FromLine );

  void decodeEscapeSequence( char code );
  void decodeEscapeCode( char code );
  void decodeEscapeSingleCode( char code );

  void tabStopClear();
  void tabStopAdd( int tabstop );
  void tabStopRemove( int tabstop );

  void keyCarriageReturn();
  void keyLineFeed( bool NewLine );
  void keyBackspace();
  void keyDelete();
  void keyTab();
  void keyInsert( unsigned char ch = ' ' );
  void keyBell();

  void setAttributes( int* attributes, int count );

  void setModes( int* attributes, int count );
  void resetModes( int* attributes, int count );
  void setModeCurVisible( bool visible );
  void setModeOrigin( bool origin );

  void ClearToEnd();
  void ClearFromBegin();
  void ClearLine();

  void InsertChar( int count );
  void DeleteChar( int count );
  void InsertLine( int count );
  void DeleteLine( int count );

  void reportDeviceStatus( int request );
  void reportDeviceAttributes( int request );

  void MoveTo( int col, int row );
  void MoveRelative( int d_col, int d_row );

  void setScrollRegion( int top, int bottom );

  void CursorPosSave();
  void CursorPosRestore();

  void Write( unsigned char ch );

  void SelectCharSet( int g, char set );

public:
  cTerminalEmulation();
  virtual ~cTerminalEmulation();

  void setOutputFileDescriptor( int fd ) { _fd = fd; }
  void Write( const unsigned char* stream );

  const sConScreenChar** getScreen() { return (const sConScreenChar**)_screen; }

  int getW() { return _w; }
  int getH() { return _h; }
  bool setSize( int w, int h );
  int getCursorX() { return _curX; }
  int getCursorY() { return _modeOrigin ? _curY - _scrollRegionTop : _curY; }
  bool getCursorVisible() { return _modeCurVisible; }

  bool ToRefresh() { return _changed; }
  void Refreshed();
  bool ToRing() { return _bell; }
  void BellSeen();

  cMutex* getMutex() { return &_mutex; }
  void WantRefreshEvent( bool WantIt ) { _wantRefreshEvent = WantIt; }
};




class cConsoles;



class cVirtualConsole
: public cListObject,
  public IWaitable
{

  friend class cConsoles;

private:

  unsigned char _buf[ INPUT_BUFSIZE + 1 ];

  volatile int _childPid;
  int _master;
  bool _isOpen;

  char* _title;

  cTerminalEmulation _screen;

private:
  bool Open(const char* command, char* const argv[]);
  bool ConsoleWaitPid(volatile int& pid, int timeoutMs);
  bool HandleOutput();


public:
  cVirtualConsole(const char* title, const char* command, char* const argv[]);
  virtual ~cVirtualConsole();

  bool IsOpen();

  bool Close();
  void HasClosed( bool force = false );

  void setTerminalSize( int charW, int charH, int pixelW, int pixelH );

  void Write( const unsigned char* data, int len );

  const char* getTitle() { return _title; }
  cTerminalEmulation& getScreen() { return _screen; }
  pid_t getChildPid() { return _childPid; }


// IWaitable
  virtual int SignalToWaitFor() const { return _master; }
};



// ----- cConsoles --------------------------------------------------------------------------





class cConsoles
: public cThread
{
private:

  cList<cVirtualConsole> _consoles;

  int _inputActive;
  struct termios _oldTerminalSettings;

  cSignal _consolesChanged;
  cWaitableList _wait;

  volatile bool _terminate;

private:
  virtual void Action();

public:
  cConsoles();
  ~cConsoles();

  virtual bool Start();

  void activateInputForTerminal();
  void deactivateInputForTerminal();
  void Flush(int WaitMs);
  void WantAllRefreshEvents( bool WantIt );


  int getCount() { LOCK_THREAD; return _consoles.Count(); }
  cVirtualConsole& getItem( int index0 ) { LOCK_THREAD; return *_consoles.Get(index0); }

  int CreateConsole();
  int CreateCommand(const char* title, const char* command);
  void Remove(cVirtualConsole* pConsole);

  static bool Active();
};


extern cConsoles* gl_pConsoles;



#endif // __ENGINE_H__


Generated by  Doxygen 1.6.0   Back to index