<commit_before>/*
 * openglViewer.cpp
 *
 *  Created on: 21/02/2012
 *      Author: Ben
 */

#include "openglViewer.h"
#include "world.h"
#include "scheduler.h"
#include "events.h"
#include "trace.h"
#include "blinkyBlocksDebugger.h"

//===========================================================================================================
//
//          GlutContext  (class)
//
//===========================================================================================================

int GlutContext::screenWidth = 1024;
int GlutContext::screenHeight = 800;
int GlutContext::keyboardModifier = 0;
//bool GlutContext::showLinks=false;
bool GlutContext::fullScreenMode=false;
GlutSlidingMainWindow *GlutContext::mainWindow=NULL;
GlutPopupWindow *GlutContext::popup=NULL;
GlutPopupMenuWindow *GlutContext::popupMenu=NULL;
GlutHelpWindow *GlutContext::helpWindow=NULL;

void GlutContext::init(int argc, char **argv) {
	OUTPUT << "Avant glutInit()" << endl;
	glutInit(&argc,argv);
	OUTPUT << "Après glutInit()" << endl;
	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_CONTINUE_EXECUTION);
	OUTPUT << "Après glutSetOption()" << endl;
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);

	// creation of a new graphic window
	glutInitWindowPosition(0, 0);
	glutInitWindowSize(screenWidth,screenHeight);
	if (glutCreateWindow("OpenGL BlockSimulator") == GL_FALSE) {
		puts("ERREUR : echec à la création de la fenêtre graphique");
		exit(EXIT_FAILURE);
	}

	//glutFullScreen();
	initShaders();

	////// GL parameters /////////////////////////////////////
	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
	glEnable(GL_NORMALIZE);

	glClearColor(0.3f,0.3f,0.8f,0.0f);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_NORMALIZE);

	glutReshapeFunc(reshapeFunc);
	glutDisplayFunc(drawFunc);
	glutMouseFunc(mouseFunc);
	glutMotionFunc(motionFunc);
	glutPassiveMotionFunc(passiveMotionFunc);
	glutKeyboardFunc(keyboardFunc);
	glutIdleFunc(idleFunc);

	mainWindow = new GlutSlidingMainWindow(screenWidth-40,50,40,screenHeight-60,"../../simulatorCore/smartBlocksTextures/fenetre_onglet.tga");
	popup = new GlutPopupWindow(NULL,0,0,40,30);
}

void GlutContext::deleteContext() {
	delete mainWindow;
	delete popup;
	delete popupMenu;
}

void *GlutContext::lanceScheduler(void *param) {
	int mode = *(int*)param;
	BaseSimulator::getScheduler()->start(mode);
	return(NULL);
}

//////////////////////////////////////////////////////////////////////////////
// fonction de changement de dimensions de la fenetre,
// - width  : largeur (x) de la zone de visualisation
// - height : hauteur (y) de la zone de visualisation
void GlutContext::reshapeFunc(int w,int h) {
	screenWidth=w;
	screenHeight=h;
	Camera* camera=getWorld()->getCamera();
	camera->updateIntrinsics(60,double(w)/double(h),1.0,1500.0);
	// size of the OpenGL drawing area
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	camera->glProjection();
	// camera intrinsic parameters
	//gluPerspective(60,(double)w/(double)h,10.0,5000.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	mainWindow->reshapeFunc(w,h);
}

//////////////////////////////////////////////////////////////////////////////
// fonction associée aux interruptions générées par la souris bouton pressé
// - x,y : coordonnée du curseur dans la fenêtre
void GlutContext::motionFunc(int x,int y) {
	if (mainWindow->mouseFunc(-1,GLUT_DOWN,x,screenHeight - y)>0) return;
	if (keyboardModifier!=GLUT_ACTIVE_CTRL) { // rotation du point de vue
		Camera* camera=getWorld()->getCamera();
		camera->mouseMove(x,y);
	}
}

void GlutContext::passiveMotionFunc(int x,int y) {
	/*int n=mainWindow->mouseFunc(-1,-1,x,screenHeight - y);
	if (n>0) return;
	n=selectFunc(x,y);
	if (n) {
		GlBlock *slct=BaseSimulator::getWorld()->getBlockByNum(n-1);
		popup->setCenterPosition(x,screenHeight - y);
		popup->setInfo(slct->getPopupInfo());
		popup->show(true);
	} else {
		popup->show(false);
	}*/
	if (popupMenu) popupMenu->mouseFunc(-1,-1,x,screenHeight - y);
	if (helpWindow) helpWindow->mouseFunc(-1,-1,x,screenHeight - y);
}

//////////////////////////////////////////////////////////////////////////////
// fonction associée aux interruptions générées par le clic de souris
// - bouton : code du bouton
// - state : état des touches du clavier
// - x,y : coordonnée du curseur dans la fenêtre
void GlutContext::mouseFunc(int button,int state,int x,int y) {
	if (mainWindow->mouseFunc(button,state,x,screenHeight - y)>0) return;
	if (popupMenu) {
		int n=popupMenu->mouseFunc(button,state,x,screenHeight - y);
		if (n) {
			popupMenu->show(false);
			getWorld()->menuChoice(n);
		}
	}
	if (helpWindow) helpWindow->mouseFunc(button,state,x,screenHeight - y);

	keyboardModifier = glutGetModifiers();
	if (keyboardModifier!=GLUT_ACTIVE_CTRL) { // rotation du point de vue
		Camera* camera=getWorld()->getCamera();
		switch (button) {
			case GLUT_LEFT_BUTTON:
				if (state==GLUT_DOWN) {
					camera->mouseDown(x,y);
					int n=selectFunc(x,y);
					GlBlock *glb = BaseSimulator::getWorld()->getBlockByNum(n-1);
					GlBlock *glbs = BaseSimulator::getWorld()->getSelectedBlock();
					if (glbs != NULL && glbs == glb) {
						BaseSimulator::getWorld()->tapBlock(BaseSimulator::getScheduler()->now(), glb->blockId);
					}
				} else
				if (state==GLUT_UP) {
					camera->mouseUp(x,y);
				}
			break;
			case GLUT_RIGHT_BUTTON:
				if (state==GLUT_DOWN) {
					camera->mouseDown(x,y,true);
				} else
				if (state==GLUT_UP) {
					camera->mouseUp(x,y);
				}
			break;
			case 3 :
				camera->mouseZoom(-10);
			break;
			case 4 :
				camera->mouseZoom(10);
			break;
		}
	} else { // selection of the clicked block
		if (state==GLUT_DOWN) {
			if (button==GLUT_LEFT_BUTTON) {
				int n=selectFunc(x,y);
				GlBlock *slct=BaseSimulator::getWorld()->getSelectedBlock();
				// unselect current if exists
				if (slct) slct->toggleHighlight();
				// set n-1 block selected block (no selected block if n=0
				if (n) BaseSimulator::getWorld()->setSelectedBlock(n-1)->toggleHighlight();
				else BaseSimulator::getWorld()->setSelectedBlock(-1);
				mainWindow->select(BaseSimulator::getWorld()->getSelectedBlock());
		  	} else if (button==GLUT_RIGHT_BUTTON) {
				int n=selectFaceFunc(x,y);
				if (n) {
					BaseSimulator::getWorld()->setSelectedFace(n-1);
					BaseSimulator::getWorld()->createPopupMenu(x,y);
				}
		  	}
		}
	}
	glutPostRedisplay();
}

/////////////////////////////////////run/////////////////////////////////////////
// fonction associée aux interruptions clavier
// - c : caractère saisi
// - x,y : coordonnée du curseur dans la fenètre
void GlutContext::keyboardFunc(unsigned char c, int x, int y)
{
	static int modeScheduler;
	Camera* camera=getWorld()->getCamera();

	switch(c)
    { case 27 : case 'q' : case 'Q' : // quit
			glutLeaveMainLoop();
      break;
      case 'f' : glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); break;
      case 'F' : glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); break;
      case '+' : camera->mouseZoom(0.5); break;
      case '-' : camera->mouseZoom(-0.5); break;
	//  case 'l' : showLinks = !showLinks; break;
      case 'r' : getScheduler()->start(SCHEDULER_MODE_REALTIME); break;
      //case 'p' : getScheduler()->pauseSimulation(getScheduler()->now()); break;
     case 'p' : BlinkyBlocks::getDebugger()->handlePauseRequest(); break;
	  case 'R' : getScheduler()->start(SCHEDULER_MODE_FASTEST); break;
	  case 'u' : BlinkyBlocks::getDebugger()->unPauseSim(); break;
	  case 'z' : {
		  World *world = BaseSimulator::getWorld();
		  GlBlock *slct=world->getSelectedBlock();
		  if (slct) {
			  world->getCamera()->setTarget(slct->getPosition());
		  }
	  }
	  break;
	  case 'w' : case 'W' :
          fullScreenMode = !fullScreenMode;
          if (fullScreenMode) {
        	  glutFullScreen();
          } else {
              glutReshapeWindow(1024, 800);
              glutPositionWindow(0,0);
          }
      break;
	  case 'h' :
		  if (!helpWindow) {
			  BaseSimulator::getWorld()->createHelpWindow();
		  }
		  helpWindow->showHide();
	  break;

    }

  glutPostRedisplay();
}

//////////////////////////////////////////////////////////////////////////////
// fonction de mise à jour des données pour l'animation
void GlutContext::idleFunc(void) {
#ifdef _WIN32
	  Sleep(20);
#else
	  usleep(20000);
#endif
	glutPostRedisplay();
}

void GlutContext::drawFunc(void) {
	Camera*camera=getWorld()->getCamera();

	shadowedRenderingStep1(camera);
	glPushMatrix();
	BaseSimulator::getWorld()->glDraw();
	glPopMatrix();

	shadowedRenderingStep2(screenWidth,screenHeight);

	shadowedRenderingStep3(camera);
	glPushMatrix();
	BaseSimulator::getWorld()->glDraw();
	glPopMatrix();

	shadowedRenderingStep4();

	// drawing of the interface
	glEnable(GL_BLEND);
	glDisable(GL_DEPTH_TEST);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0,screenWidth,0,screenHeight);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	mainWindow->glDraw();
	popup->glDraw();
	if (popupMenu) popupMenu->glDraw();
	if (helpWindow) helpWindow->glDraw();
	glEnable(GL_DEPTH_TEST);
	glutSwapBuffers();
}

