<commit_before>/*************************************************************************
 *
 *  $RCSfile: fmpgeimp.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: kz $ $Date: 2005-03-18 18:43:38 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_FMUNOPGE_HXX
#define _SVX_FMUNOPGE_HXX

#ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
#include <com/sun/star/sdbc/XDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XFORMCOMPONENT_HPP_
#include <com/sun/star/form/XFormComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XFORM_HPP_
#include <com/sun/star/form/XForm.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif

#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/dllapi.h"
#endif

class SvStream;
//BFS01class SdrIOHeader;
class FmFormObj;
class SdrObject;

//FORWARD_DECLARE_INTERFACE(uno,Reference)
FORWARD_DECLARE_INTERFACE(io,XObjectOutputStream)
FORWARD_DECLARE_INTERFACE(io,XObjectInputStream)
FORWARD_DECLARE_INTERFACE(container,XIndexContainer)

class SdrObjList;

DECLARE_LIST(FmObjectList, FmFormObj*);

//==================================================================
// FmFormPageImpl
// lauscht an allen Containern, um festzustellen, wann Objecte
// eingefuegt worden sind und wann diese entfernt wurden
//==================================================================

class SVX_DLLPRIVATE FmFormPageImpl
{
    friend class FmFormPage;
    friend class FmFormObj;
    friend class FmXFormShell;

    ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm>                xCurrentForm;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>  m_xForms;
    FmFormPage*             pPage;

    sal_Bool        m_bFirstActivation  : 1;
    sal_Bool        m_bAttemptedFormCreation : 2;

protected:
    FmFormPageImpl(FmFormPage* _pPage);
    FmFormPageImpl(FmFormPage* _pPage, const FmFormPageImpl& rImpl);
    ~FmFormPageImpl();

    void Init();

public:
    //  nur wichtig fuer den DesignMode
    void setCurForm(::com::sun::star::uno::Reference< ::com::sun::star::form::XForm> xForm);
    ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm> getDefaultForm();

    /** inserts a form component into the form component hierarchy

        If the given component does not yet belong into the form hierarchy, a suitable place for
        it is found, using <member>findFormForDataSource</member>, if possible.

        If no sutiable form is found, a new one is created, and also inserted into the
        hierarchy.
    */
    ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm> placeInFormComponentHierarchy(
        const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormComponent>& rContent,
        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource>& rDatabase = ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource>(),
        const ::rtl::OUString& rDBTitle = ::rtl::OUString(),
        const ::rtl::OUString& rCursorSource = ::rtl::OUString(),
        sal_Int32 nCommandType = 0
    );

    // activation handling
    inline  sal_Bool    hasEverBeenActivated( ) const { return !m_bFirstActivation; }
    inline  void        setHasBeenActivated( ) { m_bFirstActivation = sal_False; }

protected:
    // lesen und schreiben der Objecte
//BFS01 void WriteData(SvStream& rOut) const; //
//BFS01 void ReadData(const SdrIOHeader& rHead, SvStream& rIn); //

    void write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& OutStream) const;
    void read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& InStream);

    const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& getForms( bool _bForceCreate = true );

    void fillList(FmObjectList& rList, const SdrObjList& rObjList, sal_Bool bConnected) const;

    /** finds a form with a given data source signature
        @param rForm
            the form to start the search with. This form, including all possible sub forms,
            will be examined
        @param rDatabase
            the data source which to which the found form must be bound
        @param rCommand
            the desired Command property value of the sought-after form
        @param nCommandType
            the desired CommandType property value of the sought-after form
    */
    ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm> findFormForDataSource(
        const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm>& rForm,
        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource>& rDatabase,
        const ::rtl::OUString& rCommand,
        sal_Int32 nCommandType
    );

    ::rtl::OUString getDefaultName(
                        sal_Int16 _nClassId,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm>& _rxControls,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XServiceInfo >& _rxObject
                    ) const;

private:
    /** validates whether <member>xCurrentForm</member> is still valid and to be used

        There are situations where our current form becomes invalid, without us noticing this. Thus,
        every method which accesses <member>xCurrentForm</member> should beforehand validate the current
        form by calling this method.

        If <member>xCurrentForm</member> is not valid anymore, it is reset to <NULL/>.

        @since #i40086#
    */
    void    validateCurForm();

public:

    static UniString getDefaultName(
                        sal_Int16 nClassId,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XServiceInfo >& _rxObject
                    );

    ::rtl::OUString setUniqueName(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormComponent>& xFormComponent, const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm>& xControls);
    ::rtl::OUString getUniqueName(const ::rtl::OUString& rName, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& xNamedSet) const;
};

#endif // _SVX_FMUNOPGE_HXX

<commit_msg>INTEGRATION: CWS gcc4fwdecl (1.12.108); FILE MERGED 2005/06/01 18:18:20 pmladek 1.12.108.1: #i50075# Fixed forward declarations for gcc4 in svx<commit_after>/*************************************************************************
 *
 *  $RCSfile: fmpgeimp.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: obo $ $Date: 2005-06-14 16:33:47 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SVX_FMUNOPGE_HXX
#define _SVX_FMUNOPGE_HXX

#ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
#include <com/sun/star/sdbc/XDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XFORMCOMPONENT_HPP_
#include <com/sun/star/form/XFormComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XFORM_HPP_
#include <com/sun/star/form/XForm.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
#include <com/sun/star/container/XNameContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif

#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/dllapi.h"
#endif

class SvStream;
//BFS01class SdrIOHeader;
class FmFormObj;
class FmFormPage;
class SdrObject;

//FORWARD_DECLARE_INTERFACE(uno,Reference)
FORWARD_DECLARE_INTERFACE(io,XObjectOutputStream)
FORWARD_DECLARE_INTERFACE(io,XObjectInputStream)
FORWARD_DECLARE_INTERFACE(container,XIndexContainer)

class SdrObjList;

DECLARE_LIST(FmObjectList, FmFormObj*);

//==================================================================
// FmFormPageImpl
// lauscht an allen Containern, um festzustellen, wann Objecte
// eingefuegt worden sind und wann diese entfernt wurden
//==================================================================

class SVX_DLLPRIVATE FmFormPageImpl
{
    friend class FmFormPage;
    friend class FmFormObj;
    friend class FmXFormShell;

    ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm>                xCurrentForm;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>  m_xForms;
    FmFormPage*             pPage;

    sal_Bool        m_bFirstActivation  : 1;
    sal_Bool        m_bAttemptedFormCreation : 2;

protected:
    FmFormPageImpl(FmFormPage* _pPage);
    FmFormPageImpl(FmFormPage* _pPage, const FmFormPageImpl& rImpl);
    ~FmFormPageImpl();

    void Init();

public:
    //  nur wichtig fuer den DesignMode
    void setCurForm(::com::sun::star::uno::Reference< ::com::sun::star::form::XForm> xForm);
    ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm> getDefaultForm();

    /** inserts a form component into the form component hierarchy

        If the given component does not yet belong into the form hierarchy, a suitable place for
        it is found, using <member>findFormForDataSource</member>, if possible.

        If no sutiable form is found, a new one is created, and also inserted into the
        hierarchy.
    */
    ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm> placeInFormComponentHierarchy(
        const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormComponent>& rContent,
        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource>& rDatabase = ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource>(),
        const ::rtl::OUString& rDBTitle = ::rtl::OUString(),
        const ::rtl::OUString& rCursorSource = ::rtl::OUString(),
        sal_Int32 nCommandType = 0
    );

    // activation handling
    inline  sal_Bool    hasEverBeenActivated( ) const { return !m_bFirstActivation; }
    inline  void        setHasBeenActivated( ) { m_bFirstActivation = sal_False; }

protected:
    // lesen und schreiben der Objecte
//BFS01 void WriteData(SvStream& rOut) const; //
//BFS01 void ReadData(const SdrIOHeader& rHead, SvStream& rIn); //

    void write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& OutStream) const;
    void read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& InStream);

    const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer>& getForms( bool _bForceCreate = true );

    void fillList(FmObjectList& rList, const SdrObjList& rObjList, sal_Bool bConnected) const;

    /** finds a form with a given data source signature
        @param rForm
            the form to start the search with. This form, including all possible sub forms,
            will be examined
        @param rDatabase
            the data source which to which the found form must be bound
        @param rCommand
            the desired Command property value of the sought-after form
        @param nCommandType
            the desired CommandType property value of the sought-after form
    */
    ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm> findFormForDataSource(
        const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm>& rForm,
        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource>& rDatabase,
        const ::rtl::OUString& rCommand,
        sal_Int32 nCommandType
    );

    ::rtl::OUString getDefaultName(
                        sal_Int16 _nClassId,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm>& _rxControls,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XServiceInfo >& _rxObject
                    ) const;

private:
    /** validates whether <member>xCurrentForm</member> is still valid and to be used

        There are situations where our current form becomes invalid, without us noticing this. Thus,
        every method which accesses <member>xCurrentForm</member> should beforehand validate the current
        form by calling this method.

        If <member>xCurrentForm</member> is not valid anymore, it is reset to <NULL/>.

        @since #i40086#
    */
    void    validateCurForm();

public:

    static UniString getDefaultName(
                        sal_Int16 nClassId,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XServiceInfo >& _rxObject
                    );

    ::rtl::OUString setUniqueName(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormComponent>& xFormComponent, const ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm>& xControls);
    ::rtl::OUString getUniqueName(const ::rtl::OUString& rName, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& xNamedSet) const;
};

#endif // _SVX_FMUNOPGE_HXX

<|endoftext|>


