<commit_before>/*************************************************************************
 *
 *  $RCSfile: fuhhconv.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 13:51:33 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include <fuhhconv.hxx>
#include "drawdoc.hxx"
#include "Outliner.hxx"
#include "DrawViewShell.hxx"
#include "OutlineViewShell.hxx"

#ifndef SD_VIEW_SHELL_BASE_HXX
#include "ViewShellBase.hxx"
#endif

#include "sdresid.hxx"
#include "strings.hrc"

class SfxRequest;

namespace sd {

class ViewShell;

TYPEINIT1( FuHangulHanjaConversion, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuHangulHanjaConversion::FuHangulHanjaConversion (
    ViewShell* pViewSh,
    ::sd::Window* pWin,
    ::sd::View* pView,
    SdDrawDocument* pDocument,
    SfxRequest& rReq )
       : FuPoor(pViewSh, pWin, pView, pDocument, rReq),
    pSdOutliner(NULL),
    bOwnOutliner(FALSE)
{
    if ( pViewShell->ISA(DrawViewShell) )
    {
        bOwnOutliner = TRUE;
        pSdOutliner = new Outliner( pDoc, OUTLINERMODE_TEXTOBJECT );
    }
    else if ( pViewShell->ISA(OutlineViewShell) )
    {
        bOwnOutliner = FALSE;
        pSdOutliner = pDoc->GetOutliner();
    }

    if (pSdOutliner)
       pSdOutliner->PrepareSpelling();
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

FuHangulHanjaConversion::~FuHangulHanjaConversion()
{
    if (pSdOutliner)
        pSdOutliner->EndConversion();

    if (bOwnOutliner)
        delete pSdOutliner;
}

/*************************************************************************
|*
|* Suchen&Ersetzen
|*
\************************************************************************/

void FuHangulHanjaConversion::StartConversion( INT16 nLanguage )
{

    String aString( SdResId(STR_UNDO_HANGULHANJACONVERSION) );
    pView->BegUndo( aString );

    ViewShellBase* pBase = PTR_CAST(ViewShellBase, SfxViewShell::Current());
    if (pBase != NULL)
        pViewShell = pBase->GetMainViewShell();

    if( pViewShell )
    {
        if ( pSdOutliner && pViewShell->ISA(DrawViewShell) && !bOwnOutliner )
        {
            pSdOutliner->EndConversion();

            bOwnOutliner = TRUE;
            pSdOutliner = new Outliner( pDoc, OUTLINERMODE_TEXTOBJECT );
            pSdOutliner->BeginConversion();
        }
        else if ( pSdOutliner && pViewShell->ISA(OutlineViewShell) && bOwnOutliner )
        {
            pSdOutliner->EndConversion();
            delete pSdOutliner;

            bOwnOutliner = FALSE;
            pSdOutliner = pDoc->GetOutliner();
            pSdOutliner->BeginConversion();
        }

        if (pSdOutliner)
            pSdOutliner->StartTextConversion(nLanguage);
    }

    pView->EndUndo();
}

} // end of namespace
<commit_msg>INTEGRATION: CWS os34 (1.2.18); FILE MERGED 2004/08/06 18:18:29 tl 1.2.18.3: RESYNC: (1.2-1.3); FILE MERGED 2004/08/04 13:51:28 tl 1.2.18.2: #i30301# simplified/traditional Chinese conversion 2004/07/27 13:58:14 tl 1.2.18.1: #i30303# preparational changes for simplified/traditional Chinese conversion<commit_after>/*************************************************************************
 *
 *  $RCSfile: fuhhconv.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-09-17 13:24: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): _______________________________________
 *
 *
 ************************************************************************/

#include <fuhhconv.hxx>
#include "drawdoc.hxx"
#include "Outliner.hxx"
#include "DrawViewShell.hxx"
#include "OutlineViewShell.hxx"

#ifndef SD_VIEW_SHELL_BASE_HXX
#include "ViewShellBase.hxx"
#endif

#include "sdresid.hxx"
#include "strings.hrc"

class SfxRequest;

namespace sd {

class ViewShell;

TYPEINIT1( FuHangulHanjaConversion, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuHangulHanjaConversion::FuHangulHanjaConversion (
    ViewShell* pViewSh,
    ::sd::Window* pWin,
    ::sd::View* pView,
    SdDrawDocument* pDocument,
    SfxRequest& rReq )
       : FuPoor(pViewSh, pWin, pView, pDocument, rReq),
    pSdOutliner(NULL),
    bOwnOutliner(FALSE)
{
    if ( pViewShell->ISA(DrawViewShell) )
    {
        bOwnOutliner = TRUE;
        pSdOutliner = new Outliner( pDoc, OUTLINERMODE_TEXTOBJECT );
    }
    else if ( pViewShell->ISA(OutlineViewShell) )
    {
        bOwnOutliner = FALSE;
        pSdOutliner = pDoc->GetOutliner();
    }

    if (pSdOutliner)
       pSdOutliner->PrepareSpelling();
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

FuHangulHanjaConversion::~FuHangulHanjaConversion()
{
    if (pSdOutliner)
        pSdOutliner->EndConversion();

    if (bOwnOutliner)
        delete pSdOutliner;
}

/*************************************************************************
|*
|* Suchen&Ersetzen
|*
\************************************************************************/

void FuHangulHanjaConversion::StartConversion( INT16 nSourceLanguage, INT16 nTargetLanguage,
        const Font *pTargetFont, INT32 nOptions, BOOL bIsInteractive )
{

    String aString( SdResId(STR_UNDO_HANGULHANJACONVERSION) );
    pView->BegUndo( aString );

    ViewShellBase* pBase = PTR_CAST(ViewShellBase, SfxViewShell::Current());
    if (pBase != NULL)
        pViewShell = pBase->GetMainViewShell();

    if( pViewShell )
    {
        if ( pSdOutliner && pViewShell->ISA(DrawViewShell) && !bOwnOutliner )
        {
            pSdOutliner->EndConversion();

            bOwnOutliner = TRUE;
            pSdOutliner = new Outliner( pDoc, OUTLINERMODE_TEXTOBJECT );
            pSdOutliner->BeginConversion();
        }
        else if ( pSdOutliner && pViewShell->ISA(OutlineViewShell) && bOwnOutliner )
        {
            pSdOutliner->EndConversion();
            delete pSdOutliner;

            bOwnOutliner = FALSE;
            pSdOutliner = pDoc->GetOutliner();
            pSdOutliner->BeginConversion();
        }

        if (pSdOutliner)
            pSdOutliner->StartConversion(nSourceLanguage, nTargetLanguage, pTargetFont, nOptions, bIsInteractive );
    }

    pView->EndUndo();
}

} // end of namespace
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

//
// vie_autotest_image_process.cc
//

// Settings
#include "vie_autotest_defines.h"
#include "vie_autotest.h"
#include "engine_configurations.h"

#include "tb_interfaces.h"
#include "tb_video_channel.h"
#include "tb_capture_device.h"

class MyEffectFilter: public webrtc::ViEEffectFilter
{
public:
    MyEffectFilter() {}

    ~MyEffectFilter() {}

    virtual int Transform(int size, unsigned char* frameBuffer,
                          unsigned int timeStamp90KHz, unsigned int width,
                          unsigned int height)
    {
        // Black and white
        memset(frameBuffer + (2 * size) / 3, 0x7f, size / 3);
        return 0;
    }
};

void ViEAutoTest::ViEImageProcessStandardTest()
{
    //***************************************************************
    //	Begin create/initialize WebRTC Video Engine for testing
    //***************************************************************
    int rtpPort = 6000;
    // Create VIE
    TbInterfaces ViE("ViEImageProcessAPITest");
    // Create a video channel
    TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
    // Create a capture device
    TbCaptureDevice tbCapture(ViE);

    tbCapture.ConnectTo(tbChannel.videoChannel);
    tbChannel.StartReceive(rtpPort);
    tbChannel.StartSend(rtpPort);

    MyEffectFilter effectFilter;

    RenderCaptureDeviceAndOutputStream(&ViE, &tbChannel, &tbCapture);

    ViETest::Log("Capture device is renderered in Window 1");
    ViETest::Log("Remote stream is renderered in Window 2");
    AutoTestSleep(KAutoTestSleepTimeMs);

    //***************************************************************
    //	Engine ready. Begin testing class
    //***************************************************************

    EXPECT_EQ(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbCapture.captureId, effectFilter));

    ViETest::Log("Black and white filter registered for capture device, "
                 "affects both windows");
    AutoTestSleep(KAutoTestSleepTimeMs);

    EXPECT_EQ(0, ViE.image_process->DeregisterCaptureEffectFilter(
        tbCapture.captureId));

    EXPECT_EQ(0, ViE.image_process->RegisterRenderEffectFilter(
        tbChannel.videoChannel, effectFilter));

    ViETest::Log("Remove capture effect filter, adding filter for incoming "
                 "stream");
    ViETest::Log("Only Window 2 should be black and white");
    AutoTestSleep(KAutoTestSleepTimeMs);

    EXPECT_EQ(0, ViE.render->StopRender(tbCapture.captureId));
    EXPECT_EQ(0, ViE.render->RemoveRenderer(tbCapture.captureId));

    int rtpPort2 = rtpPort + 100;
    // Create a video channel
    TbVideoChannel tbChannel2(ViE, webrtc::kVideoCodecVP8);

    tbCapture.ConnectTo(tbChannel2.videoChannel);
    tbChannel2.StartReceive(rtpPort2);
    tbChannel2.StartSend(rtpPort2);

    EXPECT_EQ(0, ViE.render->AddRenderer(
        tbChannel2.videoChannel, _window1, 1, 0.0, 0.0, 1.0, 1.0));
    EXPECT_EQ(0, ViE.render->StartRender(tbChannel2.videoChannel));
    EXPECT_EQ(0, ViE.image_process->DeregisterRenderEffectFilter(
        tbChannel.videoChannel));

    ViETest::Log("Local renderer removed, added new channel and rendering in "
                 "Window1.");

    EXPECT_EQ(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbCapture.captureId, effectFilter));

    ViETest::Log("Black and white filter registered for capture device, "
                 "affects both windows");
    AutoTestSleep(KAutoTestSleepTimeMs);

    EXPECT_EQ(0, ViE.image_process->DeregisterCaptureEffectFilter(
        tbCapture.captureId));

    EXPECT_EQ(0, ViE.image_process->RegisterSendEffectFilter(
        tbChannel.videoChannel, effectFilter));

    ViETest::Log("Capture filter removed.");
    ViETest::Log("Black and white filter registered for one channel, Window2 "
                 "should be black and white");
    AutoTestSleep(KAutoTestSleepTimeMs);

    EXPECT_EQ(0, ViE.image_process->DeregisterSendEffectFilter(
        tbChannel.videoChannel));

    //***************************************************************
    //	Testing finished. Tear down Video Engine
    //***************************************************************
}

void ViEAutoTest::ViEImageProcessExtendedTest()
{
    ViEImageProcessStandardTest();
}

