<commit_before>// @(#)root/eg:$Name:  $:$Id: TParticle.cxx,v 1.5 2001/03/23 18:04:50 brun Exp $
// Author: Rene Brun , Federico Carminati  26/04/99

#include "TView.h"
#include "TVirtualPad.h"
#include "TPolyLine3D.h"
#include "TDatabasePDG.h"
#include "TParticle.h"

ClassImp(TParticle)

//______________________________________________________________________________
TParticle::TParticle()
{
  fParticlePDG = 0;
}

//______________________________________________________________________________
TParticle::TParticle(Int_t pdg,       Int_t status,
                     Int_t mother1,   Int_t mother2,
                     Int_t daughter1, Int_t daughter2,
                     Double_t px, Double_t py, Double_t pz, Double_t etot,
                     Double_t vx, Double_t vy, Double_t vz, Double_t time):
  fPdgCode(pdg), fStatusCode(status), fWeight(1.),fPx(px), fPy(py),
  fPz(pz), fE(etot), fVx(vx), fVy(vy), fVz(vz), fVt(time)
{
  fMother[0]   = mother1;
  fMother[1]   = mother2;
  fDaughter[0] = daughter1;
  fDaughter[1] = daughter2;

  SetPolarisation(0,0,0);

  fParticlePDG = TDatabasePDG::Instance()->GetParticle(pdg);
  if (fParticlePDG) {
     fCalcMass    = fParticlePDG->Mass();
  } else {
     Double_t a2 = fE*fE -fPx*fPx -fPy*fPy -fPz*fPz;
     if (a2 >= 0) fCalcMass =  TMath::Sqrt(a2);
     else         fCalcMass = -TMath::Sqrt(-a2);
  }
}

//______________________________________________________________________________
TParticle::TParticle(Int_t pdg,       Int_t status,
                     Int_t mother1,   Int_t mother2,
                     Int_t daughter1, Int_t daughter2,
                     const TLorentzVector &p,
                     const TLorentzVector &v) :
  fPdgCode(pdg), fStatusCode(status), fWeight(1.),fPx(p.Px()), fPy(p.Py()),
  fPz(p.Pz()), fE(p.E()), fVx(v.X()), fVy(v.Y()), fVz(v.Z()), fVt(v.T())
{
  fMother[0]   = mother1;
  fMother[1]   = mother2;
  fDaughter[0] = daughter1;
  fDaughter[1] = daughter2;

  SetPolarisation(0,0,0);

  fParticlePDG = TDatabasePDG::Instance()->GetParticle(pdg);
  if (fParticlePDG) {
     fCalcMass    = fParticlePDG->Mass();
  } else {
     Double_t a2 = fE*fE -fPx*fPx -fPy*fPy -fPz*fPz;
     if (a2 >= 0) fCalcMass =  TMath::Sqrt(a2);
     else         fCalcMass = -TMath::Sqrt(-a2);
  }
}

//______________________________________________________________________________
TParticle::TParticle(const TParticle &p)
{
    // copy constructor

   *this = p;
}

//______________________________________________________________________________
TParticle::~TParticle()
{
}

//______________________________________________________________________________
Int_t TParticle::DistancetoPrimitive(Int_t px, Int_t py)
{
//*-*-*-*-*-*-*-*Compute distance from point px,py to a primary track*-*-*-*
//*-*            ====================================================
//*-*
//*-*  Compute the closest distance of approach from point px,py to each segment
//*-*  of a track.
//*-*  The distance is computed in pixels units.
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

   const Int_t big = 9999;
   Float_t xv[3], xe[3], xndc[3];
   Float_t rmin[3], rmax[3];
   TView *view = gPad->GetView();
   if(!view) return big;

   // compute first and last point in pad coordinates
   Float_t pmom = this->P();
   if (pmom == 0) return big;
   view->GetRange(rmin,rmax);
   Float_t rbox = rmax[2];
   xv[0] = fVx;
   xv[1] = fVy;
   xv[2] = fVz;
   xe[0] = xv[0]+rbox*fPx/pmom;
   xe[1] = xv[1]+rbox*fPy/pmom;
   xe[2] = xv[2]+rbox*fPz/pmom;
   view->WCtoNDC(xv, xndc);
   Float_t x1 = xndc[0];
   Float_t y1 = xndc[1];
   view->WCtoNDC(xe, xndc);
   Float_t x2 = xndc[0];
   Float_t y2 = xndc[1];

   return DistancetoLine(px,py,x1,y1,x2,y2);
}

//______________________________________________________________________________
void TParticle::ExecuteEvent(Int_t, Int_t, Int_t)
{
//*-*-*-*-*-*-*-*-*-*-*Execute action corresponding to one event*-*-*-*
//*-*                  =========================================

   gPad->SetCursor(kPointer);
}

//______________________________________________________________________________
const char* TParticle::GetName() const {
   static char def[4] = "XXX";
   const TParticlePDG *ap = TDatabasePDG::Instance()->GetParticle(fPdgCode);
   if (ap) return ap->GetName();
   else    return def;
}

//______________________________________________________________________________
TParticlePDG*  TParticle::GetPDG(Int_t mode)
{
// returns a pointer to the TParticlePDG object using the pdgcode
// if mode == 0 (default) always get a fresh value for the pointer.
// if mode != 0 this function returns directly the previously
//              computed pointer from a previous call
// One can use mode=1 (faster) when the TParticle object is not part of a
// TClonesArray used in split mode in a Root TTree.

  if (!mode || !fParticlePDG) {
     (((TParticle*)this)->fParticlePDG = TDatabasePDG::Instance()->GetParticle(fPdgCode));
     // when mutable will be allowed, change above line to the following line
     //   fParticlePDG = TDatabasePDG::Instance()->GetParticle(fPdgCode);}
  }
  return fParticlePDG;
}

//______________________________________________________________________________
void TParticle::GetPolarisation(TVector3 &v)
{
  if(fPolarTheta == -99 && fPolarPhi == -99)
    //No polarisation to return
    v.SetXYZ(0.,0.,0.);
  else
    v.SetXYZ(TMath::Cos(fPolarPhi)*TMath::Sin(fPolarTheta),
             TMath::Sin(fPolarPhi)*TMath::Sin(fPolarTheta),
             TMath::Cos(fPolarTheta));
}

//______________________________________________________________________________
const char *TParticle::GetTitle() const
{
   static char def[4] = "XXX";
   const TParticlePDG *ap = TDatabasePDG::Instance()->GetParticle(fPdgCode);
   if (ap) return ap->GetTitle();
   else    return def;
}

//______________________________________________________________________________
void TParticle::Paint(Option_t *option)
{
//
//  Paint a primary track
//
   Float_t rmin[3], rmax[3];
   static TPolyLine3D *pline = 0;
   if (!pline) {
      pline = new TPolyLine3D(2);
   }
   Float_t pmom = this->P();
   if (pmom == 0) return;
   TView *view = gPad->GetView();
   if (!view) return;
   view->GetRange(rmin,rmax);
   Float_t rbox = rmax[2];
   pline->SetPoint(0,Vx(), Vy(), Vz());
   Float_t xend = Vx()+rbox*Px()/pmom;
   Float_t yend = Vy()+rbox*Py()/pmom;
   Float_t zend = Vz()+rbox*Pz()/pmom;
   pline->SetPoint(1, xend, yend, zend);
   pline->SetLineColor(GetLineColor());
   pline->SetLineStyle(GetLineStyle());
   pline->SetLineWidth(GetLineWidth());
   pline->Paint(option);
}

//______________________________________________________________________________
void TParticle::Print(Option_t *) const
{
//
//  Print the internals of the primary vertex particle
//
   //TParticlePDG* pdg = ((TParticle*)this)->GetPDG();
   Printf("TParticle: %-13s  p: %8f %8f %8f Vertex: %8e %8e %8e %5d %5d %s",
          GetName(),Px(),Py(),Pz(),Vx(),Vy(),Vz(),
          fMother[0],fMother[1]);
}

//______________________________________________________________________________
void TParticle::SetPolarisation(Double_t polx, Double_t poly, Double_t polz)
{
  if(polx || poly || polz) {
    fPolarTheta = TMath::ACos(polz/TMath::Sqrt(polx*polx+poly*poly+polz*polz));
    fPolarPhi   = kPI+TMath::ATan2(-poly,-polx);
  } else {
    fPolarTheta = -99;
    fPolarPhi = -99;
  }
}

//______________________________________________________________________________
void TParticle::Sizeof3D() const
{
//*-*-*-*-*-*Return total X3D size of this primary*-*-*-*-*-*-*
//*-*        =====================================

   Float_t pmom = this->P();
   if (pmom == 0) return;
   Int_t npoints = 2;
   gSize3D.numPoints += npoints;
   gSize3D.numSegs   += (npoints-1);
   gSize3D.numPolys  += 0;

}

//______________________________________________________________________________
void TParticle::Streamer(TBuffer &R__b)
{
   // Stream an object of class TParticle.

   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      if (R__v > 1) {
         TParticle::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
         fParticlePDG = TDatabasePDG::Instance()->GetParticle(fPdgCode);
         return;
      }
      //====process old versions before automatic schema evolution
      TObject::Streamer(R__b);
      TAttLine::Streamer(R__b);
      R__b >> fPdgCode;
      R__b >> fStatusCode;
      R__b.ReadStaticArray(fMother);
      R__b.ReadStaticArray(fDaughter);
      R__b >> fWeight;
      R__b >> fCalcMass;
      R__b >> fPx;
      R__b >> fPy;
      R__b >> fPz;
      R__b >> fE;
      R__b >> fVx;
      R__b >> fVy;
      R__b >> fVz;
      R__b >> fVt;
      R__b >> fPolarTheta;
      R__b >> fPolarPhi;
      fParticlePDG = TDatabasePDG::Instance()->GetParticle(fPdgCode);
      R__b.CheckByteCount(R__s, R__c, TParticle::IsA());
      //====end of old versions

   } else {
      TParticle::Class()->WriteBuffer(R__b,this);
   }
}
<commit_msg>Preset all members of TParticle in the default constructor.<commit_after>// @(#)root/eg:$Name:  $:$Id: TParticle.cxx,v 1.6 2001/08/23 22:11:48 brun Exp $
// Author: Rene Brun , Federico Carminati  26/04/99

#include "TView.h"
#include "TVirtualPad.h"
#include "TPolyLine3D.h"
#include "TDatabasePDG.h"
#include "TParticle.h"

ClassImp(TParticle)

//______________________________________________________________________________
TParticle::TParticle() :
  fPdgCode(0), fStatusCode(0), fWeight(0),fCalcMass(0), fPx(0), fPy(0),
  fPz(0), fE(0), fVx(0), fVy(0), fVz(0), fVt(0), fPolarTheta(0), fPolarPhi(0)
{
  fMother[0]   = 0;
  fMother[1]   = 0;
  fDaughter[0] = 0;
  fDaughter[1] = 0;
  fParticlePDG = 0;
}

//______________________________________________________________________________
TParticle::TParticle(Int_t pdg,       Int_t status,
                     Int_t mother1,   Int_t mother2,
                     Int_t daughter1, Int_t daughter2,
                     Double_t px, Double_t py, Double_t pz, Double_t etot,
                     Double_t vx, Double_t vy, Double_t vz, Double_t time):
  fPdgCode(pdg), fStatusCode(status), fWeight(1.),fPx(px), fPy(py),
  fPz(pz), fE(etot), fVx(vx), fVy(vy), fVz(vz), fVt(time)
{
  fMother[0]   = mother1;
  fMother[1]   = mother2;
  fDaughter[0] = daughter1;
  fDaughter[1] = daughter2;

  SetPolarisation(0,0,0);

  fParticlePDG = TDatabasePDG::Instance()->GetParticle(pdg);
  if (fParticlePDG) {
     fCalcMass    = fParticlePDG->Mass();
  } else {
     Double_t a2 = fE*fE -fPx*fPx -fPy*fPy -fPz*fPz;
     if (a2 >= 0) fCalcMass =  TMath::Sqrt(a2);
     else         fCalcMass = -TMath::Sqrt(-a2);
  }
}