<commit_before>// arm-poky-linux-gnueabi-gcc -lopencv_video -lopencv_core -lopencv_highgui -lopencv_imgproc -lstdc++ -lpthread -shared-libgcc opencv.cpp -o opencv

#include "evision.h"
#include "tracer.h"
#include "gpio.h"

// Global variables
GPIO pwm_right(1, "out"), pwm_left(3, "out"); // led_right(2 , "out");
GPIO led_front(5, "out"), led_R(4, "out"), start(7 ,"out"); // 0,2,6 bulit
int high_right = 600, high_left = 600, period = 20000; //PWM high time in us
int top_edge = 50, servo_offset = 0, road_offset = 0;
int car_left_offset = 0, obstacle_offset = 0;

// GUI globals
cv::Mat guiframe;
bool new_frame = false;
bool running = true;

// Window titles
char main_window_name[] = "Lightning Asystant :: Team eVision";
char settings_window_name[] = "Settings :: Team eVision";

// Settings variables
int settings_show_step = 0;
int settings_contrast = 0;
int settings_blur = 1;
int settings_threshold = 128;
int settings_servo_offset = 500;
int settings_road_approx = 5;
int settings_middle_line = 240;

// Graphics
std::vector<std::vector<cv::Point>> contours;

//Functions declaration
void pwm_servo_right(int);
void pwm_servo_left(int);
void set_servo_offset(int);
void set_road_offset(int);
void set_car_left_offset(int);
void set_obstacle_offset(int);

int main(int argc, char** argv)
{
    pthread_t processing_thread;
    long time_old;
    int fps_counter = 0;
    int gui_key;

	// for cpu affinity
	cpu_set_t cpuset;
	int cpu = 0;

	CPU_ZERO(&cpuset);       //clears the cpuset
	CPU_SET( cpu , &cpuset); //set CPU 2 on cpuset
	sched_setaffinity(0, sizeof(cpuset), &cpuset);

    // process priority
    setpriority(PRIO_PROCESS, 0, -20);

    // GUI setup
	cv::namedWindow(main_window_name);

	// Setup window
	cv::namedWindow(settings_window_name);
	cv::createTrackbar("Show Step   ", settings_window_name, &settings_show_step, LAST_STEP-1);
	cv::createTrackbar("Contrast    ", settings_window_name, &settings_contrast, 1);
	cv::createTrackbar("Mean Blur   ", settings_window_name, &settings_blur, 1);
	cv::createTrackbar("Threshold   ", settings_window_name, &settings_threshold, 255);
	cv::createTrackbar("Road Approx ", settings_window_name, &settings_road_approx, 30);
	cv::createTrackbar("Middle Line ", settings_window_name, &settings_middle_line, 320);
	cv::createTrackbar("Servo Offset", settings_window_name, &settings_servo_offset, 1000);
	cv::createTrackbar("Servo Right ", settings_window_name, &high_right, 1500);
	cv::createTrackbar("Servo Left  ", settings_window_name, &high_left, 1500);

	pthread_create(&processing_thread, NULL, processing_thread_function, NULL);
	//pthread_create(&pwm_thread, NULL, pwm_thread_function, NULL);

    while(running){

    	while(!new_frame){ } // loop

		cv::imshow(main_window_name, guiframe);

		// calculate fps
		if(time(NULL) != time_old){
			add_info(fps_counter);
			fps_counter = 1;
			time_old = time(NULL);
		} else {
			fps_counter++;
		}

		new_frame = 0;

		gui_key = cv::waitKey(5);
		if(gui_key >= 0) {
			gui_key %= 0xFF;

			// ESC
			if((gui_key == 43) || (gui_key == 27)){
				led_front.low();
				led_R.low();
				running = false;
			} else if((gui_key == 48) || (gui_key == 32)) {
				start.high(); // 1 = start/stop
				usleep(50000);
				start.low();
			} else if((gui_key == 50) || (gui_key == 66)) {
				led_front.toggle(); // 2 = faruri
			} else if((gui_key == 51) || (gui_key == 67)) {
				led_R.toggle(); // 3 = far pieton
			} else {
				std::cout << gui_key << std::endl;
			}
		}
    }

	pthread_join(processing_thread, NULL);

    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}

void send_frame_to_gui(cv::Mat &frame, int step){
	if((new_frame == 0) && (step == settings_show_step)){
		//cv::pyrUp(frame, guiframe);
		frame.copyTo(guiframe);
		new_frame = 1;
	}
}

bool contour_area(int a, int b){
	return cv::contourArea(contours[a]) > cv::contourArea(contours[b]);
}

bool get_obstacle(
	int parent,
	std::vector<std::vector<cv::Point>> contours,
	std::vector<cv::Vec4i> hierarchy,
	cv::Rect &obstacle){

	int start = hierarchy[parent][2];
	int closest = -1;
	bool found = false;

	while(start > 0){

		if(closest == -1){
			closest = start;
			found = true;
		} else if(cv::boundingRect(contours[start]).y > cv::boundingRect(contours[closest]).y){
			closest = start;
		}

		start = hierarchy[start][0];
	}

	if(found){
		obstacle = cv::boundingRect(contours[closest]);
	}

	return found;
}