void ViEAutoTest::ViEImageProcessAPITest()
{
    TbInterfaces ViE("ViEImageProcessAPITest");
    TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
    TbCaptureDevice tbCapture(ViE);

    tbCapture.ConnectTo(tbChannel.videoChannel);

    MyEffectFilter effectFilter;

    //
    // Capture effect filter
    //
    // Add effect filter
    EXPECT_EQ(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbCapture.captureId, effectFilter));
    // Add again -> error
    EXPECT_NE(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbCapture.captureId, effectFilter));
    EXPECT_EQ(0, ViE.image_process->DeregisterCaptureEffectFilter(
        tbCapture.captureId));

    // Double deregister
    EXPECT_NE(0, ViE.image_process->DeregisterCaptureEffectFilter(
        tbCapture.captureId));
    // Non-existing capture device
    EXPECT_NE(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbChannel.videoChannel, effectFilter));

    //
    // Render effect filter
    //
    EXPECT_EQ(0, ViE.image_process->RegisterRenderEffectFilter(
        tbChannel.videoChannel, effectFilter));
    EXPECT_NE(0, ViE.image_process->RegisterRenderEffectFilter(
        tbChannel.videoChannel, effectFilter));
    EXPECT_EQ(0, ViE.image_process->DeregisterRenderEffectFilter(
        tbChannel.videoChannel));
    EXPECT_NE(0, ViE.image_process->DeregisterRenderEffectFilter(
        tbChannel.videoChannel));

    // Non-existing channel id
    EXPECT_NE(0, ViE.image_process->RegisterRenderEffectFilter(
        tbCapture.captureId, effectFilter));

    //
    // Send effect filter
    //
    EXPECT_EQ(0, ViE.image_process->RegisterSendEffectFilter(
        tbChannel.videoChannel, effectFilter));
    EXPECT_NE(0, ViE.image_process->RegisterSendEffectFilter(
        tbChannel.videoChannel, effectFilter));
    EXPECT_EQ(0, ViE.image_process->DeregisterSendEffectFilter(
        tbChannel.videoChannel));
    EXPECT_NE(0, ViE.image_process->DeregisterSendEffectFilter(
        tbChannel.videoChannel));
    EXPECT_NE(0, ViE.image_process->RegisterSendEffectFilter(
        tbCapture.captureId, effectFilter));

    //
    // Denoising
    //
    EXPECT_EQ(0, ViE.image_process->EnableDenoising(tbCapture.captureId, true));
    // If the denoising is already enabled, it will just reuturn 0.
    EXPECT_EQ(0, ViE.image_process->EnableDenoising(tbCapture.captureId, true));
    EXPECT_EQ(0, ViE.image_process->EnableDenoising(
        tbCapture.captureId, false));
    // If the denoising is already disabled, it will just reuturn 0.
    EXPECT_EQ(0, ViE.image_process->EnableDenoising(
        tbCapture.captureId, false));
    EXPECT_NE(0, ViE.image_process->EnableDenoising(
        tbChannel.videoChannel, true));

    //
    // Deflickering
    //
    EXPECT_EQ(0, ViE.image_process->EnableDeflickering(
        tbCapture.captureId, true));
    EXPECT_NE(0, ViE.image_process->EnableDeflickering(
        tbCapture.captureId, true));
    EXPECT_EQ(0, ViE.image_process->EnableDeflickering(
        tbCapture.captureId, false));
    EXPECT_NE(0, ViE.image_process->EnableDeflickering(
        tbCapture.captureId, false));
    EXPECT_NE(0, ViE.image_process->EnableDeflickering(
        tbChannel.videoChannel, true));

    //
    // Color enhancement
    //
    EXPECT_EQ(0, ViE.image_process->EnableColorEnhancement(
        tbChannel.videoChannel, false));
    EXPECT_EQ(0, ViE.image_process->EnableColorEnhancement(
        tbChannel.videoChannel, true));
    EXPECT_NE(0, ViE.image_process->EnableColorEnhancement(
        tbChannel.videoChannel, true));
    EXPECT_EQ(0, ViE.image_process->EnableColorEnhancement(
        tbChannel.videoChannel, false));
    EXPECT_NE(0, ViE.image_process->EnableColorEnhancement(
        tbChannel.videoChannel, false));
    EXPECT_NE(0, ViE.image_process->EnableColorEnhancement(
        tbCapture.captureId, true));
}
<commit_msg>Fix color enhancement test. Review URL: https://webrtc-codereview.appspot.com/553007<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

//
// vie_autotest_image_process.cc
//

// Settings
#include "vie_autotest_defines.h"
#include "vie_autotest.h"
#include "engine_configurations.h"

#include "tb_interfaces.h"
#include "tb_video_channel.h"
#include "tb_capture_device.h"

class MyEffectFilter: public webrtc::ViEEffectFilter
{
public:
    MyEffectFilter() {}

    ~MyEffectFilter() {}

    virtual int Transform(int size, unsigned char* frameBuffer,
                          unsigned int timeStamp90KHz, unsigned int width,
                          unsigned int height)
    {
        // Black and white
        memset(frameBuffer + (2 * size) / 3, 0x7f, size / 3);
        return 0;
    }
};

void ViEAutoTest::ViEImageProcessStandardTest()
{
    //***************************************************************
    //	Begin create/initialize WebRTC Video Engine for testing
    //***************************************************************
    int rtpPort = 6000;
    // Create VIE
    TbInterfaces ViE("ViEImageProcessAPITest");
    // Create a video channel
    TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
    // Create a capture device
    TbCaptureDevice tbCapture(ViE);

    tbCapture.ConnectTo(tbChannel.videoChannel);
    tbChannel.StartReceive(rtpPort);
    tbChannel.StartSend(rtpPort);

    MyEffectFilter effectFilter;

    RenderCaptureDeviceAndOutputStream(&ViE, &tbChannel, &tbCapture);

    ViETest::Log("Capture device is renderered in Window 1");
    ViETest::Log("Remote stream is renderered in Window 2");
    AutoTestSleep(KAutoTestSleepTimeMs);

    //***************************************************************
    //	Engine ready. Begin testing class
    //***************************************************************

    EXPECT_EQ(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbCapture.captureId, effectFilter));

    ViETest::Log("Black and white filter registered for capture device, "
                 "affects both windows");
    AutoTestSleep(KAutoTestSleepTimeMs);

    EXPECT_EQ(0, ViE.image_process->DeregisterCaptureEffectFilter(
        tbCapture.captureId));

    EXPECT_EQ(0, ViE.image_process->RegisterRenderEffectFilter(
        tbChannel.videoChannel, effectFilter));

    ViETest::Log("Remove capture effect filter, adding filter for incoming "
                 "stream");
    ViETest::Log("Only Window 2 should be black and white");
    AutoTestSleep(KAutoTestSleepTimeMs);

    EXPECT_EQ(0, ViE.render->StopRender(tbCapture.captureId));
    EXPECT_EQ(0, ViE.render->RemoveRenderer(tbCapture.captureId));

    int rtpPort2 = rtpPort + 100;
    // Create a video channel
    TbVideoChannel tbChannel2(ViE, webrtc::kVideoCodecVP8);

    tbCapture.ConnectTo(tbChannel2.videoChannel);
    tbChannel2.StartReceive(rtpPort2);
    tbChannel2.StartSend(rtpPort2);

    EXPECT_EQ(0, ViE.render->AddRenderer(
        tbChannel2.videoChannel, _window1, 1, 0.0, 0.0, 1.0, 1.0));
    EXPECT_EQ(0, ViE.render->StartRender(tbChannel2.videoChannel));
    EXPECT_EQ(0, ViE.image_process->DeregisterRenderEffectFilter(
        tbChannel.videoChannel));

    ViETest::Log("Local renderer removed, added new channel and rendering in "
                 "Window1.");

    EXPECT_EQ(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbCapture.captureId, effectFilter));

    ViETest::Log("Black and white filter registered for capture device, "
                 "affects both windows");
    AutoTestSleep(KAutoTestSleepTimeMs);

    EXPECT_EQ(0, ViE.image_process->DeregisterCaptureEffectFilter(
        tbCapture.captureId));

    EXPECT_EQ(0, ViE.image_process->RegisterSendEffectFilter(
        tbChannel.videoChannel, effectFilter));

    ViETest::Log("Capture filter removed.");
    ViETest::Log("Black and white filter registered for one channel, Window2 "
                 "should be black and white");
    AutoTestSleep(KAutoTestSleepTimeMs);

    EXPECT_EQ(0, ViE.image_process->DeregisterSendEffectFilter(
        tbChannel.videoChannel));

    //***************************************************************
    //	Testing finished. Tear down Video Engine
    //***************************************************************
}

void ViEAutoTest::ViEImageProcessExtendedTest()
{
    ViEImageProcessStandardTest();
}

void ViEAutoTest::ViEImageProcessAPITest()
{
    TbInterfaces ViE("ViEImageProcessAPITest");
    TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
    TbCaptureDevice tbCapture(ViE);

    tbCapture.ConnectTo(tbChannel.videoChannel);

    MyEffectFilter effectFilter;

    //
    // Capture effect filter
    //
    // Add effect filter
    EXPECT_EQ(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbCapture.captureId, effectFilter));
    // Add again -> error
    EXPECT_NE(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbCapture.captureId, effectFilter));
    EXPECT_EQ(0, ViE.image_process->DeregisterCaptureEffectFilter(
        tbCapture.captureId));

    // Double deregister
    EXPECT_NE(0, ViE.image_process->DeregisterCaptureEffectFilter(
        tbCapture.captureId));
    // Non-existing capture device
    EXPECT_NE(0, ViE.image_process->RegisterCaptureEffectFilter(
        tbChannel.videoChannel, effectFilter));

    //
    // Render effect filter
    //
    EXPECT_EQ(0, ViE.image_process->RegisterRenderEffectFilter(
        tbChannel.videoChannel, effectFilter));
    EXPECT_NE(0, ViE.image_process->RegisterRenderEffectFilter(
        tbChannel.videoChannel, effectFilter));
    EXPECT_EQ(0, ViE.image_process->DeregisterRenderEffectFilter(
        tbChannel.videoChannel));
    EXPECT_NE(0, ViE.image_process->DeregisterRenderEffectFilter(
        tbChannel.videoChannel));

    // Non-existing channel id
    EXPECT_NE(0, ViE.image_process->RegisterRenderEffectFilter(
        tbCapture.captureId, effectFilter));

    //
    // Send effect filter
    //
    EXPECT_EQ(0, ViE.image_process->RegisterSendEffectFilter(
        tbChannel.videoChannel, effectFilter));
    EXPECT_NE(0, ViE.image_process->RegisterSendEffectFilter(
        tbChannel.videoChannel, effectFilter));
    EXPECT_EQ(0, ViE.image_process->DeregisterSendEffectFilter(
        tbChannel.videoChannel));
    EXPECT_NE(0, ViE.image_process->DeregisterSendEffectFilter(
        tbChannel.videoChannel));
    EXPECT_NE(0, ViE.image_process->RegisterSendEffectFilter(
        tbCapture.captureId, effectFilter));

    //
    // Denoising
    //
    EXPECT_EQ(0, ViE.image_process->EnableDenoising(tbCapture.captureId, true));
    // If the denoising is already enabled, it will just reuturn 0.
    EXPECT_EQ(0, ViE.image_process->EnableDenoising(tbCapture.captureId, true));
    EXPECT_EQ(0, ViE.image_process->EnableDenoising(
        tbCapture.captureId, false));
    // If the denoising is already disabled, it will just reuturn 0.
    EXPECT_EQ(0, ViE.image_process->EnableDenoising(
        tbCapture.captureId, false));
    EXPECT_NE(0, ViE.image_process->EnableDenoising(
        tbChannel.videoChannel, true));

    //
    // Deflickering
    //
    EXPECT_EQ(0, ViE.image_process->EnableDeflickering(
        tbCapture.captureId, true));
    EXPECT_NE(0, ViE.image_process->EnableDeflickering(
        tbCapture.captureId, true));
    EXPECT_EQ(0, ViE.image_process->EnableDeflickering(
        tbCapture.captureId, false));
    EXPECT_NE(0, ViE.image_process->EnableDeflickering(
        tbCapture.captureId, false));
    EXPECT_NE(0, ViE.image_process->EnableDeflickering(
        tbChannel.videoChannel, true));

    //
    // Color enhancement
    //
    EXPECT_EQ(0, ViE.image_process->EnableColorEnhancement(
        tbChannel.videoChannel, false));
    EXPECT_EQ(0, ViE.image_process->EnableColorEnhancement(
        tbChannel.videoChannel, true));
    EXPECT_EQ(0, ViE.image_process->EnableColorEnhancement(
        tbChannel.videoChannel, false));
    EXPECT_NE(0, ViE.image_process->EnableColorEnhancement(
        tbCapture.captureId, true));
}
<|endoftext|>


