<commit_before>#include <Mojagame/Scene.h>

Scene::Scene( App* app ) : _app(app) {
    grapevine.listen( SystemMessage::Update, [](int message, void* data) {
        printf("Updating in lambda %d\n", message);
        return true;
    });
        //std::bind(&Scene::onUpdate, this, std::placeholders::_1, std::placeholders::_2));
}

bool Scene::onUpdate( int message, void* data ) {
    printf("Updating %d\n", message);
}

void Scene::update( double delta ) {
    //Event updateEvent( EventType::Update, this, &delta );
    //dispatch( &updateEvent );
    grapevine.send( SystemMessage::Update, &delta );
}

void Scene::render( ) {

    //Event preRenderEvent( EventType::PreRender, this );
    //dispatch( &preRenderEvent );
    grapevine.send( SystemMessage::PreRender );

    // Render the scene

    //Event postRenderEvent( EventType::PostRender, this );
    //dispatch( &postRenderEvent );
    grapevine.send( SystemMessage::PostRender );

}<commit_msg>Update comments<commit_after>#include <Mojagame/Scene.h>

Scene::Scene( App* app ) : _app(app) {
    grapevine.listen( SystemMessage::Update, [](int message, void* data) {
        printf("Updating in lambda %d\n", message);
        return true;
    });
        //std::bind(&Scene::onUpdate, this, std::placeholders::_1, std::placeholders::_2));
}

bool Scene::onUpdate( int message, void* data ) {
    printf("Updating %d\n", message);
}

void Scene::update( double delta ) {
    grapevine.send( SystemMessage::Update, &delta );
}

void Scene::render( ) {
    grapevine.send( SystemMessage::PreRender );

    // TODO: Render the scene

    grapevine.send( SystemMessage::PostRender );

}<|endoftext|>


<commit_before>//
// OpenThread library, Copyright (C) 2002 - 2003  The Open Thread Group
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// 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
//

//
// Win32Thread.c++
// ~~~~~~~~~~~
#include <memory>
#include <string>
#include <iostream>

#if defined(_MSC_VER) && (_MSC_VER < 1300)
#ifdef __SGI_STL
using std::size_t;
#endif
#else
using std::size_t;
#endif

#include "Win32ThreadPrivateData.h"

struct Win32ThreadCanceled{};

using namespace OpenThreads;

DWORD OpenThreads::cooperativeWait(HANDLE waitHandle, unsigned long timeout){
    Thread* current = Thread::CurrentThread();
    DWORD dwResult ;
    if(current)
    {
        HANDLE cancelHandle = static_cast<Win32ThreadPrivateData*>(current->getImplementation())->cancelEvent.get();
        HANDLE handleSet[2] = {waitHandle, cancelHandle};

        dwResult = WaitForMultipleObjects(2,handleSet,FALSE,timeout);
        if(dwResult == WAIT_OBJECT_0 + 1 ) throw Win32ThreadCanceled();
    }
    else
    {
        dwResult = WaitForSingleObject(waitHandle,timeout);
    }

    return dwResult;
}

Win32ThreadPrivateData::TlsHolder Win32ThreadPrivateData::TLS;

Win32ThreadPrivateData::~Win32ThreadPrivateData()
{
}

const std::string OPENTHREAD_VERSION_STRING = "OpenThread v1.2preAlpha, WindowThreads (Public Implementation)";

//-----------------------------------------------------------------------------
// Initialize thread master priority level
//
Thread::ThreadPriority Thread::s_masterThreadPriority =  Thread::PRIORITY_DEFAULT;

bool Thread::s_isInitialized = false;
//-----------------------------------------------------------------------------
// Class to support some static methods necessary for pthread's to work
// correctly.
//
namespace OpenThreads {

    class ThreadPrivateActions {
        //-------------------------------------------------------------------------
        // We're friendly to Thread, so it can issue the methods.
        //
        friend class Thread;
    private:

        //-------------------------------------------------------------------------
        // Win32Threads standard start routine.
        //
        static unsigned long __stdcall StartThread(void *data) {

            Thread *thread = static_cast<Thread *>(data);
            Win32ThreadPrivateData *pd =
                static_cast<Win32ThreadPrivateData *>(thread->_prvData);

            TlsSetValue(Win32ThreadPrivateData::TLS.ID ,data);
            //---------------------------------------------------------------------
            // Set the proper scheduling priorities
            //
            SetThreadSchedulingParams(thread);

            pd->isRunning = true;

            try{
                thread->run();
            }
            catch(...)
            {
                // abnormal termination but must be caught in win32 anyway
            }

            pd->isRunning = false;

            return 0;
        };

        //-------------------------------------------------------------------------
        // Print information related to thread schduling parameters.
        //
        static void PrintThreadSchedulingInfo(Thread *thread) {
            Win32ThreadPrivateData *pd =
                static_cast<Win32ThreadPrivateData *>(thread->_prvData);

            std::cout<<"Thread "<< thread <<" priority : ";

            switch(thread->getSchedulePriority()) {
            case Thread::PRIORITY_MAX:
                std::cout<<"MAXIMAL"<<std::endl;
                break;
            case Thread::PRIORITY_HIGH:
                std::cout<<"HIGH"<<std::endl;
                break;
            case Thread::PRIORITY_DEFAULT:
            case Thread::PRIORITY_NOMINAL:
                std::cout<<"NORMAL"<<std::endl;
                break;
            case Thread::PRIORITY_LOW:
                std::cout<<"LOW"<<std::endl;
                break;
            case Thread::PRIORITY_MIN:
                std::cout<<"MINIMAL"<<std::endl;
                break;
            }
        }

        //--------------------------------------------------------------------------
        // Set thread scheduling parameters.
        // Note that time-critical priority is ommited :
        // 1) It's not sensible thing to do
        // 2) there's no enum for that in Thread interface
        // Also, on Windows, effective thread priority is :
        // process priority (manipulated with Get/SetProrityClass) + thread priority (here).
        //
        //
        static int SetThreadSchedulingParams(Thread *thread) {

            Win32ThreadPrivateData *pd =
                static_cast<Win32ThreadPrivateData *>(thread->_prvData);

            int prio = THREAD_PRIORITY_NORMAL;

            switch(thread->getSchedulePriority()) {
            case Thread::PRIORITY_MAX:
                prio = THREAD_PRIORITY_HIGHEST;
                break;
            case Thread::PRIORITY_HIGH:
                prio = THREAD_PRIORITY_ABOVE_NORMAL;
                break;
            case Thread::PRIORITY_NOMINAL:
                prio = THREAD_PRIORITY_NORMAL;
                break;
            case Thread::PRIORITY_LOW:
                prio = THREAD_PRIORITY_BELOW_NORMAL;
                break;
            case Thread::PRIORITY_MIN:
                prio = THREAD_PRIORITY_IDLE;
                break;
            }

            int status = SetThreadPriority( pd->tid.get(), prio);

            if(getenv("OUTPUT_THREADLIB_SCHEDULING_INFO") != 0)
	        	PrintThreadSchedulingInfo(thread);

            return status!=0;
        };
    };
};

Thread* Thread::CurrentThread()
{
    return (Thread* )TlsGetValue(Win32ThreadPrivateData::TLS.ID);
};

//----------------------------------------------------------------------------
//
// Description: Set the concurrency level (no-op)
//
// Use static public
//
int Thread::SetConcurrency(int) {
    return -1;
};

//----------------------------------------------------------------------------
//
// Description: Get the concurrency level
//
// Use static public
//
int Thread::GetConcurrency() {
    return -1;
};

//----------------------------------------------------------------------------
//
// Decription: Constructor
//
// Use: public.
//
Thread::Thread() {

    // there's no need for this
    //    if(!s_isInitialized) Init();

    Win32ThreadPrivateData *pd = new Win32ThreadPrivateData();

    pd->stackSize = 0;

    pd->stackSizeLocked = false;

    pd->idSet = false;

    pd->isRunning = false;

    pd->cancelMode = 0;

    pd->uniqueId = 0;

    pd->threadPriority = PRIORITY_DEFAULT;

    pd->threadPolicy = SCHEDULE_DEFAULT;

    pd->detached = false;

    pd->cancelEvent.set(CreateEvent(NULL,TRUE,FALSE,NULL));

    _prvData = static_cast<void *>(pd);

}

//----------------------------------------------------------------------------
//
// Decription: Destructor
//
// Use: public.
//
Thread::~Thread() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *>(_prvData);
    if(pd->isRunning) {
        std::cout<<"Error: Thread "<<this<<" still running in destructor"<<std::endl;
        pd->cancelMode = 0;
        cancel();
    }
    delete pd;
}
//-----------------------------------------------------------------------------
//
// Description: Initialize Threading
//
// Use: public.
//
void Thread::Init() {
//    if(s_isInitialized) return;
//        s_masterThreadPriority = Thread::PRIORITY_DEFAULT;
    s_isInitialized = true;
}

//-----------------------------------------------------------------------------
//
// Description: Get a unique identifier for this thread.
//
// Use: public
//
int Thread::getThreadId() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->uniqueId;
}
//-----------------------------------------------------------------------------
//
// Description: Get the thread's process id
//
// Use: public
//
int Thread::getProcessId() {

    return (int) GetCurrentProcessId();

}
//-----------------------------------------------------------------------------
//
// Description: Determine if the thread is running
//
// Use: public
//
bool Thread::isRunning() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->isRunning;
}
//-----------------------------------------------------------------------------
//
// Description: Start the thread.
//
// Use: public
//
int Thread::start() {

    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    //-------------------------------------------------------------------------
    // Prohibit the stack size from being changed.
    //
    pd->stackSizeLocked = true;
    unsigned long ID;

    pd->tid.set( CreateThread(NULL,pd->stackSize,ThreadPrivateActions::StartThread,static_cast<void *>(this),0,&ID));

    pd->uniqueId = (int)ID;

    if(!pd->tid) {
        return -1;
    }

    pd->idSet = true;

    return 0;

}

int Thread::startThread()
{ return start(); }

//-----------------------------------------------------------------------------
//
// Description: Join the thread.
//
// Use: public
//
int Thread::join() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    if( pd->detached )
        return -1; // cannot wait for detached ;

    if( WaitForSingleObject(pd->tid.get(),INFINITE) != WAIT_OBJECT_0)
        return -1 ;

    return 0;
}

int Thread::detach()
{
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    pd->detached = true;
    return 0;
}

