<commit_before>#include <iostream>
#include <math.h>
#include "detector.h"
#include "toolbox.h"
#include "io.h"
using namespace std;
using namespace arma;
using namespace detector;
using namespace toolbox;

double CDetector::d; 				// (m) detector distance
double CDetector::pix_width;		// (m)
double CDetector::pix_height;		// (m)
int CDetector::px;					// number of pixels in x
int CDetector::py;					// number of pixels in y
int CDetector::numPix;				// total number of pixels (px*py)
double CDetector::cx;				// center of detector in x
double CDetector::cy;				// center of detector in y
fmat CDetector::dp;					// diffraction pattern
fmat CDetector::q_x;				// pixel reciprocal space in x
fmat CDetector::q_y;				// pixel reciprocal space in y
fmat CDetector::q_z;				// pixel reciprocal space in z
fcube CDetector::q_xyz; // slow? perhaps waste of memory
fmat CDetector::q_mod;				// pixel reciprocal space
fmat CDetector::pixSpace;			// pixel reciprocal space in Angstrom
float CDetector::pixSpaceMax;		// max pixel reciprocal space in Angstrom
fmat CDetector::solidAngle;			// solid angle
fmat CDetector::thomson;			// Thomson scattering
uvec CDetector::badpixmap;			// bad pixel map (bad = 1)
uvec CDetector::goodpixmap;			// good pixel map (good = 1)

CDetector::CDetector (){
    d = 0;
    pix_width = 0;
    pix_height = 0;
    px = 0;
    py = 0;
    numPix = 0;
    cx = 0;
    cy = 0;
}

void CDetector::set_detector_dist(double dist){
	d = dist;
}

double CDetector::get_detector_dist(){
	return d;
}

void CDetector::set_pix_width(double width){
	pix_width = width;
}

double CDetector::get_pix_width(){
	return pix_width;
}

void CDetector::set_pix_height(double height){
	pix_height = height;
}

double CDetector::get_pix_height(){
	return pix_height;
}

void CDetector::set_numPix_x(int x){
	px = x;
}

int CDetector::get_numPix_x(){
	return px;
}

void CDetector::set_numPix_y(int y){
	py = y;
}

void CDetector::set_numPix(int y,int x){
	py = y;
	px = x;
	numPix = py*px;
}

int CDetector::get_numPix_y(){
	return py;
}

void CDetector::set_center_x(double x){
	cx = x;
}

double CDetector::get_center_x(){
	return cx;
}

void CDetector::set_center_y(double y){
	cy = y;
}

double CDetector::get_center_y(){
	return cy;
}

uvec CDetector::get_goodPixelMap(){
    return goodpixmap;
}

uvec CDetector::get_badPixelMap(){
    return badpixmap;
}

void CDetector::set_pixelMap(string badpixelmap){
	fmat temp;
	if (badpixelmap.empty()) { // badpixelmap is not specified
		if (py > 0 && px > 0) {
			temp.zeros(py,px);
		} else {
			cout << "Please set detector dimensions before calling set_pixelMap" << endl;
			exit(0);
		}
	} else { // load badpixelmap
		temp = load_asciiImage(badpixelmap);
	}
	badpixmap = find(temp == 1);
	goodpixmap = find(temp == 0);
}

void CDetector::apply_badPixels() {
    uvec::iterator a = badpixmap.begin();
    uvec::iterator b = badpixmap.end();
    for(uvec::iterator i=a; i!=b; ++i) {
        dp(*i) = 0;
    }
}

void CDetector::apply_badPixels(fmat *x) {
	fmat& myDP = x[0];
    uvec::iterator a = badpixmap.begin();
    uvec::iterator b = badpixmap.end();
    for(uvec::iterator i=a; i!=b; ++i) {
        myDP(*i) = 0;
    }
}

// set beam object variables and assign q to each pixel
void CDetector::init_dp( beam::CBeam *beam ){
    // this bit should be set already, get rid of this?
	set_detector_dist(d);
	set_pix_width(pix_width);
	set_pix_height(pix_height);
	set_numPix(py,px);
	set_center_x(cx);
	set_center_y(cy);

	// Used for single particle. Set 1/pix_width=9090 for LCLS
	q_xyz.zeros(py,px,3);
	float rx, ry, r, twotheta, az;
	float pixDist, alpha;
	solidAngle.zeros(py,px);
	fmat twoTheta(py,px);
	for (int ind_x = 0; ind_x < px; ind_x++) {
		for (int ind_y = 0; ind_y < py; ind_y++) {
			rx = (ind_x - cx) * pix_width; // equivalent to dividing by pixel resolution
			ry = (ind_y - cy) * pix_width;
			r = sqrt(pow(rx,2)+pow(ry,2));
			twotheta = atan2(r,d);
			twoTheta(ind_y,ind_x) = twotheta;
			az = atan2(ry,rx);
			q_xyz(ind_y,ind_x,0) = beam->get_wavenumber() * sin(twotheta)*cos(az);
			q_xyz(ind_y,ind_x,1) = beam->get_wavenumber() * sin(twotheta)*sin(az);
			q_xyz(ind_y,ind_x,2) = beam->get_wavenumber() * (cos(twotheta) - 1.0);

			// Analytical formula of solid angle (Zaluzec2014)
			pixDist = sqrt(pow(rx,2) + pow(ry,2) + pow(d,2)); // distance from interaction to pixel center in real space
			alpha = atan(pix_width/(2*pixDist));
			solidAngle(ind_y,ind_x) = 4 * asin( pow(sin(alpha),2) );
		}
	}
	q_mod = CToolbox::mag(q_xyz);

	double const re = 2.81793870e-15;			// classical electron radius (m)
	// Polarization factor, cos^2 mu + sin^2 mu * cos^2(2theta)
	double mu; // polarization angle
	string electricFieldPlane = "horizontal";
	if (electricFieldPlane == "horizontal") {
		mu = 0;
	} else if (electricFieldPlane == "vertical") {
		mu = datum::pi/2;
	} else {
		// unpolarized
		mu = datum::pi/4;
	}
	fmat polarizationFactor = ( pow(cos(mu),2) + pow(sin(mu),2)*pow(cos(twoTheta),2) );
	thomson = pow(re,2) * polarizationFactor;

	// Setup pixel space
	int counter = 0;
	pixSpace.zeros(numPix,3);
	for (int i = 0; i < px; i++) {
		for (int j = 0; j < py; j++) { // column-wise
			pixSpace(counter,0) = q_xyz(j,i,0);
			pixSpace(counter,1) = q_xyz(j,i,1);
			pixSpace(counter,2) = q_xyz(j,i,2);
			counter++;
		}
	}
    fvec pix_mod;
	pixSpace = pixSpace * 1e-10; // (A)
	pix_mod = sqrt(sum(pixSpace%pixSpace,1));
	pixSpaceMax = max(pix_mod);
    float inc_res = (px-1)/(2*pixSpaceMax/sqrt(2));
    pixSpace = pixSpace * inc_res;
    pix_mod = sqrt(sum(pixSpace%pixSpace,1));
	pixSpaceMax = cx; // FIXME: something fishy going on here
}

void CDetector::set_param(Packet *x){
	umat temp(x->dp, x->py, x->px, false, true);
	dp = conv_to<fmat>::from(trans(temp));
	d = x->d;
	pix_width = x->pix_width;
	pix_height = x->pix_height;
	py = x->py;
	px = x->px;
	cx = ((double) px-1)/2;			// this can be user defined
	cy = ((double) py-1)/2;			// this can be user defined
}

void CDetector::readGeomFile(string geomFile) {
	/****** Detector ******/
	// Parse the geom file
	string line;
	ifstream myGeomFile(geomFile.c_str());
	while (getline(myGeomFile, line)) {
		if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
			// line now contains a valid input
	        typedef boost::tokenizer<boost::char_separator<char> > Tok;
	        boost::char_separator<char> sep(" ="); // default constructed
	        Tok tok(line, sep);
	        for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
	            if ( boost::algorithm::iequals(*tok_iter,"geom/d") ) {
	                string temp = *++tok_iter;
	                d = atof(temp.c_str());
	                break;
	            } else if ( boost::algorithm::iequals(*tok_iter,"geom/pix_width") ) {
	                string temp = *++tok_iter;
	                pix_width = atof(temp.c_str());
	                pix_height = pix_width;
	                break;
	            } else if ( boost::algorithm::iequals(*tok_iter,"geom/px") ) {
	                string temp = *++tok_iter;
	                px = atof(temp.c_str());
	                py = px;
	                set_numPix(py,px);
	                cx = ((double) px-1)/2;
	                cy = ((double) py-1)/2;
	                break;
	            } else if ( boost::algorithm::iequals(*tok_iter,"geom/badpixmap") ) {
	                string temp = *++tok_iter;
	                string badpixmap = temp;
	                set_pixelMap(badpixmap);
	                break;
	            }
	        }
	    }
	}
}

#ifdef COMPILE_WITH_BOOST
	#include <boost/python.hpp>
	using namespace boost::python;
	using namespace detector;
	using namespace arma;

	BOOST_PYTHON_MODULE(libdetector)
	{
		class_<CDetector>("CDetector", init<>())	// constructor
			//.def_readwrite("name", &CToolbox::name)
			.add_property("value", &CDetector::set_numPix_x, &CDetector::get_numPix_x)
		;
	}
#endif
<commit_msg>beam init_dp cleanup<commit_after>#include <iostream>
#include <math.h>
#include "detector.h"
#include "toolbox.h"
#include "io.h"
using namespace std;
using namespace arma;
using namespace detector;
using namespace toolbox;

double CDetector::d; 				// (m) detector distance
double CDetector::pix_width;		// (m)
double CDetector::pix_height;		// (m)
int CDetector::px;					// number of pixels in x
int CDetector::py;					// number of pixels in y
int CDetector::numPix;				// total number of pixels (px*py)
double CDetector::cx;				// center of detector in x
double CDetector::cy;				// center of detector in y
fmat CDetector::dp;					// diffraction pattern
fmat CDetector::q_x;				// pixel reciprocal space in x
fmat CDetector::q_y;				// pixel reciprocal space in y
fmat CDetector::q_z;				// pixel reciprocal space in z
fcube CDetector::q_xyz; // slow? perhaps waste of memory
fmat CDetector::q_mod;				// pixel reciprocal space
fmat CDetector::pixSpace;			// pixel reciprocal space in Angstrom
float CDetector::pixSpaceMax;		// max pixel reciprocal space in Angstrom
fmat CDetector::solidAngle;			// solid angle
fmat CDetector::thomson;			// Thomson scattering
uvec CDetector::badpixmap;			// bad pixel map (bad = 1)
uvec CDetector::goodpixmap;			// good pixel map (good = 1)

CDetector::CDetector (){
    d = 0;
    pix_width = 0;
    pix_height = 0;
    px = 0;
    py = 0;
    numPix = 0;
    cx = 0;
    cy = 0;
}

void CDetector::set_detector_dist(double dist){
	d = dist;
}

double CDetector::get_detector_dist(){
	return d;
}

void CDetector::set_pix_width(double width){
	pix_width = width;
}

double CDetector::get_pix_width(){
	return pix_width;
}

void CDetector::set_pix_height(double height){
	pix_height = height;
}

double CDetector::get_pix_height(){
	return pix_height;
}

void CDetector::set_numPix_x(int x){
	px = x;
}

int CDetector::get_numPix_x(){
	return px;
}

void CDetector::set_numPix_y(int y){
	py = y;
}

void CDetector::set_numPix(int y,int x){
	py = y;
	px = x;
	numPix = py*px;
}