<commit_before>#include "ImagePyramid.hpp"
#include <openslide/openslide.h>
#include <tiffio.h>
#include <FAST/Utility.hpp>
#include <FAST/Data/Image.hpp>
#include <FAST/Data/Access/ImagePyramidAccess.hpp>
#include <utility>
#ifdef WIN32
#include <winbase.h>
#else
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif

namespace fast {

int ImagePyramid::m_counter = 0;

ImagePyramid::ImagePyramid(int width, int height, int channels, int patchWidth, int patchHeight) {
    if(channels <= 0 || channels > 4)
        throw Exception("Nr of channels must be between 1 and 4");

    // Determine how many levels
    int currentLevel = 0;
    int currentWidth = width;
    int currentHeight = height;
    m_channels = channels;

#ifdef WIN32
    m_tiffPath = "C:/windows/temp/fast_image_pyramid_" + std::to_string(m_counter) + ".tiff";
#else
    m_tiffPath = "/tmp/fast_image_pyramid_" + std::to_string(m_counter) + ".tiff";
#endif
    TIFFSetErrorHandler([](const char* module, const char* fmt, va_list ap) {
        auto str = make_uninitialized_unique<char[]>(512);
        sprintf(str.get(), fmt, ap);
        Reporter::warning() << "TIFF: " << module << ": " << str.get() << Reporter::end();
    });
    TIFFSetWarningHandler([](const char* module, const char* fmt, va_list ap) {
        auto str = make_uninitialized_unique<char[]>(512);
        sprintf(str.get(), fmt, ap);
        Reporter::warning() << "TIFF: " << module << ": " << str.get() << Reporter::end();
    });
    m_tiffHandle = TIFFOpen(m_tiffPath.c_str(), "w8");
    auto tiff = m_tiffHandle;
    m_counter += 1;

    ImageCompression compression = ImageCompression::LZW;

    uint photometric = PHOTOMETRIC_RGB;
    uint bitsPerSample = 8;
    uint samplesPerPixel = 3; // RGBA image pyramid is converted to RGB with getPatchAsImage
    if(channels == 1) {
        photometric = PHOTOMETRIC_MINISBLACK; // Photometric mask causes crash..
        samplesPerPixel = 1;
    }

    while(true) {
		currentWidth = width / std::pow(2, currentLevel);
		currentHeight = height / std::pow(2, currentLevel);

        if(currentWidth < 4096 && currentHeight < 4096) // IMPORTANT: This should be the same as in PatchStitcher.
            break;

        reportInfo() << "Processing level " << currentLevel << reportEnd();
        std::size_t bytes = (std::size_t)currentWidth * currentHeight * m_channels * sizeof(char);

        // Get total size of image
        float sizeInMB = (float)bytes / (1024 * 1024);
        reportInfo() << "WSI level size: " << currentWidth << ", " << currentHeight << ", " << m_channels << reportEnd();
        reportInfo() << "WSI level size: " << sizeInMB << " MBs" << reportEnd();

		ImagePyramidLevel levelData;
		levelData.width = currentWidth;
		levelData.height = currentHeight;
		levelData.tileWidth = patchWidth;
        levelData.tileHeight = patchHeight;
        levelData.tilesX = std::ceil((float)levelData.width / levelData.tileWidth);
        levelData.tilesY = std::ceil((float)levelData.height / levelData.tileHeight);

        // Write base tags
        TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, photometric);
        TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bitsPerSample);
        TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
        TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
        TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
        TIFFSetField(tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);

        if(currentLevel > 0) {
            // All levels except highest res level should have this tag?
            TIFFSetField(tiff, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
        }
        switch(compression) {
            case ImageCompression::RAW:
                TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
                break;
            case ImageCompression::LZW:
                TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
                break;
            case ImageCompression::JPEG:
                TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
                break;
            case ImageCompression::JPEG2000:
                // TODO NOT IMPLEMENTED
                throw NotImplementedException();
                TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_JP2000);
                break;
        }

        TIFFSetField(tiff, TIFFTAG_TILEWIDTH, levelData.tileWidth);
        TIFFSetField(tiff, TIFFTAG_TILELENGTH, levelData.tileHeight);
        TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, levelData.width);
        TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, levelData.height);

		m_levels.push_back(levelData);

        // TODO need to initialize somehow?
		// We need to write the first tile for some reason... or we will get an error saying it is missing required
		// TileOffsets
		auto data = std::make_unique<uchar[]>(levelData.tileWidth*levelData.tileHeight*samplesPerPixel); // Is initialized to zeros
        TIFFWriteTile(tiff, data.get(), 0, 0, 0, 0);
        /*
        // TODO Do we really need to inititalize all tiles? This takes time..
        for(int y = 0; y < levelData.tilesY; ++y) {
            for(int x = 0; x < levelData.tilesX; ++x) {
                TIFFWriteTile(tiff, data.get(), x*levelData.tileWidth, y*levelData.tileHeight, 0, 0);
            }
		}*/
        // END

		reportInfo() << "Done creating level " << currentLevel << reportEnd();
		++currentLevel;
		TIFFWriteDirectory(m_tiffHandle);
    }

    mBoundingBox = DataBoundingBox(Vector3f(getFullWidth(), getFullHeight(), 0));
    m_initialized = true;
    m_pyramidFullyInitialized = false;
	m_counter += 1;
}

ImagePyramid::ImagePyramid(openslide_t *fileHandle, std::vector<ImagePyramidLevel> levels) {
    m_fileHandle = fileHandle;
    m_levels = std::move(levels);
    m_channels = 4;
    for(int i = 0; i < m_levels.size(); ++i) {
		m_levels[i].tilesX = std::ceil((float)m_levels[i].width / m_levels[i].tileWidth);
        m_levels[i].tilesY = std::ceil((float)m_levels[i].height / m_levels[i].tileHeight);
    }
    mBoundingBox = DataBoundingBox(Vector3f(getFullWidth(), getFullHeight(), 0));
    m_initialized = true;
    m_pyramidFullyInitialized = true;
	m_counter += 1;
}

ImagePyramid::ImagePyramid() {
    m_initialized = false;
    m_pyramidFullyInitialized = false;
}

ImagePyramidLevel ImagePyramid::getLevelInfo(int level) {
    /*if(!m_initialized)
        throw Exception("ImagePyramid has not been initialized.");*/ // TODO why does this fail?
    if(level < 0 || level > m_levels.size()-1)
        throw Exception("Level " + std::to_string(level) + " doesn't exist in ImagePyramid. Pyramid has " + std::to_string(m_levels.size()) + " levels");
    return m_levels[level];
}

int ImagePyramid::getNrOfLevels() {
    return m_levels.size();
}

int ImagePyramid::getLevelWidth(int level) {
    return getLevelInfo(level).width;
}

int ImagePyramid::getLevelHeight(int level) {
    return getLevelInfo(level).height;
}

int ImagePyramid::getLevelTileWidth(int level) {
    return getLevelInfo(level).tileWidth;
}

int ImagePyramid::getLevelTileHeight(int level) {
    return getLevelInfo(level).tileHeight;
}

int ImagePyramid::getLevelTilesX(int level) {
    return getLevelInfo(level).tilesX;
}

int ImagePyramid::getLevelTilesY(int level) {
    return getLevelInfo(level).tilesY;
}

int ImagePyramid::getFullWidth() {
    return getLevelInfo(0).width;
}

int ImagePyramid::getFullHeight() {
    return getLevelInfo(0).height;
}

void ImagePyramid::free(ExecutionDevice::pointer device) {
    freeAll();
}

void ImagePyramid::freeAll() {
    if(m_fileHandle != nullptr) {
        m_levels.clear();
        openslide_close(m_fileHandle);
    } else if(m_tiffHandle != nullptr) {
        m_levels.clear();
        TIFFClose(m_tiffHandle);
    } else {
		for(auto& item : m_levels) {
			if(item.memoryMapped) {
#ifdef WIN32
				UnmapViewOfFile(item.data);
				CloseHandle(item.fileHandle);
#else
				munmap(item.data, item.width*item.height*m_channels);
				close(item.fileHandle);
#endif
			} else {
				delete[] item.data;
			}
		}
        m_levels.clear();
    }

	m_initialized = false;
	m_fileHandle = nullptr;
}

ImagePyramid::~ImagePyramid() {
    freeAll();
}
int ImagePyramid::getNrOfChannels() const {
    return m_channels;
}

ImagePyramidAccess::pointer ImagePyramid::getAccess(accessType type) {
    if(!m_initialized)
        throw Exception("ImagePyramid has not been initialized.");

    blockIfBeingWrittenTo();

    if(type == ACCESS_READ_WRITE) {
    	blockIfBeingAccessed();
        std::unique_lock<std::mutex> lock(mDataIsBeingWrittenToMutex);
        mDataIsBeingWrittenTo = true;
    }
    //updateHostData();
    if(type == ACCESS_READ_WRITE) {
        //setAllDataToOutOfDate();
        updateModifiedTimestamp();
    }
    //mHostDataIsUpToDate = true;
    {
        std::unique_lock<std::mutex> lock(mDataIsBeingAccessedMutex);
        mDataIsBeingAccessed = true;
    }
    return std::make_unique<ImagePyramidAccess>(m_levels, m_fileHandle, m_tiffHandle, std::static_pointer_cast<ImagePyramid>(mPtr.lock()), type == ACCESS_READ_WRITE, m_initializedPatchList);
}

void ImagePyramid::setDirtyPatch(int level, int patchIdX, int patchIdY) {
	std::lock_guard<std::mutex> lock(m_dirtyPatchMutex);
	const std::string tileString =
		std::to_string(level) + "_" + std::to_string(patchIdX) + "_" + std::to_string(patchIdY);
	m_dirtyPatches.insert(tileString);
}

std::unordered_set<std::string> ImagePyramid::getDirtyPatches() {
	std::lock_guard<std::mutex> lock(m_dirtyPatchMutex);
	return m_dirtyPatches;
}

bool ImagePyramid::isDirtyPatch(const std::string& tileID) {
	std::lock_guard<std::mutex> lock(m_dirtyPatchMutex);
	return m_dirtyPatches.count(tileID);
}

void ImagePyramid::clearDirtyPatches(std::set<std::string> patches) {
	std::lock_guard<std::mutex> lock(m_dirtyPatchMutex);
	for(auto&& patch : patches)
		m_dirtyPatches.erase(patch);
}

void ImagePyramid::setSpacing(Vector3f spacing) {
	m_spacing = spacing;
    if(m_tiffHandle != nullptr) {
        // Write spacing to TIFF file
		if(spacing.x() != 1 && spacing.y() != 1) { // Spacing == 1 means not set.
            auto access = getAccess(ACCESS_READ_WRITE); // Ensure we have exclusive access to TIFF
            for(int level = 0; level < getNrOfLevels(); ++level) {
                TIFFSetDirectory(m_tiffHandle, level);
                TIFFSetField(m_tiffHandle, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER);
                float scaleX = (float)getFullWidth() / getLevelWidth(level);
                float scaleY = (float)getFullHeight() / getLevelHeight(level);
                TIFFSetField(m_tiffHandle, TIFFTAG_XRESOLUTION,
                    1.0f / (spacing.x() / 10) * scaleX); // Convert to cm, and adjust for level
                TIFFSetField(m_tiffHandle, TIFFTAG_YRESOLUTION,
                    1.0f / (spacing.y() / 10) * scaleY); // Convert to cm, and adjust for level
            }
        }
    }
}