//-----------------------------------------------------------------------------
//
// Description: Cancel the thread.
//
// Use: public
//
int Thread::cancel()
{
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);

    if (pd->isRunning)
    {
        if( pd->cancelMode == 2 )
            return -1;

        // signal all interested parties that we are going to exit
        SetEvent(pd->cancelEvent.get());

        // cancelMode == 1 (asynch)-> kill em
        // cancelMode == 0 (deffered) -> wait a little then kill em

    //    if( (pd->cancelMode == 1) || (WaitForSingleObject(pd->tid,INFINITE)!=WAIT_OBJECT_0) )
        if( pd->cancelMode == 1 )
        {
            // did not terminate cleanly force termination
            pd->isRunning = false;
            return TerminateThread(pd->tid.get(),(DWORD)-1);
        }
    }

    return 0;
}

int Thread::testCancel()
{
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);

    if(WaitForSingleObject(pd->cancelEvent.get(),0) != WAIT_OBJECT_0) return 0;

    if(pd->cancelMode == 2)
        return 0;

    DWORD curr = GetCurrentThreadId();

    if( pd->uniqueId != (int)curr )
        return -1;

    pd->isRunning = false;
//    ExitThread(0);
    throw Win32ThreadCanceled();

    return 0;

}

//-----------------------------------------------------------------------------
//
// Description: Disable cancelibility
//
// Use: public
//
int Thread::setCancelModeDisable() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    pd->cancelMode = 2;
    return 0;
}

//-----------------------------------------------------------------------------
//
// Description: set the thread to cancel immediately
//
// Use: public
//
int Thread::setCancelModeAsynchronous() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    pd->cancelMode  = 1;
    return 0;
}

//-----------------------------------------------------------------------------
//
// Description: set the thread to cancel at the next convienent point.
//
// Use: public
//
int Thread::setCancelModeDeferred() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    pd->cancelMode = 0;
    return 0;
}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's schedule priority (if able)
//
// Use: public
//
int Thread::setSchedulePriority(ThreadPriority priority) {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);

    pd->threadPriority = priority;

    if(pd->isRunning)
        return ThreadPrivateActions::SetThreadSchedulingParams(this);
    else
        return 0;
}

//-----------------------------------------------------------------------------
//
// Description: Get the thread's schedule priority (if able)
//
// Use: public
//
int Thread::getSchedulePriority() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->threadPriority;
}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's scheduling policy (if able)
//
// Use: public
//
int Thread::setSchedulePolicy(ThreadPolicy policy) {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);

    pd->threadPolicy = policy;

    if(pd->isRunning)
        return ThreadPrivateActions::SetThreadSchedulingParams(this);
    else
        return 0;
}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's scheduling policy (if able)
//
// Use: public
//
int Thread::getSchedulePolicy() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->threadPolicy;
}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's desired stack size
//
// Use: public
//
int Thread::setStackSize(size_t stackSize) {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    if(pd->stackSizeLocked == true) return 13;  // EACESS
    pd->stackSize = stackSize;
    return 0;
}
//-----------------------------------------------------------------------------
//
// Description: Get the thread's stack size.
//
// Use: public
//
size_t Thread::getStackSize() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->stackSize;
}

//-----------------------------------------------------------------------------
//
// Description:  Print the thread's scheduling information to stdout.
//
// Use: public
//
void Thread::printSchedulingInfo() {
    ThreadPrivateActions::PrintThreadSchedulingInfo(this);
}

//-----------------------------------------------------------------------------
//
// Description:  Yield the processor
//
// Use: protected
//
#if _WIN32_WINNT < 0x0400 // simulate
int SwitchToThread (void)
{
    Sleep(10);
    return 0;
};
#endif

int Thread::YieldCurrentThread()
{
    return SwitchToThread();
}

<commit_msg>cancelCleanup after run() iff thread is canceled. Change suggested by Frank Lindeman<commit_after>//
// OpenThread library, Copyright (C) 2002 - 2003  The Open Thread Group
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// 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
//

//
// Win32Thread.c++
// ~~~~~~~~~~~
#include <memory>
#include <string>
#include <iostream>

#if defined(_MSC_VER) && (_MSC_VER < 1300)
#ifdef __SGI_STL
using std::size_t;
#endif
#else
using std::size_t;
#endif

#include "Win32ThreadPrivateData.h"

struct Win32ThreadCanceled{};

using namespace OpenThreads;

DWORD OpenThreads::cooperativeWait(HANDLE waitHandle, unsigned long timeout){
    Thread* current = Thread::CurrentThread();
    DWORD dwResult ;
    if(current)
    {
        HANDLE cancelHandle = static_cast<Win32ThreadPrivateData*>(current->getImplementation())->cancelEvent.get();
        HANDLE handleSet[2] = {waitHandle, cancelHandle};

        dwResult = WaitForMultipleObjects(2,handleSet,FALSE,timeout);
        if(dwResult == WAIT_OBJECT_0 + 1 ) throw Win32ThreadCanceled();
    }
    else
    {
        dwResult = WaitForSingleObject(waitHandle,timeout);
    }

    return dwResult;
}

Win32ThreadPrivateData::TlsHolder Win32ThreadPrivateData::TLS;

Win32ThreadPrivateData::~Win32ThreadPrivateData()
{
}

const std::string OPENTHREAD_VERSION_STRING = "OpenThread v1.2preAlpha, WindowThreads (Public Implementation)";

//-----------------------------------------------------------------------------
// Initialize thread master priority level
//
Thread::ThreadPriority Thread::s_masterThreadPriority =  Thread::PRIORITY_DEFAULT;

bool Thread::s_isInitialized = false;
//-----------------------------------------------------------------------------
// Class to support some static methods necessary for pthread's to work
// correctly.
//
namespace OpenThreads {

    class ThreadPrivateActions {
        //-------------------------------------------------------------------------
        // We're friendly to Thread, so it can issue the methods.
        //
        friend class Thread;
    private:

        //-------------------------------------------------------------------------
        // Win32Threads standard start routine.
        //
        static unsigned long __stdcall StartThread(void *data) {

            Thread *thread = static_cast<Thread *>(data);
            Win32ThreadPrivateData *pd =
                static_cast<Win32ThreadPrivateData *>(thread->_prvData);

            TlsSetValue(Win32ThreadPrivateData::TLS.ID ,data);
            //---------------------------------------------------------------------
            // Set the proper scheduling priorities
            //
            SetThreadSchedulingParams(thread);

            pd->isRunning = true;

            try{
                thread->run();
            }
            catch(Win32ThreadCanceled&)
            {
                // thread is canceled do cleanup
                try {
                    thread->cancelCleanup();
                } catch(...) { }
            }
            catch(...)
            {
                // abnormal termination but must be caught in win32 anyway
            }

            pd->isRunning = false;

            return 0;
        };

        //-------------------------------------------------------------------------
        // Print information related to thread schduling parameters.
        //
        static void PrintThreadSchedulingInfo(Thread *thread) {
            Win32ThreadPrivateData *pd =
                static_cast<Win32ThreadPrivateData *>(thread->_prvData);

            std::cout<<"Thread "<< thread <<" priority : ";

            switch(thread->getSchedulePriority()) {
            case Thread::PRIORITY_MAX:
                std::cout<<"MAXIMAL"<<std::endl;
                break;
            case Thread::PRIORITY_HIGH:
                std::cout<<"HIGH"<<std::endl;
                break;
            case Thread::PRIORITY_DEFAULT:
            case Thread::PRIORITY_NOMINAL:
                std::cout<<"NORMAL"<<std::endl;
                break;
            case Thread::PRIORITY_LOW:
                std::cout<<"LOW"<<std::endl;
                break;
            case Thread::PRIORITY_MIN:
                std::cout<<"MINIMAL"<<std::endl;
                break;
            }
        }

        //--------------------------------------------------------------------------
        // Set thread scheduling parameters.
        // Note that time-critical priority is ommited :
        // 1) It's not sensible thing to do
        // 2) there's no enum for that in Thread interface
        // Also, on Windows, effective thread priority is :
        // process priority (manipulated with Get/SetProrityClass) + thread priority (here).
        //
        //
        static int SetThreadSchedulingParams(Thread *thread) {

            Win32ThreadPrivateData *pd =
                static_cast<Win32ThreadPrivateData *>(thread->_prvData);

            int prio = THREAD_PRIORITY_NORMAL;

            switch(thread->getSchedulePriority()) {
            case Thread::PRIORITY_MAX:
                prio = THREAD_PRIORITY_HIGHEST;
                break;
            case Thread::PRIORITY_HIGH:
                prio = THREAD_PRIORITY_ABOVE_NORMAL;
                break;
            case Thread::PRIORITY_NOMINAL:
                prio = THREAD_PRIORITY_NORMAL;
                break;
            case Thread::PRIORITY_LOW:
                prio = THREAD_PRIORITY_BELOW_NORMAL;
                break;
            case Thread::PRIORITY_MIN:
                prio = THREAD_PRIORITY_IDLE;
                break;
            }

            int status = SetThreadPriority( pd->tid.get(), prio);

            if(getenv("OUTPUT_THREADLIB_SCHEDULING_INFO") != 0)
	        	PrintThreadSchedulingInfo(thread);

            return status!=0;
        };
    };
};

Thread* Thread::CurrentThread()
{
    return (Thread* )TlsGetValue(Win32ThreadPrivateData::TLS.ID);
};

//----------------------------------------------------------------------------
//
// Description: Set the concurrency level (no-op)
//
// Use static public
//
int Thread::SetConcurrency(int) {
    return -1;
};

//----------------------------------------------------------------------------
//
// Description: Get the concurrency level
//
// Use static public
//
int Thread::GetConcurrency() {
    return -1;
};

//----------------------------------------------------------------------------
//
// Decription: Constructor
//
// Use: public.
//
Thread::Thread() {

    // there's no need for this
    //    if(!s_isInitialized) Init();

    Win32ThreadPrivateData *pd = new Win32ThreadPrivateData();

    pd->stackSize = 0;

    pd->stackSizeLocked = false;

    pd->idSet = false;

    pd->isRunning = false;

    pd->cancelMode = 0;

    pd->uniqueId = 0;

    pd->threadPriority = PRIORITY_DEFAULT;

    pd->threadPolicy = SCHEDULE_DEFAULT;

    pd->detached = false;

    pd->cancelEvent.set(CreateEvent(NULL,TRUE,FALSE,NULL));

    _prvData = static_cast<void *>(pd);

}

//----------------------------------------------------------------------------
//
// Decription: Destructor
//
// Use: public.
//
Thread::~Thread() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *>(_prvData);
    if(pd->isRunning) {
        std::cout<<"Error: Thread "<<this<<" still running in destructor"<<std::endl;
        pd->cancelMode = 0;
        cancel();
    }
    delete pd;
}
//-----------------------------------------------------------------------------
//
// Description: Initialize Threading
//
// Use: public.
//
void Thread::Init() {
//    if(s_isInitialized) return;
//        s_masterThreadPriority = Thread::PRIORITY_DEFAULT;
    s_isInitialized = true;
}

