<commit_before>/*
 * Copyright (C) 2007 Apple Inc.
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
 * Copyright (C) 2008 Collabora Ltd.
 * Copyright (C) 2008, 2009 Google Inc.
 * Copyright (C) 2009 Kenneth Rohde Christiansen
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "core/layout/LayoutThemeDefault.h"

#include "core/CSSValueKeywords.h"
#include "core/layout/LayoutObject.h"
#include "core/layout/LayoutProgress.h"
#include "core/layout/LayoutThemeFontProvider.h"
#include "core/paint/MediaControlsPainter.h"
#include "platform/LayoutTestSupport.h"
#include "platform/PlatformResourceLoader.h"
#include "platform/graphics/Color.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "public/platform/Platform.h"
#include "public/platform/WebThemeEngine.h"

namespace blink {

enum PaddingType {
    TopPadding,
    RightPadding,
    BottomPadding,
    LeftPadding
};

static const int styledMenuListInternalPadding[4] = { 1, 4, 1, 4 };

// These values all match Safari/Win.
static const float defaultControlFontPixelSize = 13;
static const float defaultCancelButtonSize = 9;
static const float minCancelButtonSize = 5;
static const float maxCancelButtonSize = 21;
static const float defaultSearchFieldResultsDecorationSize = 13;
static const float minSearchFieldResultsDecorationSize = 9;
static const float maxSearchFieldResultsDecorationSize = 30;

static bool useMockTheme()
{
    return LayoutTestSupport::isRunningLayoutTest();
}

unsigned LayoutThemeDefault::m_activeSelectionBackgroundColor = 0xff1e90ff;
unsigned LayoutThemeDefault::m_activeSelectionForegroundColor = Color::black;
unsigned LayoutThemeDefault::m_inactiveSelectionBackgroundColor = 0xffc8c8c8;
unsigned LayoutThemeDefault::m_inactiveSelectionForegroundColor = 0xff323232;

double LayoutThemeDefault::m_caretBlinkInterval;

LayoutThemeDefault::LayoutThemeDefault()
{
    m_caretBlinkInterval = LayoutTheme::caretBlinkInterval();
}

LayoutThemeDefault::~LayoutThemeDefault()
{
}

bool LayoutThemeDefault::supportsFocusRing(const ComputedStyle& style) const
{
    if (useMockTheme()) {
        // Don't use focus rings for buttons when mocking controls.
        return style.appearance() == ButtonPart
            || style.appearance() == PushButtonPart
            || style.appearance() == SquareButtonPart;
    }

    // This causes Blink to draw the focus rings for us.
    return false;
}

Color LayoutThemeDefault::systemColor(CSSValueID cssValueId) const
{
    static const Color defaultButtonGrayColor(0xffdddddd);
    static const Color defaultMenuColor(0xfff7f7f7);

    if (cssValueId == CSSValueButtonface) {
        if (useMockTheme())
            return Color(0xc0, 0xc0, 0xc0);
        return defaultButtonGrayColor;
    }
    if (cssValueId == CSSValueMenu)
        return defaultMenuColor;
    return LayoutTheme::systemColor(cssValueId);
}

// Use the Windows style sheets to match their metrics.
String LayoutThemeDefault::extraDefaultStyleSheet()
{
    return LayoutTheme::extraDefaultStyleSheet()
        + loadResourceAsASCIIString("themeWin.css")
        + loadResourceAsASCIIString("themeChromiumSkia.css")
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
        + loadResourceAsASCIIString("themeInputMultipleFields.css")
#endif
        + loadResourceAsASCIIString("themeChromium.css");
}

String LayoutThemeDefault::extraQuirksStyleSheet()
{
    return loadResourceAsASCIIString("themeWinQuirks.css");
}

Color LayoutThemeDefault::activeListBoxSelectionBackgroundColor() const
{
    return Color(0x28, 0x28, 0x28);
}

Color LayoutThemeDefault::activeListBoxSelectionForegroundColor() const
{
    return Color::black;
}

Color LayoutThemeDefault::inactiveListBoxSelectionBackgroundColor() const
{
    return Color(0xc8, 0xc8, 0xc8);
}

Color LayoutThemeDefault::inactiveListBoxSelectionForegroundColor() const
{
    return Color(0x32, 0x32, 0x32);
}

Color LayoutThemeDefault::platformActiveSelectionBackgroundColor() const
{
    if (useMockTheme())
        return Color(0x00, 0x00, 0xff); // Royal blue.
    return m_activeSelectionBackgroundColor;
}

Color LayoutThemeDefault::platformInactiveSelectionBackgroundColor() const
{
    if (useMockTheme())
        return Color(0x99, 0x99, 0x99); // Medium gray.
    return m_inactiveSelectionBackgroundColor;
}

Color LayoutThemeDefault::platformActiveSelectionForegroundColor() const
{
    if (useMockTheme())
        return Color(0xff, 0xff, 0xcc); // Pale yellow.
    return m_activeSelectionForegroundColor;
}

Color LayoutThemeDefault::platformInactiveSelectionForegroundColor() const
{
    if (useMockTheme())
        return Color::white;
    return m_inactiveSelectionForegroundColor;
}

IntSize LayoutThemeDefault::sliderTickSize() const
{
    if (useMockTheme())
        return IntSize(1, 3);
    return IntSize(1, 6);
}

int LayoutThemeDefault::sliderTickOffsetFromTrackCenter() const
{
    if (useMockTheme())
        return 11;
    return -16;
}

void LayoutThemeDefault::adjustSliderThumbSize(ComputedStyle& style, Element* element) const
{
    IntSize size = Platform::current()->themeEngine()->getSize(WebThemeEngine::PartSliderThumb);

    // FIXME: Mock theme doesn't handle zoomed sliders.
    float zoomLevel = useMockTheme() ? 1 : style.effectiveZoom();
    if (style.appearance() == SliderThumbHorizontalPart) {
        style.setWidth(Length(size.width() * zoomLevel, Fixed));
        style.setHeight(Length(size.height() * zoomLevel, Fixed));
    } else if (style.appearance() == SliderThumbVerticalPart) {
        style.setWidth(Length(size.height() * zoomLevel, Fixed));
        style.setHeight(Length(size.width() * zoomLevel, Fixed));
    } else {
        MediaControlsPainter::adjustMediaSliderThumbSize(style);
    }
}

void LayoutThemeDefault::setCaretBlinkInterval(double interval)
{
    m_caretBlinkInterval = interval;
}

void LayoutThemeDefault::setSelectionColors(
    unsigned activeBackgroundColor,
    unsigned activeForegroundColor,
    unsigned inactiveBackgroundColor,
    unsigned inactiveForegroundColor)
{
    m_activeSelectionBackgroundColor = activeBackgroundColor;
    m_activeSelectionForegroundColor = activeForegroundColor;
    m_inactiveSelectionBackgroundColor = inactiveBackgroundColor;
    m_inactiveSelectionForegroundColor = inactiveForegroundColor;
}

void LayoutThemeDefault::setCheckboxSize(ComputedStyle& style) const
{
    // If the width and height are both specified, then we have nothing to do.
    if (!style.width().isIntrinsicOrAuto() && !style.height().isAuto())
        return;

    IntSize size = Platform::current()->themeEngine()->getSize(WebThemeEngine::PartCheckbox);
    float zoomLevel = style.effectiveZoom();
    size.setWidth(size.width() * zoomLevel);
    size.setHeight(size.height() * zoomLevel);
    setSizeIfAuto(style, size);
}

void LayoutThemeDefault::setRadioSize(ComputedStyle& style) const
{
    // If the width and height are both specified, then we have nothing to do.
    if (!style.width().isIntrinsicOrAuto() && !style.height().isAuto())
        return;

    IntSize size = Platform::current()->themeEngine()->getSize(WebThemeEngine::PartRadio);
    float zoomLevel = style.effectiveZoom();
    size.setWidth(size.width() * zoomLevel);
    size.setHeight(size.height() * zoomLevel);
    setSizeIfAuto(style, size);
}

void LayoutThemeDefault::adjustInnerSpinButtonStyle(ComputedStyle& style, Element*) const
{
    IntSize size = Platform::current()->themeEngine()->getSize(WebThemeEngine::PartInnerSpinButton);

    style.setWidth(Length(size.width(), Fixed));
    style.setMinWidth(Length(size.width(), Fixed));
}

bool LayoutThemeDefault::shouldOpenPickerWithF4Key() const
{
    return true;
}

bool LayoutThemeDefault::shouldUseFallbackTheme(const ComputedStyle& style) const
{
    if (useMockTheme()) {
        // The mock theme can't handle zoomed controls, so we fall back to the "fallback" theme.
        ControlPart part = style.appearance();
        if (part == CheckboxPart || part == RadioPart)
            return style.effectiveZoom() != 1;
    }
    return LayoutTheme::shouldUseFallbackTheme(style);
}

bool LayoutThemeDefault::supportsHover(const ComputedStyle& style) const
{
    return true;
}

Color LayoutThemeDefault::platformFocusRingColor() const
{
    static Color focusRingColor(229, 151, 0, 255);
    return focusRingColor;
}

double LayoutThemeDefault::caretBlinkInterval() const
{
    // Disable the blinking caret in layout test mode, as it introduces
    // a race condition for the pixel tests. http://b/1198440
    if (LayoutTestSupport::isRunningLayoutTest())
        return 0;

    return m_caretBlinkInterval;
}

void LayoutThemeDefault::systemFont(CSSValueID systemFontID, FontStyle& fontStyle, FontWeight& fontWeight, float& fontSize, AtomicString& fontFamily) const
{
    LayoutThemeFontProvider::systemFont(systemFontID, fontStyle, fontWeight, fontSize, fontFamily);
}

int LayoutThemeDefault::minimumMenuListSize(const ComputedStyle& style) const
{
    return 0;
}

// Return a rectangle that has the same center point as |original|, but with a
// size capped at |width| by |height|.
IntRect center(const IntRect& original, int width, int height)
{
    width = std::min(original.width(), width);
    height = std::min(original.height(), height);
    int x = original.x() + (original.width() - width) / 2;
    int y = original.y() + (original.height() - height) / 2;

    return IntRect(x, y, width, height);
}

void LayoutThemeDefault::adjustButtonStyle(ComputedStyle& style, Element*) const
{
    if (style.appearance() == PushButtonPart) {
        // Ignore line-height.
        style.setLineHeight(ComputedStyle::initialLineHeight());
    }
}

void LayoutThemeDefault::adjustSearchFieldStyle(ComputedStyle& style, Element*) const
{
    // Ignore line-height.
    style.setLineHeight(ComputedStyle::initialLineHeight());
}

void LayoutThemeDefault::adjustSearchFieldCancelButtonStyle(ComputedStyle& style, Element*) const
{
    // Scale the button size based on the font size
    float fontScale = style.fontSize() / defaultControlFontPixelSize;
    int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize));
    style.setWidth(Length(cancelButtonSize, Fixed));
    style.setHeight(Length(cancelButtonSize, Fixed));
}

void LayoutThemeDefault::adjustSearchFieldDecorationStyle(ComputedStyle& style, Element*) const
{
    IntSize emptySize(1, 11);
    style.setWidth(Length(emptySize.width(), Fixed));
    style.setHeight(Length(emptySize.height(), Fixed));
}

void LayoutThemeDefault::adjustSearchFieldResultsDecorationStyle(ComputedStyle& style, Element*) const
{
    // Scale the decoration size based on the font size
    float fontScale = style.fontSize() / defaultControlFontPixelSize;
    int magnifierSize = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale),
        maxSearchFieldResultsDecorationSize));
    style.setWidth(Length(magnifierSize, Fixed));
    style.setHeight(Length(magnifierSize, Fixed));
}

void LayoutThemeDefault::adjustMenuListStyle(ComputedStyle& style, Element*) const
{
    // Height is locked to auto on all browsers.
    style.setLineHeight(ComputedStyle::initialLineHeight());
}

void LayoutThemeDefault::adjustMenuListButtonStyle(ComputedStyle& style, Element* e) const
{
    adjustMenuListStyle(style, e);
}

int LayoutThemeDefault::popupInternalPaddingLeft(const ComputedStyle& style) const
{
    return menuListInternalPadding(style, LeftPadding);
}

int LayoutThemeDefault::popupInternalPaddingRight(const ComputedStyle& style) const
{
    return menuListInternalPadding(style, RightPadding);
}

int LayoutThemeDefault::popupInternalPaddingTop(const ComputedStyle& style) const
{
    return menuListInternalPadding(style, TopPadding);
}

int LayoutThemeDefault::popupInternalPaddingBottom(const ComputedStyle& style) const
{
    return menuListInternalPadding(style, BottomPadding);
}

// static
void LayoutThemeDefault::setDefaultFontSize(int fontSize)
{
    LayoutThemeFontProvider::setDefaultFontSize(fontSize);
}

int LayoutThemeDefault::menuListArrowPadding() const
{
    return ScrollbarTheme::theme()->scrollbarThickness();
}

int LayoutThemeDefault::menuListInternalPadding(const ComputedStyle& style, int paddingType) const
{
    // This internal padding is in addition to the user-supplied padding.
    // Matches the FF behavior.
    int padding = styledMenuListInternalPadding[paddingType];

    // Reserve the space for right arrow here. The rest of the padding is
    // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from
    // LayoutMenuList to lay out the individual items in the popup.
    // If the MenuList actually has appearance "NoAppearance", then that means
    // we don't draw a button, so don't reserve space for it.
    const int barType = style.direction() == LTR ? RightPadding : LeftPadding;
    if (paddingType == barType && style.appearance() != NoControlPart)
        padding += menuListArrowPadding();

    return padding;
}

bool LayoutThemeDefault::shouldShowPlaceholderWhenFocused() const
{
    return true;
}

//
// Following values are come from default of GTK+
//
static const int progressAnimationFrames = 10;
static const double progressAnimationInterval = 0.125;

double LayoutThemeDefault::animationRepeatIntervalForProgressBar() const
{
    return progressAnimationInterval;
}

double LayoutThemeDefault::animationDurationForProgressBar() const
{
    return progressAnimationInterval * progressAnimationFrames * 2; // "2" for back and forth
}

} // namespace blink
<commit_msg>* 改动下拉框hover态颜色，以前的黑字比较难辨认<commit_after>/*
 * Copyright (C) 2007 Apple Inc.
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
 * Copyright (C) 2008 Collabora Ltd.
 * Copyright (C) 2008, 2009 Google Inc.
 * Copyright (C) 2009 Kenneth Rohde Christiansen
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "core/layout/LayoutThemeDefault.h"

#include "core/CSSValueKeywords.h"
#include "core/layout/LayoutObject.h"
#include "core/layout/LayoutProgress.h"
#include "core/layout/LayoutThemeFontProvider.h"
#include "core/paint/MediaControlsPainter.h"
#include "platform/LayoutTestSupport.h"
#include "platform/PlatformResourceLoader.h"
#include "platform/graphics/Color.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "public/platform/Platform.h"
#include "public/platform/WebThemeEngine.h"

namespace blink {

enum PaddingType {
    TopPadding,
    RightPadding,
    BottomPadding,
    LeftPadding
};

static const int styledMenuListInternalPadding[4] = { 1, 4, 1, 4 };

// These values all match Safari/Win.
static const float defaultControlFontPixelSize = 13;
static const float defaultCancelButtonSize = 9;
static const float minCancelButtonSize = 5;
static const float maxCancelButtonSize = 21;
static const float defaultSearchFieldResultsDecorationSize = 13;
static const float minSearchFieldResultsDecorationSize = 9;
static const float maxSearchFieldResultsDecorationSize = 30;

static bool useMockTheme()
{
    return LayoutTestSupport::isRunningLayoutTest();
}

unsigned LayoutThemeDefault::m_activeSelectionBackgroundColor = 0xff1e90ff;
unsigned LayoutThemeDefault::m_activeSelectionForegroundColor = Color::white; // Color::black;
unsigned LayoutThemeDefault::m_inactiveSelectionBackgroundColor = 0xffc8c8c8;
unsigned LayoutThemeDefault::m_inactiveSelectionForegroundColor = 0xff323232;

double LayoutThemeDefault::m_caretBlinkInterval;

LayoutThemeDefault::LayoutThemeDefault()
{
    m_caretBlinkInterval = LayoutTheme::caretBlinkInterval();
}

LayoutThemeDefault::~LayoutThemeDefault()
{
}

bool LayoutThemeDefault::supportsFocusRing(const ComputedStyle& style) const
{
    if (useMockTheme()) {
        // Don't use focus rings for buttons when mocking controls.
        return style.appearance() == ButtonPart
            || style.appearance() == PushButtonPart
            || style.appearance() == SquareButtonPart;
    }

    // This causes Blink to draw the focus rings for us.
    return false;
}

Color LayoutThemeDefault::systemColor(CSSValueID cssValueId) const
{
    static const Color defaultButtonGrayColor(0xffdddddd);
    static const Color defaultMenuColor(0xfff7f7f7);

    if (cssValueId == CSSValueButtonface) {
        if (useMockTheme())
            return Color(0xc0, 0xc0, 0xc0);
        return defaultButtonGrayColor;
    }
    if (cssValueId == CSSValueMenu)
        return defaultMenuColor;
    return LayoutTheme::systemColor(cssValueId);
}

// Use the Windows style sheets to match their metrics.
String LayoutThemeDefault::extraDefaultStyleSheet()
{
    return LayoutTheme::extraDefaultStyleSheet()
        + loadResourceAsASCIIString("themeWin.css")
        + loadResourceAsASCIIString("themeChromiumSkia.css")
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
        + loadResourceAsASCIIString("themeInputMultipleFields.css")
#endif
        + loadResourceAsASCIIString("themeChromium.css");
}

String LayoutThemeDefault::extraQuirksStyleSheet()
{
    return loadResourceAsASCIIString("themeWinQuirks.css");
}

Color LayoutThemeDefault::activeListBoxSelectionBackgroundColor() const
{
    return Color(0x28, 0x28, 0x28);
}

Color LayoutThemeDefault::activeListBoxSelectionForegroundColor() const
{
    return Color::black;
}

Color LayoutThemeDefault::inactiveListBoxSelectionBackgroundColor() const
{
    return Color(0xc8, 0xc8, 0xc8);
}

Color LayoutThemeDefault::inactiveListBoxSelectionForegroundColor() const
{
    return Color(0x32, 0x32, 0x32);
}

Color LayoutThemeDefault::platformActiveSelectionBackgroundColor() const
{
    if (useMockTheme())
        return Color(0x00, 0x00, 0xff); // Royal blue.
    return m_activeSelectionBackgroundColor;
}

Color LayoutThemeDefault::platformInactiveSelectionBackgroundColor() const
{
    if (useMockTheme())
        return Color(0x99, 0x99, 0x99); // Medium gray.
    return m_inactiveSelectionBackgroundColor;
}

Color LayoutThemeDefault::platformActiveSelectionForegroundColor() const
{
    if (useMockTheme())
        return Color(0xff, 0xff, 0xcc); // Pale yellow.
    return m_activeSelectionForegroundColor;
}

Color LayoutThemeDefault::platformInactiveSelectionForegroundColor() const
{
    if (useMockTheme())
        return Color::white;
    return m_inactiveSelectionForegroundColor;
}

IntSize LayoutThemeDefault::sliderTickSize() const
{
    if (useMockTheme())
        return IntSize(1, 3);
    return IntSize(1, 6);
}

int LayoutThemeDefault::sliderTickOffsetFromTrackCenter() const
{
    if (useMockTheme())
        return 11;
    return -16;
}

void LayoutThemeDefault::adjustSliderThumbSize(ComputedStyle& style, Element* element) const
{
    IntSize size = Platform::current()->themeEngine()->getSize(WebThemeEngine::PartSliderThumb);

    // FIXME: Mock theme doesn't handle zoomed sliders.
    float zoomLevel = useMockTheme() ? 1 : style.effectiveZoom();
    if (style.appearance() == SliderThumbHorizontalPart) {
        style.setWidth(Length(size.width() * zoomLevel, Fixed));
        style.setHeight(Length(size.height() * zoomLevel, Fixed));
    } else if (style.appearance() == SliderThumbVerticalPart) {
        style.setWidth(Length(size.height() * zoomLevel, Fixed));
        style.setHeight(Length(size.width() * zoomLevel, Fixed));
    } else {
        MediaControlsPainter::adjustMediaSliderThumbSize(style);
    }
}

void LayoutThemeDefault::setCaretBlinkInterval(double interval)
{
    m_caretBlinkInterval = interval;
}

void LayoutThemeDefault::setSelectionColors(
    unsigned activeBackgroundColor,
    unsigned activeForegroundColor,
    unsigned inactiveBackgroundColor,
    unsigned inactiveForegroundColor)
{
    m_activeSelectionBackgroundColor = activeBackgroundColor;
    m_activeSelectionForegroundColor = activeForegroundColor;
    m_inactiveSelectionBackgroundColor = inactiveBackgroundColor;
    m_inactiveSelectionForegroundColor = inactiveForegroundColor;
}

void LayoutThemeDefault::setCheckboxSize(ComputedStyle& style) const
{
    // If the width and height are both specified, then we have nothing to do.
    if (!style.width().isIntrinsicOrAuto() && !style.height().isAuto())
        return;

    IntSize size = Platform::current()->themeEngine()->getSize(WebThemeEngine::PartCheckbox);
    float zoomLevel = style.effectiveZoom();
    size.setWidth(size.width() * zoomLevel);
    size.setHeight(size.height() * zoomLevel);
    setSizeIfAuto(style, size);
}

void LayoutThemeDefault::setRadioSize(ComputedStyle& style) const
{
    // If the width and height are both specified, then we have nothing to do.
    if (!style.width().isIntrinsicOrAuto() && !style.height().isAuto())
        return;

    IntSize size = Platform::current()->themeEngine()->getSize(WebThemeEngine::PartRadio);
    float zoomLevel = style.effectiveZoom();
    size.setWidth(size.width() * zoomLevel);
    size.setHeight(size.height() * zoomLevel);
    setSizeIfAuto(style, size);
}

void LayoutThemeDefault::adjustInnerSpinButtonStyle(ComputedStyle& style, Element*) const
{
    IntSize size = Platform::current()->themeEngine()->getSize(WebThemeEngine::PartInnerSpinButton);

    style.setWidth(Length(size.width(), Fixed));
    style.setMinWidth(Length(size.width(), Fixed));
}

bool LayoutThemeDefault::shouldOpenPickerWithF4Key() const
{
    return true;
}

bool LayoutThemeDefault::shouldUseFallbackTheme(const ComputedStyle& style) const
{
    if (useMockTheme()) {
        // The mock theme can't handle zoomed controls, so we fall back to the "fallback" theme.
        ControlPart part = style.appearance();
        if (part == CheckboxPart || part == RadioPart)
            return style.effectiveZoom() != 1;
    }
    return LayoutTheme::shouldUseFallbackTheme(style);
}

bool LayoutThemeDefault::supportsHover(const ComputedStyle& style) const
{
    return true;
}

Color LayoutThemeDefault::platformFocusRingColor() const
{
    static Color focusRingColor(229, 151, 0, 255);
    return focusRingColor;
}

double LayoutThemeDefault::caretBlinkInterval() const
{
    // Disable the blinking caret in layout test mode, as it introduces
    // a race condition for the pixel tests. http://b/1198440
    if (LayoutTestSupport::isRunningLayoutTest())
        return 0;

    return m_caretBlinkInterval;
}

void LayoutThemeDefault::systemFont(CSSValueID systemFontID, FontStyle& fontStyle, FontWeight& fontWeight, float& fontSize, AtomicString& fontFamily) const
{
    LayoutThemeFontProvider::systemFont(systemFontID, fontStyle, fontWeight, fontSize, fontFamily);
}

int LayoutThemeDefault::minimumMenuListSize(const ComputedStyle& style) const
{
    return 0;
}

// Return a rectangle that has the same center point as |original|, but with a
// size capped at |width| by |height|.
IntRect center(const IntRect& original, int width, int height)
{
    width = std::min(original.width(), width);
    height = std::min(original.height(), height);
    int x = original.x() + (original.width() - width) / 2;
    int y = original.y() + (original.height() - height) / 2;

    return IntRect(x, y, width, height);
}

void LayoutThemeDefault::adjustButtonStyle(ComputedStyle& style, Element*) const
{
    if (style.appearance() == PushButtonPart) {
        // Ignore line-height.
        style.setLineHeight(ComputedStyle::initialLineHeight());
    }
}

void LayoutThemeDefault::adjustSearchFieldStyle(ComputedStyle& style, Element*) const
{
    // Ignore line-height.
    style.setLineHeight(ComputedStyle::initialLineHeight());
}

void LayoutThemeDefault::adjustSearchFieldCancelButtonStyle(ComputedStyle& style, Element*) const
{
    // Scale the button size based on the font size
    float fontScale = style.fontSize() / defaultControlFontPixelSize;
    int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize));
    style.setWidth(Length(cancelButtonSize, Fixed));
    style.setHeight(Length(cancelButtonSize, Fixed));
}

void LayoutThemeDefault::adjustSearchFieldDecorationStyle(ComputedStyle& style, Element*) const
{
    IntSize emptySize(1, 11);
    style.setWidth(Length(emptySize.width(), Fixed));
    style.setHeight(Length(emptySize.height(), Fixed));
}

void LayoutThemeDefault::adjustSearchFieldResultsDecorationStyle(ComputedStyle& style, Element*) const
{
    // Scale the decoration size based on the font size
    float fontScale = style.fontSize() / defaultControlFontPixelSize;
    int magnifierSize = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale),
        maxSearchFieldResultsDecorationSize));
    style.setWidth(Length(magnifierSize, Fixed));
    style.setHeight(Length(magnifierSize, Fixed));
}

void LayoutThemeDefault::adjustMenuListStyle(ComputedStyle& style, Element*) const
{
    // Height is locked to auto on all browsers.
    style.setLineHeight(ComputedStyle::initialLineHeight());
}

void LayoutThemeDefault::adjustMenuListButtonStyle(ComputedStyle& style, Element* e) const
{
    adjustMenuListStyle(style, e);
}

int LayoutThemeDefault::popupInternalPaddingLeft(const ComputedStyle& style) const
{
    return menuListInternalPadding(style, LeftPadding);
}

int LayoutThemeDefault::popupInternalPaddingRight(const ComputedStyle& style) const
{
    return menuListInternalPadding(style, RightPadding);
}

int LayoutThemeDefault::popupInternalPaddingTop(const ComputedStyle& style) const
{
    return menuListInternalPadding(style, TopPadding);
}

int LayoutThemeDefault::popupInternalPaddingBottom(const ComputedStyle& style) const
{
    return menuListInternalPadding(style, BottomPadding);
}

// static
void LayoutThemeDefault::setDefaultFontSize(int fontSize)
{
    LayoutThemeFontProvider::setDefaultFontSize(fontSize);
}

int LayoutThemeDefault::menuListArrowPadding() const
{
    return ScrollbarTheme::theme()->scrollbarThickness();
}

int LayoutThemeDefault::menuListInternalPadding(const ComputedStyle& style, int paddingType) const
{
    // This internal padding is in addition to the user-supplied padding.
    // Matches the FF behavior.
    int padding = styledMenuListInternalPadding[paddingType];

    // Reserve the space for right arrow here. The rest of the padding is
    // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from
    // LayoutMenuList to lay out the individual items in the popup.
    // If the MenuList actually has appearance "NoAppearance", then that means
    // we don't draw a button, so don't reserve space for it.
    const int barType = style.direction() == LTR ? RightPadding : LeftPadding;
    if (paddingType == barType && style.appearance() != NoControlPart)
        padding += menuListArrowPadding();

    return padding;
}

bool LayoutThemeDefault::shouldShowPlaceholderWhenFocused() const
{
    return true;
}

//
// Following values are come from default of GTK+
//
static const int progressAnimationFrames = 10;
static const double progressAnimationInterval = 0.125;

double LayoutThemeDefault::animationRepeatIntervalForProgressBar() const
{
    return progressAnimationInterval;
}

double LayoutThemeDefault::animationDurationForProgressBar() const
{
    return progressAnimationInterval * progressAnimationFrames * 2; // "2" for back and forth
}

} // namespace blink
<|endoftext|>


<commit_before>#include <QtCore/QCoreApplication>
#include <QtCore/QEvent>
#include <QtCore/QHash>
#include <QtCore/QMultiHash>
#include <QtCore/QSocketNotifier>
#include <QtCore/QThread>
#include <event2/event.h>
#include <event2/thread.h>
#include <unistd.h>
#include "eventdispatcher_libevent.h"

static int make_pipe(int pipefd[2])
{
	int res = ::pipe(pipefd);
	if (-1 == res) {
		return res;
	}

	evutil_make_socket_closeonexec(pipefd[0]);
	evutil_make_socket_nonblocking(pipefd[0]);

	evutil_make_socket_closeonexec(pipefd[1]);
	evutil_make_socket_nonblocking(pipefd[1]);

	return 0;
}

class EventDispatcherLibEventPrivate {
public:
	EventDispatcherLibEventPrivate(EventDispatcherLibEvent* const q);
	~EventDispatcherLibEventPrivate(void);
	bool processEvents(QEventLoop::ProcessEventsFlags flags);
	void registerSocketNotifier(QSocketNotifier* notifier);
	void unregisterSocketNotifier(QSocketNotifier* notifier);
	void registerTimer(int timerId, int interval, QObject* object);
	bool unregisterTimer(int timerId);
	bool unregisterTimers(QObject* object);
	QList<QAbstractEventDispatcher::TimerInfo> registeredTimers(QObject* object) const;

	struct SocketNotifierInfo {
		QSocketNotifier* sn;
		struct event* ev;
	};

	struct TimerInfo {
		EventDispatcherLibEventPrivate* self;
		struct event* ev;
		int timerId;
		int interval;
		QObject* object;
	};

	typedef QMultiHash<evutil_socket_t, SocketNotifierInfo> SocketNotifierHash;
	typedef QHash<int, TimerInfo*> TimerHash;

private:
	Q_DISABLE_COPY(EventDispatcherLibEventPrivate)
	Q_DECLARE_PUBLIC(EventDispatcherLibEvent)
	EventDispatcherLibEvent* const q_ptr;

	bool m_interrupt;
	int m_thread_pipe[2];
	struct event_base* m_base;
	struct event* m_wakeup;
	SocketNotifierHash m_notifiers;
	TimerHash m_timers;

	static void socket_notifier_callback(evutil_socket_t fd, short int events, void* arg);
	static void timer_callback(evutil_socket_t fd, short int events, void* arg);
	static void wake_up_handler(evutil_socket_t fd, short int events, void* arg);
};

EventDispatcherLibEventPrivate::EventDispatcherLibEventPrivate(EventDispatcherLibEvent* const q)
	: q_ptr(q), m_interrupt(false), m_thread_pipe(), m_base(0), m_wakeup(0),
	  m_notifiers(), m_timers()
{
	this->m_base = event_base_new();

	if (-1 == make_pipe(this->m_thread_pipe)) {
#ifndef QT_NO_DEBUG
		qFatal("%s: Unable to create pipe", Q_FUNC_INFO);
#else
		qErrnoWarning("%s: Unable to create pipe", Q_FUNC_INFO);
#endif

		m_thread_pipe[0] = -1;
		m_thread_pipe[1] = -1;
	}
	else {
		this->m_wakeup = event_new(this->m_base, this->m_thread_pipe[0], EV_READ | EV_PERSIST, EventDispatcherLibEventPrivate::wake_up_handler, 0);
		event_add(this->m_wakeup, 0);
	}
}

EventDispatcherLibEventPrivate::~EventDispatcherLibEventPrivate(void)
{
	if (this->m_thread_pipe[0] != -1) {
		evutil_closesocket(this->m_thread_pipe[0]);
	}

	if (this->m_thread_pipe[1] != -1) {
		evutil_closesocket(this->m_thread_pipe[1]);
	}

	if (this->m_wakeup) {
		event_del(this->m_wakeup);
		event_free(this->m_wakeup);
		this->m_wakeup = 0;
	}

	if (this->m_base) {
		event_base_free(this->m_base);
		this->m_base = 0;
	}
}

bool EventDispatcherLibEventPrivate::processEvents(QEventLoop::ProcessEventsFlags flags)
{
	Q_Q(EventDispatcherLibEvent);

	Q_EMIT q->awake();
	QCoreApplication::sendPostedEvents();

	const bool canWait = (!this->m_interrupt && (flags & QEventLoop::WaitForMoreEvents));

	do {
		if (canWait) {
			Q_EMIT q->aboutToBlock();
			event_base_loop(this->m_base, EVLOOP_ONCE);
		}
		else {
			event_base_loop(this->m_base, EVLOOP_NONBLOCK | EVLOOP_ONCE);
		}

		QCoreApplication::sendPostedEvents();
	} while (!this->m_interrupt && !canWait);

	this->m_interrupt = false;
	return true;
}

void EventDispatcherLibEventPrivate::registerSocketNotifier(QSocketNotifier* notifier)
{
	evutil_socket_t sockfd = notifier->socket();
	short int what;
	switch (notifier->type()) {
		case QSocketNotifier::Read:  what = EV_READ; break;
		case QSocketNotifier::Write: what = EV_WRITE; break;
		case QSocketNotifier::Exception: /// FIXME
			return;

		default:
			Q_ASSERT(false);
			return;
	}

	what |= EV_PERSIST;
	struct event* ev = event_new(this->m_base, sockfd, what, EventDispatcherLibEventPrivate::socket_notifier_callback, this);
	event_add(ev, 0);

	SocketNotifierInfo data;
	data.sn = notifier;
	data.ev = ev;
	this->m_notifiers.insertMulti(sockfd, data);
}

void EventDispatcherLibEventPrivate::unregisterSocketNotifier(QSocketNotifier* notifier)
{
	evutil_socket_t sockfd = notifier->socket();
	SocketNotifierHash::Iterator it = this->m_notifiers.find(sockfd);
	while (it != this->m_notifiers.end() && it.key() == sockfd) {
		SocketNotifierInfo& data = it.value();
		if (data.sn == notifier) {
			event_del(data.ev);
			event_free(data.ev);
			it = this->m_notifiers.erase(it);
		}
		else {
			++it;
		}
	}
}

void EventDispatcherLibEventPrivate::registerTimer(int timerId, int interval, QObject* object)
{
	EventDispatcherLibEventPrivate::TimerInfo* info = new EventDispatcherLibEventPrivate::TimerInfo;
	info->self     = this;
	info->ev       = event_new(this->m_base, -1, EV_PERSIST, EventDispatcherLibEventPrivate::timer_callback, info);
	info->timerId  = timerId;
	info->interval = interval;
	info->object   = object;

	struct timeval tv;
	tv.tv_sec  = interval / 1000;
	tv.tv_usec = interval % 1000;
	event_add(info->ev, &tv);

	this->m_timers.insert(timerId, info);
}

bool EventDispatcherLibEventPrivate::unregisterTimer(int timerId)
{
	TimerHash::Iterator it = this->m_timers.find(timerId);
	if (it != this->m_timers.end()) {
		EventDispatcherLibEventPrivate::TimerInfo* info = it.value();
		event_del(info->ev);
		event_free(info->ev);
		delete info;
		this->m_timers.erase(it);
		return true;
	}

	return false;
}

bool EventDispatcherLibEventPrivate::unregisterTimers(QObject* object)
{
	TimerHash::Iterator it = this->m_timers.begin();
	while (it != this->m_timers.end()) {
		EventDispatcherLibEventPrivate::TimerInfo* info = it.value();
		if (object == info->object) {
			event_del(info->ev);
			event_free(info->ev);
			delete info;
			it = this->m_timers.erase(it);
		}
		else {
			++it;
		}
	}

	return true;
}

QList<QAbstractEventDispatcher::TimerInfo> EventDispatcherLibEventPrivate::registeredTimers(QObject* object) const
{
	QList<QAbstractEventDispatcher::TimerInfo> res;

	TimerHash::ConstIterator it = this->m_timers.constBegin();
	while (it != this->m_timers.constEnd()) {
		EventDispatcherLibEventPrivate::TimerInfo* info = it.value();
		if (object == info->object) {
			QAbstractEventDispatcher::TimerInfo ti(it.key(), info->interval);
			res.append(ti);
			++it;
		}
	}

	return res;
}

void EventDispatcherLibEventPrivate::socket_notifier_callback(int fd, short int events, void* arg)
{
	EventDispatcherLibEventPrivate* disp = reinterpret_cast<EventDispatcherLibEventPrivate*>(arg);
	SocketNotifierHash::Iterator it = disp->m_notifiers.find(fd);
	while (it != disp->m_notifiers.end() && it.key() == fd) {
		SocketNotifierInfo& data = it.value();
		QSocketNotifier::Type type = data.sn->type();

		if ((QSocketNotifier::Read == type && (events & EV_READ)) || (QSocketNotifier::Write == type && (events & EV_WRITE))) {
			QEvent e(QEvent::SockAct);
			QCoreApplication::sendEvent(data.sn, &e);
		}

		++it;
	}
}

void EventDispatcherLibEventPrivate::timer_callback(int fd, short int events, void* arg)
{
	Q_ASSERT(-1 == fd);
	Q_ASSERT(events & EV_TIMEOUT);
	Q_UNUSED(fd)
	Q_UNUSED(events)

	EventDispatcherLibEventPrivate::TimerInfo* info = reinterpret_cast<EventDispatcherLibEventPrivate::TimerInfo*>(arg);
	QTimerEvent event(info->timerId);
	QCoreApplication::sendEvent(info->object, &event);
}

void EventDispatcherLibEventPrivate::wake_up_handler(int fd, short int events, void* arg)
{
	Q_UNUSED(events)
	Q_UNUSED(arg)

	char buf[256];
	while (::read(fd, buf, 256) > 0) {
		// Do nothing
	}
}

EventDispatcherLibEvent::EventDispatcherLibEvent(QObject* parent)
	: QAbstractEventDispatcher(parent), d_ptr(new EventDispatcherLibEventPrivate(this))
{
}

EventDispatcherLibEvent::~EventDispatcherLibEvent(void)
{
}

bool EventDispatcherLibEvent::processEvents(QEventLoop::ProcessEventsFlags flags)
{
	Q_D(EventDispatcherLibEvent);
	return d->processEvents(flags);
}

bool EventDispatcherLibEvent::hasPendingEvents(void)
{
	extern Q_CORE_EXPORT uint qGlobalPostedEventsCount();
	return qGlobalPostedEventsCount() > 0;
}

void EventDispatcherLibEvent::registerSocketNotifier(QSocketNotifier* notifier)
{
#ifndef QT_NO_DEBUG
	if (notifier->socket() < 0) {
		qWarning("QSocketNotifier: Internal error: sockfd < 0");
		return;
	}
	else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
		qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
		return;
	}
#endif

	if (notifier->type() == QSocketNotifier::Exception) {
		return;
	}

	Q_D(EventDispatcherLibEvent);
	d->registerSocketNotifier(notifier);
}

void EventDispatcherLibEvent::unregisterSocketNotifier(QSocketNotifier* notifier)
{
#ifndef QT_NO_DEBUG
	if (notifier->socket() < 0) {
		qWarning("QSocketNotifier: Internal error: sockfd < 0");
		return;
	}
	else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
		qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
		return;
	}
#endif

	// Short circuit, we do not support QSocketNotifier::Exception
	if (notifier->type() == QSocketNotifier::Exception) {
		return;
	}

	Q_D(EventDispatcherLibEvent);
	d->unregisterSocketNotifier(notifier);
}

void EventDispatcherLibEvent::registerTimer(int timerId, int interval, QObject* object)
{
#ifndef QT_NO_DEBUG
	if (timerId < 1 || interval < 0 || !object) {
		qWarning("%s: invalid arguments", Q_FUNC_INFO);
		return;
	}

	if (object->thread() != this->thread() && this->thread() != QThread::currentThread()) {
		qWarning("%s: timers cannot be started from another thread", Q_FUNC_INFO);
		return;
	}
#endif

	Q_D(EventDispatcherLibEvent);
	d->registerTimer(timerId, interval, object);
}

bool EventDispatcherLibEvent::unregisterTimer(int timerId)
{
#ifndef QT_NO_DEBUG
	if (timerId < 1) {
		qWarning("%s: invalid arguments", Q_FUNC_INFO);
		return;
	}

	if (this->thread() != QThread::currentThread()) {
		qWarning("%s: timers cannot be stopped from another thread", Q_FUNC_INFO);
		return;
	}
#endif

	Q_D(EventDispatcherLibEvent);
	return d->unregisterTimer(timerId);
}

bool EventDispatcherLibEvent::unregisterTimers(QObject* object)
{
#ifndef QT_NO_DEBUG
	if (!object) {
		qWarning("%s: invalid arguments", Q_FUNC_INFO);
		return;
	}

	if (object->thread() != this->thread() && this->thread() != QThread::currentThread()) {
		qWarning("%s: timers cannot be stopped from another thread", Q_FUNC_INFO);
		return;
	}
#endif

	Q_D(EventDispatcherLibEvent);
	return d->unregisterTimers(object);
}

QList<QAbstractEventDispatcher::TimerInfo> EventDispatcherLibEvent::registeredTimers(QObject* object) const
{
	if (!object) {
		qWarning("%s: invalid argument", Q_FUNC_INFO);
		return QList<QAbstractEventDispatcher::TimerInfo>();
	}

	Q_D(const EventDispatcherLibEvent);
	return d->registeredTimers(object);
}

void EventDispatcherLibEvent::wakeUp(void)
{
	Q_D(EventDispatcherLibEvent);

	if (d->m_thread_pipe[1] != -1) {
		if (::write(d->m_thread_pipe[1], "w", 1) != 1) {
			// Avoid compiler's warning
		}
	}
}

void EventDispatcherLibEvent::interrupt(void)
{
	Q_D(EventDispatcherLibEvent);
	d->m_interrupt = true;
	this->wakeUp();
}

void EventDispatcherLibEvent::flush(void)
{
}
<commit_msg>tv_sec is 1,000,000 tv_usec, not 1,000<commit_after>#include <QtCore/QCoreApplication>
#include <QtCore/QEvent>
#include <QtCore/QHash>
#include <QtCore/QMultiHash>
#include <QtCore/QSocketNotifier>
#include <QtCore/QThread>
#include <event2/event.h>
#include <event2/thread.h>
#include <unistd.h>
#include "eventdispatcher_libevent.h"

static int make_pipe(int pipefd[2])
{
	int res = ::pipe(pipefd);
	if (-1 == res) {
		return res;
	}

	evutil_make_socket_closeonexec(pipefd[0]);
	evutil_make_socket_nonblocking(pipefd[0]);

	evutil_make_socket_closeonexec(pipefd[1]);
	evutil_make_socket_nonblocking(pipefd[1]);

	return 0;
}

class EventDispatcherLibEventPrivate {
public:
	EventDispatcherLibEventPrivate(EventDispatcherLibEvent* const q);
	~EventDispatcherLibEventPrivate(void);
	bool processEvents(QEventLoop::ProcessEventsFlags flags);
	void registerSocketNotifier(QSocketNotifier* notifier);
	void unregisterSocketNotifier(QSocketNotifier* notifier);
	void registerTimer(int timerId, int interval, QObject* object);
	bool unregisterTimer(int timerId);
	bool unregisterTimers(QObject* object);
	QList<QAbstractEventDispatcher::TimerInfo> registeredTimers(QObject* object) const;

	struct SocketNotifierInfo {
		QSocketNotifier* sn;
		struct event* ev;
	};

	struct TimerInfo {
		EventDispatcherLibEventPrivate* self;
		struct event* ev;
		int timerId;
		int interval;
		QObject* object;
	};

	typedef QMultiHash<evutil_socket_t, SocketNotifierInfo> SocketNotifierHash;
	typedef QHash<int, TimerInfo*> TimerHash;

private:
	Q_DISABLE_COPY(EventDispatcherLibEventPrivate)
	Q_DECLARE_PUBLIC(EventDispatcherLibEvent)
	EventDispatcherLibEvent* const q_ptr;

	bool m_interrupt;
	int m_thread_pipe[2];
	struct event_base* m_base;
	struct event* m_wakeup;
	SocketNotifierHash m_notifiers;
	TimerHash m_timers;

	static void socket_notifier_callback(evutil_socket_t fd, short int events, void* arg);
	static void timer_callback(evutil_socket_t fd, short int events, void* arg);
	static void wake_up_handler(evutil_socket_t fd, short int events, void* arg);
};

EventDispatcherLibEventPrivate::EventDispatcherLibEventPrivate(EventDispatcherLibEvent* const q)
	: q_ptr(q), m_interrupt(false), m_thread_pipe(), m_base(0), m_wakeup(0),
	  m_notifiers(), m_timers()
{
	this->m_base = event_base_new();

	if (-1 == make_pipe(this->m_thread_pipe)) {
#ifndef QT_NO_DEBUG
		qFatal("%s: Unable to create pipe", Q_FUNC_INFO);
#else
		qErrnoWarning("%s: Unable to create pipe", Q_FUNC_INFO);
#endif

		m_thread_pipe[0] = -1;
		m_thread_pipe[1] = -1;
	}
	else {
		this->m_wakeup = event_new(this->m_base, this->m_thread_pipe[0], EV_READ | EV_PERSIST, EventDispatcherLibEventPrivate::wake_up_handler, 0);
		event_add(this->m_wakeup, 0);
	}
}

EventDispatcherLibEventPrivate::~EventDispatcherLibEventPrivate(void)
{
	if (this->m_thread_pipe[0] != -1) {
		evutil_closesocket(this->m_thread_pipe[0]);
	}

	if (this->m_thread_pipe[1] != -1) {
		evutil_closesocket(this->m_thread_pipe[1]);
	}

	if (this->m_wakeup) {
		event_del(this->m_wakeup);
		event_free(this->m_wakeup);
		this->m_wakeup = 0;
	}

	if (this->m_base) {
		event_base_free(this->m_base);
		this->m_base = 0;
	}
}

bool EventDispatcherLibEventPrivate::processEvents(QEventLoop::ProcessEventsFlags flags)
{
	Q_Q(EventDispatcherLibEvent);

	Q_EMIT q->awake();
	QCoreApplication::sendPostedEvents();

	const bool canWait = (!this->m_interrupt && (flags & QEventLoop::WaitForMoreEvents));

	do {
		if (canWait) {
			Q_EMIT q->aboutToBlock();
			event_base_loop(this->m_base, EVLOOP_ONCE);
		}
		else {
			event_base_loop(this->m_base, EVLOOP_NONBLOCK | EVLOOP_ONCE);
		}

		QCoreApplication::sendPostedEvents();
	} while (!this->m_interrupt && !canWait);

	this->m_interrupt = false;
	return true;
}

void EventDispatcherLibEventPrivate::registerSocketNotifier(QSocketNotifier* notifier)
{
	evutil_socket_t sockfd = notifier->socket();
	short int what;
	switch (notifier->type()) {
		case QSocketNotifier::Read:  what = EV_READ; break;
		case QSocketNotifier::Write: what = EV_WRITE; break;
		case QSocketNotifier::Exception: /// FIXME
			return;

		default:
			Q_ASSERT(false);
			return;
	}

	what |= EV_PERSIST;
	struct event* ev = event_new(this->m_base, sockfd, what, EventDispatcherLibEventPrivate::socket_notifier_callback, this);
	event_add(ev, 0);

	SocketNotifierInfo data;
	data.sn = notifier;
	data.ev = ev;
	this->m_notifiers.insertMulti(sockfd, data);
}

void EventDispatcherLibEventPrivate::unregisterSocketNotifier(QSocketNotifier* notifier)
{
	evutil_socket_t sockfd = notifier->socket();
	SocketNotifierHash::Iterator it = this->m_notifiers.find(sockfd);
	while (it != this->m_notifiers.end() && it.key() == sockfd) {
		SocketNotifierInfo& data = it.value();
		if (data.sn == notifier) {
			event_del(data.ev);
			event_free(data.ev);
			it = this->m_notifiers.erase(it);
		}
		else {
			++it;
		}
	}
}

void EventDispatcherLibEventPrivate::registerTimer(int timerId, int interval, QObject* object)
{
	EventDispatcherLibEventPrivate::TimerInfo* info = new EventDispatcherLibEventPrivate::TimerInfo;
	info->self     = this;
	info->ev       = event_new(this->m_base, -1, EV_PERSIST, EventDispatcherLibEventPrivate::timer_callback, info);
	info->timerId  = timerId;
	info->interval = interval;
	info->object   = object;

	struct timeval tv;
	tv.tv_sec  = interval / 1000000;
	tv.tv_usec = interval % 1000000;
	event_add(info->ev, &tv);

	this->m_timers.insert(timerId, info);
}

bool EventDispatcherLibEventPrivate::unregisterTimer(int timerId)
{
	TimerHash::Iterator it = this->m_timers.find(timerId);
	if (it != this->m_timers.end()) {
		EventDispatcherLibEventPrivate::TimerInfo* info = it.value();
		event_del(info->ev);
		event_free(info->ev);
		delete info;
		this->m_timers.erase(it);
		return true;
	}

	return false;
}

bool EventDispatcherLibEventPrivate::unregisterTimers(QObject* object)
{
	TimerHash::Iterator it = this->m_timers.begin();
	while (it != this->m_timers.end()) {
		EventDispatcherLibEventPrivate::TimerInfo* info = it.value();
		if (object == info->object) {
			event_del(info->ev);
			event_free(info->ev);
			delete info;
			it = this->m_timers.erase(it);
		}
		else {
			++it;
		}
	}

	return true;
}

QList<QAbstractEventDispatcher::TimerInfo> EventDispatcherLibEventPrivate::registeredTimers(QObject* object) const
{
	QList<QAbstractEventDispatcher::TimerInfo> res;

	TimerHash::ConstIterator it = this->m_timers.constBegin();
	while (it != this->m_timers.constEnd()) {
		EventDispatcherLibEventPrivate::TimerInfo* info = it.value();
		if (object == info->object) {
			QAbstractEventDispatcher::TimerInfo ti(it.key(), info->interval);
			res.append(ti);
			++it;
		}
	}

	return res;
}

void EventDispatcherLibEventPrivate::socket_notifier_callback(int fd, short int events, void* arg)
{
	EventDispatcherLibEventPrivate* disp = reinterpret_cast<EventDispatcherLibEventPrivate*>(arg);
	SocketNotifierHash::Iterator it = disp->m_notifiers.find(fd);
	while (it != disp->m_notifiers.end() && it.key() == fd) {
		SocketNotifierInfo& data = it.value();
		QSocketNotifier::Type type = data.sn->type();

		if ((QSocketNotifier::Read == type && (events & EV_READ)) || (QSocketNotifier::Write == type && (events & EV_WRITE))) {
			QEvent e(QEvent::SockAct);
			QCoreApplication::sendEvent(data.sn, &e);
		}

		++it;
	}
}

void EventDispatcherLibEventPrivate::timer_callback(int fd, short int events, void* arg)
{
	Q_ASSERT(-1 == fd);
	Q_ASSERT(events & EV_TIMEOUT);
	Q_UNUSED(fd)
	Q_UNUSED(events)

	EventDispatcherLibEventPrivate::TimerInfo* info = reinterpret_cast<EventDispatcherLibEventPrivate::TimerInfo*>(arg);
	QTimerEvent event(info->timerId);
	QCoreApplication::sendEvent(info->object, &event);
}

void EventDispatcherLibEventPrivate::wake_up_handler(int fd, short int events, void* arg)
{
	Q_UNUSED(events)
	Q_UNUSED(arg)

	char buf[256];
	while (::read(fd, buf, 256) > 0) {
		// Do nothing
	}
}

EventDispatcherLibEvent::EventDispatcherLibEvent(QObject* parent)
	: QAbstractEventDispatcher(parent), d_ptr(new EventDispatcherLibEventPrivate(this))
{
}

EventDispatcherLibEvent::~EventDispatcherLibEvent(void)
{
}

bool EventDispatcherLibEvent::processEvents(QEventLoop::ProcessEventsFlags flags)
{
	Q_D(EventDispatcherLibEvent);
	return d->processEvents(flags);
}

bool EventDispatcherLibEvent::hasPendingEvents(void)
{
	extern Q_CORE_EXPORT uint qGlobalPostedEventsCount();
	return qGlobalPostedEventsCount() > 0;
}

void EventDispatcherLibEvent::registerSocketNotifier(QSocketNotifier* notifier)
{
#ifndef QT_NO_DEBUG
	if (notifier->socket() < 0) {
		qWarning("QSocketNotifier: Internal error: sockfd < 0");
		return;
	}
	else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
		qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
		return;
	}
#endif

	if (notifier->type() == QSocketNotifier::Exception) {
		return;
	}

	Q_D(EventDispatcherLibEvent);
	d->registerSocketNotifier(notifier);
}

void EventDispatcherLibEvent::unregisterSocketNotifier(QSocketNotifier* notifier)
{
#ifndef QT_NO_DEBUG
	if (notifier->socket() < 0) {
		qWarning("QSocketNotifier: Internal error: sockfd < 0");
		return;
	}
	else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
		qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
		return;
	}
#endif

	// Short circuit, we do not support QSocketNotifier::Exception
	if (notifier->type() == QSocketNotifier::Exception) {
		return;
	}

	Q_D(EventDispatcherLibEvent);
	d->unregisterSocketNotifier(notifier);
}

void EventDispatcherLibEvent::registerTimer(int timerId, int interval, QObject* object)
{
#ifndef QT_NO_DEBUG
	if (timerId < 1 || interval < 0 || !object) {
		qWarning("%s: invalid arguments", Q_FUNC_INFO);
		return;
	}

	if (object->thread() != this->thread() && this->thread() != QThread::currentThread()) {
		qWarning("%s: timers cannot be started from another thread", Q_FUNC_INFO);
		return;
	}
#endif

	Q_D(EventDispatcherLibEvent);
	d->registerTimer(timerId, interval, object);
}

bool EventDispatcherLibEvent::unregisterTimer(int timerId)
{
#ifndef QT_NO_DEBUG
	if (timerId < 1) {
		qWarning("%s: invalid arguments", Q_FUNC_INFO);
		return;
	}

	if (this->thread() != QThread::currentThread()) {
		qWarning("%s: timers cannot be stopped from another thread", Q_FUNC_INFO);
		return;
	}
#endif

	Q_D(EventDispatcherLibEvent);
	return d->unregisterTimer(timerId);
}

bool EventDispatcherLibEvent::unregisterTimers(QObject* object)
{
#ifndef QT_NO_DEBUG
	if (!object) {
		qWarning("%s: invalid arguments", Q_FUNC_INFO);
		return;
	}

	if (object->thread() != this->thread() && this->thread() != QThread::currentThread()) {
		qWarning("%s: timers cannot be stopped from another thread", Q_FUNC_INFO);
		return;
	}
#endif

	Q_D(EventDispatcherLibEvent);
	return d->unregisterTimers(object);
}

QList<QAbstractEventDispatcher::TimerInfo> EventDispatcherLibEvent::registeredTimers(QObject* object) const
{
	if (!object) {
		qWarning("%s: invalid argument", Q_FUNC_INFO);
		return QList<QAbstractEventDispatcher::TimerInfo>();
	}

	Q_D(const EventDispatcherLibEvent);
	return d->registeredTimers(object);
}

void EventDispatcherLibEvent::wakeUp(void)
{
	Q_D(EventDispatcherLibEvent);

	if (d->m_thread_pipe[1] != -1) {
		if (::write(d->m_thread_pipe[1], "w", 1) != 1) {
			// Avoid compiler's warning
		}
	}
}

void EventDispatcherLibEvent::interrupt(void)
{
	Q_D(EventDispatcherLibEvent);
	d->m_interrupt = true;
	this->wakeUp();
}

void EventDispatcherLibEvent::flush(void)
{
}
<|endoftext|>


<commit_before>
#include "netmessages.h"
#include "demofilebitbuf.h"
#include <cassert>

namespace math
{
    unsigned int log2(unsigned int value)
    {
        unsigned int res = 0;
        while (value >>= 1)
            ++res;
        return res;
    }

    unsigned int Bits2Bytes(unsigned int bits)
    {
        return ((bits + 7) >> 3);
    }
}

void Net_NOP(CBitRead& bitbuf)
{
    // nothing
}

void Net_Disconnect(CBitRead& bitbuf)
{
    char message[1024];
    bitbuf.ReadString(message, sizeof(message));
}

void Net_File(CBitRead& bitbuf)
{
    const unsigned int transferID = bitbuf.ReadUBitLong(32);
    char filename[1024];
    bitbuf.ReadString(filename, sizeof(filename));
    const bool isRequest = bitbuf.ReadOneBit() != 0;
}

void Net_Tick(CBitRead& bitbuf)
{
    static const float NET_TICK_SCALEUP = 100000.0f;

    const int tick = bitbuf.ReadLong();
    const float hostFrameTime = (float)bitbuf.ReadUBitLong(16) / NET_TICK_SCALEUP;
    const float hostFrameTimeStdDev = (float)bitbuf.ReadUBitLong(16) / NET_TICK_SCALEUP;
}

void Net_StringCmd(CBitRead& bitbuf)
{
    char commandBuffer[1024];
    bitbuf.ReadString(commandBuffer, sizeof(commandBuffer));
}

void Net_SetConVar(CBitRead& bitbuf)
{
    typedef struct cvar_s
    {
        char name[MAX_OSPATH];
        char value[MAX_OSPATH];
    } cvar_t;

    const int numVars = bitbuf.ReadByte();
    cvar_t cvar;
    for (int i = 0; i < numVars; ++i)
    {
        bitbuf.ReadString(cvar.name, sizeof(cvar.name));
        bitbuf.ReadString(cvar.value, sizeof(cvar.value));
    }
}

void Net_SignonState(CBitRead& bitbuf)
{
    const int signonState = bitbuf.ReadByte();
    //assert(signonState == SIGNONSTATE_PRESPAWN);
    const int spawnCount = bitbuf.ReadLong();
}

void SVC_Print(CBitRead& bitbuf)
{
    char textBuffer[2048];
    bitbuf.ReadString(textBuffer, sizeof(textBuffer));
}

void SVC_ServerInfo(CBitRead& bitbuf)
{
    const int protocol = bitbuf.ReadShort();            // protocol version
    const int serverCount = bitbuf.ReadLong();          // number of changelevels since server start
    const bool isHLTV = bitbuf.ReadOneBit() != 0;       // HLTV server ?
    const bool isDedicated = bitbuf.ReadOneBit() != 0;  // dedicated server ?
    const int clientCRC = bitbuf.ReadLong();            // client.dll CRC server is using
    const int maxClasses = bitbuf.ReadWord();           // max number of server classes

    if (protocol <= 17)
    {
        const int mapCRC = bitbuf.ReadLong();           // server map CRC
    }
    else
    {
        char unknown[16];
        bitbuf.ReadBytes(unknown, sizeof(unknown));
    }
    const int playerSlot = bitbuf.ReadByte();           // our client slot number
    const int maxClients = bitbuf.ReadByte();           // max number of clients on server
    const float tickInterval = bitbuf.ReadFloat();      // server tick interval
    const char os = bitbuf.ReadChar();                  // 'l' = linux, 'w' = Win32

    char gameDir[MAX_OSPATH];   // game directory eg "tf2"
    char mapName[MAX_OSPATH];   // name of current map
    char skyName[MAX_OSPATH];   // name of current skybox
    char hostName[MAX_OSPATH];  // host name
    bitbuf.ReadString(gameDir, sizeof(gameDir));
    bitbuf.ReadString(mapName, sizeof(mapName));
    bitbuf.ReadString(skyName, sizeof(skyName));
    bitbuf.ReadString(hostName, sizeof(hostName));
}

void SVC_SendTable(CBitRead& bitbuf)
{
    const bool needsDecoder = bitbuf.ReadOneBit() != 0;
    const int dataLengthBits = bitbuf.ReadShort();
    bitbuf.SeekRelative(dataLengthBits);
}

void SVC_ClassInfo(CBitRead& bitbuf)
{
    typedef struct class_s
    {
        int     classID;
        char    datatablename[256];
        char    classname[256];
    } class_t;

    const int numServerClasses = bitbuf.ReadShort();
    const int nServerClassBits = math::log2(numServerClasses) + 1;
    // if true, client creates own SendTables & classinfos from game.dll
    const bool createOnClient = bitbuf.ReadOneBit() != 0;
    if (!createOnClient)
    {
        class_t serverclass;
        for (int i = 0; i < numServerClasses; ++i)
        {
            serverclass.classID = bitbuf.ReadUBitLong(nServerClassBits);
            bitbuf.ReadString(serverclass.classname, sizeof(serverclass.classname));
            bitbuf.ReadString(serverclass.datatablename, sizeof(serverclass.datatablename));
        }
    }
}

void SVC_SetPause(CBitRead& bitbuf)
{
    const bool paused = bitbuf.ReadOneBit() != 0;
}

void SVC_CreateStringTable(CBitRead& bitbuf)
{
    if (bitbuf.PeekUBitLong(8) == ':')
    {
        bitbuf.ReadByte();
    }

    char tableName[256];
    bitbuf.ReadString(tableName, sizeof(tableName));
    const int maxEntries = bitbuf.ReadWord();
    const int encodeBits = math::log2(maxEntries);
    const int numEntries = bitbuf.ReadUBitLong(encodeBits + 1);
    const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PALYLOAD_BITS + 3);
    const bool userDataFixedSize = bitbuf.ReadOneBit() != 0;
    if (userDataFixedSize)
    {
        const int userDataSize = bitbuf.ReadUBitLong(12);
        const int userDataSizeBits = bitbuf.ReadUBitLong(4);
    }
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_UpdateStringTable(CBitRead& bitbuf)
{
    const int tableId = bitbuf.ReadUBitLong(math::log2(MAX_TABLES));
    const int numChangedEntries = (bitbuf.ReadOneBit() != 0) ? bitbuf.ReadWord() : 1;
    const int lengthInBits = bitbuf.ReadUBitLong(20);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_VoiceInit(CBitRead& bitbuf)
{
    char voiceCodec[MAX_OSPATH]; // used voice codec .dll
    bitbuf.ReadString(voiceCodec, sizeof(voiceCodec));
    const int quality = bitbuf.ReadByte(); // custom quality setting
}

void SVC_VoiceData(CBitRead& bitbuf)
{
    const int fromClientIndex = bitbuf.ReadByte();
    const bool proximity = !!bitbuf.ReadByte();
    const int lengthInBits = bitbuf.ReadWord();
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_HLTV(CBitRead& bitbuf)
{
    //const int state = bitbuf.ReadByte();
    assert(false);
}

void SVC_Sounds(CBitRead& bitbuf)
{
    const bool reliableSound = bitbuf.ReadOneBit() != 0;
    int numSounds;
    int lengthInBits;
    if (reliableSound)
    {
        numSounds = 1;
        lengthInBits = bitbuf.ReadUBitLong(8);
    }
    else
    {
        numSounds = bitbuf.ReadUBitLong(8);
        lengthInBits = bitbuf.ReadUBitLong(16);
    }
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_SetView(CBitRead& bitbuf)
{
    const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
}

void SVC_FixAngle(CBitRead& bitbuf)
{
    const bool relative = bitbuf.ReadOneBit() != 0;
    const float x = bitbuf.ReadBitAngle(16);
    const float y = bitbuf.ReadBitAngle(16);
    const float z = bitbuf.ReadBitAngle(16);
}

void SVC_CrosshairAngle(CBitRead& bitbuf)
{
    const float x = bitbuf.ReadBitAngle(16);
    const float y = bitbuf.ReadBitAngle(16);
    const float z = bitbuf.ReadBitAngle(16);
}

void SVC_BSPDecal(CBitRead& bitbuf)
{
    Vector pos;
    bitbuf.ReadBitVec3Coord(pos);
    const int decalTextureIndex = bitbuf.ReadUBitLong(MAX_DECAL_INDEX_BITS);
    if (bitbuf.ReadOneBit() != 0)
    {
        const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
        const int modelIndex = bitbuf.ReadUBitLong(SP_MODEL_INDEX_BITS);
    }
    else
    {
        const int entIndex = 0;
        const int modelIndex = 0;
    }
    const bool lowPriority = bitbuf.ReadOneBit() != 0;
}

void SVC_TerrainMod(CBitRead& bitbuf)
{
    assert(false);
}

void SVC_UserMessage(CBitRead& bitbuf)
{
    const int msgType = bitbuf.ReadByte();

    // max 256 * 8 bits, see MAX_USER_MSG_DATA
    const int lengthInBits = bitbuf.ReadUBitLong(11);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_EntityMessage(CBitRead& bitbuf)
{
    const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
    const int classID = bitbuf.ReadUBitLong(MAX_SERVER_CLASS_BITS);

    // max 256 * 8 bits
    const int lengthInBits = bitbuf.ReadUBitLong(11);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_GameEvent(CBitRead& bitbuf)
{
    const int lengthInBits = bitbuf.ReadUBitLong(11);
    //uint32 eventId = bitbuf.ReadUBitLong(9);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_PacketEntities(CBitRead& bitbuf)
{
    const int maxEntries = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
    const bool isDelta = bitbuf.ReadOneBit() != 0;
    if (isDelta)
    {
        const int deltaFrom = bitbuf.ReadLong();
    }
    else
    {
        const int deltaFrom = -1;
    }
    const int numBaseline = bitbuf.ReadUBitLong(1);
    const int numUpdatedEntries = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
    const int lengthInBits = bitbuf.ReadUBitLong(DELTASIZE_BITS);
    const bool updateBaseline = bitbuf.ReadOneBit() != 0;
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_TempEntities(CBitRead& bitbuf)
{
    const int numEntries = bitbuf.ReadUBitLong(EVENT_INDEX_BITS);
    const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PALYLOAD_BITS);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_Prefetch(CBitRead& bitbuf)
{
    enum
    {
        SOUND = 0,
    };

    const short type = SOUND; // bitbuf.ReadUBitLong(1);
    const short soundIndex = bitbuf.ReadUBitLong(MAX_SOUND_INDEX_BITS);
}

void SVC_Menu(CBitRead& bitbuf)
{
    typedef enum
    {
        DIALOG_MSG = 0,		// just an on screen message
        DIALOG_MENU,		// an options menu
        DIALOG_TEXT,		// a richtext dialog
        DIALOG_ENTRY,		// an entry box
        DIALOG_ASKCONNECT	// Ask the client to connect to a specified IP address. Only the "time" and "title" keys are used.
    } DIALOG_TYPE;

    DIALOG_TYPE type = (DIALOG_TYPE)bitbuf.ReadShort();
    const int lengthInBytes = bitbuf.ReadWord();
    bitbuf.SeekRelative(lengthInBytes * 8);
}

void SVC_GameEventList(CBitRead& bitbuf)
{
    const int numEvents = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
    for (int i = 0; i < numEvents; ++i)
    {
        const int id = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
        char name[MAX_EVENT_NAME_LENGTH];
        bitbuf.ReadString(name, sizeof(name));
        printf("%s\n", name);
        assert(false);
        // gameeventmanager.cpp ParseEventList
    }
    const int lengthInBits = bitbuf.ReadUBitLong(20);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_GetCvarValue(CBitRead& bitbuf)
{
    typedef int QueryCvarCookie_t;
    QueryCvarCookie_t cookie = bitbuf.ReadSBitLong(32);
    char cvarName[256];
    bitbuf.ReadString(cvarName, sizeof(cvarName));
}

static const int NUM_MESSAGES = static_cast<uint8_t>(NetMsg::SVC_LASTMSG) + 1;

void ProcessNetMsg(const std::uint32_t msgType, CBitRead& bitbuf)
{
    static NetMsgFn netMsgHandler[NUM_MESSAGES] =
    {
        &Net_NOP,
        &Net_Disconnect,
        &Net_File,
        &Net_Tick,
        &Net_StringCmd,
        &Net_SetConVar,
        &Net_SignonState,

        &SVC_Print,
        &SVC_ServerInfo,
        &SVC_SendTable,
        &SVC_ClassInfo,
        &SVC_SetPause,
        &SVC_CreateStringTable,
        &SVC_UpdateStringTable,
        &SVC_VoiceInit,
        &SVC_VoiceData,
        &SVC_HLTV,
        &SVC_Sounds,
        &SVC_SetView,
        &SVC_FixAngle,
        &SVC_CrosshairAngle,
        &SVC_BSPDecal,
        &SVC_TerrainMod,
        &SVC_UserMessage,
        &SVC_EntityMessage,
        &SVC_GameEvent,
        &SVC_PacketEntities,
        &SVC_TempEntities,
        &SVC_Prefetch,
        &SVC_Menu,
        &SVC_GameEventList,
        &SVC_GetCvarValue
    };

    assert(msgType < NUM_MESSAGES);
    netMsgHandler[msgType](bitbuf);
}
<commit_msg>Modified SVC_ServerInfo for current protocol<commit_after>
#include "netmessages.h"
#include "demofilebitbuf.h"
#include <cassert>

namespace math
{
    unsigned int log2(unsigned int value)
    {
        unsigned int res = 0;
        while (value >>= 1)
            ++res;
        return res;
    }

    unsigned int Bits2Bytes(unsigned int bits)
    {
        return ((bits + 7) >> 3);
    }
}

void Net_NOP(CBitRead& bitbuf)
{
    // nothing
}

void Net_Disconnect(CBitRead& bitbuf)
{
    char message[1024];
    bitbuf.ReadString(message, sizeof(message));
}

void Net_File(CBitRead& bitbuf)
{
    const unsigned int transferID = bitbuf.ReadUBitLong(32);
    char filename[1024];
    bitbuf.ReadString(filename, sizeof(filename));
    const bool isRequest = bitbuf.ReadOneBit() != 0;
}

void Net_Tick(CBitRead& bitbuf)
{
    static const float NET_TICK_SCALEUP = 100000.0f;

    const int tick = bitbuf.ReadLong();
    const float hostFrameTime = (float)bitbuf.ReadUBitLong(16) / NET_TICK_SCALEUP;
    const float hostFrameTimeStdDev = (float)bitbuf.ReadUBitLong(16) / NET_TICK_SCALEUP;
}

void Net_StringCmd(CBitRead& bitbuf)
{
    char commandBuffer[1024];
    bitbuf.ReadString(commandBuffer, sizeof(commandBuffer));
}

void Net_SetConVar(CBitRead& bitbuf)
{
    typedef struct cvar_s
    {
        char name[MAX_OSPATH];
        char value[MAX_OSPATH];
    } cvar_t;

    const int numVars = bitbuf.ReadByte();
    cvar_t cvar;
    for (int i = 0; i < numVars; ++i)
    {
        bitbuf.ReadString(cvar.name, sizeof(cvar.name));
        bitbuf.ReadString(cvar.value, sizeof(cvar.value));
    }
}

void Net_SignonState(CBitRead& bitbuf)
{
    const int signonState = bitbuf.ReadByte();
    //assert(signonState == SIGNONSTATE_PRESPAWN);
    const int spawnCount = bitbuf.ReadLong();
}

void SVC_Print(CBitRead& bitbuf)
{
    char textBuffer[2048];
    bitbuf.ReadString(textBuffer, sizeof(textBuffer));
}

void SVC_ServerInfo(CBitRead& bitbuf)
{
    const int protocol = bitbuf.ReadShort();            // protocol version
    const int serverCount = bitbuf.ReadLong();          // number of changelevels since server start
    const bool isHLTV = bitbuf.ReadOneBit() != 0;       // HLTV server ?
    const bool isDedicated = bitbuf.ReadOneBit() != 0;  // dedicated server ?
    const int clientCRC = bitbuf.ReadLong();            // client.dll CRC server is using
    const int maxClasses = bitbuf.ReadWord();           // max number of server classes

    if (protocol <= 17)
    {
        const int mapCRC = bitbuf.ReadLong();           // server map CRC
    }
    else
    {
        char unknown[16];
        bitbuf.ReadBytes(unknown, sizeof(unknown));
    }
    const int playerSlot = bitbuf.ReadByte();           // our client slot number
    const int maxClients = bitbuf.ReadByte();           // max number of clients on server
    const float tickInterval = bitbuf.ReadFloat();      // server tick interval
    const char os = bitbuf.ReadChar();                  // 'l' = linux, 'w' = Win32

    char gameDir[MAX_OSPATH];   // game directory eg "tf2"
    char mapName[MAX_OSPATH];   // name of current map
    char skyName[MAX_OSPATH];   // name of current skybox
    char hostName[MAX_OSPATH];  // host name
    bitbuf.ReadString(gameDir, sizeof(gameDir));
    bitbuf.ReadString(mapName, sizeof(mapName));
    bitbuf.ReadString(skyName, sizeof(skyName));
    bitbuf.ReadString(hostName, sizeof(hostName));

    // TODO:
    // if (this.something() > 15)
    // {
    const bool unknown = bitbuf.ReadOneBit() != 0;
    // }
}

void SVC_SendTable(CBitRead& bitbuf)
{
    const bool needsDecoder = bitbuf.ReadOneBit() != 0;
    const int dataLengthBits = bitbuf.ReadShort();
    bitbuf.SeekRelative(dataLengthBits);
}

void SVC_ClassInfo(CBitRead& bitbuf)
{
    typedef struct class_s
    {
        int     classID;
        char    datatablename[256];
        char    classname[256];
    } class_t;

    const int numServerClasses = bitbuf.ReadShort();
    const int nServerClassBits = math::log2(numServerClasses) + 1;
    // if true, client creates own SendTables & classinfos from game.dll
    const bool createOnClient = bitbuf.ReadOneBit() != 0;
    if (!createOnClient)
    {
        class_t serverclass;
        for (int i = 0; i < numServerClasses; ++i)
        {
            serverclass.classID = bitbuf.ReadUBitLong(nServerClassBits);
            bitbuf.ReadString(serverclass.classname, sizeof(serverclass.classname));
            bitbuf.ReadString(serverclass.datatablename, sizeof(serverclass.datatablename));
        }
    }
}

void SVC_SetPause(CBitRead& bitbuf)
{
    const bool paused = bitbuf.ReadOneBit() != 0;
}

void SVC_CreateStringTable(CBitRead& bitbuf)
{
    if (bitbuf.PeekUBitLong(8) == ':')
    {
        bitbuf.ReadByte();
    }

    char tableName[256];
    bitbuf.ReadString(tableName, sizeof(tableName));
    const int maxEntries = bitbuf.ReadWord();
    const int encodeBits = math::log2(maxEntries);
    const int numEntries = bitbuf.ReadUBitLong(encodeBits + 1);
    const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PALYLOAD_BITS + 3);
    const bool userDataFixedSize = bitbuf.ReadOneBit() != 0;
    if (userDataFixedSize)
    {
        const int userDataSize = bitbuf.ReadUBitLong(12);
        const int userDataSizeBits = bitbuf.ReadUBitLong(4);
    }
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_UpdateStringTable(CBitRead& bitbuf)
{
    const int tableId = bitbuf.ReadUBitLong(math::log2(MAX_TABLES));
    const int numChangedEntries = (bitbuf.ReadOneBit() != 0) ? bitbuf.ReadWord() : 1;
    const int lengthInBits = bitbuf.ReadUBitLong(20);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_VoiceInit(CBitRead& bitbuf)
{
    char voiceCodec[MAX_OSPATH]; // used voice codec .dll
    bitbuf.ReadString(voiceCodec, sizeof(voiceCodec));
    const int quality = bitbuf.ReadByte(); // custom quality setting
}

void SVC_VoiceData(CBitRead& bitbuf)
{
    const int fromClientIndex = bitbuf.ReadByte();
    const bool proximity = !!bitbuf.ReadByte();
    const int lengthInBits = bitbuf.ReadWord();
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_HLTV(CBitRead& bitbuf)
{
    //const int state = bitbuf.ReadByte();
    assert(false);
}

void SVC_Sounds(CBitRead& bitbuf)
{
    const bool reliableSound = bitbuf.ReadOneBit() != 0;
    int numSounds;
    int lengthInBits;
    if (reliableSound)
    {
        numSounds = 1;
        lengthInBits = bitbuf.ReadUBitLong(8);
    }
    else
    {
        numSounds = bitbuf.ReadUBitLong(8);
        lengthInBits = bitbuf.ReadUBitLong(16);
    }
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_SetView(CBitRead& bitbuf)
{
    const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
}

void SVC_FixAngle(CBitRead& bitbuf)
{
    const bool relative = bitbuf.ReadOneBit() != 0;
    const float x = bitbuf.ReadBitAngle(16);
    const float y = bitbuf.ReadBitAngle(16);
    const float z = bitbuf.ReadBitAngle(16);
}

void SVC_CrosshairAngle(CBitRead& bitbuf)
{
    const float x = bitbuf.ReadBitAngle(16);
    const float y = bitbuf.ReadBitAngle(16);
    const float z = bitbuf.ReadBitAngle(16);
}

void SVC_BSPDecal(CBitRead& bitbuf)
{
    Vector pos;
    bitbuf.ReadBitVec3Coord(pos);
    const int decalTextureIndex = bitbuf.ReadUBitLong(MAX_DECAL_INDEX_BITS);
    if (bitbuf.ReadOneBit() != 0)
    {
        const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
        const int modelIndex = bitbuf.ReadUBitLong(SP_MODEL_INDEX_BITS);
    }
    else
    {
        const int entIndex = 0;
        const int modelIndex = 0;
    }
    const bool lowPriority = bitbuf.ReadOneBit() != 0;
}

void SVC_TerrainMod(CBitRead& bitbuf)
{
    assert(false);
}

void SVC_UserMessage(CBitRead& bitbuf)
{
    const int msgType = bitbuf.ReadByte();

    // max 256 * 8 bits, see MAX_USER_MSG_DATA
    const int lengthInBits = bitbuf.ReadUBitLong(11);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_EntityMessage(CBitRead& bitbuf)
{
    const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
    const int classID = bitbuf.ReadUBitLong(MAX_SERVER_CLASS_BITS);

    // max 256 * 8 bits
    const int lengthInBits = bitbuf.ReadUBitLong(11);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_GameEvent(CBitRead& bitbuf)
{
    const int lengthInBits = bitbuf.ReadUBitLong(11);
    //uint32 eventId = bitbuf.ReadUBitLong(9);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_PacketEntities(CBitRead& bitbuf)
{
    const int maxEntries = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
    const bool isDelta = bitbuf.ReadOneBit() != 0;
    if (isDelta)
    {
        const int deltaFrom = bitbuf.ReadLong();
    }
    else
    {
        const int deltaFrom = -1;
    }
    const int numBaseline = bitbuf.ReadUBitLong(1);
    const int numUpdatedEntries = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
    const int lengthInBits = bitbuf.ReadUBitLong(DELTASIZE_BITS);
    const bool updateBaseline = bitbuf.ReadOneBit() != 0;
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_TempEntities(CBitRead& bitbuf)
{
    const int numEntries = bitbuf.ReadUBitLong(EVENT_INDEX_BITS);
    const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PALYLOAD_BITS);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_Prefetch(CBitRead& bitbuf)
{
    enum
    {
        SOUND = 0,
    };

    const short type = SOUND; // bitbuf.ReadUBitLong(1);
    const short soundIndex = bitbuf.ReadUBitLong(MAX_SOUND_INDEX_BITS);
}

void SVC_Menu(CBitRead& bitbuf)
{
    typedef enum
    {
        DIALOG_MSG = 0,		// just an on screen message
        DIALOG_MENU,		// an options menu
        DIALOG_TEXT,		// a richtext dialog
        DIALOG_ENTRY,		// an entry box
        DIALOG_ASKCONNECT	// Ask the client to connect to a specified IP address. Only the "time" and "title" keys are used.
    } DIALOG_TYPE;

    DIALOG_TYPE type = (DIALOG_TYPE)bitbuf.ReadShort();
    const int lengthInBytes = bitbuf.ReadWord();
    bitbuf.SeekRelative(lengthInBytes * 8);
}

void SVC_GameEventList(CBitRead& bitbuf)
{
    const int numEvents = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
    for (int i = 0; i < numEvents; ++i)
    {
        const int id = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
        char name[MAX_EVENT_NAME_LENGTH];
        bitbuf.ReadString(name, sizeof(name));
        printf("%s\n", name);
        assert(false);
        // gameeventmanager.cpp ParseEventList
    }
    const int lengthInBits = bitbuf.ReadUBitLong(20);
    bitbuf.SeekRelative(lengthInBits);
}

void SVC_GetCvarValue(CBitRead& bitbuf)
{
    typedef int QueryCvarCookie_t;
    QueryCvarCookie_t cookie = bitbuf.ReadSBitLong(32);
    char cvarName[256];
    bitbuf.ReadString(cvarName, sizeof(cvarName));
}

static const int NUM_MESSAGES = static_cast<uint8_t>(NetMsg::SVC_LASTMSG) + 1;

void ProcessNetMsg(const std::uint32_t msgType, CBitRead& bitbuf)
{
    static NetMsgFn netMsgHandler[NUM_MESSAGES] =
    {
        &Net_NOP,
        &Net_Disconnect,
        &Net_File,
        &Net_Tick,
        &Net_StringCmd,
        &Net_SetConVar,
        &Net_SignonState,

        &SVC_Print,
        &SVC_ServerInfo,
        &SVC_SendTable,
        &SVC_ClassInfo,
        &SVC_SetPause,
        &SVC_CreateStringTable,
        &SVC_UpdateStringTable,
        &SVC_VoiceInit,
        &SVC_VoiceData,
        &SVC_HLTV,
        &SVC_Sounds,
        &SVC_SetView,
        &SVC_FixAngle,
        &SVC_CrosshairAngle,
        &SVC_BSPDecal,
        &SVC_TerrainMod,
        &SVC_UserMessage,
        &SVC_EntityMessage,
        &SVC_GameEvent,
        &SVC_PacketEntities,
        &SVC_TempEntities,
        &SVC_Prefetch,
        &SVC_Menu,
        &SVC_GameEventList,
        &SVC_GetCvarValue
    };

    assert(msgType < NUM_MESSAGES);
    netMsgHandler[msgType](bitbuf);
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#ifndef PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_
#define PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_

#include "pcl/filters/statistical_outlier_removal.h"

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::StatisticalOutlierRemoval<PointT>::applyFilter (PointCloud &output)
{
  if (std_mul_ == 0.0)
  {
    PCL_ERROR ("[pcl::%s::applyFilter] Standard deviation multiplier not set!\n", getClassName ().c_str ());
    output.width = output.height = 0;
    output.points.clear ();
    return;
  }

  // Initialize the spatial locator
  //initTree (spatial_locator_type_, tree_, k_);

  // TODO: fix this
  tree_.reset (new KdTreeFLANN<PointT> ());

  // Send the input dataset to the spatial locator
  tree_->setInputCloud (input_);

  // Allocate enough space to hold the results
  std::vector<int> nn_indices (mean_k_);
  std::vector<float> nn_dists (mean_k_);

  std::vector<float> distances (indices_->size ());
  // Go over all the points and calculate the mean or smallest distance
  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    if (!pcl_isfinite (input_->points[(*indices_)[cp]].x) ||
        !pcl_isfinite (input_->points[(*indices_)[cp]].y) ||
        !pcl_isfinite (input_->points[(*indices_)[cp]].z))
    {
      distances[cp] = 0;
      continue;
    }

    if (tree_->nearestKSearch ((*indices_)[cp], mean_k_, nn_indices, nn_dists) == 0)
    {
      distances[cp] = 0;
      PCL_WARN ("[pcl::%s::applyFilter] Searching for the closest %d neighbors failed.\n", getClassName ().c_str (), mean_k_);
      continue;
    }

    // Minimum distance (if mean_k_ == 2) or mean distance
    double dist_sum = 0;
    for (int j = 1; j < mean_k_; ++j)
      dist_sum += sqrt (nn_dists[j]);
    distances[cp] = dist_sum / (mean_k_-1);
  }

  // Estimate the mean and the standard deviation of the distance vector
  double mean, stddev;
  getMeanStd (distances, mean, stddev);
  double distance_threshold = mean + std_mul_ * stddev; // a distance that is bigger than this signals an outlier

  output.points.resize (input_->points.size ());      // reserve enough space
  removed_indices_->resize (input_->points.size ());

  // Build a new cloud by neglecting outliers
  int nr_p = 0;
  int nr_removed_p = 0;

  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    if (negative_)
    {
      if (distances[cp] <= distance_threshold)
      {
        if (extract_removed_indices_)
        {
          (*removed_indices_)[nr_removed_p] = cp;
          nr_removed_p++;
        }
        continue;
      }
    }
    else
    {
      if (distances[cp] > distance_threshold)
      {
        if (extract_removed_indices_)
        {
          (*removed_indices_)[nr_removed_p] = cp;
          nr_removed_p++;
        }
        continue;
      }
    }

    output.points[nr_p++] = input_->points[(*indices_)[cp]];
  }

  output.points.resize (nr_p);
  output.width  = nr_p;
  output.height = 1;
  output.is_dense = true; // nearestKSearch filters invalid points

  removed_indices_->resize (nr_removed_p);
}

#define PCL_INSTANTIATE_StatisticalOutlierRemoval(T) template class PCL_EXPORTS pcl::StatisticalOutlierRemoval<T>;

#endif    // PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_

<commit_msg>we do not care for the results to be sorted when using StatisticalAnalysis outlier removal<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#ifndef PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_
#define PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_

#include "pcl/filters/statistical_outlier_removal.h"

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::StatisticalOutlierRemoval<PointT>::applyFilter (PointCloud &output)
{
  if (std_mul_ == 0.0)
  {
    PCL_ERROR ("[pcl::%s::applyFilter] Standard deviation multiplier not set!\n", getClassName ().c_str ());
    output.width = output.height = 0;
    output.points.clear ();
    return;
  }

  // Initialize the spatial locator
  //initTree (spatial_locator_type_, tree_, k_);

  // TODO: fix this
  tree_.reset (new KdTreeFLANN<PointT> (false));

  // Send the input dataset to the spatial locator
  tree_->setInputCloud (input_);

  // Allocate enough space to hold the results
  std::vector<int> nn_indices (mean_k_);
  std::vector<float> nn_dists (mean_k_);

  std::vector<float> distances (indices_->size ());
  // Go over all the points and calculate the mean or smallest distance
  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    if (!pcl_isfinite (input_->points[(*indices_)[cp]].x) ||
        !pcl_isfinite (input_->points[(*indices_)[cp]].y) ||
        !pcl_isfinite (input_->points[(*indices_)[cp]].z))
    {
      distances[cp] = 0;
      continue;
    }

    if (tree_->nearestKSearch ((*indices_)[cp], mean_k_, nn_indices, nn_dists) == 0)
    {
      distances[cp] = 0;
      PCL_WARN ("[pcl::%s::applyFilter] Searching for the closest %d neighbors failed.\n", getClassName ().c_str (), mean_k_);
      continue;
    }

    // Minimum distance (if mean_k_ == 2) or mean distance
    double dist_sum = 0;
    for (int j = 1; j < mean_k_; ++j)
      dist_sum += sqrt (nn_dists[j]);
    distances[cp] = dist_sum / (mean_k_-1);
  }

  // Estimate the mean and the standard deviation of the distance vector
  double mean, stddev;
  getMeanStd (distances, mean, stddev);
  double distance_threshold = mean + std_mul_ * stddev; // a distance that is bigger than this signals an outlier

  output.points.resize (input_->points.size ());      // reserve enough space
  removed_indices_->resize (input_->points.size ());

  // Build a new cloud by neglecting outliers
  int nr_p = 0;
  int nr_removed_p = 0;

  for (size_t cp = 0; cp < indices_->size (); ++cp)
  {
    if (negative_)
    {
      if (distances[cp] <= distance_threshold)
      {
        if (extract_removed_indices_)
        {
          (*removed_indices_)[nr_removed_p] = cp;
          nr_removed_p++;
        }
        continue;
      }
    }
    else
    {
      if (distances[cp] > distance_threshold)
      {
        if (extract_removed_indices_)
        {
          (*removed_indices_)[nr_removed_p] = cp;
          nr_removed_p++;
        }
        continue;
      }
    }

    output.points[nr_p++] = input_->points[(*indices_)[cp]];
  }

  output.points.resize (nr_p);
  output.width  = nr_p;
  output.height = 1;
  output.is_dense = true; // nearestKSearch filters invalid points

  removed_indices_->resize (nr_removed_p);
}

#define PCL_INSTANTIATE_StatisticalOutlierRemoval(T) template class PCL_EXPORTS pcl::StatisticalOutlierRemoval<T>;

#endif    // PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_

<|endoftext|>


<commit_before>#include "poScene/ui/ButtonSet.h"

using namespace std::placeholders;

namespace po
{
	namespace scene
	{
		namespace ui
		{
			ButtonSetRef ButtonSet::create()
			{
				return ButtonSetRef( new ButtonSet() );
			}

			ButtonSet::ButtonSet()
				: mType( Type::RADIO )
			{

			}

			// Add Buttons
			void ButtonSet::addButton( ButtonRef button, bool addToView )
			{
				button->setType( Button::Type::TOGGLE );
				mButtons.push_back( button );
				mButtonConnections[button] += button->getSignalToggled().connect( std::bind( &ButtonSet::buttonToggledHandler, this, ::_1 ) );

				if( addToView ) {
					getView()->addSubview( button );
				}
			}

			void ButtonSet::addButtons( const std::vector<ButtonRef>& buttons, bool addToView )
			{
				for( auto& button : buttons ) {
					addButton( button, addToView );
				}
			}

			// Remove Buttons
			void ButtonSet::removeButton( ButtonRef button )
			{
				std::vector<ButtonRef>::iterator iter = std::find( mButtons.begin(), mButtons.end(), button );

				if( iter != mButtons.end() ) {
					mButtons.erase( iter );
					mButtonConnections.erase( *iter );

					if( button->getSuperview() == getView() ) {
						button->removeFromSuperview();
					}
				}
			}

			void ButtonSet::removeButtons( const std::vector<ButtonRef>& buttons )
			{
				for( auto& button : buttons ) {
					removeButton( button );
				}
			}

			// Return a list of selected buttons
			// If radio should only be one, checkbox could be multiple
			std::vector<ButtonRef> ButtonSet::getSelectedButtons()
			{
				std::vector<ButtonRef> selectedButtons;

				for( auto& button : mButtons ) {
					if( button->getState() == Button::State::SELECTED ) {
						selectedButtons.push_back( button );
					}
				}

				return selectedButtons;
			}

			void ButtonSet::selectButton( ButtonRef selectedButton )
			{
				if( mType == Type::RADIO ) {
					for( auto& button : mButtons ) {
						if( button->getState() == Button::State::SELECTED && button != selectedButton ) {
							button->setState( Button::State::NORMAL );

							if( !mDelegate.expired() ) {
								ButtonSetRef self = std::dynamic_pointer_cast<ButtonSet>( shared_from_this() );
								mDelegate.lock()->buttonSetDidDeselectButton( self, button );
							}
						}
					}
				}

				if( selectedButton->getState() != Button::State::SELECTED ) {
					selectedButton->setState( Button::State::SELECTED );
				}

				if( !mDelegate.expired() ) {
					ButtonSetRef self = std::dynamic_pointer_cast<ButtonSet>( shared_from_this() );
					mDelegate.lock()->buttonSetDidSelectButton( self, selectedButton );
				}
			}

			void ButtonSet::selectAllButtons()
			{
				CI_ASSERT_MSG( mType == Type::CHECKBOX, "You can not select all buttons in a radio button set." );

				for( auto& button : mButtons ) {
					selectButton( button );
				}
			}

			void ButtonSet::deselectAllButtons()
			{

			}

			// -------------------------------
			// Event listeners
			void ButtonSet::buttonToggledHandler( ButtonRef button )
			{
				switch( mType ) {
					case Type::RADIO:

						// Don't allow buttons to be de-selected on their own
						if( button->getState() == Button::State::NORMAL ) {
							button->setState( Button::State::SELECTED );
						}

						// Previously unselected button selected
						else {
							selectButton( button );
						}

						return;
				}
			}
		}
	}
}<commit_msg>adding deselect method to button set<commit_after>#include "poScene/ui/ButtonSet.h"

using namespace std::placeholders;

namespace po
{
	namespace scene
	{
		namespace ui
		{
			ButtonSetRef ButtonSet::create()
			{
				return ButtonSetRef( new ButtonSet() );
			}

			ButtonSet::ButtonSet()
				: mType( Type::RADIO )
			{

			}

			// Add Buttons
			void ButtonSet::addButton( ButtonRef button, bool addToView )
			{
				button->setType( Button::Type::TOGGLE );
				mButtons.push_back( button );
				mButtonConnections[button] += button->getSignalToggled().connect( std::bind( &ButtonSet::buttonToggledHandler, this, ::_1 ) );

				if( addToView ) {
					getView()->addSubview( button );
				}
			}

			void ButtonSet::addButtons( const std::vector<ButtonRef>& buttons, bool addToView )
			{
				for( auto& button : buttons ) {
					addButton( button, addToView );
				}
			}

			// Remove Buttons
			void ButtonSet::removeButton( ButtonRef button )
			{
				std::vector<ButtonRef>::iterator iter = std::find( mButtons.begin(), mButtons.end(), button );

				if( iter != mButtons.end() ) {
					mButtons.erase( iter );
					mButtonConnections.erase( *iter );

					if( button->getSuperview() == getView() ) {
						button->removeFromSuperview();
					}
				}
			}

			void ButtonSet::removeButtons( const std::vector<ButtonRef>& buttons )
			{
				for( auto& button : buttons ) {
					removeButton( button );
				}
			}

			// Return a list of selected buttons
			// If radio should only be one, checkbox could be multiple
			std::vector<ButtonRef> ButtonSet::getSelectedButtons()
			{
				std::vector<ButtonRef> selectedButtons;

				for( auto& button : mButtons ) {
					if( button->getState() == Button::State::SELECTED ) {
						selectedButtons.push_back( button );
					}
				}

				return selectedButtons;
			}

			void ButtonSet::selectButton( ButtonRef selectedButton )
			{
				if( mType == Type::RADIO ) {
					for( auto& button : mButtons ) {
						if( button->getState() == Button::State::SELECTED && button != selectedButton ) {
							button->setState( Button::State::NORMAL );

							if( !mDelegate.expired() ) {
								ButtonSetRef self = std::dynamic_pointer_cast<ButtonSet>( shared_from_this() );
								mDelegate.lock()->buttonSetDidDeselectButton( self, button );
							}
						}
					}
				}

				if( selectedButton->getState() != Button::State::SELECTED ) {
					selectedButton->setState( Button::State::SELECTED );
				}

				if( !mDelegate.expired() ) {
					ButtonSetRef self = std::dynamic_pointer_cast<ButtonSet>( shared_from_this() );
					mDelegate.lock()->buttonSetDidSelectButton( self, selectedButton );
				}
			}

			void ButtonSet::deselectButton( ButtonRef deSelectedButton )
			{
				deSelectedButton->setState( Button::State::NORMAL );

				if( !mDelegate.expired() ) {
					ButtonSetRef self = std::dynamic_pointer_cast<ButtonSet>( shared_from_this() );
					mDelegate.lock()->buttonSetDidDeselectButton( self, deSelectedButton );
				}
			}

			void ButtonSet::selectAllButtons()
			{
				CI_ASSERT_MSG( mType == Type::CHECKBOX, "You can not select all buttons in a radio button set." );

				for( auto& button : mButtons ) {
					selectButton( button );
				}
			}

			void ButtonSet::deselectAllButtons()
			{
				for( auto& button : mButtons ) {
					deselectButton( button );
				}
			}

			// -------------------------------
			// Event listeners
			void ButtonSet::buttonToggledHandler( ButtonRef button )
			{
				switch( mType ) {
					case Type::RADIO:

						// Don't allow buttons to be de-selected on their own
						if( button->getState() == Button::State::NORMAL ) {
							button->setState( Button::State::SELECTED );
						}

						// Previously unselected button selected
						else {
							selectButton( button );
						}

						return;
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
// reserved. See file COPYRIGHT for details.
//
// This file is part of the MFEM library. For more information and source code
// availability see http://mfem.org.
//
// MFEM 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) version 2.1 dated February 1999.

#define CATCH_CONFIG_RUNNER
#include "mfem.hpp"
#include "catch.hpp"

int main(int argc, char *argv[])
{
#ifdef MFEM_USE_MPI
   mfem::MPI_Session mpi;
#endif

   // There must be exactly one instance.
   Catch::Session session;

   // Apply provided command line arguments.
   int r = session.applyCommandLine(argc, argv);
   if (r != 0)
   {
      return r;
   }

#ifdef MFEM_USE_MPI
   // Force to only run parallel tests if the tests
   // are executed on multiple processors.
   if (mpi.WorldSize() > 1)
   {
      auto cfg = session.configData();
      cfg.testsOrTags.push_back("[Parallel]");
      session.useConfigData(cfg);
      if (mpi.Root())
      {
         mfem::out
               << "WARNING: Only running the [Parallel] label on MPI ranks > 1." << std::endl;
      }
   }
#endif

   int result = session.run();

   return result;
}
<commit_msg>Modification to which unit tests are run<commit_after>// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
// reserved. See file COPYRIGHT for details.
//
// This file is part of the MFEM library. For more information and source code
// availability see http://mfem.org.
//
// MFEM 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) version 2.1 dated February 1999.

#define CATCH_CONFIG_RUNNER
#include "mfem.hpp"
#include "catch.hpp"

int main(int argc, char *argv[])
{
   // There must be exactly one instance.
   Catch::Session session;

   // Apply provided command line arguments.
   int r = session.applyCommandLine(argc, argv);
   if (r != 0)
   {
      return r;
   }

#ifdef MFEM_USE_MPI
   mfem::MPI_Session mpi;
   // Force tests not tagged as [Parallel] to run only on MPI rank 0
   if (mpi.WorldRank() > 0)
   {
      auto cfg = session.configData();
      cfg.testsOrTags.push_back("[Parallel]");
      session.useConfigData(cfg);
   }
   if (mpi.WorldSize() > 1 && mpi.Root())
   {
      mfem::out
         << "WARNING: Only running the [Parallel] label on MPI ranks > 1."
         << std::endl;
   }
#endif

   int result = session.run();

   return result;
}
<|endoftext|>


<commit_before>#pragma once

#include "file64_api.hpp"

#include "../../base/base.hpp"

#include "../../std/string.hpp"
#include "../../std/target_os.hpp"
#include "../../std/noncopyable.hpp"

#ifdef OMIM_OS_TIZEN
namespace Tizen
{
  namespace Io
  {
    class File;
  }
}
#endif

namespace my {

class FileData: private noncopyable
{
public:
  /// @note Do not change order (@see FileData::FileData).
  enum Op { OP_READ = 0, OP_WRITE_TRUNCATE, OP_WRITE_EXISTING, OP_APPEND };

  FileData(string const & fileName, Op op);
  ~FileData();

  uint64_t Size() const;
  uint64_t Pos() const;

  void Seek(uint64_t pos);

  void Read(uint64_t pos, void * p, size_t size);
  void Write(void const * p, size_t size);

  void Flush();
  void Truncate(uint64_t sz);

  string GetName() const { return m_FileName; }

private:

#ifdef OMIM_OS_TIZEN
  Tizen::Io::File * m_File;
#else
  FILE * m_File;
#endif
  string m_FileName;
  Op m_Op;

  string GetErrorProlog() const;
};

bool GetFileSize(string const & fName, uint64_t & sz);
bool DeleteFileX(string const & fName);
bool RenameFileX(string const & fOld, string const & fNew);
/// @return false if copy fails. DO NOT THROWS exceptions
bool CopyFileX(string const & fOld, string const & fNew);
bool IsEqualFiles(string const & firstFile, string const & secondFile);

}
<commit_msg>[Tizen] change position of include<commit_after>#pragma once

#include "../../std/target_os.hpp"
#include "file64_api.hpp"

#include "../../base/base.hpp"

#include "../../std/string.hpp"
#include "../../std/noncopyable.hpp"

#ifdef OMIM_OS_TIZEN
namespace Tizen
{
  namespace Io
  {
    class File;
  }
}
#endif

namespace my {

class FileData: private noncopyable
{
public:
  /// @note Do not change order (@see FileData::FileData).
  enum Op { OP_READ = 0, OP_WRITE_TRUNCATE, OP_WRITE_EXISTING, OP_APPEND };

  FileData(string const & fileName, Op op);
  ~FileData();

  uint64_t Size() const;
  uint64_t Pos() const;

  void Seek(uint64_t pos);

  void Read(uint64_t pos, void * p, size_t size);
  void Write(void const * p, size_t size);

  void Flush();
  void Truncate(uint64_t sz);

  string GetName() const { return m_FileName; }

private:

#ifdef OMIM_OS_TIZEN
  Tizen::Io::File * m_File;
#else
  FILE * m_File;
#endif
  string m_FileName;
  Op m_Op;

  string GetErrorProlog() const;
};

bool GetFileSize(string const & fName, uint64_t & sz);
bool DeleteFileX(string const & fName);
bool RenameFileX(string const & fOld, string const & fNew);
/// @return false if copy fails. DO NOT THROWS exceptions
bool CopyFileX(string const & fOld, string const & fNew);
bool IsEqualFiles(string const & firstFile, string const & secondFile);

}
<|endoftext|>