//////////////////////////////////////////////////////////////////////////////
// fonction de détection d'un objet à l'écran en position x,y.
int GlutContext::selectFunc(int x,int y) {
	GLuint selectBuf[512];
	GLint hits;
	GLint viewport[4];
	Camera* camera=getWorld()->getCamera();

	glGetIntegerv(GL_VIEWPORT,viewport); // récupération de la position et de la taille de la fenêtre

	glSelectBuffer(512,selectBuf);
	glRenderMode(GL_SELECT);
	glInitNames();
	glPushName(0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPickMatrix((float) x,(float)(screenHeight-y),3.0,3.0,viewport);
	camera->glProjection();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	camera->glLookAt();

	glPushMatrix();
  	BaseSimulator::getWorld()->glDrawId();
  	glPopMatrix();

  	glFlush();
  	hits = glRenderMode(GL_RENDER);
  	return processHits(hits,selectBuf);
 }

//////////////////////////////////////////////////////////////////////////////
// fonction de détection d'un objet à l'écran en position x,y.
int GlutContext::selectFaceFunc(int x,int y) {
	GLuint selectBuf[512];
	GLint hits;
	GLint viewport[4];
	Camera* camera=getWorld()->getCamera();

	glGetIntegerv(GL_VIEWPORT,viewport); // récupération de la position et de la taille de la fenêtre

	glSelectBuffer(512,selectBuf);
	glRenderMode(GL_SELECT);
	glInitNames();
	glPushName(0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPickMatrix((float) x,(float)(screenHeight-y),3.0,3.0,viewport);
	camera->glProjection();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	camera->glLookAt();

	glPushMatrix();
  	BaseSimulator::getWorld()->glDrawIdByMaterial();
  	glPopMatrix();

  	glFlush();
  	hits = glRenderMode(GL_RENDER);
  	return processHits(hits,selectBuf);
 }

//////////////////////////////////////////////////////////////////////////////
// recherche du premier élément dans le tableau d'objet cliqués
// tableau d'entiers : { [name,zmin,zmax,n],[name,zmin,zmax,n]...}
int GlutContext::processHits(GLint hits, GLuint *buffer) {
  if (hits==0)
  { return 0;
  }
  GLuint *ptr=buffer;
  GLuint nmini = ptr[3];
  GLuint zmini = ptr[1];
  ptr+=4;
  for (int i=1; i<hits; i++)
  { if (ptr[1]<zmini)
    { zmini = ptr[1];
      nmini = ptr[3];
    }
    ptr+=4;
  }
  // traitement d'une selection
  // nmini contient le numéro de l'élément sélectionné
  // celui de z minimum
  return nmini;
}

void GlutContext::mainLoop() {
	glutMainLoop();
	getScheduler()->stop(BaseSimulator::getScheduler()->now());
	deleteContext();
}

void GlutContext::addTrace(const string &message,int id) {
	if (mainWindow) mainWindow->addTrace(id,message);
}

<commit_msg>got rid of unnecc var<commit_after>/*
 * openglViewer.cpp
 *
 *  Created on: 21/02/2012
 *      Author: Ben
 */

#include "openglViewer.h"
#include "world.h"
#include "scheduler.h"
#include "events.h"
#include "trace.h"
#include "blinkyBlocksDebugger.h"

//===========================================================================================================
//
//          GlutContext  (class)
//
//===========================================================================================================

int GlutContext::screenWidth = 1024;
int GlutContext::screenHeight = 800;
int GlutContext::keyboardModifier = 0;
//bool GlutContext::showLinks=false;
bool GlutContext::fullScreenMode=false;
GlutSlidingMainWindow *GlutContext::mainWindow=NULL;
GlutPopupWindow *GlutContext::popup=NULL;
GlutPopupMenuWindow *GlutContext::popupMenu=NULL;
GlutHelpWindow *GlutContext::helpWindow=NULL;

void GlutContext::init(int argc, char **argv) {
	OUTPUT << "Avant glutInit()" << endl;
	glutInit(&argc,argv);
	OUTPUT << "Après glutInit()" << endl;
	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_CONTINUE_EXECUTION);
	OUTPUT << "Après glutSetOption()" << endl;
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);

	// creation of a new graphic window
	glutInitWindowPosition(0, 0);
	glutInitWindowSize(screenWidth,screenHeight);
	if (glutCreateWindow("OpenGL BlockSimulator") == GL_FALSE) {
		puts("ERREUR : echec à la création de la fenêtre graphique");
		exit(EXIT_FAILURE);
	}

	//glutFullScreen();
	initShaders();

	////// GL parameters /////////////////////////////////////
	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
	glEnable(GL_NORMALIZE);

	glClearColor(0.3f,0.3f,0.8f,0.0f);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_NORMALIZE);

	glutReshapeFunc(reshapeFunc);
	glutDisplayFunc(drawFunc);
	glutMouseFunc(mouseFunc);
	glutMotionFunc(motionFunc);
	glutPassiveMotionFunc(passiveMotionFunc);
	glutKeyboardFunc(keyboardFunc);
	glutIdleFunc(idleFunc);

	mainWindow = new GlutSlidingMainWindow(screenWidth-40,50,40,screenHeight-60,"../../simulatorCore/smartBlocksTextures/fenetre_onglet.tga");
	popup = new GlutPopupWindow(NULL,0,0,40,30);
}

void GlutContext::deleteContext() {
	delete mainWindow;
	delete popup;
	delete popupMenu;
}

void *GlutContext::lanceScheduler(void *param) {
	int mode = *(int*)param;
	BaseSimulator::getScheduler()->start(mode);
	return(NULL);
}

//////////////////////////////////////////////////////////////////////////////
// fonction de changement de dimensions de la fenetre,
// - width  : largeur (x) de la zone de visualisation
// - height : hauteur (y) de la zone de visualisation
void GlutContext::reshapeFunc(int w,int h) {
	screenWidth=w;
	screenHeight=h;
	Camera* camera=getWorld()->getCamera();
	camera->updateIntrinsics(60,double(w)/double(h),1.0,1500.0);
	// size of the OpenGL drawing area
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	camera->glProjection();
	// camera intrinsic parameters
	//gluPerspective(60,(double)w/(double)h,10.0,5000.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	mainWindow->reshapeFunc(w,h);
}

//////////////////////////////////////////////////////////////////////////////
// fonction associée aux interruptions générées par la souris bouton pressé
// - x,y : coordonnée du curseur dans la fenêtre
void GlutContext::motionFunc(int x,int y) {
	if (mainWindow->mouseFunc(-1,GLUT_DOWN,x,screenHeight - y)>0) return;
	if (keyboardModifier!=GLUT_ACTIVE_CTRL) { // rotation du point de vue
		Camera* camera=getWorld()->getCamera();
		camera->mouseMove(x,y);
	}
}

void GlutContext::passiveMotionFunc(int x,int y) {
	/*int n=mainWindow->mouseFunc(-1,-1,x,screenHeight - y);
	if (n>0) return;
	n=selectFunc(x,y);
	if (n) {
		GlBlock *slct=BaseSimulator::getWorld()->getBlockByNum(n-1);
		popup->setCenterPosition(x,screenHeight - y);
		popup->setInfo(slct->getPopupInfo());
		popup->show(true);
	} else {
		popup->show(false);
	}*/
	if (popupMenu) popupMenu->mouseFunc(-1,-1,x,screenHeight - y);
	if (helpWindow) helpWindow->mouseFunc(-1,-1,x,screenHeight - y);
}

//////////////////////////////////////////////////////////////////////////////
// fonction associée aux interruptions générées par le clic de souris
// - bouton : code du bouton
// - state : état des touches du clavier
// - x,y : coordonnée du curseur dans la fenêtre
void GlutContext::mouseFunc(int button,int state,int x,int y) {
	if (mainWindow->mouseFunc(button,state,x,screenHeight - y)>0) return;
	if (popupMenu) {
		int n=popupMenu->mouseFunc(button,state,x,screenHeight - y);
		if (n) {
			popupMenu->show(false);
			getWorld()->menuChoice(n);
		}
	}
	if (helpWindow) helpWindow->mouseFunc(button,state,x,screenHeight - y);

	keyboardModifier = glutGetModifiers();
	if (keyboardModifier!=GLUT_ACTIVE_CTRL) { // rotation du point de vue
		Camera* camera=getWorld()->getCamera();
		switch (button) {
			case GLUT_LEFT_BUTTON:
				if (state==GLUT_DOWN) {
					camera->mouseDown(x,y);
					int n=selectFunc(x,y);
					GlBlock *glb = BaseSimulator::getWorld()->getBlockByNum(n-1);
					GlBlock *glbs = BaseSimulator::getWorld()->getSelectedBlock();
					if (glbs != NULL && glbs == glb) {
						BaseSimulator::getWorld()->tapBlock(BaseSimulator::getScheduler()->now(), glb->blockId);
					}
				} else
				if (state==GLUT_UP) {
					camera->mouseUp(x,y);
				}
			break;
			case GLUT_RIGHT_BUTTON:
				if (state==GLUT_DOWN) {
					camera->mouseDown(x,y,true);
				} else
				if (state==GLUT_UP) {
					camera->mouseUp(x,y);
				}
			break;
			case 3 :
				camera->mouseZoom(-10);
			break;
			case 4 :
				camera->mouseZoom(10);
			break;
		}
	} else { // selection of the clicked block
		if (state==GLUT_DOWN) {
			if (button==GLUT_LEFT_BUTTON) {
				int n=selectFunc(x,y);
				GlBlock *slct=BaseSimulator::getWorld()->getSelectedBlock();
				// unselect current if exists
				if (slct) slct->toggleHighlight();
				// set n-1 block selected block (no selected block if n=0
				if (n) BaseSimulator::getWorld()->setSelectedBlock(n-1)->toggleHighlight();
				else BaseSimulator::getWorld()->setSelectedBlock(-1);
				mainWindow->select(BaseSimulator::getWorld()->getSelectedBlock());
		  	} else if (button==GLUT_RIGHT_BUTTON) {
				int n=selectFaceFunc(x,y);
				if (n) {
					BaseSimulator::getWorld()->setSelectedFace(n-1);
					BaseSimulator::getWorld()->createPopupMenu(x,y);
				}
		  	}
		}
	}
	glutPostRedisplay();
}

/////////////////////////////////////run/////////////////////////////////////////
// fonction associée aux interruptions clavier
// - c : caractère saisi
// - x,y : coordonnée du curseur dans la fenètre
void GlutContext::keyboardFunc(unsigned char c, int x, int y)
{
  //  static int modeScheduler;
	Camera* camera=getWorld()->getCamera();

	switch(c)
    { case 27 : case 'q' : case 'Q' : // quit
			glutLeaveMainLoop();
      break;
      case 'f' : glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); break;
      case 'F' : glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); break;
      case '+' : camera->mouseZoom(0.5); break;
      case '-' : camera->mouseZoom(-0.5); break;
	//  case 'l' : showLinks = !showLinks; break;
      case 'r' : getScheduler()->start(SCHEDULER_MODE_REALTIME); break;
      //case 'p' : getScheduler()->pauseSimulation(getScheduler()->now()); break;
     case 'p' : BlinkyBlocks::getDebugger()->handlePauseRequest(); break;
	  case 'R' : getScheduler()->start(SCHEDULER_MODE_FASTEST); break;
	  case 'u' : BlinkyBlocks::getDebugger()->unPauseSim(); break;
	  case 'z' : {
		  World *world = BaseSimulator::getWorld();
		  GlBlock *slct=world->getSelectedBlock();
		  if (slct) {
			  world->getCamera()->setTarget(slct->getPosition());
		  }
	  }
	  break;
	  case 'w' : case 'W' :
          fullScreenMode = !fullScreenMode;
          if (fullScreenMode) {
        	  glutFullScreen();
          } else {
              glutReshapeWindow(1024, 800);
              glutPositionWindow(0,0);
          }
      break;
	  case 'h' :
		  if (!helpWindow) {
			  BaseSimulator::getWorld()->createHelpWindow();
		  }
		  helpWindow->showHide();
	  break;

    }

  glutPostRedisplay();
}

//////////////////////////////////////////////////////////////////////////////
// fonction de mise à jour des données pour l'animation
void GlutContext::idleFunc(void) {
#ifdef _WIN32
	  Sleep(20);
#else
	  usleep(20000);
#endif
	glutPostRedisplay();
}

void GlutContext::drawFunc(void) {
	Camera*camera=getWorld()->getCamera();

	shadowedRenderingStep1(camera);
	glPushMatrix();
	BaseSimulator::getWorld()->glDraw();
	glPopMatrix();

	shadowedRenderingStep2(screenWidth,screenHeight);

	shadowedRenderingStep3(camera);
	glPushMatrix();
	BaseSimulator::getWorld()->glDraw();
	glPopMatrix();

	shadowedRenderingStep4();

	// drawing of the interface
	glEnable(GL_BLEND);
	glDisable(GL_DEPTH_TEST);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0,screenWidth,0,screenHeight);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	mainWindow->glDraw();
	popup->glDraw();
	if (popupMenu) popupMenu->glDraw();
	if (helpWindow) helpWindow->glDraw();
	glEnable(GL_DEPTH_TEST);
	glutSwapBuffers();
}