//-----------------------------------------------------------------------------
//
// Description: Get a unique identifier for this thread.
//
// Use: public
//
int Thread::getThreadId() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->uniqueId;
}
//-----------------------------------------------------------------------------
//
// Description: Get the thread's process id
//
// Use: public
//
int Thread::getProcessId() {

    return (int) GetCurrentProcessId();

}
//-----------------------------------------------------------------------------
//
// Description: Determine if the thread is running
//
// Use: public
//
bool Thread::isRunning() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->isRunning;
}
//-----------------------------------------------------------------------------
//
// Description: Start the thread.
//
// Use: public
//
int Thread::start() {

    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    //-------------------------------------------------------------------------
    // Prohibit the stack size from being changed.
    //
    pd->stackSizeLocked = true;
    unsigned long ID;

    pd->tid.set( CreateThread(NULL,pd->stackSize,ThreadPrivateActions::StartThread,static_cast<void *>(this),0,&ID));

    pd->uniqueId = (int)ID;

    if(!pd->tid) {
        return -1;
    }

    pd->idSet = true;

    return 0;

}

int Thread::startThread()
{ return start(); }

//-----------------------------------------------------------------------------
//
// Description: Join the thread.
//
// Use: public
//
int Thread::join() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    if( pd->detached )
        return -1; // cannot wait for detached ;

    if( WaitForSingleObject(pd->tid.get(),INFINITE) != WAIT_OBJECT_0)
        return -1 ;

    return 0;
}

int Thread::detach()
{
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    pd->detached = true;
    return 0;
}

//-----------------------------------------------------------------------------
//
// Description: Cancel the thread.
//
// Use: public
//
int Thread::cancel()
{
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);

    if (pd->isRunning)
    {
        if( pd->cancelMode == 2 )
            return -1;

        // signal all interested parties that we are going to exit
        SetEvent(pd->cancelEvent.get());

        // cancelMode == 1 (asynch)-> kill em
        // cancelMode == 0 (deffered) -> wait a little then kill em

    //    if( (pd->cancelMode == 1) || (WaitForSingleObject(pd->tid,INFINITE)!=WAIT_OBJECT_0) )
        if( pd->cancelMode == 1 )
        {
            // did not terminate cleanly force termination
            pd->isRunning = false;
            return TerminateThread(pd->tid.get(),(DWORD)-1);
        }
    }

    return 0;
}

int Thread::testCancel()
{
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);

    if(WaitForSingleObject(pd->cancelEvent.get(),0) != WAIT_OBJECT_0) return 0;

    if(pd->cancelMode == 2)
        return 0;

    DWORD curr = GetCurrentThreadId();

    if( pd->uniqueId != (int)curr )
        return -1;

//    pd->isRunning = false;
//    ExitThread(0);
    throw Win32ThreadCanceled();

    return 0;

}

//-----------------------------------------------------------------------------
//
// Description: Disable cancelibility
//
// Use: public
//
int Thread::setCancelModeDisable() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    pd->cancelMode = 2;
    return 0;
}

//-----------------------------------------------------------------------------
//
// Description: set the thread to cancel immediately
//
// Use: public
//
int Thread::setCancelModeAsynchronous() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    pd->cancelMode  = 1;
    return 0;
}

//-----------------------------------------------------------------------------
//
// Description: set the thread to cancel at the next convienent point.
//
// Use: public
//
int Thread::setCancelModeDeferred() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    pd->cancelMode = 0;
    return 0;
}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's schedule priority (if able)
//
// Use: public
//
int Thread::setSchedulePriority(ThreadPriority priority) {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);

    pd->threadPriority = priority;

    if(pd->isRunning)
        return ThreadPrivateActions::SetThreadSchedulingParams(this);
    else
        return 0;
}

//-----------------------------------------------------------------------------
//
// Description: Get the thread's schedule priority (if able)
//
// Use: public
//
int Thread::getSchedulePriority() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->threadPriority;
}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's scheduling policy (if able)
//
// Use: public
//
int Thread::setSchedulePolicy(ThreadPolicy policy) {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);

    pd->threadPolicy = policy;

    if(pd->isRunning)
        return ThreadPrivateActions::SetThreadSchedulingParams(this);
    else
        return 0;
}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's scheduling policy (if able)
//
// Use: public
//
int Thread::getSchedulePolicy() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->threadPolicy;
}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's desired stack size
//
// Use: public
//
int Thread::setStackSize(size_t stackSize) {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    if(pd->stackSizeLocked == true) return 13;  // EACESS
    pd->stackSize = stackSize;
    return 0;
}
//-----------------------------------------------------------------------------
//
// Description: Get the thread's stack size.
//
// Use: public
//
size_t Thread::getStackSize() {
    Win32ThreadPrivateData *pd = static_cast<Win32ThreadPrivateData *> (_prvData);
    return pd->stackSize;
}

//-----------------------------------------------------------------------------
//
// Description:  Print the thread's scheduling information to stdout.
//
// Use: public
//
void Thread::printSchedulingInfo() {
    ThreadPrivateActions::PrintThreadSchedulingInfo(this);
}

//-----------------------------------------------------------------------------
//
// Description:  Yield the processor
//
// Use: protected
//
#if _WIN32_WINNT < 0x0400 // simulate
int SwitchToThread (void)
{
    Sleep(10);
    return 0;
};
#endif

int Thread::YieldCurrentThread()
{
    return SwitchToThread();
}

<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// class for T0 calibration                       TM-AC-AM_6-02-2006
// equalize time shift for each time CFD channel
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliT0CalibTimeEq.h"

#include <TFile.h>
#include <TMath.h>
#include <TF1.h>
#include <TSpectrum.h>
#include <TProfile.h>
#include <iostream>

ClassImp(AliT0CalibTimeEq)

//________________________________________________________________
  AliT0CalibTimeEq::AliT0CalibTimeEq():TNamed()
{
  //
}

//________________________________________________________________
AliT0CalibTimeEq::AliT0CalibTimeEq(const char* name):TNamed()
{
  //constructor

  TString namst = "Calib_";
  namst += name;
  SetName(namst.Data());
  SetTitle(namst.Data());
}

//________________________________________________________________
AliT0CalibTimeEq::AliT0CalibTimeEq(const AliT0CalibTimeEq& calibda):TNamed(calibda)
{
// copy constructor
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

}

//________________________________________________________________
AliT0CalibTimeEq &AliT0CalibTimeEq::operator =(const AliT0CalibTimeEq& calibda)
{
// assignment operator
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

  return *this;
}

//________________________________________________________________
AliT0CalibTimeEq::~AliT0CalibTimeEq()
{
  //
  // destrictor
}
//________________________________________________________________
void AliT0CalibTimeEq::Reset()
{
  //reset values

  memset(fCFDvalue,0,120*sizeof(Float_t));
  memset(fTimeEq,1,24*sizeof(Float_t));
}

//________________________________________________________________
void  AliT0CalibTimeEq::Print(Option_t*) const
{
  // print time values

  printf("\n	----	PM Arrays	----\n\n");
  printf(" Time delay CFD \n");
  for (Int_t i=0; i<24; i++) printf(" CFD  %f ",fTimeEq[i]);
}

//________________________________________________________________
void AliT0CalibTimeEq::ComputeOnlineParams(const char* filePhys)
{
  // compute online equalized time
  // Int_t npeaks = 20;
  // Double_t sigma = 4.;
  //  Bool_t down=false;
  // Int_t index[20];

  gFile = TFile::Open(filePhys);
  gFile->ls();
  Char_t buf1[30];
  for (Int_t i=0; i<24; i++)
  {
    //    if(i<12) sprintf(buf1,"CFD1minCFD%d",i+1);
    // if(i>11) sprintf(buf1,"CFD13minCFD%d",i+1);
    if(i<12) sprintf(buf1,"T0_C_%i_CFD",i+1);
    if(i>11) sprintf(buf1,"T0_A_%i_CFD",i+1-12);
    printf(" i = %d buf1 = %s\n", i, buf1);
    TH1F *cfd = (TH1F*) gFile->Get(buf1);

    //    printf(" i = %d buf1 = %s\n", i, buf1);
    Double_t mean=cfd->GetMean();
    printf(" ipmt %i mean = %f \n", i,mean) ;

    /*
    TSpectrum *s = new TSpectrum(2*npeaks,1.);
    // printf(" buf1 = %s cfd = %x\n", buf1, cfd);
    Int_t nfound = s->Search(cfd,sigma,"goff",0.2);
    printf(" nfound = %d\n", nfound);
    if(nfound!=0)
    {
      Float_t *xpeak = s->GetPositionX();
      TMath::Sort(nfound, xpeak, index,down);
      Float_t xp = xpeak[index[0]];
      Float_t hmax = xp+3*sigma;
      Float_t hmin = xp-3*sigma;
      cfd->GetXaxis()->SetRangeUser(hmin-10,hmax+10);
      TF1 *g1 = new TF1("g1", "gaus", hmin, hmax);
      cfd->Fit("g1","IRQN");
     printf(" ipmt %i fit mean = %f \n", i, g1->GetParameter(1)) ;

    }
    */
      SetTimeEq(i,Int_t(mean));
  }
  // delete cfd;

   gFile->Close();
   delete gFile;
   printf("\n\n");
   for(int j=0;j<24;j++)
   {
                printf("fTimeEq[%d]=%f\n",j,fTimeEq[j]);
   }

}

<commit_msg> for current DA<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// class for T0 calibration                       TM-AC-AM_6-02-2006
// equalize time shift for each time CFD channel
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "AliT0CalibTimeEq.h"

#include <TFile.h>
#include <TMath.h>
#include <TF1.h>
#include <TSpectrum.h>
#include <TProfile.h>
#include <iostream>

ClassImp(AliT0CalibTimeEq)

//________________________________________________________________
  AliT0CalibTimeEq::AliT0CalibTimeEq():TNamed()
{
  //
}

//________________________________________________________________
AliT0CalibTimeEq::AliT0CalibTimeEq(const char* name):TNamed()
{
  //constructor

  TString namst = "Calib_";
  namst += name;
  SetName(namst.Data());
  SetTitle(namst.Data());
}

//________________________________________________________________
AliT0CalibTimeEq::AliT0CalibTimeEq(const AliT0CalibTimeEq& calibda):TNamed(calibda)
{
// copy constructor
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

}

//________________________________________________________________
AliT0CalibTimeEq &AliT0CalibTimeEq::operator =(const AliT0CalibTimeEq& calibda)
{
// assignment operator
  SetName(calibda.GetName());
  SetTitle(calibda.GetName());

  return *this;
}