Vector3f ImagePyramid::getSpacing() const {
	return m_spacing;
}

ImagePyramid::ImagePyramid(TIFF *fileHandle, std::vector<ImagePyramidLevel> levels, int channels) {
    if(channels <= 0 || channels > 4)
        throw Exception("Nr of channels must be between 1 and 4 in ImagePyramid when importing from TIFF");
    m_tiffHandle = fileHandle;
    m_levels = levels;
    m_channels = channels;
    for(int i = 0; i < m_levels.size(); ++i) {
        m_levels[i].tilesX = std::ceil((float)m_levels[i].width / m_levels[i].tileWidth);
        m_levels[i].tilesY = std::ceil((float)m_levels[i].height / m_levels[i].tileHeight);
    }
    mBoundingBox = DataBoundingBox(Vector3f(getFullWidth(), getFullHeight(), 0));
    m_initialized = true;
    m_pyramidFullyInitialized = true;
    m_counter += 1;
}

bool ImagePyramid::isBGRA() const {
    return m_fileHandle != nullptr;
}

bool ImagePyramid::usesTIFF() const {
    return m_tiffHandle != nullptr;
}

std::string ImagePyramid::getTIFFPath() const {
    return m_tiffPath;
}

bool ImagePyramid::usesOpenSlide() const {
    return m_fileHandle != nullptr;
}

bool ImagePyramid::isPyramidFullyInitialized() const {
    return m_pyramidFullyInitialized;
}

}
<commit_msg>Fixed spacing issue when writing/reading from TIFF in ImagePyramid<commit_after>#include "ImagePyramid.hpp"
#include <openslide/openslide.h>
#include <tiffio.h>
#include <FAST/Utility.hpp>
#include <FAST/Data/Image.hpp>
#include <FAST/Data/Access/ImagePyramidAccess.hpp>
#include <utility>
#ifdef WIN32
#include <winbase.h>
#else
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif

namespace fast {

int ImagePyramid::m_counter = 0;

ImagePyramid::ImagePyramid(int width, int height, int channels, int patchWidth, int patchHeight) {
    if(channels <= 0 || channels > 4)
        throw Exception("Nr of channels must be between 1 and 4");

    // Determine how many levels
    int currentLevel = 0;
    int currentWidth = width;
    int currentHeight = height;
    m_channels = channels;

#ifdef WIN32
    m_tiffPath = "C:/windows/temp/fast_image_pyramid_" + std::to_string(m_counter) + ".tiff";
#else
    m_tiffPath = "/tmp/fast_image_pyramid_" + std::to_string(m_counter) + ".tiff";
#endif
    TIFFSetErrorHandler([](const char* module, const char* fmt, va_list ap) {
        auto str = make_uninitialized_unique<char[]>(512);
        sprintf(str.get(), fmt, ap);
        Reporter::warning() << "TIFF: " << module << ": " << str.get() << Reporter::end();
    });
    TIFFSetWarningHandler([](const char* module, const char* fmt, va_list ap) {
        auto str = make_uninitialized_unique<char[]>(512);
        sprintf(str.get(), fmt, ap);
        Reporter::warning() << "TIFF: " << module << ": " << str.get() << Reporter::end();
    });
    m_tiffHandle = TIFFOpen(m_tiffPath.c_str(), "w8");
    auto tiff = m_tiffHandle;
    m_counter += 1;

    ImageCompression compression = ImageCompression::LZW;

    uint photometric = PHOTOMETRIC_RGB;
    uint bitsPerSample = 8;
    uint samplesPerPixel = 3; // RGBA image pyramid is converted to RGB with getPatchAsImage
    if(channels == 1) {
        photometric = PHOTOMETRIC_MINISBLACK; // Photometric mask causes crash..
        samplesPerPixel = 1;
    }

    while(true) {
		currentWidth = width / std::pow(2, currentLevel);
		currentHeight = height / std::pow(2, currentLevel);

        if(currentWidth < 4096 && currentHeight < 4096) // IMPORTANT: This should be the same as in PatchStitcher.
            break;

        reportInfo() << "Processing level " << currentLevel << reportEnd();
        std::size_t bytes = (std::size_t)currentWidth * currentHeight * m_channels * sizeof(char);

        // Get total size of image
        float sizeInMB = (float)bytes / (1024 * 1024);
        reportInfo() << "WSI level size: " << currentWidth << ", " << currentHeight << ", " << m_channels << reportEnd();
        reportInfo() << "WSI level size: " << sizeInMB << " MBs" << reportEnd();

		ImagePyramidLevel levelData;
		levelData.width = currentWidth;
		levelData.height = currentHeight;
		levelData.tileWidth = patchWidth;
        levelData.tileHeight = patchHeight;
        levelData.tilesX = std::ceil((float)levelData.width / levelData.tileWidth);
        levelData.tilesY = std::ceil((float)levelData.height / levelData.tileHeight);

        // Write base tags
        TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, photometric);
        TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bitsPerSample);
        TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
        TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
        TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
        TIFFSetField(tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);

        if(currentLevel > 0) {
            // All levels except highest res level should have this tag?
            TIFFSetField(tiff, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
        }
        switch(compression) {
            case ImageCompression::RAW:
                TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
                break;
            case ImageCompression::LZW:
                TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
                break;
            case ImageCompression::JPEG:
                TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
                break;
            case ImageCompression::JPEG2000:
                // TODO NOT IMPLEMENTED
                throw NotImplementedException();
                TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_JP2000);
                break;
        }

        TIFFSetField(tiff, TIFFTAG_TILEWIDTH, levelData.tileWidth);
        TIFFSetField(tiff, TIFFTAG_TILELENGTH, levelData.tileHeight);
        TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, levelData.width);
        TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, levelData.height);

		m_levels.push_back(levelData);

        // TODO need to initialize somehow?
		// We need to write the first tile for some reason... or we will get an error saying it is missing required
		// TileOffsets
		auto data = std::make_unique<uchar[]>(levelData.tileWidth*levelData.tileHeight*samplesPerPixel); // Is initialized to zeros
        TIFFWriteTile(tiff, data.get(), 0, 0, 0, 0);
        /*
        // TODO Do we really need to inititalize all tiles? This takes time..
        for(int y = 0; y < levelData.tilesY; ++y) {
            for(int x = 0; x < levelData.tilesX; ++x) {
                TIFFWriteTile(tiff, data.get(), x*levelData.tileWidth, y*levelData.tileHeight, 0, 0);
            }
		}*/
        // END

		reportInfo() << "Done creating level " << currentLevel << reportEnd();
		++currentLevel;
		TIFFWriteDirectory(m_tiffHandle);
    }

    mBoundingBox = DataBoundingBox(Vector3f(getFullWidth(), getFullHeight(), 0));
    m_initialized = true;
    m_pyramidFullyInitialized = false;
	m_counter += 1;
}

ImagePyramid::ImagePyramid(openslide_t *fileHandle, std::vector<ImagePyramidLevel> levels) {
    m_fileHandle = fileHandle;
    m_levels = std::move(levels);
    m_channels = 4;
    for(int i = 0; i < m_levels.size(); ++i) {
		m_levels[i].tilesX = std::ceil((float)m_levels[i].width / m_levels[i].tileWidth);
        m_levels[i].tilesY = std::ceil((float)m_levels[i].height / m_levels[i].tileHeight);
    }
    mBoundingBox = DataBoundingBox(Vector3f(getFullWidth(), getFullHeight(), 0));
    m_initialized = true;
    m_pyramidFullyInitialized = true;
	m_counter += 1;
}

ImagePyramid::ImagePyramid() {
    m_initialized = false;
    m_pyramidFullyInitialized = false;
}

ImagePyramidLevel ImagePyramid::getLevelInfo(int level) {
    /*if(!m_initialized)
        throw Exception("ImagePyramid has not been initialized.");*/ // TODO why does this fail?
    if(level < 0 || level > m_levels.size()-1)
        throw Exception("Level " + std::to_string(level) + " doesn't exist in ImagePyramid. Pyramid has " + std::to_string(m_levels.size()) + " levels");
    return m_levels[level];
}

int ImagePyramid::getNrOfLevels() {
    return m_levels.size();
}

int ImagePyramid::getLevelWidth(int level) {
    return getLevelInfo(level).width;
}

int ImagePyramid::getLevelHeight(int level) {
    return getLevelInfo(level).height;
}

int ImagePyramid::getLevelTileWidth(int level) {
    return getLevelInfo(level).tileWidth;
}

int ImagePyramid::getLevelTileHeight(int level) {
    return getLevelInfo(level).tileHeight;
}

int ImagePyramid::getLevelTilesX(int level) {
    return getLevelInfo(level).tilesX;
}

int ImagePyramid::getLevelTilesY(int level) {
    return getLevelInfo(level).tilesY;
}

int ImagePyramid::getFullWidth() {
    return getLevelInfo(0).width;
}

int ImagePyramid::getFullHeight() {
    return getLevelInfo(0).height;
}

void ImagePyramid::free(ExecutionDevice::pointer device) {
    freeAll();
}

void ImagePyramid::freeAll() {
    if(m_fileHandle != nullptr) {
        m_levels.clear();
        openslide_close(m_fileHandle);
    } else if(m_tiffHandle != nullptr) {
        m_levels.clear();
        TIFFClose(m_tiffHandle);
    } else {
		for(auto& item : m_levels) {
			if(item.memoryMapped) {
#ifdef WIN32
				UnmapViewOfFile(item.data);
				CloseHandle(item.fileHandle);
#else
				munmap(item.data, item.width*item.height*m_channels);
				close(item.fileHandle);
#endif
			} else {
				delete[] item.data;
			}
		}
        m_levels.clear();
    }

	m_initialized = false;
	m_fileHandle = nullptr;
}

ImagePyramid::~ImagePyramid() {
    freeAll();
}
int ImagePyramid::getNrOfChannels() const {
    return m_channels;
}

ImagePyramidAccess::pointer ImagePyramid::getAccess(accessType type) {
    if(!m_initialized)
        throw Exception("ImagePyramid has not been initialized.");

    blockIfBeingWrittenTo();

    if(type == ACCESS_READ_WRITE) {
    	blockIfBeingAccessed();
        std::unique_lock<std::mutex> lock(mDataIsBeingWrittenToMutex);
        mDataIsBeingWrittenTo = true;
    }
    //updateHostData();
    if(type == ACCESS_READ_WRITE) {
        //setAllDataToOutOfDate();
        updateModifiedTimestamp();
    }
    //mHostDataIsUpToDate = true;
    {
        std::unique_lock<std::mutex> lock(mDataIsBeingAccessedMutex);
        mDataIsBeingAccessed = true;
    }
    return std::make_unique<ImagePyramidAccess>(m_levels, m_fileHandle, m_tiffHandle, std::static_pointer_cast<ImagePyramid>(mPtr.lock()), type == ACCESS_READ_WRITE, m_initializedPatchList);
}

void ImagePyramid::setDirtyPatch(int level, int patchIdX, int patchIdY) {
	std::lock_guard<std::mutex> lock(m_dirtyPatchMutex);
	const std::string tileString =
		std::to_string(level) + "_" + std::to_string(patchIdX) + "_" + std::to_string(patchIdY);
	m_dirtyPatches.insert(tileString);
}

std::unordered_set<std::string> ImagePyramid::getDirtyPatches() {
	std::lock_guard<std::mutex> lock(m_dirtyPatchMutex);
	return m_dirtyPatches;
}

bool ImagePyramid::isDirtyPatch(const std::string& tileID) {
	std::lock_guard<std::mutex> lock(m_dirtyPatchMutex);
	return m_dirtyPatches.count(tileID);
}

void ImagePyramid::clearDirtyPatches(std::set<std::string> patches) {
	std::lock_guard<std::mutex> lock(m_dirtyPatchMutex);
	for(auto&& patch : patches)
		m_dirtyPatches.erase(patch);
}