void *processing_thread_function(void* unsused)
{
	cv::VideoCapture 	cap(0); // camera interface
    cv::Mat 			frame, cam_frame, bw_frame, blur_frame, contrast_frame;
    cv::Mat				threshold_frame, canny_frame, contour_frame;
    Tracer				processing_tracer;

	std::vector<std::vector<cv::Point>> road(2);
	std::vector<cv::Vec4i> hierarchy;

    // for cpu affinity
	cpu_set_t cpuset;
	int cpu = 1;

	CPU_ZERO(&cpuset);       //clears the cpuset
	CPU_SET( cpu , &cpuset); //set CPU 2 on cpuset
	sched_setaffinity(0, sizeof(cpuset), &cpuset);

    if(!cap.isOpened())  // check if we succeeded
    {
        std::cout << "Could not open default video device" << std::endl;
        pthread_exit(NULL);

    }

   	while(running) {
		if( !cap.read(frame) ){
			std::cout << "Camera was disconected";
			break;
		}

		cv::pyrDown(frame, cam_frame);
		send_frame_to_gui(cam_frame, SENSOR_IMAGE);
		processing_tracer.start();

		// All processing are done on gray image
		cv::cvtColor(cam_frame, bw_frame, CV_BGR2GRAY);
		processing_tracer.event("Convert to Gray");
		send_frame_to_gui(bw_frame, GRAY_IMAGE);

		// Increase contrast by distributing color histogram to contain all values
		if(settings_contrast){
			cv::equalizeHist(bw_frame, contrast_frame);
		} else {
			contrast_frame = bw_frame;
		}
		processing_tracer.event("Equalize histogram");
		send_frame_to_gui(contrast_frame, CONTRAST_IMAGE);

		// Apply a special blur filter which preserves edges
		if(settings_blur){
			cv::medianBlur(contrast_frame, blur_frame, 7);
		} else {
			blur_frame = contrast_frame;
		}
		processing_tracer.event("Median blur");
		send_frame_to_gui(blur_frame, BLUR_IMAGE);

		// detect edges using histeresys
		cv::Canny(contrast_frame, canny_frame, 30, 100);
		processing_tracer.event("Edge detection");
		send_frame_to_gui(canny_frame, CANNY_IMAGE);

		// Apply threshhold
		threshold(blur_frame, threshold_frame, settings_threshold, 255, CV_THRESH_BINARY);
		// Disable image top from detection to remove false edges
		cv::rectangle(threshold_frame, cv::Rect(0, 0, 320, top_edge), cv::Scalar(0), CV_FILLED);
		processing_tracer.event("Appling threshold");
		send_frame_to_gui(threshold_frame, THRESHOLD_IMAGE);

		// detect and paint contours

		cv::findContours(threshold_frame, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
		if(contours.size() > 1){

			std::vector<int> contour_indexes(contours.size());
			// create index vector
			for(unsigned int i = 0; i < contours.size(); i++){
				contour_indexes[i] = i;
			}

			// sorting index vector acording to controur area
			std::sort(contour_indexes.begin(), contour_indexes.end(), contour_area);

			cv::approxPolyDP(cv::Mat(contours[contour_indexes[0]]), road[0], settings_road_approx, true);
			cv::drawContours(cam_frame, road, 0, cv::Scalar(0, 255 ,0), 2);

			cv::approxPolyDP(cv::Mat(contours[contour_indexes[1]]), road[1], settings_road_approx, true);
			cv::drawContours(cam_frame, road, 1, cv::Scalar(255, 0, 0), 2);

			// get road offset
			int road_tmp = 600;
			for(unsigned int i = 0; i < road[0].size(); ++i){
				if((road[0][i].y == top_edge) && (road[0][i].x < road_tmp)){
					road_tmp = road[0][i].x;
				}
			}

			std::cout << road_tmp << std::endl;

			cv::Rect obstacle;
			if(get_obstacle(contour_indexes[0], contours, hierarchy, obstacle)){
				cv::rectangle(cam_frame, obstacle, cv::Scalar(0, 0, 255));
				std::cout << cv::Point(obstacle.x + (obstacle.width / 2), obstacle.y + (obstacle.height / 2)) << std::endl;
			}

			if(get_obstacle(contour_indexes[1], contours, hierarchy, obstacle)){
				cv::rectangle(cam_frame, obstacle, cv::Scalar(255, 0, 255));
			}

			cv::line(cam_frame, cv::Point(settings_middle_line, 320), cv::Point(settings_middle_line, top_edge), cv::Scalar(0, 255, 255));
		}

		processing_tracer.event("Contour detection");
		send_frame_to_gui(cam_frame, CONTOUR_IMAGE);

   		pwm_servo_right(high_right);
   		pwm_servo_left(high_left);
	}

	processing_tracer.end();
	pthread_exit(NULL);
}

void pwm_servo_right(int h_r){
	int static local_hr = 0;
	if(abs(h_r - local_hr) > 5){
		local_hr = h_r;
		pwm_right.high();
		usleep(local_hr);
		pwm_right.low();
		usleep(period - local_hr);
	}
}

void pwm_servo_left(int h_l){
	int static local_hl = 0;
	if(abs(h_l - local_hl) > 5){
		local_hl = h_l;
		pwm_left.high();
		usleep(local_hl);
		pwm_left.low();
		usleep(period - local_hl);
	}
}

void set_servo_offset(int servo_offset){
	high_right = high_right + servo_offset;
	high_left = high_left + servo_offset;
}

void set_road_offset(int road_offset){
	high_right = high_right + road_offset;
	high_left = high_left + road_offset;
}

void set_obstacle_offset(int y_position){
	obstacle_offset = int (0.9 * y_position + 15);
	high_right = high_right + obstacle_offset;
	//de facut dezactivarea obstacle_offset
}

void set_car_offset(int y_position){
	//?????
	high_left = high_left + car_left_offset;
}

void add_info(int fps){
	// white canvas
	cv::Mat img_info (25, 320, CV_8UC3, cv::Scalar(255, 255, 255));

	cv::putText(img_info, std::string("FPS: ") + std::to_string(fps), cv::Point(5, 20),
			cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, cv::Scalar(0,0,255), 1, CV_AA);

	cv::imshow(settings_window_name, img_info);
}
<commit_msg>Road offset wit limitations, should be between 50 and 250px<commit_after>// arm-poky-linux-gnueabi-gcc -lopencv_video -lopencv_core -lopencv_highgui -lopencv_imgproc -lstdc++ -lpthread -shared-libgcc opencv.cpp -o opencv

#include "evision.h"
#include "tracer.h"
#include "gpio.h"

// Global variables
GPIO pwm_right(1, "out"), pwm_left(3, "out"); // led_right(2 , "out");
GPIO led_front(5, "out"), led_R(4, "out"), start(7 ,"out"); // 0,2,6 bulit
int high_right = 600, high_left = 600, period = 20000; //PWM high time in us
int top_edge = 50, servo_offset = 0, road_offset = 0;
int car_left_offset = 0, obstacle_offset = 0;

// GUI globals
cv::Mat guiframe;
bool new_frame = false;
bool running = true;

// Window titles
char main_window_name[] = "Lightning Asystant :: Team eVision";
char settings_window_name[] = "Settings :: Team eVision";

// Settings variables
int settings_show_step = 0;
int settings_contrast = 0;
int settings_blur = 1;
int settings_threshold = 128;
int settings_servo_offset = 500;
int settings_road_approx = 5;
int settings_middle_line = 240;

// Graphics
std::vector<std::vector<cv::Point>> contours;

//Functions declaration
void pwm_servo_right(int);
void pwm_servo_left(int);
void set_servo_offset(int);
void set_road_offset(int);
void set_car_left_offset(int);
void set_obstacle_offset(int);

int main(int argc, char** argv)
{
    pthread_t processing_thread;
    long time_old;
    int fps_counter = 0;
    int gui_key;

	// for cpu affinity
	cpu_set_t cpuset;
	int cpu = 0;

	CPU_ZERO(&cpuset);       //clears the cpuset
	CPU_SET( cpu , &cpuset); //set CPU 2 on cpuset
	sched_setaffinity(0, sizeof(cpuset), &cpuset);

    // process priority
    setpriority(PRIO_PROCESS, 0, -20);

    // GUI setup
	cv::namedWindow(main_window_name);

	// Setup window
	cv::namedWindow(settings_window_name);
	cv::createTrackbar("Show Step   ", settings_window_name, &settings_show_step, LAST_STEP-1);
	cv::createTrackbar("Contrast    ", settings_window_name, &settings_contrast, 1);
	cv::createTrackbar("Mean Blur   ", settings_window_name, &settings_blur, 1);
	cv::createTrackbar("Threshold   ", settings_window_name, &settings_threshold, 255);
	cv::createTrackbar("Road Approx ", settings_window_name, &settings_road_approx, 30);
	cv::createTrackbar("Middle Line ", settings_window_name, &settings_middle_line, 320);
	cv::createTrackbar("Servo Offset", settings_window_name, &settings_servo_offset, 1000);
	cv::createTrackbar("Servo Right ", settings_window_name, &high_right, 1500);
	cv::createTrackbar("Servo Left  ", settings_window_name, &high_left, 1500);

	pthread_create(&processing_thread, NULL, processing_thread_function, NULL);
	//pthread_create(&pwm_thread, NULL, pwm_thread_function, NULL);

    while(running){

    	while(!new_frame){ } // loop

		cv::imshow(main_window_name, guiframe);

		// calculate fps
		if(time(NULL) != time_old){
			add_info(fps_counter);
			fps_counter = 1;
			time_old = time(NULL);
		} else {
			fps_counter++;
		}

		new_frame = 0;

		gui_key = cv::waitKey(5);
		if(gui_key >= 0) {
			gui_key %= 0xFF;

			// ESC
			if((gui_key == 43) || (gui_key == 27)){
				led_front.low();
				led_R.low();
				running = false;
			} else if((gui_key == 48) || (gui_key == 32)) {
				start.high(); // 1 = start/stop
				usleep(50000);
				start.low();
			} else if((gui_key == 50) || (gui_key == 66)) {
				led_front.toggle(); // 2 = faruri
			} else if((gui_key == 51) || (gui_key == 67)) {
				led_R.toggle(); // 3 = far pieton
			} else {
				std::cout << gui_key << std::endl;
			}
		}
    }

	pthread_join(processing_thread, NULL);

    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}

void send_frame_to_gui(cv::Mat &frame, int step){
	if((new_frame == 0) && (step == settings_show_step)){
		//cv::pyrUp(frame, guiframe);
		frame.copyTo(guiframe);
		new_frame = 1;
	}
}

bool contour_area(int a, int b){
	return cv::contourArea(contours[a]) > cv::contourArea(contours[b]);
}

bool get_obstacle(
	int parent,
	std::vector<std::vector<cv::Point>> contours,
	std::vector<cv::Vec4i> hierarchy,
	cv::Rect &obstacle){

	int start = hierarchy[parent][2];
	int closest = -1;
	bool found = false;

	while(start > 0){

		if(closest == -1){
			closest = start;
			found = true;
		} else if(cv::boundingRect(contours[start]).y > cv::boundingRect(contours[closest]).y){
			closest = start;
		}

		start = hierarchy[start][0];
	}

	if(found){
		obstacle = cv::boundingRect(contours[closest]);
	}

	return found;
}

void *processing_thread_function(void* unsused)
{
	cv::VideoCapture 	cap(0); // camera interface
    cv::Mat 			frame, cam_frame, bw_frame, blur_frame, contrast_frame;
    cv::Mat				threshold_frame, canny_frame, contour_frame;
    Tracer				processing_tracer;

	std::vector<std::vector<cv::Point>> road(2);
	std::vector<cv::Vec4i> hierarchy;

    // for cpu affinity
	cpu_set_t cpuset;
	int cpu = 1;

	CPU_ZERO(&cpuset);       //clears the cpuset
	CPU_SET( cpu , &cpuset); //set CPU 2 on cpuset
	sched_setaffinity(0, sizeof(cpuset), &cpuset);

    if(!cap.isOpened())  // check if we succeeded
    {
        std::cout << "Could not open default video device" << std::endl;
        pthread_exit(NULL);

    }

   	while(running) {
		if( !cap.read(frame) ){
			std::cout << "Camera was disconected";
			break;
		}

		cv::pyrDown(frame, cam_frame);
		send_frame_to_gui(cam_frame, SENSOR_IMAGE);
		processing_tracer.start();

		// All processing are done on gray image
		cv::cvtColor(cam_frame, bw_frame, CV_BGR2GRAY);
		processing_tracer.event("Convert to Gray");
		send_frame_to_gui(bw_frame, GRAY_IMAGE);

		// Increase contrast by distributing color histogram to contain all values
		if(settings_contrast){
			cv::equalizeHist(bw_frame, contrast_frame);
		} else {
			contrast_frame = bw_frame;
		}
		processing_tracer.event("Equalize histogram");
		send_frame_to_gui(contrast_frame, CONTRAST_IMAGE);

		// Apply a special blur filter which preserves edges
		if(settings_blur){
			cv::medianBlur(contrast_frame, blur_frame, 7);
		} else {
			blur_frame = contrast_frame;
		}
		processing_tracer.event("Median blur");
		send_frame_to_gui(blur_frame, BLUR_IMAGE);

		// detect edges using histeresys
		cv::Canny(contrast_frame, canny_frame, 30, 100);
		processing_tracer.event("Edge detection");
		send_frame_to_gui(canny_frame, CANNY_IMAGE);

		// Apply threshhold
		threshold(blur_frame, threshold_frame, settings_threshold, 255, CV_THRESH_BINARY);
		// Disable image top from detection to remove false edges
		cv::rectangle(threshold_frame, cv::Rect(0, 0, 320, top_edge), cv::Scalar(0), CV_FILLED);
		processing_tracer.event("Appling threshold");
		send_frame_to_gui(threshold_frame, THRESHOLD_IMAGE);

		// detect and paint contours

		cv::findContours(threshold_frame, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
		if(contours.size() > 1){

			std::vector<int> contour_indexes(contours.size());
			// create index vector
			for(unsigned int i = 0; i < contours.size(); i++){
				contour_indexes[i] = i;
			}

			// sorting index vector acording to controur area
			std::sort(contour_indexes.begin(), contour_indexes.end(), contour_area);

			cv::approxPolyDP(cv::Mat(contours[contour_indexes[0]]), road[0], settings_road_approx, true);
			cv::drawContours(cam_frame, road, 0, cv::Scalar(0, 255 ,0), 2);

			cv::approxPolyDP(cv::Mat(contours[contour_indexes[1]]), road[1], settings_road_approx, true);
			cv::drawContours(cam_frame, road, 1, cv::Scalar(255, 0, 0), 2);

			// get road offset
			// reference point is the left most point from the top edge of road contour
			int new_road_offset = 600;
			for(unsigned int i = 0; i < road[0].size(); ++i){
				if((road[0][i].y == top_edge) && (road[0][i].x < new_road_offset)){
					new_road_offset = road[0][i].x;
				}
			}

			if((new_road_offset > 50) && (new_road_offset < 250)){
				road_offset = new_road_offset;
			}

			std::cout << road_offset << std::endl;

			cv::Rect obstacle;
			if(get_obstacle(contour_indexes[0], contours, hierarchy, obstacle)){
				cv::rectangle(cam_frame, obstacle, cv::Scalar(0, 0, 255));
				std::cout << cv::Point(obstacle.x + (obstacle.width / 2), obstacle.y + (obstacle.height / 2)) << std::endl;
			}

			if(get_obstacle(contour_indexes[1], contours, hierarchy, obstacle)){
				cv::rectangle(cam_frame, obstacle, cv::Scalar(255, 0, 255));
			}

			cv::line(cam_frame, cv::Point(settings_middle_line, 320), cv::Point(settings_middle_line, top_edge), cv::Scalar(0, 255, 255));
		}

		processing_tracer.event("Contour detection");
		send_frame_to_gui(cam_frame, CONTOUR_IMAGE);

   		pwm_servo_right(high_right);
   		pwm_servo_left(high_left);
	}

	processing_tracer.end();
	pthread_exit(NULL);
}

void pwm_servo_right(int h_r){
	int static local_hr = 0;
	if(abs(h_r - local_hr) > 5){
		local_hr = h_r;
		pwm_right.high();
		usleep(local_hr);
		pwm_right.low();
		usleep(period - local_hr);
	}
}

void pwm_servo_left(int h_l){
	int static local_hl = 0;
	if(abs(h_l - local_hl) > 5){
		local_hl = h_l;
		pwm_left.high();
		usleep(local_hl);
		pwm_left.low();
		usleep(period - local_hl);
	}
}

void set_servo_offset(int servo_offset){
	high_right = high_right + servo_offset;
	high_left = high_left + servo_offset;
}

void set_road_offset(int road_offset){
	high_right = high_right + road_offset;
	high_left = high_left + road_offset;
}

void set_obstacle_offset(int y_position){
	obstacle_offset = int (0.9 * y_position + 15);
	high_right = high_right + obstacle_offset;
	//de facut dezactivarea obstacle_offset
}

void set_car_offset(int y_position){
	//?????
	high_left = high_left + car_left_offset;
}

void add_info(int fps){
	// white canvas
	cv::Mat img_info (25, 320, CV_8UC3, cv::Scalar(255, 255, 255));

	cv::putText(img_info, std::string("FPS: ") + std::to_string(fps), cv::Point(5, 20),
			cv::FONT_HERSHEY_COMPLEX_SMALL, 0.8, cv::Scalar(0,0,255), 1, CV_AA);

	cv::imshow(settings_window_name, img_info);
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QHash>
#include <QDebug>
#include <QX11Info>

#include "windowinfo.h"
#include "xtools/xatomcache.h"

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xdamage.h>

class WindowInfo::WindowData
{

public:
    //! Constructs a window data object
    WindowData(Window id) :
            window(id),
            transientFor(0),
            title(),
            types(),
            states(),
            pid(0),
            pixmapSerial(0)
    {
    }

    //! Destructor
    ~WindowData()
    {
    }

    //! The X window ID
    Window window;

    //! The ID of the window this window is transient for
    Window transientFor;

    //! The title of the window
    QString title;

    //! The window types associated with this window
    QList<Atom> types;

    //! The status atoms of this window
    QList<Atom> states;

    int pid;

    int pixmapSerial;
};

//! Storage for the WindowInfo data objects. A central storage enables constructing
//! new WindowInfo objects with shared data.
static QHash<Window, WindowInfo * > windowDatas;

WindowInfo *WindowInfo::windowFor(Qt::HANDLE wid)
{
    if (WindowInfo *wi = windowDatas.value(wid)) {
        return wi;
    } else {
        return new WindowInfo(wid);
    }
}

WindowInfo::WindowInfo(Qt::HANDLE window)
    : d(new WindowData(window))
{
    qDebug() << Q_FUNC_INFO << "Created WindowInfo for " << window;
    updateWindowTitle();
    updateWindowProperties();
    windowDatas[window] = this;
}

WindowInfo::~WindowInfo()
{
    qDebug() << Q_FUNC_INFO << "Destroyed windwo for " << d->window;
    windowDatas.remove(d->window);
}

const QString& WindowInfo::title() const
{
    return d->title;
}

Qt::HANDLE WindowInfo::window() const
{
    return d->window;
}

Qt::HANDLE WindowInfo::transientFor() const
{
    return d->transientFor;
}

QList<Qt::HANDLE> WindowInfo::types() const
{
    return d->types;
}

QList<Qt::HANDLE> WindowInfo::states() const
{
    return d->states;
}

bool operator==(const WindowInfo &wi1, const WindowInfo &wi2)
{
    return wi1.window() == wi2.window();
}

bool WindowInfo::updateWindowTitle()
{
    Display *dpy = QX11Info::display();
    XTextProperty textProperty;
    bool updated = false;
    int result = XGetTextProperty(dpy, d->window, &textProperty, AtomCache::atom("_NET_WM_NAME"));
    if (result == 0) {
        result = XGetWMName(dpy, d->window, &textProperty);
    }

    if (result != 0) {
        d->title = QString::fromUtf8((const char *)textProperty.value);
        XFree(textProperty.value);
        updated = true;
    }
    return updated;
}

void WindowInfo::updateWindowProperties()
{
    d->types = getWindowProperties(d->window, AtomCache::atom("_NET_WM_WINDOW_TYPE"));
    d->states = getWindowProperties(d->window, AtomCache::atom("_NET_WM_STATE"));

    if (!XGetTransientForHint(QX11Info::display(), d->window, &d->transientFor) || d->transientFor == d->window) {
        d->transientFor = 0;
    }
}

int WindowInfo::pid() const
{
    return d->pid;
}

void WindowInfo::setPid(int pid)
{
    d->pid = pid;
}

QList<Qt::HANDLE> WindowInfo::getWindowProperties(Qt::HANDLE winId, Qt::HANDLE propertyAtom, long maxCount)
{
    QList<Atom> properties;
    Atom actualType;
    int actualFormat;
    unsigned long numTypeItems, bytesLeft;
    unsigned char *typeData = NULL;

    Status result = XGetWindowProperty(QX11Info::display(), winId, propertyAtom, 0L, maxCount, False, XA_ATOM, &actualType, &actualFormat, &numTypeItems, &bytesLeft, &typeData);
    if (result == Success) {
        Atom *type = (Atom *) typeData;
        for (unsigned int n = 0; n < numTypeItems; n++) {
            properties.append(type[n]);
        }
        XFree(typeData);
    }
    return properties;
}

Qt::HANDLE WindowInfo::pixmapSerial() const
{
    return d->pixmapSerial;
}

void WindowInfo::setPixmapSerial(Qt::HANDLE pixmapSerial)
{
    d->pixmapSerial = pixmapSerial;
    qDebug() << Q_FUNC_INFO << "Changed pixmap serial on " << d->window << " to " << d->pixmapSerial;
    emit pixmapSerialChanged();
}

bool WindowInfo::handleXEvent(const XEvent &event)
{
    if (event.type == PropertyNotify &&
             (event.xproperty.atom == AtomCache::atom("_NET_WM_WINDOW_TYPE") ||
              event.xproperty.atom == AtomCache::atom("_NET_WM_STATE")))
    {
        emit visibleInSwitcherChanged();
        return true;
    }

    return false;
}

static QVector<Atom> getNetWmState(Display *display, Window window)
{
    QVector<Atom> atomList;

    Atom actualType;
    int actualFormat;
    ulong propertyLength;
    ulong bytesLeft;
    uchar *propertyData = 0;

    // Step 1: Get the size of the list
    bool result = XGetWindowProperty(display, window, AtomCache::atom("_NET_WM_STATE"), 0, 0x7fffffff,
                                     false, XA_ATOM, &actualType,
                                     &actualFormat, &propertyLength,
                                     &bytesLeft, &propertyData);
    if (result != Success || actualType != XA_ATOM || actualFormat != 32)
        return atomList;

    XFree(propertyData);
    atomList.resize(propertyLength);

    // Step 2: Get the actual list
    if (!XGetWindowProperty(display, window, AtomCache::atom("_NET_WM_STATE"), 0,
                            atomList.size(), false, XA_ATOM,
                            &actualType, &actualFormat,
                            &propertyLength, &bytesLeft,
                            &propertyData) == Success) {
        qWarning("Unable to retrieve window properties: %i", (int) window);
        return atomList;
    }

    if (!atomList.isEmpty())
        memcpy(atomList.data(), propertyData,
               atomList.size() * sizeof(Atom));

    XFree(propertyData);
    return atomList;
}

// TODO: ideally we can cache this and make it a simple getter
// updated when properties change.
bool WindowInfo::visibleInSwitcher()
{
    Atom actualType;
    int actualFormat;
    unsigned char *typeData = NULL;
    unsigned long numTypeItems;
    unsigned long bytesLeft;

    bool result = XGetWindowProperty(QX11Info::display(),
                                     d->window,
                                     AtomCache::atom("_NET_WM_WINDOW_TYPE"),
                                     0L, 16L, false,
                                     XA_ATOM,
                                     &actualType,
                                     &actualFormat,
                                     &numTypeItems,
                                     &bytesLeft,
                                     &typeData);

    if (result != Success)
        return false;

    Atom *type = (Atom *)typeData;
    bool includeInWindowList = false;

    // plain Xlib windows do not have a type
    if (numTypeItems == 0)
        includeInWindowList = true;
    for (unsigned int n = 0; n < numTypeItems; n++) {
        if (type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_DESKTOP") ||
            type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_NOTIFICATION") ||
            type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_DOCK") ||
            type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_MENU"))
        {
            includeInWindowList = false;
            break;
        }
        if (type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_NORMAL"))
        {
            includeInWindowList = true;
        }
    }

    XFree(typeData);

    if (includeInWindowList)
    {
        if (getNetWmState(QX11Info::display(), d->window).contains(AtomCache::atom("_NET_WM_STATE_SKIP_TASKBAR")))
        {
            includeInWindowList = false;
        }
    }

    return includeInWindowList;
}
<commit_msg>Request properties in one go<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QHash>
#include <QDebug>
#include <QX11Info>

#include "windowinfo.h"
#include "xtools/xatomcache.h"

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xdamage.h>

class WindowInfo::WindowData
{

public:
    //! Constructs a window data object
    WindowData(Window id) :
            window(id),
            transientFor(0),
            title(),
            types(),
            states(),
            pid(0),
            pixmapSerial(0)
    {
    }

    //! Destructor
    ~WindowData()
    {
    }

    //! The X window ID
    Window window;

    //! The ID of the window this window is transient for
    Window transientFor;

    //! The title of the window
    QString title;

    //! The window types associated with this window
    QList<Atom> types;

    //! The status atoms of this window
    QList<Atom> states;

    int pid;

    int pixmapSerial;
};

//! Storage for the WindowInfo data objects. A central storage enables constructing
//! new WindowInfo objects with shared data.
static QHash<Window, WindowInfo * > windowDatas;

WindowInfo *WindowInfo::windowFor(Qt::HANDLE wid)
{
    if (WindowInfo *wi = windowDatas.value(wid)) {
        return wi;
    } else {
        return new WindowInfo(wid);
    }
}

WindowInfo::WindowInfo(Qt::HANDLE window)
    : d(new WindowData(window))
{
    qDebug() << Q_FUNC_INFO << "Created WindowInfo for " << window;
    updateWindowTitle();
    updateWindowProperties();
    windowDatas[window] = this;
}

WindowInfo::~WindowInfo()
{
    qDebug() << Q_FUNC_INFO << "Destroyed windwo for " << d->window;
    windowDatas.remove(d->window);
}

const QString& WindowInfo::title() const
{
    return d->title;
}

Qt::HANDLE WindowInfo::window() const
{
    return d->window;
}

Qt::HANDLE WindowInfo::transientFor() const
{
    return d->transientFor;
}

QList<Qt::HANDLE> WindowInfo::types() const
{
    return d->types;
}

QList<Qt::HANDLE> WindowInfo::states() const
{
    return d->states;
}

bool operator==(const WindowInfo &wi1, const WindowInfo &wi2)
{
    return wi1.window() == wi2.window();
}

bool WindowInfo::updateWindowTitle()
{
    Display *dpy = QX11Info::display();
    XTextProperty textProperty;
    bool updated = false;
    int result = XGetTextProperty(dpy, d->window, &textProperty, AtomCache::atom("_NET_WM_NAME"));
    if (result == 0) {
        result = XGetWMName(dpy, d->window, &textProperty);
    }

    if (result != 0) {
        d->title = QString::fromUtf8((const char *)textProperty.value);
        XFree(textProperty.value);
        updated = true;
    }
    return updated;
}

void WindowInfo::updateWindowProperties()
{
    d->types = getWindowProperties(d->window, AtomCache::atom("_NET_WM_WINDOW_TYPE"));
    d->states = getWindowProperties(d->window, AtomCache::atom("_NET_WM_STATE"));

    if (!XGetTransientForHint(QX11Info::display(), d->window, &d->transientFor) || d->transientFor == d->window) {
        d->transientFor = 0;
    }
}

int WindowInfo::pid() const
{
    return d->pid;
}

void WindowInfo::setPid(int pid)
{
    d->pid = pid;
}

QList<Qt::HANDLE> WindowInfo::getWindowProperties(Qt::HANDLE winId, Qt::HANDLE propertyAtom, long maxCount)
{
    QList<Atom> properties;
    Atom actualType;
    int actualFormat;
    unsigned long numTypeItems, bytesLeft;
    unsigned char *typeData = NULL;

    Status result = XGetWindowProperty(QX11Info::display(), winId, propertyAtom, 0L, maxCount, False, XA_ATOM, &actualType, &actualFormat, &numTypeItems, &bytesLeft, &typeData);
    if (result == Success) {
        Atom *type = (Atom *) typeData;
        for (unsigned int n = 0; n < numTypeItems; n++) {
            properties.append(type[n]);
        }
        XFree(typeData);
    }
    return properties;
}

Qt::HANDLE WindowInfo::pixmapSerial() const
{
    return d->pixmapSerial;
}

void WindowInfo::setPixmapSerial(Qt::HANDLE pixmapSerial)
{
    d->pixmapSerial = pixmapSerial;
    qDebug() << Q_FUNC_INFO << "Changed pixmap serial on " << d->window << " to " << d->pixmapSerial;
    emit pixmapSerialChanged();
}

bool WindowInfo::handleXEvent(const XEvent &event)
{
    if (event.type == PropertyNotify &&
             (event.xproperty.atom == AtomCache::atom("_NET_WM_WINDOW_TYPE") ||
              event.xproperty.atom == AtomCache::atom("_NET_WM_STATE")))
    {
        emit visibleInSwitcherChanged();
        return true;
    }

    return false;
}

static QVector<Atom> getNetWmState(Display *display, Window window)
{
    QVector<Atom> atomList;

    Atom actualType;
    int actualFormat;
    ulong propertyLength;
    ulong bytesLeft;
    uchar *propertyData = 0;

    bool result = XGetWindowProperty(display, window, AtomCache::atom("_NET_WM_STATE"), 0, 12L,
                                     false, XA_ATOM, &actualType,
                                     &actualFormat, &propertyLength,
                                     &bytesLeft, &propertyData);
    if (result != Success || actualType != XA_ATOM || actualFormat != 32) {
        if (propertyData) {
            XFree(propertyData);
        }
        return atomList;
    }

    atomList.resize(propertyLength);
    if (!atomList.isEmpty())
        memcpy(atomList.data(), propertyData,
               atomList.size() * sizeof(Atom));

    XFree(propertyData);
    return atomList;
}

// TODO: ideally we can cache this and make it a simple getter
// updated when properties change.
bool WindowInfo::visibleInSwitcher()
{
    Atom actualType;
    int actualFormat;
    unsigned char *typeData = NULL;
    unsigned long numTypeItems;
    unsigned long bytesLeft;

    bool result = XGetWindowProperty(QX11Info::display(),
                                     d->window,
                                     AtomCache::atom("_NET_WM_WINDOW_TYPE"),
                                     0L, 16L, false,
                                     XA_ATOM,
                                     &actualType,
                                     &actualFormat,
                                     &numTypeItems,
                                     &bytesLeft,
                                     &typeData);

    if (result != Success)
        return false;

    Atom *type = (Atom *)typeData;
    bool includeInWindowList = false;

    // plain Xlib windows do not have a type
    if (numTypeItems == 0)
        includeInWindowList = true;
    for (unsigned int n = 0; n < numTypeItems; n++) {
        if (type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_DESKTOP") ||
            type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_NOTIFICATION") ||
            type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_DOCK") ||
            type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_MENU"))
        {
            includeInWindowList = false;
            break;
        }
        if (type[n] == AtomCache::atom("_NET_WM_WINDOW_TYPE_NORMAL"))
        {
            includeInWindowList = true;
        }
    }

    XFree(typeData);

    if (includeInWindowList)
    {
        if (getNetWmState(QX11Info::display(), d->window).contains(AtomCache::atom("_NET_WM_STATE_SKIP_TASKBAR")))
        {
            includeInWindowList = false;
        }
    }

    return includeInWindowList;
}
<|endoftext|>


<commit_before>#include "server_state_game.hpp"
#include "server_state_idle.hpp"
#include "server_instance.hpp"
#include <filesystem.hpp>

namespace server {
namespace state {
    game::game(server::instance& serv) : base(serv, server::state_id::game, "game") {
        // TODO: add all game components to this container
        save_chunks_.push_back(universe_.make_serializer());
    }

    void game::register_callbacks() {
        pool_ << net_.watch_request(
            [this](server::netcom::request_t<request::server::game_save>&& req) {
            try {
                save_to_directory(req.arg.save);
                req.answer();
            } catch (request::server::game_save::failure& fail) {
                // Clear load buffers
                for (auto& c : save_chunks_) {
                    c.clear();
                }

                req.fail(std::move(fail));
            } catch (...) {
                // Clear load buffers
                for (auto& c : save_chunks_) {
                    c.clear();
                }

                out_.error("unexpected exception in game::save_to_directory()");
                throw;
            }
        });

        pool_ << net_.watch_request(
            [this](server::netcom::request_t<request::server::game_load>&& req) {
            try {
                load_from_directory(req.arg.save);
                req.answer();
            } catch (request::server::game_load::failure& fail) {
                // Clear load buffers
                for (auto& c : save_chunks_) {
                    c.clear();
                }

                req.fail(std::move(fail));
            } catch (...) {
                // Clear load buffers
                for (auto& c : save_chunks_) {
                    c.clear();
                }

                out_.error("unexpected exception in game::load_from_directory()");
                throw;
            }
        });

        pool_ << net_.watch_request(
            [this](server::netcom::request_t<request::server::stop_and_idle>&& req) {
            serv_.set_state<server::state::idle>();
            req.answer();
        });
    }

    void game::set_player_list(std::unique_ptr<server::player_list> plist) {
        plist_ = std::move(plist);
    }

    void game::save_to_directory(const std::string& dir) {
        using failure = request::server::game_save::failure;

        if (saving_) {
            throw failure{failure::reason::already_saving, ""};
        }

        saving_ = true;

        // Block the game and bake all game data into serializable structures
        net_.send_message(netcom::all_actor_id, make_packet<message::server::game_save_progress>(
            message::server::game_save_progress::step::gathering_game_data
        ));

        for (auto& c : save_chunks_) {
            c.save_data();
        }

        // Save to disk in the background
        net_.send_message(netcom::all_actor_id, make_packet<message::server::game_save_progress>(
            message::server::game_save_progress::step::saving_to_disk
        ));

        thread_ = std::thread([this, dir]() {
            for (auto& c : save_chunks_) {
                c.serialize(dir);
            }

            // Clear buffers
            for (auto& c : save_chunks_) {
                c.clear();
            }

            net_.send_message(netcom::all_actor_id, make_packet<message::server::game_save_progress>(
                message::server::game_save_progress::step::game_saved
            ));

            saving_ = false;
        });
    }

    void game::load_from_directory(const std::string& dir) {
        using failure = request::server::game_load::failure;

        // The whole game will be blocked during the operation.

        if (saving_) {
            throw failure{failure::reason::cannot_load_while_saving, ""};
        }

        if (!file::exists(dir)) {
            throw failure{failure::reason::no_such_saved_game, ""};
        }

        if (!is_saved_game_directory(dir)) {
            throw failure{failure::reason::invalid_saved_game, ""};
        }

        // NOTE: One might need to clear the game state before

        std::uint16_t s = 0;
        std::uint16_t nchunk = save_chunks_.size();
        for (auto& c : save_chunks_) {
            net_.send_message(netcom::all_actor_id, make_packet<message::server::game_load_progress>(
                nchunk, s, c.name()
            ));

            c.deserialize(dir);
            c.load_data_first_pass();

            ++s;
        }

        net_.send_message(netcom::all_actor_id, make_packet<message::server::game_load_progress>(
            nchunk, nchunk, "loading_second_pass"
        ));

        // A two pass loading is needed for some components
        for (auto& c : save_chunks_) {
            c.load_data_second_pass();
        }

        // Clear buffers
        for (auto& c : save_chunks_) {
            c.clear();
        }
    }

    bool game::is_saved_game_directory(const std::string& dir) const {
        for (auto& c : save_chunks_) {
            if (!c.is_valid_directory(dir)) {
                return false;
            }
        }

        return true;
    }
}
}
<commit_msg>Fixed loading failing<commit_after>#include "server_state_game.hpp"
#include "server_state_idle.hpp"
#include "server_instance.hpp"
#include <filesystem.hpp>

namespace server {
namespace state {
    game::game(server::instance& serv) : base(serv, server::state_id::game, "game"), saving_(false) {
        // TODO: add all game components to this container
        save_chunks_.push_back(universe_.make_serializer());
    }

    void game::register_callbacks() {
        pool_ << net_.watch_request(
            [this](server::netcom::request_t<request::server::game_save>&& req) {
            try {
                save_to_directory(req.arg.save);
                req.answer();
            } catch (request::server::game_save::failure& fail) {
                // Clear load buffers
                for (auto& c : save_chunks_) {
                    c.clear();
                }

                req.fail(std::move(fail));
            } catch (...) {
                // Clear load buffers
                for (auto& c : save_chunks_) {
                    c.clear();
                }

                out_.error("unexpected exception in game::save_to_directory()");
                throw;
            }
        });

        pool_ << net_.watch_request(
            [this](server::netcom::request_t<request::server::game_load>&& req) {
            try {
                load_from_directory(req.arg.save);
                req.answer();
            } catch (request::server::game_load::failure& fail) {
                // Clear load buffers
                for (auto& c : save_chunks_) {
                    c.clear();
                }

                req.fail(std::move(fail));
            } catch (...) {
                // Clear load buffers
                for (auto& c : save_chunks_) {
                    c.clear();
                }

                out_.error("unexpected exception in game::load_from_directory()");
                throw;
            }
        });

        pool_ << net_.watch_request(
            [this](server::netcom::request_t<request::server::stop_and_idle>&& req) {
            serv_.set_state<server::state::idle>();
            req.answer();
        });
    }

    void game::set_player_list(std::unique_ptr<server::player_list> plist) {
        plist_ = std::move(plist);
    }

    void game::save_to_directory(const std::string& dir) {
        using failure = request::server::game_save::failure;

        if (saving_) {
            throw failure{failure::reason::already_saving, ""};
        }

        saving_ = true;

        // Block the game and bake all game data into serializable structures
        net_.send_message(netcom::all_actor_id, make_packet<message::server::game_save_progress>(
            message::server::game_save_progress::step::gathering_game_data
        ));

        for (auto& c : save_chunks_) {
            c.save_data();
        }

        // Save to disk in the background
        net_.send_message(netcom::all_actor_id, make_packet<message::server::game_save_progress>(
            message::server::game_save_progress::step::saving_to_disk
        ));

        thread_ = std::thread([this, dir]() {
            for (auto& c : save_chunks_) {
                c.serialize(dir);
            }

            // Clear buffers
            for (auto& c : save_chunks_) {
                c.clear();
            }

            net_.send_message(netcom::all_actor_id, make_packet<message::server::game_save_progress>(
                message::server::game_save_progress::step::game_saved
            ));

            saving_ = false;
        });
    }

    void game::load_from_directory(const std::string& dir) {
        using failure = request::server::game_load::failure;

        // The whole game will be blocked during the operation.

        if (saving_) {
            throw failure{failure::reason::cannot_load_while_saving, ""};
        }

        if (!file::exists(dir)) {
            throw failure{failure::reason::no_such_saved_game, ""};
        }

        if (!is_saved_game_directory(dir)) {
            throw failure{failure::reason::invalid_saved_game, ""};
        }

        // NOTE: One might need to clear the game state before

        std::uint16_t s = 0;
        std::uint16_t nchunk = save_chunks_.size();
        for (auto& c : save_chunks_) {
            net_.send_message(netcom::all_actor_id, make_packet<message::server::game_load_progress>(
                nchunk, s, c.name()
            ));

            c.deserialize(dir);
            c.load_data_first_pass();

            ++s;
        }

        net_.send_message(netcom::all_actor_id, make_packet<message::server::game_load_progress>(
            nchunk, nchunk, "loading_second_pass"
        ));

        // A two pass loading is needed for some components
        for (auto& c : save_chunks_) {
            c.load_data_second_pass();
        }

        // Clear buffers
        for (auto& c : save_chunks_) {
            c.clear();
        }
    }

    bool game::is_saved_game_directory(const std::string& dir) const {
        for (auto& c : save_chunks_) {
            if (!c.is_valid_directory(dir)) {
                return false;
            }
        }

        return true;
    }
}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#undef UNICODE
#undef _UNICODE

#define _WIN32_WINDOWS 0x0410

#ifdef _MSC_VER
#pragma warning(push, 1) /* disable warnings within system headers */
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <msiquery.h>
#include <shellapi.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <malloc.h>
#include <assert.h>
#include <string.h>

#ifdef UNICODE
#define _UNICODE
#define _tstring    wstring
#else
#define _tstring    string
#endif
#include <tchar.h>
#include <string>

/** creates a temporary folder with a unique name.

    The returned string is a file URL.
*/
static std::_tstring createTempFolder()
{
    BOOL bExist = FALSE;
    TCHAR szTempName[MAX_PATH];
    do
    {
        bExist = FALSE;
        // Get the temp path.
        TCHAR lpPathBuffer[MAX_PATH];
        DWORD dwRetVal = GetTempPath(MAX_PATH, lpPathBuffer);
        if (dwRetVal > MAX_PATH || (dwRetVal == 0))
        {
            //fprintf (stderr, "GetTempPath failed with error %d.\n", GetLastError());
            return TEXT("");
        }
        // Create a temporary file.
        UINT uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files
                                       "upg",        // temp file name prefix
                                       0,            // create unique name
                                       szTempName);  // buffer for name
        if (uRetVal == 0)
        {
            //fprintf (stderr, "GetTempFileName failed with error %d.\n", GetLastError());
            return TEXT("");
        }
        //Delete the file
        BOOL bDel = DeleteFile(szTempName);
        if (FALSE == bDel)
        {
            //fprintf(stderr, "Could not delete temp file. Error %d.\n", GetLastError());
            return TEXT("");
        }
        // Create the directory
        BOOL bDir = CreateDirectory(szTempName, NULL);
        if (FALSE == bDir)
        {
            DWORD error =GetLastError();
            if (ERROR_ALREADY_EXISTS == error)
            {
                bExist = TRUE;
            }
            else
            {
                //fprintf(stderr, "CreateDirectory failed with error %d.\n", error);
                return TEXT("");
            }
        }
    } while(bExist);

    std::_tstring cur(szTempName);
    //make a file URL from the path
    std::_tstring ret(TEXT("file:///"));
    for (std::_tstring::iterator i = cur.begin(); i != cur.end(); i++)
    {
        if (*i == '\\')
            ret.append(TEXT("/"));
        else
            ret.push_back(*i);
    }
//    MessageBox(NULL, ret.c_str(), "createTempFolder", MB_OK);
    return ret.c_str();
}

/** deletes the temporary folder.
    The argument must be a file URL.
*/
static void deleteTempFolder(const std::_tstring& sTempFolder)
{
    if (sTempFolder.size() == 0)
        return;
    //convert the file URL to a path
    const std::_tstring path(sTempFolder.substr(8));
    std::_tstring path2;
//    MessageBox(NULL, path.c_str(), "del1", MB_OK);
    for (std::_tstring::const_iterator i = path.begin(); i != path.end(); i++)
    {
        if (*i == '/')
            path2.append(TEXT("\\"));
        else
            path2.push_back(*i);
    }

    //We need a null terminated string with two nulls in the end
    //for the SHFILEOPSTRUCT
    const TCHAR * szTemp = path2.c_str();
    size_t size = path2.size();
    TCHAR * szTemp2 = new TCHAR[size + 2];
    ZeroMemory(szTemp2, (size + 2) * sizeof(TCHAR));
    memcpy(szTemp2, szTemp, size * sizeof(TCHAR));

//    MessageBox(NULL, szTemp2, "del3", MB_OK);
    SHFILEOPSTRUCT operation =
        {
            NULL,
            FO_DELETE,
            szTemp2,
            NULL,
            FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR,
            FALSE,
            NULL,
            NULL
        };

    SHFileOperation( &operation);
    delete [] szTemp2;
}

static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
{
    std::_tstring result;
    TCHAR szDummy[1] = TEXT("");
    DWORD nChars = 0;

    if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
    {
        DWORD nBytes = ++nChars * sizeof(TCHAR);
        LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
        ZeroMemory( buffer, nBytes );
        MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
        result = buffer;
    }

    return result;
}

/* creates a child process which is specified in lpCommand.

  out_exitCode is the exit code of the child process

**/
static BOOL ExecuteCommand( LPCTSTR lpCommand, DWORD * out_exitCode)
{
    BOOL                fSuccess = FALSE;
    STARTUPINFO         si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);

    fSuccess = CreateProcess(
        NULL,
        (LPTSTR)lpCommand,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi
        );

    if ( fSuccess )
    {
        WaitForSingleObject( pi.hProcess, INFINITE );

        if (!GetExitCodeProcess( pi.hProcess, out_exitCode))
            fSuccess = FALSE;

        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
    }

    return fSuccess;
}

static BOOL RemoveCompleteDirectory( std::_tstring sPath )
{
    bool bDirectoryRemoved = true;

    std::_tstring mystr;
    std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*");
    WIN32_FIND_DATA aFindData;

    // Finding all content in sPath

    HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData );

    if ( hFindContent != INVALID_HANDLE_VALUE )
    {
        bool fNextFile = false;

        do
        {
            std::_tstring sFileName = aFindData.cFileName;
            std::_tstring sCurrentDir = TEXT(".");
            std::_tstring sParentDir = TEXT("..");

            mystr = "Current short file: " + sFileName;
            // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK);

            if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) &&
                ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 ))
            {
                std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName;

                if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
                {
                    bool fSuccess = RemoveCompleteDirectory(sCompleteFileName);
                    if ( fSuccess )
                    {
                        mystr = "Successfully removed content of dir " + sCompleteFileName;
                        // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
                    }
                    else
                    {
                        mystr = "An error occured during removing content of " + sCompleteFileName;
                        // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
                    }
                }
                else
                {
                    bool fSuccess = DeleteFile( sCompleteFileName.c_str() );
                    if ( fSuccess )
                    {
                        mystr = "Successfully removed file " + sCompleteFileName;
                        // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK);
                    }
                    else
                    {
                        mystr = "An error occured during removal of file " + sCompleteFileName;
                        // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK);
                    }
                }
            }

            fNextFile = FindNextFile( hFindContent, &aFindData );

        } while ( fNextFile );

        FindClose( hFindContent );

        // empty directory can be removed now
        // RemoveDirectory is only successful, if the last handle to the directory is closed
        // -> first removing content -> closing handle -> remove empty directory

        bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str());

        if ( fRemoveDirSuccess )
        {
            mystr = "Successfully removed dir " + sPath;
            // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
        }
        else
        {
            mystr = "An error occured during removal of empty directory " + sPath;
            // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
            bDirectoryRemoved = false;
        }
    }

    return bDirectoryRemoved;
}

