<commit_before>#include "itkCommandLineArgumentParser.h"
#include "CommandLineArgumentHelper.h"

#include "itkImageFileReader.h"
#include "itkVectorIndexSelectionCastImageFilter.h"
#include "itkImageFileWriter.h"

#include "itkImage.h"
#include "itkVector.h"

//-------------------------------------------------------------------------------------

/** run: A macro to call a function. */
#define run( function, type, dim ) \
if ( ComponentTypeIn == #type && Dimension == dim ) \
{ \
  function< type, dim >( inputFileName, outputFileName, index ); \
  supported = true; \
}

//-------------------------------------------------------------------------------------

/** Declare ExtractIndex. */
template< class TPixel, unsigned int NDimension >
void ExtractIndex(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const unsigned int & index );

/** Declare PrintHelp. */
void PrintHelp( void );

//-------------------------------------------------------------------------------------

int main( int argc, char ** argv )
{
  /** Check arguments for help. */
  if ( argc < 5 )
  {
    PrintHelp();
    return 1;
  }

  /** Create a command line argument parser. */
  itk::CommandLineArgumentParser::Pointer parser = itk::CommandLineArgumentParser::New();
  parser->SetCommandLineArguments( argc, argv );

  /** Get arguments. */
  std::string inputFileName = "";
  bool retin = parser->GetCommandLineArgument( "-in", inputFileName );

  std::string outputFileName = inputFileName.substr( 0, inputFileName.rfind( "." ) );
  outputFileName += "INDEXEXTRACTED.mhd";
  bool retout = parser->GetCommandLineArgument( "-out", outputFileName );

  unsigned int index = 0;
  bool retind = parser->GetCommandLineArgument( "-ind", index );

  /** Check if the required arguments are given. */
  if ( !retin )
  {
    std::cerr << "ERROR: You should specify \"-in\"." << std::endl;
    return 1;
  }
  /** Check if the required arguments are given. */
  if ( !retind )
  {
    std::cerr << "ERROR: You should specify \"-ind\"." << std::endl;
    return 1;
  }

  /** Determine image properties. */
  std::string ComponentTypeIn = "short";
  std::string PixelType; //we don't use this
  unsigned int Dimension = 3;
  unsigned int NumberOfComponents = 1;
  std::vector<unsigned int> imagesize( Dimension, 0 );
  int retgip = GetImageProperties(
    inputFileName,
    PixelType,
    ComponentTypeIn,
    Dimension,
    NumberOfComponents,
    imagesize );
  if ( retgip != 0 )
  {
    std::cerr << "ERROR: error while getting image properties of the input image!" << std::endl;
    return 1;
  }

  /** Check for vector images. */
  if ( NumberOfComponents == 1 )
  {
    std::cerr << "ERROR: The NumberOfComponents is 1!" << std::endl;
    std::cerr << "Cannot make extract index from a scalar image." << std::endl;
    return 1;
  }

  /** Get rid of the possible "_" in ComponentType. */
  ReplaceUnderscoreWithSpace( ComponentTypeIn );

  /** Sanity check. */
  if ( index > NumberOfComponents - 1 )
  {
    std::cerr << "ERROR: You selected index "
      << index << ", where the input image only has "
      << NumberOfComponents << " components." << std::endl;
    return 1;
  }

  /** Run the program. */
  bool supported = false;
  try
  {
    run( ExtractIndex, char, 2 );
    run( ExtractIndex, unsigned char, 2 );
    run( ExtractIndex, short, 2 );
    run( ExtractIndex, unsigned short, 2 );
    run( ExtractIndex, int, 2 );
    run( ExtractIndex, unsigned int, 2 );
    run( ExtractIndex, long, 2 );
    //run( ExtractIndex, unsigned long, 2 );
    run( ExtractIndex, float, 2 );
    run( ExtractIndex, double, 2 );

    run( ExtractIndex, char, 3 );
    run( ExtractIndex, unsigned char, 3 );
    run( ExtractIndex, short, 3 );
    run( ExtractIndex, unsigned short, 3 );
    run( ExtractIndex, int, 3 );
    run( ExtractIndex, unsigned int, 3 );
    run( ExtractIndex, long, 3 );
    //run( ExtractIndex, unsigned long, 3 );
    run( ExtractIndex, float, 3 );
    run( ExtractIndex, double, 3 );
  }
  catch( itk::ExceptionObject &e )
  {
    std::cerr << "Caught ITK exception: " << e << std::endl;
    return 1;
  }
  if ( !supported )
  {
    std::cerr << "ERROR: this combination of pixeltype and dimension is not supported!" << std::endl;
    std::cerr
      << "pixel (component) type = " << ComponentTypeIn
      << " ; dimension = " << Dimension
      << std::endl;
    return 1;
  }

  /** End program. */
  return 0;

} // end main

/**
 * ******************* ExtractIndex *******************
 */

template< class TPixel, unsigned int NDimension >
void ExtractIndex(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const unsigned int & index )
{
  /** Typedef's. */
  typedef TPixel                 PixelType;
  const unsigned int Dimension = NDimension;

  //typedef itk::Vector< PixelType, Dimension >         VectorPixelType;
  //typedef itk::Image< VectorPixelType, Dimension >    VectorImageType;
  /** Use vector image type that dynamically determines vector length: */
  typedef itk::VectorImage< PixelType, Dimension >    VectorImageType;
  typedef itk::Image< PixelType, Dimension >          ImageType;
  typedef itk::ImageFileReader< VectorImageType >     ImageReaderType;
  typedef itk::VectorIndexSelectionCastImageFilter<
    VectorImageType, ImageType >                      IndexExtractorType;
  typedef itk::ImageFileWriter< ImageType >           ImageWriterType;

  /** Read input image. */
  typename ImageReaderType::Pointer reader = ImageReaderType::New();
  reader->SetFileName( inputFileName );

  /** Extract index. */
  typename IndexExtractorType::Pointer extractor = IndexExtractorType::New();
  extractor->SetInput( reader->GetOutput() );
  extractor->SetIndex( index );

  /** Write output image. */
  typename ImageWriterType::Pointer writer = ImageWriterType::New();
  writer->SetFileName( outputFileName );
  writer->SetInput( extractor->GetOutput() );
  writer->Update();

} // end ExtractIndex()

/**
 * ******************* PrintHelp *******************
 */

void PrintHelp()
{
  std::cout << "This program extracts a user specified component from a vector image.\n";
  std::cout << "Usage:\n"
            << "pxextractindexfromvectorimage\n";
  std::cout << "  -in      inputFilename\n";
  std::cout << "  [-out]   outputFilename, default in + INDEXEXTRACTED.mhd\n";
  std::cout << "  -ind     a valid index\n";
  std::cout << "Supported: 2D, 3D, (unsigned) char, (unsigned) short, (unsigned) int,\n"
            << "long, float, double." << std::endl;

} // end PrintHelp()

<commit_msg>SK: -BUG: forgot including itkVectorImage.h but anyway it compiled already.<commit_after>#include "itkCommandLineArgumentParser.h"
#include "CommandLineArgumentHelper.h"

#include "itkImageFileReader.h"
#include "itkVectorIndexSelectionCastImageFilter.h"
#include "itkImageFileWriter.h"

#include "itkImage.h"
#include "itkVectorImage.h"
#include "itkVector.h"

//-------------------------------------------------------------------------------------

/** run: A macro to call a function. */
#define run( function, type, dim ) \
if ( ComponentTypeIn == #type && Dimension == dim ) \
{ \
  function< type, dim >( inputFileName, outputFileName, index ); \
  supported = true; \
}

//-------------------------------------------------------------------------------------

/** Declare ExtractIndex. */
template< class TPixel, unsigned int NDimension >
void ExtractIndex(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const unsigned int & index );

/** Declare PrintHelp. */
void PrintHelp( void );

//-------------------------------------------------------------------------------------

int main( int argc, char ** argv )
{
  /** Check arguments for help. */
  if ( argc < 5 )
  {
    PrintHelp();
    return 1;
  }

  /** Create a command line argument parser. */
  itk::CommandLineArgumentParser::Pointer parser = itk::CommandLineArgumentParser::New();
  parser->SetCommandLineArguments( argc, argv );

  /** Get arguments. */
  std::string inputFileName = "";
  bool retin = parser->GetCommandLineArgument( "-in", inputFileName );

  std::string outputFileName = inputFileName.substr( 0, inputFileName.rfind( "." ) );
  outputFileName += "INDEXEXTRACTED.mhd";
  bool retout = parser->GetCommandLineArgument( "-out", outputFileName );

  unsigned int index = 0;
  bool retind = parser->GetCommandLineArgument( "-ind", index );

  /** Check if the required arguments are given. */
  if ( !retin )
  {
    std::cerr << "ERROR: You should specify \"-in\"." << std::endl;
    return 1;
  }
  /** Check if the required arguments are given. */
  if ( !retind )
  {
    std::cerr << "ERROR: You should specify \"-ind\"." << std::endl;
    return 1;
  }

  /** Determine image properties. */
  std::string ComponentTypeIn = "short";
  std::string PixelType; //we don't use this
  unsigned int Dimension = 3;
  unsigned int NumberOfComponents = 1;
  std::vector<unsigned int> imagesize( Dimension, 0 );
  int retgip = GetImageProperties(
    inputFileName,
    PixelType,
    ComponentTypeIn,
    Dimension,
    NumberOfComponents,
    imagesize );
  if ( retgip != 0 )
  {
    std::cerr << "ERROR: error while getting image properties of the input image!" << std::endl;
    return 1;
  }

  /** Check for vector images. */
  if ( NumberOfComponents == 1 )
  {
    std::cerr << "ERROR: The NumberOfComponents is 1!" << std::endl;
    std::cerr << "Cannot make extract index from a scalar image." << std::endl;
    return 1;
  }

  /** Get rid of the possible "_" in ComponentType. */
  ReplaceUnderscoreWithSpace( ComponentTypeIn );

  /** Sanity check. */
  if ( index > NumberOfComponents - 1 )
  {
    std::cerr << "ERROR: You selected index "
      << index << ", where the input image only has "
      << NumberOfComponents << " components." << std::endl;
    return 1;
  }

  /** Run the program. */
  bool supported = false;
  try
  {
    run( ExtractIndex, char, 2 );
    run( ExtractIndex, unsigned char, 2 );
    run( ExtractIndex, short, 2 );
    run( ExtractIndex, unsigned short, 2 );
    run( ExtractIndex, int, 2 );
    run( ExtractIndex, unsigned int, 2 );
    run( ExtractIndex, long, 2 );
    //run( ExtractIndex, unsigned long, 2 );
    run( ExtractIndex, float, 2 );
    run( ExtractIndex, double, 2 );

    run( ExtractIndex, char, 3 );
    run( ExtractIndex, unsigned char, 3 );
    run( ExtractIndex, short, 3 );
    run( ExtractIndex, unsigned short, 3 );
    run( ExtractIndex, int, 3 );
    run( ExtractIndex, unsigned int, 3 );
    run( ExtractIndex, long, 3 );
    //run( ExtractIndex, unsigned long, 3 );
    run( ExtractIndex, float, 3 );
    run( ExtractIndex, double, 3 );
  }
  catch( itk::ExceptionObject &e )
  {
    std::cerr << "Caught ITK exception: " << e << std::endl;
    return 1;
  }
  if ( !supported )
  {
    std::cerr << "ERROR: this combination of pixeltype and dimension is not supported!" << std::endl;
    std::cerr
      << "pixel (component) type = " << ComponentTypeIn
      << " ; dimension = " << Dimension
      << std::endl;
    return 1;
  }

  /** End program. */
  return 0;

} // end main

/**
 * ******************* ExtractIndex *******************
 */

template< class TPixel, unsigned int NDimension >
void ExtractIndex(
  const std::string & inputFileName,
  const std::string & outputFileName,
  const unsigned int & index )
{
  /** Typedef's. */
  typedef TPixel                 PixelType;
  const unsigned int Dimension = NDimension;

  //typedef itk::Vector< PixelType, Dimension >         VectorPixelType;
  //typedef itk::Image< VectorPixelType, Dimension >    VectorImageType;
  /** Use vector image type that dynamically determines vector length: */
  typedef itk::VectorImage< PixelType, Dimension >    VectorImageType;
  typedef itk::Image< PixelType, Dimension >          ImageType;
  typedef itk::ImageFileReader< VectorImageType >     ImageReaderType;
  typedef itk::VectorIndexSelectionCastImageFilter<
    VectorImageType, ImageType >                      IndexExtractorType;
  typedef itk::ImageFileWriter< ImageType >           ImageWriterType;

  /** Read input image. */
  typename ImageReaderType::Pointer reader = ImageReaderType::New();
  reader->SetFileName( inputFileName );

  /** Extract index. */
  typename IndexExtractorType::Pointer extractor = IndexExtractorType::New();
  extractor->SetInput( reader->GetOutput() );
  extractor->SetIndex( index );

  /** Write output image. */
  typename ImageWriterType::Pointer writer = ImageWriterType::New();
  writer->SetFileName( outputFileName );
  writer->SetInput( extractor->GetOutput() );
  writer->Update();

} // end ExtractIndex()

/**
 * ******************* PrintHelp *******************
 */

void PrintHelp()
{
  std::cout << "This program extracts a user specified component from a vector image.\n";
  std::cout << "Usage:\n"
            << "pxextractindexfromvectorimage\n";
  std::cout << "  -in      inputFilename\n";
  std::cout << "  [-out]   outputFilename, default in + INDEXEXTRACTED.mhd\n";
  std::cout << "  -ind     a valid index\n";
  std::cout << "Supported: 2D, 3D, (unsigned) char, (unsigned) short, (unsigned) int,\n"
            << "long, float, double." << std::endl;

} // end PrintHelp()

<|endoftext|>


<commit_before>#include "opencv2/opencv.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace cv;

#include "Pipeline.hpp"
#include "util.hpp"

void Pipeline::register_camera(ImagePairs& pairs,CamFrames& cam_Frames){
	Logger _log("Step 3 (register)");

	// ---------Parameters for solvePnPRansac----------------//
	bool useExtrinsicGuess = false;
	int iterationsCount=500;
	float reprojectionError=15.0;
	// portion of inliers in matches
	float minInliers = 0.8;
	int flag = CV_ITERATIVE; //CV_ITERATIVE CV_P3P CV_EPNP

	// get 3D-2D registration for all matched frames
	for(auto pair = pairs.begin(); pair != pairs.end(); pair++){

		int i = (pair -> pair_index).first;
		int j = (pair -> pair_index).second;

		std::vector<Point2f> keyPoints1 = pair -> matched_points.first;
		std::vector<Point2f> keyPoints2 = pair -> matched_points.second;
		Depths depths1 = pair-> pair_depths.first;
		Depths depths2 = pair-> pair_depths.second;

		// get depth value of all matched keypoints in image1
		std::vector<Point3f> points3D;
		std::vector<Point2f> valid_keyPoints;
		for(std::size_t k = 0; k < keyPoints1.size(); ++k){

			float x = keyPoints1[k].x;
			float y = keyPoints1[k].y;
			float d = depths1[k];
			// skip invalid depth
			if (d == 0) continue;
			// backproject 3d points
			Mat new_point = d * cameraMatrix.inv() * (Mat_<float>(3,1) << x,y,1.f);
			//Point3f new_point = backproject3D(x,y,d,cameraMatrix);
			valid_keyPoints.push_back(keyPoints2[k]);
			points3D.push_back(Point3f(new_point));
		}

		Mat rvec,tvec,R;
		Mat inliers;
		//NOTE the following command always fails
		solvePnPRansac(points3D,valid_keyPoints,cameraMatrix,distCoeffs,
			 rvec,tvec,
			 useExtrinsicGuess, iterationsCount, reprojectionError, .95, inliers, flag);

		_log("%03d inliers for %04d-%04d pair.", inliers.rows, i, j);

		tvec.convertTo(tvec,CV_32FC1);
		rvec.convertTo(rvec,CV_32FC1);

		Rodrigues(rvec,R);
		pair -> R = R;
		pair -> t = tvec;
		//TODO CheckCoherentRotation(R);
		/*
		std::vector<cv::Point2f> projected3D;
		cv::projectPoints(points3D, rvec, tvec, cameraMatrix, distCoeffs, projected3D);
		for(int i=0;i<projected3D.size();i++) {
			std::cout << i << ". " << valid_keyPoints[i] << std::endl;
			std::cout << i << ". " << projected3D[i] << std::endl;
		}
		*/
	}

	_log("Complete");
}
/**
* 3D-2D registration using Kinect depth points
*/
// bool Pipeline::ransacRegistration(ImagePair& pair)
// {
// 	int i = (pair -> pair_index).first;
// 	int j = (pair -> pair_index).second;

// 	std::vector<Point2f> keyPoints1 = pair -> matched_points.first;
// 	std::vector<Point2f> keyPoints2 = pair -> matched_points.second;
// 	Depths depths1 = pair-> pair_depths.first;
// 	Depths depths2 = pair-> pair_depths.second;

// 	// get depth value of all matched keypoints in image1
// 	std::vector<Point3f> points3D;
// 	std::vector<Point2f> valid_keyPoints;
// 	for(std::size_t k = 0; k < keyPoints1.size(); ++k){

// 		float x = keyPoints1[k].x;
// 		float y = keyPoints1[k].y;
// 		float d = depths1[k];
// 		// skip invalid depth
// 		if (d == 0) continue;
// 		// backproject 3d points
// 		Mat new_point = d * cameraMatrix.inv() * (Mat_<float>(3,1) << x,y,1.f);
// 		// Point3f new_point = backproject3D(x,y,d,cameraMatrix);
// 		valid_keyPoints.push_back(keyPoints2[k]);
// 		points3D.push_back(Point3f(new_point));
// 	}

// 	Mat rvec,tvec,R;
// 	Mat inliers;
// 	//NOTE the following command always fails
// 	// solvePnPRansac(points3D,valid_keyPoints,cameraMatrix,distCoeffs,
// 	// 	rvec,tvec,
// 	// 	useExtrinsicGuess, iterationsCount, reprojectionError,100, noArray(), flag);
// 	solvePnPRansac(points3D,valid_keyPoints,cameraMatrix,distCoeffs,
// 		rvec,tvec);
// 	tvec.convertTo(tvec,CV_32FC1);
// 	rvec.convertTo(rvec,CV_32FC1);

// 	Rodrigues(rvec,R);
// 	pair -> R = R;
// 	pair -> t = tvec;
// 	//TODO CheckCoherentRotation(R);
// 	std::cout << " test" << std::endl<< R <<std::endl;
// 	std::vector<cv::Point2f> projected3D;
// 	cv::projectPoints(points3D, rvec, tvec, cameraMatrix, distCoeffs, projected3D);
// 	for(int i=0;i<projected3D.size();i++) {
// 		std::cout << i << ". " << valid_keyPoints[i] << std::endl;
// 		std::cout << i << ". " << projected3D[i] << std::endl;
// 	}
// }
// bool CheckCoherentRotation(cv::Mat_<float>& R) {

// 	if(fabs(determinant(R))-1.0 > 1e-05) {
// 		std::cerr << "det(R) != +-1.0, this is not a rotation matrix" << std::endl;
// 		return false;
// 	}
// 	return true;
// }
<commit_msg>try to average rotation matrix with quaternion - doesn't work<commit_after>#include "opencv2/opencv.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace cv;

#include "Pipeline.hpp"
#include "util.hpp"

void Pipeline::register_camera(ImagePairs& pairs,CamFrames& cam_Frames){
	Logger _log("Step 3 (register)");

	// ---------Parameters for solvePnPRansac----------------//
	bool useExtrinsicGuess = false;
	int iterationsCount=500;
	float reprojectionError=15.0;
	// portion of inliers in matches
	float minInliers = 0.8;
	int flag = CV_ITERATIVE; //CV_ITERATIVE CV_P3P CV_EPNP

	// get 3D-2D registration for all matched frames
	for(auto pair = pairs.begin(); pair != pairs.end(); pair++){

		int i = (pair -> pair_index).first;
		int j = (pair -> pair_index).second;

		std::vector<Point2f> keyPoints_i = pair -> matched_points.first;
		std::vector<Point2f> keyPoints_j = pair -> matched_points.second;
		Depths depths_i = pair-> pair_depths.first;
		Depths depths_j = pair-> pair_depths.second;

		// get depth value of all matched keypoints in image1
		std::vector<Point3f> points3D_i, points3D_j;
		std::vector<Point2f> valid_keyPoints_i,valid_keyPoints_j;
		for(std::size_t k = 0; k < keyPoints_i.size(); ++k){

			float x_i = keyPoints_i[k].x;
			float y_i = keyPoints_i[k].y;
			float d_i = depths_i[k];
			float x_j = keyPoints_j[k].x;
			float y_j = keyPoints_j[k].y;
			float d_j = depths_j[k];

			// skip invalid depth
			if (d_j == 0 || d_i ==0 ) continue;

			// backproject 3d points
			Point3f objPoints_i = backproject3D(x_i,y_i,d_i,cameraMatrix);
			valid_keyPoints_i.push_back(keyPoints_i[k]);
			points3D_i.push_back(objPoints_i);

			Point3f objPoints_j = backproject3D(x_j,y_j,d_j,cameraMatrix);
			valid_keyPoints_j.push_back(keyPoints_j[k]);
			points3D_j.push_back(objPoints_j);
		}

		Mat rvec_i,tvec_i,R_i,rvec_j,tvec_j,R_j;
		Mat inliers,inliers_j;
		//NOTE the following command always fails
		solvePnPRansac(points3D_i,valid_keyPoints_j,
			cameraMatrix,noArray(),
			rvec_i,tvec_i,
			useExtrinsicGuess, iterationsCount, reprojectionError, .95, inliers, flag);

		solvePnPRansac(points3D_j,valid_keyPoints_i,
			cameraMatrix,noArray(),
			rvec_j,tvec_j,
			useExtrinsicGuess, iterationsCount, reprojectionError, .95, inliers_j, flag);

		_log("%03d inliers for %04d-%04d pair.", inliers.rows, i, j);

		tvec_i.convertTo(tvec_i,CV_32FC1);
		rvec_i.convertTo(rvec_i,CV_32FC1);
		tvec_j.convertTo(tvec_j,CV_32FC1);
		rvec_j.convertTo(rvec_j,CV_32FC1);

		Rodrigues(rvec_i,R_i);
		Rodrigues(rvec_j,R_j);
		Mat R_j_t = R_j.t();
		Vec4f q_i = R2Quaternion(R_i);
		Vec4f q_j = R2Quaternion(R_j_t);
		// std::cout<<"points3D_j "<<points3D_j<<std::endl;
		std::cout<<"inliers "<<std::endl<<inliers<<std::endl;
		std::cout<<"inliers_j "<<std::endl<<inliers_j<<std::endl;
		std::cout<<"q_i "<<std::endl<<q_i<<std::endl;
		std::cout<<"q_j "<<std::endl<<q_j<<std::endl;

		pair -> R = R_i;
		pair -> t = tvec_i;
		//TODO CheckCoherentRotation(R);

		std::vector<cv::Point2f> projected3D;
		cv::projectPoints(points3D_j, rvec_j, tvec_j, cameraMatrix, noArray(), projected3D);
		for(int i=0;i<projected3D.size();i++) {
			std::cout << i << ". " << valid_keyPoints_i[i] << std::endl;
			std::cout << i << ". " << projected3D[i] << std::endl;
		}

	}

	_log("Complete");
}
/**
* 3D-2D registration using Kinect depth points
*/
// bool Pipeline::ransacRegistration(ImagePair& pair)
// {
// 	int i = (pair -> pair_index).first;
// 	int j = (pair -> pair_index).second;

// 	std::vector<Point2f> keyPoints1 = pair -> matched_points.first;
// 	std::vector<Point2f> keyPoints2 = pair -> matched_points.second;
// 	Depths depths1 = pair-> pair_depths.first;
// 	Depths depths2 = pair-> pair_depths.second;

// 	// get depth value of all matched keypoints in image1
// 	std::vector<Point3f> points3D;
// 	std::vector<Point2f> valid_keyPoints;
// 	for(std::size_t k = 0; k < keyPoints1.size(); ++k){

// 		float x = keyPoints1[k].x;
// 		float y = keyPoints1[k].y;
// 		float d = depths1[k];
// 		// skip invalid depth
// 		if (d == 0) continue;
// 		// backproject 3d points
// 		Mat new_point = d * cameraMatrix.inv() * (Mat_<float>(3,1) << x,y,1.f);
// 		// Point3f new_point = backproject3D(x,y,d,cameraMatrix);
// 		valid_keyPoints.push_back(keyPoints2[k]);
// 		points3D.push_back(Point3f(new_point));
// 	}

// 	Mat rvec,tvec,R;
// 	Mat inliers;
// 	//NOTE the following command always fails
// 	// solvePnPRansac(points3D,valid_keyPoints,cameraMatrix,distCoeffs,
// 	// 	rvec,tvec,
// 	// 	useExtrinsicGuess, iterationsCount, reprojectionError,100, noArray(), flag);
// 	solvePnPRansac(points3D,valid_keyPoints,cameraMatrix,distCoeffs,
// 		rvec,tvec);
// 	tvec.convertTo(tvec,CV_32FC1);
// 	rvec.convertTo(rvec,CV_32FC1);

// 	Rodrigues(rvec,R);
// 	pair -> R = R;
// 	pair -> t = tvec;
// 	//TODO CheckCoherentRotation(R);
// 	std::cout << " test" << std::endl<< R <<std::endl;
// 	std::vector<cv::Point2f> projected3D;
// 	cv::projectPoints(points3D, rvec, tvec, cameraMatrix, distCoeffs, projected3D);
// 	for(int i=0;i<projected3D.size();i++) {
// 		std::cout << i << ". " << valid_keyPoints[i] << std::endl;
// 		std::cout << i << ". " << projected3D[i] << std::endl;
// 	}
// }
// bool CheckCoherentRotation(cv::Mat_<float>& R) {

// 	if(fabs(determinant(R))-1.0 > 1e-05) {
// 		std::cerr << "det(R) != +-1.0, this is not a rotation matrix" << std::endl;
// 		return false;
// 	}
// 	return true;
// }
<|endoftext|>


<commit_before>// WinButton.cc for Fluxbox Window Manager
// Copyright (c) 2003 - 2005 Henrik Kinnunen (fluxgen at fluxbox dot org)
//
// 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.

/// $Id$

#include <X11/Xlib.h>

#include "WinButton.hh"
#include "App.hh"
#include "Window.hh"
#include "Screen.hh"
#include "WinClient.hh"
#include "WinButtonTheme.hh"
#include "FbTk/Color.hh"

#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif // SHAPE

WinButton::WinButton(const FluxboxWindow &listen_to,
                     WinButtonTheme &theme,
                     Type buttontype, const FbTk::FbWindow &parent,
                     int x, int y,
                     unsigned int width, unsigned int height):
    FbTk::Button(parent, x, y, width, height),
    m_type(buttontype), m_listen_to(listen_to), m_theme(theme),
    m_icon_pixmap(0), m_icon_mask(0),
    overrode_bg(false), overrode_pressed(false) {
    theme.reconfigSig().attach(this);

    if (buttontype == MENUICON)
        update(0);
}

void WinButton::exposeEvent(XExposeEvent &event) {
    FbTk::Button::exposeEvent(event);
    drawType();
}

void WinButton::buttonReleaseEvent(XButtonEvent &event) {
    FbTk::Button::buttonReleaseEvent(event);
}

// when someone else tries to set the background, we may override it
void WinButton::setBackgroundPixmap(Pixmap pm) {
    Pixmap my_pm = getBackgroundPixmap();

    if (my_pm != 0) {
        overrode_bg = true;
        pm = my_pm;
    } else {
        overrode_bg = false;
    }

    FbTk::Button::setBackgroundPixmap(pm);
}

void WinButton::setBackgroundColor(const FbTk::Color &color) {
    Pixmap my_pm = getBackgroundPixmap();

    if (my_pm != 0) {
        overrode_bg = true;
        FbTk::Button::setBackgroundPixmap(my_pm);
    } else {
        overrode_bg = false;
        FbTk::Button::setBackgroundColor(color);
    }
}

void WinButton::setPressedPixmap(Pixmap pm) {
    Pixmap my_pm = getPressedPixmap();

    if (my_pm != 0) {
        overrode_pressed = true;
        pm = my_pm;
    } else {
        overrode_pressed = false;
    }

    FbTk::Button::setPressedPixmap(pm);
}

void WinButton::setPressedColor(const FbTk::Color &color) {
    Pixmap my_pm = getPressedPixmap();

    if (my_pm != 0) {
        overrode_pressed = true;
        FbTk::Button::setPressedPixmap(my_pm);
    } else {
        overrode_pressed = false;
        FbTk::Button::setPressedColor(color);
    }
}

Pixmap WinButton::getBackgroundPixmap() const {
    bool focused = m_listen_to.isFocused();
    switch(m_type) {
    case MAXIMIZE:
        if (focused)
            return m_theme.maximizePixmap().pixmap().drawable();
        else
            return m_theme.maximizeUnfocusPixmap().pixmap().drawable();
        break;
    case MINIMIZE:
        if (focused)
            return m_theme.iconifyPixmap().pixmap().drawable();
        else
            return m_theme.iconifyUnfocusPixmap().pixmap().drawable();
        break;
    case STICK:
        if (m_listen_to.isStuck()) {
            if (focused)
                return m_theme.stuckPixmap().pixmap().drawable();
            else
                return m_theme.stuckUnfocusPixmap().pixmap().drawable();
        } else {
            if (focused)
                return m_theme.stickPixmap().pixmap().drawable();
            else
                return m_theme.stickUnfocusPixmap().pixmap().drawable();
        }
        break;
    case CLOSE:
        if (focused)
            return m_theme.closePixmap().pixmap().drawable();
        else
            return m_theme.closeUnfocusPixmap().pixmap().drawable();
        break;
    case SHADE:
        if (m_listen_to.isShaded()) {
            if (focused)
                return m_theme.unshadePixmap().pixmap().drawable();
            else
                return m_theme.unshadeUnfocusPixmap().pixmap().drawable();
        } else {
            if (focused)
                return m_theme.shadePixmap().pixmap().drawable();
            else
                return m_theme.shadeUnfocusPixmap().pixmap().drawable();
        }
        break;
    case MENUICON:
        if (m_icon_pixmap.drawable()) {
            if (focused)
                return m_theme.titleFocusPixmap().pixmap().drawable();
            else
                return m_theme.titleUnfocusPixmap().pixmap().drawable();
        } else {
            if (focused)
                return m_theme.menuiconPixmap().pixmap().drawable();
            else
                return m_theme.menuiconUnfocusPixmap().pixmap().drawable();
        }
        break;
    }
    return None;
}

Pixmap WinButton::getPressedPixmap() const {
    switch(m_type) {
    case MAXIMIZE:
        return m_theme.maximizePressedPixmap().pixmap().drawable();
    case MINIMIZE:
        return m_theme.iconifyPressedPixmap().pixmap().drawable();
    case STICK:
        return m_theme.stickPressedPixmap().pixmap().drawable();
    case CLOSE:
        return m_theme.closePressedPixmap().pixmap().drawable();
    case SHADE:
        if (m_listen_to.isShaded())
            return m_theme.unshadePressedPixmap().pixmap().drawable();
        else
            return m_theme.shadePressedPixmap().pixmap().drawable();
    case MENUICON:
        if (m_icon_pixmap.drawable())
            if (m_listen_to.isFocused())
                return m_theme.titleFocusPixmap().pixmap().drawable();
            else
                return m_theme.titleUnfocusPixmap().pixmap().drawable();
        else
            return m_theme.menuiconPressedPixmap().pixmap().drawable();
    }
    return None;
}

// clear is used to force this to clear the window (e.g. called from clear())
void WinButton::drawType() {

    // if it's odd and we're centring, we need to add one
    int oddW = width()%2;
    int oddH = height()%2;

    bool is_pressed = pressed();
    if (is_pressed && overrode_pressed && !m_icon_pixmap.drawable())
        return;
    if (!is_pressed && overrode_bg && !m_icon_pixmap.drawable())
        return;
    if (gc() == 0)
        return;

    // otherwise draw old style imagery
    switch (m_type) {
    case MAXIMIZE:
        // if no pixmap was used, use old style
        if (gc() == 0) // must have valid graphic context
            return;

        drawRectangle(gc(),
                      2, 2, width() - 5, height() - 5);
        drawLine(gc(),
                 2, 3, width() - 3, 3);
        break;
    case MINIMIZE:
        drawRectangle(gc(), 2, height() - 5, width() - 5, 2);
        break;
    case STICK:
        // width/4 != width/2, so we use /4*2 so that it's properly centred
        if (m_listen_to.isStuck()) {
            fillRectangle(gc(),
                          width()/2 - width()/4, height()/2 - height()/4,
                          width()/4*2 + oddW, height()/4*2 + oddH);
        } else {
            fillRectangle(gc(),
                          width()/2 - width()/10, height()/2 - height()/10,
                          width()/10*2 + oddW, height()/10*2 + oddH);
        }
        break;
    case CLOSE:
        drawLine(gc(),
                 2, 2,
                 width() - 3, height() - 3);
        // I can't figure out why this second one needs a y offset of 1?????
        // but it does - at least on my box:
        //   XFree86 Version 4.2.1.1 (Debian 4.2.1-12.1 20031003005825)
        //   (protocol Version 11, revision 0, vendor release 6600)
        // But not on mine? It's wonky. Put back to the same coords.
        //  was width-2, 1 in the second drawline
        // Perhaps some X versions don't draw the endpoint?
        // Mine:
        // XFree86 Version 4.3.0.1 (Debian 4.3.0.dfsg.1-1 20040428170728)
        // (X Protocol Version 11, Revision 0, Release 6.6)

        drawLine(gc(),
                 2, height() - 3,
                 width() - 3, 2);
        break;
    case SHADE:

        drawRectangle(gc(), 2, 2, width() - 5 - oddW, 2);

        XPoint points[3];
        if (m_listen_to.isShaded()) {
            points[1].x = (width() / 2) - 3; points[1].y = 7;
            points[2].x = (width() / 2) + 4 - oddW; points[2].y = 7;
            points[0].x = (width() / 2); points[0].y = height() / 2 + 2;
        } else {
            points[0].x = (width() / 2); points[0].y = 6;
            points[1].x = (width() / 2) - 4; points[1].y = height() / 2 + 2;
            points[2].x = (width() / 2) + 4 - oddW; points[2].y = height() / 2 + 2;
        }
        fillPolygon(gc(), points, 3, Convex, CoordModeOrigin);
        break;
    case MENUICON:
        if (m_icon_pixmap.drawable()) {

            if (m_icon_mask.drawable()) {
                XSetClipMask(m_listen_to.fbWindow().display(),
                             gc(), m_icon_mask.drawable());
                XSetClipOrigin(m_listen_to.fbWindow().display(),
                             gc(), 2, 2);
            }

            copyArea(m_icon_pixmap.drawable(),
                     gc(),
                     0, 0,
                     2, 2,
                     m_icon_pixmap.width(), m_icon_pixmap.height());

            if (m_icon_mask.drawable())
                XSetClipMask(m_listen_to.fbWindow().display(), gc(), None);
        } else {
            for (int y = height()/3; y <= height() - height()/3; y+=3) {
                drawLine(gc(), width()/4, y, width() - width()/4 - oddW - 1, y);
            }
            drawRectangle(gc(),
                      2, 2, width() - 5, height() - 5);
        }
        break;
    }
}

void WinButton::clear() {
    FbTk::Button::clear();

    // ensure the m_listen_to has actually a client
    if (m_type == MENUICON && m_listen_to.numClients() && (
        !m_icon_pixmap.drawable() ||
        (m_icon_pixmap.width() != width() - 4 ||
         m_icon_pixmap.height() != height() - 4))) {

        Display* display = m_listen_to.fbWindow().display();
        int screen = m_listen_to.screen().screenNumber();
        XWMHints* hints = XGetWMHints(display, m_listen_to.winClient().window());
        if (hints == 0) {
            m_icon_pixmap.release();
            m_icon_mask.release();
        } else {
            if ((hints->flags & IconPixmapHint) && hints->icon_pixmap != 0) {
                 m_icon_pixmap.copy(hints->icon_pixmap,
                                    DefaultDepth(display, screen), screen);
                 m_icon_pixmap.scale(width() - 4, height() - 4);
            } else
                m_icon_pixmap.release();

            if ((hints->flags & IconMaskHint)) {
                m_icon_mask.copy(hints->icon_mask, 0, 0);
                m_icon_mask.scale(width() - 4, height() - 4);
            } else
                m_icon_mask.release();
        }

        XFree(hints);
    }

    drawType();
}

void WinButton::update(FbTk::Subject *subj) {

    // just checking, if we the app provides a pixmap.
    if (m_type == MENUICON && m_listen_to.numClients()) {
        XWMHints* hints = XGetWMHints(m_listen_to.fbWindow().display(),
                                      m_listen_to.winClient().window());
        if (hints == 0) {
            m_icon_pixmap.release();
            m_icon_mask.release();
        } else {
            if (!((hints->flags & IconPixmapHint) && hints->icon_pixmap != 0))
                m_icon_pixmap.release();

            if (!(hints->flags & IconMaskHint))
                m_icon_mask.release();
        }

        XFree(hints);
    }

    // pressed_pixmap isn't stateful in any current buttons, so no need
    // to potentially override that. Just make sure background pm is ok
    Pixmap my_pm = getBackgroundPixmap();
    if (my_pm != None)
        setBackgroundPixmap(my_pm);

    clear();
}
<commit_msg>minor optimization<commit_after>// WinButton.cc for Fluxbox Window Manager
// Copyright (c) 2003 - 2005 Henrik Kinnunen (fluxgen at fluxbox dot org)
//
// 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.

/// $Id$

#include <X11/Xlib.h>

#include "WinButton.hh"
#include "App.hh"
#include "Window.hh"
#include "Screen.hh"
#include "WinClient.hh"
#include "WinButtonTheme.hh"
#include "FbTk/Color.hh"

#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif // SHAPE

WinButton::WinButton(const FluxboxWindow &listen_to,
                     WinButtonTheme &theme,
                     Type buttontype, const FbTk::FbWindow &parent,
                     int x, int y,
                     unsigned int width, unsigned int height):
    FbTk::Button(parent, x, y, width, height),
    m_type(buttontype), m_listen_to(listen_to), m_theme(theme),
    m_icon_pixmap(0), m_icon_mask(0),
    overrode_bg(false), overrode_pressed(false) {
    theme.reconfigSig().attach(this);

    if (buttontype == MENUICON)
        update(0);
}

void WinButton::exposeEvent(XExposeEvent &event) {
    FbTk::Button::exposeEvent(event);
    drawType();
}

void WinButton::buttonReleaseEvent(XButtonEvent &event) {
    FbTk::Button::buttonReleaseEvent(event);
}

// when someone else tries to set the background, we may override it
void WinButton::setBackgroundPixmap(Pixmap pm) {
    Pixmap my_pm = getBackgroundPixmap();

    if (my_pm != 0) {
        overrode_bg = true;
        pm = my_pm;
    } else {
        overrode_bg = false;
    }

    FbTk::Button::setBackgroundPixmap(pm);
}

void WinButton::setBackgroundColor(const FbTk::Color &color) {
    Pixmap my_pm = getBackgroundPixmap();

    if (my_pm != 0) {
        overrode_bg = true;
        FbTk::Button::setBackgroundPixmap(my_pm);
    } else {
        overrode_bg = false;
        FbTk::Button::setBackgroundColor(color);
    }
}

void WinButton::setPressedPixmap(Pixmap pm) {
    Pixmap my_pm = getPressedPixmap();

    if (my_pm != 0) {
        overrode_pressed = true;
        pm = my_pm;
    } else {
        overrode_pressed = false;
    }

    FbTk::Button::setPressedPixmap(pm);
}

void WinButton::setPressedColor(const FbTk::Color &color) {
    Pixmap my_pm = getPressedPixmap();

    if (my_pm != 0) {
        overrode_pressed = true;
        FbTk::Button::setPressedPixmap(my_pm);
    } else {
        overrode_pressed = false;
        FbTk::Button::setPressedColor(color);
    }
}

Pixmap WinButton::getBackgroundPixmap() const {
    bool focused = m_listen_to.isFocused();
    switch(m_type) {
    case MAXIMIZE:
        if (focused)
            return m_theme.maximizePixmap().pixmap().drawable();
        else
            return m_theme.maximizeUnfocusPixmap().pixmap().drawable();
        break;
    case MINIMIZE:
        if (focused)
            return m_theme.iconifyPixmap().pixmap().drawable();
        else
            return m_theme.iconifyUnfocusPixmap().pixmap().drawable();
        break;
    case STICK:
        if (m_listen_to.isStuck()) {
            if (focused)
                return m_theme.stuckPixmap().pixmap().drawable();
            else
                return m_theme.stuckUnfocusPixmap().pixmap().drawable();
        } else {
            if (focused)
                return m_theme.stickPixmap().pixmap().drawable();
            else
                return m_theme.stickUnfocusPixmap().pixmap().drawable();
        }
        break;
    case CLOSE:
        if (focused)
            return m_theme.closePixmap().pixmap().drawable();
        else
            return m_theme.closeUnfocusPixmap().pixmap().drawable();
        break;
    case SHADE:
        if (m_listen_to.isShaded()) {
            if (focused)
                return m_theme.unshadePixmap().pixmap().drawable();
            else
                return m_theme.unshadeUnfocusPixmap().pixmap().drawable();
        } else {
            if (focused)
                return m_theme.shadePixmap().pixmap().drawable();
            else
                return m_theme.shadeUnfocusPixmap().pixmap().drawable();
        }
        break;
    case MENUICON:
        if (m_icon_pixmap.drawable()) {
            if (focused)
                return m_theme.titleFocusPixmap().pixmap().drawable();
            else
                return m_theme.titleUnfocusPixmap().pixmap().drawable();
        } else {
            if (focused)
                return m_theme.menuiconPixmap().pixmap().drawable();
            else
                return m_theme.menuiconUnfocusPixmap().pixmap().drawable();
        }
        break;
    }
    return None;
}

Pixmap WinButton::getPressedPixmap() const {
    switch(m_type) {
    case MAXIMIZE:
        return m_theme.maximizePressedPixmap().pixmap().drawable();
    case MINIMIZE:
        return m_theme.iconifyPressedPixmap().pixmap().drawable();
    case STICK:
        return m_theme.stickPressedPixmap().pixmap().drawable();
    case CLOSE:
        return m_theme.closePressedPixmap().pixmap().drawable();
    case SHADE:
        if (m_listen_to.isShaded())
            return m_theme.unshadePressedPixmap().pixmap().drawable();
        else
            return m_theme.shadePressedPixmap().pixmap().drawable();
    case MENUICON:
        if (m_icon_pixmap.drawable())
            if (m_listen_to.isFocused())
                return m_theme.titleFocusPixmap().pixmap().drawable();
            else
                return m_theme.titleUnfocusPixmap().pixmap().drawable();
        else
            return m_theme.menuiconPressedPixmap().pixmap().drawable();
    }
    return None;
}

// clear is used to force this to clear the window (e.g. called from clear())
void WinButton::drawType() {

    // if it's odd and we're centring, we need to add one
    int oddW = width()%2;
    int oddH = height()%2;

    bool is_pressed = pressed();
    if (is_pressed && overrode_pressed && !m_icon_pixmap.drawable())
        return;
    if (!is_pressed && overrode_bg && !m_icon_pixmap.drawable())
        return;
    if (gc() == 0)
        return;

    // otherwise draw old style imagery
    switch (m_type) {
    case MAXIMIZE:
        // if no pixmap was used, use old style
        if (gc() == 0) // must have valid graphic context
            return;

        drawRectangle(gc(),
                      2, 2, width() - 5, height() - 5);
        drawLine(gc(),
                 2, 3, width() - 3, 3);
        break;
    case MINIMIZE:
        drawRectangle(gc(), 2, height() - 5, width() - 5, 2);
        break;
    case STICK:
        // width/4 != width/2, so we use /4*2 so that it's properly centred
        if (m_listen_to.isStuck()) {
            fillRectangle(gc(),
                          width()/2 - width()/4, height()/2 - height()/4,
                          width()/4*2 + oddW, height()/4*2 + oddH);
        } else {
            fillRectangle(gc(),
                          width()/2 - width()/10, height()/2 - height()/10,
                          width()/10*2 + oddW, height()/10*2 + oddH);
        }
        break;
    case CLOSE:
        drawLine(gc(),
                 2, 2,
                 width() - 3, height() - 3);
        // I can't figure out why this second one needs a y offset of 1?????
        // but it does - at least on my box:
        //   XFree86 Version 4.2.1.1 (Debian 4.2.1-12.1 20031003005825)
        //   (protocol Version 11, revision 0, vendor release 6600)
        // But not on mine? It's wonky. Put back to the same coords.
        //  was width-2, 1 in the second drawline
        // Perhaps some X versions don't draw the endpoint?
        // Mine:
        // XFree86 Version 4.3.0.1 (Debian 4.3.0.dfsg.1-1 20040428170728)
        // (X Protocol Version 11, Revision 0, Release 6.6)

        drawLine(gc(),
                 2, height() - 3,
                 width() - 3, 2);
        break;
    case SHADE:

        drawRectangle(gc(), 2, 2, width() - 5 - oddW, 2);

        XPoint points[3];
        if (m_listen_to.isShaded()) {
            points[1].x = (width() / 2) - 3; points[1].y = 7;
            points[2].x = (width() / 2) + 4 - oddW; points[2].y = 7;
            points[0].x = (width() / 2); points[0].y = height() / 2 + 2;
        } else {
            points[0].x = (width() / 2); points[0].y = 6;
            points[1].x = (width() / 2) - 4; points[1].y = height() / 2 + 2;
            points[2].x = (width() / 2) + 4 - oddW; points[2].y = height() / 2 + 2;
        }
        fillPolygon(gc(), points, 3, Convex, CoordModeOrigin);
        break;
    case MENUICON:
        if (m_icon_pixmap.drawable()) {

            if (m_icon_mask.drawable()) {
                XSetClipMask(m_listen_to.fbWindow().display(),
                             gc(), m_icon_mask.drawable());
                XSetClipOrigin(m_listen_to.fbWindow().display(),
                             gc(), 2, 2);
            }

            copyArea(m_icon_pixmap.drawable(),
                     gc(),
                     0, 0,
                     2, 2,
                     m_icon_pixmap.width(), m_icon_pixmap.height());

            if (m_icon_mask.drawable())
                XSetClipMask(m_listen_to.fbWindow().display(), gc(), None);
        } else {
            for (int y = height()/3; y <= height() - height()/3; y+=3) {
                drawLine(gc(), width()/4, y, width() - width()/4 - oddW - 1, y);
            }
            drawRectangle(gc(),
                      2, 2, width() - 5, height() - 5);
        }
        break;
    }
}

void WinButton::clear() {
    FbTk::Button::clear();

    // ensure the m_listen_to has actually a client
    if (m_type == MENUICON && !m_listen_to.empty() && (
        !m_icon_pixmap.drawable() ||
        (m_icon_pixmap.width() != width() - 4 ||
         m_icon_pixmap.height() != height() - 4))) {

        Display* display = m_listen_to.fbWindow().display();
        int screen = m_listen_to.screen().screenNumber();
        XWMHints* hints = XGetWMHints(display, m_listen_to.winClient().window());
        if (hints == 0) {
            m_icon_pixmap.release();
            m_icon_mask.release();
        } else {
            if ((hints->flags & IconPixmapHint) && hints->icon_pixmap != 0) {
                 m_icon_pixmap.copy(hints->icon_pixmap,
                                    DefaultDepth(display, screen), screen);
                 m_icon_pixmap.scale(width() - 4, height() - 4);
            } else
                m_icon_pixmap.release();

            if ((hints->flags & IconMaskHint)) {
                m_icon_mask.copy(hints->icon_mask, 0, 0);
                m_icon_mask.scale(width() - 4, height() - 4);
            } else
                m_icon_mask.release();
        }

        XFree(hints);
    }

    drawType();
}

void WinButton::update(FbTk::Subject *subj) {

    // just checking, if we the app provides a pixmap.
    if (m_type == MENUICON && !m_listen_to.empty()) {
        XWMHints* hints = XGetWMHints(m_listen_to.fbWindow().display(),
                                      m_listen_to.winClient().window());
        if (hints == 0) {
            m_icon_pixmap.release();
            m_icon_mask.release();
        } else {
            if (!((hints->flags & IconPixmapHint) && hints->icon_pixmap != 0))
                m_icon_pixmap.release();

            if (!(hints->flags & IconMaskHint))
                m_icon_mask.release();
        }

        XFree(hints);
    }

    // pressed_pixmap isn't stateful in any current buttons, so no need
    // to potentially override that. Just make sure background pm is ok
    Pixmap my_pm = getBackgroundPixmap();
    if (my_pm != None)
        setBackgroundPixmap(my_pm);

    clear();
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Satoshi");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-beta"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "$Format:%h$"
#    define GIT_COMMIT_DATE "$Format:%cD$"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<commit_msg>Update version.cpp<commit_after>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Satoshi");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-beta-gravity"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "$Format:%h$"
#    define GIT_COMMIT_DATE "$Format:%cD$"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<|endoftext|>


<commit_before>/* Copyright (c) 2014 UCR-UAS
 * You should have recieved a copy of the MIT licence with this file.
 * Engineer: Brandon Lu
 * Description: This is the BISON-Transfer client version 1.
 * This is not a multi-threaded client.
 */

/* ================ Notices ===============
 * You should probably read the server code comments for the most updated
 * information.  The server kind of came first.
 */

// =============== Includes ===============
#include <arpa/inet.h>
#include "BISON-Defaults.h"
#include <boost/filesystem.hpp>
#include "config-check.h"
#include <dirent.h>
#include <errno.h>
#include <exception>
#include <fstream>
#include <map>
#include <netinet/in.h>
#include <openssl/md5.h>
#include "filetable.h"
#include <queue>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "filetable.h"
#include <vector>
#include <yaml-cpp/yaml.h>

typedef enum {FILETABLE, TRANSFER, REALTIME, RECALCULATE_MD5} action_t;

// =========== Global Variables ===========
int sfd;
std::string BISON_TRANSFER_SERVER;
int BISON_TRANSFER_PORT;
std::string BISON_RECIEVE_DIR;
int ERROR_WAIT;
std::queue<std::string> filequeue;
std::queue<std::string> recalc_queue;
std::map<std::string, std::vector<unsigned char>> filetable;
YAML::Node config;

// ============ Configuration ==============
/*
 * The configuration functions for the server and client get very repetetive.
 * But they're darn easy to program in!!! -- Brandon
 *
 */
void configure_client(YAML::Node &config)
{
	try {
		config = YAML::LoadFile(__DEF_CLIENT_CONFIG_PATH__
			+ std::string(__DEF_CLIENT_CONFIG_FILE__));
#if DEBUG
		std::cout << "Successfully opened configuration file." << std::endl;
#endif // DEBUG
	} catch (std::exception& e) {
		std::cerr << e.what() << std::endl;
		std::cerr << "Attempting to configure automatically." << std::endl;
	}

	if (!config["BISON-Transfer"]["Client"]["Server-address"])
		config["BISON-Transfer"]["Client"]["Server-address"]
			= DEF_BISON_TRANSFER_SERVER;
	if (!config["BISON-Transfer"]["Client"]["Port"])
		config["BISON-Transfer"]["Client"]["Port"] = DEF_BISON_TRANSFER_PORT;
	if (!config["BISON-Transfer"]["Client"]["Recieve-Dir"])
		config["BISON-Transfer"]["Client"]["Recieve-Dir"] = DEF_RECIEVE_DIR;
	if (!config["BISON-Transfer"]["Client"]["Error-Wait"])
		config["BISON-Transfer"]["Client"]["Error-Wait"] = DEF_ERROR_WAIT;

	BISON_TRANSFER_SERVER
		= config["BISON-Transfer"]["Client"]["Server-address"]
		.as<std::string>();
	BISON_TRANSFER_PORT = config["BISON-Transfer"]["Client"]["Port"].as<int>();
	BISON_RECIEVE_DIR = config["BISON-Transfer"]["Client"]["Recieve-Dir"]
		.as<std::string>();
	ERROR_WAIT = config["BISON-Transfer"]["Client"]["Error-Wait"].as<int>();

	if (DEBUG) {
		std::cout << "Transfer Address (for binding): "
			<< BISON_TRANSFER_SERVER << std::endl;
		std::cout << "Transfer port: " << BISON_TRANSFER_PORT << std::endl;
	}

#if DEBUG
	std::cout << "Writing config file" << std::endl;
#endif // if DEBUG

	// Write out the configuration before starting
	dirChkCreate(__DEF_CLIENT_CONFIG_PATH__, "configuration");

	writeOutYaml(config, __DEF_CLIENT_CONFIG_PATH__
			+ std::string(__DEF_CLIENT_CONFIG_FILE__));
}

// ======= Nice Termination handler =======
// terminate nicely!
void terminate_nicely(int sig)
{
	close(sfd);
	exit(0);
}

// ===== Not Nice Termination handler =====
void error_terminate(const int status) {
	close(sfd);
	exit(status);
}

// =========== Handle Connection ===========
void handle_connection(action_t &action)
{
#if DEBUG
	printf("Socketing... \n");
#endif // if DEBUG
	sfd = socket(PF_INET, SOCK_STREAM, 0);
	if (sfd == -1) {
		close(sfd);
	}

	// set things for sockaddr_in before connection
	struct sockaddr_in srv_addr;
	memset(&srv_addr, 0, sizeof(struct sockaddr_in));
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_port = htons(BISON_TRANSFER_PORT);
	if (!inet_aton(BISON_TRANSFER_SERVER.c_str(),
		(struct in_addr*) &srv_addr.sin_addr.s_addr)) {
		std::cerr << "Server Address Invalid" << std::endl;
		close(sfd);
		return;
	}

#if DEBUG
	printf("Connecting... \n");
#endif // if DEBUG
	if (connect(sfd, (struct sockaddr*) &srv_addr,
		sizeof(struct sockaddr_in)) == -1) {
		errno = 0;
		close(sfd);
		return;
	}

	if (filequeue.empty()) {
		std::cout << "Filequeue is empty.  Checking for new files."
			<< std::endl;
		action = FILETABLE;
	}

	if (!recalc_queue.empty()) {
		std::cout << "Recalculation queue is not empty. Relaying filenames."
			<< std::endl;
		action = RECALCULATE_MD5;
	}

	switch (action) {
		case TRANSFER:
		{
			// In this case, we transfer over the file that is on top of the--
			// file queue.

			// Man, I really need to implement loglevels -- Brandon
			std::cout << "Front is: " << filequeue.front() << std::endl;

			// Get the filename
			std::string filename(filequeue.front());
			// Remove the very top file
			filequeue.pop();				// remove front member
			// Tell the server exactly what we want.
			dprintf(sfd, "REQ: %s\n\n", filename.c_str());
			// Open the file that we want to put it in.
			FILE *output_file = fopen((BISON_RECIEVE_DIR + filename).c_str(),
				"w");
			// If we couldn't open it for some reason, let the server continue
			if (output_file == 0) {
				std::cerr << "Could not open new file for writing."
					<< std::endl;
				close(sfd);
				return;
			}

			// Write the data into the output file which was opened earlier.
			bool delete_flag = false;
			char buf[MAXBUFLEN + 1];
			int len = 0;
            // file descriptor set for writing to file
            fd_set set;
            FD_SET(sfd, &set);
            struct timeval timeout;
            timeout.tv_sec = 30;
            timeout.tv_usec = 0;
			while(select(sfd+1, &set, NULL, NULL, &timeout) != 0) {
                len = read(sfd, buf, MAXBUFLEN);
                if (len == 0)					// reached end of file
                    break;
				if (len == -1) {				// error condition
					std::cerr << "Error on socket read from client."
						<< strerror(errno) << std::endl;
					errno = 0;
					delete_flag = true;
					break;
				}
				fwrite(buf, sizeof(char), len, output_file);
                timeout.tv_sec = 30;
                timeout.tv_usec = 0;
			}

			// Close the file, of course.
			fclose(output_file);

			// Delete the file if necessary
			if (delete_flag == true) {
				std::cerr << "Deleting error'd file." << std::endl;
			}
		}	break;

		case FILETABLE:
		{
			// Have the server send over a fresh copy of its file queue so --
			// that we know what's going on.

			// Start off by asking ourselves what we have.
            const char *ret;
			ret = update_filetable(BISON_RECIEVE_DIR, filetable);
			// Oh yeah, and if we failed at that... try again.
			if (ret) {
				std::cerr << "Filetable did not update:" << ret << std::endl;
				std::cerr << "Well, the file recieve directory is being made."
					<< std::endl;
				dirChkCreate(BISON_RECIEVE_DIR.c_str(), "recieve");
				close(sfd);
				return;
			}
			// Ask the server for its file table.
			// (What is this?  A date? -- Brandon)
			dprintf(sfd, "FTREQ\n\n");
			std::map<std::string, std::vector<unsigned char>> tmp_filetable;

			// Parse the filetable information.
			// (Hang in there buddy, it's going to take a little work to --
			// make it all work out. -- Brandon)
			md5_parse(sfd, tmp_filetable);

			// If our current filetable is empty, dump it.
			if (!filequeue.empty())
				std::cerr << "Filetable is not empty. Emptying." << std::endl;
			while(!filequeue.empty())
				filequeue.pop();

			// Check for files here that do not exist on our end.
			for (std::map<std::string, std::vector<unsigned char>>::iterator
				it = tmp_filetable.begin(); it != tmp_filetable.end(); it++) {
				std::map<std::string, std::vector<unsigned char>>::iterator
					it2 = filetable.find(it->first);

				// nonexistent file
				if (it2 == filetable.end()) {
					std::cout << "Missing: " << it->first << std::endl;
					filequeue.push(it->first);
					continue;
				}

				// handle incorrect / incomplete files
				if (it2->second != it->second) {
					std::cout << "Corrupt file: " << it->first << std::endl;
					recalc_queue.push(it->first);
					filequeue.push(it->first);
					continue;
				}
			}

			action = TRANSFER;
		}	break;
		case REALTIME:
			// Not implemented yet, I blame the rest of the requirements.
			break;
		case RECALCULATE_MD5:
		{
			// Oh, we're in trouble.  We need to recalculate a faulty MD5 sum.

			// Get the file that we need to recalculate
			std::string filename = recalc_queue.front();
			recalc_queue.pop();

			// Tell the server to recalculate it.
			dprintf(sfd, "RECALC: %s\n\n", filename.c_str());

			// And recalculate it ourselves.
			recalculate_MD5(BISON_RECIEVE_DIR, filename, filetable);
		}	break;
	}
	close(sfd);
}

// ======= Configuration Reloading ========
void configuration_reload(int sig)
{
	configure_client(config);
}

// =========== Signal Handling =============
void signalHandling()
{
	signal (SIGHUP, configuration_reload);
	signal(SIGCHLD, SIG_IGN);				// ignore children for now
	// Handle different ways of program termination
	signal(SIGTERM, terminate_nicely);
	signal(SIGINT, terminate_nicely);

}

// ========== The Main Function ============
int main (int argc, char *argv[])
{
	configure_client(config);

	// PID management is offloaded to initialization daemon

	signalHandling();

	dirChkCreate(BISON_RECIEVE_DIR.c_str(), "recieve");

	printf("Client Starting Up...\n");
	action_t action = FILETABLE;

	while(1) {
		handle_connection(action);
		// Actually time things out after return
		// this runs for one second.
		for (int i = 0; i < ERROR_WAIT; i++)
			usleep(1000);
	}
	return 0;
}
<commit_msg>Debug messages off<commit_after>/* Copyright (c) 2014 UCR-UAS
 * You should have recieved a copy of the MIT licence with this file.
 * Engineer: Brandon Lu
 * Description: This is the BISON-Transfer client version 1.
 * This is not a multi-threaded client.
 */

/* ================ Notices ===============
 * You should probably read the server code comments for the most updated
 * information.  The server kind of came first.
 */

// =============== Includes ===============
#include <arpa/inet.h>
#include "BISON-Defaults.h"
#include <boost/filesystem.hpp>
#include "config-check.h"
#include <dirent.h>
#include <errno.h>
#include <exception>
#include <fstream>
#include <map>
#include <netinet/in.h>
#include <openssl/md5.h>
#include "filetable.h"
#include <queue>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "filetable.h"
#include <vector>
#include <yaml-cpp/yaml.h>

typedef enum {FILETABLE, TRANSFER, REALTIME, RECALCULATE_MD5} action_t;

// =========== Global Variables ===========
int sfd;
std::string BISON_TRANSFER_SERVER;
int BISON_TRANSFER_PORT;
std::string BISON_RECIEVE_DIR;
int ERROR_WAIT;
std::queue<std::string> filequeue;
std::queue<std::string> recalc_queue;
std::map<std::string, std::vector<unsigned char>> filetable;
YAML::Node config;

// ============ Configuration ==============
/*
 * The configuration functions for the server and client get very repetetive.
 * But they're darn easy to program in!!! -- Brandon
 *
 */
void configure_client(YAML::Node &config)
{
	try {
		config = YAML::LoadFile(__DEF_CLIENT_CONFIG_PATH__
			+ std::string(__DEF_CLIENT_CONFIG_FILE__));
#if DEBUG
		std::cout << "Successfully opened configuration file." << std::endl;
#endif // DEBUG
	} catch (std::exception& e) {
		std::cerr << e.what() << std::endl;
		std::cerr << "Attempting to configure automatically." << std::endl;
	}

	if (!config["BISON-Transfer"]["Client"]["Server-address"])
		config["BISON-Transfer"]["Client"]["Server-address"]
			= DEF_BISON_TRANSFER_SERVER;
	if (!config["BISON-Transfer"]["Client"]["Port"])
		config["BISON-Transfer"]["Client"]["Port"] = DEF_BISON_TRANSFER_PORT;
	if (!config["BISON-Transfer"]["Client"]["Recieve-Dir"])
		config["BISON-Transfer"]["Client"]["Recieve-Dir"] = DEF_RECIEVE_DIR;
	if (!config["BISON-Transfer"]["Client"]["Error-Wait"])
		config["BISON-Transfer"]["Client"]["Error-Wait"] = DEF_ERROR_WAIT;

	BISON_TRANSFER_SERVER
		= config["BISON-Transfer"]["Client"]["Server-address"]
		.as<std::string>();
	BISON_TRANSFER_PORT = config["BISON-Transfer"]["Client"]["Port"].as<int>();
	BISON_RECIEVE_DIR = config["BISON-Transfer"]["Client"]["Recieve-Dir"]
		.as<std::string>();
	ERROR_WAIT = config["BISON-Transfer"]["Client"]["Error-Wait"].as<int>();

	if (DEBUG) {
		std::cout << "Transfer Address (for binding): "
			<< BISON_TRANSFER_SERVER << std::endl;
		std::cout << "Transfer port: " << BISON_TRANSFER_PORT << std::endl;
	}

#if DEBUG
	std::cout << "Writing config file" << std::endl;
#endif // if DEBUG

	// Write out the configuration before starting
	dirChkCreate(__DEF_CLIENT_CONFIG_PATH__, "configuration");

	writeOutYaml(config, __DEF_CLIENT_CONFIG_PATH__
			+ std::string(__DEF_CLIENT_CONFIG_FILE__));
}

// ======= Nice Termination handler =======
// terminate nicely!
void terminate_nicely(int sig)
{
	close(sfd);
	exit(0);
}

// ===== Not Nice Termination handler =====
void error_terminate(const int status) {
	close(sfd);
	exit(status);
}

// =========== Handle Connection ===========
void handle_connection(action_t &action)
{
#if DEBUG
	// printf("Socketing... \n");
#endif // if DEBUG
	sfd = socket(PF_INET, SOCK_STREAM, 0);
	if (sfd == -1) {
		close(sfd);
	}

	// set things for sockaddr_in before connection
	struct sockaddr_in srv_addr;
	memset(&srv_addr, 0, sizeof(struct sockaddr_in));
	srv_addr.sin_family = AF_INET;
	srv_addr.sin_port = htons(BISON_TRANSFER_PORT);
	if (!inet_aton(BISON_TRANSFER_SERVER.c_str(),
		(struct in_addr*) &srv_addr.sin_addr.s_addr)) {
		std::cerr << "Server Address Invalid" << std::endl;
		close(sfd);
		return;
	}

#if DEBUG
	// printf("Connecting... \n");
#endif // if DEBUG
	if (connect(sfd, (struct sockaddr*) &srv_addr,
		sizeof(struct sockaddr_in)) == -1) {
		errno = 0;
		close(sfd);
		return;
	}

	if (filequeue.empty()) {
		std::cout << "Filequeue is empty.  Checking for new files."
			<< std::endl;
		action = FILETABLE;
	}

	if (!recalc_queue.empty()) {
		std::cout << "Recalculation queue is not empty. Relaying filenames."
			<< std::endl;
		action = RECALCULATE_MD5;
	}

	switch (action) {
		case TRANSFER:
		{
			// In this case, we transfer over the file that is on top of the--
			// file queue.

			// Man, I really need to implement loglevels -- Brandon
			std::cout << "Front is: " << filequeue.front() << std::endl;

			// Get the filename
			std::string filename(filequeue.front());
			// Remove the very top file
			filequeue.pop();				// remove front member
			// Tell the server exactly what we want.
			dprintf(sfd, "REQ: %s\n\n", filename.c_str());
			// Open the file that we want to put it in.
			FILE *output_file = fopen((BISON_RECIEVE_DIR + filename).c_str(),
				"w");
			// If we couldn't open it for some reason, let the server continue
			if (output_file == 0) {
				std::cerr << "Could not open new file for writing."
					<< std::endl;
				close(sfd);
				return;
			}

			// Write the data into the output file which was opened earlier.
			bool delete_flag = false;
			char buf[MAXBUFLEN + 1];
			int len = 0;
            // file descriptor set for writing to file
            fd_set set;
            FD_SET(sfd, &set);
            struct timeval timeout;
            timeout.tv_sec = 30;
            timeout.tv_usec = 0;
			while(select(sfd+1, &set, NULL, NULL, &timeout) != 0) {
                len = read(sfd, buf, MAXBUFLEN);
                if (len == 0)					// reached end of file
                    break;
				if (len == -1) {				// error condition
					std::cerr << "Error on socket read from client."
						<< strerror(errno) << std::endl;
					errno = 0;
					delete_flag = true;
					break;
				}
				fwrite(buf, sizeof(char), len, output_file);
                timeout.tv_sec = 30;
                timeout.tv_usec = 0;
			}

			// Close the file, of course.
			fclose(output_file);

			// Delete the file if necessary
			if (delete_flag == true) {
				std::cerr << "Deleting error'd file." << std::endl;
			}
		}	break;

		case FILETABLE:
		{
			// Have the server send over a fresh copy of its file queue so --
			// that we know what's going on.

			// Start off by asking ourselves what we have.
            const char *ret;
			ret = update_filetable(BISON_RECIEVE_DIR, filetable);
			// Oh yeah, and if we failed at that... try again.
			if (ret) {
				std::cerr << "Filetable did not update:" << ret << std::endl;
				std::cerr << "Well, the file recieve directory is being made."
					<< std::endl;
				dirChkCreate(BISON_RECIEVE_DIR.c_str(), "recieve");
				close(sfd);
				return;
			}
			// Ask the server for its file table.
			// (What is this?  A date? -- Brandon)
			dprintf(sfd, "FTREQ\n\n");
			std::map<std::string, std::vector<unsigned char>> tmp_filetable;

			// Parse the filetable information.
			// (Hang in there buddy, it's going to take a little work to --
			// make it all work out. -- Brandon)
			md5_parse(sfd, tmp_filetable);

			// If our current filetable is empty, dump it.
			if (!filequeue.empty())
				std::cerr << "Filetable is not empty. Emptying." << std::endl;
			while(!filequeue.empty())
				filequeue.pop();

			// Check for files here that do not exist on our end.
			for (std::map<std::string, std::vector<unsigned char>>::iterator
				it = tmp_filetable.begin(); it != tmp_filetable.end(); it++) {
				std::map<std::string, std::vector<unsigned char>>::iterator
					it2 = filetable.find(it->first);

				// nonexistent file
				if (it2 == filetable.end()) {
					std::cout << "Missing: " << it->first << std::endl;
					filequeue.push(it->first);
					continue;
				}

				// handle incorrect / incomplete files
				if (it2->second != it->second) {
					std::cout << "Corrupt file: " << it->first << std::endl;
					recalc_queue.push(it->first);
					filequeue.push(it->first);
					continue;
				}
			}

			action = TRANSFER;
		}	break;
		case REALTIME:
			// Not implemented yet, I blame the rest of the requirements.
			break;
		case RECALCULATE_MD5:
		{
			// Oh, we're in trouble.  We need to recalculate a faulty MD5 sum.

			// Get the file that we need to recalculate
			std::string filename = recalc_queue.front();
			recalc_queue.pop();

			// Tell the server to recalculate it.
			dprintf(sfd, "RECALC: %s\n\n", filename.c_str());

			// And recalculate it ourselves.
			recalculate_MD5(BISON_RECIEVE_DIR, filename, filetable);
		}	break;
	}
	close(sfd);
}

// ======= Configuration Reloading ========
void configuration_reload(int sig)
{
	configure_client(config);
}

// =========== Signal Handling =============
void signalHandling()
{
	signal (SIGHUP, configuration_reload);
	signal(SIGCHLD, SIG_IGN);				// ignore children for now
	// Handle different ways of program termination
	signal(SIGTERM, terminate_nicely);
	signal(SIGINT, terminate_nicely);

}

// ========== The Main Function ============
int main (int argc, char *argv[])
{
	configure_client(config);

	// PID management is offloaded to initialization daemon

	signalHandling();

	dirChkCreate(BISON_RECIEVE_DIR.c_str(), "recieve");

	printf("Client Starting Up...\n");
	action_t action = FILETABLE;

	while(1) {
		handle_connection(action);
		// Actually time things out after return
		// this runs for one second.
		for (int i = 0; i < ERROR_WAIT; i++)
			usleep(1000);
	}
	return 0;
}
<|endoftext|>


<commit_before>/**********************************************************************/
/* Copyright 2014 RCF                                                 */
/*                                                                    */
/* Licensed under the Apache License, Version 2.0 (the "License");    */
/* you may not use this file except in compliance with the License.   */
/* You may obtain a copy of the License at                            */
/*                                                                    */
/*     http://www.apache.org/licenses/LICENSE-2.0                     */
/*                                                                    */
/* Unless required by applicable law or agreed to in writing,         */
/* software distributed under the License is distributed on an        */
/* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,       */
/* either express or implied.                                         */
/* See the License for the specific language governing permissions    */
/* and limitations under the License.                                 */
/**********************************************************************/

// Internal libraries
#include "Ctrl.hpp"
#include "Stk.hpp"
#include "Arit.hpp"
using namespace vm;

void vm::ctrl(const RVM& rvm, const Command& cmd)
{
    switch(cmd.cmd)
    {
        // Stack functions
        case Command::Opcode::PUSH: vm::PUSH (rvm, cmd.arg); break;
        case Command::Opcode::POP:  vm::POP  (rvm);          break;
        case Command::Opcode::SWAP: vm::SWAP (rvm);          break;
        case Command::Opcode::DUP:  vm::DUP  (rvm);          break;

        // Arithmetic functions
        case Command::Opcode::ADD:  vm::ADD  (rvm);          break;
        case Command::Opcode::SUB:  vm::SUB  (rvm);          break;
        case Command::Opcode::DIV:  vm::DIV  (rvm);          break;
        case Command::Opcode::MUL:  vm::MUL  (rvm);          break;
        case Command::Opcode::MOD:  vm::MOD  (rvm);          break;

        // Control functions
        case Command::Opcode::END:
            break;
        default:
            break;
    }
}
<commit_msg>Adding new asm functions (Jumps needing corrections)<commit_after>/**********************************************************************/
/* Copyright 2014 RCF                                                 */
/*                                                                    */
/* Licensed under the Apache License, Version 2.0 (the "License");    */
/* you may not use this file except in compliance with the License.   */
/* You may obtain a copy of the License at                            */
/*                                                                    */
/*     http://www.apache.org/licenses/LICENSE-2.0                     */
/*                                                                    */
/* Unless required by applicable law or agreed to in writing,         */
/* software distributed under the License is distributed on an        */
/* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,       */
/* either express or implied.                                         */
/* See the License for the specific language governing permissions    */
/* and limitations under the License.                                 */
/**********************************************************************/

// Internal libraries
#include "Asm.hpp"
#include "Ctrl.hpp"
using namespace vm;

void vm::ctrl(const RVM& rvm, const Command& cmd)
{
    switch(cmd.cmd)
    {
        // Stack functions
        case Command::Opcode::PUSH: vm::Asm::PUSH (rvm, cmd.arg); break;
        case Command::Opcode::POP:  vm::Asm::POP  (rvm);          break;
        case Command::Opcode::SWAP: vm::Asm::SWAP (rvm);          break;
        case Command::Opcode::DUP:  vm::Asm::DUP  (rvm);          break;

        // Arithmetic functions
        case Command::Opcode::ADD:  vm::Asm::ADD  (rvm);          break;
        case Command::Opcode::SUB:  vm::Asm::SUB  (rvm);          break;
        case Command::Opcode::DIV:  vm::Asm::DIV  (rvm);          break;
        case Command::Opcode::MUL:  vm::Asm::MUL  (rvm);          break;
        case Command::Opcode::MOD:  vm::Asm::MOD  (rvm);          break;

        // Memory functions
        case Command::Opcode::STO:  vm::Asm::STO  (rvm, cmd.arg); break;
        case Command::Opcode::RCL:  vm::Asm::RCL  (rvm, cmd.arg); break;

        // IO functions
        case Command::Opcode::PRN:  vm::Asm::PRN  (rvm);          break;

        // Comparison functions
        case Command::Opcode::EQ:   vm::Asm::EQ   (rvm);          break;
        case Command::Opcode::NE:   vm::Asm::NE   (rvm);          break;
        case Command::Opcode::GT:   vm::Asm::GT   (rvm);          break;
        case Command::Opcode::GE:   vm::Asm::GE   (rvm);          break;
        case Command::Opcode::LT:   vm::Asm::LT   (rvm);          break;
        case Command::Opcode::LE:   vm::Asm::LE   (rvm);          break;

        // Jump functions
        case Command::Opcode::JMP:  vm::Asm::JMP  (rvm, cmd.arg); break;
        case Command::Opcode::JIT:  vm::Asm::JIT  (rvm, cmd.arg); break;
        case Command::Opcode::JIF:  vm::Asm::JIF  (rvm, cmd.arg); break;

        // Control functions
        case Command::Opcode::END: break;

        default:
            break;
    }
}
<|endoftext|>