//////////////////////////////////////////////////////////////////////////////
// fonction de détection d'un objet à l'écran en position x,y.
int GlutContext::selectFunc(int x,int y) {
	GLuint selectBuf[512];
	GLint hits;
	GLint viewport[4];
	Camera* camera=getWorld()->getCamera();

	glGetIntegerv(GL_VIEWPORT,viewport); // récupération de la position et de la taille de la fenêtre

	glSelectBuffer(512,selectBuf);
	glRenderMode(GL_SELECT);
	glInitNames();
	glPushName(0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPickMatrix((float) x,(float)(screenHeight-y),3.0,3.0,viewport);
	camera->glProjection();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	camera->glLookAt();

	glPushMatrix();
  	BaseSimulator::getWorld()->glDrawId();
  	glPopMatrix();

  	glFlush();
  	hits = glRenderMode(GL_RENDER);
  	return processHits(hits,selectBuf);
 }

//////////////////////////////////////////////////////////////////////////////
// fonction de détection d'un objet à l'écran en position x,y.
int GlutContext::selectFaceFunc(int x,int y) {
	GLuint selectBuf[512];
	GLint hits;
	GLint viewport[4];
	Camera* camera=getWorld()->getCamera();

	glGetIntegerv(GL_VIEWPORT,viewport); // récupération de la position et de la taille de la fenêtre

	glSelectBuffer(512,selectBuf);
	glRenderMode(GL_SELECT);
	glInitNames();
	glPushName(0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPickMatrix((float) x,(float)(screenHeight-y),3.0,3.0,viewport);
	camera->glProjection();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	camera->glLookAt();

	glPushMatrix();
  	BaseSimulator::getWorld()->glDrawIdByMaterial();
  	glPopMatrix();

  	glFlush();
  	hits = glRenderMode(GL_RENDER);
  	return processHits(hits,selectBuf);
 }

//////////////////////////////////////////////////////////////////////////////
// recherche du premier élément dans le tableau d'objet cliqués
// tableau d'entiers : { [name,zmin,zmax,n],[name,zmin,zmax,n]...}
int GlutContext::processHits(GLint hits, GLuint *buffer) {
  if (hits==0)
  { return 0;
  }
  GLuint *ptr=buffer;
  GLuint nmini = ptr[3];
  GLuint zmini = ptr[1];
  ptr+=4;
  for (int i=1; i<hits; i++)
  { if (ptr[1]<zmini)
    { zmini = ptr[1];
      nmini = ptr[3];
    }
    ptr+=4;
  }
  // traitement d'une selection
  // nmini contient le numéro de l'élément sélectionné
  // celui de z minimum
  return nmini;
}

void GlutContext::mainLoop() {
	glutMainLoop();
	getScheduler()->stop(BaseSimulator::getScheduler()->now());
	deleteContext();
}

void GlutContext::addTrace(const string &message,int id) {
	if (mainWindow) mainWindow->addTrace(id,message);
}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAdaptiveHistogramEqualizationImageFilter.txx"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.txx"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBSplineCenteredL2ResampleImageFilterBase.txx"
#include "itkBSplineCenteredResampleImageFilterBase.txx"
#include "itkBSplineDecompositionImageFilter.txx"
#include "itkBSplineDownsampleImageFilter.txx"
#include "itkBSplineInterpolateImageFunction.txx"
#include "itkBSplineL2ResampleImageFilterBase.txx"
#include "itkBSplineResampleImageFilterBase.txx"
#include "itkBSplineResampleImageFunction.h"
#include "itkBSplineUpsampleImageFilter.txx"
#include "itkBilateralImageFilter.txx"
#include "itkBinaryDilateImageFilter.txx"
#include "itkBinaryErodeImageFilter.txx"
#include "itkBinaryFunctorImageFilter.txx"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinaryMaskToNarrowBandPointSetFilter.txx"
#include "itkBinaryMedianImageFilter.txx"
#include "itkBinaryThresholdImageFilter.txx"
#include "itkBinomialBlurImageFilter.txx"
#include "itkBloxBoundaryPointImageToBloxBoundaryProfileImageFilter.txx"
#include "itkBloxBoundaryPointToCoreAtomImageFilter.txx"
#include "itkCannyEdgeDetectionImageFilter.txx"
#include "itkCastImageFilter.h"
#include "itkChangeInformationImageFilter.txx"
#include "itkComposeRGBImageFilter.h"
#include "itkConfidenceConnectedImageFilter.txx"
#include "itkConnectedComponentImageFilter.txx"
#include "itkConnectedThresholdImageFilter.txx"
#include "itkConstantPadImageFilter.txx"
#include "itkCosImageFilter.h"
#include "itkCropImageFilter.txx"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkDanielssonDistanceMapImageFilter.txx"
#include "itkDerivativeImageFilter.txx"
#include "itkDifferenceOfGaussiansGradientImageFilter.txx"
#include "itkDilateObjectMorphologyImageFilter.txx"
#include "itkDirectedHausdorffDistanceImageFilter.txx"
#include "itkDiscreteGaussianImageFilter.txx"
#include "itkDivideImageFilter.h"
#include "itkDoubleThresholdImageFilter.txx"
#include "itkEdgePotentialImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.txx"
#include "itkErodeObjectMorphologyImageFilter.txx"
#include "itkExpImageFilter.h"
#include "itkExpNegativeImageFilter.h"
#include "itkExpandImageFilter.txx"
#include "itkExtractImageFilter.txx"
#include "itkExtractImageFilterRegionCopier.h"
#include "itkFlipImageFilter.txx"
#include "itkGaussianImageSource.txx"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.txx"
#include "itkGradientImageToBloxBoundaryPointImageFilter.txx"
#include "itkGradientMagnitudeImageFilter.txx"
#include "itkGradientMagnitudeRecursiveGaussianImageFilter.txx"
#include "itkGradientNDAnisotropicDiffusionFunction.txx"
#include "itkGradientRecursiveGaussianImageFilter.txx"
#include "itkGradientToMagnitudeImageFilter.h"
#include "itkGrayscaleConnectedClosingImageFilter.txx"
#include "itkGrayscaleConnectedOpeningImageFilter.txx"
#include "itkGrayscaleDilateImageFilter.txx"
#include "itkGrayscaleErodeImageFilter.txx"
#include "itkGrayscaleFillholeImageFilter.txx"
#include "itkGrayscaleFunctionDilateImageFilter.txx"
#include "itkGrayscaleFunctionErodeImageFilter.txx"
#include "itkGrayscaleGeodesicDilateImageFilter.txx"
#include "itkGrayscaleGeodesicErodeImageFilter.txx"
#include "itkHConcaveImageFilter.txx"
#include "itkHConvexImageFilter.txx"
#include "itkHMaximaImageFilter.txx"
#include "itkHMinimaImageFilter.txx"
#include "itkHardConnectedComponentImageFilter.txx"
#include "itkHausdorffDistanceImageFilter.txx"
#include "itkHoughTransform2DCirclesImageFilter.txx"
#include "itkHoughTransform2DLinesImageFilter.txx"
#include "itkImageToMeshFilter.txx"
#include "itkImageToParametricSpaceFilter.txx"
#include "itkImportImageFilter.txx"
#include "itkIntensityWindowingImageFilter.txx"
#include "itkInteriorExteriorMeshFilter.txx"
#include "itkInterpolateImageFilter.txx"
#include "itkInterpolateImagePointsFilter.txx"
#include "itkIsolatedConnectedImageFilter.txx"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.txx"
#include "itkLaplacianRecursiveGaussianImageFilter.txx"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMaskImageFilter.h"
#include "itkMaximumImageFilter.h"
#include "itkMeanImageFilter.txx"
#include "itkMedianImageFilter.txx"
#include "itkMinimumImageFilter.h"
#include "itkMinimumMaximumImageCalculator.txx"
#include "itkMinimumMaximumImageFilter.txx"
#include "itkMirrorPadImageFilter.txx"
#include "itkMorphologyImageFilter.txx"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.txx"
#include "itkNeighborhoodConnectedImageFilter.txx"
#include "itkNeighborhoodOperatorImageFilter.txx"
#include "itkNoiseImageFilter.txx"
#include "itkNonThreadedShrinkImageFilter.txx"
#include "itkNormalizeImageFilter.txx"
#include "itkObjectMorphologyImageFilter.txx"
#include "itkPadImageFilter.txx"
#include "itkParametricSpaceToImageSpaceMeshFilter.txx"
#include "itkPasteImageFilter.txx"
#include "itkPermuteAxesImageFilter.txx"
#include "itkPlaheImageFilter.txx"
#include "itkRandomImageSource.txx"
#include "itkRecursiveGaussianImageFilter.txx"
#include "itkRecursiveSeparableImageFilter.txx"
#include "itkReflectImageFilter.txx"
#include "itkReflectiveImageRegionConstIterator.txx"
#include "itkReflectiveImageRegionIterator.txx"
#include "itkRegionOfInterestImageFilter.txx"
#include "itkRelabelComponentImageFilter.txx"
#include "itkResampleImageFilter.txx"
#include "itkRescaleIntensityImageFilter.txx"
#include "itkScalarAnisotropicDiffusionFunction.txx"
#include "itkScalarToArrayCastImageFilter.txx"
#include "itkShiftScaleImageFilter.txx"
#include "itkShiftScaleInPlaceImageFilter.txx"
#include "itkShrinkImageFilter.txx"
#include "itkSigmoidImageFilter.h"
#include "itkSimilarityIndexImageFilter.txx"
#include "itkSinImageFilter.h"
#include "itkSmoothingRecursiveGaussianImageFilter.txx"
#include "itkSobelEdgeDetectionImageFilter.txx"
#include "itkSparseFieldLayer.txx"
#include "itkSparseFieldLevelSetImageFilter.txx"
#include "itkSpatialFunctionImageEvaluatorFilter.txx"
#include "itkSpatialObjectToImageFilter.txx"
#include "itkSpatialObjectToImageStatisticsCalculator.txx"
#include "itkSqrtImageFilter.h"
#include "itkSquareImageFilter.h"
#include "itkSquaredDifferenceImageFilter.h"
#include "itkStatisticsImageFilter.txx"
#include "itkStreamingImageFilter.txx"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.txx"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.txx"
#include "itkTobogganImageFilter.txx"
#include "itkTransformMeshFilter.txx"
#include "itkTwoOutputExampleImageFilter.txx"
#include "itkUnaryFunctorImageFilter.txx"
#include "itkVTKImageExport.txx"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.txx"
#include "itkVectorAnisotropicDiffusionFunction.txx"
#include "itkVectorCastImageFilter.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkVectorExpandImageFilter.txx"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientMagnitudeImageFilter.txx"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.txx"
#include "itkVectorIndexSelectionCastImageFilter.h"
#include "itkVectorNeighborhoodOperatorImageFilter.txx"
#include "itkWarpImageFilter.txx"
#include "itkWrapPadImageFilter.txx"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.txx"
#include "itkZeroCrossingImageFilter.txx"

int main ( int , char*  )
{

  return 0;
}

<commit_msg>ENH: Updated to latest headers<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAdaptiveHistogramEqualizationImageFilter.txx"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.txx"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBSplineCenteredL2ResampleImageFilterBase.txx"
#include "itkBSplineCenteredResampleImageFilterBase.txx"
#include "itkBSplineDecompositionImageFilter.txx"
#include "itkBSplineDownsampleImageFilter.txx"
#include "itkBSplineInterpolateImageFunction.txx"
#include "itkBSplineL2ResampleImageFilterBase.txx"
#include "itkBSplineResampleImageFilterBase.txx"
#include "itkBSplineResampleImageFunction.h"
#include "itkBSplineUpsampleImageFilter.txx"
#include "itkBilateralImageFilter.txx"
#include "itkBinaryDilateImageFilter.txx"
#include "itkBinaryErodeImageFilter.txx"
#include "itkBinaryFunctorImageFilter.txx"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinaryMaskToNarrowBandPointSetFilter.txx"
#include "itkBinaryMedianImageFilter.txx"
#include "itkBinaryThresholdImageFilter.txx"
#include "itkBinomialBlurImageFilter.txx"
#include "itkBloxBoundaryPointImageToBloxBoundaryProfileImageFilter.txx"
#include "itkBloxBoundaryPointToCoreAtomImageFilter.txx"
#include "itkCannyEdgeDetectionImageFilter.txx"
#include "itkCastImageFilter.h"
#include "itkChangeInformationImageFilter.txx"
#include "itkComposeRGBImageFilter.h"
#include "itkConfidenceConnectedImageFilter.txx"
#include "itkConnectedComponentImageFilter.txx"
#include "itkConnectedThresholdImageFilter.txx"
#include "itkConstantPadImageFilter.txx"
#include "itkCosImageFilter.h"
#include "itkCropImageFilter.txx"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkDanielssonDistanceMapImageFilter.txx"
#include "itkDerivativeImageFilter.txx"
#include "itkDifferenceOfGaussiansGradientImageFilter.txx"
#include "itkDilateObjectMorphologyImageFilter.txx"
#include "itkDirectedHausdorffDistanceImageFilter.txx"
#include "itkDiscreteGaussianImageFilter.txx"
#include "itkDivideImageFilter.h"
#include "itkDoubleThresholdImageFilter.txx"
#include "itkEdgePotentialImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.txx"
#include "itkErodeObjectMorphologyImageFilter.txx"
#include "itkExpImageFilter.h"
#include "itkExpNegativeImageFilter.h"
#include "itkExpandImageFilter.txx"
#include "itkExtractImageFilter.txx"
#include "itkExtractImageFilterRegionCopier.h"
#include "itkFlipImageFilter.txx"
#include "itkGaussianImageSource.txx"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.txx"
#include "itkGradientImageToBloxBoundaryPointImageFilter.txx"
#include "itkGradientMagnitudeImageFilter.txx"
#include "itkGradientMagnitudeRecursiveGaussianImageFilter.txx"
#include "itkGradientNDAnisotropicDiffusionFunction.txx"
#include "itkGradientRecursiveGaussianImageFilter.txx"
#include "itkGradientToMagnitudeImageFilter.h"
#include "itkGrayscaleConnectedClosingImageFilter.txx"
#include "itkGrayscaleConnectedOpeningImageFilter.txx"
#include "itkGrayscaleDilateImageFilter.txx"
#include "itkGrayscaleErodeImageFilter.txx"
#include "itkGrayscaleFillholeImageFilter.txx"
#include "itkGrayscaleFunctionDilateImageFilter.txx"
#include "itkGrayscaleFunctionErodeImageFilter.txx"
#include "itkGrayscaleGeodesicDilateImageFilter.txx"
#include "itkGrayscaleGeodesicErodeImageFilter.txx"
#include "itkHConcaveImageFilter.txx"
#include "itkHConvexImageFilter.txx"
#include "itkHMaximaImageFilter.txx"
#include "itkHMinimaImageFilter.txx"
#include "itkHardConnectedComponentImageFilter.txx"
#include "itkHausdorffDistanceImageFilter.txx"
#include "itkHoughTransform2DCirclesImageFilter.txx"
#include "itkHoughTransform2DLinesImageFilter.txx"
#include "itkImageToMeshFilter.txx"
#include "itkImageToParametricSpaceFilter.txx"
#include "itkImportImageFilter.txx"
#include "itkIntensityWindowingImageFilter.txx"
#include "itkInteriorExteriorMeshFilter.txx"
#include "itkInterpolateImageFilter.txx"
#include "itkInterpolateImagePointsFilter.txx"
#include "itkIsolatedConnectedImageFilter.txx"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.txx"
#include "itkLaplacianRecursiveGaussianImageFilter.txx"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMaskImageFilter.h"
#include "itkMaximumImageFilter.h"
#include "itkMeanImageFilter.txx"
#include "itkMedianImageFilter.txx"
#include "itkMinimumImageFilter.h"
#include "itkMinimumMaximumImageCalculator.txx"
#include "itkMinimumMaximumImageFilter.txx"
#include "itkMirrorPadImageFilter.txx"
#include "itkMorphologyImageFilter.txx"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.txx"
#include "itkNeighborhoodConnectedImageFilter.txx"
#include "itkNeighborhoodOperatorImageFilter.txx"
#include "itkNoiseImageFilter.txx"
#include "itkNonThreadedShrinkImageFilter.txx"
#include "itkNormalizeImageFilter.txx"
#include "itkObjectMorphologyImageFilter.txx"
#include "itkPadImageFilter.txx"
#include "itkParametricSpaceToImageSpaceMeshFilter.txx"
#include "itkPasteImageFilter.txx"
#include "itkPermuteAxesImageFilter.txx"
#include "itkPlaheImageFilter.txx"
#include "itkRandomImageSource.txx"
#include "itkRecursiveGaussianImageFilter.txx"
#include "itkRecursiveSeparableImageFilter.txx"
#include "itkReflectImageFilter.txx"
#include "itkReflectiveImageRegionConstIterator.txx"
#include "itkReflectiveImageRegionIterator.txx"
#include "itkRegionOfInterestImageFilter.txx"
#include "itkRelabelComponentImageFilter.txx"
#include "itkResampleImageFilter.txx"
#include "itkRescaleIntensityImageFilter.txx"
#include "itkScalarAnisotropicDiffusionFunction.txx"
#include "itkScalarToArrayCastImageFilter.txx"
#include "itkShiftScaleImageFilter.txx"
#include "itkShiftScaleInPlaceImageFilter.txx"
#include "itkShrinkImageFilter.txx"
#include "itkSigmoidImageFilter.h"
#include "itkSimilarityIndexImageFilter.txx"
#include "itkSinImageFilter.h"
#include "itkSmoothingRecursiveGaussianImageFilter.txx"
#include "itkSobelEdgeDetectionImageFilter.txx"
#include "itkSparseFieldLayer.txx"
#include "itkSparseFieldLevelSetImageFilter.txx"
#include "itkSpatialFunctionImageEvaluatorFilter.txx"
#include "itkSpatialObjectToImageFilter.txx"
#include "itkSpatialObjectToImageStatisticsCalculator.txx"
#include "itkSqrtImageFilter.h"
#include "itkSquareImageFilter.h"
#include "itkSquaredDifferenceImageFilter.h"
#include "itkStatisticsImageFilter.txx"
#include "itkStreamingImageFilter.txx"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.txx"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.txx"
#include "itkTobogganImageFilter.txx"
#include "itkTransformMeshFilter.txx"
#include "itkTwoOutputExampleImageFilter.txx"
#include "itkUnaryFunctorImageFilter.txx"
#include "itkVTKImageExport.txx"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.txx"
#include "itkVectorAnisotropicDiffusionFunction.txx"
#include "itkVectorCastImageFilter.h"
#include "itkVectorConfidenceConnectedImageFilter.txx"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkVectorExpandImageFilter.txx"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientMagnitudeImageFilter.txx"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.txx"
#include "itkVectorIndexSelectionCastImageFilter.h"
#include "itkVectorNeighborhoodOperatorImageFilter.txx"
#include "itkWarpImageFilter.txx"
#include "itkWrapPadImageFilter.txx"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.txx"
#include "itkZeroCrossingImageFilter.txx"

int main ( int , char*  )
{

  return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2021 dresden elektronik ingenieurtechnik gmbh.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 *
 */

#include "deconz/aps.h"
#include "device_js.h"
#include "device_js_wrappers.h"

#include <QJSEngine>
#include <QMetaProperty>

static DeviceJs *_djs = nullptr; // singleton

class DeviceJsPrivate
{
public:
    QJSEngine engine;
    QJSValue result;
    JsResource *jsResource = nullptr;
    JsZclAttribute *jsZclAttribute = nullptr;
    JsZclFrame *jsZclFrame = nullptr;
    JsResourceItem *jsItem = nullptr;
    JsUtils *jsUtils = nullptr;
    const deCONZ::ApsDataIndication *apsInd = nullptr;
};

// Polyfills for older Qt versions
static const char *PF_String_prototype_padStart = "String.prototype.padString = String.prototype.padString || "
                                     "function (targetLength, padString) { return Utils.padStart(this, targetLength, padString); } ";
static const char *PF_Math_log10 = "Math.log10 = Math.log10 || function(x) { return Utils.log10(x) };";

DeviceJs::DeviceJs() :
    d(new DeviceJsPrivate)
{
    Q_ASSERT(_djs == nullptr); // enforce singleton

#if QT_VERSION > 0x050700
    d->engine.installExtensions(QJSEngine::ConsoleExtension);
#endif
    d->jsResource = new JsResource(&d->engine);
    auto jsR = d->engine.newQObject(d->jsResource);
    d->engine.globalObject().setProperty("R", jsR);

    d->jsZclAttribute = new JsZclAttribute(&d->engine);
    auto jsAttr = d->engine.newQObject(d->jsZclAttribute);
    d->engine.globalObject().setProperty("Attr", jsAttr);

    d->jsZclFrame = new JsZclFrame(&d->engine);
    auto jsZclFrame = d->engine.newQObject(d->jsZclFrame);
    d->engine.globalObject().setProperty("ZclFrame", jsZclFrame);

    d->jsItem = new JsResourceItem(&d->engine);
    auto jsItem = d->engine.newQObject(d->jsItem);
    d->engine.globalObject().setProperty("Item", jsItem);

    d->jsUtils = new JsUtils(&d->engine);
    auto jsUtils = d->engine.newQObject(d->jsUtils);
    d->engine.globalObject().setProperty("Utils", jsUtils);

    // apply polyfills
    d->engine.evaluate(PF_String_prototype_padStart);
    d->engine.evaluate(PF_Math_log10);

    _djs = this;
}

DeviceJs::~DeviceJs()
{
    _djs = nullptr;
}

DeviceJs *DeviceJs::instance()
{
    Q_ASSERT(_djs);
    return _djs;
}

JsEvalResult DeviceJs::evaluate(const QString &expr)
{
    d->result = d->engine.evaluate(expr);
    if (d->result.isError())
    {
        return JsEvalResult::Error;
    }

    return JsEvalResult::Ok;
}

void DeviceJs::setResource(Resource *r)
{
    d->jsResource->r = r;
    d->jsResource->cr = r;
}

void DeviceJs::setResource(const Resource *r)
{
    d->jsResource->r = nullptr;
    d->jsResource->cr = r;
}

void DeviceJs::setApsIndication(const deCONZ::ApsDataIndication &ind)
{
    d->apsInd = &ind;
    d->engine.globalObject().setProperty("SrcEp", int(ind.srcEndpoint()));
    d->engine.globalObject().setProperty("ClusterId", int(ind.clusterId()));
}

void DeviceJs::setZclFrame(const deCONZ::ZclFrame &zclFrame)
{
    d->jsZclFrame->zclFrame = &zclFrame;
}

void DeviceJs::setZclAttribute(const deCONZ::ZclAttribute &attr)
{
    d->jsZclAttribute->attr = &attr;
}

void DeviceJs::setItem(ResourceItem *item)
{
    d->jsItem->item = item;
    d->jsItem->citem = item;
}

void DeviceJs::setItem(const ResourceItem *item)
{
    d->jsItem->item = nullptr;
    d->jsItem->citem = item;
}

QVariant DeviceJs::result()
{
    return d->result.toVariant();
}

void DeviceJs::reset()
{
    d->apsInd = nullptr;
    d->jsItem->item = nullptr;
    d->jsItem->citem = nullptr;
    d->jsResource->r = nullptr;
    d->jsResource->cr = nullptr;
    d->jsZclAttribute->attr = nullptr;
    d->jsZclFrame->zclFrame = nullptr;
    d->engine.collectGarbage();
}

QString DeviceJs::errorString() const
{
    return d->result.toString();
}
<commit_msg>Fix JS padStart polyfill<commit_after>/*
 * Copyright (c) 2021 dresden elektronik ingenieurtechnik gmbh.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 *
 */

#include "deconz/aps.h"
#include "device_js.h"
#include "device_js_wrappers.h"

#include <QJSEngine>
#include <QMetaProperty>

static DeviceJs *_djs = nullptr; // singleton

class DeviceJsPrivate
{
public:
    QJSEngine engine;
    QJSValue result;
    JsResource *jsResource = nullptr;
    JsZclAttribute *jsZclAttribute = nullptr;
    JsZclFrame *jsZclFrame = nullptr;
    JsResourceItem *jsItem = nullptr;
    JsUtils *jsUtils = nullptr;
    const deCONZ::ApsDataIndication *apsInd = nullptr;
};

// Polyfills for older Qt versions
static const char *PF_String_prototype_padStart = "String.prototype.padStart = String.prototype.padStart || "
                                     "function (targetLength, padString) { return Utils.padStart(this, targetLength, padString); } ";
static const char *PF_Math_log10 = "Math.log10 = Math.log10 || function(x) { return Utils.log10(x) };";

DeviceJs::DeviceJs() :
    d(new DeviceJsPrivate)
{
    Q_ASSERT(_djs == nullptr); // enforce singleton

#if QT_VERSION > 0x050700
    d->engine.installExtensions(QJSEngine::ConsoleExtension);
#endif
    d->jsResource = new JsResource(&d->engine);
    auto jsR = d->engine.newQObject(d->jsResource);
    d->engine.globalObject().setProperty("R", jsR);

    d->jsZclAttribute = new JsZclAttribute(&d->engine);
    auto jsAttr = d->engine.newQObject(d->jsZclAttribute);
    d->engine.globalObject().setProperty("Attr", jsAttr);

    d->jsZclFrame = new JsZclFrame(&d->engine);
    auto jsZclFrame = d->engine.newQObject(d->jsZclFrame);
    d->engine.globalObject().setProperty("ZclFrame", jsZclFrame);

    d->jsItem = new JsResourceItem(&d->engine);
    auto jsItem = d->engine.newQObject(d->jsItem);
    d->engine.globalObject().setProperty("Item", jsItem);

    d->jsUtils = new JsUtils(&d->engine);
    auto jsUtils = d->engine.newQObject(d->jsUtils);
    d->engine.globalObject().setProperty("Utils", jsUtils);

    // apply polyfills
    d->engine.evaluate(PF_String_prototype_padStart);
    d->engine.evaluate(PF_Math_log10);

    _djs = this;
}

DeviceJs::~DeviceJs()
{
    _djs = nullptr;
}

DeviceJs *DeviceJs::instance()
{
    Q_ASSERT(_djs);
    return _djs;
}

JsEvalResult DeviceJs::evaluate(const QString &expr)
{
    d->result = d->engine.evaluate(expr);
    if (d->result.isError())
    {
        return JsEvalResult::Error;
    }

    return JsEvalResult::Ok;
}

void DeviceJs::setResource(Resource *r)
{
    d->jsResource->r = r;
    d->jsResource->cr = r;
}

void DeviceJs::setResource(const Resource *r)
{
    d->jsResource->r = nullptr;
    d->jsResource->cr = r;
}

void DeviceJs::setApsIndication(const deCONZ::ApsDataIndication &ind)
{
    d->apsInd = &ind;
    d->engine.globalObject().setProperty("SrcEp", int(ind.srcEndpoint()));
    d->engine.globalObject().setProperty("ClusterId", int(ind.clusterId()));
}

void DeviceJs::setZclFrame(const deCONZ::ZclFrame &zclFrame)
{
    d->jsZclFrame->zclFrame = &zclFrame;
}

void DeviceJs::setZclAttribute(const deCONZ::ZclAttribute &attr)
{
    d->jsZclAttribute->attr = &attr;
}

void DeviceJs::setItem(ResourceItem *item)
{
    d->jsItem->item = item;
    d->jsItem->citem = item;
}

void DeviceJs::setItem(const ResourceItem *item)
{
    d->jsItem->item = nullptr;
    d->jsItem->citem = item;
}

QVariant DeviceJs::result()
{
    return d->result.toVariant();
}

void DeviceJs::reset()
{
    d->apsInd = nullptr;
    d->jsItem->item = nullptr;
    d->jsItem->citem = nullptr;
    d->jsResource->r = nullptr;
    d->jsResource->cr = nullptr;
    d->jsZclAttribute->attr = nullptr;
    d->jsZclFrame->zclFrame = nullptr;
    d->engine.collectGarbage();
}

QString DeviceJs::errorString() const
{
    return d->result.toString();
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

/*
 * SpeciesInitialValueLostFocusCommand.cpp
 *
 *  Created on: 19 Sep 2014
 *      Author: dada
 */

#include "qtUtilities.h"

#include "model/CMetab.h"
#include "UI/CQSpeciesDetail.h"
#include "model/CCompartment.h"

#include "UndoSpeciesData.h"

#include "SpeciesInitialValueLostFocusCommand.h"

SpeciesInitialValueLostFocusCommand::SpeciesInitialValueLostFocusCommand(
  CQSpeciesDetail *pSpecieDetail)
  : CCopasiUndoCommand("Species", SPECIES_TYPE_CHANGE, "Change")
  , mpSpecieDetail(pSpecieDetail)
  , mpSpeciesData(new UndoSpeciesData(mpSpecieDetail->mpMetab))
  , mFirstTime(true)
{

  std::string sName = mpSpecieDetail->mpMetab->getObjectName();
  setText(QString(": Species Initial Value Change for %1").arg(FROM_UTF8(sName)));
  setName(mpSpeciesData->getName());

  {
    setNewValue(mpSpecieDetail->mpEditInitialValue->text().toStdString());
  }
  {
    std::ostringstream strs;
    strs.precision(std::numeric_limits<double>::max());
    strs << mpSpecieDetail->mInitialConcentration;
    std::string str = strs.str();
    setOldValue(str);
  }
  setProperty("Initial Value");
}
void SpeciesInitialValueLostFocusCommand::redo()
{
  if (mFirstTime)
    {
      mpSpecieDetail->speciesInitialValueLostFocus();
      mFirstTime = false;
    }
  else
    {
      mpSpecieDetail->speciesInitialValueLostFocus(mpSpeciesData);
    }

  setAction("Change");
}
void SpeciesInitialValueLostFocusCommand::undo()
{
  mpSpecieDetail->speciesInitialValueLostFocus(mpSpeciesData);
  setAction("Undone change");
}

SpeciesInitialValueLostFocusCommand::~SpeciesInitialValueLostFocusCommand()
{
  pdelete(mpSpeciesData);
}
<commit_msg>Restore code intended to produce a string which can only be interpreted as a number (double). Include fix to set precision of ostringstream to not truncate resultant string.<commit_after>// Copyright (C) 2015 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

/*
 * SpeciesInitialValueLostFocusCommand.cpp
 *
 *  Created on: 19 Sep 2014
 *      Author: dada
 */

#include "qtUtilities.h"

#include "model/CMetab.h"
#include "UI/CQSpeciesDetail.h"
#include "model/CCompartment.h"

#include "UndoSpeciesData.h"

#include "SpeciesInitialValueLostFocusCommand.h"

SpeciesInitialValueLostFocusCommand::SpeciesInitialValueLostFocusCommand(
  CQSpeciesDetail *pSpecieDetail)
  : CCopasiUndoCommand("Species", SPECIES_TYPE_CHANGE, "Change")
  , mpSpecieDetail(pSpecieDetail)
  , mpSpeciesData(new UndoSpeciesData(mpSpecieDetail->mpMetab))
  , mFirstTime(true)
{

  std::string sName = mpSpecieDetail->mpMetab->getObjectName();
  setText(QString(": Species Initial Value Change for %1").arg(FROM_UTF8(sName)));
  setName(mpSpeciesData->getName());

  {
    double newValue = mpSpecieDetail->mpEditInitialValue->text().toDouble();
    strs.precision(std::numeric_limits<double>::max());
    std::ostringstream strs;
    strs << newValue;
    std::string str = strs.str();
    setNewValue(str)
  }
  {
    std::ostringstream strs;
    strs.precision(std::numeric_limits<double>::max());
    strs << mpSpecieDetail->mInitialConcentration;
    std::string str = strs.str();
    setOldValue(str);
  }
  setProperty("Initial Value");
}
void SpeciesInitialValueLostFocusCommand::redo()
{
  if (mFirstTime)
    {
      mpSpecieDetail->speciesInitialValueLostFocus();
      mFirstTime = false;
    }
  else
    {
      mpSpecieDetail->speciesInitialValueLostFocus(mpSpeciesData);
    }

  setAction("Change");
}
void SpeciesInitialValueLostFocusCommand::undo()
{
  mpSpecieDetail->speciesInitialValueLostFocus(mpSpeciesData);
  setAction("Undone change");
}

SpeciesInitialValueLostFocusCommand::~SpeciesInitialValueLostFocusCommand()
{
  pdelete(mpSpeciesData);
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling 2>&1 | FileCheck %s

// This file should be used as regression test for the value printing subsystem
// Reproducers of fixed bugs should be put here

extern "C" int mustPrintFirst() { return 6; }
mustPrintFirst
// CHECK: (int (*)()) Function

// PR #93006
.rawInput 1
extern "C" int printf(const char* fmt, ...);
class A {
public:
  int Var;
  A(int arg) { Var = arg; }
  int someFunc(float) { return 42; }
  ~A() { printf("A d'tor\n"); }
};

const A& foo(const A& arg) { return arg; }
A foo2(const A& arg) { return A(42); }
.rawInput 0

foo(A(12)).Var
// CHECK: (const int) 12
// CHECK: A d'tor
// End PR #93006

// myvector.end() failed to print (roottest/cling/stl/default/VectorSort.C)
foo2(A(42))
// CHECK: (A) @0x{{[0-9a-f]+}}
// CHECK: A d'tor

 // Savannah #96523
int *p = (int*)0x123;
p // CHECK: (int *) 0x123
const int *q = (int*)0x123;
q // CHECK: (const int *) 0x123 <invalid memory address>

0.00001234L // CHECK-NEXT: (long double) 1.2340000e-05L

// PR ROOT-5467
&A::someFunc // CHECK: (int (A::*)(float)) Function @0x{{[0-9a-f]+}}

nullptr // CHECK: (nullptr_t) nullptr

true // CHECK: (bool) true
false // CHECK: (bool) false

unordered_multiset<float> {1} // ROOT-7310
// expected-error@2 {{use of undeclared identifier 'unordered_multiset'}}
// expected-error@2 {{expected '(' for function-style cast or type construction}}
// expected-error@2 {{initializer list cannot be used on the right hand side of operator '>'}}

#include <unordered_set>
std::unordered_multiset<float> {1}
// FIXME: BROKEN_ON_LINUX-CHECK: (std::unordered_multiset<float>) { 1.00000f }

// ROOT-7426
#include <string>
#include <vector>
std::vector<std::string> a = { "a", "b", "c" } // CHECK: (std::vector<std::string> &) { "a", "b", "c" }
a // CHECK: (std::vector<std::string> &) { "a", "b", "c" }
a[0] // CHECK: ({{.*}} &) "a"

// ROOT-7918
struct Enumer {
#ifndef _WIN32
  // This variant fails on Windows, and seems conforming behaviour to do so
  enum H {  h = (unsigned long long )-1 };
#else
  enum H : unsigned long long { h = (unsigned long long )-1 };
#endif
};
Enumer::h
// CHECK: (Enumer::H) (Enumer::h) : (unsigned long{{( long)?}}) 18446744073709551615

// ROOT-7837
auto bla=[](double *x, double *par, int blub){return x[0]*blub;} // CHECK: ((lambda) &) @0x{{[0-9a-f]+}}

#include <functional>
using namespace std::placeholders;
auto fn_moo = std::bind (bla, _1,_2,10) // CHECK: ({{.*\(lambda\).*}}> &) @0x{{[0-9a-f]+}}

// Make sure cling survives
12 // CHECK: (int) 12

// ROOT-8077
.rawInput 1
#include <string>
void f(std::string) {}
.rawInput 0
f // CHECK: (void (*)(std::string)) Function @0x{{[0-9a-f]+}}
// CHECK: at input_line_{{[0-9].*}}:1:
// CHECK: void f(std::string) {}

class notapointer {};
struct OverloadedAddrOf {
  notapointer operator&() {
    return notapointer();
  }
};
OverloadedAddrOf overloadedAddrOf
// CHECK: (OverloadedAddrOf &) @0x{{[0-9a-f]+}}

// Much more important than what cling prints: cling survives this!
.rawInput
namespace WithUnnamed { namespace { struct Y {} y; } Y z; }
.rawInput
WithUnnamed::y
WithUnnamed::z // CHECK: (WithUnnamed::

.rawInput 1
#if __cplusplus > 201103L
auto func() { class X {} x; return x; };
#endif
.rawInput 0
#if __cplusplus > 201103L
//func
func()
#endif

namespace PR180 {
  class base {};

  template <class B>
  class Derived : public B {};
  using Foo = Derived<base>;
}
auto bar = PR180::Foo()
// CHECK: (PR180::Derived<PR180::base> &) @0x{{[0-9a-f]+}}
<commit_msg>Check for the expected diagnostics.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling -Xclang -verify 2>&1 | FileCheck %s

// This file should be used as regression test for the value printing subsystem
// Reproducers of fixed bugs should be put here

extern "C" int mustPrintFirst() { return 6; }
mustPrintFirst
// CHECK: (int (*)()) Function

// PR #93006
.rawInput 1
extern "C" int printf(const char* fmt, ...);
class A {
public:
  int Var;
  A(int arg) { Var = arg; }
  int someFunc(float) { return 42; }
  ~A() { printf("A d'tor\n"); }
};

const A& foo(const A& arg) { return arg; }
A foo2(const A& arg) { return A(42); }
.rawInput 0

foo(A(12)).Var
// CHECK: (const int) 12
// CHECK: A d'tor
// End PR #93006

// myvector.end() failed to print (roottest/cling/stl/default/VectorSort.C)
foo2(A(42))
// CHECK: (A) @0x{{[0-9a-f]+}}
// CHECK: A d'tor

 // Savannah #96523
int *p = (int*)0x123;
p // CHECK: (int *) 0x123
const int *q = (int*)0x123;
q // CHECK: (const int *) 0x123 <invalid memory address>

0.00001234L // CHECK-NEXT: (long double) 1.2340000e-05L

// PR ROOT-5467
&A::someFunc // CHECK: (int (A::*)(float)) Function @0x{{[0-9a-f]+}}

nullptr // CHECK: (nullptr_t) nullptr

true // CHECK: (bool) true
false // CHECK: (bool) false

unordered_multiset<float> {1} // ROOT-7310
// expected-error@input_line_42:2 {{expected ';' after expression}}
// expected-error@input_line_42:2 {{use of undeclared identifier 'unordered_multiset'}}
// expected-error@input_line_42:2 {{expected ';' after expression}}

#include <unordered_set>
std::unordered_multiset<float> {1}
// FIXME: BROKEN_ON_LINUX-CHECK: (std::unordered_multiset<float>) { 1.00000f }

// ROOT-7426
#include <string>
#include <vector>
std::vector<std::string> a = { "a", "b", "c" } // CHECK: (std::vector<std::string> &) { "a", "b", "c" }
a // CHECK: (std::vector<std::string> &) { "a", "b", "c" }
a[0] // CHECK: ({{.*}} &) "a"

// ROOT-7918
struct Enumer {
#ifndef _WIN32
  // This variant fails on Windows, and seems conforming behaviour to do so
  enum H {  h = (unsigned long long )-1 };
#else
  enum H : unsigned long long { h = (unsigned long long )-1 };
#endif
};
Enumer::h
// CHECK: (Enumer::H) (Enumer::h) : (unsigned long{{( long)?}}) 18446744073709551615

// ROOT-7837
auto bla=[](double *x, double *par, int blub){return x[0]*blub;} // CHECK: ((lambda) &) @0x{{[0-9a-f]+}}

#include <functional>
using namespace std::placeholders;
auto fn_moo = std::bind (bla, _1,_2,10) // CHECK: ({{.*\(lambda\).*}}> &) @0x{{[0-9a-f]+}}

// Make sure cling survives
12 // CHECK: (int) 12

// ROOT-8077
.rawInput 1
#include <string>
void f(std::string) {}
.rawInput 0
f // CHECK: (void (*)(std::string)) Function @0x{{[0-9a-f]+}}
// CHECK: at input_line_{{[0-9].*}}:1:
// CHECK: void f(std::string) {}

class notapointer {};
struct OverloadedAddrOf {
  notapointer operator&() {
    return notapointer();
  }
};
OverloadedAddrOf overloadedAddrOf
// CHECK: (OverloadedAddrOf &) @0x{{[0-9a-f]+}}

// Much more important than what cling prints: cling survives this!
.rawInput
namespace WithUnnamed { namespace { struct Y {} y; } Y z; }
.rawInput
WithUnnamed::y
WithUnnamed::z // CHECK: (WithUnnamed::

.rawInput 1
#if __cplusplus > 201103L
auto func() { class X {} x; return x; };
#endif
.rawInput 0
#if __cplusplus > 201103L
//func
func()
#endif

namespace PR180 {
  class base {};

  template <class B>
  class Derived : public B {};
  using Foo = Derived<base>;
}
auto bar = PR180::Foo()
// CHECK: (PR180::Derived<PR180::base> &) @0x{{[0-9a-f]+}}
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2013-2014 winlin

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <srs_app_ingest.hpp>

#ifdef SRS_INGEST

#include <srs_kernel_error.hpp>
#include <srs_app_config.hpp>
#include <srs_kernel_log.hpp>
#include <srs_app_ffmpeg.hpp>
#include <srs_app_pithy_print.hpp>

// when error, ingester sleep for a while and retry.
#define SRS_INGESTER_SLEEP_US (int64_t)(6*100*1000LL)

SrsIngester::SrsIngester()
{
    // TODO: FIXME: support reload.
    pthread = new SrsThread(this, SRS_INGESTER_SLEEP_US);
    pithy_print = new SrsPithyPrint(SRS_STAGE_INGESTER);
}

SrsIngester::~SrsIngester()
{
    srs_freep(pthread);
    clear_engines();
}

int SrsIngester::start()
{
    int ret = ERROR_SUCCESS;

    if ((ret = parse()) != ERROR_SUCCESS) {
        clear_engines();
        ret = ERROR_SUCCESS;
        return ret;
    }

    // return for error or no engine.
    if (ffmpegs.empty()) {
        return ret;
    }

    // start thread to run all encoding engines.
    if ((ret = pthread->start()) != ERROR_SUCCESS) {
        srs_error("st_thread_create failed. ret=%d", ret);
        return ret;
    }

    return ret;
}

int SrsIngester::parse_ingesters(SrsConfDirective* vhost)
{
    int ret = ERROR_SUCCESS;

    std::vector<SrsConfDirective*> ingesters;
    _srs_config->get_ingesters(vhost->arg0(), ingesters);

    // create engine
    for (int i = 0; i < (int)ingesters.size(); i++) {
        SrsConfDirective* ingest = ingesters[i];
        if (!_srs_config->get_ingest_enabled(ingest)) {
            continue;
        }

        if ((ret = parse_engines(vhost, ingest)) != ERROR_SUCCESS) {
            return ret;
        }
    }

    return ret;
}

int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest)
{
    int ret = ERROR_SUCCESS;

    std::string ffmpeg_bin = _srs_config->get_ingest_ffmpeg(ingest);
    if (ffmpeg_bin.empty()) {
        ret = ERROR_ENCODER_PARSE;
        srs_trace("empty ffmpeg ret=%d", ret);
        return ret;
    }

    // get all engines.
    std::vector<SrsConfDirective*> engines;
    _srs_config->get_transcode_engines(ingest, engines);
    if (engines.empty()) {
        SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin);
        if ((ret = initialize_ffmpeg(ffmpeg, vhost, ingest, NULL)) != ERROR_SUCCESS) {
            srs_freep(ffmpeg);
            if (ret != ERROR_ENCODER_LOOP) {
                srs_error("invalid ingest engine. ret=%d", ret);
            }
            return ret;
        }

        ffmpegs.push_back(ffmpeg);
        return ret;
    }

    // create engine
    for (int i = 0; i < (int)engines.size(); i++) {
        SrsConfDirective* engine = engines[i];
        SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin);
        if ((ret = initialize_ffmpeg(ffmpeg, vhost, ingest, engine)) != ERROR_SUCCESS) {
            srs_freep(ffmpeg);
            if (ret != ERROR_ENCODER_LOOP) {
                srs_error("invalid ingest engine: %s %s", ingest->arg0().c_str(), engine->arg0().c_str());
            }
            return ret;
        }

        ffmpegs.push_back(ffmpeg);
    }

    return ret;
}

void SrsIngester::stop()
{
    pthread->stop();
    clear_engines();
}

int SrsIngester::cycle()
{
    int ret = ERROR_SUCCESS;

    std::vector<SrsFFMPEG*>::iterator it;
    for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
        SrsFFMPEG* ffmpeg = *it;

        // start all ffmpegs.
        if ((ret = ffmpeg->start()) != ERROR_SUCCESS) {
            srs_error("ingest ffmpeg start failed. ret=%d", ret);
            return ret;
        }

        // check ffmpeg status.
        if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) {
            srs_error("ingest ffmpeg cycle failed. ret=%d", ret);
            return ret;
        }
    }

    // pithy print
    ingester();
    pithy_print->elapse(SRS_INGESTER_SLEEP_US / 1000);

    return ret;
}