int CDetector::get_numPix_y(){
	return py;
}

void CDetector::set_center_x(double x){
	cx = x;
}

double CDetector::get_center_x(){
	return cx;
}

void CDetector::set_center_y(double y){
	cy = y;
}

double CDetector::get_center_y(){
	return cy;
}

uvec CDetector::get_goodPixelMap(){
    return goodpixmap;
}

uvec CDetector::get_badPixelMap(){
    return badpixmap;
}

void CDetector::set_pixelMap(string badpixelmap){
	fmat temp;
	if (badpixelmap.empty()) { // badpixelmap is not specified
		if (py > 0 && px > 0) {
			temp.zeros(py,px);
		} else {
			cout << "Please set detector dimensions before calling set_pixelMap" << endl;
			exit(0);
		}
	} else { // load badpixelmap
		temp = load_asciiImage(badpixelmap);
	}
	badpixmap = find(temp == 1);
	goodpixmap = find(temp == 0);
}

void CDetector::apply_badPixels() {
    uvec::iterator a = badpixmap.begin();
    uvec::iterator b = badpixmap.end();
    for(uvec::iterator i=a; i!=b; ++i) {
        dp(*i) = 0;
    }
}

void CDetector::apply_badPixels(fmat *x) {
	fmat& myDP = x[0];
    uvec::iterator a = badpixmap.begin();
    uvec::iterator b = badpixmap.end();
    for(uvec::iterator i=a; i!=b; ++i) {
        myDP(*i) = 0;
    }
}

// set beam object variables and assign q to each pixel
void CDetector::init_dp( beam::CBeam *beam ){
    // this bit should be set already, get rid of this?
	set_detector_dist(d);
	set_pix_width(pix_width);
	set_pix_height(pix_height);
	set_numPix(py,px);
	set_center_x(cx);
	set_center_y(cy);

	// Used for single particle. Set 1/pix_width=9090 for LCLS
	q_xyz.zeros(py,px,3);
	float rx, ry, r, twotheta, az;
	float pixDist, alpha;
	float ss;
	solidAngle.zeros(py,px);
	fmat twoTheta(py,px);
	for (int ind_x = 0; ind_x < px; ind_x++) {
		for (int ind_y = 0; ind_y < py; ind_y++) {
			rx = (ind_x - cx) * pix_width; // equivalent to dividing by pixel resolution
			ry = (ind_y - cy) * pix_width;
			r = sqrt(pow(rx,2)+pow(ry,2));
			pixDist = sqrt(pow(r,2) + pow(d,2)); // distance from interaction to pixel center in real space
			twotheta = atan2(r,d);
			twoTheta(ind_y,ind_x) = twotheta;
			//az = atan2(ry,rx);
			//q_xyz(ind_y,ind_x,0) = beam->get_wavenumber() * sin(twotheta)*cos(az);
			q_xyz(ind_y,ind_x,0) = beam->get_wavenumber() * rx/pixDist;
			//q_xyz(ind_y,ind_x,1) = beam->get_wavenumber() * sin(twotheta)*sin(az);
			q_xyz(ind_y,ind_x,1) = beam->get_wavenumber() * ry/pixDist;
			//q_xyz(ind_y,ind_x,2) = beam->get_wavenumber() * (cos(twotheta) - 1.0);
			q_xyz(ind_y,ind_x,2) = beam->get_wavenumber() * ((d - pixDist)/pixDist);
			// Analytical formula of solid angle (Zaluzec2014)
			ss = pix_width*pix_width/(4*pixDist*pixDist + pix_width*pix_width);
			solidAngle(ind_y,ind_x) = 4*asin(ss);

		}
	}
	q_mod = CToolbox::mag(q_xyz);

	double const re = 2.81793870e-15;			// classical electron radius (m)
	// Polarization factor, cos^2 mu + sin^2 mu * cos^2(2theta)
	double mu; // polarization angle
	string electricFieldPlane = "horizontal";
	if (electricFieldPlane == "horizontal") {
		mu = 0;
	} else if (electricFieldPlane == "vertical") {
		mu = datum::pi/2;
	} else {
		// unpolarized
		mu = datum::pi/4;
	}
	fmat polarizationFactor = ( pow(cos(mu),2) + pow(sin(mu),2)*pow(cos(twoTheta),2) );
	thomson = pow(re,2) * polarizationFactor;

	// Setup pixel space
	int counter = 0;
	pixSpace.zeros(numPix,3);
	for (int i = 0; i < px; i++) {
		for (int j = 0; j < py; j++) { // column-wise
			pixSpace(counter,0) = q_xyz(j,i,0);
			pixSpace(counter,1) = q_xyz(j,i,1);
			pixSpace(counter,2) = q_xyz(j,i,2);
			counter++;
		}
	}
    fvec pix_mod;
	pixSpace = pixSpace * 1e-10; // (A)
	pix_mod = sqrt(sum(pixSpace%pixSpace,1));
	pixSpaceMax = max(pix_mod);
    float inc_res = (px-1)/(2*pixSpaceMax/sqrt(2));
    pixSpace = pixSpace * inc_res;
    pix_mod = sqrt(sum(pixSpace%pixSpace,1));
	pixSpaceMax = cx; // FIXME: something fishy going on here
}

void CDetector::set_param(Packet *x){
	umat temp(x->dp, x->py, x->px, false, true);
	dp = conv_to<fmat>::from(trans(temp));
	d = x->d;
	pix_width = x->pix_width;
	pix_height = x->pix_height;
	py = x->py;
	px = x->px;
	cx = ((double) px-1)/2;			// this can be user defined
	cy = ((double) py-1)/2;			// this can be user defined
}

void CDetector::readGeomFile(string geomFile) {
	/****** Detector ******/
	// Parse the geom file
	string line;
	ifstream myGeomFile(geomFile.c_str());
	while (getline(myGeomFile, line)) {
		if (line.compare(0,1,"#") && line.compare(0,1,";") && line.length() > 0) {
			// line now contains a valid input
	        typedef boost::tokenizer<boost::char_separator<char> > Tok;
	        boost::char_separator<char> sep(" ="); // default constructed
	        Tok tok(line, sep);
	        for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter){
	            if ( boost::algorithm::iequals(*tok_iter,"geom/d") ) {
	                string temp = *++tok_iter;
	                d = atof(temp.c_str());
	                break;
	            } else if ( boost::algorithm::iequals(*tok_iter,"geom/pix_width") ) {
	                string temp = *++tok_iter;
	                pix_width = atof(temp.c_str());
	                pix_height = pix_width;
	                break;
	            } else if ( boost::algorithm::iequals(*tok_iter,"geom/px") ) {
	                string temp = *++tok_iter;
	                px = atof(temp.c_str());
	                py = px;
	                set_numPix(py,px);
	                cx = ((double) px-1)/2;
	                cy = ((double) py-1)/2;
	                break;
	            } else if ( boost::algorithm::iequals(*tok_iter,"geom/badpixmap") ) {
	                string temp = *++tok_iter;
	                string badpixmap = temp;
	                set_pixelMap(badpixmap);
	                break;
	            }
	        }
	    }
	}
}

#ifdef COMPILE_WITH_BOOST
	#include <boost/python.hpp>
	using namespace boost::python;
	using namespace detector;
	using namespace arma;

	BOOST_PYTHON_MODULE(libdetector)
	{
		class_<CDetector>("CDetector", init<>())	// constructor
			//.def_readwrite("name", &CToolbox::name)
			.add_property("value", &CDetector::set_numPix_x, &CDetector::get_numPix_x)
		;
	}
#endif
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	BMP280 デジタル圧力センサー・ドライバー @n
			Bosch Sensotec / Digital Pressure Sensor @n
			https://www.bosch-sensortec.com/bst/products/all_products/bmp280 @n
			Copyright 2016 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include <cmath>