//________________________________________________________________
AliT0CalibTimeEq::~AliT0CalibTimeEq()
{
  //
  // destrictor
}
//________________________________________________________________
void AliT0CalibTimeEq::Reset()
{
  //reset values

  memset(fCFDvalue,0,120*sizeof(Float_t));
  memset(fTimeEq,1,24*sizeof(Float_t));
}

//________________________________________________________________
void  AliT0CalibTimeEq::Print(Option_t*) const
{
  // print time values

  printf("\n	----	PM Arrays	----\n\n");
  printf(" Time delay CFD \n");
  for (Int_t i=0; i<24; i++) printf(" CFD  %f ",fTimeEq[i]);
}

//________________________________________________________________
void AliT0CalibTimeEq::ComputeOnlineParams(const char* filePhys)
{
  // compute online equalized time
  // Int_t npeaks = 20;
  // Double_t sigma = 4.;
  //  Bool_t down=false;
  // Int_t index[20];

  gFile = TFile::Open(filePhys);
  gFile->ls();
  Char_t buf1[30];
 for (Int_t i=0; i<24; i++)
  {
    sprintf(buf1,"CFD1-CFD%d",i+1);
    TH1F *cfd = (TH1F*) gFile->Get(buf1);
    //    printf(" i = %d buf1 = %s\n", i, buf1);
    Double_t mean=cfd->GetMean();
    SetTimeEq(i,mean);
    delete cfd;
  }

   gFile->Close();
   delete gFile;
   printf("\n\n");
   for(int j=0;j<24;j++)
   {
                printf("fTimeEq[%d]=%f\n",j,fTimeEq[j]);
   }

}

<|endoftext|>


<commit_before>// Copyright (c) 2015 The Brick Authors.

#include "brick/window_util.h"

#include <gtk/gtk.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>

#include "include/internal/cef_linux.h"
#include "include/base/cef_logging.h"

#include "brick/brick_app.h"

namespace {
  GList *default_icons = NULL;
  CefWindowHandle leader_window_;
  double device_scale_factor = 0;
  const double kCSSDefaultDPI = 96.0;

  int
  XErrorHandlerImpl(Display *display, XErrorEvent *event) {
    LOG(WARNING)
    << "X error received: "
    << "type " << event->type << ", "
    << "serial " << event->serial << ", "
    << "error_code " << static_cast<int>(event->error_code) << ", "
    << "request_code " << static_cast<int>(event->request_code) << ", "
    << "minor_code " << static_cast<int>(event->minor_code);
    return 0;
  }

  int
  XIOErrorHandlerImpl(Display *display) {
    return 0;
  }
}  // namespace

namespace window_util {

  CefWindowHandle
  GetParent(CefWindowHandle handle) {
    ::Window root;
    ::Window parent;
    ::Window *children;
    unsigned int nchildren;
    XQueryTree(cef_get_xdisplay(), handle, &root, &parent, &children, &nchildren);
    XFree(children);

    return parent;
  }

  void
  Resize(CefWindowHandle handle, int width, int height) {
    XResizeWindow(
       cef_get_xdisplay(),
       handle,
       (unsigned int) width,
       (unsigned int) height
    );
  }