extern "C" UINT __stdcall RegisterExtensions(MSIHANDLE handle)
{
    std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
    std::_tstring sUnoPkgFile = sInstDir + TEXT("program\\unopkg.exe");
    std::_tstring mystr;

    WIN32_FIND_DATA aFindFileData;

    mystr = "unopkg file: " + sUnoPkgFile;
    //MessageBox(NULL, mystr.c_str(), "Command", MB_OK);

    // Find unopkg.exe
    HANDLE hFindUnopkg = FindFirstFile( sUnoPkgFile.c_str(), &aFindFileData );

    if ( hFindUnopkg != INVALID_HANDLE_VALUE )
    {
        // unopkg.exe exists in program directory

        const std::_tstring sTempFolder(createTempFolder());
        std::_tstring sCommandPart1 = sUnoPkgFile + " sync";
        std::_tstring sCommand = sCommandPart1
            + TEXT(" -env:BUNDLED_EXTENSIONS_USER=$BRAND_BASE_DIR/share/prereg/bundled")
            + TEXT(" -env:UNO_JAVA_JFW_INSTALL_DATA=$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml")
            + TEXT(" -env:UserInstallation=") + sTempFolder;
        mystr = "Command: " + sCommand;
        //MessageBox(NULL, mystr.c_str(), "Command", MB_OK);

        DWORD exitCode = 0;
        bool fSuccess = ExecuteCommand( sCommand.c_str(), & exitCode);

        deleteTempFolder(sTempFolder);

//         if ( fSuccess )
//         {
//             mystr = "Executed successfully!";
//             MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
//         }
//         else
//         {
//             mystr = "An error occured during execution!";
//             MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
//         }

        FindClose( hFindUnopkg );
    }
//     else
//     {
//         mystr = "Error: Did not find " + sUnoPkgFile;
//         MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
//     }

    return ERROR_SUCCESS;
}

