<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_pfet_control.C $  */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_pm_pfet_control.C
/// @brief Enable PFET devices to power on/off all enabled Core and Cache
/// chiplets in target passed.
///
//----------------------------------------------------------------------------
// *HWP HWP Owner       : Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner        : Sumit Kumar <sumit_kumar@in.ibm.com>
// *HWP Team            : PM
// *HWP Level           : 2
// *HWP Consumed by     : OCC:CME:FSP
//----------------------------------------------------------------------------
//
// @verbatim
// High-level procedure flow:
// PFET Control
// Power-on via Hardare FSM:
// ------------------------
// VDD first, VCS second
// Read PFETCNTLSTAT_REG and check for bits 0:3 being 0b0000.
// Write PFETCNTLSTAT_REG with values defined below
// -vdd_pfet_force_state = 11 (Force Von)
// -vdd_pfet_val_override = 0 (Override disabled)
// -vdd_pfet_sel_override = 0 (Override disabled)
// -vdd_pfet_enable_regulation_finger = 0 (Regulation finger controlled by FSM)
// Poll for PFETCNTLSTAT_REG[VDD_PG_STATE] for 0b1000 (FSM idle)-Timeout value = 1ms
// (Optional) Check PFETCNTLSTAT_REG[VDD_PG_SEL]being 0x8 (Off encode point)
// Write PFETCNTLSTAT_REG_WCLEAR
// -vdd_pfet_force_state = 00 (No Operation);all fields set to 1 for WAND
// Write PFETCNTLSTAT_REG_OR with values defined below
// -vcs_pfet_force_state = 11 (Force Von)
// Write to PFETCNTLSTAT_REG_CLR
// -vcs_pfet_val_override = 0 (Override disabled)
// -vcs_pfet_sel_override = 0 (Override disabled)
// Note there is no vcs_pfet_enable_regulation_finger
// Poll for PFETCNTLSTAT_REG[VCS_PG_STATE] for 0b1000 (FSM idle)-Timeout value = 1ms
// (Optional) Check PFETCNTLSTAT_REG[VCS_PG_SEL] being 0x8 (Off encode point)
// Write PFETCNTLSTAT_REG_WCLEAR
// -vcs_pfet_force_state = 00 (No Operation);all fields set to 1 for WAND
//
// Power-off via Hardare FSM:
// -------------------------
// VCS first, VDD second
// Read PFETCNTLSTAT_REG and check for bits 0:3 being 0b0000.
// Write PFETCNTLSTAT_REG with values defined below
// -vcs_pfet_force_state = 01 (Force Voff)
// -vcs_pfet_val_override = 0 (Override disabled)
// -vcs_pfet_sel_override = 0 (Override disabled)
// Note there is no vcs_pfet_enable_regulation_finger
// Poll for PFETCNTLSTAT_REG[VCS_PG_STATE] for 0b1000 (FSM idle)-Timeout value = 1ms
// (Optional) Check PFETCNTLSTAT_REG[VCS_PG_SEL]being 0x8 (Off encode point)
// Write PFETCNTLSTAT_REG_WCLEAR
// -vcs_pfet_force_state = 00 (No Operation);all fields set to 1 for WAND
// Write PFETCNTLSTAT_REG_OR with values defined below
// -vdd_pfet_force_state = 01 (Force Voff)
// Write to PFETCNTLSTAT_REG_CLR
// -vdd_pfet_val_override = 0 (Override disabled)
// -vdd_pfet_sel_override = 0 (Override disabled)
// -vdd_pfet_enable_regulation_finger = 0 (Regulation finger controlled by FSM)
// Poll for PFETCNTLSTAT_REG[VDD_PG_STATE] for 0b1000 (FSM idle)-Timeout value = 1ms
// (Optional) Check PFETCNTLSTAT_REG[VDD_PG_SEL] being 0x8 (Off encode point)
// Write PFETCNTLSTAT_REG_WCLEAR
// -vdd_pfet_force_state = 00 (No Operation);all fields set to 1 for WAND
//
// NOTE:
// For EQ supports: VDD,VCS,BOTH
// For EC & EX supports: VDD only. VCS returns an error. BOTH reports a warning that only VDD was controlled.
// EX target only powers OFF the two cores associated with that 'half' of the quad.
//
// Procedure Prereq:
//    - System clocks are running
//
// @endverbatim
//------------------------------------------------------------------------------

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------
#include <p9_common_poweronoff.H>
#include <p9_common_poweronoff.C>
#include <p9_pm_pfet_control.H>

//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Global variables
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Function definitions
//------------------------------------------------------------------------------

///
/// @brief Enable power on/off for core and cache chiplets
///
/// @param [in]  i_target          Target type Core/EQ/Ex chiplet
/// @param [in]  i_rail            Valid rail options:BOTH/VDD/VCS
/// @param [in]  i_op              Valid options:OFF/ON
///
/// @return FAPI2_RC_SUCCESS on success, error otherwise.
///
template <fapi2::TargetType K >
static fapi2::ReturnCode pfet_ctrl(
    const fapi2::Target< K >&  i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op);

// Procedure pfet control-EQ entry point, comments in header
fapi2::ReturnCode p9_pm_pfet_control_eq(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op)
{
    fapi2::current_err     = fapi2::FAPI2_RC_SUCCESS;
    uint32_t l_unit_pos     = 0;
    bool core_target_found = false;

    FAPI_INF("p9_pm_pfet_control_eq: Entering...");

    // Get chiplet position
    l_unit_pos = i_target.getChipletNumber();
    FAPI_INF("pfet control for EQ chiplet %d", l_unit_pos);

    // When i_op == OFF all functional cores first followed by EQ
    // When i_op == ON EQ first followed by all functional cores
    if(i_op == PM_PFET_TYPE_C::ON)
    {
        FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_EQ>(i_target,
                 i_rail, i_op), "Error: pfet_ctrl for eq!!");
    }

    // Check for all core chiplets in EQ and power on/off targets accordingly
    for (auto& l_core_target : i_target.getChildren<fapi2::TARGET_TYPE_CORE>
         (fapi2::TARGET_STATE_FUNCTIONAL))
    {
        l_unit_pos = l_core_target.getChipletNumber();
        FAPI_INF("Core chiplet %d in EQ", l_unit_pos);
        FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_CORE>(l_core_target,
                 i_rail, i_op), "Error: pfet_ctrl for core!!");
        core_target_found = true;
    }

    // Power on/off EQ target
    if( (i_op == PM_PFET_TYPE_C::OFF) && (core_target_found) )
    {
        FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_EQ>(i_target,
                 i_rail, i_op), "Error: pfet_ctrl for eq!!");
    }
    else if( ((i_op == PM_PFET_TYPE_C::ON) && !(core_target_found)) ||
             ((i_op == PM_PFET_TYPE_C::OFF) && !(core_target_found)) )
    {
        FAPI_INF("EQ chiplet no. %d; No core target found in functional state in this EQ\n", l_unit_pos);
    }

    FAPI_INF("p9_pm_pfet_control_eq: ...Exiting");

fapi_try_exit:
    return fapi2::current_err;
} //p9_pm_pfet_control_eq

// Procedure pfet control-EX entry point, comments in header
fapi2::ReturnCode p9_pm_pfet_control_ex(
    const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op)
{
    fapi2::current_err     = fapi2::FAPI2_RC_SUCCESS;
    uint32_t l_unit_pos     = 0;
    bool core_target_found = false;

    FAPI_INF("p9_pm_pfet_control_ex: Entering...");

    // Get chiplet position
    l_unit_pos = i_target.getChipletNumber();
    FAPI_INF("pfet control for EX chiplet %d", l_unit_pos);

    // Check for all core chiplets in EX and power on/off targets accordingly
    for (auto& l_core_target : i_target.getChildren<fapi2::TARGET_TYPE_CORE>
         (fapi2::TARGET_STATE_FUNCTIONAL))
    {
        l_unit_pos = l_core_target.getChipletNumber();
        FAPI_INF("Core chiplet %d in EX", l_unit_pos);
        FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_CORE>(l_core_target,
                 i_rail, i_op), "Error: pfet_ctrl for core!!");
        core_target_found = true;
    }

    // When no functional chiplet target found
    if(!core_target_found)
    {
        FAPI_INF("EX chiplet no. %d; No core target found in functional state in this EX\n", l_unit_pos);
    }

    FAPI_INF("p9_pm_pfet_control_ex: ...Exiting");

fapi_try_exit:
    return fapi2::current_err;
} //p9_pm_pfet_control_ex

// Procedure pfet control-Core entry point, comments in header
fapi2::ReturnCode p9_pm_pfet_control_ec(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op)
{
    fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;

    FAPI_INF("p9_pm_pfet_control_core: Entering...");

    FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_CORE>(i_target,
             i_rail, i_op), "Error: pfet_ctrl for core!!");

    FAPI_INF("p9_pm_pfet_control_core: ...Exiting");

fapi_try_exit:
    return fapi2::current_err;
} //p9_pm_pfet_control_ec

//------------------------------------------------------------------------------
// pfet_ctrl:
//  Function to power on/off core and cache chiplets
//------------------------------------------------------------------------------
template <fapi2::TargetType K >
fapi2::ReturnCode pfet_ctrl(
    const fapi2::Target< K >&  i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op)
{
    fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
    uint32_t l_unit_pos     = 0;

    FAPI_INF("pfet_ctrl: Entering...");

    // Get chiplet position
    l_unit_pos = i_target.getChipletNumber();

    // Check for target passed
    if(i_target.getType() & fapi2::TARGET_TYPE_CORE)
    {
        FAPI_INF("pfet control for Core chiplet %d", l_unit_pos);
    }
    else if(i_target.getType() & fapi2::TARGET_TYPE_EQ)
    {
        FAPI_INF("pfet control for EQ chiplet %d", l_unit_pos);
    }
    else
    {
        // Invalid chiplet selected
        FAPI_ASSERT(false,
                    fapi2::PFET_CTRL_INVALID_CHIPLET_ERROR()
                    .set_TARGET(i_target),
                    "ERROR: Invalid chiplet selected");
    }

    switch(i_op)
    {
        case PM_PFET_TYPE_C::OFF:
            switch(i_rail)
            {
                case PM_PFET_TYPE_C::BOTH:
                    if(i_target.getType() & fapi2::TARGET_TYPE_EQ)
                    {
                        FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_OFF));
                    }
                    else
                    {
                        FAPI_IMP("WARNING:Only VDD (not BOTH/VCS) is controlled for target Core & EX");
                        FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_OFF_VDD));
                    }

                    break;

                case PM_PFET_TYPE_C::VDD:
                    FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_OFF_VDD));
                    break;

                case PM_PFET_TYPE_C::VCS:
                    FAPI_IMP("WARNING:Only VDD or both VDD/VCS controlled for target Core/EX & Cache respectively");
                    break;
            }

            break;

        case PM_PFET_TYPE_C::ON:
            switch(i_rail)
            {
                case PM_PFET_TYPE_C::BOTH:
                    if(i_target.getType() & fapi2::TARGET_TYPE_EQ)
                    {
                        FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_ON));
                    }
                    else
                    {
                        FAPI_IMP("WARNING:Only VDD (not BOTH/VCS) is controlled for target Core & EX");
                        FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_ON_VDD));
                    }

                    break;

                case PM_PFET_TYPE_C::VDD:
                    FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_ON_VDD));
                    break;

                case PM_PFET_TYPE_C::VCS:
                    FAPI_IMP("WARNING:Only VDD or both VDD/VCS controlled for target Core/EX & Cache respectively");
                    break;
            }

            break;
    }