void ImagePyramid::setSpacing(Vector3f spacing) {
	m_spacing = spacing;
    if(m_tiffHandle != nullptr) {
        // Write spacing to TIFF file
		if(spacing.x() != 1 && spacing.y() != 1) { // Spacing == 1 means not set.
            auto access = getAccess(ACCESS_READ_WRITE); // Ensure we have exclusive access to TIFF
            for(int level = 0; level < getNrOfLevels(); ++level) {
                TIFFSetDirectory(m_tiffHandle, level);
                TIFFSetField(m_tiffHandle, TIFFTAG_RESOLUTIONUNIT, RESUNIT_CENTIMETER);
                float scaleX = (float)getFullWidth() / getLevelWidth(level);
                float scaleY = (float)getFullHeight() / getLevelHeight(level);
                TIFFSetField(m_tiffHandle, TIFFTAG_XRESOLUTION,
                    1.0f / (spacing.x() / 10.0f) * scaleX); // Convert to cm, and adjust for level
                TIFFSetField(m_tiffHandle, TIFFTAG_YRESOLUTION,
                    1.0f / (spacing.y() / 10.0f) * scaleY); // Convert to cm, and adjust for level
                TIFFRewriteDirectory(m_tiffHandle); // Write changes
            }
        }
    }
}

Vector3f ImagePyramid::getSpacing() const {
	return m_spacing;
}

ImagePyramid::ImagePyramid(TIFF *fileHandle, std::vector<ImagePyramidLevel> levels, int channels) {
    if(channels <= 0 || channels > 4)
        throw Exception("Nr of channels must be between 1 and 4 in ImagePyramid when importing from TIFF");
    m_tiffHandle = fileHandle;
    m_levels = levels;
    m_channels = channels;
    for(int i = 0; i < m_levels.size(); ++i) {
        m_levels[i].tilesX = std::ceil((float)m_levels[i].width / m_levels[i].tileWidth);
        m_levels[i].tilesY = std::ceil((float)m_levels[i].height / m_levels[i].tileHeight);
    }
    // Get spacing from TIFF
    float spacingX;
    float spacingY;
    TIFFSetDirectory(fileHandle, 0);
    int resX = TIFFGetField(fileHandle, TIFFTAG_XRESOLUTION, &spacingX);
    int resY = TIFFGetField(fileHandle, TIFFTAG_YRESOLUTION, &spacingY);
    if(resX == 1 && resY == 1) {
        // Convert from cm
        spacingX = 1.0f/(spacingX/10.0f);
        spacingY = 1.0f/(spacingY/10.0f);
        reportInfo() << "Spacing from TIFF was" << spacingX << " " << spacingY << reportEnd();
        m_spacing = Vector3f(spacingX, spacingY, 1.0f);
    }
    mBoundingBox = DataBoundingBox(Vector3f(getFullWidth(), getFullHeight(), 0));
    m_initialized = true;
    m_pyramidFullyInitialized = true;
    m_counter += 1;
}

bool ImagePyramid::isBGRA() const {
    return m_fileHandle != nullptr;
}

bool ImagePyramid::usesTIFF() const {
    return m_tiffHandle != nullptr;
}

std::string ImagePyramid::getTIFFPath() const {
    return m_tiffPath;
}

bool ImagePyramid::usesOpenSlide() const {
    return m_fileHandle != nullptr;
}

bool ImagePyramid::isPyramidFullyInitialized() const {
    return m_pyramidFullyInitialized;
}

}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "ErrorHandler.h"
#include "BzfWindow.h"

BzfWindow::BzfWindow(const BzfDisplay* _display) : display(_display)
{
#ifdef HAVE_SDL
  if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) {
    std::vector<std::string> args;
    args.push_back(SDL_GetError());
    printError("Could not initialize SDL Joystick subsystem: %s.\n", &args);
  };
#endif
}

BzfWindow::~BzfWindow()
{
#ifdef HAVE_SDL
  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
#endif
}

void			BzfWindow::callExposeCallbacks() const
{
  const int count = exposeCallbacks.size();
  for (int i = 0; i < count; i++) {
    const BzfWindowCB& cb = exposeCallbacks[i];
    (*cb.cb)(cb.data);
  }
}

void			BzfWindow::addExposeCallback(
				void (*_cb)(void*), void* data)
{
  BzfWindowCB cb;
  cb.cb = _cb;
  cb.data = data;
  exposeCallbacks.push_back(cb);
}

void			BzfWindow::removeExposeCallback(
				void (*_cb)(void*), void* data)
{
  std::vector<BzfWindowCB>::iterator it = exposeCallbacks.begin();
  for(; it != exposeCallbacks.end(); it++) {
    if((it->cb == _cb) && (it->data == data)) {
      exposeCallbacks.erase(it);
      break;
    }
  }
}

void			BzfWindow::callResizeCallbacks() const
{
  const int count = resizeCallbacks.size();
  for (int i = 0; i < count; i++) {
    const BzfWindowCB& cb = resizeCallbacks[i];
    (*cb.cb)(cb.data);
  }
}

void			BzfWindow::addResizeCallback(
				void (*_cb)(void*), void* data)
{
  BzfWindowCB cb;
  cb.cb = _cb;
  cb.data = data;
  resizeCallbacks.push_back(cb);
}

void			BzfWindow::removeResizeCallback(
				void (*_cb)(void*), void* data)
{
  std::vector<BzfWindowCB>::iterator it = resizeCallbacks.begin();
  for(; it != resizeCallbacks.end(); it++) {
    if((it->cb == _cb) && (it->data == data)) {
      resizeCallbacks.erase(it);
      break;
    }
  }
}

void			BzfWindow::initJoystick(const char* joystickName)
{
#ifdef HAVE_SDL
  if (!strcmp(joystickName, "off")) {
    joystickID = NULL;
    return;
  }
  int numJoystick = SDL_NumJoysticks();
  if (!numJoystick) {
    printError("no joystick is supported...");
    return;
  }
  int i;
  for (i = 0; i < numJoystick; i++)
    if (strcmp(SDL_JoystickName(i), joystickName) == 0)
      break;
  if (i >= numJoystick)
    i = 0;
  joystickID = SDL_JoystickOpen(i);
  if (SDL_JoystickNumAxes(joystickID) < 2) {
    SDL_JoystickClose(joystickID);
    printError("joystick has less then 2 axis:\n");
    joystickID = NULL;
    return;
  }
  joystickButtons = SDL_JoystickNumButtons(joystickID);
#else
  if (strcmp(joystickName, "off") && strcmp(joystickName, "")) {
    std::vector<std::string> args;
    args.push_back(joystickName);
    printError("joystick '{1}' not supported...", &args);
  }
#endif
}

bool			BzfWindow::joystick() const
{
#ifdef HAVE_SDL
  return joystickID != NULL;
#else
  return false;
#endif
}

void			BzfWindow::getJoy(int& x, int& y) const
{
#ifdef HAVE_SDL
  if (!joystickID)
    return;

  SDL_JoystickUpdate();
  x = SDL_JoystickGetAxis(joystickID, 0);
  y = SDL_JoystickGetAxis(joystickID, 1);

  x = x * 1000 / 32768;
  y = y * 1000 / 32768;

  /* balistic */
  x = (x * abs(x))/1000;
  y = (y * abs(y))/1000;
#else
  x = 0;
  y = 0;
#endif
}

unsigned long		BzfWindow::getJoyButtons() const
{
#ifdef HAVE_SDL
  unsigned long buttons = 0;

  if (!joystickID)
    return 0;

  SDL_JoystickUpdate();
  for (int i = 0; i < joystickButtons; i++)
    if (SDL_JoystickGetButton(joystickID, i) == 1)
      if (i == 1)
	buttons |= 1 << 9;
      else
	if ((i > 1) && (i < 10))
	  buttons |= 1 << (i - 1);
	else
	  buttons |= 1 << i;
  return buttons;
#else
  return 0;
#endif
}

void                    BzfWindow::getJoyDevices(std::vector<std::string>
						 &) const {
#ifdef HAVE_SDL

  int numJoystick = SDL_NumJoysticks();
  int i;
  for (i = 0; i < numJoystick; i++)
    list.push_back(SDL_JoystickName(i));
#endif
}

void			BzfWindow::yieldCurrent(void)
{
	// do nothing
}

void			BzfWindow::releaseCurrent(void)
{
	// do nothing
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>Didn't mean to update that file<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "ErrorHandler.h"
#include "BzfWindow.h"

BzfWindow::BzfWindow(const BzfDisplay* _display) : display(_display)
{
#ifdef HAVE_SDL
  if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) {
    std::vector<std::string> args;
    args.push_back(SDL_GetError());
    printError("Could not initialize SDL Joystick subsystem: %s.\n", &args);
  };
#endif
}

BzfWindow::~BzfWindow()
{
#ifdef HAVE_SDL
  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
#endif
}

void			BzfWindow::callExposeCallbacks() const
{
  const int count = exposeCallbacks.size();
  for (int i = 0; i < count; i++) {
    const BzfWindowCB& cb = exposeCallbacks[i];
    (*cb.cb)(cb.data);
  }
}

void			BzfWindow::addExposeCallback(
				void (*_cb)(void*), void* data)
{
  BzfWindowCB cb;
  cb.cb = _cb;
  cb.data = data;
  exposeCallbacks.push_back(cb);
}

void			BzfWindow::removeExposeCallback(
				void (*_cb)(void*), void* data)
{
  std::vector<BzfWindowCB>::iterator it = exposeCallbacks.begin();
  for(; it != exposeCallbacks.end(); it++) {
    if((it->cb == _cb) && (it->data == data)) {
      exposeCallbacks.erase(it);
      break;
    }
  }
}

void			BzfWindow::callResizeCallbacks() const
{
  const int count = resizeCallbacks.size();
  for (int i = 0; i < count; i++) {
    const BzfWindowCB& cb = resizeCallbacks[i];
    (*cb.cb)(cb.data);
  }
}

void			BzfWindow::addResizeCallback(
				void (*_cb)(void*), void* data)
{
  BzfWindowCB cb;
  cb.cb = _cb;
  cb.data = data;
  resizeCallbacks.push_back(cb);
}

void			BzfWindow::removeResizeCallback(
				void (*_cb)(void*), void* data)
{
  std::vector<BzfWindowCB>::iterator it = resizeCallbacks.begin();
  for(; it != resizeCallbacks.end(); it++) {
    if((it->cb == _cb) && (it->data == data)) {
      resizeCallbacks.erase(it);
      break;
    }
  }
}

void			BzfWindow::initJoystick(const char* joystickName)
{
#ifdef HAVE_SDL
  if (!strcmp(joystickName, "off")) {
    joystickID = NULL;
    return;
  }
  int numJoystick = SDL_NumJoysticks();
  if (!numJoystick) {
    printError("no joystick is supported...");
    return;
  }
  int i;
  for (i = 0; i < numJoystick; i++)
    if (strcmp(SDL_JoystickName(i), joystickName) == 0)
      break;
  if (i >= numJoystick)
    i = 0;
  joystickID = SDL_JoystickOpen(i);
  if (SDL_JoystickNumAxes(joystickID) < 2) {
    SDL_JoystickClose(joystickID);
    printError("joystick has less then 2 axis:\n");
    joystickID = NULL;
    return;
  }
  joystickButtons = SDL_JoystickNumButtons(joystickID);
#else
  if (strcmp(joystickName, "off") && strcmp(joystickName, "")) {
    std::vector<std::string> args;
    args.push_back(joystickName);
    printError("joystick '{1}' not supported...", &args);
  }
#endif
}

bool			BzfWindow::joystick() const
{
#ifdef HAVE_SDL
  return joystickID != NULL;
#else
  return false;
#endif
}