void SrsIngester::on_thread_stop()
{
}

void SrsIngester::clear_engines()
{
    std::vector<SrsFFMPEG*>::iterator it;

    for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
        SrsFFMPEG* ffmpeg = *it;
        srs_freep(ffmpeg);
    }

    ffmpegs.clear();
}

int SrsIngester::parse()
{
    int ret = ERROR_SUCCESS;

    // parse ingesters
    std::vector<SrsConfDirective*> vhosts;
    _srs_config->get_vhosts(vhosts);

    for (int i = 0; i < (int)vhosts.size(); i++) {
        SrsConfDirective* vhost = vhosts[i];
        if ((ret = parse_ingesters(vhost)) != ERROR_SUCCESS) {
            return ret;
        }
    }

    return ret;
}

int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, SrsConfDirective* ingest, SrsConfDirective* engine)
{
    int ret = ERROR_SUCCESS;

    SrsConfDirective* listen = _srs_config->get_listen();
    srs_assert(listen->args.size() > 0);
    std::string port = listen->arg0();

    std::string output = _srs_config->get_engine_output(engine);
    // output stream, to other/self server
    // ie. rtmp://127.0.0.1:1935/live/livestream_sd
    output = srs_string_replace(output, "[vhost]", vhost->arg0());
    output = srs_string_replace(output, "[port]", port);
    if (output.empty()) {
        ret = ERROR_ENCODER_NO_OUTPUT;
        srs_trace("empty ingest output url. ret=%d", ret);
        return ret;
    }

    // find the app and stream in rtmp url
    std::string url = output;
    std::string app, stream;
    size_t pos = std::string::npos;
    if ((pos = url.rfind("/")) != std::string::npos) {
        stream = url.substr(pos + 1);
        url = url.substr(0, pos);
    }
    if ((pos = url.rfind("/")) != std::string::npos) {
        app = url.substr(pos + 1);
        url = url.substr(0, pos);
    }
    if ((pos = app.rfind("?")) != std::string::npos) {
        app = app.substr(0, pos);
    }

    std::string log_file;
    // write ffmpeg info to log file.
    log_file = _srs_config->get_ffmpeg_log_dir();
    log_file += "/";
    log_file += "ffmpeg-ingest";
    log_file += "-";
    log_file += vhost->arg0();
    log_file += "-";
    log_file += app;
    log_file += "-";
    log_file += stream;
    log_file += ".log";

    // stream name: vhost/app/stream for print
    input_stream_name = vhost->arg0();
    input_stream_name += "/";
    input_stream_name += app;
    input_stream_name += "/";
    input_stream_name += stream;

    // input
    std::string input_type = _srs_config->get_ingest_input_type(ingest);
    if (input_type.empty()) {
        ret = ERROR_ENCODER_NO_INPUT;
        srs_trace("empty ingest intput type. ret=%d", ret);
        return ret;
    }

    if (input_type == SRS_INGEST_TYPE_FILE) {
        std::string input_url = _srs_config->get_ingest_input_url(ingest);
        if (input_url.empty()) {
            ret = ERROR_ENCODER_NO_INPUT;
            srs_trace("empty ingest intput url. ret=%d", ret);
            return ret;
        }

        // for file, set re.
        ffmpeg->set_iparams("-re");

        if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) {
            return ret;
        }
    } else if (input_type == SRS_INGEST_TYPE_STREAM) {
        std::string input_url = _srs_config->get_ingest_input_url(ingest);
        if (input_url.empty()) {
            ret = ERROR_ENCODER_NO_INPUT;
            srs_trace("empty ingest intput url. ret=%d", ret);
            return ret;
        }

        // for stream, no re.
        ffmpeg->set_iparams("");

        if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) {
            return ret;
        }
    } else {
        ret = ERROR_ENCODER_INPUT_TYPE;
        srs_error("invalid ingest type=%s, ret=%d", input_type.c_str(), ret);
    }

    std::string vcodec = _srs_config->get_engine_vcodec(engine);
    std::string acodec = _srs_config->get_engine_acodec(engine);
    // whatever the engine config, use copy as default.
    if (!engine || !_srs_config->get_engine_enabled(engine) || vcodec.empty() || acodec.empty()) {
        if ((ret = ffmpeg->initialize_copy()) != ERROR_SUCCESS) {
            return ret;
        }
    } else {
        if ((ret = ffmpeg->initialize_transcode(engine)) != ERROR_SUCCESS) {
            return ret;
        }
    }

    return ret;
}