#include "common/iica_io.hpp"
#include "common/delay.hpp"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  BMP280 テンプレートクラス
		@param[in]	I2C_IO	i2c I/O クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class I2C_IO>
	class BMP280 {

		// R/W ビットを含まない７ビット値
		// ※ SDO:L ---> 0x76, SDO:H ---> 0x77
		static const uint8_t BMP280_ADR_ = 0x77;

		I2C_IO& i2c_;

		uint8_t	addr_;

		enum class REG : uint8_t {
      		DIG_T1        = 0x88,
      		DIG_T2        = 0x8A,
      		DIG_T3        = 0x8C,

      		DIG_P1        = 0x8E,
      		DIG_P2        = 0x90,
      		DIG_P3        = 0x92,
      		DIG_P4        = 0x94,
      		DIG_P5        = 0x96,
      		DIG_P6        = 0x98,
      		DIG_P7        = 0x9A,
      		DIG_P8        = 0x9C,
      		DIG_P9        = 0x9E,

      		CHIPID        = 0xD0,
      		VERSION       = 0xD1,
      		SOFTRESET     = 0xE0,

      		CAL26         = 0xE1,  // R calibration stored in 0xE1-0xF0

      		CONTROL       = 0xF4,
      		CONFIG        = 0xF5,
      		PRESSUREDATA  = 0xF7,
      		TEMPDATA      = 0xFA,
			HUMIDDATA     = 0xFD,
		};

    	struct calib_t {
			uint16_t	dig_T1;
			int16_t		dig_T2;
			int16_t		dig_T3;

			uint16_t	dig_P1;
			int16_t		dig_P2;
			int16_t		dig_P3;
			int16_t		dig_P4;
			int16_t		dig_P5;
			int16_t		dig_P6;
			int16_t		dig_P7;
			int16_t		dig_P8;
			int16_t		dig_P9;

			uint8_t		dig_H1;
			int16_t		dig_H2;
			uint8_t		dig_H3;
			int16_t		dig_H4;
			int16_t		dig_H5;
			int8_t		dig_H6;
		};

		calib_t		calib_;

		int32_t		t_fine_;

		uint8_t read8_(REG adr) {
			uint8_t reg[1];
			reg[0] = static_cast<uint8_t>(adr);
			i2c_.send(addr_, reg, 1);
			i2c_.recv(addr_, reg, 1);
			return reg[0];
		}

		uint16_t read16_(REG adr) {
			uint8_t reg[2];
			reg[0] = static_cast<uint8_t>(adr);
			i2c_.send(addr_, reg, 1);
			i2c_.recv(addr_, reg, 2);
			return (reg[0] << 8) | reg[1];
		}

		uint32_t read24_(REG adr) {
			uint8_t reg[3];
			reg[0] = static_cast<uint8_t>(adr);
			i2c_.send(addr_, reg, 1);
			i2c_.recv(addr_, reg, 3);
			return (static_cast<uint32_t>(reg[0]) << 16) | (static_cast<uint32_t>(reg[1]) << 8) | reg[2];
		}

		uint16_t read16le_(REG adr) {
			uint8_t reg[2];
			reg[0] = static_cast<uint8_t>(adr);
			i2c_.send(addr_, reg, 1);
			i2c_.recv(addr_, reg, 2);
			return (reg[1] << 8) | reg[0];
		}

		void write8_(REG a, uint8_t data) {
			uint8_t reg[2];
			reg[0] = static_cast<uint8_t>(a);
			reg[1] = data;
			i2c_.send(addr_, reg, 2);
		}

		void get_coefficients_() {
			calib_.dig_T1 = read16le_(REG::DIG_T1);
			calib_.dig_T2 = read16le_(REG::DIG_T2);
			calib_.dig_T3 = read16le_(REG::DIG_T3);

			calib_.dig_P1 = read16le_(REG::DIG_P1);
			calib_.dig_P2 = read16le_(REG::DIG_P2);
			calib_.dig_P3 = read16le_(REG::DIG_P3);
			calib_.dig_P4 = read16le_(REG::DIG_P4);
			calib_.dig_P5 = read16le_(REG::DIG_P5);
			calib_.dig_P6 = read16le_(REG::DIG_P6);
			calib_.dig_P7 = read16le_(REG::DIG_P7);
			calib_.dig_P8 = read16le_(REG::DIG_P8);
			calib_.dig_P9 = read16le_(REG::DIG_P9);
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	i2c	iica_io クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		BMP280(I2C_IO& i2c) : i2c_(i2c), addr_(0), calib_(), t_fine_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	開始
			@param[in]	addr	オプションの I2C アドレス @n
								※ SDO:L ---> 0x76, SDO:H ---> 0x77 (default)
			@return エラーなら「false」を返す
		 */
		//-----------------------------------------------------------------//
		bool start(uint8_t addr = BMP280_ADR_)
		{
			addr_ = addr;

			if(read8_(REG::CHIPID) != 0x58) {  // チップＩＤの確認
				addr_ = 0;
				return false;
			}

			get_coefficients_();  // 補正データ取得

			// Ex: Ultra high resolution
			// setting control
			// osrs_t(X2): 010, osrs_p(X16): 101, mode(Normal): 11
			uint8_t mode = 0b01000000 | 0b00010100 | 0b00000011;
			write8_(REG::CONTROL, mode);

			// setting config
			// t_sb(0.5ms): 000, filter(16): 100, xxx(0): 0, spi3w_en(0): 0
			uint8_t conf = 0b00000000 | 0b00010000 | 0b00000000 | 0b00000000;
			write8_(REG::CONFIG, conf);

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	温度を返す（℃ * 100）
			@return 温度
		 */
		//-----------------------------------------------------------------//
		int32_t get_temperature()
		{
			if(addr_ == 0) return 0;

			int32_t adc_T = read24_(REG::TEMPDATA);
			adc_T >>= 4;

  			int32_t var1  = ((((adc_T>>3) - (static_cast<int32_t>(calib_.dig_T1) << 1))) *
				(static_cast<int32_t>(calib_.dig_T2))) >> 11;

			int32_t var2  = (((((adc_T>>4) - (static_cast<int32_t>(calib_.dig_T1))) *
				((adc_T>>4) - (static_cast<int32_t>(calib_.dig_T1)))) >> 12) *
				(static_cast<int32_t>(calib_.dig_T3))) >> 14;

			t_fine_ = var1 + var2;

			return (t_fine_ * 5 + 128) >> 8;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	湿度を返す（％）(for BME280)
			@return 湿度
		 */
		//-----------------------------------------------------------------//
		float get_humidity()
		{
			if(addr_ == 0) return 0;

			get_temperature(); // must be done first to get t_fine

			int32_t adc_H = read16_(REG::HUMIDDATA);

			int32_t v_x1_u32r = (t_fine_ - (static_cast<int32_t>(76800)));

			v_x1_u32r = (((((adc_H << 14) - ((static_cast<int32_t>(calib_.dig_H4)) << 20) -
				((static_cast<int32_t>(calib_.dig_H5)) * v_x1_u32r)) + (static_cast<int32_t>(16384))) >> 15) *
				(((((((v_x1_u32r * (static_cast<int32_t>(calib_.dig_H6))) >> 10) *
				(((v_x1_u32r * (static_cast<int32_t>(calib_.dig_H3))) >> 11) +
				(static_cast<int32_t>(32768)))) >> 10) +
				(static_cast<int32_t>(2097152))) * (static_cast<int32_t>(calib_.dig_H2)) + 8192) >> 14));

			v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
				(static_cast<int32_t>(calib_.dig_H1))) >> 4));

			v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
			v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
			float h = (v_x1_u32r>>12);
			return  h / 1024.0f;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	圧力を返す [hPa * 100]
			@return 圧力
		 */
		//-----------------------------------------------------------------//
		int32_t get_pressure()
		{
			if(addr_ == 0) return 0;

			// Must be done first to get the t_fine variable set up
			get_temperature();

			int32_t adc_P = read24_(REG::PRESSUREDATA);
			adc_P >>= 4;

			int64_t var1 = (static_cast<int64_t>(t_fine_)) - 128000;
			int64_t var2 = var1 * var1 * static_cast<int64_t>(calib_.dig_P6);
			var2 = var2 + ((var1 * static_cast<int64_t>(calib_.dig_P5)) << 17);
			var2 = var2 + ((static_cast<int64_t>(calib_.dig_P4)) << 35);
			var1 = ((var1 * var1 * static_cast<int64_t>(calib_.dig_P3)) >> 8) +
				((var1 * static_cast<int64_t>(calib_.dig_P2)) << 12);
			var1 = ((((static_cast<int64_t>(1)) << 47) + var1)) * (static_cast<int64_t>(calib_.dig_P1)) >> 33;

			if(var1 == 0) {
				return 0.0f;  // avoid exception caused by division by zero
			}

			int64_t p = 1048576 - adc_P;
			p = (((p << 31) - var2) * 3125) / var1;
			var1 = ((static_cast<int64_t>(calib_.dig_P9)) * (p >> 13) * (p >> 13)) >> 25;
			var2 = ((static_cast<int64_t>(calib_.dig_P8)) * p) >> 19;

			p = ((p + var1 + var2) >> 8) + ((static_cast<int64_t>(calib_.dig_P7)) << 4);

			return p >> 8;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	高度を返す
			@param[in]	seaLevelhPa 海面ヘクトパスカル
			@return 高度
		 */
		//-----------------------------------------------------------------//
		float get_altitude(float seaLevelhPa = 1013.25f)
		{
			if(addr_ == 0) return 0.0f;

			float pressure = static_cast<float>(get_pressure()) / 100.0f;
			float altitude = 44330.0f * (1.0f - std::pow(pressure / seaLevelhPa, 0.1903f));
			return altitude;
		}

	};
}
<commit_msg>update c++14 binary literal<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	BMP280 デジタル圧力センサー・ドライバー @n
			Bosch Sensotec / Digital Pressure Sensor @n
			https://www.bosch-sensortec.com/bst/products/all_products/bmp280 @n
			Copyright 2016 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include <cmath>
#include "common/iica_io.hpp"
#include "common/delay.hpp"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  BMP280 テンプレートクラス
		@param[in]	I2C_IO	i2c I/O クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class I2C_IO>
	class BMP280 {

		// R/W ビットを含まない７ビット値
		// ※ SDO:L ---> 0x76, SDO:H ---> 0x77
		static const uint8_t BMP280_ADR_ = 0x77;

		I2C_IO& i2c_;

		uint8_t	addr_;

		enum class REG : uint8_t {
      		DIG_T1        = 0x88,
      		DIG_T2        = 0x8A,
      		DIG_T3        = 0x8C,

      		DIG_P1        = 0x8E,
      		DIG_P2        = 0x90,
      		DIG_P3        = 0x92,
      		DIG_P4        = 0x94,
      		DIG_P5        = 0x96,
      		DIG_P6        = 0x98,
      		DIG_P7        = 0x9A,
      		DIG_P8        = 0x9C,
      		DIG_P9        = 0x9E,

      		CHIPID        = 0xD0,
      		VERSION       = 0xD1,
      		SOFTRESET     = 0xE0,

      		CAL26         = 0xE1,  // R calibration stored in 0xE1-0xF0

      		CONTROL       = 0xF4,
      		CONFIG        = 0xF5,
      		PRESSUREDATA  = 0xF7,
      		TEMPDATA      = 0xFA,
			HUMIDDATA     = 0xFD,
		};

    	struct calib_t {
			uint16_t	dig_T1;
			int16_t		dig_T2;
			int16_t		dig_T3;

			uint16_t	dig_P1;
			int16_t		dig_P2;
			int16_t		dig_P3;
			int16_t		dig_P4;
			int16_t		dig_P5;
			int16_t		dig_P6;
			int16_t		dig_P7;
			int16_t		dig_P8;
			int16_t		dig_P9;

			uint8_t		dig_H1;
			int16_t		dig_H2;
			uint8_t		dig_H3;
			int16_t		dig_H4;
			int16_t		dig_H5;
			int8_t		dig_H6;
		};

		calib_t		calib_;

		int32_t		t_fine_;

		uint8_t read8_(REG adr) {
			uint8_t reg[1];
			reg[0] = static_cast<uint8_t>(adr);
			i2c_.send(addr_, reg, 1);
			i2c_.recv(addr_, reg, 1);
			return reg[0];
		}

		uint16_t read16_(REG adr) {
			uint8_t reg[2];
			reg[0] = static_cast<uint8_t>(adr);
			i2c_.send(addr_, reg, 1);
			i2c_.recv(addr_, reg, 2);
			return (reg[0] << 8) | reg[1];
		}

		uint32_t read24_(REG adr) {
			uint8_t reg[3];
			reg[0] = static_cast<uint8_t>(adr);
			i2c_.send(addr_, reg, 1);
			i2c_.recv(addr_, reg, 3);
			return (static_cast<uint32_t>(reg[0]) << 16) | (static_cast<uint32_t>(reg[1]) << 8) | reg[2];
		}

		uint16_t read16le_(REG adr) {
			uint8_t reg[2];
			reg[0] = static_cast<uint8_t>(adr);
			i2c_.send(addr_, reg, 1);
			i2c_.recv(addr_, reg, 2);
			return (reg[1] << 8) | reg[0];
		}

		void write8_(REG a, uint8_t data) {
			uint8_t reg[2];
			reg[0] = static_cast<uint8_t>(a);
			reg[1] = data;
			i2c_.send(addr_, reg, 2);
		}

		void get_coefficients_() {
			calib_.dig_T1 = read16le_(REG::DIG_T1);
			calib_.dig_T2 = read16le_(REG::DIG_T2);
			calib_.dig_T3 = read16le_(REG::DIG_T3);

			calib_.dig_P1 = read16le_(REG::DIG_P1);
			calib_.dig_P2 = read16le_(REG::DIG_P2);
			calib_.dig_P3 = read16le_(REG::DIG_P3);
			calib_.dig_P4 = read16le_(REG::DIG_P4);
			calib_.dig_P5 = read16le_(REG::DIG_P5);
			calib_.dig_P6 = read16le_(REG::DIG_P6);
			calib_.dig_P7 = read16le_(REG::DIG_P7);
			calib_.dig_P8 = read16le_(REG::DIG_P8);
			calib_.dig_P9 = read16le_(REG::DIG_P9);
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	i2c	iica_io クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		BMP280(I2C_IO& i2c) : i2c_(i2c), addr_(0), calib_(), t_fine_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	開始
			@param[in]	addr	オプションの I2C アドレス @n
								※ SDO:L ---> 0x76, SDO:H ---> 0x77 (default)
			@return エラーなら「false」を返す
		 */
		//-----------------------------------------------------------------//
		bool start(uint8_t addr = BMP280_ADR_)
		{
			addr_ = addr;

			if(read8_(REG::CHIPID) != 0x58) {  // チップＩＤの確認
				addr_ = 0;
				return false;
			}

			get_coefficients_();  // 補正データ取得

			// Ex: Ultra high resolution
			// setting control
			// osrs_t(X2): 010, osrs_p(X16): 101, mode(Normal): 11
			uint8_t mode = 0b010'000'00 | 0b000'101'00 | 0b000'000'11;
			write8_(REG::CONTROL, mode);

			// setting config
			// t_sb(0.5ms): 000, filter(16): 100, xxx(0): 0, spi3w_en(0): 0
			uint8_t conf = 0b000'000'0'0 | 0b000'100'0'0 | 0b000'000'0'0 | 0b000'000'0'0;
			write8_(REG::CONFIG, conf);

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	温度を返す（℃ * 100）
			@return 温度
		 */
		//-----------------------------------------------------------------//
		int32_t get_temperature()
		{
			if(addr_ == 0) return 0;

			int32_t adc_T = read24_(REG::TEMPDATA);
			adc_T >>= 4;

  			int32_t var1  = ((((adc_T>>3) - (static_cast<int32_t>(calib_.dig_T1) << 1))) *
				(static_cast<int32_t>(calib_.dig_T2))) >> 11;

			int32_t var2  = (((((adc_T>>4) - (static_cast<int32_t>(calib_.dig_T1))) *
				((adc_T>>4) - (static_cast<int32_t>(calib_.dig_T1)))) >> 12) *
				(static_cast<int32_t>(calib_.dig_T3))) >> 14;

			t_fine_ = var1 + var2;

			return (t_fine_ * 5 + 128) >> 8;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	湿度を返す（％）(for BME280)
			@return 湿度
		 */
		//-----------------------------------------------------------------//
		float get_humidity()
		{
			if(addr_ == 0) return 0;

			get_temperature(); // must be done first to get t_fine

			int32_t adc_H = read16_(REG::HUMIDDATA);

			int32_t v_x1_u32r = (t_fine_ - (static_cast<int32_t>(76800)));

			v_x1_u32r = (((((adc_H << 14) - ((static_cast<int32_t>(calib_.dig_H4)) << 20) -
				((static_cast<int32_t>(calib_.dig_H5)) * v_x1_u32r)) + (static_cast<int32_t>(16384))) >> 15) *
				(((((((v_x1_u32r * (static_cast<int32_t>(calib_.dig_H6))) >> 10) *
				(((v_x1_u32r * (static_cast<int32_t>(calib_.dig_H3))) >> 11) +
				(static_cast<int32_t>(32768)))) >> 10) +
				(static_cast<int32_t>(2097152))) * (static_cast<int32_t>(calib_.dig_H2)) + 8192) >> 14));

			v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
				(static_cast<int32_t>(calib_.dig_H1))) >> 4));

			v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
			v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
			float h = (v_x1_u32r>>12);
			return  h / 1024.0f;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	圧力を返す [hPa * 100]
			@return 圧力
		 */
		//-----------------------------------------------------------------//
		int32_t get_pressure()
		{
			if(addr_ == 0) return 0;

			// Must be done first to get the t_fine variable set up
			get_temperature();

			int32_t adc_P = read24_(REG::PRESSUREDATA);
			adc_P >>= 4;

			int64_t var1 = (static_cast<int64_t>(t_fine_)) - 128000;
			int64_t var2 = var1 * var1 * static_cast<int64_t>(calib_.dig_P6);
			var2 = var2 + ((var1 * static_cast<int64_t>(calib_.dig_P5)) << 17);
			var2 = var2 + ((static_cast<int64_t>(calib_.dig_P4)) << 35);
			var1 = ((var1 * var1 * static_cast<int64_t>(calib_.dig_P3)) >> 8) +
				((var1 * static_cast<int64_t>(calib_.dig_P2)) << 12);
			var1 = ((((static_cast<int64_t>(1)) << 47) + var1)) * (static_cast<int64_t>(calib_.dig_P1)) >> 33;

			if(var1 == 0) {
				return 0.0f;  // avoid exception caused by division by zero
			}

			int64_t p = 1048576 - adc_P;
			p = (((p << 31) - var2) * 3125) / var1;
			var1 = ((static_cast<int64_t>(calib_.dig_P9)) * (p >> 13) * (p >> 13)) >> 25;
			var2 = ((static_cast<int64_t>(calib_.dig_P8)) * p) >> 19;

			p = ((p + var1 + var2) >> 8) + ((static_cast<int64_t>(calib_.dig_P7)) << 4);

			return p >> 8;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	高度を返す
			@param[in]	seaLevelhPa 海面ヘクトパスカル
			@return 高度
		 */
		//-----------------------------------------------------------------//
		float get_altitude(float seaLevelhPa = 1013.25f)
		{
			if(addr_ == 0) return 0.0f;

			float pressure = static_cast<float>(get_pressure()) / 100.0f;
			float altitude = 44330.0f * (1.0f - std::pow(pressure / seaLevelhPa, 0.1903f));
			return altitude;
		}

	};
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DrawViewWrapper.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 15:30:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser 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, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "DrawViewWrapper.hxx"
#include "DrawModelWrapper.hxx"
#include "ConfigurationAccess.hxx"
#include "ViewSingletons.hxx"

// header for class SdrPage
#ifndef _SVDPAGE_HXX
#include <svx/svdpage.hxx>
#endif
//header for class SdrPageView
#ifndef _SVDPAGV_HXX
#include <svx/svdpagv.hxx>
#endif
// header for class SdrModel
#ifndef _SVDMODEL_HXX
#include <svx/svdmodel.hxx>
#endif

#ifndef _SVDETC_HXX
#include <svx/svdetc.hxx>
#endif

#ifndef _SVDOUTL_HXX
#include <svx/svdoutl.hxx>
#endif

// header for class SvxForbiddenCharactersTable
#ifndef _FORBIDDENCHARACTERSTABLE_HXX
#include <svx/forbiddencharacterstable.hxx>
#endif

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif

//.............................................................................
namespace chart
{
//.............................................................................
    /*
void lcl_initOutliner( SdrOutliner* pTargetOutliner, SdrOutliner* pSourceOutliner )
{
    //just an unsuccessful try to initialize the text edit outliner correctly
    //if( bInit )
    {
        pTargetOutliner->EraseVirtualDevice();
        pTargetOutliner->SetUpdateMode(FALSE);
        pTargetOutliner->SetEditTextObjectPool( pSourceOutliner->GetEditTextObjectPool() );
        pTargetOutliner->SetDefTab( pSourceOutliner->GetDefTab() );
    }

    pTargetOutliner->SetRefDevice( pSourceOutliner->GetRefDevice() );
    pTargetOutliner->SetForbiddenCharsTable( pSourceOutliner->GetForbiddenCharsTable() );
    pTargetOutliner->SetAsianCompressionMode( pSourceOutliner->GetAsianCompressionMode() );
    pTargetOutliner->SetKernAsianPunctuation( pSourceOutliner->IsKernAsianPunctuation() );
    pTargetOutliner->SetStyleSheetPool( pSourceOutliner->GetStyleSheetPool() );
    pTargetOutliner->SetRefMapMode( pSourceOutliner->GetRefMapMode() );
    pTargetOutliner->SetDefaultLanguage( pSourceOutliner->GetDefaultLanguage() );
    pTargetOutliner->SetHyphenator( pSourceOutliner->GetHyphenator() );

    USHORT nX, nY;
    pSourceOutliner->GetGlobalCharStretching( nX, nY );
    pTargetOutliner->SetGlobalCharStretching( nX, nY );

    *//*
    if ( !GetRefDevice() )
    {
        MapMode aMapMode(eObjUnit, Point(0,0), aObjUnit, aObjUnit);
        pTargetOutliner->SetRefMapMode(aMapMode);
    }
    *//*
}
*/

DrawViewWrapper::DrawViewWrapper( SdrModel* pSdrModel, OutputDevice* pOut)
            : E3dView(pSdrModel, pOut)
            , m_pWrappedDLPageView(NULL)
            , m_pMarkHandleProvider(NULL)
            , m_apOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, pSdrModel ) )
{
    // #114898#
    SetBufferedOutputAllowed(true);
    SetBufferedOverlayAllowed(true);

    ReInit();
}

void DrawViewWrapper::ReInit()
{
    OutputDevice* pOutDev = this->GetFirstOutputDevice();
    Size aOutputSize(100,100);
    if(pOutDev)
        aOutputSize = pOutDev->GetOutputSize();

    m_pWrappedDLPageView = this->ShowSdrPage(this->GetModel()->GetPage(0));
    m_pWrappedDLPageView->GetPage()->SetSize( aOutputSize );
    this->SetPageBorderVisible(false);
    this->SetBordVisible(false);
    this->SetGridVisible(false);
    this->SetGridFront(false);
    this->SetHlplVisible(false);
    this->SetNoDragXorPolys(true);//for interactive 3D resize-dragging: paint only a single rectangle (not a simulated 3D object)
    //this->SetResizeAtCenter(true);//for interactive resize-dragging: keep the object center fix

    //a correct work area is at least necessary for correct values in the position and  size dialog
    //Rectangle aRect = pOutDev->PixelToLogic(Rectangle(Point(0,0), aOutputSize));
    Rectangle aRect(Point(0,0), aOutputSize);
    this->SetWorkArea(aRect);
}

DrawViewWrapper::~DrawViewWrapper()
{
    m_pWrappedDLPageView = NULL;//@ todo: sufficient? or remove necessary
    aComeBackTimer.Stop();//@todo this should be done in destructor of base class
}

//virtual
void DrawViewWrapper::SetMarkHandles()
{
    if( m_pMarkHandleProvider && m_pMarkHandleProvider->getMarkHandles( aHdl ) )
        return;
    else
        SdrView::SetMarkHandles();
}

SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const
{
    const short HITPIX=2; //hit-tolerance in pixel

    SdrObject* pRet = NULL;
    //ULONG nOptions =SDRSEARCH_DEEP|SDRSEARCH_PASS2BOUND|SDRSEARCH_PASS3NEAREST;
    //ULONG nOptions = SDRSEARCH_TESTMARKABLE;
    ULONG nOptions = SDRSEARCH_DEEP | SDRSEARCH_TESTMARKABLE;
    //ULONG nOptions = SDRSEARCH_DEEP|SDRSEARCH_ALSOONMASTER|SDRSEARCH_WHOLEPAGE|SDRSEARCH_PASS2BOUND|SDRSEARCH_PASS3NEAREST;
    //ULONG nOptions = 0;

    short nHitTolerance = 50;
    {
        OutputDevice* pOutDev = this->GetFirstOutputDevice();
        if(pOutDev)
            nHitTolerance = static_cast<short>(pOutDev->PixelToLogic(Size(HITPIX,0)).Width());
    }
    this->SdrView::PickObj(rPnt, nHitTolerance, pRet, m_pWrappedDLPageView, nOptions);
    return pRet;
}

void DrawViewWrapper::MarkObject( SdrObject* pObj )
{
    bool bFrameDragSingles = true;//true == green == surrounding handles
    pObj->SetMarkProtect(false);
    if( m_pMarkHandleProvider )
        bFrameDragSingles = m_pMarkHandleProvider->getFrameDragSingles();
    this->SetFrameDragSingles(bFrameDragSingles);//decide wether each single object should get handles
    this->SdrView::MarkObj( pObj, m_pWrappedDLPageView );
    this->SetMarkHdlHidden(FALSE);
}

void DrawViewWrapper::setMarkHandleProvider( MarkHandleProvider* pMarkHandleProvider )
{
    m_pMarkHandleProvider = pMarkHandleProvider;
}

void DrawViewWrapper::CompleteRedraw( OutputDevice* pOut, const Region& rReg )
{
    svtools::ColorConfig aColorConfig;
    Color aFillColor = Color( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
    this->SetApplicationBackgroundColor(aFillColor);
    this->E3dView::CompleteRedraw( pOut, rReg );
}

SdrObject* DrawViewWrapper::getSelectedObject() const
{
    SdrObject* pObj(NULL);
    const SdrMarkList& rMarkList = this->GetMarkedObjectList();
    if(rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        pObj = pMark->GetMarkedSdrObj();
    }
    return pObj;
}

SdrObject* DrawViewWrapper::getTextEditObject() const
{
    SdrObject* pObj = this->getSelectedObject();
    SdrObject* pTextObj = NULL;
    if( pObj && pObj->HasTextEdit())
        pTextObj = (SdrTextObj*)pObj;
    return pTextObj;
}

SdrOutliner* DrawViewWrapper::getOutliner() const
{
//    lcl_initOutliner( m_apOutliner.get(), &GetModel()->GetDrawOutliner() );
    return m_apOutliner.get();
}

SfxItemSet DrawViewWrapper::getPositionAndSizeItemSetFromMarkedObject() const
{
    SfxItemSet aFullSet( GetModel()->GetItemPool(),
                    SID_ATTR_TRANSFORM_POS_X,SID_ATTR_TRANSFORM_ANGLE,
                    SID_ATTR_TRANSFORM_PROTECT_POS,SID_ATTR_TRANSFORM_AUTOHEIGHT,
                    SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS,
                    SID_ATTR_METRIC,SID_ATTR_METRIC,
                    0);
    SfxItemSet aGeoSet( E3dView::GetGeoAttrFromMarked() );
    aFullSet.Put( aGeoSet );
    aFullSet.Put( SfxUInt16Item(SID_ATTR_METRIC,ViewSingletons::getConfigurationAccess()->getFieldUnit()) );
    return aFullSet;
}

//.............................................................................
} //namespace chart
//.............................................................................
<commit_msg>INTEGRATION: CWS aw037 (1.13.2); FILE MERGED 2006/11/28 10:42:49 aw 1.13.2.1: #i65399# made show/hideMarkHandles more concrete<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DrawViewWrapper.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 16:45:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser 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, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "DrawViewWrapper.hxx"
#include "DrawModelWrapper.hxx"
#include "ConfigurationAccess.hxx"
#include "ViewSingletons.hxx"

// header for class SdrPage
#ifndef _SVDPAGE_HXX
#include <svx/svdpage.hxx>
#endif
//header for class SdrPageView
#ifndef _SVDPAGV_HXX
#include <svx/svdpagv.hxx>
#endif
// header for class SdrModel
#ifndef _SVDMODEL_HXX
#include <svx/svdmodel.hxx>
#endif

#ifndef _SVDETC_HXX
#include <svx/svdetc.hxx>
#endif

#ifndef _SVDOUTL_HXX
#include <svx/svdoutl.hxx>
#endif

// header for class SvxForbiddenCharactersTable
#ifndef _FORBIDDENCHARACTERSTABLE_HXX
#include <svx/forbiddencharacterstable.hxx>
#endif

#ifndef _SVX_SVXIDS_HRC
#include <svx/svxids.hrc>
#endif

//.............................................................................
namespace chart
{
//.............................................................................
    /*
void lcl_initOutliner( SdrOutliner* pTargetOutliner, SdrOutliner* pSourceOutliner )
{
    //just an unsuccessful try to initialize the text edit outliner correctly
    //if( bInit )
    {
        pTargetOutliner->EraseVirtualDevice();
        pTargetOutliner->SetUpdateMode(FALSE);
        pTargetOutliner->SetEditTextObjectPool( pSourceOutliner->GetEditTextObjectPool() );
        pTargetOutliner->SetDefTab( pSourceOutliner->GetDefTab() );
    }

    pTargetOutliner->SetRefDevice( pSourceOutliner->GetRefDevice() );
    pTargetOutliner->SetForbiddenCharsTable( pSourceOutliner->GetForbiddenCharsTable() );
    pTargetOutliner->SetAsianCompressionMode( pSourceOutliner->GetAsianCompressionMode() );
    pTargetOutliner->SetKernAsianPunctuation( pSourceOutliner->IsKernAsianPunctuation() );
    pTargetOutliner->SetStyleSheetPool( pSourceOutliner->GetStyleSheetPool() );
    pTargetOutliner->SetRefMapMode( pSourceOutliner->GetRefMapMode() );
    pTargetOutliner->SetDefaultLanguage( pSourceOutliner->GetDefaultLanguage() );
    pTargetOutliner->SetHyphenator( pSourceOutliner->GetHyphenator() );

    USHORT nX, nY;
    pSourceOutliner->GetGlobalCharStretching( nX, nY );
    pTargetOutliner->SetGlobalCharStretching( nX, nY );

    *//*
    if ( !GetRefDevice() )
    {
        MapMode aMapMode(eObjUnit, Point(0,0), aObjUnit, aObjUnit);
        pTargetOutliner->SetRefMapMode(aMapMode);
    }
    *//*
}
*/

DrawViewWrapper::DrawViewWrapper( SdrModel* pSdrModel, OutputDevice* pOut)
            : E3dView(pSdrModel, pOut)
            , m_pWrappedDLPageView(NULL)
            , m_pMarkHandleProvider(NULL)
            , m_apOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, pSdrModel ) )
{
    // #114898#
    SetBufferedOutputAllowed(true);
    SetBufferedOverlayAllowed(true);

    ReInit();
}

void DrawViewWrapper::ReInit()
{
    OutputDevice* pOutDev = this->GetFirstOutputDevice();
    Size aOutputSize(100,100);
    if(pOutDev)
        aOutputSize = pOutDev->GetOutputSize();

    m_pWrappedDLPageView = this->ShowSdrPage(this->GetModel()->GetPage(0));
    m_pWrappedDLPageView->GetPage()->SetSize( aOutputSize );
    this->SetPageBorderVisible(false);
    this->SetBordVisible(false);
    this->SetGridVisible(false);
    this->SetGridFront(false);
    this->SetHlplVisible(false);
    this->SetNoDragXorPolys(true);//for interactive 3D resize-dragging: paint only a single rectangle (not a simulated 3D object)
    //this->SetResizeAtCenter(true);//for interactive resize-dragging: keep the object center fix

    //a correct work area is at least necessary for correct values in the position and  size dialog
    //Rectangle aRect = pOutDev->PixelToLogic(Rectangle(Point(0,0), aOutputSize));
    Rectangle aRect(Point(0,0), aOutputSize);
    this->SetWorkArea(aRect);
}

DrawViewWrapper::~DrawViewWrapper()
{
    m_pWrappedDLPageView = NULL;//@ todo: sufficient? or remove necessary
    aComeBackTimer.Stop();//@todo this should be done in destructor of base class
}

//virtual
void DrawViewWrapper::SetMarkHandles()
{
    if( m_pMarkHandleProvider && m_pMarkHandleProvider->getMarkHandles( aHdl ) )
        return;
    else
        SdrView::SetMarkHandles();
}

SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const
{
    const short HITPIX=2; //hit-tolerance in pixel

    SdrObject* pRet = NULL;
    //ULONG nOptions =SDRSEARCH_DEEP|SDRSEARCH_PASS2BOUND|SDRSEARCH_PASS3NEAREST;
    //ULONG nOptions = SDRSEARCH_TESTMARKABLE;
    ULONG nOptions = SDRSEARCH_DEEP | SDRSEARCH_TESTMARKABLE;
    //ULONG nOptions = SDRSEARCH_DEEP|SDRSEARCH_ALSOONMASTER|SDRSEARCH_WHOLEPAGE|SDRSEARCH_PASS2BOUND|SDRSEARCH_PASS3NEAREST;
    //ULONG nOptions = 0;

    short nHitTolerance = 50;
    {
        OutputDevice* pOutDev = this->GetFirstOutputDevice();
        if(pOutDev)
            nHitTolerance = static_cast<short>(pOutDev->PixelToLogic(Size(HITPIX,0)).Width());
    }
    this->SdrView::PickObj(rPnt, nHitTolerance, pRet, m_pWrappedDLPageView, nOptions);
    return pRet;
}

void DrawViewWrapper::MarkObject( SdrObject* pObj )
{
    bool bFrameDragSingles = true;//true == green == surrounding handles
    pObj->SetMarkProtect(false);
    if( m_pMarkHandleProvider )
        bFrameDragSingles = m_pMarkHandleProvider->getFrameDragSingles();
    this->SetFrameDragSingles(bFrameDragSingles);//decide wether each single object should get handles
    this->SdrView::MarkObj( pObj, m_pWrappedDLPageView );
    this->showMarkHandles();
}

void DrawViewWrapper::setMarkHandleProvider( MarkHandleProvider* pMarkHandleProvider )
{
    m_pMarkHandleProvider = pMarkHandleProvider;
}

void DrawViewWrapper::CompleteRedraw( OutputDevice* pOut, const Region& rReg )
{
    svtools::ColorConfig aColorConfig;
    Color aFillColor = Color( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
    this->SetApplicationBackgroundColor(aFillColor);
    this->E3dView::CompleteRedraw( pOut, rReg );
}

SdrObject* DrawViewWrapper::getSelectedObject() const
{
    SdrObject* pObj(NULL);
    const SdrMarkList& rMarkList = this->GetMarkedObjectList();
    if(rMarkList.GetMarkCount() == 1)
    {
        SdrMark* pMark = rMarkList.GetMark(0);
        pObj = pMark->GetMarkedSdrObj();
    }
    return pObj;
}

SdrObject* DrawViewWrapper::getTextEditObject() const
{
    SdrObject* pObj = this->getSelectedObject();
    SdrObject* pTextObj = NULL;
    if( pObj && pObj->HasTextEdit())
        pTextObj = (SdrTextObj*)pObj;
    return pTextObj;
}

SdrOutliner* DrawViewWrapper::getOutliner() const
{
//    lcl_initOutliner( m_apOutliner.get(), &GetModel()->GetDrawOutliner() );
    return m_apOutliner.get();
}

SfxItemSet DrawViewWrapper::getPositionAndSizeItemSetFromMarkedObject() const
{
    SfxItemSet aFullSet( GetModel()->GetItemPool(),
                    SID_ATTR_TRANSFORM_POS_X,SID_ATTR_TRANSFORM_ANGLE,
                    SID_ATTR_TRANSFORM_PROTECT_POS,SID_ATTR_TRANSFORM_AUTOHEIGHT,
                    SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS,
                    SID_ATTR_METRIC,SID_ATTR_METRIC,
                    0);
    SfxItemSet aGeoSet( E3dView::GetGeoAttrFromMarked() );
    aFullSet.Put( aGeoSet );
    aFullSet.Put( SfxUInt16Item(SID_ATTR_METRIC,ViewSingletons::getConfigurationAccess()->getFieldUnit()) );
    return aFullSet;
}

//.............................................................................
} //namespace chart
//.............................................................................
<|endoftext|>


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

#include "chrome/browser/debugger/devtools_http_protocol_handler.h"

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/debugger/devtools_client_host.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/devtools_messages.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "googleurl/src/gurl.h"
#include "net/base/io_buffer.h"
#include "net/base/listen_socket.h"
#include "net/server/http_server_request_info.h"
#include "net/url_request/url_request_context.h"

const int kBufferSize = 16 * 1024;

namespace {

// An internal implementation of DevToolsClientHost that delegates
// messages sent for DevToolsClient to a DebuggerShell instance.
class DevToolsClientHostImpl : public DevToolsClientHost {
 public:
  explicit DevToolsClientHostImpl(HttpListenSocket* socket)
      : socket_(socket) {}
  ~DevToolsClientHostImpl() {}

  // DevToolsClientHost interface
  virtual void InspectedTabClosing() {
    socket_->Close();
  }

  virtual void SendMessageToClient(const IPC::Message& msg) {
    IPC_BEGIN_MESSAGE_MAP(DevToolsClientHostImpl, msg)
      IPC_MESSAGE_HANDLER(DevToolsClientMsg_RpcMessage, OnRpcMessage);
      IPC_MESSAGE_UNHANDLED_ERROR()
    IPC_END_MESSAGE_MAP()
  }

  void NotifyCloseListener() {
    DevToolsClientHost::NotifyCloseListener();
  }
 private:
  // Message handling routines
  void OnRpcMessage(const DevToolsMessageData& data) {
    std::string message;
    message += "devtools$$dispatch(\"" + data.class_name + "\", \"" +
        data.method_name + "\"";
    for (std::vector<std::string>::const_iterator it = data.arguments.begin();
         it != data.arguments.end(); ++it) {
      std::string param = *it;
      if (!param.empty())
        message += ", " + param;
    }
    message += ")";
    socket_->SendOverWebSocket(message);
  }
  HttpListenSocket* socket_;
};

}

DevToolsHttpProtocolHandler::~DevToolsHttpProtocolHandler() {
  // Stop() must be called prior to this being called
  DCHECK(server_.get() == NULL);
}

void DevToolsHttpProtocolHandler::Start() {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(this, &DevToolsHttpProtocolHandler::Init));
}