fapi_try_exit:
    return fapi2::current_err;
}

<commit_msg>Solve compilation issues when FAPI_INF is disabled<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_pfet_control.C $  */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_pm_pfet_control.C
/// @brief Enable PFET devices to power on/off all enabled Core and Cache
/// chiplets in target passed.
///
//----------------------------------------------------------------------------
// *HWP HWP Owner       : Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner        : Sumit Kumar <sumit_kumar@in.ibm.com>
// *HWP Team            : PM
// *HWP Level           : 2
// *HWP Consumed by     : OCC:CME:FSP
//----------------------------------------------------------------------------
//
// @verbatim
// High-level procedure flow:
// PFET Control
// Power-on via Hardare FSM:
// ------------------------
// VDD first, VCS second
// Read PFETCNTLSTAT_REG and check for bits 0:3 being 0b0000.
// Write PFETCNTLSTAT_REG with values defined below
// -vdd_pfet_force_state = 11 (Force Von)
// -vdd_pfet_val_override = 0 (Override disabled)
// -vdd_pfet_sel_override = 0 (Override disabled)
// -vdd_pfet_enable_regulation_finger = 0 (Regulation finger controlled by FSM)
// Poll for PFETCNTLSTAT_REG[VDD_PG_STATE] for 0b1000 (FSM idle)-Timeout value = 1ms
// (Optional) Check PFETCNTLSTAT_REG[VDD_PG_SEL]being 0x8 (Off encode point)
// Write PFETCNTLSTAT_REG_WCLEAR
// -vdd_pfet_force_state = 00 (No Operation);all fields set to 1 for WAND
// Write PFETCNTLSTAT_REG_OR with values defined below
// -vcs_pfet_force_state = 11 (Force Von)
// Write to PFETCNTLSTAT_REG_CLR
// -vcs_pfet_val_override = 0 (Override disabled)
// -vcs_pfet_sel_override = 0 (Override disabled)
// Note there is no vcs_pfet_enable_regulation_finger
// Poll for PFETCNTLSTAT_REG[VCS_PG_STATE] for 0b1000 (FSM idle)-Timeout value = 1ms
// (Optional) Check PFETCNTLSTAT_REG[VCS_PG_SEL] being 0x8 (Off encode point)
// Write PFETCNTLSTAT_REG_WCLEAR
// -vcs_pfet_force_state = 00 (No Operation);all fields set to 1 for WAND
//
// Power-off via Hardare FSM:
// -------------------------
// VCS first, VDD second
// Read PFETCNTLSTAT_REG and check for bits 0:3 being 0b0000.
// Write PFETCNTLSTAT_REG with values defined below
// -vcs_pfet_force_state = 01 (Force Voff)
// -vcs_pfet_val_override = 0 (Override disabled)
// -vcs_pfet_sel_override = 0 (Override disabled)
// Note there is no vcs_pfet_enable_regulation_finger
// Poll for PFETCNTLSTAT_REG[VCS_PG_STATE] for 0b1000 (FSM idle)-Timeout value = 1ms
// (Optional) Check PFETCNTLSTAT_REG[VCS_PG_SEL]being 0x8 (Off encode point)
// Write PFETCNTLSTAT_REG_WCLEAR
// -vcs_pfet_force_state = 00 (No Operation);all fields set to 1 for WAND
// Write PFETCNTLSTAT_REG_OR with values defined below
// -vdd_pfet_force_state = 01 (Force Voff)
// Write to PFETCNTLSTAT_REG_CLR
// -vdd_pfet_val_override = 0 (Override disabled)
// -vdd_pfet_sel_override = 0 (Override disabled)
// -vdd_pfet_enable_regulation_finger = 0 (Regulation finger controlled by FSM)
// Poll for PFETCNTLSTAT_REG[VDD_PG_STATE] for 0b1000 (FSM idle)-Timeout value = 1ms
// (Optional) Check PFETCNTLSTAT_REG[VDD_PG_SEL] being 0x8 (Off encode point)
// Write PFETCNTLSTAT_REG_WCLEAR
// -vdd_pfet_force_state = 00 (No Operation);all fields set to 1 for WAND
//
// NOTE:
// For EQ supports: VDD,VCS,BOTH
// For EC & EX supports: VDD only. VCS returns an error. BOTH reports a warning that only VDD was controlled.
// EX target only powers OFF the two cores associated with that 'half' of the quad.
//
// Procedure Prereq:
//    - System clocks are running
//
// @endverbatim
//------------------------------------------------------------------------------

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------
#include <p9_common_poweronoff.H>
#include <p9_common_poweronoff.C>
#include <p9_pm_pfet_control.H>

//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Global variables
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Function definitions
//------------------------------------------------------------------------------

///
/// @brief Enable power on/off for core and cache chiplets
///
/// @param [in]  i_target          Target type Core/EQ/Ex chiplet
/// @param [in]  i_rail            Valid rail options:BOTH/VDD/VCS
/// @param [in]  i_op              Valid options:OFF/ON
///
/// @return FAPI2_RC_SUCCESS on success, error otherwise.
///
template <fapi2::TargetType K >
static fapi2::ReturnCode pfet_ctrl(
    const fapi2::Target< K >&  i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op);

// Procedure pfet control-EQ entry point, comments in header
fapi2::ReturnCode p9_pm_pfet_control_eq(
    const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op)
{
    fapi2::current_err     = fapi2::FAPI2_RC_SUCCESS;
    bool core_target_found = false;

    FAPI_INF("p9_pm_pfet_control_eq: Entering...");

    // Print chiplet position
    FAPI_INF("pfet control for EQ chiplet %d", i_target.getChipletNumber());

    // When i_op == OFF all functional cores first followed by EQ
    // When i_op == ON EQ first followed by all functional cores
    if(i_op == PM_PFET_TYPE_C::ON)
    {
        FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_EQ>(i_target,
                 i_rail, i_op), "Error: pfet_ctrl for eq!!");
    }

    // Check for all core chiplets in EQ and power on/off targets accordingly
    for (auto& l_core_target : i_target.getChildren<fapi2::TARGET_TYPE_CORE>
         (fapi2::TARGET_STATE_FUNCTIONAL))
    {
        FAPI_INF("Core chiplet %d in EQ", l_core_target.getChipletNumber());
        FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_CORE>(l_core_target,
                 i_rail, i_op), "Error: pfet_ctrl for core!!");
        core_target_found = true;
    }

    // Power on/off EQ target
    if( (i_op == PM_PFET_TYPE_C::OFF) && (core_target_found) )
    {
        FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_EQ>(i_target,
                 i_rail, i_op), "Error: pfet_ctrl for eq!!");
    }
    else if( ((i_op == PM_PFET_TYPE_C::ON) && !(core_target_found)) ||
             ((i_op == PM_PFET_TYPE_C::OFF) && !(core_target_found)) )
    {
        FAPI_INF("EQ chiplet no. %d; No core target found in functional state in this EQ\n", i_target.getChipletNumber());
    }

    FAPI_INF("p9_pm_pfet_control_eq: ...Exiting");

fapi_try_exit:
    return fapi2::current_err;
} //p9_pm_pfet_control_eq

// Procedure pfet control-EX entry point, comments in header
fapi2::ReturnCode p9_pm_pfet_control_ex(
    const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op)
{
    fapi2::current_err     = fapi2::FAPI2_RC_SUCCESS;
    bool core_target_found = false;

    FAPI_INF("p9_pm_pfet_control_ex: Entering...");

    // Get chiplet position
    FAPI_INF("pfet control for EX chiplet %d", i_target.getChipletNumber());

    // Check for all core chiplets in EX and power on/off targets accordingly
    for (auto& l_core_target : i_target.getChildren<fapi2::TARGET_TYPE_CORE>
         (fapi2::TARGET_STATE_FUNCTIONAL))
    {
        FAPI_INF("Core chiplet %d in EX", l_core_target.getChipletNumber());
        FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_CORE>(l_core_target,
                 i_rail, i_op), "Error: pfet_ctrl for core!!");
        core_target_found = true;
    }

    // When no functional chiplet target found
    if(!core_target_found)
    {
        FAPI_INF("EX chiplet no. %d; No core target found in functional state"
                 " in this EX", i_target.getChipletNumber());
    }

    FAPI_INF("p9_pm_pfet_control_ex: ...Exiting");

fapi_try_exit:
    return fapi2::current_err;
} //p9_pm_pfet_control_ex

// Procedure pfet control-Core entry point, comments in header
fapi2::ReturnCode p9_pm_pfet_control_ec(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op)
{
    fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;

    FAPI_INF("p9_pm_pfet_control_core: Entering...");

    FAPI_TRY(pfet_ctrl<fapi2::TargetType::TARGET_TYPE_CORE>(i_target,
             i_rail, i_op), "Error: pfet_ctrl for core!!");

    FAPI_INF("p9_pm_pfet_control_core: ...Exiting");

fapi_try_exit:
    return fapi2::current_err;
} //p9_pm_pfet_control_ec

//------------------------------------------------------------------------------
// pfet_ctrl:
//  Function to power on/off core and cache chiplets
//------------------------------------------------------------------------------
template <fapi2::TargetType K >
fapi2::ReturnCode pfet_ctrl(
    const fapi2::Target< K >&  i_target,
    const PM_PFET_TYPE_C::pfet_rail_t  i_rail,
    const PM_PFET_TYPE_C::pfet_force_t i_op)
{
    fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;

    FAPI_INF("pfet_ctrl: Entering...");

    // Check for target passed
    if(i_target.getType() & fapi2::TARGET_TYPE_CORE)
    {
        FAPI_INF("pfet control for Core chiplet %d",
                 i_target.getChipletNumber());
    }
    else if(i_target.getType() & fapi2::TARGET_TYPE_EQ)
    {
        FAPI_INF("pfet control for EQ chiplet %d", i_target.getChipletNumber());
    }
    else
    {
        // Invalid chiplet selected
        FAPI_ASSERT(false,
                    fapi2::PFET_CTRL_INVALID_CHIPLET_ERROR()
                    .set_TARGET(i_target),
                    "ERROR: Invalid chiplet selected");
    }

    switch(i_op)
    {
        case PM_PFET_TYPE_C::OFF:
            switch(i_rail)
            {
                case PM_PFET_TYPE_C::BOTH:
                    if(i_target.getType() & fapi2::TARGET_TYPE_EQ)
                    {
                        FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_OFF));
                    }
                    else
                    {
                        FAPI_IMP("WARNING:Only VDD (not BOTH/VCS) is controlled for target Core & EX");
                        FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_OFF_VDD));
                    }

                    break;

                case PM_PFET_TYPE_C::VDD:
                    FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_OFF_VDD));
                    break;

                case PM_PFET_TYPE_C::VCS:
                    FAPI_IMP("WARNING:Only VDD or both VDD/VCS controlled for target Core/EX & Cache respectively");
                    break;
            }

            break;

        case PM_PFET_TYPE_C::ON:
            switch(i_rail)
            {
                case PM_PFET_TYPE_C::BOTH:
                    if(i_target.getType() & fapi2::TARGET_TYPE_EQ)
                    {
                        FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_ON));
                    }
                    else
                    {
                        FAPI_IMP("WARNING:Only VDD (not BOTH/VCS) is controlled for target Core & EX");
                        FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_ON_VDD));
                    }

                    break;

                case PM_PFET_TYPE_C::VDD:
                    FAPI_TRY(p9_common_poweronoff(i_target, p9power::POWER_ON_VDD));
                    break;

                case PM_PFET_TYPE_C::VCS:
                    FAPI_IMP("WARNING:Only VDD or both VDD/VCS controlled for target Core/EX & Cache respectively");
                    break;
            }

            break;
    }