  void
  SetMinSize(CefWindowHandle handle, int width, int height) {
    XSizeHints *size_hints = XAllocSizeHints();
    if (!size_hints) {
      LOG(ERROR) << "SetMinSize: Can't allocate memory for XAllocSizeHints";
      return;
    }

    size_hints->flags = PMinSize;
    size_hints->min_width = width;
    size_hints->min_height = height;

    XSetWMNormalHints(
       cef_get_xdisplay(),
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  ConfigureAsDialog(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();

    Atom type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
    Atom value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
    XChangeProperty(display, handle, type, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&value), 1);
  }

  void
  ConfigureAsTopmost(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();

    Atom type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
    Atom value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_UTILITY", False);
    XChangeProperty(display, handle, type, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&value), 1);

    Atom state[2];
    state[0] = XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", False);
    state[1] = XInternAtom(display, "_NET_WM_STATE_SKIP_PAGER", False);
    Atom wm_state = XInternAtom(display, "_NET_WM_STATE", False);
    XChangeProperty (display, handle, wm_state, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&state), 2);
  }

  void
  SetGroupByLeader(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();
    XWMHints base_hints;
    XWMHints * h = XGetWMHints(display, handle);
    if (!h) {
      h = &base_hints;
      h->flags = 0;
    }
    h->flags |= WindowGroupHint;
    h->window_group = leader_window_;
    XSetWMHints(display, handle, h);
    if(h != &base_hints) {
      XFree(h);
    }
  }

  void
  SetClientLeader(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();

    Atom type = XInternAtom(display, "WM_CLIENT_LEADER", False);
    XChangeProperty(display, handle, type, XA_WINDOW, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&leader_window_), 1);
    SetGroupByLeader(handle);
  }

  void
  FixSize(CefWindowHandle handle, int width, int height) {
    XSizeHints *size_hints = XAllocSizeHints();
    ::XDisplay *display = cef_get_xdisplay();

    if (!size_hints) {
      LOG(ERROR) << "FixSize: Can't allocate memory for XAllocSizeHints";
      return;
    }

    if (width && height) {
      size_hints->flags = PSize | PMinSize | PMaxSize;
      size_hints->width = width;
      size_hints->height = height;
      size_hints->min_width = width;
      size_hints->min_height = height;
      size_hints->max_width = width;
      size_hints->max_height = height;
    } else {
      size_hints->flags = PMinSize | PMaxSize;
      size_hints->max_width = width;
      size_hints->max_height = height;
    }

    XSetWMNormalHints(
       display,
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  InitAsPopup(CefWindowHandle handle) {
    ConfigureAsDialog(handle);
  }

  void
  Hide(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XUnmapWindow(display, handle);
  }

  void
  Show(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XMapWindow(display, handle);
  }

  void
  CenterPosition(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XSizeHints *size_hints = XAllocSizeHints();
    if (!size_hints) {
      LOG(ERROR) << "CenterPosition: Can't allocate memory for XAllocSizeHints";
      return;
    }

    size_hints->flags = PWinGravity;
    size_hints->win_gravity = CenterGravity;

    XSetWMNormalHints(
       display,
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  SetTitle(CefWindowHandle handle, std::string title) {
    std::string titleStr(title);

    // Retrieve the X11 display shared with Chromium.
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    DCHECK(handle != kNullWindowHandle);

    // Retrieve the atoms required by the below XChangeProperty call.
    const char *kAtoms[] = {
       "_NET_WM_NAME",
       "UTF8_STRING"
    };
    Atom atoms[2];
    int result = XInternAtoms(display, const_cast<char **>(kAtoms), 2, false,
       atoms);
    if (!result)
      NOTREACHED();

    // Set the window title.
    XChangeProperty(display,
       handle,
       atoms[0],
       atoms[1],
       8,
       PropModeReplace,
       reinterpret_cast<const unsigned char *>(titleStr.c_str()),
       titleStr.size());

    // TODO(erg): This is technically wrong. So XStoreName and friends expect
    // this in Host Portable Character Encoding instead of UTF-8, which I believe
    // is Compound Text. This shouldn't matter 90% of the time since this is the
    // fallback to the UTF8 property above.
    XStoreName(display, handle, titleStr.c_str());
  }

  void
  SetClassHints(CefWindowHandle handle, char *res_name, char *res_class) {
    XClassHint *class_hints = XAllocClassHint();
    ::XDisplay *display = cef_get_xdisplay();

    if (!class_hints) {
      LOG(ERROR) << "SetClassHints: Can't allocate memory for XAllocClassHint";
      return;
    }

    class_hints->res_name = res_name;
    class_hints->res_class = res_class;

    XSetClassHint(display, handle, class_hints);
    XFree(class_hints);
  }

  void
  SetLeaderWindow(CefWindowHandle handle) {
    leader_window_ = handle;
  }

  CefWindowHandle
  GetLeaderWindow() {
    return leader_window_;
  }

  void
  InitHooks() {
    XSetErrorHandler(XErrorHandlerImpl);
    XSetIOErrorHandler(XIOErrorHandlerImpl);
  }

  void
  InitWindow(CefWindowHandle handle, bool is_leader) {
    if (is_leader)
      SetLeaderWindow(handle);
    else
      SetClientLeader(handle);

    SetClassHints(handle, const_cast<char *>(APP_COMMON_NAME), const_cast<char *>(APP_NAME));
  }

  GList*
  GetDefaultIcons() {
    return default_icons;
  }

  void SetDefaultIcons(GList* icons) {
    if (default_icons) {
      g_list_foreach(default_icons, (GFunc) g_object_unref, NULL);
      g_list_free(default_icons);
    }

    default_icons = icons;
    gtk_window_set_default_icon_list(icons);
  }

  BrowserWindow*
  LookupBrowserWindow(CefWindowHandle native_window) {
    GdkWindow * gdk_window = GDK_WINDOW(gdk_xid_table_lookup(native_window));
    return reinterpret_cast<BrowserWindow*>(
        g_object_get_data(G_OBJECT(gdk_window), "wrapper")
    );
  }

  BrowserWindow*
  LookupBrowserWindow(GdkEvent* event) {
    if (event->type == GDK_NOTHING) {
      // GDK_NOTHING event doesn't have any windows
      return NULL;
    }

    GObject *object = G_OBJECT(event->any.window);
    if (!G_IS_OBJECT(object)) {
      LOG(ERROR) << "Try lookup browser window of bad native window"
         << ", event type: " << event->type
         << ", event window: " << event->any.window;
      return NULL;
    }

    return reinterpret_cast<BrowserWindow*>(
        g_object_get_data(object, "wrapper")
    );
  }

  void
  FlushChanges() {
    ::XDisplay *display = cef_get_xdisplay();

    XFlush(display);
  }

  CefRect
  GetDefaultScreenRect() {
    GdkRectangle monitor_rect;
    gdk_screen_get_monitor_geometry(gdk_screen_get_default(), 0, &monitor_rect);

    return CefRect(
       monitor_rect.x,
       monitor_rect.y,
       monitor_rect.width,
       monitor_rect.height
    );
  }

  double
  GetDPI() {
    GtkSettings* gtk_settings = gtk_settings_get_default();
    DCHECK(gtk_settings);
    gint gtk_dpi = -1;
    g_object_get(gtk_settings, "gtk-xft-dpi", &gtk_dpi, NULL);

    // GTK multiplies the DPI by 1024 before storing it.
    return (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kCSSDefaultDPI;
  }

  double
  GetDeviceScaleFactor() {
    if (!device_scale_factor)
      device_scale_factor = floor((GetDPI() / kCSSDefaultDPI) * 100) / 100;

    return device_scale_factor;
  }
}  // namespace window_util
<commit_msg>_NET_WM_WINDOW_TYPE_UTILITY для topmost окошек не лучший выбор (мешают некоторым тайловым WM), пока вернемся на _NET_WM_WINDOW_TYPE_DIALOG а дальше посмотрим.<commit_after>// Copyright (c) 2015 The Brick Authors.

#include "brick/window_util.h"

#include <gtk/gtk.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>

#include "include/internal/cef_linux.h"
#include "include/base/cef_logging.h"

#include "brick/brick_app.h"

namespace {
  GList *default_icons = NULL;
  CefWindowHandle leader_window_;
  double device_scale_factor = 0;
  const double kCSSDefaultDPI = 96.0;

  int
  XErrorHandlerImpl(Display *display, XErrorEvent *event) {
    LOG(WARNING)
    << "X error received: "
    << "type " << event->type << ", "
    << "serial " << event->serial << ", "
    << "error_code " << static_cast<int>(event->error_code) << ", "
    << "request_code " << static_cast<int>(event->request_code) << ", "
    << "minor_code " << static_cast<int>(event->minor_code);
    return 0;
  }

  int
  XIOErrorHandlerImpl(Display *display) {
    return 0;
  }
}  // namespace

namespace window_util {

  CefWindowHandle
  GetParent(CefWindowHandle handle) {
    ::Window root;
    ::Window parent;
    ::Window *children;
    unsigned int nchildren;
    XQueryTree(cef_get_xdisplay(), handle, &root, &parent, &children, &nchildren);
    XFree(children);

    return parent;
  }

  void
  Resize(CefWindowHandle handle, int width, int height) {
    XResizeWindow(
       cef_get_xdisplay(),
       handle,
       (unsigned int) width,
       (unsigned int) height
    );
  }

  void
  SetMinSize(CefWindowHandle handle, int width, int height) {
    XSizeHints *size_hints = XAllocSizeHints();
    if (!size_hints) {
      LOG(ERROR) << "SetMinSize: Can't allocate memory for XAllocSizeHints";
      return;
    }

    size_hints->flags = PMinSize;
    size_hints->min_width = width;
    size_hints->min_height = height;

    XSetWMNormalHints(
       cef_get_xdisplay(),
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  ConfigureAsDialog(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();

    Atom type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
    Atom value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
    XChangeProperty(display, handle, type, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&value), 1);
  }

  void
  ConfigureAsTopmost(CefWindowHandle handle) {
    ConfigureAsDialog(handle);

    ::XDisplay *display = cef_get_xdisplay();

    Atom state[2];
    state[0] = XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", False);
    state[1] = XInternAtom(display, "_NET_WM_STATE_SKIP_PAGER", False);
    Atom wm_state = XInternAtom(display, "_NET_WM_STATE", False);
    XChangeProperty (display, handle, wm_state, XA_ATOM, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&state), 2);
  }

  void
  SetGroupByLeader(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();
    XWMHints base_hints;
    XWMHints * h = XGetWMHints(display, handle);
    if (!h) {
      h = &base_hints;
      h->flags = 0;
    }
    h->flags |= WindowGroupHint;
    h->window_group = leader_window_;
    XSetWMHints(display, handle, h);
    if(h != &base_hints) {
      XFree(h);
    }
  }

  void
  SetClientLeader(CefWindowHandle handle) {
    ::XDisplay *display = cef_get_xdisplay();

    Atom type = XInternAtom(display, "WM_CLIENT_LEADER", False);
    XChangeProperty(display, handle, type, XA_WINDOW, 32, PropModeReplace, reinterpret_cast<unsigned char *>(&leader_window_), 1);
    SetGroupByLeader(handle);
  }

  void
  FixSize(CefWindowHandle handle, int width, int height) {
    XSizeHints *size_hints = XAllocSizeHints();
    ::XDisplay *display = cef_get_xdisplay();

    if (!size_hints) {
      LOG(ERROR) << "FixSize: Can't allocate memory for XAllocSizeHints";
      return;
    }

    if (width && height) {
      size_hints->flags = PSize | PMinSize | PMaxSize;
      size_hints->width = width;
      size_hints->height = height;
      size_hints->min_width = width;
      size_hints->min_height = height;
      size_hints->max_width = width;
      size_hints->max_height = height;
    } else {
      size_hints->flags = PMinSize | PMaxSize;
      size_hints->max_width = width;
      size_hints->max_height = height;
    }

    XSetWMNormalHints(
       display,
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  InitAsPopup(CefWindowHandle handle) {
    ConfigureAsDialog(handle);
  }

  void
  Hide(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XUnmapWindow(display, handle);
  }

  void
  Show(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XMapWindow(display, handle);
  }

  void
  CenterPosition(CefWindowHandle handle) {
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    XSizeHints *size_hints = XAllocSizeHints();
    if (!size_hints) {
      LOG(ERROR) << "CenterPosition: Can't allocate memory for XAllocSizeHints";
      return;
    }

    size_hints->flags = PWinGravity;
    size_hints->win_gravity = CenterGravity;

    XSetWMNormalHints(
       display,
       handle,
       size_hints
    );
    XFree(size_hints);
  }

  void
  SetTitle(CefWindowHandle handle, std::string title) {
    std::string titleStr(title);

    // Retrieve the X11 display shared with Chromium.
    ::Display *display = cef_get_xdisplay();
    DCHECK(display);

    DCHECK(handle != kNullWindowHandle);

    // Retrieve the atoms required by the below XChangeProperty call.
    const char *kAtoms[] = {
       "_NET_WM_NAME",
       "UTF8_STRING"
    };
    Atom atoms[2];
    int result = XInternAtoms(display, const_cast<char **>(kAtoms), 2, false,
       atoms);
    if (!result)
      NOTREACHED();

    // Set the window title.
    XChangeProperty(display,
       handle,
       atoms[0],
       atoms[1],
       8,
       PropModeReplace,
       reinterpret_cast<const unsigned char *>(titleStr.c_str()),
       titleStr.size());

    // TODO(erg): This is technically wrong. So XStoreName and friends expect
    // this in Host Portable Character Encoding instead of UTF-8, which I believe
    // is Compound Text. This shouldn't matter 90% of the time since this is the
    // fallback to the UTF8 property above.
    XStoreName(display, handle, titleStr.c_str());
  }

  void
  SetClassHints(CefWindowHandle handle, char *res_name, char *res_class) {
    XClassHint *class_hints = XAllocClassHint();
    ::XDisplay *display = cef_get_xdisplay();

    if (!class_hints) {
      LOG(ERROR) << "SetClassHints: Can't allocate memory for XAllocClassHint";
      return;
    }

    class_hints->res_name = res_name;
    class_hints->res_class = res_class;

    XSetClassHint(display, handle, class_hints);
    XFree(class_hints);
  }

  void
  SetLeaderWindow(CefWindowHandle handle) {
    leader_window_ = handle;
  }

  CefWindowHandle
  GetLeaderWindow() {
    return leader_window_;
  }

  void
  InitHooks() {
    XSetErrorHandler(XErrorHandlerImpl);
    XSetIOErrorHandler(XIOErrorHandlerImpl);
  }

  void
  InitWindow(CefWindowHandle handle, bool is_leader) {
    if (is_leader)
      SetLeaderWindow(handle);
    else
      SetClientLeader(handle);

    SetClassHints(handle, const_cast<char *>(APP_COMMON_NAME), const_cast<char *>(APP_NAME));
  }

  GList*
  GetDefaultIcons() {
    return default_icons;
  }

  void SetDefaultIcons(GList* icons) {
    if (default_icons) {
      g_list_foreach(default_icons, (GFunc) g_object_unref, NULL);
      g_list_free(default_icons);
    }

    default_icons = icons;
    gtk_window_set_default_icon_list(icons);
  }

  BrowserWindow*
  LookupBrowserWindow(CefWindowHandle native_window) {
    GdkWindow * gdk_window = GDK_WINDOW(gdk_xid_table_lookup(native_window));
    return reinterpret_cast<BrowserWindow*>(
        g_object_get_data(G_OBJECT(gdk_window), "wrapper")
    );
  }

  BrowserWindow*
  LookupBrowserWindow(GdkEvent* event) {
    if (event->type == GDK_NOTHING) {
      // GDK_NOTHING event doesn't have any windows
      return NULL;
    }

    GObject *object = G_OBJECT(event->any.window);
    if (!G_IS_OBJECT(object)) {
      LOG(ERROR) << "Try lookup browser window of bad native window"
         << ", event type: " << event->type
         << ", event window: " << event->any.window;
      return NULL;
    }

    return reinterpret_cast<BrowserWindow*>(
        g_object_get_data(object, "wrapper")
    );
  }

  void
  FlushChanges() {
    ::XDisplay *display = cef_get_xdisplay();

    XFlush(display);
  }

  CefRect
  GetDefaultScreenRect() {
    GdkRectangle monitor_rect;
    gdk_screen_get_monitor_geometry(gdk_screen_get_default(), 0, &monitor_rect);

    return CefRect(
       monitor_rect.x,
       monitor_rect.y,
       monitor_rect.width,
       monitor_rect.height
    );
  }

  double
  GetDPI() {
    GtkSettings* gtk_settings = gtk_settings_get_default();
    DCHECK(gtk_settings);
    gint gtk_dpi = -1;
    g_object_get(gtk_settings, "gtk-xft-dpi", &gtk_dpi, NULL);

    // GTK multiplies the DPI by 1024 before storing it.
    return (gtk_dpi > 0) ? gtk_dpi / 1024.0 : kCSSDefaultDPI;
  }

  double
  GetDeviceScaleFactor() {
    if (!device_scale_factor)
      device_scale_factor = floor((GetDPI() / kCSSDefaultDPI) * 100) / 100;

    return device_scale_factor;
  }
}  // namespace window_util
<|endoftext|>


<commit_before>//  Based on https://github.com/MediaTek-Labs/WeatherStation1.0/blob/master/WeatherStation_1.0.ino

//  Update these 2 lines with your group ID and device ID.
#define GROUP "1"
#define DEVICE "1"

//  This is the REST service for transmitting the sensor values.
#define SITE_URL "AzureIoTService.cloudapp.net"
#define SITE_PORT 80

//  This is a long-lasting TCP socket connection to receive actuation commands from the cloud.
#define SERVER_IP "AzureIoTService.cloudapp.net"
#define SERVER_PORT 2012
/*
Make sure you have a file named password.h containing the lines:
#define WIFI_SSID "yourwifissid"
#define WIFI_KEY "yourwifipassword"
*/
#include <Arduino.h>
#include "password.h"
#include "send_data.h"
#include "led.h"
#include <LTask.h>
#include <LWiFi.h>
#include <LWiFiClient.h>
#include <Wire.h>
#include <math.h>
#include <LDateTime.h>
#include <HttpClient.h>
#include <LFlash.h>

// ================================================
// Define
#undef _DBG_
#define WIFI_AUTH LWIFI_WPA  // choose from LWIFI_OPEN, LWIFI_WPA, or LWIFI_WEP.
#define per 5 // time interval in seconds to upload sensor data to MCS
#define per1 50 // time interval in seconds to initiate TCP heart beat
#define Drv LFlash

// ================================================
// Global variable

const unsigned char OSS = 0;  // Oversampling Setting
// Calibration values
int16_t ac1;
int16_t ac2;
int16_t ac3;
uint16_t ac4;
uint16_t ac5;
uint16_t ac6;
int16_t b1;
int16_t b2;
int16_t mb;
int16_t mc;
int16_t md;
unsigned int rtc;
unsigned int lrtc;
unsigned int lrtc2;
unsigned int rtc2;
unsigned int rtc1;
unsigned int lrtc1;
char ssid[] = WIFI_SSID;
char key[] = WIFI_KEY;
char deviceid[] = "mydeviceid";
char devicekey[] = "mydevicekey";
LWiFiClient c;
LWiFiClient c2;
char connection_info[21]="                    ";
char ip[] = SERVER_IP;
int portnum = SERVER_PORT;
int val = 0;
String tcpcmd_led_on;
String tcpcmd_led_off;
String upload_led;
String hello;
HttpClient http(c2);
int state = 0;
int i = 0;

void fatal_error(const char* str)
{
  Serial.println(str);
  while(1)
    delay(100);
}

// ==============================================================
// TCP Socket server connection functions

void connectTCP(){
  //establish TCP connection with TCP Server with designate IP and Port
  c.stop();
  Serial.println("Connecting to TCP socket for receiving actuation commands...");
  Serial.print("IP: "); Serial.println(ip);
  Serial.print("Port: "); Serial.println(portnum);
  while (0 == c.connect(ip, portnum))
  {
    Serial.println("Re-Connecting to TCP");
    delay(1000);
  }
  //  Tell the server our group ID and device ID.
  Serial.println("Connected to TCP socket for receiving actuation commands");
  hello = "HELLO " + String(GROUP) + " " + String(DEVICE);
  Serial.print(">>> "); Serial.println(hello);
  c.println(hello);
  Serial.println("Waiting for TCP response...");
} //connectTCP

void heartBeat(){
  Serial.println("Sending TCP heartBeat...");
  Serial.print(">>> "); Serial.println(hello);
  c.println(hello);
} //heartBeat

void senddata(float temperature_sensor_value, int light_sensor_value) {
  Serial.println("Sending sensor data to cloud...");
  char buffer1[5];
  sprintf(buffer1, "%.2f", temperature_sensor_value);

  LWiFiClient c2;
  unsigned long t1 = millis();
  Serial.print("Connecting to "); Serial.print(SITE_URL); Serial.print(" port "); Serial.print(SITE_PORT); Serial.println("...");
  while (0 == c2.connect(SITE_URL, SITE_PORT))
  {
    Serial.println("Reconnecting to cloud REST server...");
    delay(1000);
  }

  delay(500);
  Serial.println("Sending POST request to cloud REST server...");
  String url = "POST /RecordSensorData.aspx?Group=" + String(GROUP) + "&Device=" + String(DEVICE) +
    "&Temperature=" + String(buffer1) + "&LightLevel=" + String(light_sensor_value) + " HTTP/1.1";
  Serial.print(">>> "); Serial.println(url);
  c2.println(url);
  c2.print("Host: ");
  c2.print(SITE_URL); c2.print(":"); c2.println(SITE_PORT);
  c2.print("Content-Length: ");
  c2.println(0);
  //c2.println(thisLength);
  c2.println("Content-Type: text/csv");
  c2.println("Connection: close");
  c2.println();

  String dataget = "";
  Serial.println("Waiting for HTTP response...");

  int errorcount = 0;
  while (!c2.available())
  {
    Serial.println("Waiting for HTTP response...");
    errorcount += 1;
    if (errorcount > 10) {
      c2.stop();
      return;
    }
    delay(100);
  }
  while (c2)
  {
    int v = c2.read();
    if (v != -1)
    {
      Serial.print(char(v));

      delay(1);
    }
    else
    {
      Serial.println("No more content, disconnecting...");
      c2.stop();
    }
  }
  Serial.println("\r\nSensor data sent to cloud");
  delay(300);
  unsigned long t2 = millis();
}

// ==============================================================
// Main program
void send_data_setup() {
  Wire.begin();
  LTask.begin();
  LWiFi.begin();
  //while(!Serial) delay(1000); //mark this demo as standalone
  Serial.println("Connecting to WiFi access point...");
  Serial.println(ssid);
  Serial.println(key);
  while (0 == LWiFi.connect(ssid, LWiFiLoginInfo(WIFI_AUTH, key))){
    Serial.print(".");
    delay(1000);
  }
  Serial.println("WiFi Connected");
  delay(100);
  Serial.println("LED is set to LOW");
  LDateTime.getRtc(&lrtc);
  LDateTime.getRtc(&lrtc2);
  while (!c2.connect(SITE_URL, SITE_PORT)){
    Serial.println("Reconnecting to cloud REST server...");
    delay(1000);
  }
  delay(100);
  connectTCP();
}

void send_data_loop(float temperature_sensor_value, int light_sensor_value) {
  if (LWiFi.status() == LWIFI_STATUS_DISCONNECTED) {
    Serial.println("Disconnected from WiFi");
    while (0 == LWiFi.connect(ssid, LWiFiLoginInfo(WIFI_AUTH, key))){
      Serial.println("Connecting to WiFi...");
      delay(1000);
    }

  }
  LDateTime.getRtc(&rtc);
  if ((rtc - lrtc) >= per) {
     senddata(temperature_sensor_value, light_sensor_value);
    lrtc = rtc;
  }
  //Check for TCP socket command from MCS Server
  String tcpcmd="";
  while (c.available())
   {
      int v = c.read();
      if (v != -1)
      {
        Serial.print((char)v);
        tcpcmd += (char)v;
        if (tcpcmd.indexOf("led on") >= 0) {
          Serial.print("Received actuator command: "); Serial.println(tcpcmd);
          Serial.println("Switching LED ON...");
          led_on();
          tcpcmd="";
        }else if(tcpcmd.indexOf("led off") >= 0) {
          Serial.print("Received actuator command: "); Serial.println(tcpcmd);
          Serial.println("Switching LED OFF...");
          led_off();
          tcpcmd="";
        }
      }
   }
  //Check for hearbeat interval
  LDateTime.getRtc(&rtc2);
  if ((rtc2 - lrtc2) >= per1) {
    heartBeat();
    lrtc2 = rtc2;
  }
}

<commit_msg>Documented the HTTP and TCP code<commit_after>//  Based on https://github.com/MediaTek-Labs/WeatherStation1.0/blob/master/WeatherStation_1.0.ino

//  Update these 2 lines with your group ID and device ID.
#define GROUP "1"
#define DEVICE "1"

//  This is the REST service for transmitting the sensor values.
#define SITE_URL "AzureIoTService.cloudapp.net"
#define SITE_PORT 80

//  This is a long-lasting TCP socket connection to receive actuation commands from the cloud.
#define SERVER_IP "AzureIoTService.cloudapp.net"
#define SERVER_PORT 2012
/*
Make sure you have a file named password.h containing the lines:
#define WIFI_SSID "yourwifissid"
#define WIFI_KEY "yourwifipassword"
*/
#include <Arduino.h>
#include "password.h"
#include "send_data.h"
#include "led.h"
#include <LTask.h>
#include <LWiFi.h>
#include <LWiFiClient.h>
#include <Wire.h>
#include <math.h>
#include <LDateTime.h>
#include <HttpClient.h>
#include <LFlash.h>

// ================================================
// Define
#undef _DBG_
#define WIFI_AUTH LWIFI_WPA  // choose from LWIFI_OPEN, LWIFI_WPA, or LWIFI_WEP.
#define per 5 // time interval in seconds to upload sensor data to MCS
#define per1 50 // time interval in seconds to initiate TCP heart beat
#define Drv LFlash

// ================================================
// Global variable

//  For networking.
char ssid[] = WIFI_SSID;
char key[] = WIFI_KEY;
char ip[] = SERVER_IP;
int portnum = SERVER_PORT;
LWiFiClient c;
LWiFiClient c2;
HttpClient http(c2);
char connection_info[21]="                    ";

//  This is the Hello message ("HELLO 1 2"), used by the LinkIt ONE to specify the group ID and device ID upon startup.
//  The Hello message is also sent periodically by the LinkIt ONE to keep the TCP connection alive with the server.
String hello;

//  For real-time clock.
unsigned int rtc;
unsigned int lrtc;
unsigned int lrtc2;
unsigned int rtc2;
unsigned int rtc1;
unsigned int lrtc1;
int val = 0;
int state = 0;
int i = 0;

void fatal_error(const char* str)
{
  Serial.println(str);
  while(1)
    delay(100);
}

// ==============================================================
// TCP Socket server connection functions

void connectTCP(){
  //  Connect to the TCP server to establish a channel for the cloud to send actuation commands to the LinkIt ONE.
  c.stop();
  Serial.println("Connecting to TCP socket for receiving actuation commands...");
  Serial.print("IP: "); Serial.println(ip);
  Serial.print("Port: "); Serial.println(portnum);
  while (0 == c.connect(ip, portnum))
  {
    Serial.println("Re-connecting to TCP socket...");
    delay(1000);
  }
  //  Tell the server our group ID and device ID.
  Serial.println("Connected to TCP socket for receiving actuation commands");
  hello = "HELLO " + String(GROUP) + " " + String(DEVICE);
  Serial.print(">>> "); Serial.println(hello);
  c.println(hello);
  Serial.println("Waiting for TCP response...");
} //connectTCP

void heartBeat(){
  //  The Hello message is sent periodically by the LinkIt ONE to keep the TCP connection alive with the server.
  Serial.println("Sending TCP heartBeat...");
  Serial.print(">>> "); Serial.println(hello);
  c.println(hello);
} //heartBeat

void senddata(float temperature_sensor_value, int light_sensor_value) {
  //  Send the sensor values to the cloud.
  //  TODO: Send a dictionary of <key, value> strings instead.
  Serial.println("Sending sensor data to cloud...");
  char buffer1[5];
  sprintf(buffer1, "%.2f", temperature_sensor_value);

  //  Open a connection to the HTTP port (usually port 80).
  LWiFiClient c2;
  unsigned long t1 = millis();
  Serial.print("Connecting to "); Serial.print(SITE_URL); Serial.print(" port "); Serial.print(SITE_PORT); Serial.println("...");
  while (0 == c2.connect(SITE_URL, SITE_PORT))
  {
    Serial.println("Reconnecting to cloud REST server...");
    delay(1000);
  }
  delay(500);

  //  Send a HTTP POST command to transmit the sensor values.
  //  TODO: May need to do URL encoding of the sensor values if they contain special characters.
  Serial.println("Sending POST request to cloud REST server...");
  String url = "POST /RecordSensorData.aspx?Group=" + String(GROUP) + "&Device=" + String(DEVICE) +
    "&Temperature=" + String(buffer1) + "&LightLevel=" + String(light_sensor_value) + " HTTP/1.1";
  Serial.print(">>> "); Serial.println(url);
  c2.println(url);
  //  Send the other HTTP request headers, according to the HTTP specifications.
  c2.print("Host: ");
  c2.print(SITE_URL); c2.print(":"); c2.println(SITE_PORT);
  c2.print("Content-Length: ");
  c2.println(0);
  c2.println("Content-Type: text/csv");
  c2.println("Connection: close");
  c2.println();

  String dataget = "";
  Serial.println("Waiting for HTTP response...");

  int errorcount = 0;
  while (!c2.available())
  {
    Serial.println("Waiting for HTTP response...");
    errorcount += 1;
    if (errorcount > 10) {
      c2.stop();
      return;
    }
    delay(100);
  }
  while (c2)
  {
    int v = c2.read();
    if (v != -1)
    {
      Serial.print(char(v));

      delay(1);
    }
    else
    {
      Serial.println("No more content, disconnecting...");
      c2.stop();
    }
  }
  Serial.println("\r\nSensor data sent to cloud");
  delay(300);
  unsigned long t2 = millis();
}

// ==============================================================
// Main program
void send_data_setup() {
  Wire.begin();
  LTask.begin();
  LWiFi.begin();
  //while(!Serial) delay(1000); //mark this demo as standalone
  Serial.println("Connecting to WiFi access point...");
  Serial.println(ssid);
  Serial.println(key);
  while (0 == LWiFi.connect(ssid, LWiFiLoginInfo(WIFI_AUTH, key))){
    Serial.print(".");
    delay(1000);
  }
  Serial.println("WiFi Connected");
  delay(100);
  Serial.println("LED is set to LOW");
  LDateTime.getRtc(&lrtc);
  LDateTime.getRtc(&lrtc2);
  while (!c2.connect(SITE_URL, SITE_PORT)){
    Serial.println("Reconnecting to cloud REST server...");
    delay(1000);
  }
  delay(100);
  connectTCP();
}

void send_data_loop(float temperature_sensor_value, int light_sensor_value) {
  if (LWiFi.status() == LWIFI_STATUS_DISCONNECTED) {
    Serial.println("Disconnected from WiFi");
    while (0 == LWiFi.connect(ssid, LWiFiLoginInfo(WIFI_AUTH, key))){
      Serial.println("Connecting to WiFi...");
      delay(1000);
    }

  }
  LDateTime.getRtc(&rtc);
  if ((rtc - lrtc) >= per) {
     senddata(temperature_sensor_value, light_sensor_value);
    lrtc = rtc;
  }
  //Check for TCP socket command from MCS Server
  String tcpcmd="";
  while (c.available())
   {
      int v = c.read();
      if (v != -1)
      {
        Serial.print((char)v);
        tcpcmd += (char)v;
        if (tcpcmd.indexOf("led on") >= 0) {
          Serial.print("Received actuator command: "); Serial.println(tcpcmd);
          Serial.println("Switching LED ON...");
          led_on();
          tcpcmd="";
        }else if(tcpcmd.indexOf("led off") >= 0) {
          Serial.print("Received actuator command: "); Serial.println(tcpcmd);
          Serial.println("Switching LED OFF...");
          led_off();
          tcpcmd="";
        }
      }
   }
  //Check for hearbeat interval
  LDateTime.getRtc(&rtc2);
  if ((rtc2 - lrtc2) >= per1) {
    heartBeat();
    lrtc2 = rtc2;
  }
}

<|endoftext|>


<commit_before><commit_msg>Go West `Shader` & Go West `ComputeTask`.<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *   Copyright (C) 2011-2013 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Teapotnet.                                     *
 *                                                                       *
 *   Teapotnet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Teapotnet 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Teapotnet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tpn/html.h"
#include "tpn/exception.h"
#include "tpn/request.h"
#include "tpn/user.h"
#include "tpn/mime.h"
#include "tpn/config.h"

namespace tpn
{

String Html::escape(const String &str)
{
	String result;
	for(int i=0; i<str.size(); ++i)
	{
		char chr = str[i];
		switch(chr)
		{
		case '"': 	result << """;	break;
		case '\'': 	result << "'";	break;
		case '<': 	result << "<";	break;
		case '>': 	result << ">";	break;
		case '&': 	result << "&";	break;
		default:	result+=chr;		break;
		}
	}
	return result;
}

Html::Html(Stream *stream) :
	mStream(stream),
	mBlank(false),
	mAdmin(false)
{

}

Html::Html(Socket *sock) :
	mStream(sock),
	mBlank(false),
	mAdmin(sock->getRemoteAddress().isLocal())
{

}

Html::~Html(void)
{

}

void Html::header(const String &title, bool blank, const String &redirect)
{
	mBlank = blank;

	*mStream<<"<!DOCTYPE html>\n";
	*mStream<<"\n";
	*mStream<<"\n";
	if(blank) *mStream<<"<title>"<<title<<"</title>\n";
	else if(title.empty()) *mStream<<"<title>"<<APPNAME<<"</title>\n";
	else *mStream<<"<title>"<<title<<" - "<<APPNAME<<"</title>\n";
	*mStream<<"<meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\">\n";
	*mStream<<"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">\n";
	*mStream<<"<link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\">\n";
	*mStream<<"<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/favicon.ico\">\n";
	if(!redirect.empty()) *mStream<<"<meta http-equiv=\"refresh\" content=\"5;URL='"+redirect+"'\">\n";
	*mStream<<"<meta http-equiv=\"refresh\" content=\"0;url=/noscript.html\">\n";
	*mStream<<"\n";
	*mStream<<"\n";
	*mStream<<"\n";
	*mStream<<"\n";

	javascript("var deviceAgent = navigator.userAgent.toLowerCase();\n\
		if(deviceAgent.indexOf('android') >= 0 || deviceAgent.indexOf('iPhone') >= 0 || deviceAgent.indexOf('iPad') >= 0)\n\
			$('head').append('<link rel=\"stylesheet\" type=\"text/css\" href=\"/touchscreen.css\">');");

	*mStream<<"\n";
	*mStream<<"\n";

	open("div","page");

	if(!mBlank)
	{
		open("div","header");
		openLink("/"); image("/logo.png", APPNAME, "logo"); closeLink();
		open("div","title");
		if(title.empty()) text(APPNAME);
		else text(title);
		close("div");
		close("div");
		open("div","content");
	}
}

void Html::footer(void)
{
	if(!mBlank)
	{
		close("div");
		open("div", "footer");
		close("div");
	}

	close("div");

	*mStream<<"\n";
	*mStream<<"\n";
}

void Html::raw(const String &str)
{
	mStream->write(str);
}

void Html::text(const String &str)
{
	mStream->write(escape(str));
}

void Html::object(const Serializable &s)
{
	// TODO
	open("span");
	mStream->write(escape(s.toString()));
	close("span");
}

void Html::open(const String &type, String id)
{
	assert(!type.empty());

	if(!id.empty() && id[0] == '#') id.ignore();
	String cl = id.cut('.');

	*mStream<<"<"<<type;
	if(!id.empty()) *mStream<<" id=\""<<id<<"\"";
	if(!cl.empty()) *mStream<<" class=\""<<cl<<"\"";
	*mStream<<">";
}

void Html::close(const String &type)
{
	assert(!type.empty());
	*mStream<<"</"<<type<<">\n";
}

void Html::openLink(const String &url, String id, bool newTab)
{
	if(!id.empty() && id[0] == '#') id.ignore();
	String cl = id.cut('.');

	*mStream<<"<a href=\""<<url<<"\"";
	if(!id.empty()) *mStream<<" id=\""<<id<<"\"";
	if(!cl.empty()) *mStream<<" class=\""<<cl<<"\"";
	if(newTab) *mStream<<" target=\"_blank\"";
	*mStream<<">";
}

void Html::closeLink(void)
{
	*mStream<<"";
}

void Html::span(const String &txt, String id)
{
 	open("span",id);
	text(txt);
	close("span");
}

void Html::div(const String &txt, String id)
{
	open("div",id);
	text(txt);
	close("div");
}

void Html::link(	const String &url,
			const String &txt,
			String id,
			bool newTab)
{
	openLink(url, id, newTab);
	text(txt);
	closeLink();
}

void Html::image(	const String &url,
			const String &alt,
			String id)
{
	if(!id.empty() && id[0] == '#') id.ignore();
  	String cl = id.cut('.');

	*mStream<<"<img src=\""<<url<<"\"";
	if(!alt.empty()) *mStream<<" alt=\""<<alt<<"\"";
	if(!id.empty())  *mStream<<" id=\""<<id<<"\"";
	if(!cl.empty())  *mStream<<" class=\""<<cl<<"\"";
	*mStream<<"/>";
}

void Html::javascript(const String &code)
{
	*mStream<<"\n";
}

void Html::space(void)
{
	*mStream<<' ';
}

void Html::br(void)
{
	*mStream<<"
\n";
}

void Html::openForm(	const String &action,
			const String &method,
		     	const String &name,
			bool multipart)
{
	String enctype;
	if(multipart) enctype = "multipart/form-data";
	else enctype = "application/x-www-form-urlencoded";

	*mStream<<"<form";
	if(!name.empty()) *mStream<<" name=\""<<name<<"\"";
	*mStream<<" action=\""<<escape(action)<<"\" method=\""<<method<<"\"";
	if(method == "post") *mStream<<" enctype=\""<<enctype<<"\"";
	*mStream<<">\n";
}

void Html::closeForm(void)
{
	*mStream<<"</form>\n";
}

void Html::openFieldset(const String &legend)
{
	open("fieldset");
	open("legend");
	text(legend);
	close("legend");
}

void Html::closeFieldset(void)
{
  	close("fieldset");
}

void Html::label(const String &name, const String &label)
{
	*mStream<<"<label";
	if(!name.empty()) *mStream<<" for=\""<<name<<"\"";
	*mStream<<">"<<label<<"\n";
}

void Html::input(const String &type, const String &name, const String &value, bool noautocomplete)
{
	String t(type);
	if(t == "button") t = "submit";
 	*mStream<<"<input type=\""<<t<<"\" class=\""<<name<<"\" name=\""<<name<<"\" value=\""<<value<<"\"";
 	if(noautocomplete) *mStream<<" autocomplete=\"off\"";
 	*mStream<<">\n";
}

void Html::checkbox(const String &name, const String &value, bool checked)
{
 	*mStream<<"<span class=\""<<name<<"\"><input type=\"checkbox\" value=\"1\" name=\""<<name<<"\" "<<(checked ? "checked" : "")<<">";
 	text(value);
 	*mStream<<"\n";
}

void Html::textarea(const String &name, const String &value)
{
	*mStream<<"<textarea class=\""<<name<<"\" name=\""<<name<<"\">";
	text(value);
	*mStream<<"</textarea>\n";
}

void Html::select(const String &name, const StringMap &options, const String &def)
{
	*mStream<<"<select name=\""<<name<<"\">\n";
	for(StringMap::const_iterator it=options.begin(); it!=options.end(); ++it)
	{
		 *mStream<<"<option ";
		 if(def == it->first) *mStream<<"selected ";
		 *mStream<<"value=\""<<it->first<<"\">";
		 text(it->second);
		 *mStream<<"</option>\n";
	}
	*mStream<<"</select>\n";
}

void Html::button(const String &name, String text)
{
  	if(text.empty()) input("submit", name, name);
	else input("submit", name, text);
}

void Html::file(const String &name, String text)
{
	if(text.empty()) text = name;
	String id = String("input_file_") + name;
	*mStream<<"<input type=\"file\" id=\""<<id<<"\" class=\""<<name<<"\" name=\""<<name<<"\" size=\"30\">\n";
	javascript("$('#"+id+"').css('visibility', 'hidden').css('display', 'inline').css('width', '0px').css('margin', '0px').css('padding', '0px');\n\
		$('#"+id+"').after('"+escape(text)+"');");
}

Stream *Html::stream(void)
{
	return mStream;
}

}
<commit_msg>Normal behaviour for back links<commit_after>/*************************************************************************
 *   Copyright (C) 2011-2013 by Paul-Louis Ageneau                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Teapotnet.                                     *
 *                                                                       *
 *   Teapotnet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Teapotnet 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Teapotnet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tpn/html.h"
#include "tpn/exception.h"
#include "tpn/request.h"
#include "tpn/user.h"
#include "tpn/mime.h"
#include "tpn/config.h"

namespace tpn
{

String Html::escape(const String &str)
{
	String result;
	for(int i=0; i<str.size(); ++i)
	{
		char chr = str[i];
		switch(chr)
		{
		case '"': 	result << """;	break;
		case '\'': 	result << "'";	break;
		case '<': 	result << "<";	break;
		case '>': 	result << ">";	break;
		case '&': 	result << "&";	break;
		default:	result+=chr;		break;
		}
	}
	return result;
}

Html::Html(Stream *stream) :
	mStream(stream),
	mBlank(false),
	mAdmin(false)
{

}

Html::Html(Socket *sock) :
	mStream(sock),
	mBlank(false),
	mAdmin(sock->getRemoteAddress().isLocal())
{

}

Html::~Html(void)
{

}

void Html::header(const String &title, bool blank, const String &redirect)
{
	mBlank = blank;

	*mStream<<"<!DOCTYPE html>\n";
	*mStream<<"\n";
	*mStream<<"\n";
	if(blank) *mStream<<"<title>"<<title<<"</title>\n";
	else if(title.empty()) *mStream<<"<title>"<<APPNAME<<"</title>\n";
	else *mStream<<"<title>"<<title<<" - "<<APPNAME<<"</title>\n";
	*mStream<<"<meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\">\n";
	*mStream<<"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">\n";
	*mStream<<"<link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\">\n";
	*mStream<<"<link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/favicon.ico\">\n";
	if(!redirect.empty()) *mStream<<"<meta http-equiv=\"refresh\" content=\"5;URL='"+redirect+"'\">\n";
	*mStream<<"<meta http-equiv=\"refresh\" content=\"0;url=/noscript.html\">\n";
	*mStream<<"\n";
	*mStream<<"\n";
	*mStream<<"\n";
	*mStream<<"\n";

	javascript("var deviceAgent = navigator.userAgent.toLowerCase();\n\
		if(deviceAgent.indexOf('android') >= 0 || deviceAgent.indexOf('iPhone') >= 0 || deviceAgent.indexOf('iPad') >= 0)\n\
			$('head').append('<link rel=\"stylesheet\" type=\"text/css\" href=\"/touchscreen.css\">');");

	*mStream<<"\n";
	*mStream<<"\n";

	open("div","page");

	if(!mBlank)
	{
		open("div","header");
		openLink("/","#backlink"); image("/logo.png", APPNAME, "logo"); closeLink();
		open("div","title");
		if(title.empty()) text(APPNAME);
		else text(title);
		close("div");
		close("div");
		javascript("$('#backlink').click(function(){ window.location.href = getBasePath(1); return false;});");
		open("div","content");
	}
}

void Html::footer(void)
{
	if(!mBlank)
	{
		close("div");
		open("div", "footer");
		close("div");
	}

	close("div");

	*mStream<<"\n";
	*mStream<<"\n";
}

void Html::raw(const String &str)
{
	mStream->write(str);
}

void Html::text(const String &str)
{
	mStream->write(escape(str));
}

void Html::object(const Serializable &s)
{
	// TODO
	open("span");
	mStream->write(escape(s.toString()));
	close("span");
}

void Html::open(const String &type, String id)
{
	assert(!type.empty());

	if(!id.empty() && id[0] == '#') id.ignore();
	String cl = id.cut('.');

	*mStream<<"<"<<type;
	if(!id.empty()) *mStream<<" id=\""<<id<<"\"";
	if(!cl.empty()) *mStream<<" class=\""<<cl<<"\"";
	*mStream<<">";
}

void Html::close(const String &type)
{
	assert(!type.empty());
	*mStream<<"</"<<type<<">\n";
}

void Html::openLink(const String &url, String id, bool newTab)
{
	if(!id.empty() && id[0] == '#') id.ignore();
	String cl = id.cut('.');

	*mStream<<"<a href=\""<<url<<"\"";
	if(!id.empty()) *mStream<<" id=\""<<id<<"\"";
	if(!cl.empty()) *mStream<<" class=\""<<cl<<"\"";
	if(newTab) *mStream<<" target=\"_blank\"";
	*mStream<<">";
}

void Html::closeLink(void)
{
	*mStream<<"";
}

void Html::span(const String &txt, String id)
{
 	open("span",id);
	text(txt);
	close("span");
}

void Html::div(const String &txt, String id)
{
	open("div",id);
	text(txt);
	close("div");
}

void Html::link(	const String &url,
			const String &txt,
			String id,
			bool newTab)
{
	openLink(url, id, newTab);
	text(txt);
	closeLink();
}

void Html::image(	const String &url,
			const String &alt,
			String id)
{
	if(!id.empty() && id[0] == '#') id.ignore();
  	String cl = id.cut('.');

	*mStream<<"<img src=\""<<url<<"\"";
	if(!alt.empty()) *mStream<<" alt=\""<<alt<<"\"";
	if(!id.empty())  *mStream<<" id=\""<<id<<"\"";
	if(!cl.empty())  *mStream<<" class=\""<<cl<<"\"";
	*mStream<<"/>";
}

void Html::javascript(const String &code)
{
	*mStream<<"\n";
}

void Html::space(void)
{
	*mStream<<' ';
}

void Html::br(void)
{
	*mStream<<"
\n";
}

void Html::openForm(	const String &action,
			const String &method,
		     	const String &name,
			bool multipart)
{
	String enctype;
	if(multipart) enctype = "multipart/form-data";
	else enctype = "application/x-www-form-urlencoded";

	*mStream<<"<form";
	if(!name.empty()) *mStream<<" name=\""<<name<<"\"";
	*mStream<<" action=\""<<escape(action)<<"\" method=\""<<method<<"\"";
	if(method == "post") *mStream<<" enctype=\""<<enctype<<"\"";
	*mStream<<">\n";
}

void Html::closeForm(void)
{
	*mStream<<"</form>\n";
}

void Html::openFieldset(const String &legend)
{
	open("fieldset");
	open("legend");
	text(legend);
	close("legend");
}

void Html::closeFieldset(void)
{
  	close("fieldset");
}

void Html::label(const String &name, const String &label)
{
	*mStream<<"<label";
	if(!name.empty()) *mStream<<" for=\""<<name<<"\"";
	*mStream<<">"<<label<<"\n";
}

void Html::input(const String &type, const String &name, const String &value, bool noautocomplete)
{
	String t(type);
	if(t == "button") t = "submit";
 	*mStream<<"<input type=\""<<t<<"\" class=\""<<name<<"\" name=\""<<name<<"\" value=\""<<value<<"\"";
 	if(noautocomplete) *mStream<<" autocomplete=\"off\"";
 	*mStream<<">\n";
}

void Html::checkbox(const String &name, const String &value, bool checked)
{
 	*mStream<<"<span class=\""<<name<<"\"><input type=\"checkbox\" value=\"1\" name=\""<<name<<"\" "<<(checked ? "checked" : "")<<">";
 	text(value);
 	*mStream<<"\n";
}

void Html::textarea(const String &name, const String &value)
{
	*mStream<<"<textarea class=\""<<name<<"\" name=\""<<name<<"\">";
	text(value);
	*mStream<<"</textarea>\n";
}

void Html::select(const String &name, const StringMap &options, const String &def)
{
	*mStream<<"<select name=\""<<name<<"\">\n";
	for(StringMap::const_iterator it=options.begin(); it!=options.end(); ++it)
	{
		 *mStream<<"<option ";
		 if(def == it->first) *mStream<<"selected ";
		 *mStream<<"value=\""<<it->first<<"\">";
		 text(it->second);
		 *mStream<<"</option>\n";
	}
	*mStream<<"</select>\n";
}

void Html::button(const String &name, String text)
{
  	if(text.empty()) input("submit", name, name);
	else input("submit", name, text);
}

void Html::file(const String &name, String text)
{
	if(text.empty()) text = name;
	String id = String("input_file_") + name;
	*mStream<<"<input type=\"file\" id=\""<<id<<"\" class=\""<<name<<"\" name=\""<<name<<"\" size=\"30\">\n";
	javascript("$('#"+id+"').css('visibility', 'hidden').css('display', 'inline').css('width', '0px').css('margin', '0px').css('padding', '0px');\n\
		$('#"+id+"').after('"+escape(text)+"');");
}

Stream *Html::stream(void)
{
	return mStream;
}

}
<|endoftext|>