void DevToolsHttpProtocolHandler::Stop() {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(this, &DevToolsHttpProtocolHandler::Teardown));
}

void DevToolsHttpProtocolHandler::OnHttpRequest(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& info) {
  if (info.path == "" || info.path == "/") {
    // Pages discovery request.
    ChromeThread::PostTask(
        ChromeThread::UI,
        FROM_HERE,
        NewRunnableMethod(this,
                          &DevToolsHttpProtocolHandler::OnHttpRequestUI,
                          socket,
                          info));
    return;
  }

  size_t pos = info.path.find("/devtools/");
  if (pos != 0) {
    socket->Send404();
    return;
  }

  // Proxy static files from chrome://devtools/*.
  URLRequest* request = new URLRequest(GURL("chrome:/" + info.path), this);
  Bind(request, socket);
  request->set_context(
      Profile::GetDefaultRequestContext()->GetURLRequestContext());
  request->Start();
}

void DevToolsHttpProtocolHandler::OnWebSocketRequest(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& request) {
  ChromeThread::PostTask(
      ChromeThread::UI,
      FROM_HERE,
      NewRunnableMethod(
          this,
          &DevToolsHttpProtocolHandler::OnWebSocketRequestUI,
          socket,
          request));
}

void DevToolsHttpProtocolHandler::OnWebSocketMessage(HttpListenSocket* socket,
                                                     const std::string& data) {
  ChromeThread::PostTask(
      ChromeThread::UI,
      FROM_HERE,
      NewRunnableMethod(
          this,
          &DevToolsHttpProtocolHandler::OnWebSocketMessageUI,
          socket,
          data));
}