extern "C" UINT __stdcall RemoveExtensions(MSIHANDLE handle)
{
    std::_tstring mystr;

    // Finding the product with the help of the propery FINDPRODUCT,
    // that contains a Windows Registry key, that points to the install location.

    TCHAR szValue[8192];
    DWORD nValueSize = sizeof(szValue);
    HKEY  hKey;
    std::_tstring sInstDir;

    std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
    //MessageBox( NULL, sProductKey.c_str(), "Titel", MB_OK );

    if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER,  sProductKey.c_str(), &hKey ) )
    {
        if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
        {
            sInstDir = szValue;
        }
        RegCloseKey( hKey );
    }
    else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE,  sProductKey.c_str(), &hKey ) )
    {
        if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
        {
            sInstDir = szValue;
        }
        RegCloseKey( hKey );
    }
    else
    {
        return ERROR_SUCCESS;
    }

    // Removing complete directory "Basis\presets\bundled"

    std::_tstring sCacheDir = sInstDir + TEXT("Basis\\presets\\bundled");

    bool fSuccess = RemoveCompleteDirectory( sCacheDir );

//     if ( fSuccess )
//     {
//         mystr = "Executed successfully!";
//          MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK);
//     }
//     else
//     {
//         mystr = "An error occured during execution!";
//         MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK);
//     }

    return ERROR_SUCCESS;
}
<commit_msg>jl154 #i162868# changed RemoveExtensions custom action (windows) to delete brand/share/prereg/bundled<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#undef UNICODE
#undef _UNICODE