void SrsIngester::ingester()
{
    // reportable
    if (pithy_print->can_print()) {
        // TODO: FIXME: show more info.
        srs_trace("-> time=%"PRId64", ingesters=%d, input=%s",
            pithy_print->get_age(), (int)ffmpegs.size(), input_stream_name.c_str());
    }
}

#endif
<commit_msg>change sleep time from 3s to 0.6s for ingester.<commit_after>/*
The MIT License (MIT)

Copyright (c) 2013-2014 winlin

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <srs_app_ingest.hpp>

#ifdef SRS_INGEST

#include <srs_kernel_error.hpp>
#include <srs_app_config.hpp>
#include <srs_kernel_log.hpp>
#include <srs_app_ffmpeg.hpp>
#include <srs_app_pithy_print.hpp>

// when error, ingester sleep for a while and retry.
// ingest never sleep a long time, for we must start the stream ASAP.
#define SRS_INGESTER_SLEEP_US (int64_t)(6*100*1000LL)

SrsIngester::SrsIngester()
{
    // TODO: FIXME: support reload.
    pthread = new SrsThread(this, SRS_INGESTER_SLEEP_US);
    pithy_print = new SrsPithyPrint(SRS_STAGE_INGESTER);
}

SrsIngester::~SrsIngester()
{
    srs_freep(pthread);
    clear_engines();
}

int SrsIngester::start()
{
    int ret = ERROR_SUCCESS;

    if ((ret = parse()) != ERROR_SUCCESS) {
        clear_engines();
        ret = ERROR_SUCCESS;
        return ret;
    }

    // return for error or no engine.
    if (ffmpegs.empty()) {
        return ret;
    }

    // start thread to run all encoding engines.
    if ((ret = pthread->start()) != ERROR_SUCCESS) {
        srs_error("st_thread_create failed. ret=%d", ret);
        return ret;
    }

    return ret;
}

int SrsIngester::parse_ingesters(SrsConfDirective* vhost)
{
    int ret = ERROR_SUCCESS;

    std::vector<SrsConfDirective*> ingesters;
    _srs_config->get_ingesters(vhost->arg0(), ingesters);

    // create engine
    for (int i = 0; i < (int)ingesters.size(); i++) {
        SrsConfDirective* ingest = ingesters[i];
        if (!_srs_config->get_ingest_enabled(ingest)) {
            continue;
        }

        if ((ret = parse_engines(vhost, ingest)) != ERROR_SUCCESS) {
            return ret;
        }
    }

    return ret;
}

int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest)
{
    int ret = ERROR_SUCCESS;

    std::string ffmpeg_bin = _srs_config->get_ingest_ffmpeg(ingest);
    if (ffmpeg_bin.empty()) {
        ret = ERROR_ENCODER_PARSE;
        srs_trace("empty ffmpeg ret=%d", ret);
        return ret;
    }

    // get all engines.
    std::vector<SrsConfDirective*> engines;
    _srs_config->get_transcode_engines(ingest, engines);
    if (engines.empty()) {
        SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin);
        if ((ret = initialize_ffmpeg(ffmpeg, vhost, ingest, NULL)) != ERROR_SUCCESS) {
            srs_freep(ffmpeg);
            if (ret != ERROR_ENCODER_LOOP) {
                srs_error("invalid ingest engine. ret=%d", ret);
            }
            return ret;
        }

        ffmpegs.push_back(ffmpeg);
        return ret;
    }

    // create engine
    for (int i = 0; i < (int)engines.size(); i++) {
        SrsConfDirective* engine = engines[i];
        SrsFFMPEG* ffmpeg = new SrsFFMPEG(ffmpeg_bin);
        if ((ret = initialize_ffmpeg(ffmpeg, vhost, ingest, engine)) != ERROR_SUCCESS) {
            srs_freep(ffmpeg);
            if (ret != ERROR_ENCODER_LOOP) {
                srs_error("invalid ingest engine: %s %s", ingest->arg0().c_str(), engine->arg0().c_str());
            }
            return ret;
        }

        ffmpegs.push_back(ffmpeg);
    }

    return ret;
}

void SrsIngester::stop()
{
    pthread->stop();
    clear_engines();
}

int SrsIngester::cycle()
{
    int ret = ERROR_SUCCESS;

    std::vector<SrsFFMPEG*>::iterator it;
    for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
        SrsFFMPEG* ffmpeg = *it;

        // start all ffmpegs.
        if ((ret = ffmpeg->start()) != ERROR_SUCCESS) {
            srs_error("ingest ffmpeg start failed. ret=%d", ret);
            return ret;
        }

        // check ffmpeg status.
        if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) {
            srs_error("ingest ffmpeg cycle failed. ret=%d", ret);
            return ret;
        }
    }

    // pithy print
    ingester();
    pithy_print->elapse(SRS_INGESTER_SLEEP_US / 1000);

    return ret;
}

void SrsIngester::on_thread_stop()
{
}

void SrsIngester::clear_engines()
{
    std::vector<SrsFFMPEG*>::iterator it;

    for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) {
        SrsFFMPEG* ffmpeg = *it;
        srs_freep(ffmpeg);
    }

    ffmpegs.clear();
}

int SrsIngester::parse()
{
    int ret = ERROR_SUCCESS;

    // parse ingesters
    std::vector<SrsConfDirective*> vhosts;
    _srs_config->get_vhosts(vhosts);

    for (int i = 0; i < (int)vhosts.size(); i++) {
        SrsConfDirective* vhost = vhosts[i];
        if ((ret = parse_ingesters(vhost)) != ERROR_SUCCESS) {
            return ret;
        }
    }

    return ret;
}

int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, SrsConfDirective* ingest, SrsConfDirective* engine)
{
    int ret = ERROR_SUCCESS;

    SrsConfDirective* listen = _srs_config->get_listen();
    srs_assert(listen->args.size() > 0);
    std::string port = listen->arg0();

    std::string output = _srs_config->get_engine_output(engine);
    // output stream, to other/self server
    // ie. rtmp://127.0.0.1:1935/live/livestream_sd
    output = srs_string_replace(output, "[vhost]", vhost->arg0());
    output = srs_string_replace(output, "[port]", port);
    if (output.empty()) {
        ret = ERROR_ENCODER_NO_OUTPUT;
        srs_trace("empty ingest output url. ret=%d", ret);
        return ret;
    }

    // find the app and stream in rtmp url
    std::string url = output;
    std::string app, stream;
    size_t pos = std::string::npos;
    if ((pos = url.rfind("/")) != std::string::npos) {
        stream = url.substr(pos + 1);
        url = url.substr(0, pos);
    }
    if ((pos = url.rfind("/")) != std::string::npos) {
        app = url.substr(pos + 1);
        url = url.substr(0, pos);
    }
    if ((pos = app.rfind("?")) != std::string::npos) {
        app = app.substr(0, pos);
    }

    std::string log_file;
    // write ffmpeg info to log file.
    log_file = _srs_config->get_ffmpeg_log_dir();
    log_file += "/";
    log_file += "ffmpeg-ingest";
    log_file += "-";
    log_file += vhost->arg0();
    log_file += "-";
    log_file += app;
    log_file += "-";
    log_file += stream;
    log_file += ".log";

    // stream name: vhost/app/stream for print
    input_stream_name = vhost->arg0();
    input_stream_name += "/";
    input_stream_name += app;
    input_stream_name += "/";
    input_stream_name += stream;

    // input
    std::string input_type = _srs_config->get_ingest_input_type(ingest);
    if (input_type.empty()) {
        ret = ERROR_ENCODER_NO_INPUT;
        srs_trace("empty ingest intput type. ret=%d", ret);
        return ret;
    }

    if (input_type == SRS_INGEST_TYPE_FILE) {
        std::string input_url = _srs_config->get_ingest_input_url(ingest);
        if (input_url.empty()) {
            ret = ERROR_ENCODER_NO_INPUT;
            srs_trace("empty ingest intput url. ret=%d", ret);
            return ret;
        }

        // for file, set re.
        ffmpeg->set_iparams("-re");

        if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) {
            return ret;
        }
    } else if (input_type == SRS_INGEST_TYPE_STREAM) {
        std::string input_url = _srs_config->get_ingest_input_url(ingest);
        if (input_url.empty()) {
            ret = ERROR_ENCODER_NO_INPUT;
            srs_trace("empty ingest intput url. ret=%d", ret);
            return ret;
        }

        // for stream, no re.
        ffmpeg->set_iparams("");

        if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) {
            return ret;
        }
    } else {
        ret = ERROR_ENCODER_INPUT_TYPE;
        srs_error("invalid ingest type=%s, ret=%d", input_type.c_str(), ret);
    }

    std::string vcodec = _srs_config->get_engine_vcodec(engine);
    std::string acodec = _srs_config->get_engine_acodec(engine);
    // whatever the engine config, use copy as default.
    if (!engine || !_srs_config->get_engine_enabled(engine) || vcodec.empty() || acodec.empty()) {
        if ((ret = ffmpeg->initialize_copy()) != ERROR_SUCCESS) {
            return ret;
        }
    } else {
        if ((ret = ffmpeg->initialize_transcode(engine)) != ERROR_SUCCESS) {
            return ret;
        }
    }

    return ret;
}

void SrsIngester::ingester()
{
    // reportable
    if (pithy_print->can_print()) {
        // TODO: FIXME: show more info.
        srs_trace("-> time=%"PRId64", ingesters=%d, input=%s",
            pithy_print->get_age(), (int)ffmpegs.size(), input_stream_name.c_str());
    }
}

#endif
<|endoftext|>


<commit_before>/* $Id$ */