void DevToolsHttpProtocolHandler::OnClose(HttpListenSocket* socket) {
  SocketToRequestsMap::iterator it = socket_to_requests_io_.find(socket);
  if (it != socket_to_requests_io_.end()) {
    // Dispose delegating socket.
    for (std::set<URLRequest*>::iterator it2 = it->second.begin();
         it2 != it->second.end(); ++it2) {
      URLRequest* request = *it2;
      request->Cancel();
      request_to_socket_io_.erase(request);
      request_to_buffer_io_.erase(request);
      delete request;
    }
    socket_to_requests_io_.erase(socket);
  }

  ChromeThread::PostTask(
      ChromeThread::UI,
      FROM_HERE,
      NewRunnableMethod(
          this,
          &DevToolsHttpProtocolHandler::OnCloseUI,
          socket));
}

void DevToolsHttpProtocolHandler::OnHttpRequestUI(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& info) {
  std::string response = "";
  for (BrowserList::const_iterator it = BrowserList::begin(),
       end = BrowserList::end(); it != end; ++it) {
    TabStripModel* model = (*it)->tabstrip_model();
    for (int i = 0, size = model->count(); i < size; ++i) {
      TabContents* tab_contents = model->GetTabContentsAt(i);
      NavigationController& controller = tab_contents->controller();
      NavigationEntry* entry = controller.GetActiveEntry();
      if (entry == NULL)
        continue;

      if (!entry->url().is_valid())
        continue;

      DevToolsClientHost* client_host = DevToolsManager::GetInstance()->
          GetDevToolsClientHostFor(tab_contents->render_view_host());
      if (!client_host) {
        response += StringPrintf(
            "%s (%s)
",
            controller.session_id().id(),
            UTF16ToUTF8(entry->title()).c_str(),
            entry->url().spec().c_str());
      } else {
        response += StringPrintf(
            "%s (%s)
",
            UTF16ToUTF8(entry->title()).c_str(),
            entry->url().spec().c_str());
      }
    }
  }
  response += "";
  Send200(socket, response, "text/html");
}