//______________________________________________________________________________
TParticle::TParticle(Int_t pdg,       Int_t status,
                     Int_t mother1,   Int_t mother2,
                     Int_t daughter1, Int_t daughter2,
                     const TLorentzVector &p,
                     const TLorentzVector &v) :
  fPdgCode(pdg), fStatusCode(status), fWeight(1.),fPx(p.Px()), fPy(p.Py()),
  fPz(p.Pz()), fE(p.E()), fVx(v.X()), fVy(v.Y()), fVz(v.Z()), fVt(v.T())
{
  fMother[0]   = mother1;
  fMother[1]   = mother2;
  fDaughter[0] = daughter1;
  fDaughter[1] = daughter2;

  SetPolarisation(0,0,0);

  fParticlePDG = TDatabasePDG::Instance()->GetParticle(pdg);
  if (fParticlePDG) {
     fCalcMass    = fParticlePDG->Mass();
  } else {
     Double_t a2 = fE*fE -fPx*fPx -fPy*fPy -fPz*fPz;
     if (a2 >= 0) fCalcMass =  TMath::Sqrt(a2);
     else         fCalcMass = -TMath::Sqrt(-a2);
  }
}

//______________________________________________________________________________
TParticle::TParticle(const TParticle &p)
{
    // copy constructor

   *this = p;
}

//______________________________________________________________________________
TParticle::~TParticle()
{
}

//______________________________________________________________________________
Int_t TParticle::DistancetoPrimitive(Int_t px, Int_t py)
{
//*-*-*-*-*-*-*-*Compute distance from point px,py to a primary track*-*-*-*
//*-*            ====================================================
//*-*
//*-*  Compute the closest distance of approach from point px,py to each segment
//*-*  of a track.
//*-*  The distance is computed in pixels units.
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

   const Int_t big = 9999;
   Float_t xv[3], xe[3], xndc[3];
   Float_t rmin[3], rmax[3];
   TView *view = gPad->GetView();
   if(!view) return big;

   // compute first and last point in pad coordinates
   Float_t pmom = this->P();
   if (pmom == 0) return big;
   view->GetRange(rmin,rmax);
   Float_t rbox = rmax[2];
   xv[0] = fVx;
   xv[1] = fVy;
   xv[2] = fVz;
   xe[0] = xv[0]+rbox*fPx/pmom;
   xe[1] = xv[1]+rbox*fPy/pmom;
   xe[2] = xv[2]+rbox*fPz/pmom;
   view->WCtoNDC(xv, xndc);
   Float_t x1 = xndc[0];
   Float_t y1 = xndc[1];
   view->WCtoNDC(xe, xndc);
   Float_t x2 = xndc[0];
   Float_t y2 = xndc[1];

   return DistancetoLine(px,py,x1,y1,x2,y2);
}

//______________________________________________________________________________
void TParticle::ExecuteEvent(Int_t, Int_t, Int_t)
{
//*-*-*-*-*-*-*-*-*-*-*Execute action corresponding to one event*-*-*-*
//*-*                  =========================================

   gPad->SetCursor(kPointer);
}

//______________________________________________________________________________
const char* TParticle::GetName() const {
   static char def[4] = "XXX";
   const TParticlePDG *ap = TDatabasePDG::Instance()->GetParticle(fPdgCode);
   if (ap) return ap->GetName();
   else    return def;
}

//______________________________________________________________________________
TParticlePDG*  TParticle::GetPDG(Int_t mode)
{
// returns a pointer to the TParticlePDG object using the pdgcode
// if mode == 0 (default) always get a fresh value for the pointer.
// if mode != 0 this function returns directly the previously
//              computed pointer from a previous call
// One can use mode=1 (faster) when the TParticle object is not part of a
// TClonesArray used in split mode in a Root TTree.

  if (!mode || !fParticlePDG) {
     (((TParticle*)this)->fParticlePDG = TDatabasePDG::Instance()->GetParticle(fPdgCode));
     // when mutable will be allowed, change above line to the following line
     //   fParticlePDG = TDatabasePDG::Instance()->GetParticle(fPdgCode);}
  }
  return fParticlePDG;
}

//______________________________________________________________________________
void TParticle::GetPolarisation(TVector3 &v)
{
  if(fPolarTheta == -99 && fPolarPhi == -99)
    //No polarisation to return
    v.SetXYZ(0.,0.,0.);
  else
    v.SetXYZ(TMath::Cos(fPolarPhi)*TMath::Sin(fPolarTheta),
             TMath::Sin(fPolarPhi)*TMath::Sin(fPolarTheta),
             TMath::Cos(fPolarTheta));
}

//______________________________________________________________________________
const char *TParticle::GetTitle() const
{
   static char def[4] = "XXX";
   const TParticlePDG *ap = TDatabasePDG::Instance()->GetParticle(fPdgCode);
   if (ap) return ap->GetTitle();
   else    return def;
}

//______________________________________________________________________________
void TParticle::Paint(Option_t *option)
{
//
//  Paint a primary track
//
   Float_t rmin[3], rmax[3];
   static TPolyLine3D *pline = 0;
   if (!pline) {
      pline = new TPolyLine3D(2);
   }
   Float_t pmom = this->P();
   if (pmom == 0) return;
   TView *view = gPad->GetView();
   if (!view) return;
   view->GetRange(rmin,rmax);
   Float_t rbox = rmax[2];
   pline->SetPoint(0,Vx(), Vy(), Vz());
   Float_t xend = Vx()+rbox*Px()/pmom;
   Float_t yend = Vy()+rbox*Py()/pmom;
   Float_t zend = Vz()+rbox*Pz()/pmom;
   pline->SetPoint(1, xend, yend, zend);
   pline->SetLineColor(GetLineColor());
   pline->SetLineStyle(GetLineStyle());
   pline->SetLineWidth(GetLineWidth());
   pline->Paint(option);
}

//______________________________________________________________________________
void TParticle::Print(Option_t *) const
{
//
//  Print the internals of the primary vertex particle
//
   //TParticlePDG* pdg = ((TParticle*)this)->GetPDG();
   Printf("TParticle: %-13s  p: %8f %8f %8f Vertex: %8e %8e %8e %5d %5d %s",
          GetName(),Px(),Py(),Pz(),Vx(),Vy(),Vz(),
          fMother[0],fMother[1]);
}

//______________________________________________________________________________
void TParticle::SetPolarisation(Double_t polx, Double_t poly, Double_t polz)
{
  if(polx || poly || polz) {
    fPolarTheta = TMath::ACos(polz/TMath::Sqrt(polx*polx+poly*poly+polz*polz));
    fPolarPhi   = kPI+TMath::ATan2(-poly,-polx);
  } else {
    fPolarTheta = -99;
    fPolarPhi = -99;
  }
}

//______________________________________________________________________________
void TParticle::Sizeof3D() const
{
//*-*-*-*-*-*Return total X3D size of this primary*-*-*-*-*-*-*
//*-*        =====================================

   Float_t pmom = this->P();
   if (pmom == 0) return;
   Int_t npoints = 2;
   gSize3D.numPoints += npoints;
   gSize3D.numSegs   += (npoints-1);
   gSize3D.numPolys  += 0;

}

//______________________________________________________________________________
void TParticle::Streamer(TBuffer &R__b)
{
   // Stream an object of class TParticle.

   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      if (R__v > 1) {
         TParticle::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
         fParticlePDG = TDatabasePDG::Instance()->GetParticle(fPdgCode);
         return;
      }
      //====process old versions before automatic schema evolution
      TObject::Streamer(R__b);
      TAttLine::Streamer(R__b);
      R__b >> fPdgCode;
      R__b >> fStatusCode;
      R__b.ReadStaticArray(fMother);
      R__b.ReadStaticArray(fDaughter);
      R__b >> fWeight;
      R__b >> fCalcMass;
      R__b >> fPx;
      R__b >> fPy;
      R__b >> fPz;
      R__b >> fE;
      R__b >> fVx;
      R__b >> fVy;
      R__b >> fVz;
      R__b >> fVt;
      R__b >> fPolarTheta;
      R__b >> fPolarPhi;
      fParticlePDG = TDatabasePDG::Instance()->GetParticle(fPdgCode);
      R__b.CheckByteCount(R__s, R__c, TParticle::IsA());
      //====end of old versions

   } else {
      TParticle::Class()->WriteBuffer(R__b,this);
   }
}
<|endoftext|>


<commit_before>#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

#include <io/pipe.h>

#include <zlib/inflate_pipe.h>

#define	INFLATE_CHUNK_SIZE	65536

InflatePipe::InflatePipe(void)
: PipeSimple("/zlib/inflate_pipe"),
  stream_()
{
	stream_.zalloc = Z_NULL;
	stream_.zfree = Z_NULL;
	stream_.opaque = Z_NULL;

	stream_.avail_in = 0;
	stream_.next_in = Z_NULL;

	int error = inflateInit(&stream_);
	if (error != Z_OK)
		HALT(log_) << "Could not initialize inflate stream.";
}

InflatePipe::~InflatePipe()
{
	int error = inflateEnd(&stream_);
	if (error != Z_OK)
		ERROR(log_) << "Inflate stream did not end cleanly.";
}

bool
InflatePipe::process(Buffer *out, Buffer *in)
{
	uint8_t outbuf[INFLATE_CHUNK_SIZE];
	bool first = true;

	stream_.avail_out = sizeof outbuf;
	stream_.next_out = outbuf;

	for (;;) {
		Buffer::SegmentIterator iter = in->segments();
		const BufferSegment *seg;
		int flush;

		if (iter.end()) {
			seg = NULL;
			flush = first ? Z_FINISH : Z_SYNC_FLUSH;

			stream_.avail_in = 0;
			stream_.next_in = Z_NULL;
		} else {
			seg = *iter;
			flush = Z_NO_FLUSH;
			first = false;

			stream_.avail_in = seg->length();
			stream_.next_in = (Bytef *)(uintptr_t)seg->data();
		}

		for (;;) {
			int error = inflate(&stream_, flush);
			if (error == Z_OK && stream_.avail_out > 0 &&
			    flush == Z_NO_FLUSH)
				break;
			if (error == Z_NEED_DICT || error == Z_DATA_ERROR ||
			    error == Z_MEM_ERROR)
				return (false);

			if (flush == Z_SYNC_FLUSH && error == Z_BUF_ERROR &&
			    stream_.avail_out == sizeof outbuf)
				error = Z_OK;

			out->append(outbuf, sizeof outbuf - stream_.avail_out);
			stream_.avail_out = sizeof outbuf;
			stream_.next_out = outbuf;

			if (flush == Z_NO_FLUSH)
				break;
			if (flush != Z_NO_FLUSH && error == Z_OK)
				return (true);
			if (error == Z_STREAM_END)
				return (true);
			/* More data to output.  */
		}

		if (seg != NULL)
			in->skip(seg->length() - stream_.avail_in);
	}
	NOTREACHED();
}
<commit_msg>Handle Z_BUF_ERROR on Z_FINISH like on Z_SYNC_FLUSH.<commit_after>#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

#include <io/pipe.h>

#include <zlib/inflate_pipe.h>

#define	INFLATE_CHUNK_SIZE	65536

InflatePipe::InflatePipe(void)
: PipeSimple("/zlib/inflate_pipe"),
  stream_()
{
	stream_.zalloc = Z_NULL;
	stream_.zfree = Z_NULL;
	stream_.opaque = Z_NULL;

	stream_.avail_in = 0;
	stream_.next_in = Z_NULL;

	int error = inflateInit(&stream_);
	if (error != Z_OK)
		HALT(log_) << "Could not initialize inflate stream.";
}

InflatePipe::~InflatePipe()
{
	int error = inflateEnd(&stream_);
	if (error != Z_OK)
		ERROR(log_) << "Inflate stream did not end cleanly.";
}

bool
InflatePipe::process(Buffer *out, Buffer *in)
{
	uint8_t outbuf[INFLATE_CHUNK_SIZE];
	bool first = true;

	stream_.avail_out = sizeof outbuf;
	stream_.next_out = outbuf;

	for (;;) {
		Buffer::SegmentIterator iter = in->segments();
		const BufferSegment *seg;
		int flush;

		if (iter.end()) {
			seg = NULL;
			flush = first ? Z_FINISH : Z_SYNC_FLUSH;

			stream_.avail_in = 0;
			stream_.next_in = Z_NULL;
		} else {
			seg = *iter;
			flush = Z_NO_FLUSH;
			first = false;

			stream_.avail_in = seg->length();
			stream_.next_in = (Bytef *)(uintptr_t)seg->data();
		}

		for (;;) {
			int error = inflate(&stream_, flush);
			if (error == Z_OK && stream_.avail_out > 0 &&
			    flush == Z_NO_FLUSH)
				break;
			if (error == Z_NEED_DICT || error == Z_DATA_ERROR ||
			    error == Z_MEM_ERROR)
				return (false);

			if (flush != Z_NO_FLUSH && error == Z_BUF_ERROR &&
			    stream_.avail_out == sizeof outbuf)
				error = Z_OK;

			out->append(outbuf, sizeof outbuf - stream_.avail_out);
			stream_.avail_out = sizeof outbuf;
			stream_.next_out = outbuf;

			if (flush == Z_NO_FLUSH)
				break;
			if (error == Z_OK || error == Z_STREAM_END)
				return (true);
			/* More data to output.  */
		}

		if (seg != NULL)
			in->skip(seg->length() - stream_.avail_in);
	}
	NOTREACHED();
}
<|endoftext|>


