printf("Status Running, kBack\n");
namespace Mhp {/* --------- Control ------------- */Messages::Message Messages::message = Messages::NoMessage;const char *ConfigPath = 0;//static functionvoid Messages::DisplayMessage(Message m) {   message=m;}Control::Control()  : cControl (player=new Player(this)), app(0){   status=Waiting;      display=0;   visible=false;   doShow=true;      appName=unknownName=tr("<unknown name>");}Control::~Control() {   // Hide shall only be called from main thread, but we are in main thread because   // cControl objects are always deleted by VDR from main thread.   Hide();   // Do not call Stop() directly, there may be a race condition since Stop() may be called from any thread.   // ShutdownControl() calls Stop(), is thread safe and cleanly sets the status for RunningManager.   ((ControlRunningManager *)RunningManager::getManager())->ShutdownControl();}// Shall only be called from VDR's main threadvoid Control::Hide(void) {   if (visible) {      delete display;      display=0;      //Interface->Close();      visible=false;   }}void Control::Stop() {   printf("Control::Stop()\n");   //set status to Stopped so that osEnd is returned when ProcessKey is called again   //(asynchronous stop)   status=Stopped;   delete player;   player=0;   Messages::message=Messages::NoMessage;}eOSState Control::ProcessKey(eKeys Key) {   //status shall be set to Waiting if and only if returning osEnd   switch (status) {   case Stopped:      status=Waiting;      return osEnd;   case Waiting:      break;   /*case Loading:     {      switch (Key) {      case kBack:         Hide();         Stop();         status=Waiting;         return osEnd;      case kOk:         if (visible) {            doShow=false;            Hide();         } else            doShow=true;      default:         ControlLoadingManager::getManager()->ProgressInfo(this);         CheckMessage();      }      break;    }*/   case Running:      switch (Key) {      case kBack:         printf("Status Running, kBack\n");         RunningManager::getManager()->Stop(app);         ((ControlRunningManager *)RunningManager::getManager())->ShutdownControl();         status=Waiting;         return osEnd;      case kNone:         LoadingManager::getManager()->ProgressInfo(this);         CheckMessage();         break;      default:         JavaInterface::ProcessKey(Key);      }      break;   }   return osContinue;}// Shall only be called from VDR's main threadvoid Control::CheckMessage() {   switch (Messages::message) {   case Messages::NoMessage:      break;   case Messages::LoadingFailed:      Skins.Message(mtError, tr("Loading failed"));      break;   case Messages::StartingFailed:      Skins.Message(mtError, tr("Starting failed"));      break;   case Messages::OutputSystemError:      Skins.Message(mtError, tr("Error in output system: Plugin disabled"));      break;  case Messages::JavaSystemError:      Skins.Message(mtError, tr("Error in Java system: Plugin disabled"));      break;  case Messages::JavaStartError:      Skins.Message(mtError, tr("Error while starting Java environment"));      break;  case Messages::AlreadyRunning:      Skins.Message(mtInfo, tr("The application has already been started"));   }   Messages::message=Messages::NoMessage;}// Shall only be called from VDR's main threadvoid Control::ShowProgress(float progress, int currentSize, int totalSize) {   if (!doShow)      return;   if (!visible) {      display = Skins.Current()->DisplayReplay(false);      char *title;      if (asprintf(&title, tr("Loading %s"), appName.c_str()) != -1) {         display->SetTitle(title);         free(title);      }      visible=true;   }   //int progressPercentage=(int)(100.0 *progress);   display->SetProgress(currentSize, totalSize);   char text[32];   snprintf(text, sizeof(text), "%d B", currentSize);   display->SetCurrent(text);   if (totalSize != 0) {      //initially, totalSize maybe 0, don't display this      snprintf(text, sizeof(text), "%d B", totalSize);      display->SetTotal(text);   }   }void Control::SetApplicationName(const std::string &a) {   appName=a;}// Shall only be called from VDR's main threadvoid Control::HideProgress() {   Hide();   appName=unknownName;}void Control::SetApplication(ApplicationInfo::cApplication::Ptr a) {   app=a;}//#include <dfb++/dfb++.h>//#include <libmhpoutput/output.h>void Control::StartMhp() {   printf("Control::StartMhp()\n");   if (status==Stopped)      return;   //Check that everything essential is working, as far as we can see it.   /*if (!JavaInterface::CheckStart()) {      Hide();      Messages::DisplayMessage(Messages::JavaStartError);      CheckMessage();      Stop();      return;   }*/   //Now the ApplicationManager in the Java stack will take control.   //It will interact with the ControlLoadingManager if necessary,    //also starting DSMCC downloads.   //Control's ProcessKey will call ControlLoadingManager::ProgressInfo   //to take care for OSD progress display if necessary.   if (app && JavaInterface::StartApplication(app)) {      status=Running;      //Actually activate output on TV      player->ActivateParent();   }      //Simple testcase for the output system   /*player->ActivateParent();   IDirectFBDisplayLayer *l=MhpOutput::System::self()->GetMainLayer();   try {     IDirectFBWindow       *window, *   window2;     DFBWindowDescription  desc;     //l->SetCooperativeLevel(DLSCL_EXCLUSIVE);     desc.flags=(DFBWindowDescriptionFlags)0;          if (!getenv( "MHP_NO_ALPHA" )) {          desc.caps=(DFBWindowCapabilities)0;          DFB_ADD_WINDOW_DESC(desc.flags, DWDESC_CAPS);          DFB_ADD_WINDOW_CAPS(desc.caps, DWCAPS_ALPHACHANNEL);          DFB_ADD_WINDOW_CAPS(desc.caps, DWCAPS_DOUBLEBUFFER);     }          DFB_ADD_WINDOW_DESC(desc.flags, DWDESC_POSX);          desc.posx = 0;          DFB_ADD_WINDOW_DESC(desc.flags, DWDESC_POSY);          desc.posy = 0;          DFB_ADD_WINDOW_DESC(desc.flags, DWDESC_WIDTH);          desc.width = 720;          DFB_ADD_WINDOW_DESC(desc.flags, DWDESC_HEIGHT);          desc.height = 576;      window=l->CreateWindow(desc);      desc.posx=100;desc.posy=100;desc.width=100;desc.height=75;      window2=l->CreateWindow(desc);      window->SetStackingClass(DWSC_MIDDLE);      window2->SetStackingClass(DWSC_UPPER);      IDirectFBSurface *s=window->GetSurface();      IDirectFBSurface *s2=window2->GetSurface();            DFBFontDescription fdesc;fdesc.flags=DFDESC_HEIGHT;fdesc.height=25;      IDirectFBFont *font=MhpOutput::System::self()->Interface()->CreateFont("/usr/local/vdr/mhp/data/fonts/vera.ttf", fdesc);      //IDirec   printf("RunningManager: Notified about start of application %p\n", a.getPointer());tFBSurface *s=l->GetSurface();      printf("Starting to draw\n");      s->SetDrawingFlags(DSDRAW_BLEND);      s->SetColor(255, 0, 0, 255);      s->FillRectangle(5, 5, 300, 450);      s->SetColor(230, 230, 230, 124);      s->FillTriangle(300, 20, 20, 500, 500, 550);      s->SetColor(0, 0, 0, 255);      s->SetFont(font);      s->DrawString("Hallo, was soll das?", 20, 300, 250, DSTF_LEFT);      s->Flip();      s2->SetColor(0, 0, 0, 0);      s2->FillRectangle(0,0,100,75);      s2->SetColor(120, 120, 0, 120);      s2->FillTriangle(20,20,70,20,45,70);      s2->Flip();      window->SetOpacity(0xff);      window2->SetOpacity(0xff);      printf("Drawn\n");      //l->GetSurface()->Blit(s, 0, 0, 0);      //IDirectFBSurface *ls=l->GetSurface();      //void *ptr;      //int pitch;      //s->Lock(DSLF_READ, &ptr, &pitch);      //FILE *fd=fopen("surface.rgb", "w");      //int width, height;      //s->GetSize(&width, &height);      //printf("Dumping surface of format %d, %dx%d, %d, address %p\n", s->GetPixelFormat(), width, height, pitch, ptr);      //fwrite(ptr, DFB_BYTES_PER_LINE(s->GetPixelFormat(), width)*height, 1, fd);      //fclose(fd);      //s->Unlock();            //window->Release();      //window2->Release();      //s->Release();      //s2->Release();   } catch (DFBException *e) {      printf("DirectFB: Error %s, %s\n", e->GetAction(), e->GetResult());      delete e;   }*/     }/* --------- Player ------------- */Player::~Player() {   Detach();}void Player::Activate(bool On) {   //printf("Player::Activate %d\n", On);   if (On) {      //intercept activation to display loading progress      control->StartMhp();   } else       MhpOutput::Player::Activate(On);}void Player::ActivateParent() {   MhpOutput::Player::Activate(true);}/* --------- RunningManager and ControlRunningManager ------------- *//*   The running manager handles the starting of applications initiated   from the ApplicationMenu or possibly other parts of the VDR plugin in contrast   two the facilities provided by the ApplicationManager and the org.dvb.application   package on the Java side. This Java code keeps the state machine for applications   and is perfectly capable of initiating loading and starting itself. It will   however inform the RunningManager about starting and stopping.   The RunningManager keeps a list of running applications, creates and launches the   cControl object when the first application is started and deletes it when   the last application is stopped.   In theory multiple applications can run concurrently, but this will only be   initiated from the Java stack. The running manager has the notion of a   foreground application which is launched from the ApplicationMenu. Launching   another application via the RunningManager will therefore cause the currently running   one to be stopped.      This policy may be adapted to future needs.*/RunningManager *RunningManager::s_self=0;RunningManager *RunningManager::getManager() {   if (!s_self)      s_self=new ControlRunningManager;   return s_self;}RunningManager::RunningManager() {   s_self = this;}RunningManager::~RunningManager() {   s_self = 0;}ControlRunningManager::ControlRunningManager()   : foregroundApp(0), control(0){}