#define _WIN32_WINDOWS 0x0410

#ifdef _MSC_VER
#pragma warning(push, 1) /* disable warnings within system headers */
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <msiquery.h>
#include <shellapi.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <malloc.h>
#include <assert.h>
#include <string.h>

#ifdef UNICODE
#define _UNICODE
#define _tstring    wstring
#else
#define _tstring    string
#endif
#include <tchar.h>
#include <string>

/** creates a temporary folder with a unique name.

    The returned string is a file URL.
*/
static std::_tstring createTempFolder()
{
    BOOL bExist = FALSE;
    TCHAR szTempName[MAX_PATH];
    do
    {
        bExist = FALSE;
        // Get the temp path.
        TCHAR lpPathBuffer[MAX_PATH];
        DWORD dwRetVal = GetTempPath(MAX_PATH, lpPathBuffer);
        if (dwRetVal > MAX_PATH || (dwRetVal == 0))
        {
            //fprintf (stderr, "GetTempPath failed with error %d.\n", GetLastError());
            return TEXT("");
        }
        // Create a temporary file.
        UINT uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files
                                       "upg",        // temp file name prefix
                                       0,            // create unique name
                                       szTempName);  // buffer for name
        if (uRetVal == 0)
        {
            //fprintf (stderr, "GetTempFileName failed with error %d.\n", GetLastError());
            return TEXT("");
        }
        //Delete the file
        BOOL bDel = DeleteFile(szTempName);
        if (FALSE == bDel)
        {
            //fprintf(stderr, "Could not delete temp file. Error %d.\n", GetLastError());
            return TEXT("");
        }
        // Create the directory
        BOOL bDir = CreateDirectory(szTempName, NULL);
        if (FALSE == bDir)
        {
            DWORD error =GetLastError();
            if (ERROR_ALREADY_EXISTS == error)
            {
                bExist = TRUE;
            }
            else
            {
                //fprintf(stderr, "CreateDirectory failed with error %d.\n", error);
                return TEXT("");
            }
        }
    } while(bExist);

    std::_tstring cur(szTempName);
    //make a file URL from the path
    std::_tstring ret(TEXT("file:///"));
    for (std::_tstring::iterator i = cur.begin(); i != cur.end(); i++)
    {
        if (*i == '\\')
            ret.append(TEXT("/"));
        else
            ret.push_back(*i);
    }