fapi_try_exit:
    return fapi2::current_err;
}

<|endoftext|>


<commit_before>/*
    This file is part of Akregator.

    Copyright (C) 2008 Frank Osterfeld <osterfeld@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "createfeedcommand.h"

#include "addfeeddialog.h"
#include "feed.h"
#include "feedpropertiesdialog.h"
#include "folder.h"
#include "subscriptionlistview.h"

#include <KInputDialog>
#include <KLocalizedString>
#include <KUrl>

#include <QPointer>
#include <QTimer>

#include <cassert>

using namespace Akregator;

class CreateFeedCommand::Private
{
    CreateFeedCommand* const q;
public:
    explicit Private( CreateFeedCommand* qq );

    void doCreate();

    QPointer<Folder> m_rootFolder;
    QPointer<SubscriptionListView> m_subscriptionListView;
    QString m_url;
    QPointer<Folder> m_parentFolder;
    QPointer<TreeNode> m_after;
    bool m_autoexec;
};

CreateFeedCommand::Private::Private( CreateFeedCommand* qq )
  : q( qq ),
    m_rootFolder( 0 ),
    m_subscriptionListView( 0 ),
    m_parentFolder( 0 ),
    m_after( 0 ),
    m_autoexec( false )
{

}

void CreateFeedCommand::Private::doCreate()
{
    assert( m_rootFolder );
    assert( m_subscriptionListView );

    QPointer<AddFeedDialog> afd = new AddFeedDialog( q->parentWidget(), "add_feed" );

    afd->setUrl( KUrl::fromPercentEncoding( m_url.toLatin1() ) );

    QPointer<QObject> thisPointer( q );

    if ( m_autoexec )
        afd->accept();
    else
        afd->exec();

    if ( !thisPointer ) // "this" might have been deleted while exec()!
        return;

    Feed* const feed = afd->feed();
    delete afd;

    if ( !feed )
    {
        q->done();
        return;
    }

    QPointer<FeedPropertiesDialog> dlg = new FeedPropertiesDialog( q->parentWidget(), "edit_feed" );
    dlg->setFeed( feed );
    dlg->selectFeedName();

    if ( !m_autoexec && ( dlg->exec() != QDialog::Accepted || !thisPointer ) )
    {
        delete feed;
    }
    else
    {
        m_parentFolder = m_parentFolder ? m_parentFolder : m_rootFolder;
        m_parentFolder->insertChild( feed, m_after );
        m_subscriptionListView->ensureNodeVisible( feed );
    }

    delete dlg;
    q->done();
}

CreateFeedCommand::CreateFeedCommand( QObject* parent ) : Command( parent ), d( new Private( this ) )
{

}

CreateFeedCommand::~CreateFeedCommand()
{
    delete d;
}

void CreateFeedCommand::setSubscriptionListView( SubscriptionListView* view )
{
    d->m_subscriptionListView = view;
}

void CreateFeedCommand::setRootFolder( Folder* rootFolder )
{
    d->m_rootFolder = rootFolder;
}

void CreateFeedCommand::setUrl( const QString& url )
{
    d->m_url = url;
}

void CreateFeedCommand::setPosition( Folder* parent, TreeNode* after )
{
    d->m_parentFolder = parent;
    d->m_after = after;
}

void CreateFeedCommand::setAutoExecute( bool autoexec )
{
    d->m_autoexec = autoexec;
}

void CreateFeedCommand::doStart()
{
    QTimer::singleShot( 0, this, SLOT( doCreate() ) );
}

void CreateFeedCommand::doAbort()
{

}

#include "createfeedcommand.moc"
<commit_msg>Paste clipboard contents in add feed dlg if it is a valid URL Patch by Jordi De Groof, jordi.degroof at gmail.com BUG:111214<commit_after>/*
    This file is part of Akregator.

    Copyright (C) 2008 Frank Osterfeld <osterfeld@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "createfeedcommand.h"

#include "addfeeddialog.h"
#include "feed.h"
#include "feedpropertiesdialog.h"
#include "folder.h"
#include "subscriptionlistview.h"

#include <KInputDialog>
#include <KLocalizedString>
#include <KUrl>

#include <QPointer>
#include <QTimer>
#include <QClipboard>

#include <cassert>

using namespace Akregator;

class CreateFeedCommand::Private
{
    CreateFeedCommand* const q;
public:
    explicit Private( CreateFeedCommand* qq );

    void doCreate();

    QPointer<Folder> m_rootFolder;
    QPointer<SubscriptionListView> m_subscriptionListView;
    QString m_url;
    QPointer<Folder> m_parentFolder;
    QPointer<TreeNode> m_after;
    bool m_autoexec;
};

CreateFeedCommand::Private::Private( CreateFeedCommand* qq )
  : q( qq ),
    m_rootFolder( 0 ),
    m_subscriptionListView( 0 ),
    m_parentFolder( 0 ),
    m_after( 0 ),
    m_autoexec( false )
{

}

void CreateFeedCommand::Private::doCreate()
{
    assert( m_rootFolder );
    assert( m_subscriptionListView );

    QPointer<AddFeedDialog> afd = new AddFeedDialog( q->parentWidget(), "add_feed" );

    QString url = m_url;

    if( url.isEmpty() )
    {
        const QClipboard* const clipboard = QApplication::clipboard();
        assert( clipboard );
        const QString clipboardText = clipboard->text();
        // Check for the hostname, since the isValid method is not strict enough
        if( !KUrl( clipboardText ).isEmpty() )
            url = clipboardText;
    }

    afd->setUrl( KUrl::fromPercentEncoding( url.toLatin1() ) );

    QPointer<QObject> thisPointer( q );

    if ( m_autoexec )
        afd->accept();
    else
        afd->exec();

    if ( !thisPointer ) // "this" might have been deleted while exec()!
        return;

    Feed* const feed = afd->feed();
    delete afd;

    if ( !feed )
    {
        q->done();
        return;
    }

    QPointer<FeedPropertiesDialog> dlg = new FeedPropertiesDialog( q->parentWidget(), "edit_feed" );
    dlg->setFeed( feed );
    dlg->selectFeedName();

    if ( !m_autoexec && ( dlg->exec() != QDialog::Accepted || !thisPointer ) )
    {
        delete feed;
    }
    else
    {
        m_parentFolder = m_parentFolder ? m_parentFolder : m_rootFolder;
        m_parentFolder->insertChild( feed, m_after );
        m_subscriptionListView->ensureNodeVisible( feed );
    }

    delete dlg;
    q->done();
}

CreateFeedCommand::CreateFeedCommand( QObject* parent ) : Command( parent ), d( new Private( this ) )
{

}

CreateFeedCommand::~CreateFeedCommand()
{
    delete d;
}

void CreateFeedCommand::setSubscriptionListView( SubscriptionListView* view )
{
    d->m_subscriptionListView = view;
}

void CreateFeedCommand::setRootFolder( Folder* rootFolder )
{
    d->m_rootFolder = rootFolder;
}

void CreateFeedCommand::setUrl( const QString& url )
{
    d->m_url = url;
}

void CreateFeedCommand::setPosition( Folder* parent, TreeNode* after )
{
    d->m_parentFolder = parent;
    d->m_after = after;
}

void CreateFeedCommand::setAutoExecute( bool autoexec )
{
    d->m_autoexec = autoexec;
}

void CreateFeedCommand::doStart()
{
    QTimer::singleShot( 0, this, SLOT( doCreate() ) );
}

void CreateFeedCommand::doAbort()
{

}

#include "createfeedcommand.moc"
<|endoftext|>


<commit_before>#include "akregatorconfig.h"
#include "settings_advanced.h"
#include "storagefactory.h"
#include "storagefactoryregistry.h"

#include <QPushButton>
#include <QStringList>
#include <QWidget>

#include <kcombobox.h>

namespace Akregator {

SettingsAdvanced::SettingsAdvanced(QWidget* parent, const char* name) : QWidget(parent)
{
    setObjectName(name);
    setupUi(this);

    QStringList backends = Backend::StorageFactoryRegistry::self()->list();
    QString tname;
    int i = 0;
    QStringList::Iterator end( backends.end() );
    for (QStringList::Iterator it = backends.begin(); it != end; ++it)
    {
        m_factories[i] = Backend::StorageFactoryRegistry::self()->getFactory(*it);
        m_keyPos[m_factories[i]->key()] = i;
        cbBackend->addItem(m_factories[i]->name());
        i++;
    }
    connect(pbBackendConfigure, SIGNAL(clicked()), this, SLOT(slotConfigureStorage()));
    connect(cbBackend, SIGNAL(activated(int)), this, SLOT(slotFactorySelected(int)));
}

QString SettingsAdvanced::selectedFactory() const
{
    return m_factories[cbBackend->currentIndex()]->key();
}

void SettingsAdvanced::selectFactory(const QString& key)
{
    cbBackend->setCurrentIndex(m_keyPos[key]);
    pbBackendConfigure->setEnabled((m_factories[m_keyPos[key]]->isConfigurable()));
}

void SettingsAdvanced::slotConfigureStorage()
{
    m_factories[cbBackend->currentIndex()]->configure();
}

void SettingsAdvanced::slotFactorySelected(int pos)
{
    pbBackendConfigure->setEnabled(m_factories[pos]->isConfigurable());
}

} //namespace Akregator
#include "settings_advanced.moc"
<commit_msg>Fix crash when backend doesn't exist<commit_after>#include "akregatorconfig.h"
#include "settings_advanced.h"
#include "storagefactory.h"
#include "storagefactoryregistry.h"

#include <QPushButton>
#include <QStringList>
#include <QWidget>

#include <kcombobox.h>

namespace Akregator {

SettingsAdvanced::SettingsAdvanced(QWidget* parent, const char* name) : QWidget(parent)
{
    setObjectName(name);
    setupUi(this);

    QStringList backends = Backend::StorageFactoryRegistry::self()->list();
    QString tname;
    int i = 0;
    QStringList::Iterator end( backends.end() );
    for (QStringList::Iterator it = backends.begin(); it != end; ++it)
    {
        m_factories[i] = Backend::StorageFactoryRegistry::self()->getFactory(*it);
	if(m_factories[i])
	{
          m_keyPos[m_factories[i]->key()] = i;
          cbBackend->addItem(m_factories[i]->name());
	}
        i++;
    }
    connect(pbBackendConfigure, SIGNAL(clicked()), this, SLOT(slotConfigureStorage()));
    connect(cbBackend, SIGNAL(activated(int)), this, SLOT(slotFactorySelected(int)));
}

QString SettingsAdvanced::selectedFactory() const
{
    return m_factories[cbBackend->currentIndex()]->key();
}

void SettingsAdvanced::selectFactory(const QString& key)
{
    cbBackend->setCurrentIndex(m_keyPos[key]);
    pbBackendConfigure->setEnabled((m_factories[m_keyPos[key]]->isConfigurable()));
}

void SettingsAdvanced::slotConfigureStorage()
{
    m_factories[cbBackend->currentIndex()]->configure();
}

void SettingsAdvanced::slotFactorySelected(int pos)
{
    pbBackendConfigure->setEnabled(m_factories[pos]->isConfigurable());
}

} //namespace Akregator
#include "settings_advanced.moc"
<|endoftext|>


<commit_before>#ifndef ENUMERABLE__H__
#define ENUMERABLE__H__

#include "iterbase.hpp"

#include <utility>
#include <iterator>
#include <functional>
#include <initializer_list>

// enumerate functionality for python-style for-each enumerate loops
// for (auto e : enumerate(vec)) {
//     std::cout << e.index
//               << ": "
//               << e.element
//               << '\n';
// }

namespace iter {

    //Forward declarations of Enumerable and enumerate
    template <typename Container>
    class Enumerable;

    template <typename T>
    Enumerable<std::initializer_list<T>> enumerate(
            std::initializer_list<T> &&);

    template <typename Container>
    Enumerable<Container> enumerate(Container &&);

    template <typename Container>
    class Enumerable {
        private:
            Container & container;

            // The only thing allowed to directly instantiate an Enumerable is
            // the enumerate function
            friend Enumerable enumerate<Container>(Container &&);
            template <typename T>
            friend Enumerable<std::initializer_list<T>> enumerate(
                    std::initializer_list<T> &&);

            using IterDef = IterBase<Container>;

            Enumerable(Container && container) : container(container) { }

        public:
            // Value constructor for use only in the enumerate function
            Enumerable () = delete;
            Enumerable & operator=(const Enumerable &) = delete;

            Enumerable(const Enumerable &) = default;

            // "yielded" by the Enumerable::Iterator.  Has a .index, and a
            // .element referencing the value yielded by the subiterator
            class IterYield {
                public:
                    std::size_t index;
                    typename IterDef::contained_iter_ret element;
                    IterYield(std::size_t i, typename IterDef::contained_iter_ret elem):
                        index(i),
                        element(elem)
                    { }
            };

            //  Holds an iterator of the contained type and a size_t for the
            //  index.  Each call to ++ increments both of these data members.
            //  Each dereference returns an IterYield.
            class Iterator {
                private:
                    typename IterDef::contained_iter_type sub_iter;
                    std::size_t index;
                public:
                    Iterator (typename IterDef::contained_iter_type si) :
                        sub_iter(si),
                        index(0) { }

                    IterYield operator*() const {
                        return IterYield(this->index, *this->sub_iter);
                    }

                    Iterator & operator++() {
                        ++this->sub_iter;
                        ++this->index;
                        return *this;
                    }

                    bool operator!=(const Iterator & other) const {
                        return this->sub_iter != other.sub_iter;
                    }
            };

            Iterator begin() const {
                return Iterator(std::begin(this->container));
            }

            Iterator end() const {
                return Iterator(std::end(this->container));
            }

    };

    // Helper function to instantiate an Enumerable
    template <typename Container>
    Enumerable<Container> enumerate(Container && container) {
        return Enumerable<Container>(std::forward<Container>(container));
    }

    template <typename T>
    Enumerable<std::initializer_list<T>> enumerate(std::initializer_list<T> && il)
    {
        return Enumerable<std::initializer_list<T>>(std::move(il));
    }

}

#endif //ifndef ENUMERABLE__H__
<commit_msg>flattens with explicit using<commit_after>#ifndef ENUMERABLE__H__
#define ENUMERABLE__H__

#include "iterbase.hpp"

#include <utility>
#include <iterator>
#include <functional>
#include <initializer_list>

// enumerate functionality for python-style for-each enumerate loops
// for (auto e : enumerate(vec)) {
//     std::cout << e.index
//               << ": "
//               << e.element
//               << '\n';
// }

namespace iter {

    //Forward declarations of Enumerable and enumerate
    template <typename Container>
    class Enumerable;

    template <typename T>
    Enumerable<std::initializer_list<T>> enumerate(
            std::initializer_list<T> &&);

    template <typename Container>
    Enumerable<Container> enumerate(Container &&);

    template <typename Container>
    class Enumerable {
        private:
            Container & container;

            // The only thing allowed to directly instantiate an Enumerable is
            // the enumerate function
            friend Enumerable enumerate<Container>(Container &&);
            template <typename T>
            friend Enumerable<std::initializer_list<T>> enumerate(
                    std::initializer_list<T> &&);

            using contained_iter_ret =
                typename IterBase<Container>::contained_iter_ret;
            using contained_iter_type =
                typename IterBase<Container>::contained_iter_type;

            Enumerable(Container && container) : container(container) { }

        public:
            // Value constructor for use only in the enumerate function
            Enumerable () = delete;
            Enumerable & operator=(const Enumerable &) = delete;

            Enumerable(const Enumerable &) = default;

            // "yielded" by the Enumerable::Iterator.  Has a .index, and a
            // .element referencing the value yielded by the subiterator
            class IterYield {
                public:
                    std::size_t index;
                    contained_iter_ret element;
                    IterYield(std::size_t i, contained_iter_ret elem):
                        index(i),
                        element(elem)
                    { }
            };

            //  Holds an iterator of the contained type and a size_t for the
            //  index.  Each call to ++ increments both of these data members.
            //  Each dereference returns an IterYield.
            class Iterator {
                private:
                    contained_iter_type sub_iter;
                    std::size_t index;
                public:
                    Iterator (contained_iter_type si) :
                        sub_iter(si),
                        index(0) { }

                    IterYield operator*() const {
                        return IterYield(this->index, *this->sub_iter);
                    }

                    Iterator & operator++() {
                        ++this->sub_iter;
                        ++this->index;
                        return *this;
                    }

                    bool operator!=(const Iterator & other) const {
                        return this->sub_iter != other.sub_iter;
                    }
            };

            Iterator begin() const {
                return Iterator(std::begin(this->container));
            }

            Iterator end() const {
                return Iterator(std::end(this->container));
            }

    };

    // Helper function to instantiate an Enumerable
    template <typename Container>
    Enumerable<Container> enumerate(Container && container) {
        return Enumerable<Container>(std::forward<Container>(container));
    }

    template <typename T>
    Enumerable<std::initializer_list<T>> enumerate(std::initializer_list<T> && il)
    {
        return Enumerable<std::initializer_list<T>>(std::move(il));
    }

}

#endif //ifndef ENUMERABLE__H__
<|endoftext|>


<commit_before>#include <iostream>

void distinct_permute(

int main() {

}
<commit_msg>combinatorics: Removed all distinct permutation generator - missing implementation.<commit_after><|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include <mapnik/debug.hpp>
#include <mapnik/image_reader.hpp>
#include <mapnik/noncopyable.hpp>

extern "C"
{
#include <png.h>
}

#include <boost/scoped_array.hpp>

namespace mapnik
{
class png_reader : public image_reader, mapnik::noncopyable
{
private:
    std::string fileName_;
    unsigned width_;
    unsigned height_;
    int bit_depth_;
    int color_type_;
public:
    explicit png_reader(std::string const& fileName);
    ~png_reader();
    unsigned width() const;
    unsigned height() const;
    bool premultiplied_alpha() const { return false; } //http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html
    void read(unsigned x,unsigned y,image_data_32& image);
private:
    void init();
};

namespace
{
image_reader* create_png_reader(std::string const& file)
{
    return new png_reader(file);
}
const bool registered = register_image_reader("png",create_png_reader);
}

png_reader::png_reader(std::string const& fileName)
    : fileName_(fileName),
      width_(0),
      height_(0),
      bit_depth_(0),
      color_type_(0)
{
    init();
}

png_reader::~png_reader() {}

void user_error_fn(png_structp png_ptr, png_const_charp error_msg)
{
    throw image_reader_exception("failed to read invalid png");
}

void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg)
{
    MAPNIK_LOG_DEBUG(png_reader) << "libpng warning: '" << warning_msg << "'";
}

static void
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
    png_size_t check;
    check = (png_size_t)fread(data, (png_size_t)1, length,
                              (FILE *)png_get_io_ptr(png_ptr));

    if (check != length)
    {
        png_error(png_ptr, "Read Error");
    }
}

void png_reader::init()
{
    FILE *fp=fopen(fileName_.c_str(),"rb");
    if (!fp) throw image_reader_exception("cannot open image file "+fileName_);
    png_byte header[8];
    memset(header,0,8);
    if ( fread(header,1,8,fp) != 8)
    {
        fclose(fp);
        throw image_reader_exception("Could not read " + fileName_);
    }
    int is_png=!png_sig_cmp(header,0,8);
    if (!is_png)
    {
        fclose(fp);
        throw image_reader_exception(fileName_ + " is not a png file");
    }
    png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING,0,0,0);

    if (!png_ptr)
    {
        fclose(fp);
        throw image_reader_exception("failed to allocate png_ptr");
    }

    // catch errors in a custom way to avoid the need for setjmp
    png_set_error_fn(png_ptr, png_get_error_ptr(png_ptr), user_error_fn, user_warning_fn);

    png_infop info_ptr;
    try
    {
        info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr)
        {
            png_destroy_read_struct(&png_ptr,0,0);
            fclose(fp);
            throw image_reader_exception("failed to create info_ptr");
        }
    }
    catch (std::exception const& ex)
    {
        png_destroy_read_struct(&png_ptr,0,0);
        fclose(fp);
        throw;
    }

    png_set_read_fn(png_ptr, (png_voidp)fp, png_read_data);

    png_set_sig_bytes(png_ptr,8);
    png_read_info(png_ptr, info_ptr);

    png_uint_32  width, height;
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth_, &color_type_,0,0,0);

    width_=width;
    height_=height;

    MAPNIK_LOG_DEBUG(png_reader) << "png_reader: bit_depth=" << bit_depth_ << ",color_type=" << color_type_;

    png_destroy_read_struct(&png_ptr,&info_ptr,0);
    fclose(fp);
}

unsigned png_reader::width() const
{
    return width_;
}

unsigned png_reader::height() const
{
    return height_;
}

void png_reader::read(unsigned x0, unsigned y0,image_data_32& image)
{
    FILE *fp=fopen(fileName_.c_str(),"rb");
    if (!fp) throw image_reader_exception("cannot open image file "+fileName_);

    png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING,0,0,0);

    if (!png_ptr)
    {
        fclose(fp);
        throw image_reader_exception("failed to allocate png_ptr");
    }

    // catch errors in a custom way to avoid the need for setjmp
    png_set_error_fn(png_ptr, png_get_error_ptr(png_ptr), user_error_fn, user_warning_fn);

    png_infop info_ptr;
    try
    {
        info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr)
        {
            png_destroy_read_struct(&png_ptr,0,0);
            fclose(fp);
            throw image_reader_exception("failed to create info_ptr");
        }
    }
    catch (std::exception const& ex)
    {
        png_destroy_read_struct(&png_ptr,0,0);
        fclose(fp);
        throw;
    }

    png_set_read_fn(png_ptr, (png_voidp)fp, png_read_data);
    png_read_info(png_ptr, info_ptr);

    if (color_type_ == PNG_COLOR_TYPE_PALETTE)
        png_set_expand(png_ptr);
    if (color_type_ == PNG_COLOR_TYPE_GRAY && bit_depth_ < 8)
        png_set_expand(png_ptr);
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_expand(png_ptr);
    if (bit_depth_ == 16)
        png_set_strip_16(png_ptr);
    if (color_type_ == PNG_COLOR_TYPE_GRAY ||
        color_type_ == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png_ptr);

    // quick hack -- only work in >=libpng 1.2.7
    png_set_add_alpha(png_ptr,0xff,PNG_FILLER_AFTER); //rgba

    double gamma;
    if (png_get_gAMA(png_ptr, info_ptr, &gamma))
        png_set_gamma(png_ptr, 2.2, gamma);

    if (x0 == 0 && y0 == 0 && image.width() >= width_ && image.height() >= height_)
    {

        if (png_get_interlace_type(png_ptr,info_ptr) == PNG_INTERLACE_ADAM7)
        {
            png_set_interlace_handling(png_ptr); // FIXME: libpng bug?
            // according to docs png_read_image
            // "..automatically handles interlacing,
            // so you don't need to call png_set_interlace_handling()"
        }
        png_read_update_info(png_ptr, info_ptr);
        // we can read whole image at once
        // alloc row pointers
        boost::scoped_array<png_byte*> rows(new png_bytep[height_]);
        for (unsigned i=0; i<height_; ++i)
            rows[i] = (png_bytep)image.getRow(i);
        png_read_image(png_ptr, rows.get());
    }
    else
    {
        png_read_update_info(png_ptr, info_ptr);
        unsigned w=std::min(unsigned(image.width()),width_);
        unsigned h=std::min(unsigned(image.height()),height_);
        unsigned rowbytes=png_get_rowbytes(png_ptr, info_ptr);
        boost::scoped_array<png_byte> row(new png_byte[rowbytes]);
        //START read image rows
        for (unsigned i=0;i<height_;++i)
        {
            png_read_row(png_ptr,row.get(),0);
            if (i>=y0 && i<h)
            {
                image.setRow(i-y0,reinterpret_cast<unsigned*>(&row[x0]),w);
            }
        }
        //END
    }

    png_read_end(png_ptr,0);
    png_destroy_read_struct(&png_ptr, &info_ptr,0);
    fclose(fp);
}
}
<commit_msg>+ fix region reading, so png's can be used in raster.input<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include <mapnik/debug.hpp>
#include <mapnik/image_reader.hpp>
#include <mapnik/noncopyable.hpp>

extern "C"
{
#include <png.h>
}

#include <boost/scoped_array.hpp>

namespace mapnik
{
class png_reader : public image_reader, mapnik::noncopyable
{
private:
    std::string fileName_;
    unsigned width_;
    unsigned height_;
    int bit_depth_;
    int color_type_;
public:
    explicit png_reader(std::string const& fileName);
    ~png_reader();
    unsigned width() const;
    unsigned height() const;
    bool premultiplied_alpha() const { return false; } //http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html
    void read(unsigned x,unsigned y,image_data_32& image);
private:
    void init();
};

namespace
{
image_reader* create_png_reader(std::string const& file)
{
    return new png_reader(file);
}
const bool registered = register_image_reader("png",create_png_reader);
}

png_reader::png_reader(std::string const& fileName)
    : fileName_(fileName),
      width_(0),
      height_(0),
      bit_depth_(0),
      color_type_(0)
{
    init();
}

png_reader::~png_reader() {}

void user_error_fn(png_structp png_ptr, png_const_charp error_msg)
{
    throw image_reader_exception("failed to read invalid png");
}

void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg)
{
    MAPNIK_LOG_DEBUG(png_reader) << "libpng warning: '" << warning_msg << "'";
}

static void
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
    png_size_t check;
    check = (png_size_t)fread(data, (png_size_t)1, length,
                              (FILE *)png_get_io_ptr(png_ptr));

    if (check != length)
    {
        png_error(png_ptr, "Read Error");
    }
}

void png_reader::init()
{
    FILE *fp=fopen(fileName_.c_str(),"rb");
    if (!fp) throw image_reader_exception("cannot open image file "+fileName_);
    png_byte header[8];
    memset(header,0,8);
    if ( fread(header,1,8,fp) != 8)
    {
        fclose(fp);
        throw image_reader_exception("Could not read " + fileName_);
    }
    int is_png=!png_sig_cmp(header,0,8);
    if (!is_png)
    {
        fclose(fp);
        throw image_reader_exception(fileName_ + " is not a png file");
    }
    png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING,0,0,0);

    if (!png_ptr)
    {
        fclose(fp);
        throw image_reader_exception("failed to allocate png_ptr");
    }

    // catch errors in a custom way to avoid the need for setjmp
    png_set_error_fn(png_ptr, png_get_error_ptr(png_ptr), user_error_fn, user_warning_fn);

    png_infop info_ptr;
    try
    {
        info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr)
        {
            png_destroy_read_struct(&png_ptr,0,0);
            fclose(fp);
            throw image_reader_exception("failed to create info_ptr");
        }
    }
    catch (std::exception const& ex)
    {
        png_destroy_read_struct(&png_ptr,0,0);
        fclose(fp);
        throw;
    }

    png_set_read_fn(png_ptr, (png_voidp)fp, png_read_data);

    png_set_sig_bytes(png_ptr,8);
    png_read_info(png_ptr, info_ptr);

    png_uint_32  width, height;
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth_, &color_type_,0,0,0);

    width_=width;
    height_=height;

    MAPNIK_LOG_DEBUG(png_reader) << "png_reader: bit_depth=" << bit_depth_ << ",color_type=" << color_type_;

    png_destroy_read_struct(&png_ptr,&info_ptr,0);
    fclose(fp);
}

unsigned png_reader::width() const
{
    return width_;
}

unsigned png_reader::height() const
{
    return height_;
}

void png_reader::read(unsigned x0, unsigned y0,image_data_32& image)
{
    FILE *fp=fopen(fileName_.c_str(),"rb");
    if (!fp) throw image_reader_exception("cannot open image file "+fileName_);

    png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING,0,0,0);

    if (!png_ptr)
    {
        fclose(fp);
        throw image_reader_exception("failed to allocate png_ptr");
    }

    // catch errors in a custom way to avoid the need for setjmp
    png_set_error_fn(png_ptr, png_get_error_ptr(png_ptr), user_error_fn, user_warning_fn);

    png_infop info_ptr;
    try
    {
        info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr)
        {
            png_destroy_read_struct(&png_ptr,0,0);
            fclose(fp);
            throw image_reader_exception("failed to create info_ptr");
        }
    }
    catch (std::exception const& ex)
    {
        png_destroy_read_struct(&png_ptr,0,0);
        fclose(fp);
        throw;
    }

    png_set_read_fn(png_ptr, (png_voidp)fp, png_read_data);
    png_read_info(png_ptr, info_ptr);

    if (color_type_ == PNG_COLOR_TYPE_PALETTE)
        png_set_expand(png_ptr);
    if (color_type_ == PNG_COLOR_TYPE_GRAY && bit_depth_ < 8)
        png_set_expand(png_ptr);
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_expand(png_ptr);
    if (bit_depth_ == 16)
        png_set_strip_16(png_ptr);
    if (color_type_ == PNG_COLOR_TYPE_GRAY ||
        color_type_ == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png_ptr);

    // quick hack -- only work in >=libpng 1.2.7
    png_set_add_alpha(png_ptr,0xff,PNG_FILLER_AFTER); //rgba

    double gamma;
    if (png_get_gAMA(png_ptr, info_ptr, &gamma))
        png_set_gamma(png_ptr, 2.2, gamma);

    if (x0 == 0 && y0 == 0 && image.width() >= width_ && image.height() >= height_)
    {

        if (png_get_interlace_type(png_ptr,info_ptr) == PNG_INTERLACE_ADAM7)
        {
            png_set_interlace_handling(png_ptr); // FIXME: libpng bug?
            // according to docs png_read_image
            // "..automatically handles interlacing,
            // so you don't need to call png_set_interlace_handling()"
        }
        png_read_update_info(png_ptr, info_ptr);
        // we can read whole image at once
        // alloc row pointers
        boost::scoped_array<png_byte*> rows(new png_bytep[height_]);
        for (unsigned i=0; i<height_; ++i)
            rows[i] = (png_bytep)image.getRow(i);
        png_read_image(png_ptr, rows.get());
    }
    else
    {
        png_read_update_info(png_ptr, info_ptr);
        unsigned w=std::min(unsigned(image.width()),width_ - x0);
        unsigned h=std::min(unsigned(image.height()),height_ - y0);
        unsigned rowbytes=png_get_rowbytes(png_ptr, info_ptr);
        boost::scoped_array<png_byte> row(new png_byte[rowbytes]);
        //START read image rows
        for (unsigned i = 0;i < height_; ++i)
        {
            png_read_row(png_ptr,row.get(),0);
            if (i >= y0 && i < (y0 + h))
            {
                image.setRow(i-y0,reinterpret_cast<unsigned*>(&row[x0 * 4]),w);
            }
        }
        //END
    }

    png_read_end(png_ptr,0);
    png_destroy_read_struct(&png_ptr, &info_ptr,0);
    fclose(fp);
}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: newppdlg.cxx,v $
 * $Revision: 1.15 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <psprint/ppdparser.hxx>
#include <psprint/helper.hxx>
#include <vcl/svapp.hxx>
#include <vcl/mnemonic.hxx>
#include <tools/urlobj.hxx>
#ifndef __SGI_STL_LIST
#include <list>
#endif
#include <osl/file.hxx>
#include <helper.hxx>
#ifndef _PAD_PADIALOG_HRC_
#include <padialog.hrc>
#endif
#include <newppdlg.hxx>
#include <padialog.hxx>
#include <progress.hxx>

#define PPDIMPORT_GROUP "PPDImport"

using namespace padmin;
using namespace psp;
using namespace osl;
using namespace rtl;

PPDImportDialog::PPDImportDialog( Window* pParent ) :
        ModalDialog( pParent, PaResId( RID_PPDIMPORT_DLG ) ),
        m_aOKBtn( this, PaResId( RID_PPDIMP_BTN_OK ) ),
        m_aCancelBtn( this, PaResId( RID_PPDIMP_BTN_CANCEL ) ),
        m_aPathTxt( this, PaResId( RID_PPDIMP_TXT_PATH ) ),
        m_aPathBox( this, PaResId( RID_PPDIMP_LB_PATH ) ),
        m_aSearchBtn( this, PaResId( RID_PPDIMP_BTN_SEARCH ) ),
        m_aDriverTxt( this, PaResId( RID_PPDIMP_TXT_DRIVER ) ),
        m_aDriverLB( this, PaResId( RID_PPDIMP_LB_DRIVER ) ),
        m_aPathGroup( this, PaResId( RID_PPDIMP_GROUP_PATH ) ),
        m_aDriverGroup( this, PaResId( RID_PPDIMP_GROUP_DRIVER ) ),
        m_aLoadingPPD( PaResId( RID_PPDIMP_STR_LOADINGPPD ) )
{
    FreeResource();

    String aText( m_aDriverTxt.GetText() );
    aText.SearchAndReplaceAscii( "%s", Button::GetStandardText( BUTTON_OK ) );
    m_aDriverTxt.SetText( MnemonicGenerator::EraseAllMnemonicChars( aText ) );

    Config& rConfig = getPadminRC();
    rConfig.SetGroup( PPDIMPORT_GROUP );
    m_aPathBox.SetText( String( rConfig.ReadKey( "LastDir" ), RTL_TEXTENCODING_UTF8 ) );
    for( int i = 0; i < 11; i++ )
    {
        ByteString aEntry( rConfig.ReadKey( ByteString::CreateFromInt32( i ) ) );
        if( aEntry.Len() )
            m_aPathBox.InsertEntry( String( aEntry, RTL_TEXTENCODING_UTF8 ) );
    }

    m_aOKBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aCancelBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aSearchBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aPathBox.SetSelectHdl( LINK( this, PPDImportDialog, SelectHdl ) );
    m_aPathBox.SetModifyHdl( LINK( this, PPDImportDialog, ModifyHdl ) );

    if( m_aPathBox.GetText().Len() )
        Import();
}

PPDImportDialog::~PPDImportDialog()
{
    while( m_aDriverLB.GetEntryCount() )
    {
        delete (String*)m_aDriverLB.GetEntryData( 0 );
        m_aDriverLB.RemoveEntry( 0 );
    }
}

void PPDImportDialog::Import()
{
    String aImportPath( m_aPathBox.GetText() );

    Config& rConfig = getPadminRC();
    rConfig.SetGroup( PPDIMPORT_GROUP );
    rConfig.WriteKey( "LastDir", ByteString( aImportPath, RTL_TEXTENCODING_UTF8 ) );

    int nEntries = m_aPathBox.GetEntryCount();
    while( nEntries-- )
        if( aImportPath == m_aPathBox.GetEntry( nEntries ) )
            break;
    if( nEntries < 0 )
    {
        int nNextEntry = rConfig.ReadKey( "NextEntry" ).ToInt32();
        rConfig.WriteKey( ByteString::CreateFromInt32( nNextEntry ), ByteString( aImportPath, RTL_TEXTENCODING_UTF8 ) );
        nNextEntry = nNextEntry < 10 ? nNextEntry+1 : 0;
        rConfig.WriteKey( "NextEntry", ByteString::CreateFromInt32( nNextEntry ) );
        m_aPathBox.InsertEntry( aImportPath );
    }
    while( m_aDriverLB.GetEntryCount() )
    {
        delete (String*)m_aDriverLB.GetEntryData( 0 );
        m_aDriverLB.RemoveEntry( 0 );
    }

    ProgressDialog aProgress( Application::GetFocusWindow() );
    aProgress.startOperation( m_aLoadingPPD );

    ::std::list< String > aFiles;
    FindFiles( aImportPath, aFiles, String::CreateFromAscii( "PS;PPD" ) );

    int i = 0;
    aProgress.setRange( 0, aFiles.size() );
    while( aFiles.size() )
    {
        aProgress.setValue( ++i );
        aProgress.setFilename( aFiles.front() );
        INetURLObject aPath( aImportPath, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
        aPath.Append( aFiles.front() );
        String aPrinterName = PPDParser::getPPDPrinterName( aPath.PathToFileName() );
        aFiles.pop_front();

        if( ! aPrinterName.Len() )
        {
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "Warning: File %s has empty printer name.\n",
                     rtl::OUStringToOString( aPath.PathToFileName(), osl_getThreadTextEncoding() ).getStr() );
#endif
            continue;
        }

        USHORT nPos = m_aDriverLB.InsertEntry( aPrinterName );
        m_aDriverLB.SetEntryData( nPos, new String( aPath.PathToFileName() ) );
    }
}

IMPL_LINK( PPDImportDialog, ClickBtnHdl, PushButton*, pButton )
{
    if( pButton == &m_aCancelBtn )
    {
        EndDialog( 0 );
    }
    else if( pButton == &m_aOKBtn )
    {
        // copy the files
        ::std::list< rtl::OUString > aToDirs;
        psp::getPrinterPathList( aToDirs, PSPRINT_PPDDIR );
        ::std::list< rtl::OUString >::iterator writeDir = aToDirs.begin();

        for( int i = 0; i < m_aDriverLB.GetSelectEntryCount(); i++ )
        {
            INetURLObject aFile( *(String*)m_aDriverLB.GetEntryData(
                m_aDriverLB.GetSelectEntryPos( i )
                ), INET_PROT_FILE, INetURLObject::ENCODE_ALL );
            OUString aFromUni( aFile.GetMainURL(INetURLObject::DECODE_TO_IURI) );

            do
            {
                INetURLObject aToFile( *writeDir, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
                aToFile.Append( aFile.GetName() );
                aToFile.setExtension( String::CreateFromAscii( "PPD" ) );
                OUString aToUni( aToFile.GetMainURL(INetURLObject::DECODE_TO_IURI) );
                if( ! File::copy( aFromUni, aToUni ) )
                    break;
                ++writeDir;
            } while( writeDir != aToDirs.end() );
        }
        EndDialog( 1 );
    }
    else if( pButton == &m_aSearchBtn )
    {
        String aPath( m_aPathBox.GetText() );
        if( chooseDirectory( aPath ) )
        {
            m_aPathBox.SetText( aPath );
            Import();
        }
    }
    return 0;
}

IMPL_LINK( PPDImportDialog, SelectHdl, ComboBox*, pListBox )
{
    if( pListBox == &m_aPathBox )
    {
        Import();
    }
    return 0;
}

IMPL_LINK( PPDImportDialog, ModifyHdl, ComboBox*, pListBox )
{
    if( pListBox == &m_aPathBox )
    {
        ByteString aDir( m_aPathBox.GetText(), osl_getThreadTextEncoding() );
        if( ! access( aDir.GetBuffer(), F_OK ) )
            Import();
    }
    return 0;
}
<commit_msg>INTEGRATION: CWS vcl89 (1.15.4); FILE MERGED 2008/05/07 19:44:47 pl 1.15.4.2: #i72327# support for system ppd dir 2008/05/07 17:40:12 pl 1.15.4.1: #i72327# support for gzipped PPD files<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: newppdlg.cxx,v $
 * $Revision: 1.16 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <psprint/ppdparser.hxx>
#include <psprint/helper.hxx>
#include <vcl/svapp.hxx>
#include <vcl/mnemonic.hxx>
#include <tools/urlobj.hxx>
#ifndef __SGI_STL_LIST
#include <list>
#endif
#include <osl/file.hxx>
#include <helper.hxx>
#ifndef _PAD_PADIALOG_HRC_
#include <padialog.hrc>
#endif
#include <newppdlg.hxx>
#include <padialog.hxx>
#include <progress.hxx>

#define PPDIMPORT_GROUP "PPDImport"

using namespace padmin;
using namespace psp;
using namespace osl;
using namespace rtl;

PPDImportDialog::PPDImportDialog( Window* pParent ) :
        ModalDialog( pParent, PaResId( RID_PPDIMPORT_DLG ) ),
        m_aOKBtn( this, PaResId( RID_PPDIMP_BTN_OK ) ),
        m_aCancelBtn( this, PaResId( RID_PPDIMP_BTN_CANCEL ) ),
        m_aPathTxt( this, PaResId( RID_PPDIMP_TXT_PATH ) ),
        m_aPathBox( this, PaResId( RID_PPDIMP_LB_PATH ) ),
        m_aSearchBtn( this, PaResId( RID_PPDIMP_BTN_SEARCH ) ),
        m_aDriverTxt( this, PaResId( RID_PPDIMP_TXT_DRIVER ) ),
        m_aDriverLB( this, PaResId( RID_PPDIMP_LB_DRIVER ) ),
        m_aPathGroup( this, PaResId( RID_PPDIMP_GROUP_PATH ) ),
        m_aDriverGroup( this, PaResId( RID_PPDIMP_GROUP_DRIVER ) ),
        m_aLoadingPPD( PaResId( RID_PPDIMP_STR_LOADINGPPD ) )
{
    FreeResource();

    String aText( m_aDriverTxt.GetText() );
    aText.SearchAndReplaceAscii( "%s", Button::GetStandardText( BUTTON_OK ) );
    m_aDriverTxt.SetText( MnemonicGenerator::EraseAllMnemonicChars( aText ) );

    Config& rConfig = getPadminRC();
    rConfig.SetGroup( PPDIMPORT_GROUP );
    m_aPathBox.SetText( String( rConfig.ReadKey( "LastDir" ), RTL_TEXTENCODING_UTF8 ) );
    for( int i = 0; i < 11; i++ )
    {
        ByteString aEntry( rConfig.ReadKey( ByteString::CreateFromInt32( i ) ) );
        if( aEntry.Len() )
            m_aPathBox.InsertEntry( String( aEntry, RTL_TEXTENCODING_UTF8 ) );
    }

    m_aOKBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aCancelBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aSearchBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aPathBox.SetSelectHdl( LINK( this, PPDImportDialog, SelectHdl ) );
    m_aPathBox.SetModifyHdl( LINK( this, PPDImportDialog, ModifyHdl ) );

    if( m_aPathBox.GetText().Len() )
        Import();
}

PPDImportDialog::~PPDImportDialog()
{
    while( m_aDriverLB.GetEntryCount() )
    {
        delete (String*)m_aDriverLB.GetEntryData( 0 );
        m_aDriverLB.RemoveEntry( 0 );
    }
}

void PPDImportDialog::Import()
{
    String aImportPath( m_aPathBox.GetText() );

    Config& rConfig = getPadminRC();
    rConfig.SetGroup( PPDIMPORT_GROUP );
    rConfig.WriteKey( "LastDir", ByteString( aImportPath, RTL_TEXTENCODING_UTF8 ) );

    int nEntries = m_aPathBox.GetEntryCount();
    while( nEntries-- )
        if( aImportPath == m_aPathBox.GetEntry( nEntries ) )
            break;
    if( nEntries < 0 )
    {
        int nNextEntry = rConfig.ReadKey( "NextEntry" ).ToInt32();
        rConfig.WriteKey( ByteString::CreateFromInt32( nNextEntry ), ByteString( aImportPath, RTL_TEXTENCODING_UTF8 ) );
        nNextEntry = nNextEntry < 10 ? nNextEntry+1 : 0;
        rConfig.WriteKey( "NextEntry", ByteString::CreateFromInt32( nNextEntry ) );
        m_aPathBox.InsertEntry( aImportPath );
    }
    while( m_aDriverLB.GetEntryCount() )
    {
        delete (String*)m_aDriverLB.GetEntryData( 0 );
        m_aDriverLB.RemoveEntry( 0 );
    }

    ProgressDialog aProgress( Application::GetFocusWindow() );
    aProgress.startOperation( m_aLoadingPPD );

    ::std::list< String > aFiles;
    FindFiles( aImportPath, aFiles, String( RTL_CONSTASCII_USTRINGPARAM( "PS;PPD;PS.GZ;PPD.GZ" ) ), true );

    int i = 0;
    aProgress.setRange( 0, aFiles.size() );
    while( aFiles.size() )
    {
        aProgress.setValue( ++i );
        aProgress.setFilename( aFiles.front() );
        INetURLObject aPath( aImportPath, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
        aPath.Append( aFiles.front() );
        String aPrinterName = PPDParser::getPPDPrinterName( aPath.PathToFileName() );
        aFiles.pop_front();

        if( ! aPrinterName.Len() )
        {
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "Warning: File %s has empty printer name.\n",
                     rtl::OUStringToOString( aPath.PathToFileName(), osl_getThreadTextEncoding() ).getStr() );
#endif
            continue;
        }

        USHORT nPos = m_aDriverLB.InsertEntry( aPrinterName );
        m_aDriverLB.SetEntryData( nPos, new String( aPath.PathToFileName() ) );
    }
}

IMPL_LINK( PPDImportDialog, ClickBtnHdl, PushButton*, pButton )
{
    if( pButton == &m_aCancelBtn )
    {
        EndDialog( 0 );
    }
    else if( pButton == &m_aOKBtn )
    {
        // copy the files
        ::std::list< rtl::OUString > aToDirs;
        psp::getPrinterPathList( aToDirs, PRINTER_PPDDIR );
        ::std::list< rtl::OUString >::iterator writeDir = aToDirs.begin();

        for( int i = 0; i < m_aDriverLB.GetSelectEntryCount(); i++ )
        {
            INetURLObject aFile( *(String*)m_aDriverLB.GetEntryData(
                m_aDriverLB.GetSelectEntryPos( i )
                ), INET_PROT_FILE, INetURLObject::ENCODE_ALL );
            OUString aFromUni( aFile.GetMainURL(INetURLObject::DECODE_TO_IURI) );

            do
            {
                INetURLObject aToFile( *writeDir, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
                aToFile.Append( aFile.GetName() );
                OUString aToUni( aToFile.GetMainURL(INetURLObject::DECODE_TO_IURI) );
                if( ! File::copy( aFromUni, aToUni ) )
                    break;
                ++writeDir;
            } while( writeDir != aToDirs.end() );
        }
        EndDialog( 1 );
    }
    else if( pButton == &m_aSearchBtn )
    {
        String aPath( m_aPathBox.GetText() );
        if( chooseDirectory( aPath ) )
        {
            m_aPathBox.SetText( aPath );
            Import();
        }
    }
    return 0;
}

IMPL_LINK( PPDImportDialog, SelectHdl, ComboBox*, pListBox )
{
    if( pListBox == &m_aPathBox )
    {
        Import();
    }
    return 0;
}

IMPL_LINK( PPDImportDialog, ModifyHdl, ComboBox*, pListBox )
{
    if( pListBox == &m_aPathBox )
    {
        ByteString aDir( m_aPathBox.GetText(), osl_getThreadTextEncoding() );
        if( ! access( aDir.GetBuffer(), F_OK ) )
            Import();
    }
    return 0;
}
<|endoftext|>


<commit_before>#include "../../../shared/generated/cpp/MediaplayerBase.h"
#include "net/INetRequest.h"
#include "RhoFile.h"

namespace rho {

using namespace apiGenerator;

std::wstring s2ws(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

class CMediaplayerImpl: public CMediaplayerBase
{
public:
    CMediaplayerImpl(const rho::String& strID): CMediaplayerBase()
    {
    }
};

class CMediaplayerSingleton: public CMediaplayerSingletonBase
{

	static HANDLE	m_hPlayThread;			/// Handle to player thread
	static HANDLE	m_hPlayProcess;			/// Handle to player process
	static StringW  lFilename;

    ~CMediaplayerSingleton(){}
    virtual rho::String getInitialDefaultID();
    virtual void enumerate(CMethodResult& oResult);

	/**
	* Function to kill the player thread so that VideoCapture can unlock
	* any in-use media files
	*/
	void KillPlayer()
	{
		if (m_hPlayProcess)
		{
			TerminateProcess(m_hPlayProcess, -1);
			WaitForSingleObject(m_hPlayProcess, 500);
			CloseHandle(m_hPlayProcess);
			m_hPlayProcess = NULL;
		}
		if (m_hPlayThread)
		{
			TerminateThread(m_hPlayThread, -1);
			CloseHandle(m_hPlayThread);
			m_hPlayThread = NULL;
		}
	}

	bool playLocalAudio()
	{
		LOG(INFO) + __FUNCTION__ + ": playLocalAudio called";
		m_hPlayThread = CreateThread(NULL, 0, (&rho::CMediaplayerSingleton::playThreadProc), this, 0, NULL);
		return (m_hPlayThread != NULL);
	}

	static DWORD WINAPI playThreadProc(LPVOID lpParam)
	{
		DWORD dwRet = S_OK;

		CMediaplayerSingleton *pMediaplayer = (CMediaplayerSingleton *)lpParam;

		if (pMediaplayer)
		{
			LOG(INFO) + __FUNCTION__ + "pMediaplayer object exists: using lFilename: " + lFilename.c_str();
			if (!PlaySound(lFilename.c_str(), NULL, SND_FILENAME|SND_SYNC|SND_NODEFAULT)) {
				LOG(INFO) + __FUNCTION__ + " PlaySound function failed ";
				dwRet = false;
			}

			CloseHandle(pMediaplayer->m_hPlayThread);
			pMediaplayer->m_hPlayThread = NULL;
		}

		return dwRet;
	}

	// Play an audio file.
	virtual void start( const rho::String& filename, rho::apiGenerator::CMethodResult& oResult)
	{
		// Check that the filename is not empty or NULL.
		if (!filename.empty() && (!m_hPlayThread))
		{
			// Download the audio file and store name in lFilename
			if(String_startsWith(filename, "http://") || String_startsWith(filename, "https://"))
			{
				rho::common::CRhoFile::deleteFile("download.wav");
				// Networked code
				LOG(INFO) + __FUNCTION__ + "Attempting to download the file. " + filename;
				NetRequest oNetRequest;
				Hashtable<String,String> mapHeaders;
				bool overwriteFile = true;
				bool createFolders = false;
				bool fileExists = false;
				String& newfilename = String("download.wav");

				// Call the download function with the url and new filename the temp filename to be used.
				net::CNetRequestHolder *requestHolder = new net::CNetRequestHolder();
				requestHolder->setSslVerifyPeer(false);
				NetResponse resp = getNetRequest(requestHolder).pullFile( filename, newfilename, null, &mapHeaders,overwriteFile,createFolders,&fileExists);

				delete requestHolder;

				if (!resp.isOK())
				{
					LOG(INFO) + __FUNCTION__ + "Could not download the file";
					return; // Don't attempt to play the file.
				}
				else
				{
					LOG(INFO) + __FUNCTION__ + "Could download the file";
					lFilename = s2ws(newfilename);
				}
			}
			else
			{
				// Store the local filename away.
				lFilename = s2ws(filename);
			}

			// Launch the audio player.
			playLocalAudio();
		}
	}

	// Stop playing an audio file.
    virtual void stop(rho::apiGenerator::CMethodResult& oResult)
	{
		// If the player is currently playing an audio file, stop it.
		PlaySound(NULL, NULL, 0);
		LOG(INFO) + __FUNCTION__ + " Stopping audio playback";
		if (WaitForSingleObject(m_hPlayThread, 500) == WAIT_TIMEOUT)
		{
			TerminateThread(m_hPlayThread, -1);
			CloseHandle(m_hPlayThread);
			m_hPlayThread = NULL;
		}
	}

	// Start playing a video file.
    virtual void startvideo( const rho::String& filename, rho::apiGenerator::CMethodResult& oResult)
	{
		// Attempt to kill the player.  If we don't do this, WMP holds a lock on the file and we cannot delete it.
		KillPlayer();
		rho::common::CRhoFile::deleteFile("download.wmv");

		// Check that the filename is not empty or NULL.
		if (!filename.empty() &&  (!m_hPlayProcess))
		{
			PROCESS_INFORMATION pi;
			StringW m_lpzFilename;

			if (String_startsWith(filename, "http://") || String_startsWith(filename, "https://"))
			{
				// Networked code
				LOG(INFO) + __FUNCTION__ + "Attempting to download the file. " + filename;
				NetRequest oNetRequest;
				Hashtable<String,String> mapHeaders;
				bool overwriteFile = true;
				bool createFolders = false;
				bool fileExists = false;
				String& newfilename = String("download.wmv");

				// Call the download function with the url and new filename the temp filename to be used.
				net::CNetRequestHolder *requestHolder = new net::CNetRequestHolder();
				requestHolder->setSslVerifyPeer(false);

				NetResponse resp = getNetRequest(requestHolder).pullFile( filename, newfilename, null, &mapHeaders,overwriteFile,createFolders,&fileExists);

				delete requestHolder;

				if (!resp.isOK())
				{
					LOG(INFO) + __FUNCTION__ + "Could not download the file";
					return; // Don't attempt to play the file.
				}
				else
				{
					LOG(INFO) + __FUNCTION__ + "Could download the file";
					m_lpzFilename = s2ws(newfilename);
				}
			}
			else
			{
				// Local file, just change the name to a format the WM/CE understands.
				m_lpzFilename = s2ws(filename);
			}

			// Launch the video player.
			if (!CreateProcess(L"\\windows\\WMPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi))
			{
				// for WinCE CEPlayer we need to set a registry key to make sure it launches full screen
				HKEY hKey = 0;
				LPCWSTR subkey = L"SOFTWARE\\Microsoft\\CEPlayer";

				if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0,0,&hKey) == ERROR_SUCCESS)
				{
					DWORD dwType = REG_DWORD;
					DWORD dwData = 1; // Set AlwaysFullSize to 1
					RegSetValueEx(hKey, L"AlwaysFullSize", 0, dwType, (BYTE*)&dwData, sizeof(dwData));
					RegCloseKey(hKey);
				}

				if (!CreateProcess(L"\\windows\\CEPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi))
				{
					// if CEPlayer doesn't exist either, try VPlayer
					if (!CreateProcess(L"\\windows\\VPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi))
					{
						LOG(INFO) + __FUNCTION__ +  "Error launching MediaPlayer";
						return;
					}
				}

				m_hPlayProcess = pi.hProcess;
				m_hPlayThread = pi.hThread;
			}

			m_hPlayProcess = pi.hProcess;
			m_hPlayThread = pi.hThread;
		}
	}

	// Stop playing a video file.
    virtual void stopvideo(rho::apiGenerator::CMethodResult& oResult)
	{
		// If the player is currently playing a video file, stop it.
		TerminateProcess(m_hPlayProcess, -1);
		WaitForSingleObject(m_hPlayProcess, 500);
		CloseHandle(m_hPlayThread);
		m_hPlayThread = NULL;
		CloseHandle(m_hPlayProcess);
		m_hPlayProcess = NULL;
		LOG(INFO) + __FUNCTION__ + " stopping video player.";
	}

    virtual void getAllRingtones(rho::apiGenerator::CMethodResult& oResult)
	{
		// Not implemented in CE
	}

    virtual void playRingTone( const rho::String& name, rho::apiGenerator::CMethodResult& oResult)
	{
		// Not implemented in CE
	}

    virtual void stopRingTone(rho::apiGenerator::CMethodResult& oResult)
	{
		// Not implemented in CE
	}
};

StringW CMediaplayerSingleton::lFilename;

HANDLE CMediaplayerSingleton::m_hPlayThread = NULL;
HANDLE CMediaplayerSingleton::m_hPlayProcess = NULL;

class CMediaplayerFactory: public CMediaplayerFactoryBase
{
    ~CMediaplayerFactory(){}
    virtual IMediaplayerSingleton* createModuleSingleton();
    virtual IMediaplayer* createModuleByID(const rho::String& strID);
};

extern "C" void Init_Mediaplayer_extension()
{
    CMediaplayerFactory::setInstance( new CMediaplayerFactory() );
    Init_Mediaplayer_API();
}

IMediaplayer* CMediaplayerFactory::createModuleByID(const rho::String& strID)
{
    return new CMediaplayerImpl(strID);
}

IMediaplayerSingleton* CMediaplayerFactory::createModuleSingleton()
{
    return new CMediaplayerSingleton();
}

void CMediaplayerSingleton::enumerate(CMethodResult& oResult)
{
    rho::Vector<rho::String> arIDs;
    arIDs.addElement("SC1");
    arIDs.addElement("SC2");

    oResult.set(arIDs);
}

rho::String CMediaplayerSingleton::getInitialDefaultID()
{
    CMethodResult oRes;
    enumerate(oRes);

    rho::Vector<rho::String>& arIDs = oRes.getStringArray();

    return arIDs[0];
}

}<commit_msg>/****************************************/ /* 	SR ID - EMBPD00128123 	Issue Description - Video Files are not getting played in MediaPlayer with Native Application on WM 	Fix Provided - Issue was reproducing because of CreateProcess Microsoft API which donot understand the path which consists of space. 		       Hence we need to put an extra double inverted at the front & at the end of the string. 	Developer Name - Abhineet Agarwal 	File Name - Mediaplayer_impl.cpp 	Function Name - startvideo 	Date - 09/06/2014 */ /****************************************/<commit_after>#include "../../../shared/generated/cpp/MediaplayerBase.h"
#include "net/INetRequest.h"
#include "RhoFile.h"

namespace rho {

using namespace apiGenerator;

std::wstring s2ws(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

class CMediaplayerImpl: public CMediaplayerBase
{
public:
    CMediaplayerImpl(const rho::String& strID): CMediaplayerBase()
    {
    }
};

class CMediaplayerSingleton: public CMediaplayerSingletonBase
{

	static HANDLE	m_hPlayThread;			/// Handle to player thread
	static HANDLE	m_hPlayProcess;			/// Handle to player process
	static StringW  lFilename;

    ~CMediaplayerSingleton(){}
    virtual rho::String getInitialDefaultID();
    virtual void enumerate(CMethodResult& oResult);

	/**
	* Function to kill the player thread so that VideoCapture can unlock
	* any in-use media files
	*/
	void KillPlayer()
	{
		if (m_hPlayProcess)
		{
			TerminateProcess(m_hPlayProcess, -1);
			WaitForSingleObject(m_hPlayProcess, 500);
			CloseHandle(m_hPlayProcess);
			m_hPlayProcess = NULL;
		}
		if (m_hPlayThread)
		{
			TerminateThread(m_hPlayThread, -1);
			CloseHandle(m_hPlayThread);
			m_hPlayThread = NULL;
		}
	}

	bool playLocalAudio()
	{
		LOG(INFO) + __FUNCTION__ + ": playLocalAudio called";
		m_hPlayThread = CreateThread(NULL, 0, (&rho::CMediaplayerSingleton::playThreadProc), this, 0, NULL);
		return (m_hPlayThread != NULL);
	}

	static DWORD WINAPI playThreadProc(LPVOID lpParam)
	{
		DWORD dwRet = S_OK;

		CMediaplayerSingleton *pMediaplayer = (CMediaplayerSingleton *)lpParam;

		if (pMediaplayer)
		{
			LOG(INFO) + __FUNCTION__ + "pMediaplayer object exists: using lFilename: " + lFilename.c_str();
			if (!PlaySound(lFilename.c_str(), NULL, SND_FILENAME|SND_SYNC|SND_NODEFAULT)) {
				LOG(INFO) + __FUNCTION__ + " PlaySound function failed ";
				dwRet = false;
			}

			CloseHandle(pMediaplayer->m_hPlayThread);
			pMediaplayer->m_hPlayThread = NULL;
		}

		return dwRet;
	}

	// Play an audio file.
	virtual void start( const rho::String& filename, rho::apiGenerator::CMethodResult& oResult)
	{
		// Check that the filename is not empty or NULL.
		if (!filename.empty() && (!m_hPlayThread))
		{
			// Download the audio file and store name in lFilename
			if(String_startsWith(filename, "http://") || String_startsWith(filename, "https://"))
			{
				rho::common::CRhoFile::deleteFile("download.wav");
				// Networked code
				LOG(INFO) + __FUNCTION__ + "Attempting to download the file. " + filename;
				NetRequest oNetRequest;
				Hashtable<String,String> mapHeaders;
				bool overwriteFile = true;
				bool createFolders = false;
				bool fileExists = false;
				String& newfilename = String("download.wav");

				// Call the download function with the url and new filename the temp filename to be used.
				net::CNetRequestHolder *requestHolder = new net::CNetRequestHolder();
				requestHolder->setSslVerifyPeer(false);
				NetResponse resp = getNetRequest(requestHolder).pullFile( filename, newfilename, null, &mapHeaders,overwriteFile,createFolders,&fileExists);

				delete requestHolder;

				if (!resp.isOK())
				{
					LOG(INFO) + __FUNCTION__ + "Could not download the file";
					return; // Don't attempt to play the file.
				}
				else
				{
					LOG(INFO) + __FUNCTION__ + "Could download the file";
					lFilename = s2ws(newfilename);
				}
			}
			else
			{
				// Store the local filename away.
				lFilename = s2ws(filename);
			}

			// Launch the audio player.
			playLocalAudio();
		}
	}

	// Stop playing an audio file.
    virtual void stop(rho::apiGenerator::CMethodResult& oResult)
	{
		// If the player is currently playing an audio file, stop it.
		PlaySound(NULL, NULL, 0);
		LOG(INFO) + __FUNCTION__ + " Stopping audio playback";
		if (WaitForSingleObject(m_hPlayThread, 500) == WAIT_TIMEOUT)
		{
			TerminateThread(m_hPlayThread, -1);
			CloseHandle(m_hPlayThread);
			m_hPlayThread = NULL;
		}
	}

	// Start playing a video file.
    virtual void startvideo( const rho::String& filename, rho::apiGenerator::CMethodResult& oResult)
	{
		// Attempt to kill the player.  If we don't do this, WMP holds a lock on the file and we cannot delete it.
		KillPlayer();
		rho::common::CRhoFile::deleteFile("download.wmv");

		// Check that the filename is not empty or NULL.
		if (!filename.empty() &&  (!m_hPlayProcess))
		{
			PROCESS_INFORMATION pi;
			StringW m_lpzFilename;

			if (String_startsWith(filename, "http://") || String_startsWith(filename, "https://"))
			{
				// Networked code
				LOG(INFO) + __FUNCTION__ + "Attempting to download the file. " + filename;
				NetRequest oNetRequest;
				Hashtable<String,String> mapHeaders;
				bool overwriteFile = true;
				bool createFolders = false;
				bool fileExists = false;
				String& newfilename = String("download.wmv");

				// Call the download function with the url and new filename the temp filename to be used.
				net::CNetRequestHolder *requestHolder = new net::CNetRequestHolder();
				requestHolder->setSslVerifyPeer(false);

				NetResponse resp = getNetRequest(requestHolder).pullFile( filename, newfilename, null, &mapHeaders,overwriteFile,createFolders,&fileExists);

				delete requestHolder;

				if (!resp.isOK())
				{
					LOG(INFO) + __FUNCTION__ + "Could not download the file";
					return; // Don't attempt to play the file.
				}
				else
				{
					LOG(INFO) + __FUNCTION__ + "Could download the file";
					m_lpzFilename = s2ws(newfilename);
				}
			}
			else
			{
				// Local file, just change the name to a format the WM/CE understands.
				m_lpzFilename = s2ws(filename);
			}

			/****************************************/
			/*
				SR ID - EMBPD00128123
				Issue Description - Video Files are not getting played in MediaPlayer with Native Application on WM
				Fix Provided - Issue was reproducing because of CreateProcess Microsoft API which donot understand the path which consists of space.
							   Hence we need to put an extra double inverted at the front & at the end of the string.
				Developer Name - Abhineet Agarwal
				File Name - Mediaplayer_impl.cpp
				Function Name - startvideo
				Date - 09/06/2014
			*/
			/****************************************/
			m_lpzFilename = L"\"" + m_lpzFilename + L"\"";

			// Launch the video player.
			if (!CreateProcess(L"\\windows\\WMPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi))
			{
				// for WinCE CEPlayer we need to set a registry key to make sure it launches full screen
				HKEY hKey = 0;
				LPCWSTR subkey = L"SOFTWARE\\Microsoft\\CEPlayer";

				if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0,0,&hKey) == ERROR_SUCCESS)
				{
					DWORD dwType = REG_DWORD;
					DWORD dwData = 1; // Set AlwaysFullSize to 1
					RegSetValueEx(hKey, L"AlwaysFullSize", 0, dwType, (BYTE*)&dwData, sizeof(dwData));
					RegCloseKey(hKey);
				}

				if (!CreateProcess(L"\\windows\\CEPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi))
				{
					// if CEPlayer doesn't exist either, try VPlayer
					if (!CreateProcess(L"\\windows\\VPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi))
					{
						LOG(INFO) + __FUNCTION__ +  "Error launching MediaPlayer";
						return;
					}
				}

				m_hPlayProcess = pi.hProcess;
				m_hPlayThread = pi.hThread;
			}

			m_hPlayProcess = pi.hProcess;
			m_hPlayThread = pi.hThread;
		}
	}

	// Stop playing a video file.
    virtual void stopvideo(rho::apiGenerator::CMethodResult& oResult)
	{
		// If the player is currently playing a video file, stop it.
		TerminateProcess(m_hPlayProcess, -1);
		WaitForSingleObject(m_hPlayProcess, 500);
		CloseHandle(m_hPlayThread);
		m_hPlayThread = NULL;
		CloseHandle(m_hPlayProcess);
		m_hPlayProcess = NULL;
		LOG(INFO) + __FUNCTION__ + " stopping video player.";
	}

    virtual void getAllRingtones(rho::apiGenerator::CMethodResult& oResult)
	{
		// Not implemented in CE
	}

    virtual void playRingTone( const rho::String& name, rho::apiGenerator::CMethodResult& oResult)
	{
		// Not implemented in CE
	}

    virtual void stopRingTone(rho::apiGenerator::CMethodResult& oResult)
	{
		// Not implemented in CE
	}
};

StringW CMediaplayerSingleton::lFilename;

HANDLE CMediaplayerSingleton::m_hPlayThread = NULL;
HANDLE CMediaplayerSingleton::m_hPlayProcess = NULL;

class CMediaplayerFactory: public CMediaplayerFactoryBase
{
    ~CMediaplayerFactory(){}
    virtual IMediaplayerSingleton* createModuleSingleton();
    virtual IMediaplayer* createModuleByID(const rho::String& strID);
};

extern "C" void Init_Mediaplayer_extension()
{
    CMediaplayerFactory::setInstance( new CMediaplayerFactory() );
    Init_Mediaplayer_API();
}

IMediaplayer* CMediaplayerFactory::createModuleByID(const rho::String& strID)
{
    return new CMediaplayerImpl(strID);
}

IMediaplayerSingleton* CMediaplayerFactory::createModuleSingleton()
{
    return new CMediaplayerSingleton();
}

void CMediaplayerSingleton::enumerate(CMethodResult& oResult)
{
    rho::Vector<rho::String> arIDs;
    arIDs.addElement("SC1");
    arIDs.addElement("SC2");

    oResult.set(arIDs);
}

rho::String CMediaplayerSingleton::getInitialDefaultID()
{
    CMethodResult oRes;
    enumerate(oRes);

    rho::Vector<rho::String>& arIDs = oRes.getStringArray();

    return arIDs[0];
}

}<|endoftext|>