/*
 * Copyright (c) 2010 SURFnet bv
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "log.h"
#include "ObjectStore.h"
#include "Token.h"
#include "OSAttribute.h"
#include "ByteString.h"
#include "SecureDataManager.h"

#include <sys/time.h>

// Constructor
Token::Token()
{
	token = NULL;
	sdm = NULL;
	valid = false;
}

// Constructor
Token::Token(OSToken* token)
{
	this->token = token;

	ByteString soPINBlob, userPINBlob;

	valid = token->getSOPIN(soPINBlob) && token->getUserPIN(userPINBlob);

	sdm = new SecureDataManager(soPINBlob, userPINBlob);
}

// Destructor
Token::~Token()
{
	delete sdm;
}

// Check if the token is still valid
bool Token::isValid()
{
	return (valid && token->isValid());
}

// Create a new token
CK_RV Token::createToken(ObjectStore* objectStore, CK_UTF8CHAR_PTR soPIN, CK_ULONG pinLen, CK_UTF8CHAR_PTR label)
{
	if (!objectStore) return CKR_GENERAL_ERROR;
	if (!soPIN) return CKR_ARGUMENTS_BAD;
	if (!label) return CKR_ARGUMENTS_BAD;
	if (pinLen < MIN_PIN_LEN || pinLen > MAX_PIN_LEN) return CKR_PIN_INCORRECT;

	if (token != NULL)
	{
		// The token is already initialised. Destroy it first.
		if (!objectStore->destroyToken(token))
		{
			ERROR_MSG("Failed to destroy existing token");

			return CKR_DEVICE_ERROR;
		}

		token = NULL;
	}

	// Generate the SO PIN blob
	ByteString soPINByteStr((const unsigned char*) soPIN, pinLen);

	SecureDataManager soPINBlobGen;

	if (!soPINBlobGen.setSOPIN(soPINByteStr))
	{
		return CKR_GENERAL_ERROR;
	}

	// Convert the label
	ByteString labelByteStr((const unsigned char*) label, 32);

	// Create the token
	OSToken* newToken = objectStore->newToken(labelByteStr);

	if (!newToken)
	{
		return CKR_DEVICE_ERROR;
	}

	// Set the SO PIN on the token
	if (!newToken->setSOPIN(soPINBlobGen.getSOPINBlob()))
	{
		ERROR_MSG("Failed to set SO PIN on new token");

		if (!objectStore->destroyToken(newToken))
		{
			ERROR_MSG("Failed to destroy incomplete token");
		}

		return CKR_DEVICE_ERROR;
	}

	token = newToken;

	ByteString soPINBlob, userPINBlob;

	valid = token->getSOPIN(soPINBlob) && token->getUserPIN(userPINBlob);

	sdm = new SecureDataManager(soPINBlob, userPINBlob);

	return CKR_OK;
}

// Retrieve token information for the token
CK_RV Token::getTokenInfo(CK_TOKEN_INFO_PTR info)
{
	ByteString label, serial;

	if (info == NULL)
	{
		return CKR_ARGUMENTS_BAD;
	}

	memset(info->label, ' ', 32);
	memset(info->serialNumber, ' ', 16);

	// Token specific information
	if (token)
	{
		if (!token->getTokenFlags(info->flags))
		{
			ERROR_MSG("Could not get the token flags");
			return CKR_GENERAL_ERROR;
		}

		if (token->getTokenLabel(label))
		{
			strncpy((char*) info->label, (char*) label.byte_str(), label.size());
		}

		if (token->getTokenSerial(serial))
		{
			strncpy((char*) info->serialNumber, (char*) serial.byte_str(), serial.size());
		}
	}
	else
	{
		info->flags =	CKF_RNG |
				CKF_LOGIN_REQUIRED |
				CKF_RESTORE_KEY_NOT_NEEDED |
				CKF_SO_PIN_LOCKED |
				CKF_SO_PIN_TO_BE_CHANGED;
	}

	// Information shared by all tokens
	char mfgID[33];
	char model[17];

	snprintf(mfgID, 33, "SoftHSM project");
	snprintf(model, 17, "SoftHSM v2");

	memset(info->manufacturerID, ' ', 32);
	memset(info->model, ' ', 16);
	strncpy((char*) info->manufacturerID, mfgID, strlen(mfgID));
	strncpy((char*) info->model, model, strlen(model));

	// TODO: Can we set these?
	info->ulSessionCount = CK_UNAVAILABLE_INFORMATION;
	info->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;

	info->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
	info->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
	info->ulMaxPinLen = MAX_PIN_LEN;
	info->ulMinPinLen = MIN_PIN_LEN;
	info->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
	info->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
	info->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
	info->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
	info->hardwareVersion.major = VERSION_MAJOR;
	info->hardwareVersion.minor = VERSION_MINOR;
	info->firmwareVersion.major = VERSION_MAJOR;
	info->firmwareVersion.minor = VERSION_MINOR;

	// Current time
	time_t rawtime;
	time(&rawtime);
	char dateTime[17];
	strftime(dateTime, 17, "%Y%m%d%H%M%S00", gmtime(&rawtime));
	memcpy(info->utcTime, dateTime, 16);

        return CKR_OK;
}
<commit_msg>Also check that you have the correct pw when re-initializing a token <commit_after>/* $Id$ */