//    MessageBox(NULL, ret.c_str(), "createTempFolder", MB_OK);
    return ret.c_str();
}

/** deletes the temporary folder.
    The argument must be a file URL.
*/
static void deleteTempFolder(const std::_tstring& sTempFolder)
{
    if (sTempFolder.size() == 0)
        return;
    //convert the file URL to a path
    const std::_tstring path(sTempFolder.substr(8));
    std::_tstring path2;
//    MessageBox(NULL, path.c_str(), "del1", MB_OK);
    for (std::_tstring::const_iterator i = path.begin(); i != path.end(); i++)
    {
        if (*i == '/')
            path2.append(TEXT("\\"));
        else
            path2.push_back(*i);
    }

    //We need a null terminated string with two nulls in the end
    //for the SHFILEOPSTRUCT
    const TCHAR * szTemp = path2.c_str();
    size_t size = path2.size();
    TCHAR * szTemp2 = new TCHAR[size + 2];
    ZeroMemory(szTemp2, (size + 2) * sizeof(TCHAR));
    memcpy(szTemp2, szTemp, size * sizeof(TCHAR));

//    MessageBox(NULL, szTemp2, "del3", MB_OK);
    SHFILEOPSTRUCT operation =
        {
            NULL,
            FO_DELETE,
            szTemp2,
            NULL,
            FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR,
            FALSE,
            NULL,
            NULL
        };

    SHFileOperation( &operation);
    delete [] szTemp2;
}