void			BzfWindow::getJoy(int& x, int& y) const
{
#ifdef HAVE_SDL
  if (!joystickID)
    return;

  SDL_JoystickUpdate();
  x = SDL_JoystickGetAxis(joystickID, 0);
  y = SDL_JoystickGetAxis(joystickID, 1);

  x = x * 1000 / 32768;
  y = y * 1000 / 32768;

  /* balistic */
  x = (x * abs(x))/1000;
  y = (y * abs(y))/1000;
#else
  x = 0;
  y = 0;
#endif
}

unsigned long		BzfWindow::getJoyButtons() const
{
#ifdef HAVE_SDL
  unsigned long buttons = 0;

  if (!joystickID)
    return 0;

  SDL_JoystickUpdate();
  for (int i = 0; i < joystickButtons; i++)
    if (SDL_JoystickGetButton(joystickID, i) == 1)
      if (i == 1)
	buttons |= 1 << 9;
      else
	if ((i > 1) && (i < 10))
	  buttons |= 1 << (i - 1);
	else
	  buttons |= 1 << i;
  return buttons;
#else
  return 0;
#endif
}

void                    BzfWindow::getJoyDevices(std::vector<std::string>
						 &list) const {
#ifdef HAVE_SDL

  int numJoystick = SDL_NumJoysticks();
  int i;
  for (i = 0; i < numJoystick; i++)
    list.push_back(SDL_JoystickName(i));
#endif
}

void			BzfWindow::yieldCurrent(void)
{
	// do nothing
}

void			BzfWindow::releaseCurrent(void)
{
	// do nothing
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


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

#include "content/browser/accessibility/browser_accessibility_manager_win.h"

#include "content/browser/accessibility/browser_accessibility_win.h"
#include "content/common/view_messages.h"

using webkit_glue::WebAccessibility;

// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
    gfx::NativeView parent_view,
    const WebAccessibility& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  return new BrowserAccessibilityManagerWin(
      parent_view,
      src,
      delegate,
      factory);
}

BrowserAccessibilityManagerWin*
BrowserAccessibilityManager::toBrowserAccessibilityManagerWin() {
  return static_cast<BrowserAccessibilityManagerWin*>(this);
}

BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
    HWND parent_view,
    const WebAccessibility& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory)
    : BrowserAccessibilityManager(parent_view, src, delegate, factory) {
  // Allow NULL parent_view for unit testing.
  if (parent_view == NULL) {
    window_iaccessible_ = NULL;
    return;
  }

  HRESULT hr = ::CreateStdAccessibleObject(
      parent_view, OBJID_WINDOW, IID_IAccessible,
      reinterpret_cast<void **>(&window_iaccessible_));
  DCHECK(SUCCEEDED(hr));
}

BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
}

IAccessible* BrowserAccessibilityManagerWin::GetParentWindowIAccessible() {
  return window_iaccessible_;
}

void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
    int type,
    BrowserAccessibility* node) {
  LONG event_id = EVENT_MIN;
  switch (type) {
    case ViewHostMsg_AccEvent::ACTIVE_DESCENDANT_CHANGED:
      event_id = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED;
      break;
    case ViewHostMsg_AccEvent::CHECK_STATE_CHANGED:
      event_id = EVENT_OBJECT_STATECHANGE;
      break;
    case ViewHostMsg_AccEvent::CHILDREN_CHANGED:
      event_id = EVENT_OBJECT_REORDER;
      break;
    case ViewHostMsg_AccEvent::FOCUS_CHANGED:
      event_id = EVENT_OBJECT_FOCUS;
      break;
    case ViewHostMsg_AccEvent::LOAD_COMPLETE:
      event_id = IA2_EVENT_DOCUMENT_LOAD_COMPLETE;
      break;
    case ViewHostMsg_AccEvent::VALUE_CHANGED:
      event_id = EVENT_OBJECT_VALUECHANGE;
      break;
    case ViewHostMsg_AccEvent::SELECTED_TEXT_CHANGED:
      event_id = IA2_EVENT_TEXT_CARET_MOVED;
      break;
    case ViewHostMsg_AccEvent::LIVE_REGION_CHANGED:
      event_id = EVENT_OBJECT_REORDER;
      break;
    case ViewHostMsg_AccEvent::TEXT_INSERTED:
      event_id = IA2_EVENT_TEXT_INSERTED;
      break;
    case ViewHostMsg_AccEvent::TEXT_REMOVED:
      event_id = IA2_EVENT_TEXT_REMOVED;
      break;
    case ViewHostMsg_AccEvent::OBJECT_SHOW:
      event_id = EVENT_OBJECT_SHOW;
      break;
    case ViewHostMsg_AccEvent::OBJECT_HIDE:
      event_id = EVENT_OBJECT_HIDE;
      break;
    case ViewHostMsg_AccEvent::ALERT:
      event_id = EVENT_SYSTEM_ALERT;
      break;
    default:
      // Not all WebKit accessibility events result in a Windows
      // accessibility notification.
      return;
  }

  NotifyWinEvent(event_id, GetParentView(), OBJID_CLIENT, node->child_id());
}
<commit_msg>Add Windows accessibility notifications used by <select> controls (list boxes and combo boxes).<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/accessibility/browser_accessibility_manager_win.h"

#include "content/browser/accessibility/browser_accessibility_win.h"
#include "content/common/view_messages.h"

using webkit_glue::WebAccessibility;

// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
    gfx::NativeView parent_view,
    const WebAccessibility& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  return new BrowserAccessibilityManagerWin(
      parent_view,
      src,
      delegate,
      factory);
}

BrowserAccessibilityManagerWin*
BrowserAccessibilityManager::toBrowserAccessibilityManagerWin() {
  return static_cast<BrowserAccessibilityManagerWin*>(this);
}

BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
    HWND parent_view,
    const WebAccessibility& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory)
    : BrowserAccessibilityManager(parent_view, src, delegate, factory) {
  // Allow NULL parent_view for unit testing.
  if (parent_view == NULL) {
    window_iaccessible_ = NULL;
    return;
  }

  HRESULT hr = ::CreateStdAccessibleObject(
      parent_view, OBJID_WINDOW, IID_IAccessible,
      reinterpret_cast<void **>(&window_iaccessible_));
  DCHECK(SUCCEEDED(hr));
}

BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
}

IAccessible* BrowserAccessibilityManagerWin::GetParentWindowIAccessible() {
  return window_iaccessible_;
}

void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent(
    int type,
    BrowserAccessibility* node) {
  LONG event_id = EVENT_MIN;
  switch (type) {
    case ViewHostMsg_AccEvent::ACTIVE_DESCENDANT_CHANGED:
      event_id = IA2_EVENT_ACTIVE_DESCENDANT_CHANGED;
      break;
    case ViewHostMsg_AccEvent::CHECK_STATE_CHANGED:
      event_id = EVENT_OBJECT_STATECHANGE;
      break;
    case ViewHostMsg_AccEvent::CHILDREN_CHANGED:
      event_id = EVENT_OBJECT_REORDER;
      break;
    case ViewHostMsg_AccEvent::FOCUS_CHANGED:
      event_id = EVENT_OBJECT_FOCUS;
      break;
    case ViewHostMsg_AccEvent::LOAD_COMPLETE:
      event_id = IA2_EVENT_DOCUMENT_LOAD_COMPLETE;
      break;
    case ViewHostMsg_AccEvent::VALUE_CHANGED:
      event_id = EVENT_OBJECT_VALUECHANGE;
      break;
    case ViewHostMsg_AccEvent::SELECTED_TEXT_CHANGED:
      event_id = IA2_EVENT_TEXT_CARET_MOVED;
      break;
    case ViewHostMsg_AccEvent::LIVE_REGION_CHANGED:
      event_id = EVENT_OBJECT_REORDER;
      break;
    case ViewHostMsg_AccEvent::TEXT_INSERTED:
      event_id = IA2_EVENT_TEXT_INSERTED;
      break;
    case ViewHostMsg_AccEvent::TEXT_REMOVED:
      event_id = IA2_EVENT_TEXT_REMOVED;
      break;
    case ViewHostMsg_AccEvent::OBJECT_SHOW:
      event_id = EVENT_OBJECT_SHOW;
      break;
    case ViewHostMsg_AccEvent::OBJECT_HIDE:
      event_id = EVENT_OBJECT_HIDE;
      break;
    case ViewHostMsg_AccEvent::ALERT:
      event_id = EVENT_SYSTEM_ALERT;
      break;
    case ViewHostMsg_AccEvent::MENU_LIST_VALUE_CHANGED:
      event_id = EVENT_OBJECT_VALUECHANGE;
      break;
    case ViewHostMsg_AccEvent::SELECTED_CHILDREN_CHANGED:
      event_id = EVENT_OBJECT_SELECTIONWITHIN;
      break;
    default:
      // Not all WebKit accessibility events result in a Windows
      // accessibility notification.
      return;
  }

  NotifyWinEvent(event_id, GetParentView(), OBJID_CLIENT, node->child_id());
}
<|endoftext|>


<commit_before>#include <sys/time.h>

#include "MacWindow.h"

#ifdef __cplusplus
#  define EXTERN_C_BEGIN extern "C" {
#  define EXTERN_C_END   }
#endif

EXTERN_C_BEGIN
extern WindowRef GetWindowRefFromNativeWindow(void * nativeWindow);
EXTERN_C_END

struct Settings
{
  bool Use_Main_Display;
  bool Switch_Display;
  bool Capture_Display;
  CGSize Window_Size;
  long Display_Hz;
  bool VBL_Synch;
  int depth;

  Settings() {
    Use_Main_Display = true;
    Capture_Display = true;
    Switch_Display = true;
    Window_Size = CGSizeMake(CGDisplayPixelsWide(kCGDirectMainDisplay),
	CGDisplayPixelsHigh(kCGDirectMainDisplay));
    Display_Hz = 60;
    VBL_Synch = false; //CAPS-LOCK overrides
    depth = 24;
  }
} settings;

static double get_time()
{
  struct timeval tod;

  gettimeofday(&tod, NULL);

  return tod.tv_sec + tod.tv_usec * 1.0E-6;
}

#ifndef USE_DSP
  #define GLOBAL_OFFSET_X 0
  #define GLOBAL_OFFSET_Y 20
#else
  #define GLOBAL_OFFSET_X 0
  #define GLOBAL_OFFSET_Y 0
#endif

//Point gMousePosition;
bool gMouseGrabbed;

class GLContext
{
  const CGLPixelFormatAttribute* GetPixelFormat(u_int32_t display_id = 0x01,
      int color = settings.depth, int depth = 0, int stencil = 0) {
    static CGLPixelFormatAttribute attribs[32];

    CGLPixelFormatAttribute* attrib = attribs;

    *attrib++ = kCGLPFANoRecovery;
    *attrib++ = kCGLPFADoubleBuffer;
    *attrib++ = kCGLPFAAccelerated;
    *attrib++ = kCGLPFAFullScreen;
    *attrib++ = kCGLPFADisplayMask; *attrib++ = (CGLPixelFormatAttribute) display_id;
    *attrib++ = kCGLPFAColorSize; *attrib++ = (CGLPixelFormatAttribute) color;
    *attrib++ = kCGLPFADepthSize; *attrib++ = (CGLPixelFormatAttribute) depth;
    *attrib++ = kCGLPFAStencilSize; *attrib++ = (CGLPixelFormatAttribute) stencil;
    *attrib++ = (CGLPixelFormatAttribute) 0;

    return attribs;
  }

  public:

    CGRect bounds;
    CGLContextObj cgl_context;

    GLContext() {
      bounds = CGRectMake(0,0,0,0);
      cgl_context = NULL;
    }

    CGLContextObj GetGLContext(void) {
      return cgl_context;
    }