void DevToolsHttpProtocolHandler::OnWebSocketRequestUI(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& request) {
  std::string prefix = "/devtools/page/";
  size_t pos = request.path.find(prefix);
  if (pos != 0) {
    Send404(socket);
    return;
  }
  std::string page_id = request.path.substr(prefix.length());
  int id = 0;
  if (!StringToInt(page_id, &id)) {
    Send500(socket, "Invalid page id: " + page_id);
    return;
  }

  TabContents* tab_contents = GetTabContents(id);
  if (tab_contents == NULL) {
    Send500(socket, "No such page id: " + page_id);
    return;
  }

  DevToolsManager* manager = DevToolsManager::GetInstance();
  if (manager->GetDevToolsClientHostFor(tab_contents->render_view_host())) {
    Send500(socket, "Page with given id is being inspected: " + page_id);
    return;
  }

  DevToolsClientHostImpl* client_host = new DevToolsClientHostImpl(socket);
  socket_to_client_host_ui_[socket] = client_host;

  manager->RegisterDevToolsClientHostFor(
      tab_contents->render_view_host(),
      client_host);
  AcceptWebSocket(socket, request);
}

void DevToolsHttpProtocolHandler::OnWebSocketMessageUI(
    HttpListenSocket* socket,
    const std::string& d) {
  SocketToClientHostMap::iterator it = socket_to_client_host_ui_.find(socket);
  if (it == socket_to_client_host_ui_.end())
    return;

  std::string data = d;
  // TODO(pfeldman): Replace with proper parsing / dispatching.
  DevToolsMessageData message_data;
  message_data.class_name = "ToolsAgent";
  message_data.method_name = "dispatchOnInspectorController";

  size_t pos = data.find(" ");
  message_data.arguments.push_back(data.substr(0, pos));
  data = data.substr(pos + 1);

  message_data.arguments.push_back(data);

  DevToolsManager* manager = DevToolsManager::GetInstance();
  manager->ForwardToDevToolsAgent(it->second,
      DevToolsAgentMsg_RpcMessage(DevToolsMessageData(message_data)));
}

void DevToolsHttpProtocolHandler::OnCloseUI(HttpListenSocket* socket) {
  SocketToClientHostMap::iterator it = socket_to_client_host_ui_.find(socket);
  if (it == socket_to_client_host_ui_.end())
    return;
  DevToolsClientHostImpl* client_host =
      static_cast<DevToolsClientHostImpl*>(it->second);
  client_host->NotifyCloseListener();
  delete client_host;
  socket_to_client_host_ui_.erase(socket);
}

void DevToolsHttpProtocolHandler::OnResponseStarted(URLRequest* request) {
  RequestToSocketMap::iterator it = request_to_socket_io_.find(request);
  if (it == request_to_socket_io_.end())
    return;

  HttpListenSocket* socket = it->second;

  int expected_size = static_cast<int>(request->GetExpectedContentSize());

  std::string content_type;
  request->GetMimeType(&content_type);

  if (request->status().is_success()) {
    socket->Send(StringPrintf("HTTP/1.1 200 OK\r\n"
                              "Content-Type:%s\r\n"
                              "Content-Length:%d\r\n"
                              "\r\n",
                              content_type.c_str(),
                              expected_size));
  } else {
    socket->Send404();
  }

  int bytes_read = 0;
  // Some servers may treat HEAD requests as GET requests.  To free up the
  // network connection as soon as possible, signal that the request has
  // completed immediately, without trying to read any data back (all we care
  // about is the response code and headers, which we already have).
  net::IOBuffer* buffer = request_to_buffer_io_[request].get();
  if (request->status().is_success())
    request->Read(buffer, kBufferSize, &bytes_read);
  OnReadCompleted(request, bytes_read);
}

void DevToolsHttpProtocolHandler::OnReadCompleted(URLRequest* request,
                                                  int bytes_read) {
  RequestToSocketMap::iterator it = request_to_socket_io_.find(request);
  if (it == request_to_socket_io_.end())
    return;

  HttpListenSocket* socket = it->second;

  net::IOBuffer* buffer = request_to_buffer_io_[request].get();
  do {
    if (!request->status().is_success() || bytes_read <= 0)
      break;
    socket->Send(buffer->data(), bytes_read);
  } while (request->Read(buffer, kBufferSize, &bytes_read));

  // See comments re: HEAD requests in OnResponseStarted().
  if (!request->status().is_io_pending())
    RequestCompleted(request);
}

DevToolsHttpProtocolHandler::DevToolsHttpProtocolHandler(int port)
    : port_(port),
      server_(NULL) {
}

void DevToolsHttpProtocolHandler::Init() {
  server_ = HttpListenSocket::Listen("127.0.0.1", port_, this);
}

// Run on I/O thread
void DevToolsHttpProtocolHandler::Teardown() {
  server_ = NULL;
}

void DevToolsHttpProtocolHandler::Bind(URLRequest* request,
                                       HttpListenSocket* socket) {
  request_to_socket_io_[request] = socket;
  SocketToRequestsMap::iterator it = socket_to_requests_io_.find(socket);
  if (it == socket_to_requests_io_.end()) {
    std::pair<HttpListenSocket*, std::set<URLRequest*> > value(
        socket,
        std::set<URLRequest*>());
    it = socket_to_requests_io_.insert(value).first;
  }
  it->second.insert(request);
  request_to_buffer_io_[request] = new net::IOBuffer(kBufferSize);
}

void DevToolsHttpProtocolHandler::RequestCompleted(URLRequest* request) {
  RequestToSocketMap::iterator it = request_to_socket_io_.find(request);
  if (it == request_to_socket_io_.end())
    return;

  HttpListenSocket* socket = it->second;
  request_to_socket_io_.erase(request);
  SocketToRequestsMap::iterator it2 = socket_to_requests_io_.find(socket);
  it2->second.erase(request);
  request_to_buffer_io_.erase(request);
  delete request;
}

void DevToolsHttpProtocolHandler::Send200(HttpListenSocket* socket,
                                          const std::string& data,
                                          const std::string& mime_type) {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(socket,
                        &HttpListenSocket::Send200,
                        data,
                        mime_type));
}

void DevToolsHttpProtocolHandler::Send404(HttpListenSocket* socket) {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(socket,
                        &HttpListenSocket::Send404));
}

void DevToolsHttpProtocolHandler::Send500(HttpListenSocket* socket,
                                          const std::string& message) {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(socket,
                        &HttpListenSocket::Send500,
                        message));
}

void DevToolsHttpProtocolHandler::AcceptWebSocket(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& request) {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(socket,
                        &HttpListenSocket::AcceptWebSocket,
                        request));
}