static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
{
    std::_tstring result;
    TCHAR szDummy[1] = TEXT("");
    DWORD nChars = 0;

    if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
    {
        DWORD nBytes = ++nChars * sizeof(TCHAR);
        LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
        ZeroMemory( buffer, nBytes );
        MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
        result = buffer;
    }

    return result;
}

/* creates a child process which is specified in lpCommand.

  out_exitCode is the exit code of the child process

**/
static BOOL ExecuteCommand( LPCTSTR lpCommand, DWORD * out_exitCode)
{
    BOOL                fSuccess = FALSE;
    STARTUPINFO         si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);

    fSuccess = CreateProcess(
        NULL,
        (LPTSTR)lpCommand,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi
        );

    if ( fSuccess )
    {
        WaitForSingleObject( pi.hProcess, INFINITE );

        if (!GetExitCodeProcess( pi.hProcess, out_exitCode))
            fSuccess = FALSE;

        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
    }

    return fSuccess;
}

static BOOL RemoveCompleteDirectory( std::_tstring sPath )
{
    bool bDirectoryRemoved = true;

    std::_tstring mystr;
    std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*");
    WIN32_FIND_DATA aFindData;

    // Finding all content in sPath

    HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData );

    if ( hFindContent != INVALID_HANDLE_VALUE )
    {
        bool fNextFile = false;

        do
        {
            std::_tstring sFileName = aFindData.cFileName;
            std::_tstring sCurrentDir = TEXT(".");
            std::_tstring sParentDir = TEXT("..");

            mystr = "Current short file: " + sFileName;
            // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK);

            if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) &&
                ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 ))
            {
                std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName;

                if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
                {
                    bool fSuccess = RemoveCompleteDirectory(sCompleteFileName);
                    if ( fSuccess )
                    {
                        mystr = "Successfully removed content of dir " + sCompleteFileName;
                        // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
                    }
                    else
                    {
                        mystr = "An error occured during removing content of " + sCompleteFileName;
                        // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
                    }
                }
                else
                {
                    bool fSuccess = DeleteFile( sCompleteFileName.c_str() );
                    if ( fSuccess )
                    {
                        mystr = "Successfully removed file " + sCompleteFileName;
                        // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK);
                    }
                    else
                    {
                        mystr = "An error occured during removal of file " + sCompleteFileName;
                        // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK);
                    }
                }
            }

            fNextFile = FindNextFile( hFindContent, &aFindData );

        } while ( fNextFile );

        FindClose( hFindContent );

        // empty directory can be removed now
        // RemoveDirectory is only successful, if the last handle to the directory is closed
        // -> first removing content -> closing handle -> remove empty directory

        bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str());

        if ( fRemoveDirSuccess )
        {
            mystr = "Successfully removed dir " + sPath;
            // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
        }
        else
        {
            mystr = "An error occured during removal of empty directory " + sPath;
            // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
            bDirectoryRemoved = false;
        }
    }

    return bDirectoryRemoved;
}

extern "C" UINT __stdcall RegisterExtensions(MSIHANDLE handle)
{
    std::_tstring sInstDir = GetMsiProperty( handle, TEXT("INSTALLLOCATION") );
    std::_tstring sUnoPkgFile = sInstDir + TEXT("program\\unopkg.exe");
    std::_tstring mystr;

    WIN32_FIND_DATA aFindFileData;

    mystr = "unopkg file: " + sUnoPkgFile;
    //MessageBox(NULL, mystr.c_str(), "Command", MB_OK);

    // Find unopkg.exe
    HANDLE hFindUnopkg = FindFirstFile( sUnoPkgFile.c_str(), &aFindFileData );

    if ( hFindUnopkg != INVALID_HANDLE_VALUE )
    {
        // unopkg.exe exists in program directory

        const std::_tstring sTempFolder(createTempFolder());
        std::_tstring sCommandPart1 = sUnoPkgFile + " sync";
        std::_tstring sCommand = sCommandPart1
            + TEXT(" -env:BUNDLED_EXTENSIONS_USER=$BRAND_BASE_DIR/share/prereg/bundled")
            + TEXT(" -env:UNO_JAVA_JFW_INSTALL_DATA=$OOO_BASE_DIR/share/config/javasettingsunopkginstall.xml")
            + TEXT(" -env:UserInstallation=") + sTempFolder;
        mystr = "Command: " + sCommand;
        //MessageBox(NULL, mystr.c_str(), "Command", MB_OK);

        DWORD exitCode = 0;
        bool fSuccess = ExecuteCommand( sCommand.c_str(), & exitCode);

        deleteTempFolder(sTempFolder);

//         if ( fSuccess )
//         {
//             mystr = "Executed successfully!";
//             MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
//         }
//         else
//         {
//             mystr = "An error occured during execution!";
//             MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
//         }

        FindClose( hFindUnopkg );
    }
//     else
//     {
//         mystr = "Error: Did not find " + sUnoPkgFile;
//         MessageBox(NULL, mystr.c_str(), "Command", MB_OK);
//     }

    return ERROR_SUCCESS;
}

extern "C" UINT __stdcall RemoveExtensions(MSIHANDLE handle)
{
    std::_tstring mystr;

    // Finding the product with the help of the propery FINDPRODUCT,
    // that contains a Windows Registry key, that points to the install location.

    TCHAR szValue[8192];
    DWORD nValueSize = sizeof(szValue);
    HKEY  hKey;
    std::_tstring sInstDir;

    std::_tstring sProductKey = GetMsiProperty( handle, TEXT("FINDPRODUCT") );
    //MessageBox( NULL, sProductKey.c_str(), "Titel", MB_OK );

    if ( ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER,  sProductKey.c_str(), &hKey ) )
    {
        if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
        {
            sInstDir = szValue;
        }
        RegCloseKey( hKey );
    }
    else if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE,  sProductKey.c_str(), &hKey ) )
    {
        if ( ERROR_SUCCESS == RegQueryValueEx( hKey, TEXT("INSTALLLOCATION"), NULL, NULL, (LPBYTE)szValue, &nValueSize ) )
        {
            sInstDir = szValue;
        }
        RegCloseKey( hKey );
    }
    else
    {
        return ERROR_SUCCESS;
    }

    // Removing complete directory "Basis\presets\bundled"

    std::_tstring sCacheDir = sInstDir + TEXT("share\\prereg\\bundled");

    bool fSuccess = RemoveCompleteDirectory( sCacheDir );

//     if ( fSuccess )
//     {
//         mystr = "Executed successfully!";
//          MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK);
//     }
//     else
//     {
//         mystr = "An error occured during execution!";
//         MessageBox(NULL, mystr.c_str(), "Main methode", MB_OK);
//     }

    return ERROR_SUCCESS;
}
<|endoftext|>