    bool Init(u_int32_t display_id, const CGRect& display_rect) {
      CGLPixelFormatObj pixel_format;
      long num_pixel_formats;

      CGLError err = CGLChoosePixelFormat(GetPixelFormat(display_id, 24),
	  &pixel_format, &num_pixel_formats);

      if (err || !pixel_format)
	return false;

      err = CGLCreateContext(pixel_format, NULL, &cgl_context);

      if (err)
	return false;

      CGLDestroyPixelFormat(pixel_format);
      pixel_format = NULL;

      err = CGLSetCurrentContext(cgl_context);

      if (err)
	return false;

      err = CGLSetFullScreen(cgl_context);

      if (err)
	return false;

      bounds = display_rect;

      if (settings.VBL_Synch)
	SetVBLSynch(true);

      return true;
    }

    void Reset() {
      if (cgl_context) {
	CGLSetCurrentContext(NULL);
	CGLClearDrawable(cgl_context);
	CGLDestroyContext(cgl_context);
	cgl_context = NULL;
      }
    }

    void SetPerspective(float angle, float near, float far) {
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();

      float aspect_ratio = bounds.size.width / bounds.size.height;

      gluPerspective(angle, aspect_ratio, near, far);
      glMatrixMode(GL_MODELVIEW);
    }

    void SetOrthographic() {
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();

      GLint params[4];
      glGetIntegerv(GL_VIEWPORT, params);
      gluOrtho2D(0, params[2], params[3], 0);

      glMatrixMode(GL_MODELVIEW);
    }

    void SetVBLSynch(bool synch) {
      long params[] = { synch ? 1 : 0 };
      CGLSetParameter(cgl_context, kCGLCPSwapInterval, params);

      settings.VBL_Synch = synch;
    }

    void Flush() {
      glFinish();
      if (cgl_context)
	CGLFlushDrawable(cgl_context);
    }

    void Process() {
      if (!cgl_context)
	return;

      static float t0 = get_time();

      float t = get_time() - t0;

      bool vbl_synch = false;

      if (settings.VBL_Synch != vbl_synch)
	SetVBLSynch(vbl_synch);

      float t1 = fabs(sin(t));

      glClearColor(0,0,0.1*t1,0);
      glClear(GL_COLOR_BUFFER_BIT);

      SetOrthographic();

      glPushMatrix();

      glTranslatef(bounds.size.width*0.5f-64.0,0,0);
      glTranslatef((bounds.size.width*0.5f-64.0-(1-0.435))*sin(t*3),0,0);

      glBegin(GL_QUADS);

      glColor3f(fabs(cos(t)),0,fabs(sin(t)));
      glVertex2f(0.0, 0.435);

      glColor3f(fabs(cos(t)),fabs(sin(t)),0);
      glVertex2f(0.0, bounds.size.height);

      glColor3f(0,fabs(cos(t)),fabs(sin(t)));
      glVertex2f(128.0, bounds.size.height);

      glColor3f(fabs(sin(t)),0,fabs(cos(t)));
      glVertex2f(128.0, 0.435);

      glEnd();

      GLfloat frame[4] = { 1,1,1,1};
      glColor4fv(frame);

      glBegin(GL_LINE_LOOP);

      glVertex2f(0.0, 0.435);

      glVertex2f(0.0, bounds.size.height);

      glVertex2f(128.0, bounds.size.height);

      glVertex2f(128.0, 0.435);

      glEnd();

      glPopMatrix();

      glFinish();

      CGLFlushDrawable(cgl_context);
    }
} gl_context;

long get_value(CFDictionaryRef values, CFStringRef key)
{
  CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(values, key);

  if (!number_value)
    return -1;

  long int_value;

  if (!CFNumberGetValue(number_value, kCFNumberLongType, &int_value))
    return -1;

  return int_value;
}

class DirectDisplay
{
  CGDisplayCount num_displays;
  CGDirectDisplayID* display_ids;

  void DumpDisplayModeValues(CFDictionaryRef values) {
  /*
    dprintf("   ----- Display Mode Info for %d -----\n", get_value(values, kCGDisplayMode));
    dprintf("   Bounds = %d x %d\n", get_value(values, kCGDisplayWidth), get_value(values, kCGDisplayHeight));
    dprintf("   bpp = %d, hz = %d\n", get_value(values, kCGDisplayBitsPerPixel), get_value(values,  kCGDisplayRefreshRate));
  */
  }

public:

  DirectDisplay() {
    num_displays = 0;
    display_ids = 0;
  }

  int Init() {
     if (CGGetActiveDisplayList(0, NULL, &num_displays) != CGDisplayNoErr || num_displays == 0)
      return 0;

    display_ids = new CGDirectDisplayID[num_displays];

    if (CGGetActiveDisplayList(num_displays, display_ids, &num_displays) != CGDisplayNoErr)
      return false;

    return num_displays;
  }

  CGRect GetDisplayBounds(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return CGRectMake(0,0,0,0);

    return CGDisplayBounds(display_ids[display_num]);
  }

  u_int32_t GetOpenGLDisplayID(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return 0;

    return CGDisplayIDToOpenGLDisplayMask(display_ids[display_num]);
  }

  CGDirectDisplayID GetDirectDisplayID(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return 0;

    return display_ids[display_num];
  }

  void DumpCurrentDisplayMode(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return;

    CFDictionaryRef display_mode_values = CGDisplayCurrentMode(display_ids[display_num]);

    DumpDisplayModeValues(display_mode_values);
  }

  void DumpDisplayModes(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return;

    CFArrayRef display_modes = CGDisplayAvailableModes(display_ids[display_num]);

    CFIndex num_modes = CFArrayGetCount(display_modes);
  }

  bool SetDisplayMode(CGDisplayCount display_num, const CGSize& size, size_t bpp, CGRefreshRate hz) {
    if (display_num >= num_displays)
      return false;

    CFDictionaryRef display_mode_values = CGDisplayBestModeForParametersAndRefreshRate(display_ids[display_num], bpp, (size_t) size.width, (size_t) size.height, hz, NULL);

    int display_hz = get_value(display_mode_values,  kCGDisplayRefreshRate);

    CGDisplayErr err = CGDisplaySwitchToMode(display_ids[display_num], display_mode_values);

    return err == CGDisplayNoErr;
  }

  bool Capture(CGDisplayCount display_num) {
    if (display_num >= num_displays || CGDisplayIsCaptured(display_ids[display_num]))
      return false;

    return CGDisplayCapture(display_ids[display_num]) == CGDisplayNoErr;
  }

  bool Release(CGDisplayCount display_num = 0) {
    if (display_num >= num_displays || !CGDisplayIsCaptured(display_ids[display_num]))
      return false;

    return CGDisplayRelease(display_ids[display_num]) == CGDisplayNoErr;
  }
} displays;

void Display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

MacWindow::MacWindow(const MacDisplay *display, MacVisual *visual) :
			BzfWindow(display)
{
  GLboolean ok;
  int argc = 0;
  char **argv = {NULL};

  int num_displays = displays.Init();

  if (num_displays == 0)
    return;

  int display_index = settings.Use_Main_Display ? 0 : num_displays-1;

  u_int32_t display_id = displays.GetOpenGLDisplayID(display_index);

  if (settings.Capture_Display)
    displays.Capture(display_index);

  if (settings.Switch_Display)
    if (displays.SetDisplayMode(display_index, settings.Window_Size, settings.depth, settings.Display_Hz))
      displays.DumpCurrentDisplayMode(display_index);

  CGRect window_rect = CGRectMake(0,0, settings.Window_Size.width, settings.Window_Size.height);

  if (!settings.Switch_Display)
    window_rect.origin = CGPointMake(32,32);

  if (!gl_context.Init(display_id, window_rect))
    return;

#ifdef USE_DSP
  display->setWindow(window);
#endif

  visual->reset();
  visual->setLevel(0);
  visual->setIndex(24);
  //visual->setDepth(24);
  visual->setDoubleBuffer(true);
  visual->setRGBA(1, 1, 1, 0);
  //visual->setStencil(1);

  //visual->addAttribute1(AGL_FULLSCREEN);

  visual->build();

  display->setContext(gl_context.GetGLContext());

  makeCurrent();

  //hideMouse();
}

MacWindow::~MacWindow() {
  if (window != NULL)
    DisposeWindow(window);

  showMouse();
  gl_context.Reset();
  displays.Release();
}

bool MacWindow::isValid() const { return true; }

void MacWindow::showWindow(bool show) {
  hideMouse();
}

void MacWindow::getPosition(int &x, int &y) { x = 0, y = 0; }

void MacWindow::getSize(int &width, int &height) const {

  width = CGDisplayPixelsWide(kCGDirectMainDisplay);
  height = CGDisplayPixelsHigh(kCGDirectMainDisplay);
}

void MacWindow::setTitle(const char *title) {}
void MacWindow::setPosition(int x, int y) {}
void MacWindow::setSize(int width, int height) {}

void MacWindow::setMinSize(int width, int height) {
#ifndef USE_DSP
  if (window == NULL) return;

  // Not sure what this wants, leave out for now.
  //CollapseWindow(window, true);
#endif
}

void MacWindow::setFullscreen() {} // do nothing for now
void MacWindow::warpMouse(int x, int y) {
  CGDisplayErr cgErr;
  CGPoint  mp;

  mp = CGPointMake(x,y);
  cgErr = CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, mp);
}

void MacWindow::getMouse(int &x, int &y) const {
  Point   tmpMouse;
  GrafPtr savedPort;

  GetPort(&savedPort);
  //SetPort(window);
  GetMouse(&tmpMouse);  // returns mouse location in coords of local
			  // window which must be set
  x = tmpMouse.h;
  y = tmpMouse.v;
  SetPort(savedPort);
}

void MacWindow::grabMouse() { gMouseGrabbed = true;  }
void MacWindow::ungrabMouse() { gMouseGrabbed = false; }
void MacWindow::showMouse() { ShowCursor(); }
void MacWindow::hideMouse() { HideCursor(); }

void MacWindow::setGamma(float)         {}
float MacWindow::getGamma()        const { return 0.0;   }
bool MacWindow::hasGammaControl() const { return false; }

void MacWindow::makeContext() {}
void MacWindow::freeContext() {}
void MacWindow::makeCurrent() {}

void MacWindow::swapBuffers() {
  gl_context.Flush();
}
// ex: shiftwidth=2 tabstop=8
<commit_msg>speed from rae<commit_after>#include <sys/time.h>

#include "MacWindow.h"

#ifdef __cplusplus
#  define EXTERN_C_BEGIN extern "C" {
#  define EXTERN_C_END   }
#endif

EXTERN_C_BEGIN
extern WindowRef GetWindowRefFromNativeWindow(void * nativeWindow);
EXTERN_C_END

struct Settings
{
  bool Use_Main_Display;
  bool Switch_Display;
  bool Capture_Display;
  CGSize Window_Size;
  long Display_Hz;
  bool VBL_Synch;
  int depth;

  Settings() {
    Use_Main_Display = true;
    Capture_Display = true;
    Switch_Display = true;
    Window_Size = CGSizeMake(CGDisplayPixelsWide(kCGDirectMainDisplay),
	CGDisplayPixelsHigh(kCGDirectMainDisplay));
    Display_Hz = 60;
    VBL_Synch = false; //CAPS-LOCK overrides
    depth = 24;
  }
} settings;

static double get_time()
{
  struct timeval tod;

  gettimeofday(&tod, NULL);

  return tod.tv_sec + tod.tv_usec * 1.0E-6;
}

#ifndef USE_DSP
  #define GLOBAL_OFFSET_X 0
  #define GLOBAL_OFFSET_Y 20
#else
  #define GLOBAL_OFFSET_X 0
  #define GLOBAL_OFFSET_Y 0
#endif

//Point gMousePosition;
bool gMouseGrabbed;