TabContents* DevToolsHttpProtocolHandler::GetTabContents(int session_id) {
  for (BrowserList::const_iterator it = BrowserList::begin(),
       end = BrowserList::end(); it != end; ++it) {
    TabStripModel* model = (*it)->tabstrip_model();
    for (int i = 0, size = model->count(); i < size; ++i) {
      NavigationController& controller =
          model->GetTabContentsAt(i)->controller();
      if (controller.session_id().id() == session_id)
        return controller.tab_contents();
    }
  }
  return NULL;
}
<commit_msg>DevTools: close remote debugging connection on IO thread when inspected tab closes.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/debugger/devtools_http_protocol_handler.h"

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/debugger/devtools_client_host.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/devtools_messages.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "googleurl/src/gurl.h"
#include "net/base/io_buffer.h"
#include "net/base/listen_socket.h"
#include "net/server/http_server_request_info.h"
#include "net/url_request/url_request_context.h"

const int kBufferSize = 16 * 1024;

namespace {

// An internal implementation of DevToolsClientHost that delegates
// messages sent for DevToolsClient to a DebuggerShell instance.
class DevToolsClientHostImpl : public DevToolsClientHost {
 public:
  explicit DevToolsClientHostImpl(HttpListenSocket* socket)
      : socket_(socket) {}
  ~DevToolsClientHostImpl() {}

  // DevToolsClientHost interface
  virtual void InspectedTabClosing() {
    ChromeThread::PostTask(
        ChromeThread::IO,
        FROM_HERE,
        NewRunnableMethod(socket_,
                          &HttpListenSocket::Close));
  }

  virtual void SendMessageToClient(const IPC::Message& msg) {
    IPC_BEGIN_MESSAGE_MAP(DevToolsClientHostImpl, msg)
      IPC_MESSAGE_HANDLER(DevToolsClientMsg_RpcMessage, OnRpcMessage);
      IPC_MESSAGE_UNHANDLED_ERROR()
    IPC_END_MESSAGE_MAP()
  }

  void NotifyCloseListener() {
    DevToolsClientHost::NotifyCloseListener();
  }
 private:
  // Message handling routines
  void OnRpcMessage(const DevToolsMessageData& data) {
    std::string message;
    message += "devtools$$dispatch(\"" + data.class_name + "\", \"" +
        data.method_name + "\"";
    for (std::vector<std::string>::const_iterator it = data.arguments.begin();
         it != data.arguments.end(); ++it) {
      std::string param = *it;
      if (!param.empty())
        message += ", " + param;
    }
    message += ")";
    socket_->SendOverWebSocket(message);
  }
  HttpListenSocket* socket_;
};

}

DevToolsHttpProtocolHandler::~DevToolsHttpProtocolHandler() {
  // Stop() must be called prior to this being called
  DCHECK(server_.get() == NULL);
}

void DevToolsHttpProtocolHandler::Start() {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(this, &DevToolsHttpProtocolHandler::Init));
}

void DevToolsHttpProtocolHandler::Stop() {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(this, &DevToolsHttpProtocolHandler::Teardown));
}

void DevToolsHttpProtocolHandler::OnHttpRequest(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& info) {
  if (info.path == "" || info.path == "/") {
    // Pages discovery request.
    ChromeThread::PostTask(
        ChromeThread::UI,
        FROM_HERE,
        NewRunnableMethod(this,
                          &DevToolsHttpProtocolHandler::OnHttpRequestUI,
                          socket,
                          info));
    return;
  }

  size_t pos = info.path.find("/devtools/");
  if (pos != 0) {
    socket->Send404();
    return;
  }

  // Proxy static files from chrome://devtools/*.
  URLRequest* request = new URLRequest(GURL("chrome:/" + info.path), this);
  Bind(request, socket);
  request->set_context(
      Profile::GetDefaultRequestContext()->GetURLRequestContext());
  request->Start();
}

void DevToolsHttpProtocolHandler::OnWebSocketRequest(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& request) {
  ChromeThread::PostTask(
      ChromeThread::UI,
      FROM_HERE,
      NewRunnableMethod(
          this,
          &DevToolsHttpProtocolHandler::OnWebSocketRequestUI,
          socket,
          request));
}

void DevToolsHttpProtocolHandler::OnWebSocketMessage(HttpListenSocket* socket,
                                                     const std::string& data) {
  ChromeThread::PostTask(
      ChromeThread::UI,
      FROM_HERE,
      NewRunnableMethod(
          this,
          &DevToolsHttpProtocolHandler::OnWebSocketMessageUI,
          socket,
          data));
}

void DevToolsHttpProtocolHandler::OnClose(HttpListenSocket* socket) {
  SocketToRequestsMap::iterator it = socket_to_requests_io_.find(socket);
  if (it != socket_to_requests_io_.end()) {
    // Dispose delegating socket.
    for (std::set<URLRequest*>::iterator it2 = it->second.begin();
         it2 != it->second.end(); ++it2) {
      URLRequest* request = *it2;
      request->Cancel();
      request_to_socket_io_.erase(request);
      request_to_buffer_io_.erase(request);
      delete request;
    }
    socket_to_requests_io_.erase(socket);
  }

  ChromeThread::PostTask(
      ChromeThread::UI,
      FROM_HERE,
      NewRunnableMethod(
          this,
          &DevToolsHttpProtocolHandler::OnCloseUI,
          socket));
}

void DevToolsHttpProtocolHandler::OnHttpRequestUI(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& info) {
  std::string response = "";
  for (BrowserList::const_iterator it = BrowserList::begin(),
       end = BrowserList::end(); it != end; ++it) {
    TabStripModel* model = (*it)->tabstrip_model();
    for (int i = 0, size = model->count(); i < size; ++i) {
      TabContents* tab_contents = model->GetTabContentsAt(i);
      NavigationController& controller = tab_contents->controller();
      NavigationEntry* entry = controller.GetActiveEntry();
      if (entry == NULL)
        continue;

      if (!entry->url().is_valid())
        continue;

      DevToolsClientHost* client_host = DevToolsManager::GetInstance()->
          GetDevToolsClientHostFor(tab_contents->render_view_host());
      if (!client_host) {
        response += StringPrintf(
            "%s (%s)
",
            controller.session_id().id(),
            UTF16ToUTF8(entry->title()).c_str(),
            entry->url().spec().c_str());
      } else {
        response += StringPrintf(
            "%s (%s)
",
            UTF16ToUTF8(entry->title()).c_str(),
            entry->url().spec().c_str());
      }
    }
  }
  response += "";
  Send200(socket, response, "text/html");
}

void DevToolsHttpProtocolHandler::OnWebSocketRequestUI(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& request) {
  std::string prefix = "/devtools/page/";
  size_t pos = request.path.find(prefix);
  if (pos != 0) {
    Send404(socket);
    return;
  }
  std::string page_id = request.path.substr(prefix.length());
  int id = 0;
  if (!StringToInt(page_id, &id)) {
    Send500(socket, "Invalid page id: " + page_id);
    return;
  }

  TabContents* tab_contents = GetTabContents(id);
  if (tab_contents == NULL) {
    Send500(socket, "No such page id: " + page_id);
    return;
  }

  DevToolsManager* manager = DevToolsManager::GetInstance();
  if (manager->GetDevToolsClientHostFor(tab_contents->render_view_host())) {
    Send500(socket, "Page with given id is being inspected: " + page_id);
    return;
  }

  DevToolsClientHostImpl* client_host = new DevToolsClientHostImpl(socket);
  socket_to_client_host_ui_[socket] = client_host;

  manager->RegisterDevToolsClientHostFor(
      tab_contents->render_view_host(),
      client_host);
  AcceptWebSocket(socket, request);
}

void DevToolsHttpProtocolHandler::OnWebSocketMessageUI(
    HttpListenSocket* socket,
    const std::string& d) {
  SocketToClientHostMap::iterator it = socket_to_client_host_ui_.find(socket);
  if (it == socket_to_client_host_ui_.end())
    return;

  std::string data = d;
  // TODO(pfeldman): Replace with proper parsing / dispatching.
  DevToolsMessageData message_data;
  message_data.class_name = "ToolsAgent";
  message_data.method_name = "dispatchOnInspectorController";

  size_t pos = data.find(" ");
  message_data.arguments.push_back(data.substr(0, pos));
  data = data.substr(pos + 1);

  message_data.arguments.push_back(data);

  DevToolsManager* manager = DevToolsManager::GetInstance();
  manager->ForwardToDevToolsAgent(it->second,
      DevToolsAgentMsg_RpcMessage(DevToolsMessageData(message_data)));
}

void DevToolsHttpProtocolHandler::OnCloseUI(HttpListenSocket* socket) {
  SocketToClientHostMap::iterator it = socket_to_client_host_ui_.find(socket);
  if (it == socket_to_client_host_ui_.end())
    return;
  DevToolsClientHostImpl* client_host =
      static_cast<DevToolsClientHostImpl*>(it->second);
  client_host->NotifyCloseListener();
  delete client_host;
  socket_to_client_host_ui_.erase(socket);
}

void DevToolsHttpProtocolHandler::OnResponseStarted(URLRequest* request) {
  RequestToSocketMap::iterator it = request_to_socket_io_.find(request);
  if (it == request_to_socket_io_.end())
    return;

  HttpListenSocket* socket = it->second;

  int expected_size = static_cast<int>(request->GetExpectedContentSize());

  std::string content_type;
  request->GetMimeType(&content_type);

  if (request->status().is_success()) {
    socket->Send(StringPrintf("HTTP/1.1 200 OK\r\n"
                              "Content-Type:%s\r\n"
                              "Content-Length:%d\r\n"
                              "\r\n",
                              content_type.c_str(),
                              expected_size));
  } else {
    socket->Send404();
  }

  int bytes_read = 0;
  // Some servers may treat HEAD requests as GET requests.  To free up the
  // network connection as soon as possible, signal that the request has
  // completed immediately, without trying to read any data back (all we care
  // about is the response code and headers, which we already have).
  net::IOBuffer* buffer = request_to_buffer_io_[request].get();
  if (request->status().is_success())
    request->Read(buffer, kBufferSize, &bytes_read);
  OnReadCompleted(request, bytes_read);
}

void DevToolsHttpProtocolHandler::OnReadCompleted(URLRequest* request,
                                                  int bytes_read) {
  RequestToSocketMap::iterator it = request_to_socket_io_.find(request);
  if (it == request_to_socket_io_.end())
    return;

  HttpListenSocket* socket = it->second;

  net::IOBuffer* buffer = request_to_buffer_io_[request].get();
  do {
    if (!request->status().is_success() || bytes_read <= 0)
      break;
    socket->Send(buffer->data(), bytes_read);
  } while (request->Read(buffer, kBufferSize, &bytes_read));

  // See comments re: HEAD requests in OnResponseStarted().
  if (!request->status().is_io_pending())
    RequestCompleted(request);
}

DevToolsHttpProtocolHandler::DevToolsHttpProtocolHandler(int port)
    : port_(port),
      server_(NULL) {
}

void DevToolsHttpProtocolHandler::Init() {
  server_ = HttpListenSocket::Listen("127.0.0.1", port_, this);
}

// Run on I/O thread
void DevToolsHttpProtocolHandler::Teardown() {
  server_ = NULL;
}

void DevToolsHttpProtocolHandler::Bind(URLRequest* request,
                                       HttpListenSocket* socket) {
  request_to_socket_io_[request] = socket;
  SocketToRequestsMap::iterator it = socket_to_requests_io_.find(socket);
  if (it == socket_to_requests_io_.end()) {
    std::pair<HttpListenSocket*, std::set<URLRequest*> > value(
        socket,
        std::set<URLRequest*>());
    it = socket_to_requests_io_.insert(value).first;
  }
  it->second.insert(request);
  request_to_buffer_io_[request] = new net::IOBuffer(kBufferSize);
}