/*
 * Copyright (c) 2010 SURFnet bv
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "log.h"
#include "ObjectStore.h"
#include "Token.h"
#include "OSAttribute.h"
#include "ByteString.h"
#include "SecureDataManager.h"

#include <sys/time.h>

// Constructor
Token::Token()
{
	token = NULL;
	sdm = NULL;
	valid = false;
}

// Constructor
Token::Token(OSToken* token)
{
	this->token = token;

	ByteString soPINBlob, userPINBlob;

	valid = token->getSOPIN(soPINBlob) && token->getUserPIN(userPINBlob);

	sdm = new SecureDataManager(soPINBlob, userPINBlob);
}

// Destructor
Token::~Token()
{
	if (sdm != NULL) delete sdm;
}

// Check if the token is still valid
bool Token::isValid()
{
	return (valid && token->isValid());
}

// Create a new token
CK_RV Token::createToken(ObjectStore* objectStore, CK_UTF8CHAR_PTR soPIN, CK_ULONG pinLen, CK_UTF8CHAR_PTR label)
{
	if (objectStore == NULL) return CKR_GENERAL_ERROR;
	if (soPIN == NULL_PTR) return CKR_ARGUMENTS_BAD;
	if (label == NULL_PTR) return CKR_ARGUMENTS_BAD;
	if (pinLen < MIN_PIN_LEN || pinLen > MAX_PIN_LEN) return CKR_PIN_INCORRECT;

	if (token != NULL)
	{
		ByteString oldSOPIN(soPIN, pinLen);

		if (sdm->getSOPINBlob().size() > 0 && !sdm->loginSO(oldSOPIN))
		{
			ERROR_MSG("Incorrect SO PIN");

			return CKR_PIN_INCORRECT;
		}

		// The token is already initialised. Destroy it first.
		if (!objectStore->destroyToken(token))
		{
			ERROR_MSG("Failed to destroy existing token");

			return CKR_DEVICE_ERROR;
		}

		token = NULL;
	}

	// Generate the SO PIN blob
	ByteString soPINByteStr((const unsigned char*) soPIN, pinLen);

	SecureDataManager soPINBlobGen;

	if (!soPINBlobGen.setSOPIN(soPINByteStr))
	{
		return CKR_GENERAL_ERROR;
	}

	// Convert the label
	ByteString labelByteStr((const unsigned char*) label, 32);

	// Create the token
	OSToken* newToken = objectStore->newToken(labelByteStr);

	if (newToken == NULL)
	{
		return CKR_DEVICE_ERROR;
	}

	// Set the SO PIN on the token
	if (!newToken->setSOPIN(soPINBlobGen.getSOPINBlob()))
	{
		ERROR_MSG("Failed to set SO PIN on new token");

		if (!objectStore->destroyToken(newToken))
		{
			ERROR_MSG("Failed to destroy incomplete token");
		}

		return CKR_DEVICE_ERROR;
	}

	token = newToken;

	ByteString soPINBlob, userPINBlob;

	valid = token->getSOPIN(soPINBlob) && token->getUserPIN(userPINBlob);

	if (sdm != NULL) delete sdm;
	sdm = new SecureDataManager(soPINBlob, userPINBlob);

	return CKR_OK;
}

// Retrieve token information for the token
CK_RV Token::getTokenInfo(CK_TOKEN_INFO_PTR info)
{
	ByteString label, serial;

	if (info == NULL)
	{
		return CKR_ARGUMENTS_BAD;
	}

	memset(info->label, ' ', 32);
	memset(info->serialNumber, ' ', 16);

	// Token specific information
	if (token)
	{
		if (!token->getTokenFlags(info->flags))
		{
			ERROR_MSG("Could not get the token flags");
			return CKR_GENERAL_ERROR;
		}

		if (token->getTokenLabel(label))
		{
			strncpy((char*) info->label, (char*) label.byte_str(), label.size());
		}

		if (token->getTokenSerial(serial))
		{
			strncpy((char*) info->serialNumber, (char*) serial.byte_str(), serial.size());
		}
	}
	else
	{
		info->flags =	CKF_RNG |
				CKF_LOGIN_REQUIRED |
				CKF_RESTORE_KEY_NOT_NEEDED |
				CKF_SO_PIN_LOCKED |
				CKF_SO_PIN_TO_BE_CHANGED;
	}

	// Information shared by all tokens
	char mfgID[33];
	char model[17];

	snprintf(mfgID, 33, "SoftHSM project");
	snprintf(model, 17, "SoftHSM v2");

	memset(info->manufacturerID, ' ', 32);
	memset(info->model, ' ', 16);
	strncpy((char*) info->manufacturerID, mfgID, strlen(mfgID));
	strncpy((char*) info->model, model, strlen(model));

	// TODO: Can we set these?
	info->ulSessionCount = CK_UNAVAILABLE_INFORMATION;
	info->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;

	info->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
	info->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
	info->ulMaxPinLen = MAX_PIN_LEN;
	info->ulMinPinLen = MIN_PIN_LEN;
	info->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
	info->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
	info->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
	info->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
	info->hardwareVersion.major = VERSION_MAJOR;
	info->hardwareVersion.minor = VERSION_MINOR;
	info->firmwareVersion.major = VERSION_MAJOR;
	info->firmwareVersion.minor = VERSION_MINOR;

	// Current time
	time_t rawtime;
	time(&rawtime);
	char dateTime[17];
	strftime(dateTime, 17, "%Y%m%d%H%M%S00", gmtime(&rawtime));
	memcpy(info->utcTime, dateTime, 16);

        return CKR_OK;
}
<|endoftext|>


<commit_before>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2 of the Licence, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "templateloader.h"
#include "engine.h"
#include "exception.h"

#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>

using namespace Grantlee;

AbstractTemplateLoader::~AbstractTemplateLoader()
{

}

FileSystemTemplateLoader::FileSystemTemplateLoader()
    : AbstractTemplateLoader()
{

}

FileSystemTemplateLoader::~FileSystemTemplateLoader()
{

}

InMemoryTemplateLoader::InMemoryTemplateLoader()
    : AbstractTemplateLoader()
{

}

InMemoryTemplateLoader::~InMemoryTemplateLoader()
{

}

void FileSystemTemplateLoader::setTheme( const QString &themeName )
{
  m_themeName = themeName;
}

QString FileSystemTemplateLoader::themeName() const
{
  return m_themeName;
}

void FileSystemTemplateLoader::setTemplateDirs( const QStringList &dirs )
{
  m_templateDirs = dirs;
}

bool FileSystemTemplateLoader::canLoadTemplate( const QString &name ) const
{
  int i = 0;
  QFile file;

  while ( !file.exists() ) {
    if ( i >= m_templateDirs.size() )
      break;

    file.setFileName( m_templateDirs.at( i ) + '/' + m_themeName + '/' + name );
    ++i;
  }

  if ( !file.exists() || !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
    return false;
  }
  file.close();
  return true;
}

Template FileSystemTemplateLoader::loadByName( const QString &fileName, Engine const *engine ) const
{
  int i = 0;
  QFile file;

  while ( !file.exists() ) {
    if ( i >= m_templateDirs.size() )
      break;

    file.setFileName( m_templateDirs.at( i ) + '/' + m_themeName + '/' + fileName );
    QFileInfo fi( file );
    if ( !fi.canonicalFilePath().contains( QDir( m_templateDirs.at( i ) ).canonicalPath() ) )
      return Template();
    ++i;
  }

  if ( !file.exists() || !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
    return Template();
  }

  QString content;
  content = file.readAll();
  return engine->newTemplate( content, fileName );
}

QPair<QString, QString> FileSystemTemplateLoader::getMediaUri( const QString& fileName ) const
{
  int i = 0;
  QFile file;
  while ( !file.exists() ) {
    if ( i >= m_templateDirs.size() )
      break;

    file.setFileName( m_templateDirs.at( i ) + '/' + m_themeName + '/' + fileName );

    QFileInfo fi( file );
    if ( !fi.canonicalFilePath().contains( QDir( m_templateDirs.at( i ) ).canonicalPath() ) )
    {
      ++i;
      continue;
    }

    if ( file.exists() ) {
      QFileInfo fi( file );
      QString path = fi.absoluteFilePath();
      path.chop( fileName.size() );
      return qMakePair( path, fileName );
    }
    ++i;
  }
  return QPair<QString, QString>();
}

void InMemoryTemplateLoader::setTemplate( const QString &name, const QString &content )
{
  m_namedTemplates.insert( name, content );
}

bool InMemoryTemplateLoader::canLoadTemplate( const QString &name ) const
{
  return m_namedTemplates.contains( name );
}

Template InMemoryTemplateLoader::loadByName( const QString& name, Engine const *engine ) const
{
  if ( m_namedTemplates.contains( name ) ) {
    Template t = engine->newTemplate( m_namedTemplates.value( name ), name );
    return t;
  }
  throw Grantlee::Exception( TagSyntaxError, QString( "Couldn't load template %1. Template does not exist." ).arg( name ) );
}

QPair<QString, QString> InMemoryTemplateLoader::getMediaUri( const QString& fileName ) const
{
  Q_UNUSED( fileName )
  // This loader doesn't make any media available yet.
  return QPair<QString, QString>();
}

<commit_msg>Fix to allow use of multiple template directories.<commit_after>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2 of the Licence, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "templateloader.h"
#include "engine.h"
#include "exception.h"

#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>

using namespace Grantlee;

AbstractTemplateLoader::~AbstractTemplateLoader()
{

}

FileSystemTemplateLoader::FileSystemTemplateLoader()
    : AbstractTemplateLoader()
{

}

FileSystemTemplateLoader::~FileSystemTemplateLoader()
{

}

InMemoryTemplateLoader::InMemoryTemplateLoader()
    : AbstractTemplateLoader()
{

}

InMemoryTemplateLoader::~InMemoryTemplateLoader()
{

}

void FileSystemTemplateLoader::setTheme( const QString &themeName )
{
  m_themeName = themeName;
}

QString FileSystemTemplateLoader::themeName() const
{
  return m_themeName;
}

void FileSystemTemplateLoader::setTemplateDirs( const QStringList &dirs )
{
  m_templateDirs = dirs;
}

bool FileSystemTemplateLoader::canLoadTemplate( const QString &name ) const
{
  int i = 0;
  QFile file;

  while ( !file.exists() ) {
    if ( i >= m_templateDirs.size() )
      break;

    file.setFileName( m_templateDirs.at( i ) + '/' + m_themeName + '/' + name );
    ++i;
  }

  if ( !file.exists() || !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
    return false;
  }
  file.close();
  return true;
}

Template FileSystemTemplateLoader::loadByName( const QString &fileName, Engine const *engine ) const
{
  int i = 0;
  QFile file;

  while ( !file.exists() ) {
    if ( i >= m_templateDirs.size() )
      break;

    file.setFileName( m_templateDirs.at( i ) + '/' + m_themeName + '/' + fileName );
    QFileInfo fi( file );

    if ( file.exists() &&
          !fi.canonicalFilePath().contains( QDir( m_templateDirs.at( i ) ).canonicalPath() ) )
      return Template();
    ++i;
  }

  if ( !file.exists() || !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
    return Template();
  }

  QString content;
  content = file.readAll();
  return engine->newTemplate( content, fileName );
}

QPair<QString, QString> FileSystemTemplateLoader::getMediaUri( const QString& fileName ) const
{
  int i = 0;
  QFile file;
  while ( !file.exists() ) {
    if ( i >= m_templateDirs.size() )
      break;

    file.setFileName( m_templateDirs.at( i ) + '/' + m_themeName + '/' + fileName );

    QFileInfo fi( file );
    if ( !fi.canonicalFilePath().contains( QDir( m_templateDirs.at( i ) ).canonicalPath() ) )
    {
      ++i;
      continue;
    }

    if ( file.exists() ) {
      QFileInfo fi( file );
      QString path = fi.absoluteFilePath();
      path.chop( fileName.size() );
      return qMakePair( path, fileName );
    }
    ++i;
  }
  return QPair<QString, QString>();
}

void InMemoryTemplateLoader::setTemplate( const QString &name, const QString &content )
{
  m_namedTemplates.insert( name, content );
}

bool InMemoryTemplateLoader::canLoadTemplate( const QString &name ) const
{
  return m_namedTemplates.contains( name );
}

Template InMemoryTemplateLoader::loadByName( const QString& name, Engine const *engine ) const
{
  if ( m_namedTemplates.contains( name ) ) {
    Template t = engine->newTemplate( m_namedTemplates.value( name ), name );
    return t;
  }
  throw Grantlee::Exception( TagSyntaxError, QString( "Couldn't load template %1. Template does not exist." ).arg( name ) );
}

QPair<QString, QString> InMemoryTemplateLoader::getMediaUri( const QString& fileName ) const
{
  Q_UNUSED( fileName )
  // This loader doesn't make any media available yet.
  return QPair<QString, QString>();
}

<|endoftext|>