<commit_before>/*******************************************************************************/
/* Bela Csound Rendering functions                                             */
/*                                                                           */
/*******************************************************************************/

#include <Bela.h>
#include <csound/csound.hpp>
#include <vector>
#include <sstream>

static int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiInDevice(CSOUND *csound, void *userData);
static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf,
			int nbytes);

struct csChan {
  std::vector<MYFLT> data;
  std::stringstream name;
};

struct csData{
  Csound *csound;
  int blocksize;
  int res;
  int count;
  csChan channel[8];
};

struct CsMIDI {
  Midi midi;
};

csData* gCsData;

bool setup(BelaContext *context, void *userData)
{
  Csound *csound = new Csound();
  const char *csdfile = "my.csd"; /* CSD name */
  int numArgs = 8;
  char *args[] = { "csound", csdfile, "-iadc", "-odac", "-+rtaudio=null",
		   "--realtime", "--daemon", "-Mhw:1,0,0"};

  gCsData  = new csData;
  csound->SetHostImplementedAudioIO(1,0);
  csound>SetHostImplementedMIDIIO(1);
  csound->SetExternalMidiInOpenCallback(OpenMidiInDevice);
  csound->SetExternalMidiReadCallback(ReadMidiData);
  csound->SetExternalMidiInCloseCallback(CloseMidiInDevice);
  gCsData->res = csound->Compile(numArgs, args);
  gCsData->csound = csound;
  gCsData->blocksize =
    csound->GetKsmps()*userData->csound->GetNchnls();
  gCsData->count = 0;

  /* set up the channels */
  for(int i; i < context->analogInChannels; i++) {
    gCsData.channel[i].data.resize(csound->GetKsmps());
    gCsData.channel[i].name << "analogue" << i+1;
  }

  if(gCsData->res != 0) return false;
  else return true;
}

void render(BelaContext *context, void *Data)
{
  csData *userData = gCsData;
  if(gCsData->res == 0) {
    int n,i,k,count, frmcount,blocksize,res;
    MYFLT scal = userData->csound->Get0dBFS();
    MYFLT* audioIn = userData->csound->GetSpin();
    MYFLT* audioOut = userData->csound->GetSpout();
    int nchnls = userData->csound->GetNchnls();
    int chns = nchnls;
    int an_chns = context->analogInChannels;
    CsChan *channel = userData->channel;
    float frm = 0, incr = ((float) context->analogFrames)/context->audioFrames;
    int an_chans = context->analogInChannels;
    count = userData->count;
    blocksize = userData->blocksize;

    /* this is called when Csound is not running */
    if(count < 0) {
      for(n = 0; n < context->audioFrames; n++){
	for(i = 0; i < context->audioOutChannels; i++){
	  audioWrite(context,n,i,0);
	}
      }
      return;
    }

    if(chns > context->audioOutChannels)
      chns = context->audioOutChannels;

    /* this is where Csound is called */
    for(n = 0; n < context->audioFrames; n++, frm+=incr, count+=nchnls){
      if(count == blocksize) {
	/* set the channels */
	for(i = 0; i < an_chns; i++) {
          csound->SetChannel(channel[i].name.str().c_str(),
			     &(channel[i].data[0]));
	}
	/* run csound */
	if((res = userData->csound->PerformKsmps()) == 0) count = 0;
	else {
	  count = -1;
	  break;
	}
      }
      /* read/write audio data */
      for(i = 0; i < chns; i++){
	audioIn[count+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[count+i]/scal);
      }

      /* read analogue data
         analogue frame pos gets incremented according to the
         ratio analogFrames/audioFrames.
      */
      frmcount = count/nchnls;
      for(i = 0; i < an_chns; i++) {
	k = (int) frm;
        channel[i].data[frmcount] = analogRead(context,k,i);
      }
    }
    gCsData->res = res;
    userData->count = count;
  }
}

void cleanup(BelaContext *context, void *Data)
{
  csData *userData = gCsData;
  delete userData->csound;
  delete userData;
}

/** MIDI Input functions
 */
int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev) {
  CsMIDI *midiData = new CsMIDI;
  Midi &midi = midiData->midi;
  midi.readFrom(dev);
  midi.enableParser(false);
  *userData = (void *) midiData;
}

int CloseMidiInDevice(CSOUND *csound, void *userData) {
  CsMIDI *midiData = (CsMIDI *) userData;
  delete midiData;
}

int ReadMidiData(CSOUND *csound, void *userData,
                         unsigned char *mbuf, int nbytes) {
  int n = 0;
  CsMIDI *midiData = (CsMIDI *) userData;
  Midi &midi = midiData->midi;

  while((byte = midi.getInput()) >= 0) {
    *mbuf++ = (unsigned char) byte;
    if(++n == nbytes) break;
  }

  return n;
}
<commit_msg>vector<commit_after>/*******************************************************************************/
/* Bela Csound Rendering functions                                             */
/*                                                                           */
/*******************************************************************************/

#include <Bela.h>
#include <csound/csound.hpp>
#include <vector>
#include <sstream>

static int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiInDevice(CSOUND *csound, void *userData);
static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf,
			int nbytes);

struct csChan {
  std::vector<MYFLT> data;
  std::stringstream name;
};

struct csData{
  Csound *csound;
  int blocksize;
  int res;
  int count;
  std::vector<csChan> channel;
};

struct CsMIDI {
  Midi midi;
};

csData* gCsData;

bool setup(BelaContext *context, void *userData)
{
  Csound *csound = new Csound();
  const char *csdfile = "my.csd"; /* CSD name */
  int numArgs = 8;
  char *args[] = { "csound", csdfile, "-iadc", "-odac", "-+rtaudio=null",
		   "--realtime", "--daemon", "-Mhw:1,0,0"};

  gCsData  = new csData;
  csound->SetHostImplementedAudioIO(1,0);
  csound>SetHostImplementedMIDIIO(1);
  csound->SetExternalMidiInOpenCallback(OpenMidiInDevice);
  csound->SetExternalMidiReadCallback(ReadMidiData);
  csound->SetExternalMidiInCloseCallback(CloseMidiInDevice);
  gCsData->res = csound->Compile(numArgs, args);
  gCsData->csound = csound;
  gCsData->blocksize =
    csound->GetKsmps()*userData->csound->GetNchnls();
  gCsData->count = 0;

  /* set up the channels */
  gCsData->channel.resize(context->analogInChannels);
  for(int i; i < context->analogInChannels; i++) {
    gCsData->channel[i].data.resize(csound->GetKsmps());
    gCsData->channel[i].name << "analogue" << i+1;
  }

  if(gCsData->res != 0) return false;
  else return true;
}

void render(BelaContext *context, void *Data)
{
  csData *userData = gCsData;
  if(gCsData->res == 0) {
    int n,i,k,count, frmcount,blocksize,res;
    MYFLT scal = userData->csound->Get0dBFS();
    MYFLT* audioIn = userData->csound->GetSpin();
    MYFLT* audioOut = userData->csound->GetSpout();
    int nchnls = userData->csound->GetNchnls();
    int chns = nchnls;
    int an_chns = context->analogInChannels;
    CsChan *channel = &(userData->channel[0]);
    float frm = 0, incr = ((float) context->analogFrames)/context->audioFrames;
    int an_chans = context->analogInChannels;
    count = userData->count;
    blocksize = userData->blocksize;

    /* this is called when Csound is not running */
    if(count < 0) {
      for(n = 0; n < context->audioFrames; n++){
	for(i = 0; i < context->audioOutChannels; i++){
	  audioWrite(context,n,i,0);
	}
      }
      return;
    }

    if(chns > context->audioOutChannels)
      chns = context->audioOutChannels;

    /* this is where Csound is called */
    for(n = 0; n < context->audioFrames; n++, frm+=incr, count+=nchnls){
      if(count == blocksize) {
	/* set the channels */
	for(i = 0; i < an_chns; i++) {
          csound->SetChannel(channel[i].name.str().c_str(),
			     &(channel[i].data[0]));
	}
	/* run csound */
	if((res = userData->csound->PerformKsmps()) == 0) count = 0;
	else {
	  count = -1;
	  break;
	}
      }
      /* read/write audio data */
      for(i = 0; i < chns; i++){
	audioIn[count+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[count+i]/scal);
      }

      /* read analogue data
         analogue frame pos gets incremented according to the
         ratio analogFrames/audioFrames.
      */
      frmcount = count/nchnls;
      for(i = 0; i < an_chns; i++) {
	k = (int) frm;
        channel[i].data[frmcount] = analogRead(context,k,i);
      }
    }
    gCsData->res = res;
    userData->count = count;
  }
}

void cleanup(BelaContext *context, void *Data)
{
  csData *userData = gCsData;
  delete userData->csound;
  delete userData;
}

/** MIDI Input functions
 */
int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev) {
  CsMIDI *midiData = new CsMIDI;
  Midi &midi = midiData->midi;
  midi.readFrom(dev);
  midi.enableParser(false);
  *userData = (void *) midiData;
}

int CloseMidiInDevice(CSOUND *csound, void *userData) {
  CsMIDI *midiData = (CsMIDI *) userData;
  delete midiData;
}

int ReadMidiData(CSOUND *csound, void *userData,
		 unsigned char *mbuf, int nbytes) {
  int n = 0;
  CsMIDI *midiData = (CsMIDI *) userData;
  Midi &midi = midiData->midi;

  while((byte = midi.getInput()) >= 0) {
    *mbuf++ = (unsigned char) byte;
    if(++n == nbytes) break;
  }

  return n;
}
<|endoftext|>


<commit_before>#include <functional>
#include <gtest/gtest.h>
#include <entt/process/process.hpp>
#include <entt/process/scheduler.hpp>

struct foo_process: entt::process<foo_process, int> {
    foo_process(std::function<void()> upd, std::function<void()> abort)
        : on_update{upd}, on_aborted{abort} {}

    void update(delta_type, void *) {
        on_update();
    }

    void aborted() {
        on_aborted();
    }

    std::function<void()> on_update;
    std::function<void()> on_aborted;
};

struct succeeded_process: entt::process<succeeded_process, int> {
    void update(delta_type, void *) {
        ASSERT_FALSE(updated);
        updated = true;
        ++invoked;
        succeed();
    }

    static unsigned int invoked;
    bool updated = false;
};

unsigned int succeeded_process::invoked = 0;

struct failed_process: entt::process<failed_process, int> {
    void update(delta_type, void *) {
        ASSERT_FALSE(updated);
        updated = true;
        fail();
    }

    bool updated = false;
};

TEST(Scheduler, Functionalities) {
    entt::scheduler<int> scheduler{};

    bool updated = false;
    bool aborted = false;

    ASSERT_EQ(scheduler.size(), 0u);
    ASSERT_TRUE(scheduler.empty());

    scheduler.attach<foo_process>(
        [&updated]() { updated = true; },
        [&aborted]() { aborted = true; });

    ASSERT_NE(scheduler.size(), 0u);
    ASSERT_FALSE(scheduler.empty());

    scheduler.update(0);
    scheduler.abort(true);

    ASSERT_TRUE(updated);
    ASSERT_TRUE(aborted);

    ASSERT_NE(scheduler.size(), 0u);
    ASSERT_FALSE(scheduler.empty());

    scheduler.clear();

    ASSERT_EQ(scheduler.size(), 0u);
    ASSERT_TRUE(scheduler.empty());
}

TEST(Scheduler, Then) {
    entt::scheduler<int> scheduler;

    // failing process with successor
    scheduler.attach<succeeded_process>()
        .then<succeeded_process>()
        .then<failed_process>()
        .then<succeeded_process>();

    // failing process without successor
    scheduler.attach<succeeded_process>()
        .then<succeeded_process>()
        .then<failed_process>();

    // non-failing process
    scheduler.attach<succeeded_process>()
        .then<succeeded_process>();

    for(auto i = 0; i < 8; ++i) {
        scheduler.update(0);
    }

    ASSERT_EQ(succeeded_process::invoked, 6u);
    ASSERT_TRUE(scheduler.empty());
}