void DevToolsHttpProtocolHandler::RequestCompleted(URLRequest* request) {
  RequestToSocketMap::iterator it = request_to_socket_io_.find(request);
  if (it == request_to_socket_io_.end())
    return;

  HttpListenSocket* socket = it->second;
  request_to_socket_io_.erase(request);
  SocketToRequestsMap::iterator it2 = socket_to_requests_io_.find(socket);
  it2->second.erase(request);
  request_to_buffer_io_.erase(request);
  delete request;
}

void DevToolsHttpProtocolHandler::Send200(HttpListenSocket* socket,
                                          const std::string& data,
                                          const std::string& mime_type) {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(socket,
                        &HttpListenSocket::Send200,
                        data,
                        mime_type));
}

void DevToolsHttpProtocolHandler::Send404(HttpListenSocket* socket) {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(socket,
                        &HttpListenSocket::Send404));
}

void DevToolsHttpProtocolHandler::Send500(HttpListenSocket* socket,
                                          const std::string& message) {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(socket,
                        &HttpListenSocket::Send500,
                        message));
}

void DevToolsHttpProtocolHandler::AcceptWebSocket(
    HttpListenSocket* socket,
    const HttpServerRequestInfo& request) {
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(socket,
                        &HttpListenSocket::AcceptWebSocket,
                        request));
}

TabContents* DevToolsHttpProtocolHandler::GetTabContents(int session_id) {
  for (BrowserList::const_iterator it = BrowserList::begin(),
       end = BrowserList::end(); it != end; ++it) {
    TabStripModel* model = (*it)->tabstrip_model();
    for (int i = 0, size = model->count(); i < size; ++i) {
      NavigationController& controller =
          model->GetTabContentsAt(i)->controller();
      if (controller.session_id().id() == session_id)
        return controller.tab_contents();
    }
  }
  return NULL;
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 "slotted_disk_user.H"

#include "fclaw2d_forestclaw.H"
#include "fclaw2d_clawpatch.H"
#include "fc2d_clawpack46.H"

static fclaw2d_vtable_t vt;
static fc2d_clawpack46_vtable_t classic_claw;

void slotted_disk_link_solvers(fclaw2d_domain_t *domain)
{
    fclaw2d_init_vtable(&vt);
    fc2d_clawpack46_init_vtable(&classic_claw);

    vt.problem_setup             = &slotted_disk_problem_setup;

    vt.patch_setup               = &slotted_disk_patch_setup;

    vt.patch_initialize          = &slotted_disk_qinit;
    vt.patch_physical_bc         = &fc2d_clawpack46_bc2;

    vt.patch_single_step_update  = &slotted_disk_update;
    classic_claw.rpn2            = &RPN2;
    classic_claw.rpt2            = &RPT2;

    fclaw2d_set_vtable(domain,&vt);
    fc2d_clawpack46_set_vtable(&classic_claw);
}

void slotted_disk_problem_setup(fclaw2d_domain_t* domain)
{
    const user_options_t *user;
    user = (user_options_t*) fclaw2d_domain_get_user_options(domain);
    SETPROB_TRANSPORT(&user->vflag,&user->init_choice);
}

void slotted_disk_patch_setup(fclaw2d_domain_t *domain,
                              fclaw2d_patch_t *this_patch,
                              int this_block_idx,
                              int this_patch_idx)
{
    int mx, my, mbc, maux;
    double xlower,ylower, dx,dy;
    double *xp,*yp,*zp,*xd,*yd,*zd;
    double *aux, *area;

    fclaw2d_clawpatch_grid_data(domain,this_patch,&mx,&my,&mbc,
                                &xlower,&ylower,&dx,&dy);

    fc2d_clawpack46_define_auxarray(domain,this_patch);
    fc2d_clawpack46_aux_data(domain,this_patch,&aux,&maux);

    fclaw2d_clawpatch_metric_data(domain,this_patch,&xp,&yp,&zp,
                                  &xd,&yd,&zd,&area);

    SETAUX_TRANSPORT(&mx,&my,&mbc,&xlower,&ylower,&dx,&dy,
                      &maux,aux,&this_block_idx,xd,yd,zd,area);
}

void slotted_disk_qinit(fclaw2d_domain_t *domain,
                        fclaw2d_patch_t *this_patch,
                        int this_block_idx,
                        int this_patch_idx)
{
    int mx, my, mbc, meqn, maux;
    double xlower,ylower, dx,dy;
    double *xp,*yp,*zp,*xd,*yd,*zd;
    double *aux, *area;
    double *q;

    fclaw2d_clawpatch_grid_data(domain,this_patch,&mx,&my,&mbc,
                                &xlower,&ylower,&dx,&dy);

    fc2d_clawpack46_aux_data(domain,this_patch,&aux,&maux);

    fclaw2d_clawpatch_metric_data(domain,this_patch,&xp,&yp,&zp,&xd,&yd,&zd,&area);
    fclaw2d_clawpatch_soln_data(domain,this_patch,&q,&meqn);

    QINIT_TRANSPORT(&mx,&my,&meqn,&mbc,&xlower,&ylower,&dx,&dy,q,&maux,aux,
                     &this_block_idx,xp,yp,zp);
}

void slotted_disk_b4step2(fclaw2d_domain_t *domain,
                          fclaw2d_patch_t *this_patch,
                          int this_block_idx,
                          int this_patch_idx,
                          double t,
                          double dt)
{
    int mx, my, mbc, maux;
    double xlower,ylower, dx,dy;
    double *xp,*yp,*zp,*xd,*yd,*zd;
    double *aux, *area;

    fclaw2d_clawpatch_grid_data(domain,this_patch,&mx,&my,&mbc,
                                &xlower,&ylower,&dx,&dy);

    fc2d_clawpack46_aux_data(domain,this_patch,&aux,&maux);

    fclaw2d_clawpatch_metric_data(domain,this_patch,&xp,&yp,&zp,&xd,&yd,&zd,&area);

    B4STEP2_TRANSPORT(&mx,&my,&mbc,&dx,&dy,&t,&maux,aux,&this_block_idx,xd,yd,zd);
}

/* A special update is needed, since we are calling a specialized b4step2
   that doesn't call B4STEP2 with the classic signature */
double slotted_disk_update(fclaw2d_domain_t *domain,
                           fclaw2d_patch_t *this_patch,
                           int this_block_idx,
                           int this_patch_idx,
                           double t,
                           double dt)
{
    slotted_disk_b4step2(domain,this_patch,this_block_idx,
                         this_patch_idx,t,dt);

    double maxcfl = fc2d_clawpack46_step2(domain,this_patch,this_block_idx,
                                       this_patch_idx,t,dt);

    return maxcfl;
}
<commit_msg>(slotted_disk) Fix header issue (again)<commit_after>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 "slotted_disk_user.H"

#include "fclaw2d_forestclaw.h"
#include "fclaw2d_clawpatch.h"
#include "fc2d_clawpack46.h"

static fclaw2d_vtable_t vt;
static fc2d_clawpack46_vtable_t classic_claw;

void slotted_disk_link_solvers(fclaw2d_domain_t *domain)
{
    fclaw2d_init_vtable(&vt);
    fc2d_clawpack46_init_vtable(&classic_claw);

    vt.problem_setup             = &slotted_disk_problem_setup;

    vt.patch_setup               = &slotted_disk_patch_setup;

    vt.patch_initialize          = &slotted_disk_qinit;
    vt.patch_physical_bc         = &fc2d_clawpack46_bc2;

    vt.patch_single_step_update  = &slotted_disk_update;
    classic_claw.rpn2            = &RPN2;
    classic_claw.rpt2            = &RPT2;

    fclaw2d_set_vtable(domain,&vt);
    fc2d_clawpack46_set_vtable(&classic_claw);
}

void slotted_disk_problem_setup(fclaw2d_domain_t* domain)
{
    const user_options_t *user;
    user = (user_options_t*) fclaw2d_domain_get_user_options(domain);
    SETPROB_TRANSPORT(&user->vflag,&user->init_choice);
}

void slotted_disk_patch_setup(fclaw2d_domain_t *domain,
                              fclaw2d_patch_t *this_patch,
                              int this_block_idx,
                              int this_patch_idx)
{
    int mx, my, mbc, maux;
    double xlower,ylower, dx,dy;
    double *xp,*yp,*zp,*xd,*yd,*zd;
    double *aux, *area;

    fclaw2d_clawpatch_grid_data(domain,this_patch,&mx,&my,&mbc,
                                &xlower,&ylower,&dx,&dy);

    fc2d_clawpack46_define_auxarray(domain,this_patch);
    fc2d_clawpack46_aux_data(domain,this_patch,&aux,&maux);

    fclaw2d_clawpatch_metric_data(domain,this_patch,&xp,&yp,&zp,
                                  &xd,&yd,&zd,&area);

    SETAUX_TRANSPORT(&mx,&my,&mbc,&xlower,&ylower,&dx,&dy,
                      &maux,aux,&this_block_idx,xd,yd,zd,area);
}

void slotted_disk_qinit(fclaw2d_domain_t *domain,
                        fclaw2d_patch_t *this_patch,
                        int this_block_idx,
                        int this_patch_idx)
{
    int mx, my, mbc, meqn, maux;
    double xlower,ylower, dx,dy;
    double *xp,*yp,*zp,*xd,*yd,*zd;
    double *aux, *area;
    double *q;

    fclaw2d_clawpatch_grid_data(domain,this_patch,&mx,&my,&mbc,
                                &xlower,&ylower,&dx,&dy);

    fc2d_clawpack46_aux_data(domain,this_patch,&aux,&maux);

    fclaw2d_clawpatch_metric_data(domain,this_patch,&xp,&yp,&zp,&xd,&yd,&zd,&area);
    fclaw2d_clawpatch_soln_data(domain,this_patch,&q,&meqn);

    QINIT_TRANSPORT(&mx,&my,&meqn,&mbc,&xlower,&ylower,&dx,&dy,q,&maux,aux,
                     &this_block_idx,xp,yp,zp);
}

void slotted_disk_b4step2(fclaw2d_domain_t *domain,
                          fclaw2d_patch_t *this_patch,
                          int this_block_idx,
                          int this_patch_idx,
                          double t,
                          double dt)
{
    int mx, my, mbc, maux;
    double xlower,ylower, dx,dy;
    double *xp,*yp,*zp,*xd,*yd,*zd;
    double *aux, *area;

    fclaw2d_clawpatch_grid_data(domain,this_patch,&mx,&my,&mbc,
                                &xlower,&ylower,&dx,&dy);

    fc2d_clawpack46_aux_data(domain,this_patch,&aux,&maux);

    fclaw2d_clawpatch_metric_data(domain,this_patch,&xp,&yp,&zp,&xd,&yd,&zd,&area);

    B4STEP2_TRANSPORT(&mx,&my,&mbc,&dx,&dy,&t,&maux,aux,&this_block_idx,xd,yd,zd);
}

/* A special update is needed, since we are calling a specialized b4step2
   that doesn't call B4STEP2 with the classic signature */
double slotted_disk_update(fclaw2d_domain_t *domain,
                           fclaw2d_patch_t *this_patch,
                           int this_block_idx,
                           int this_patch_idx,
                           double t,
                           double dt)
{
    slotted_disk_b4step2(domain,this_patch,this_block_idx,
                         this_patch_idx,t,dt);

    double maxcfl = fc2d_clawpack46_step2(domain,this_patch,this_block_idx,
                                       this_patch_idx,t,dt);

    return maxcfl;
}
<|endoftext|>