class GLContext
{
  const CGLPixelFormatAttribute* GetPixelFormat(u_int32_t display_id = 0x01,
      int color = settings.depth, int depth = 0, int stencil = 0) {
    static CGLPixelFormatAttribute attribs[32];

    CGLPixelFormatAttribute* attrib = attribs;

    *attrib++ = kCGLPFANoRecovery;
    *attrib++ = kCGLPFADoubleBuffer;
    *attrib++ = kCGLPFAAccelerated;
    *attrib++ = kCGLPFAFullScreen;
    *attrib++ = kCGLPFADisplayMask; *attrib++ = (CGLPixelFormatAttribute) display_id;
    *attrib++ = kCGLPFAColorSize; *attrib++ = (CGLPixelFormatAttribute) color;
    *attrib++ = kCGLPFADepthSize; *attrib++ = (CGLPixelFormatAttribute) depth;
    *attrib++ = kCGLPFAStencilSize; *attrib++ = (CGLPixelFormatAttribute) stencil;
    *attrib++ = (CGLPixelFormatAttribute) 0;

    return attribs;
  }

  public:

    CGRect bounds;
    CGLContextObj cgl_context;

    GLContext() {
      bounds = CGRectMake(0,0,0,0);
      cgl_context = NULL;
    }

    CGLContextObj GetGLContext(void) {
      return cgl_context;
    }

    bool Init(u_int32_t display_id, const CGRect& display_rect) {
      CGLPixelFormatObj pixel_format;
      long num_pixel_formats;

      CGLError err = CGLChoosePixelFormat(GetPixelFormat(display_id, 24),
	  &pixel_format, &num_pixel_formats);

      if (err || !pixel_format)
	return false;

      err = CGLCreateContext(pixel_format, NULL, &cgl_context);

      if (err)
	return false;

      CGLDestroyPixelFormat(pixel_format);
      pixel_format = NULL;

      err = CGLSetCurrentContext(cgl_context);

      if (err)
	return false;

      err = CGLSetFullScreen(cgl_context);

      if (err)
	return false;

      bounds = display_rect;

      if (settings.VBL_Synch)
	SetVBLSynch(true);

      return true;
    }

    void Reset() {
      if (cgl_context) {
	CGLSetCurrentContext(NULL);
	CGLClearDrawable(cgl_context);
	CGLDestroyContext(cgl_context);
	cgl_context = NULL;
      }
    }

    void SetPerspective(float angle, float near, float far) {
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();

      float aspect_ratio = bounds.size.width / bounds.size.height;

      gluPerspective(angle, aspect_ratio, near, far);
      glMatrixMode(GL_MODELVIEW);
    }

    void SetOrthographic() {
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();

      GLint params[4];
      glGetIntegerv(GL_VIEWPORT, params);
      gluOrtho2D(0, params[2], params[3], 0);

      glMatrixMode(GL_MODELVIEW);
    }

    void SetVBLSynch(bool synch) {
      long params[] = { synch ? 1 : 0 };
      CGLSetParameter(cgl_context, kCGLCPSwapInterval, params);

      settings.VBL_Synch = synch;
    }

    void Flush() {
      // glFinish(); CGLFlushDrawable says don't call glFinsh first
      if (cgl_context)
	CGLFlushDrawable(cgl_context);
    }

    void Process() {
      if (!cgl_context)
	return;

      static float t0 = get_time();

      float t = get_time() - t0;

      bool vbl_synch = false;

      if (settings.VBL_Synch != vbl_synch)
	SetVBLSynch(vbl_synch);

      float t1 = fabs(sin(t));

      glClearColor(0,0,0.1*t1,0);
      glClear(GL_COLOR_BUFFER_BIT);

      SetOrthographic();

      glPushMatrix();

      glTranslatef(bounds.size.width*0.5f-64.0,0,0);
      glTranslatef((bounds.size.width*0.5f-64.0-(1-0.435))*sin(t*3),0,0);

      glBegin(GL_QUADS);

      glColor3f(fabs(cos(t)),0,fabs(sin(t)));
      glVertex2f(0.0, 0.435);

      glColor3f(fabs(cos(t)),fabs(sin(t)),0);
      glVertex2f(0.0, bounds.size.height);

      glColor3f(0,fabs(cos(t)),fabs(sin(t)));
      glVertex2f(128.0, bounds.size.height);

      glColor3f(fabs(sin(t)),0,fabs(cos(t)));
      glVertex2f(128.0, 0.435);

      glEnd();

      GLfloat frame[4] = { 1,1,1,1};
      glColor4fv(frame);

      glBegin(GL_LINE_LOOP);

      glVertex2f(0.0, 0.435);

      glVertex2f(0.0, bounds.size.height);

      glVertex2f(128.0, bounds.size.height);

      glVertex2f(128.0, 0.435);

      glEnd();

      glPopMatrix();

      glFinish();

      CGLFlushDrawable(cgl_context);
    }
} gl_context;

long get_value(CFDictionaryRef values, CFStringRef key)
{
  CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(values, key);

  if (!number_value)
    return -1;

  long int_value;

  if (!CFNumberGetValue(number_value, kCFNumberLongType, &int_value))
    return -1;

  return int_value;
}

class DirectDisplay
{
  CGDisplayCount num_displays;
  CGDirectDisplayID* display_ids;

  void DumpDisplayModeValues(CFDictionaryRef values) {
  /*
    dprintf("   ----- Display Mode Info for %d -----\n", get_value(values, kCGDisplayMode));
    dprintf("   Bounds = %d x %d\n", get_value(values, kCGDisplayWidth), get_value(values, kCGDisplayHeight));
    dprintf("   bpp = %d, hz = %d\n", get_value(values, kCGDisplayBitsPerPixel), get_value(values,  kCGDisplayRefreshRate));
  */
  }

public:

  DirectDisplay() {
    num_displays = 0;
    display_ids = 0;
  }

  int Init() {
     if (CGGetActiveDisplayList(0, NULL, &num_displays) != CGDisplayNoErr || num_displays == 0)
      return 0;

    display_ids = new CGDirectDisplayID[num_displays];

    if (CGGetActiveDisplayList(num_displays, display_ids, &num_displays) != CGDisplayNoErr)
      return false;

    return num_displays;
  }

  CGRect GetDisplayBounds(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return CGRectMake(0,0,0,0);

    return CGDisplayBounds(display_ids[display_num]);
  }

  u_int32_t GetOpenGLDisplayID(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return 0;

    return CGDisplayIDToOpenGLDisplayMask(display_ids[display_num]);
  }

  CGDirectDisplayID GetDirectDisplayID(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return 0;

    return display_ids[display_num];
  }

  void DumpCurrentDisplayMode(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return;

    CFDictionaryRef display_mode_values = CGDisplayCurrentMode(display_ids[display_num]);

    DumpDisplayModeValues(display_mode_values);
  }

  void DumpDisplayModes(CGDisplayCount display_num) {
    if (display_num >= num_displays)
      return;

    CFArrayRef display_modes = CGDisplayAvailableModes(display_ids[display_num]);

    CFIndex num_modes = CFArrayGetCount(display_modes);
  }

  bool SetDisplayMode(CGDisplayCount display_num, const CGSize& size, size_t bpp, CGRefreshRate hz) {
    if (display_num >= num_displays)
      return false;

    CFDictionaryRef display_mode_values = CGDisplayBestModeForParametersAndRefreshRate(display_ids[display_num], bpp, (size_t) size.width, (size_t) size.height, hz, NULL);

    int display_hz = get_value(display_mode_values,  kCGDisplayRefreshRate);

    CGDisplayErr err = CGDisplaySwitchToMode(display_ids[display_num], display_mode_values);

    return err == CGDisplayNoErr;
  }

  bool Capture(CGDisplayCount display_num) {
    if (display_num >= num_displays || CGDisplayIsCaptured(display_ids[display_num]))
      return false;

    return CGDisplayCapture(display_ids[display_num]) == CGDisplayNoErr;
  }

  bool Release(CGDisplayCount display_num = 0) {
    if (display_num >= num_displays || !CGDisplayIsCaptured(display_ids[display_num]))
      return false;

    return CGDisplayRelease(display_ids[display_num]) == CGDisplayNoErr;
  }
} displays;

void Display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

MacWindow::MacWindow(const MacDisplay *display, MacVisual *visual) :
			BzfWindow(display)
{
  GLboolean ok;
  int argc = 0;
  char **argv = {NULL};

  int num_displays = displays.Init();

  if (num_displays == 0)
    return;

  int display_index = settings.Use_Main_Display ? 0 : num_displays-1;

  u_int32_t display_id = displays.GetOpenGLDisplayID(display_index);

  if (settings.Capture_Display)
    displays.Capture(display_index);

  if (settings.Switch_Display)
    if (displays.SetDisplayMode(display_index, settings.Window_Size, settings.depth, settings.Display_Hz))
      displays.DumpCurrentDisplayMode(display_index);

  CGRect window_rect = CGRectMake(0,0, settings.Window_Size.width, settings.Window_Size.height);

  if (!settings.Switch_Display)
    window_rect.origin = CGPointMake(32,32);

  if (!gl_context.Init(display_id, window_rect))
    return;

#ifdef USE_DSP
  display->setWindow(window);
#endif

  visual->reset();
  visual->setLevel(0);
  visual->setIndex(24);
  //visual->setDepth(24);
  visual->setDoubleBuffer(true);
  visual->setRGBA(1, 1, 1, 0);
  //visual->setStencil(1);

  //visual->addAttribute1(AGL_FULLSCREEN);

  visual->build();

  display->setContext(gl_context.GetGLContext());

  makeCurrent();

  //hideMouse();
}

MacWindow::~MacWindow() {
  if (window != NULL)
    DisposeWindow(window);

  showMouse();
  gl_context.Reset();
  displays.Release();
}

bool MacWindow::isValid() const { return true; }

void MacWindow::showWindow(bool show) {
  hideMouse();
}

void MacWindow::getPosition(int &x, int &y) { x = 0, y = 0; }

void MacWindow::getSize(int &width, int &height) const {

  width = CGDisplayPixelsWide(kCGDirectMainDisplay);
  height = CGDisplayPixelsHigh(kCGDirectMainDisplay);
}

void MacWindow::setTitle(const char *title) {}
void MacWindow::setPosition(int x, int y) {}
void MacWindow::setSize(int width, int height) {}

void MacWindow::setMinSize(int width, int height) {
#ifndef USE_DSP
  if (window == NULL) return;

  // Not sure what this wants, leave out for now.
  //CollapseWindow(window, true);
#endif
}

void MacWindow::setFullscreen() {} // do nothing for now
void MacWindow::warpMouse(int x, int y) {
  CGDisplayErr cgErr;
  CGPoint  mp;

  mp = CGPointMake(x,y);
  cgErr = CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, mp);
}

void MacWindow::getMouse(int &x, int &y) const {
  Point   tmpMouse;
  GrafPtr savedPort;

  GetPort(&savedPort);
  //SetPort(window);
  GetMouse(&tmpMouse);  // returns mouse location in coords of local
			  // window which must be set
  x = tmpMouse.h;
  y = tmpMouse.v;
  SetPort(savedPort);
}

void MacWindow::grabMouse() { gMouseGrabbed = true;  }
void MacWindow::ungrabMouse() { gMouseGrabbed = false; }
void MacWindow::showMouse() { ShowCursor(); }
void MacWindow::hideMouse() { HideCursor(); }

void MacWindow::setGamma(float)         {}
float MacWindow::getGamma()        const { return 0.0;   }
bool MacWindow::hasGammaControl() const { return false; }

void MacWindow::makeContext() {}
void MacWindow::freeContext() {}
void MacWindow::makeCurrent() {}

void MacWindow::swapBuffers() {
  gl_context.Flush();
}
// ex: shiftwidth=2 tabstop=8
<|endoftext|>