TEST(Scheduler, Functor) {
    entt::scheduler<int> scheduler;

    bool first_functor = false;
    bool second_functor = false;

    auto attach = [&first_functor](auto, void *, auto resolve, auto) {
        ASSERT_FALSE(first_functor);
        first_functor = true;
        resolve();
    };

    auto then = [&second_functor](auto, void *, auto, auto reject) {
        ASSERT_FALSE(second_functor);
        second_functor = true;
        reject();
    };

    auto fail = [](auto...) { FAIL(); };

    scheduler.attach(std::move(attach)).then(std::move(then)).then(std::move(fail));

    for(auto i = 0; i < 8; ++i) {
        scheduler.update(0);
    }

    ASSERT_TRUE(first_functor);
    ASSERT_TRUE(second_functor);
    ASSERT_TRUE(scheduler.empty());
}
<commit_msg>test: code coverage<commit_after>#include <functional>
#include <gtest/gtest.h>
#include <entt/process/process.hpp>
#include <entt/process/scheduler.hpp>

struct foo_process: entt::process<foo_process, int> {
    foo_process(std::function<void()> upd, std::function<void()> abort)
        : on_update{upd}, on_aborted{abort} {}

    void update(delta_type, void *) {
        on_update();
    }

    void aborted() {
        on_aborted();
    }

    std::function<void()> on_update;
    std::function<void()> on_aborted;
};

struct succeeded_process: entt::process<succeeded_process, int> {
    void update(delta_type, void *) {
        ASSERT_FALSE(updated);
        updated = true;
        ++invoked;
        succeed();
    }

    static unsigned int invoked;
    bool updated = false;
};

unsigned int succeeded_process::invoked = 0;

struct failed_process: entt::process<failed_process, int> {
    void update(delta_type, void *) {
        ASSERT_FALSE(updated);
        updated = true;
        fail();
    }

    bool updated = false;
};

TEST(Scheduler, Functionalities) {
    entt::scheduler<int> scheduler{};

    bool updated = false;
    bool aborted = false;

    ASSERT_EQ(scheduler.size(), 0u);
    ASSERT_TRUE(scheduler.empty());

    scheduler.attach<foo_process>(
        [&updated]() { updated = true; },
        [&aborted]() { aborted = true; });

    ASSERT_NE(scheduler.size(), 0u);
    ASSERT_FALSE(scheduler.empty());

    scheduler.update(0);
    scheduler.abort(true);

    ASSERT_TRUE(updated);
    ASSERT_TRUE(aborted);

    ASSERT_NE(scheduler.size(), 0u);
    ASSERT_FALSE(scheduler.empty());

    scheduler.clear();

    ASSERT_EQ(scheduler.size(), 0u);
    ASSERT_TRUE(scheduler.empty());
}

TEST(Scheduler, Then) {
    entt::scheduler<int> scheduler;

    // failing process with successor
    scheduler.attach<succeeded_process>()
        .then<succeeded_process>()
        .then<failed_process>()
        .then<succeeded_process>();

    // failing process without successor
    scheduler.attach<succeeded_process>()
        .then<succeeded_process>()
        .then<failed_process>();

    // non-failing process
    scheduler.attach<succeeded_process>()
        .then<succeeded_process>();

    for(auto i = 0; i < 8; ++i) {
        scheduler.update(0);
    }

    ASSERT_EQ(succeeded_process::invoked, 6u);
    ASSERT_TRUE(scheduler.empty());
}

TEST(Scheduler, Functor) {
    entt::scheduler<int> scheduler;

    bool first_functor = false;
    bool second_functor = false;

    auto attach = [&first_functor](auto, void *, auto resolve, auto) {
        ASSERT_FALSE(first_functor);
        first_functor = true;
        resolve();
    };

    auto then = [&second_functor](auto, void *, auto, auto reject) {
        ASSERT_FALSE(second_functor);
        second_functor = true;
        reject();
    };

    scheduler.attach(std::move(attach)).then(std::move(then)).then(std::move([](auto...) { FAIL(); }));

    for(auto i = 0; i < 8; ++i) {
        scheduler.update(0);
    }

    ASSERT_TRUE(first_functor);
    ASSERT_TRUE(second_functor);
    ASSERT_TRUE(scheduler.empty());
}
<|endoftext|>


<commit_before>// Copyright 2016, Dawid Kurek, <dawikur@gmail.com>

#include "firmware.hpp"

#include <vector>

#include "gtest/gtest.h"

#include "mock.hpp"

namespace Functions {

#define set_rows(row0, row1, row2, row3, row4)                                 \
  EXPECT_CALL(hardware, getRow(0))                                             \
    .WillOnce(::testing::Return(Crow::Row{row0}));                             \
  EXPECT_CALL(hardware, getRow(1))                                             \
    .WillOnce(::testing::Return(Crow::Row{row1}));                             \
  EXPECT_CALL(hardware, getRow(2))                                             \
    .WillOnce(::testing::Return(Crow::Row{row2}));                             \
  EXPECT_CALL(hardware, getRow(3))                                             \
    .WillOnce(::testing::Return(Crow::Row{row3}));                             \
  EXPECT_CALL(hardware, getRow(4)).WillOnce(::testing::Return(Crow::Row{row4}));

#define expect_report(...)                                                     \
  EXPECT_CALL(usbHid, sendReport(std::vector<uint8_t>(__VA_ARGS__)))           \
    .WillOnce(::testing::Return(1))

Crow::Mock::Hardware *_hardware;
Crow::Mock::USBHid *_usbHid;

Crow::Row getRow(Crow::Index const i) {
  return _hardware->getRow(i);
}

void sendReport(Crow::Index const id,
                void const *const data,
                Crow::Index const size) {
  auto *bytes = reinterpret_cast<uint8_t const *>(data);
  std::vector<uint8_t> buffor(bytes, bytes + size);
  _usbHid->sendReport(buffor);
}

void setLayer(Crow::Index const) {}

}  // namespace Functions

class firmware_test : public ::testing::Test {
 protected:
  void SetUp() override {
    Functions::_hardware = &hardware;
    Functions::_usbHid = &usbHid;

    firmware.setup(
      Functions::getRow, Functions::sendReport, Functions::setLayer);
  }

  void TearDown() override {
    Functions::_usbHid = nullptr;
    Functions::_hardware = nullptr;
  }

  Crow::Firmware firmware;

  Crow::Mock::Hardware hardware;
  Crow::Mock::USBHid usbHid;
};

using namespace Crow::Keymap;

TEST_F(firmware_test, not_pressing_any_key_will_not_send_report) {
  set_rows(0, 0, 0, 0, 0);

  firmware.loop();
}

TEST_F(firmware_test, pressing_one_key_will_send_report_with_that_key) {
  set_rows(0, 0, 2, 0, 0);
  expect_report({0, 0, Key_A, 0, 0, 0, 0, 0});

  firmware.loop();
}

TEST_F(firmware_test, pressing_and_releasing_key_will_send_two_reports) {
  set_rows(0, 0, 4, 0, 0);
  expect_report({0, 0, Key_S, 0, 0, 0, 0, 0});

  firmware.loop();

  set_rows(0, 0, 0, 0, 0);
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();
}

TEST_F(firmware_test,
       when_pressing_three_keys_they_will_be_send_in_one_report) {
  set_rows(32, 4, 64, 0,0);
  expect_report({0, 0, Key_5, Key_W, Key_H, 0, 0, 0});

  firmware.loop();
}

TEST_F(firmware_test, pressed_modifier_will_be_send) {
  set_rows(0, 0, 1, 0, 0);
  expect_report({
    Modifier_CtrlL, 0, 0, 0, 0, 0, 0, 0,
  });

  firmware.loop();
}

TEST_F(firmware_test, pressed_multiple_modifiers_will_be_send) {
  set_rows(0, 0, 1, 1, 0);
  expect_report({
    Modifier_CtrlL | Modifier_ShiftL, 0, 0, 0, 0, 0, 0, 0,
  });

  firmware.loop();
}

TEST_F(firmware_test, modifiers_can_be_unpressed) {
  set_rows(0, 0, 0, 0, 256);                                                   // Press AltR
  expect_report({Modifier_AltR, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release AltR
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();
}

TEST_F(firmware_test, modifiers_press_can_be_combined_with_normal_keys) {
  set_rows(0, 32, 1, 8, 256);
  expect_report({Modifier_AltR | Modifier_CtrlL, 0, Key_T, Key_C, 0, 0, 0, 0});

  firmware.loop();
}

TEST_F(firmware_test, first_layer_can_be_reached) {
  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1

  firmware.loop();

  set_rows(2, 0, 0, 0, 1);                                                     // Press 2
  expect_report({0, 0, Key_F1, 0, 0, 0, 0, 0});                                // ? Got F2

  firmware.loop();
}

TEST_F(firmware_test, can_click_on_first_layer_and_than_back_on_default_one) {
  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1

  firmware.loop();

  set_rows(0, 0, 512, 0, 1);                                                   // Press l
  expect_report({0, 0, Key_Right, 0, 0, 0, 0, 0});                             // ? Got RightKey

  firmware.loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();

  set_rows(4, 0, 0, 0, 0);                                                     // Press 2
  expect_report({0, 0, Key_2, 0, 0, 0, 0, 0});                                 // ? Got 2

  firmware.loop();
}

TEST_F(firmware_test, layer_can_be_toggled) {
  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1

  firmware.loop();

  set_rows(0, 1, 0, 0, 1);                                                     // Press Layer1Toggle

  firmware.loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Releas both

  firmware.loop();

  set_rows(2, 0, 0, 0, 0);                                                     // Press 1
  expect_report({0, 0, Key_F1, 0, 0, 0, 0, 0});                                // ? Got F1

  firmware.loop();

  set_rows(0, 0, 64, 0, 0);                                                    // Press h
  expect_report({0, 0, Key_Left, 0, 0, 0, 0, 0});                              // ? Got Leftkey

  firmware.loop();
}

TEST_F(firmware_test, layer_can_be_toggled_twice) {
  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1

  firmware.loop();

  set_rows(0, 1, 0, 0, 1);                                                     // Press Layer1Toggle

  firmware.loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both

  firmware.loop();

  set_rows(8, 0, 0, 0, 0);                                                     // Press 3
  expect_report({0, 0, Key_F3, 0, 0, 0, 0, 0});                                // ? Got F3

  firmware.loop();

  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();

  set_rows(0, 1, 0, 0, 1);                                                     // Press Layer1Toggle

  firmware.loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both

  firmware.loop();

  set_rows(8, 0, 0, 0, 0);                                                     // Press 3
  expect_report({0, 0, Key_3, 0, 0, 0, 0, 0});                                 // ? Got 3

  firmware.loop();
}

TEST_F(firmware_test, shift_locking_and_unlocking_works_on_layer_2) {
  set_rows(0, 0, 0, 0, 2048);                                                  // Press Layer2

  firmware.loop();

  set_rows(0, 0, 0, 2048, 2048);                                               // Press ShiftLock
  expect_report({Modifier_ShiftR, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both

  firmware.loop();

  set_rows(4, 0, 0, 0, 0);                                                     // Press 2
  expect_report({Modifier_ShiftR, 0, Key_2, 0, 0, 0, 0, 0});                   // ? Got @

  firmware.loop();

  set_rows(0, 0, 0, 0, 2048);                                                  // Press Layer2
  expect_report({Modifier_ShiftR, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();

  set_rows(0, 0, 0, 2048, 2048);                                               // Press ShiftLock
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both

  firmware.loop();

  set_rows(4, 0, 0, 0, 0);                                                     // Press 2
  expect_report({0, 0, Key_2, 0, 0, 0, 0, 0});                                 // ? Got 2

  firmware.loop();
}

TEST_F(firmware_test, can_lock_both_shift_keys) {
  set_rows(0, 0, 0, 0, 2048);                                                  // Press Layer2

  firmware.loop();

  set_rows(0, 0, 0, 2049, 2048);                                               // Press both ShiftLock
  expect_report({Modifier_ShiftL | Modifier_ShiftR, 0, 0, 0, 0, 0, 0, 0});     // ? Got both Shift

  firmware.loop();
}

TEST_F(firmware_test, when_changing_layer_all_keys_are_cleared) {
  set_rows(0, 0, 0, 0, 1);

  firmware.loop();

  set_rows(1, 0, 0, 0, 1);
  expect_report({0, 0, Key_Esc, 0, 0, 0, 0, 0});

  firmware.loop();

  set_rows(1, 0, 0, 0, 0);
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();
}

TEST_F(firmware_test, when_changing_layer_modifier_keys_are_not_cleared) {
  set_rows(0, 0, 0, 1, 1);
  expect_report({Modifier_ShiftL, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();

  set_rows(0, 0, 0, 1, 0);

  firmware.loop();

  set_rows(0, 0, 0, 0, 0);
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  firmware.loop();
}
<commit_msg>[test] Minor  refactor, more comments<commit_after>// Copyright 2016, Dawid Kurek, <dawikur@gmail.com>

#include "firmware.hpp"

#include <vector>

#include "gtest/gtest.h"

#include "mock.hpp"

namespace Functions {

#define set_rows(row0, row1, row2, row3, row4)                                 \
  EXPECT_CALL(hardware, getRow(0))                                             \
    .WillOnce(::testing::Return(Crow::Row{row0}));                             \
  EXPECT_CALL(hardware, getRow(1))                                             \
    .WillOnce(::testing::Return(Crow::Row{row1}));                             \
  EXPECT_CALL(hardware, getRow(2))                                             \
    .WillOnce(::testing::Return(Crow::Row{row2}));                             \
  EXPECT_CALL(hardware, getRow(3))                                             \
    .WillOnce(::testing::Return(Crow::Row{row3}));                             \
  EXPECT_CALL(hardware, getRow(4)).WillOnce(::testing::Return(Crow::Row{row4}));

#define expect_report(...)                                                     \
  EXPECT_CALL(usbHid, sendReport(std::vector<uint8_t>(__VA_ARGS__)))           \
    .WillOnce(::testing::Return(1))

Crow::Mock::Hardware *_hardware;
Crow::Mock::USBHid *_usbHid;

Crow::Row getRow(Crow::Index const i) {
  return _hardware->getRow(i);
}

void sendReport(Crow::Index const id,
                void const *const data,
                Crow::Index const size) {
  auto *bytes = reinterpret_cast<uint8_t const *>(data);
  std::vector<uint8_t> buffor(bytes, bytes + size);
  _usbHid->sendReport(buffor);
}

void setLayer(Crow::Index const) {}

}  // namespace Functions

class firmware_test : public ::testing::Test {
 protected:
  void SetUp() override {
    Functions::_hardware = &hardware;
    Functions::_usbHid = &usbHid;

    firmware.setup(
      Functions::getRow, Functions::sendReport, Functions::setLayer);
  }

  void TearDown() override {
    Functions::_usbHid = nullptr;
    Functions::_hardware = nullptr;
  }

  void loop() {
    firmware.loop();
  }

  Crow::Firmware firmware;

  Crow::Mock::Hardware hardware;
  Crow::Mock::USBHid usbHid;
};

using namespace Crow::Keymap;

TEST_F(firmware_test, not_pressing_any_key_will_not_send_report) {
  set_rows(0, 0, 0, 0, 0);

  loop();
}

TEST_F(firmware_test, pressing_one_key_will_send_report_with_that_key) {
  set_rows(0, 0, 2, 0, 0);
  expect_report({0, 0, Key_A, 0, 0, 0, 0, 0});

  loop();
}

TEST_F(firmware_test, pressing_and_releasing_key_will_send_two_reports) {
  set_rows(0, 0, 4, 0, 0);
  expect_report({0, 0, Key_S, 0, 0, 0, 0, 0});

  loop();

  set_rows(0, 0, 0, 0, 0);
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  loop();
}

TEST_F(firmware_test,
       when_pressing_three_keys_they_will_be_send_in_one_report) {
  set_rows(32, 4, 64, 0,0);
  expect_report({0, 0, Key_5, Key_W, Key_H, 0, 0, 0});

  loop();
}

TEST_F(firmware_test, pressed_modifier_will_be_send) {
  set_rows(0, 0, 1, 0, 0);
  expect_report({
    Modifier_CtrlL, 0, 0, 0, 0, 0, 0, 0,
  });

  loop();
}

TEST_F(firmware_test, pressed_multiple_modifiers_will_be_send) {
  set_rows(0, 0, 1, 1, 0);
  expect_report({
    Modifier_CtrlL | Modifier_ShiftL, 0, 0, 0, 0, 0, 0, 0,
  });

  loop();
}

TEST_F(firmware_test, modifiers_can_be_unpressed) {
  set_rows(0, 0, 0, 0, 256);                                                   // Press AltR
  expect_report({Modifier_AltR, 0, 0, 0, 0, 0, 0, 0});

  loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release AltR
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  loop();
}

TEST_F(firmware_test, modifiers_press_can_be_combined_with_normal_keys) {
  set_rows(0, 32, 1, 8, 256);
  expect_report({Modifier_AltR | Modifier_CtrlL, 0, Key_T, Key_C, 0, 0, 0, 0});

  loop();
}

TEST_F(firmware_test, first_layer_can_be_reached) {
  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1

  loop();

  set_rows(2, 0, 0, 0, 1);                                                     // Press 2
  expect_report({0, 0, Key_F1, 0, 0, 0, 0, 0});                                // ? Got F2

  loop();
}

TEST_F(firmware_test, can_click_on_first_layer_and_than_back_on_default_one) {
  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1

  loop();

  set_rows(0, 0, 512, 0, 1);                                                   // Press l
  expect_report({0, 0, Key_Right, 0, 0, 0, 0, 0});                             // ? Got RightKey

  loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  loop();

  set_rows(4, 0, 0, 0, 0);                                                     // Press 2
  expect_report({0, 0, Key_2, 0, 0, 0, 0, 0});                                 // ? Got 2

  loop();
}

TEST_F(firmware_test, layer_can_be_toggled) {
  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1

  loop();

  set_rows(0, 1, 0, 0, 1);                                                     // Press Layer1Toggle

  loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Releas both

  loop();

  set_rows(2, 0, 0, 0, 0);                                                     // Press 1
  expect_report({0, 0, Key_F1, 0, 0, 0, 0, 0});                                // ? Got F1

  loop();

  set_rows(0, 0, 64, 0, 0);                                                    // Press h
  expect_report({0, 0, Key_Left, 0, 0, 0, 0, 0});                              // ? Got Leftkey

  loop();
}

TEST_F(firmware_test, layer_can_be_toggled_twice) {
  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1

  loop();

  set_rows(0, 1, 0, 0, 1);                                                     // Press Layer1Toggle

  loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both

  loop();

  set_rows(8, 0, 0, 0, 0);                                                     // Press 3
  expect_report({0, 0, Key_F3, 0, 0, 0, 0, 0});                                // ? Got F3

  loop();

  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  loop();

  set_rows(0, 1, 0, 0, 1);                                                     // Press Layer1Toggle

  loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both

  loop();

  set_rows(8, 0, 0, 0, 0);                                                     // Press 3
  expect_report({0, 0, Key_3, 0, 0, 0, 0, 0});                                 // ? Got 3

  loop();
}

TEST_F(firmware_test, shift_locking_and_unlocking_works_on_layer_2) {
  set_rows(0, 0, 0, 0, 2048);                                                  // Press Layer2

  loop();

  set_rows(0, 0, 0, 2048, 2048);                                               // Press ShiftLock
  expect_report({Modifier_ShiftR, 0, 0, 0, 0, 0, 0, 0});

  loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both

  loop();

  set_rows(4, 0, 0, 0, 0);                                                     // Press 2
  expect_report({Modifier_ShiftR, 0, Key_2, 0, 0, 0, 0, 0});                   // ? Got @

  loop();

  set_rows(0, 0, 0, 0, 2048);                                                  // Press Layer2
  expect_report({Modifier_ShiftR, 0, 0, 0, 0, 0, 0, 0});

  loop();

  set_rows(0, 0, 0, 2048, 2048);                                               // Press ShiftLock
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});

  loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release both

  loop();

  set_rows(4, 0, 0, 0, 0);                                                     // Press 2
  expect_report({0, 0, Key_2, 0, 0, 0, 0, 0});                                 // ? Got 2

  loop();
}

TEST_F(firmware_test, can_lock_both_shift_keys) {
  set_rows(0, 0, 0, 0, 2048);                                                  // Press Layer2

  loop();

  set_rows(0, 0, 0, 2049, 2048);                                               // Press both ShiftLock
  expect_report({Modifier_ShiftL | Modifier_ShiftR, 0, 0, 0, 0, 0, 0, 0});     // ? Got both Shift

  loop();
}

TEST_F(firmware_test, when_changing_layer_all_keys_are_cleared) {
  set_rows(0, 0, 0, 0, 1);                                                     // Press Layer1

  loop();

  set_rows(1, 0, 0, 0, 1);                                                     // Press Esc
  expect_report({0, 0, Key_Esc, 0, 0, 0, 0, 0});                               // ? Got Esc

  loop();

  set_rows(1, 0, 0, 0, 0);                                                     // Release Layer1
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});                                     // ? Did not get Esc

  loop();
}

TEST_F(firmware_test, when_changing_layer_modifier_keys_are_not_cleared) {
  set_rows(0, 0, 0, 1, 1);                                                     // Press Layer1 and ShiftL
  expect_report({Modifier_ShiftL, 0, 0, 0, 0, 0, 0, 0});                       // ? Got ShiftL

  loop();

  set_rows(0, 0, 0, 1, 0);                                                     // Release Layer1

  loop();

  set_rows(0, 0, 0, 0, 0);                                                     // Release ShiftL
  expect_report({0, 0, 0, 0, 0, 0, 0, 0});                                     // ? Did not get ShiftL

  loop();
}
<|endoftext|>


<commit_before>#include <sstream>
#include <set>
#include <memory>
#include <dlfcn.h>

#include "plugin-loader.hpp"
#include "output.hpp"
#include "../core/wm.hpp"
#include "core.hpp"
#include "debug.hpp"

namespace
{
    template<class A, class B> B union_cast(A object)
    {
        union {
            A x;
            B y;
        } helper;
        helper.x = object;
        return helper.y;
    }
}

static const std::string default_plugins = "viewport_impl move resize animate \
                                            switcher vswitch cube expo command \
                                            grid";

static void idle_reload(void *data)
{
    auto manager = (plugin_manager *) data;
    manager->reload_dynamic_plugins();
    manager->idle_reload_dynamic_plugins = NULL;
}

plugin_manager::plugin_manager(wayfire_output *o, wayfire_config *config)
{
    this->config = config;
    this->output = o;

    auto section = config->get_section("core");
    plugins_opt = section->get_option("plugins", "default");

    reload_dynamic_plugins();
    load_static_plugins();

    list_updated = [=] ()
    {
        /* reload when config reload has finished */
        idle_reload_dynamic_plugins =
            wl_event_loop_add_idle(core->ev_loop, idle_reload, this);
    };

    plugins_opt->updated.push_back(&list_updated);
}

void plugin_manager::deinit_plugins(bool unloadable, bool internal)
{
    for (auto& p : loaded_plugins)
    {
        if (!p.second) // already destroyed on the previous iteration
            continue;

        if (p.second->is_unloadable() == unloadable && p.second->is_internal() == internal)
            destroy_plugin(p.second);
    }
}

plugin_manager::~plugin_manager()
{
    deinit_plugins(true, false); // regular plugins - unloadable, not internal
    deinit_plugins(false, false); // regular plugins - not-unloadable, not internal
    deinit_plugins(true, true); // system plugins - unloadable, internal
    deinit_plugins(false, true); // system plugins - not-unloadable, internal

    loaded_plugins.clear();

    if (idle_reload_dynamic_plugins)
        wl_event_source_remove(idle_reload_dynamic_plugins);

    plugins_opt->updated.erase(std::remove(plugins_opt->updated.begin(), plugins_opt->updated.end(),
                                           &list_updated), plugins_opt->updated.end());
}

void plugin_manager::init_plugin(wayfire_plugin& p)
{
    p->grab_interface = new wayfire_grab_interface_t(output);
    p->output = output;

    p->init(config);
}

void plugin_manager::destroy_plugin(wayfire_plugin& p)
{
    p->grab_interface->ungrab();
    output->deactivate_plugin(p->grab_interface);

    p->fini();
    delete p->grab_interface;

    /* we load the same plugins for each output, so we must dlclose() the handle
     * only when we remove the last output */
    if (core->get_num_outputs() < 1)
    {
        if (p->dynamic)
            dlclose(p->handle);
    }

    p.reset();
}

wayfire_plugin plugin_manager::load_plugin_from_file(std::string path)
{
    void *handle = dlopen(path.c_str(), RTLD_NOW);
    if(handle == NULL)
    {
        log_error("error loading plugin: %s", dlerror());
        return nullptr;
    }

    auto initptr = dlsym(handle, "newInstance");
    if(initptr == NULL)
    {
        log_error("%s: missing newInstance(). %s", path.c_str(), dlerror());
        return nullptr;
    }

    log_debug("loading plugin %s", path.c_str());
    get_plugin_instance_t init = union_cast<void*, get_plugin_instance_t> (initptr);

    auto ptr = wayfire_plugin(init());

    ptr->handle = handle;
    ptr->dynamic = true;

    return wayfire_plugin(init());
}

void plugin_manager::reload_dynamic_plugins()
{
    std::stringstream stream(plugins_opt->as_string());
    std::vector<std::string> next_plugins;

    auto plugin_prefix = std::string(INSTALL_PREFIX "/lib/wayfire/");

    std::string plugin_name;
    while(stream >> plugin_name)
    {
        if (plugin_name.size())
        {
            if (plugin_name.at(0) == '/')
                next_plugins.push_back(plugin_name);
            else
                next_plugins.push_back(plugin_prefix + "lib" + plugin_name + ".so");
        }
    }

    /* erase plugins that have been removed from the config */
    auto it = loaded_plugins.begin();
    while(it != loaded_plugins.end())
    {
        /* skip built-in(static) plugins */
        if (it->first.size() && it->first[0] == '_')
        {
            ++it;
            continue;
        }

        if (std::find(next_plugins.begin(), next_plugins.end(), it->first) == next_plugins.end() &&
            it->second->is_unloadable())
        {
            log_debug("unload plugin %s", it->first.c_str());
            destroy_plugin(it->second);
            it = loaded_plugins.erase(it);
        }
        else
        {
            ++it;
        }
    }

    /* load new plugins */
    for (auto plugin : next_plugins)
    {
        if (loaded_plugins.count(plugin))
            continue;

        auto ptr = load_plugin_from_file(plugin);
        if (ptr)
        {
            init_plugin(ptr);
            loaded_plugins[plugin] = std::move(ptr);
        }
    }
}

template<class T> static wayfire_plugin create_plugin()
{
    return std::unique_ptr<wayfire_plugin_t>(new T);
}

void plugin_manager::load_static_plugins()
{
    loaded_plugins["_exit"]         = create_plugin<wayfire_exit>();
    loaded_plugins["_focus"]        = create_plugin<wayfire_focus>();
    loaded_plugins["_close"]        = create_plugin<wayfire_close>();
    loaded_plugins["_focus_parent"] = create_plugin<wayfire_handle_focus_parent>();

    init_plugin(loaded_plugins["_exit"]);
    init_plugin(loaded_plugins["_focus"]);
    init_plugin(loaded_plugins["_close"]);
    init_plugin(loaded_plugins["_focus_parent"]);
}
<commit_msg>plugin-loader: Load a list of basic plugins in case of bad configuration<commit_after>#include <sstream>
#include <set>
#include <memory>
#include <dlfcn.h>

#include "plugin-loader.hpp"
#include "output.hpp"
#include "../core/wm.hpp"
#include "core.hpp"
#include "debug.hpp"

namespace
{
    template<class A, class B> B union_cast(A object)
    {
        union {
            A x;
            B y;
        } helper;
        helper.x = object;
        return helper.y;
    }
}

static const std::string default_plugins = "viewport_impl move resize animate \
                                            switcher vswitch cube expo command \
                                            grid";

static void idle_reload(void *data)
{
    auto manager = (plugin_manager *) data;
    manager->reload_dynamic_plugins();
    manager->idle_reload_dynamic_plugins = NULL;
}

plugin_manager::plugin_manager(wayfire_output *o, wayfire_config *config)
{
    this->config = config;
    this->output = o;

    auto section = config->get_section("core");
    plugins_opt = section->get_option("plugins", "none");

    reload_dynamic_plugins();
    load_static_plugins();

    list_updated = [=] ()
    {
        /* reload when config reload has finished */
        idle_reload_dynamic_plugins =
            wl_event_loop_add_idle(core->ev_loop, idle_reload, this);
    };

    plugins_opt->updated.push_back(&list_updated);
}

void plugin_manager::deinit_plugins(bool unloadable, bool internal)
{
    for (auto& p : loaded_plugins)
    {
        if (!p.second) // already destroyed on the previous iteration
            continue;

        if (p.second->is_unloadable() == unloadable && p.second->is_internal() == internal)
            destroy_plugin(p.second);
    }
}

plugin_manager::~plugin_manager()
{
    deinit_plugins(true, false); // regular plugins - unloadable, not internal
    deinit_plugins(false, false); // regular plugins - not-unloadable, not internal
    deinit_plugins(true, true); // system plugins - unloadable, internal
    deinit_plugins(false, true); // system plugins - not-unloadable, internal

    loaded_plugins.clear();

    if (idle_reload_dynamic_plugins)
        wl_event_source_remove(idle_reload_dynamic_plugins);

    plugins_opt->updated.erase(std::remove(plugins_opt->updated.begin(), plugins_opt->updated.end(),
                                           &list_updated), plugins_opt->updated.end());
}

void plugin_manager::init_plugin(wayfire_plugin& p)
{
    p->grab_interface = new wayfire_grab_interface_t(output);
    p->output = output;

    p->init(config);
}

void plugin_manager::destroy_plugin(wayfire_plugin& p)
{
    p->grab_interface->ungrab();
    output->deactivate_plugin(p->grab_interface);

    p->fini();
    delete p->grab_interface;

    /* we load the same plugins for each output, so we must dlclose() the handle
     * only when we remove the last output */
    if (core->get_num_outputs() < 1)
    {
        if (p->dynamic)
            dlclose(p->handle);
    }

    p.reset();
}

wayfire_plugin plugin_manager::load_plugin_from_file(std::string path)
{
    void *handle = dlopen(path.c_str(), RTLD_NOW);
    if(handle == NULL)
    {
        log_error("error loading plugin: %s", dlerror());
        return nullptr;
    }

    auto initptr = dlsym(handle, "newInstance");
    if(initptr == NULL)
    {
        log_error("%s: missing newInstance(). %s", path.c_str(), dlerror());
        return nullptr;
    }

    log_debug("loading plugin %s", path.c_str());
    get_plugin_instance_t init = union_cast<void*, get_plugin_instance_t> (initptr);

    auto ptr = wayfire_plugin(init());

    ptr->handle = handle;
    ptr->dynamic = true;

    return wayfire_plugin(init());
}

void plugin_manager::reload_dynamic_plugins()
{
    auto plugin_list = plugins_opt->as_string();
    if (plugin_list == "none")
    {
        log_error("No plugins specified in the config file, or config file is "
            "missing. In this state the compositor is nearly unusable, please "
            "ensure your configuration file is set up properly.");
        plugin_list = default_plugins;
    }

    std::stringstream stream(plugin_list);
    std::vector<std::string> next_plugins;

    auto plugin_prefix = std::string(INSTALL_PREFIX "/lib/wayfire/");

    std::string plugin_name;
    while(stream >> plugin_name)
    {
        if (plugin_name.size())
        {
            if (plugin_name.at(0) == '/')
                next_plugins.push_back(plugin_name);
            else
                next_plugins.push_back(plugin_prefix + "lib" + plugin_name + ".so");
        }
    }

    /* erase plugins that have been removed from the config */
    auto it = loaded_plugins.begin();
    while(it != loaded_plugins.end())
    {
        /* skip built-in(static) plugins */
        if (it->first.size() && it->first[0] == '_')
        {
            ++it;
            continue;
        }

        if (std::find(next_plugins.begin(), next_plugins.end(), it->first) == next_plugins.end() &&
            it->second->is_unloadable())
        {
            log_debug("unload plugin %s", it->first.c_str());
            destroy_plugin(it->second);
            it = loaded_plugins.erase(it);
        }
        else
        {
            ++it;
        }
    }

    /* load new plugins */
    for (auto plugin : next_plugins)
    {
        if (loaded_plugins.count(plugin))
            continue;

        auto ptr = load_plugin_from_file(plugin);
        if (ptr)
        {
            init_plugin(ptr);
            loaded_plugins[plugin] = std::move(ptr);
        }
    }
}

template<class T> static wayfire_plugin create_plugin()
{
    return std::unique_ptr<wayfire_plugin_t>(new T);
}

void plugin_manager::load_static_plugins()
{
    loaded_plugins["_exit"]         = create_plugin<wayfire_exit>();
    loaded_plugins["_focus"]        = create_plugin<wayfire_focus>();
    loaded_plugins["_close"]        = create_plugin<wayfire_close>();
    loaded_plugins["_focus_parent"] = create_plugin<wayfire_handle_focus_parent>();

    init_plugin(loaded_plugins["_exit"]);
    init_plugin(loaded_plugins["_focus"]);
    init_plugin(loaded_plugins["_close"]);
    init_plugin(loaded_plugins["_focus_parent"]);
}
<|endoftext|>


<commit_before>//
// Created by volundr on 7/19/16.
//

#include <vector>
#include <iostream>
#include "Bno055Interface.h"

namespace bno055 {

    bool Bno055Interface::init(const char* bno055File) {

        #define REPORT_FAILURE(byteSent) std::cout << "Did not receive response after sending " byteSent "\n"; wasSuccess = false
        bool wasSuccess = true;
        if ( ! uart.openPort(bno055File, BNO055_BAUD_RATE) ) {
            std::cout << "Could not open serial connection to bno055!\n";
            wasSuccess = false;
        }
        if ( ! writeByte(OPR_MODE, CONFIG) ) {
            REPORT_FAILURE("OPR_MODE");
            wasSuccess = false;
        }
        if ( ! writeByte(PWR_MODE, NORMAL) ) {
            REPORT_FAILURE("PWR_MODE");
            wasSuccess = false;
        }
        if ( ! writeByte(Page_ID, 0) ) {
            REPORT_FAILURE("Page_ID");
            wasSuccess = false;
        }
        if ( ! writeByte(SYS_TRIGGER, 0) ) {
            REPORT_FAILURE("SYS_TRIGGER");
            wasSuccess = false;
        }
        if ( ! writeByte(UNIT_SEL, 0x83) ) {
            REPORT_FAILURE("UNIT_SEL");
            wasSuccess = false;
        }
        if ( ! writeByte(AXIS_MAP_CONFIG, 0x24) ) {
            REPORT_FAILURE("AXIS_MAP_CONFIG");
            wasSuccess = false;
        }
        if ( ! writeByte(AXIS_MAP_SIGN, 0x06) ) {
            REPORT_FAILURE("AXIS_MAP_SIGN");
            wasSuccess = false;
        }
        if ( ! writeByte(OPR_MODE, NDOF) ) {
            REPORT_FAILURE("OPR_MODE");
            wasSuccess = false;
        }
        #undef REPORT_FAILURE

        hasInit = wasSuccess;
        return wasSuccess;
    }

    bool Bno055Interface::write(uint8_t regAddr, uint8_t length, uint8_t* data) {
        RegisterWritePacket packetToSend(regAddr, length, data);
        uart.sendData(packetToSend.bytes(), packetToSend.length);
        ReceivedAck ack;
        if (ack.readFrom(uart) == RECEIVED_EXPECTED) {
            std::cout << "Did not receive ack!\n";
        }
        return (ack.isValidAck() && ! ack.isErrorStatus());
    }

    bool Bno055Interface::writeByte(uint8_t regAddr, uint8_t data) {
        return write(regAddr, 1, &data);
    }

    bool Bno055Interface::isLive() {
        return hasInit;
    }

}

<commit_msg>added error response<commit_after>//
// Created by volundr on 7/19/16.
//

#include <vector>
#include <iostream>
#include "Bno055Interface.h"

namespace bno055 {

    bool Bno055Interface::init(const char* bno055File) {

        #define REPORT_FAILURE(byteSent) std::cout << "Did not receive response after sending " byteSent "\n"; wasSuccess = false
        bool wasSuccess = true;
        if ( ! uart.openPort(bno055File, BNO055_BAUD_RATE) ) {
            std::cout << "Could not open serial connection to bno055!\n";
            wasSuccess = false;
        }
        if ( ! writeByte(OPR_MODE, CONFIG) ) {
            REPORT_FAILURE("OPR_MODE");
            wasSuccess = false;
        }
        if ( ! writeByte(PWR_MODE, NORMAL) ) {
            REPORT_FAILURE("PWR_MODE");
            wasSuccess = false;
        }
        if ( ! writeByte(Page_ID, 0) ) {
            REPORT_FAILURE("Page_ID");
            wasSuccess = false;
        }
        if ( ! writeByte(SYS_TRIGGER, 0) ) {
            REPORT_FAILURE("SYS_TRIGGER");
            wasSuccess = false;
        }
        if ( ! writeByte(UNIT_SEL, 0x83) ) {
            REPORT_FAILURE("UNIT_SEL");
            wasSuccess = false;
        }
        if ( ! writeByte(AXIS_MAP_CONFIG, 0x24) ) {
            REPORT_FAILURE("AXIS_MAP_CONFIG");
            wasSuccess = false;
        }
        if ( ! writeByte(AXIS_MAP_SIGN, 0x06) ) {
            REPORT_FAILURE("AXIS_MAP_SIGN");
            wasSuccess = false;
        }
        if ( ! writeByte(OPR_MODE, NDOF) ) {
            REPORT_FAILURE("OPR_MODE");
            wasSuccess = false;
        }
        #undef REPORT_FAILURE

        hasInit = wasSuccess;
        return wasSuccess;
    }

    bool Bno055Interface::write(uint8_t regAddr, uint8_t length, uint8_t* data) {
        RegisterWritePacket packetToSend(regAddr, length, data);
        uart.sendData(packetToSend.bytes(), packetToSend.length);
        ReceivedAck ack;
        int loopCount = 0;
        while (ack.readFrom(uart) != RECEIVED_EXPECTED) {
            if (++loopCount > 100) {
                std::cout << "ack reception timed out!";
                return false;
            }
        }
        return (ack.isValidAck() && ! ack.isErrorStatus());
    }

    bool Bno055Interface::writeByte(uint8_t regAddr, uint8_t data) {
        return write(regAddr, 1, &data);
    }

    bool Bno055Interface::isLive() {
        return hasInit;
    }

}

<|endoftext|>


<commit_before>#include "layout.h"

using namespace Tempest;

Layout::Layout(){
  ow       = 0;
  mspacing = 0;
  }

Layout::~Layout() {
  removeAll();
  }

Widget *Layout::owner() {
  return ow;
  }

const Widget *Layout::owner() const {
  return ow;
  }

void Layout::add(Widget *widget, size_t pos) {
  T_ASSERT_X(widget!=nullptr,"widget is null");

  if(widget->parentLay==this)
    return;

  size_t hasReleaseReciver = -1, hasLeavePtr = -1;
  if(widget->parentLay){
    Widget* ow = widget->parentLay->owner();

    for(size_t i=0; i<ow->mouseReleseReciver.size(); ++i)
      if(widget==ow->mouseReleseReciver[i])
        hasReleaseReciver=i;

    for(size_t i=0; i<ow->mouseLeaveReciver.size(); ++i)
      if(widget==ow->mouseLeaveReciver[i])
        hasLeavePtr=i;

    widget->parentLay->take(widget);
    }

  if(pos>=w.size())
    pos=w.size();

  if( widget->hasFocus() || widget->hasChildFocus() )
    widget->unsetChFocus(widget, 0);

  w.insert(w.begin()+pos,widget);

  widget->parentLay = this;
  if( hasReleaseReciver!=size_t(-1) )
    widget->setupMouseReleasePtr(hasReleaseReciver);

  if( hasLeavePtr!=size_t(-1) )
    widget->setupMouseReleasePtr(hasLeavePtr);

  if( owner() )
    widget->setContext( owner()->context() );

  if( widget->nToUpdate ){
    widget->nToUpdate    = false;
    widget->update();
    }

  applyLayout();
  }

void Layout::add(Widget *widget) {
  add(widget,w.size());
  }

void Layout::del(Widget *widget) {
  if(widget->parentLay!=this)
    return;

  w.resize( std::remove( w.begin(), w.end(), widget ) - w.begin() );
  widget->deleteLater();
  widget->detachMouseReleasePtr();
  widget->detachMouseLeavePtr();

  applyLayout();

  if( owner() )
    owner()->update();
  }

void Tempest::Layout::removeAll() {
  std::vector<Widget*> wx;
  std::swap(wx,w);

  if( owner() ){
    Widget* w = owner();

    w->lockDelete();
    w->mouseReleseReciver.clear();
    w->update();

    std::vector<Widget*> lv = w->mouseLeaveReciver;
    for(size_t i=0;i<lv.size();++i){
      Widget*& wx = lv[i];
      while( wx && i<wx->mouseLeaveReciver.size() && wx->mouseLeaveReciver[i]!=nullptr ){
        Widget* l = wx->mouseLeaveReciver[i];
        wx->mouseLeaveReciver[i] = nullptr;
        wx = l;
        }
      }

    for(size_t i=0;i<lv.size();++i){
      Widget* wx = lv[i];
      if( wx )
        wx->lockDelete();
      }

    for(size_t i=0;i<lv.size();++i){
      Widget* wx = lv[i];
      MouseEvent e(0,0,Event::ButtonNone,0,i,Event::MouseLeave);
      if( wx )
        wx->event(e);
      }

    for(size_t i=0;i<lv.size();++i){
      Widget* wx = lv[i];
      if( wx )
        wx->unlockDelete();
      }

    w->mouseLeaveReciver.clear();
    w->unlockDelete();
    }

  for( size_t i=0; i<wx.size(); ++i ){
    wx[i]->parentLay = 0;
    wx[i]->deleteLater();
    }
  wx.clear();

  applyLayout();
  }

Widget *Layout::take(Widget *widget) {
  if(widget->parentLay!=this)
    return widget;

  if( widget->hasFocus() )
    widget->setFocus(0);

  widget->detachMouseReleasePtr();
  widget->detachMouseLeavePtr();
  w.resize( std::remove( w.begin(), w.end(), widget ) - w.begin() );
  widget->parentLay = 0;

  applyLayout();

  if( owner() ){
    owner()->update();
    }

  return widget;
  }

const std::vector<Widget*> &Layout::widgets() {
  return w;
  }

int Layout::spacing() const {
  return mspacing;
  }

void Layout::setMargin(const Margin &m){
  mmargin = m;
  applyLayout();
  }

void Layout::setMargin(int l, int r, int t, int b) {
  setMargin( Margin(l,r,t,b) );
  }

const Margin &Layout::margin() const {
  return mmargin;
  }

void Layout::placeIn(Widget *wx, int x, int y, int w, int h) {
  placeIn(wx, Rect(x,y,w,h) );
  }

void Layout::placeIn(Widget *wx, const Rect &r) {
  int w = std::max( wx->sizePolicy().minSize.w, r.w ),
      h = std::max( wx->sizePolicy().minSize.h, r.h );

  w = std::min( wx->sizePolicy().maxSize.w, w );
  h = std::min( wx->sizePolicy().maxSize.h, h );

  wx->setGeometry( r.x + (r.w-w)/2,
                   r.y + (r.h-h)/2,
                   w,
                   h );
  }

Size Layout::sizeHint(const Widget *wx) {
  Size sz = wx->sizePolicy().minSize;
  if( wx->sizePolicy().typeH==FixedMax )
    sz.w = wx->sizePolicy().maxSize.w;
  if( wx->sizePolicy().typeH==FixedMin)
    sz.w = wx->sizePolicy().minSize.w;

  if( wx->sizePolicy().typeV==FixedMax )
    sz.h = wx->sizePolicy().maxSize.h;
  if( wx->sizePolicy().typeV==FixedMin)
    sz.h = wx->sizePolicy().minSize.h;

  return sz;
  }

int Layout::summarySpacings() {
  return visibleCount()*mspacing;
  }

int Layout::visibleCount() const {
  int cnt = 0;

  for(Widget* wx:w)
    if( wx->isVisible() )
      cnt++;
  return cnt;
  }

void Layout::rebind( Widget* wx) {
  ow = wx;

  if( ow ){
    for( size_t i=0; i<w.size(); ++i ){
      T_ASSERT_X(w[i]!=ow,"recursive layout detected");
      w[i]->setContext( ow->context() );
      }
    }
  }

void Layout::swap(Layout *other){
  if( other==0 ){
    for(Widget* wx:w)
      wx->deleteLater();
    w.clear();
    return;
    }

  size_t s[2] = { w.size(), other->w.size() };
  std::swap( mmargin, other->mmargin );

  w.resize( std::max(s[0], s[1]) );
  other->w.resize( w.size() );

  for( size_t i=0; i<w.size(); ++i ){
    std::swap( w[i], other->w[i] );
    }

  w.resize( s[1] );
  other->w.resize( s[0] );

  for( size_t i=0; i<w.size(); ++i )
    w[i]->parentLay = this;

  for( size_t i=0; i<other->w.size(); ++i )
    other->w[i]->parentLay = other;

  }

void Layout::setSpacing(int s){
  s = std::max(s,0);

  if( mspacing!=s ){
    mspacing = s;
    applyLayout();
    }
  }

void LinearLayout::applyLayoutPrivate( int (*w)( const Size& wd ),
                                       int (*h)( const Size& wd ),
                                       SizePolicyType (*typeH)( const Widget*  ),
                                       SizePolicyType (*typeV)( const Widget*  ),
                                       bool /*hor*/,
                                       void (*setGeometry)( Widget* wd,
                                                            int x, int y,
                                                            int w, int h ) ){
      if( this->widgets().size()==0 )
        return;

      int fixedSize    = 0,
          maxSpaceNeed = 0,
          minSpaceNeedByPref = 0,
          maxSpaceNeedByExp = 0,
          visibles = visibleCount(),
          spacing  = visibles*this->spacing(),

          prefCount = 0,
          exCount   = 0;

      const std::vector<Widget*>& wd = widgets();

      for( size_t i=0; i<wd.size(); ++i )
        if( wd[i]->isVisible() ){
          if( typeH(wd[i])==FixedMin )
            fixedSize += w(wd[i]->sizePolicy().minSize);
            else
          if( typeH(wd[i])==FixedMax )
            fixedSize += w(wd[i]->sizePolicy().maxSize);
            else {
            maxSpaceNeed += w(wd[i]->sizePolicy().maxSize);

            if( typeH(wd[i])==Expanding ){
              maxSpaceNeedByExp += w(wd[i]->sizePolicy().maxSize);
              ++exCount;
              }

            if( typeH(wd[i])==Preferred ){
              minSpaceNeedByPref += w(wd[i]->sizePolicy().minSize);
              ++prefCount;
              }
            }
          }

      spacing = std::max(spacing,
                         w( owner()->size() ) -
                         (maxSpaceNeed+fixedSize+
                          ((orientation()==Vertical)? margin().yMargin() : margin().xMargin()) ) );

      int x = margin().left,
          hmarg = margin().top  + margin().bottom,
          wmarg = margin().left + margin().right,
          marg  = margin().top,
          spaceEx = w(owner()->size()) - spacing - fixedSize - minSpaceNeedByPref,
          spacePref = minSpaceNeedByPref;

      if( orientation()==Vertical ){
        x     = margin().top;
        hmarg = margin().left + margin().right;
        wmarg = margin().top  + margin().bottom;
        marg  = margin().left;
        }

      spaceEx -= wmarg;
      if( spacePref < spaceEx-maxSpaceNeedByExp )
        spacePref = spaceEx-maxSpaceNeedByExp;

      if( exCount==0 ) // TESTME
        spacePref = w(owner()->size()) - spacing - fixedSize - wmarg;

      size_t nVisible=0;
      for( size_t i=0; i<wd.size(); ++i )
        if( wd[i]->isVisible() ){
          int sp = 0, hw = h(owner()->size()) - hmarg;
          if( spaceEx==0 )
            sp = this->spacing();
          else if( visibles-nVisible > 1 )
            sp = spacing/(visibles-nVisible-1);

          if( typeV(wd[i])==FixedMin )
            hw = h(wd[i]->sizePolicy().minSize);else//-hmarg; else
          if( typeV(wd[i])==FixedMax )
            hw = h(wd[i]->sizePolicy().maxSize);//-hmarg;

          int y = marg+( h(owner()->size())-hw-hmarg )/2,
              ww = 0;

          if( typeH(wd[i])==FixedMin ){
            ww = w(wd[i]->sizePolicy().minSize);
            }

          if( typeH(wd[i])==FixedMax ){
            ww = w(wd[i]->sizePolicy().maxSize);
            }

          if( typeH(wd[i])==Preferred ){
            ww = spacePref/prefCount;
            ww = std::max(ww, w(wd[i]->sizePolicy().minSize));
            ww = std::min(ww, w(wd[i]->sizePolicy().maxSize));
            spacePref -= ww;
            --prefCount;
            }

          if( typeH(wd[i])==Expanding ){
            ww = spaceEx/exCount;
            ww = std::max(ww, w(wd[i]->sizePolicy().minSize));
            ww = std::min(ww, w(wd[i]->sizePolicy().maxSize));
            spaceEx -= ww;
            --exCount;
            }

          nVisible++;
          setGeometry( wd[i], x, y, ww, hw );
          x       += ww;
          x       += sp;
          spacing -= sp;
          }
    }

<commit_msg>linear layout fix<commit_after>#include "layout.h"

using namespace Tempest;

Layout::Layout(){
  ow       = 0;
  mspacing = 0;
  }

Layout::~Layout() {
  removeAll();
  }

Widget *Layout::owner() {
  return ow;
  }

const Widget *Layout::owner() const {
  return ow;
  }

void Layout::add(Widget *widget, size_t pos) {
  T_ASSERT_X(widget!=nullptr,"widget is null");

  if(widget->parentLay==this)
    return;

  size_t hasReleaseReciver = -1, hasLeavePtr = -1;
  if(widget->parentLay){
    Widget* ow = widget->parentLay->owner();

    for(size_t i=0; i<ow->mouseReleseReciver.size(); ++i)
      if(widget==ow->mouseReleseReciver[i])
        hasReleaseReciver=i;

    for(size_t i=0; i<ow->mouseLeaveReciver.size(); ++i)
      if(widget==ow->mouseLeaveReciver[i])
        hasLeavePtr=i;

    widget->parentLay->take(widget);
    }

  if(pos>=w.size())
    pos=w.size();

  if( widget->hasFocus() || widget->hasChildFocus() )
    widget->unsetChFocus(widget, 0);

  w.insert(w.begin()+pos,widget);

  widget->parentLay = this;
  if( hasReleaseReciver!=size_t(-1) )
    widget->setupMouseReleasePtr(hasReleaseReciver);

  if( hasLeavePtr!=size_t(-1) )
    widget->setupMouseReleasePtr(hasLeavePtr);

  if( owner() )
    widget->setContext( owner()->context() );

  if( widget->nToUpdate ){
    widget->nToUpdate    = false;
    widget->update();
    }

  applyLayout();
  }

void Layout::add(Widget *widget) {
  add(widget,w.size());
  }

void Layout::del(Widget *widget) {
  if(widget->parentLay!=this)
    return;

  w.resize( std::remove( w.begin(), w.end(), widget ) - w.begin() );
  widget->deleteLater();
  widget->detachMouseReleasePtr();
  widget->detachMouseLeavePtr();

  applyLayout();

  if( owner() )
    owner()->update();
  }

void Tempest::Layout::removeAll() {
  std::vector<Widget*> wx;
  std::swap(wx,w);

  if( owner() ){
    Widget* w = owner();

    w->lockDelete();
    w->mouseReleseReciver.clear();
    w->update();

    std::vector<Widget*> lv = w->mouseLeaveReciver;
    for(size_t i=0;i<lv.size();++i){
      Widget*& wx = lv[i];
      while( wx && i<wx->mouseLeaveReciver.size() && wx->mouseLeaveReciver[i]!=nullptr ){
        Widget* l = wx->mouseLeaveReciver[i];
        wx->mouseLeaveReciver[i] = nullptr;
        wx = l;
        }
      }

    for(size_t i=0;i<lv.size();++i){
      Widget* wx = lv[i];
      if( wx )
        wx->lockDelete();
      }

    for(size_t i=0;i<lv.size();++i){
      Widget* wx = lv[i];
      MouseEvent e(0,0,Event::ButtonNone,0,i,Event::MouseLeave);
      if( wx )
        wx->event(e);
      }

    for(size_t i=0;i<lv.size();++i){
      Widget* wx = lv[i];
      if( wx )
        wx->unlockDelete();
      }

    w->mouseLeaveReciver.clear();
    w->unlockDelete();
    }

  for( size_t i=0; i<wx.size(); ++i ){
    wx[i]->parentLay = 0;
    wx[i]->deleteLater();
    }
  wx.clear();

  applyLayout();
  }

Widget *Layout::take(Widget *widget) {
  if(widget->parentLay!=this)
    return widget;

  if( widget->hasFocus() )
    widget->setFocus(0);

  widget->detachMouseReleasePtr();
  widget->detachMouseLeavePtr();
  w.resize( std::remove( w.begin(), w.end(), widget ) - w.begin() );
  widget->parentLay = 0;

  applyLayout();

  if( owner() ){
    owner()->update();
    }

  return widget;
  }

const std::vector<Widget*> &Layout::widgets() {
  return w;
  }

int Layout::spacing() const {
  return mspacing;
  }

void Layout::setMargin(const Margin &m){
  mmargin = m;
  applyLayout();
  }

void Layout::setMargin(int l, int r, int t, int b) {
  setMargin( Margin(l,r,t,b) );
  }

const Margin &Layout::margin() const {
  return mmargin;
  }

void Layout::placeIn(Widget *wx, int x, int y, int w, int h) {
  placeIn(wx, Rect(x,y,w,h) );
  }

void Layout::placeIn(Widget *wx, const Rect &r) {
  int w = std::max( wx->sizePolicy().minSize.w, r.w ),
      h = std::max( wx->sizePolicy().minSize.h, r.h );

  w = std::min( wx->sizePolicy().maxSize.w, w );
  h = std::min( wx->sizePolicy().maxSize.h, h );

  wx->setGeometry( r.x + (r.w-w)/2,
                   r.y + (r.h-h)/2,
                   w,
                   h );
  }

Size Layout::sizeHint(const Widget *wx) {
  Size sz = wx->sizePolicy().minSize;
  if( wx->sizePolicy().typeH==FixedMax )
    sz.w = wx->sizePolicy().maxSize.w;
  if( wx->sizePolicy().typeH==FixedMin)
    sz.w = wx->sizePolicy().minSize.w;

  if( wx->sizePolicy().typeV==FixedMax )
    sz.h = wx->sizePolicy().maxSize.h;
  if( wx->sizePolicy().typeV==FixedMin)
    sz.h = wx->sizePolicy().minSize.h;

  return sz;
  }

int Layout::summarySpacings() {
  const int vcount = visibleCount();
  if( vcount<=0 )
    return 0;
  return (vcount-1)*mspacing;
  }

int Layout::visibleCount() const {
  int cnt = 0;

  for(Widget* wx:w)
    if( wx->isVisible() )
      cnt++;
  return cnt;
  }

void Layout::rebind( Widget* wx) {
  ow = wx;

  if( ow ){
    for( size_t i=0; i<w.size(); ++i ){
      T_ASSERT_X(w[i]!=ow,"recursive layout detected");
      w[i]->setContext( ow->context() );
      }
    }
  }

void Layout::swap(Layout *other){
  if( other==0 ){
    for(Widget* wx:w)
      wx->deleteLater();
    w.clear();
    return;
    }

  size_t s[2] = { w.size(), other->w.size() };
  std::swap( mmargin, other->mmargin );

  w.resize( std::max(s[0], s[1]) );
  other->w.resize( w.size() );

  for( size_t i=0; i<w.size(); ++i ){
    std::swap( w[i], other->w[i] );
    }

  w.resize( s[1] );
  other->w.resize( s[0] );

  for( size_t i=0; i<w.size(); ++i )
    w[i]->parentLay = this;

  for( size_t i=0; i<other->w.size(); ++i )
    other->w[i]->parentLay = other;

  }

void Layout::setSpacing(int s){
  s = std::max(s,0);

  if( mspacing!=s ){
    mspacing = s;
    applyLayout();
    }
  }

void LinearLayout::applyLayoutPrivate( int (*w)( const Size& wd ),
                                       int (*h)( const Size& wd ),
                                       SizePolicyType (*typeH)( const Widget*  ),
                                       SizePolicyType (*typeV)( const Widget*  ),
                                       bool /*hor*/,
                                       void (*setGeometry)( Widget* wd,
                                                            int x, int y,
                                                            int w, int h ) ){
      if( this->widgets().size()==0 )
        return;

      int fixedSize    = 0,
          maxSpaceNeed = 0,
          minSpaceNeedByPref = 0,
          maxSpaceNeedByExp = 0,
          visibles = visibleCount(),
          spacing  = std::max(0,visibles-1)*this->spacing(),

          prefCount = 0,
          exCount   = 0;

      const std::vector<Widget*>& wd = widgets();

      for( size_t i=0; i<wd.size(); ++i )
        if( wd[i]->isVisible() ){
          if( typeH(wd[i])==FixedMin )
            fixedSize += w(wd[i]->sizePolicy().minSize);
            else
          if( typeH(wd[i])==FixedMax )
            fixedSize += w(wd[i]->sizePolicy().maxSize);
            else {
            maxSpaceNeed += w(wd[i]->sizePolicy().maxSize);

            if( typeH(wd[i])==Expanding ){
              maxSpaceNeedByExp += w(wd[i]->sizePolicy().maxSize);
              ++exCount;
              }

            if( typeH(wd[i])==Preferred ){
              minSpaceNeedByPref += w(wd[i]->sizePolicy().minSize);
              ++prefCount;
              }
            }
          }

      const int realSpacing = w( owner()->size() )
                             -maxSpaceNeed
                             -fixedSize
                             -((orientation()==Vertical)? margin().yMargin() : margin().xMargin());
      spacing = std::max(spacing,realSpacing);

      int x = margin().left,
          hmarg = margin().top  + margin().bottom,
          wmarg = margin().left + margin().right,
          marg  = margin().top,
          spaceEx = w(owner()->size()) - spacing - fixedSize - minSpaceNeedByPref,
          spacePref = minSpaceNeedByPref;

      if( orientation()==Vertical ){
        x     = margin().top;
        hmarg = margin().left + margin().right;
        wmarg = margin().top  + margin().bottom;
        marg  = margin().left;
        }

      spaceEx -= wmarg;
      if( spacePref < spaceEx-maxSpaceNeedByExp )
        spacePref = spaceEx-maxSpaceNeedByExp;

      if( exCount==0 ) // TESTME
        spacePref = w(owner()->size()) - spacing - fixedSize - wmarg;

      size_t nVisible=0;
      for( size_t i=0; i<wd.size(); ++i )
        if( wd[i]->isVisible() ){
          int sp = 0, hw = h(owner()->size()) - hmarg;
          if( visibles-nVisible > 1 )
            sp = spacing/(visibles-nVisible-1);

          if( typeV(wd[i])==FixedMin )
            hw = h(wd[i]->sizePolicy().minSize);else
          if( typeV(wd[i])==FixedMax )
            hw = h(wd[i]->sizePolicy().maxSize);

          int y = marg+( h(owner()->size())-hw-hmarg )/2,
              ww = 0;

          if( typeH(wd[i])==FixedMin ){
            ww = w(wd[i]->sizePolicy().minSize);
            }

          if( typeH(wd[i])==FixedMax ){
            ww = w(wd[i]->sizePolicy().maxSize);
            }

          if( typeH(wd[i])==Preferred ){
            ww = spacePref/prefCount;
            ww = std::max(ww, w(wd[i]->sizePolicy().minSize));
            ww = std::min(ww, w(wd[i]->sizePolicy().maxSize));
            spacePref -= ww;
            --prefCount;
            }

          if( typeH(wd[i])==Expanding ){
            ww = spaceEx/exCount;
            ww = std::max(ww, w(wd[i]->sizePolicy().minSize));
            ww = std::min(ww, w(wd[i]->sizePolicy().maxSize));
            spaceEx -= ww;
            --exCount;
            }

          nVisible++;
          setGeometry( wd[i], x, y, ww, hw );
          x       += ww;
          x       += sp;
          spacing -= sp;
          }
    }

<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/test/test_server.h"

namespace {

const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");

}  // namespace

typedef UITest CollectedCookiesTest;

TEST_F(CollectedCookiesTest, DoubleDisplay) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Disable cookies.
  ASSERT_TRUE(browser->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
                                                CONTENT_SETTING_BLOCK));

  // Load a page with cookies.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie1.html")));

  // Click on the info link twice.
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());
}

TEST_F(CollectedCookiesTest, NavigateAway) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Disable cookies.
  ASSERT_TRUE(browser->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
                                                CONTENT_SETTING_BLOCK));

  // Load a page with cookies.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie1.html")));

  // Click on the info link.
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());

  // Navigate to another page.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie2.html")));
}
<commit_msg>Disable DoubleDisplay and NavigateAway [mark as FAILS_].<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/test/test_server.h"

namespace {

const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");

}  // namespace

typedef UITest CollectedCookiesTest;

// See crbug.com/76573
TEST_F(CollectedCookiesTest, FAILS_DoubleDisplay) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Disable cookies.
  ASSERT_TRUE(browser->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
                                                CONTENT_SETTING_BLOCK));

  // Load a page with cookies.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie1.html")));

  // Click on the info link twice.
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());
}

// See crbug.com/76573
TEST_F(CollectedCookiesTest, FAILS_NavigateAway) {
  net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab(browser->GetTab(0));
  ASSERT_TRUE(tab.get());

  // Disable cookies.
  ASSERT_TRUE(browser->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES,
                                                CONTENT_SETTING_BLOCK));

  // Load a page with cookies.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie1.html")));

  // Click on the info link.
  ASSERT_TRUE(tab->ShowCollectedCookiesDialog());

  // Navigate to another page.
  ASSERT_TRUE(tab->NavigateToURL(test_server.GetURL("files/cookie2.html")));
}
<|endoftext|>