<commit_before>/*
 * Copyright (C) 2008 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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.
 */

#include "config.h"
#include "ScrollbarThemeWin.h"

#include "GraphicsContext.h"
#include "PlatformMouseEvent.h"
#include "Scrollbar.h"
#include "SoftLinking.h"

// Generic state constants
#define TS_NORMAL    1
#define TS_HOVER     2
#define TS_ACTIVE    3
#define TS_DISABLED  4

#define SP_BUTTON          1
#define SP_THUMBHOR        2
#define SP_THUMBVERT       3
#define SP_TRACKSTARTHOR   4
#define SP_TRACKENDHOR     5
#define SP_TRACKSTARTVERT  6
#define SP_TRACKENDVERT    7
#define SP_GRIPPERHOR      8
#define SP_GRIPPERVERT     9

#define TS_UP_BUTTON       0
#define TS_DOWN_BUTTON     4
#define TS_LEFT_BUTTON     8
#define TS_RIGHT_BUTTON    12
#define TS_UP_BUTTON_HOVER   17
#define TS_DOWN_BUTTON_HOVER  18
#define TS_LEFT_BUTTON_HOVER  19
#define TS_RIGHT_BUTTON_HOVER   20

using namespace std;

namespace WebCore {

static HANDLE scrollbarTheme;
static bool haveTheme;
static bool runningVista;

// FIXME:  Refactor the soft-linking code so that it can be shared with RenderThemeWin
SOFT_LINK_LIBRARY(uxtheme)
SOFT_LINK(uxtheme, OpenThemeData, HANDLE, WINAPI, (HWND hwnd, LPCWSTR pszClassList), (hwnd, pszClassList))
SOFT_LINK(uxtheme, CloseThemeData, HRESULT, WINAPI, (HANDLE hTheme), (hTheme))
SOFT_LINK(uxtheme, DrawThemeBackground, HRESULT, WINAPI, (HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT* pRect, const RECT* pClipRect), (hTheme, hdc, iPartId, iStateId, pRect, pClipRect))
SOFT_LINK(uxtheme, IsThemeActive, BOOL, WINAPI, (), ())
SOFT_LINK(uxtheme, IsThemeBackgroundPartiallyTransparent, BOOL, WINAPI, (HANDLE hTheme, int iPartId, int iStateId), (hTheme, iPartId, iStateId))

static bool isRunningOnVistaOrLater()
{
    static bool os = false;
    static bool initialized = false;
    if (!initialized) {
        OSVERSIONINFOEX vi = {sizeof(vi), 0};
        GetVersionEx((OSVERSIONINFO*)&vi);

        // NOTE: This does not work under a debugger - Vista shims Visual Studio,
        // making it believe it is xpsp2, which is inherited by debugged applications
        os = vi.dwMajorVersion >= 6;
        initialized = true;
    }
    return os;
}

static void checkAndInitScrollbarTheme()
{
    if (uxthemeLibrary() && !scrollbarTheme)
        scrollbarTheme = OpenThemeData(0, L"Scrollbar");
    haveTheme = scrollbarTheme && IsThemeActive();
}

#if !USE(SAFARI_THEME)
ScrollbarTheme* ScrollbarTheme::nativeTheme()
{
    static SafariThemeWin winTheme;
    return &winTheme;
}
#endif

ScrollbarThemeWin::ScrollbarThemeWin()
{
    static bool initialized;
    if (!initialized) {
        initialized = true;
        checkAndInitScrollbarTheme();
        runningVista = isRunningOnVistaOrLater();
    }
}

ScrollbarThemeWin::~ScrollbarThemeWin()
{
}

int ScrollbarThemeWin::scrollbarThickness(ScrollbarControlSize)
{
    static int thickness;
    if (!thickness)
        thickness = ::GetSystemMetrics(SM_CXVSCROLL);
    return thickness;
}

void ScrollbarThemeWin::themeChanged()
{
    if (haveTheme)
        CloseThemeData(scrollbarTheme);
}

bool ScrollbarThemeWin::invalidateOnMouseEnterExit()
{
    return runningVista;
}

bool ScrollbarThemeWin::hasThumb(Scrollbar* scrollbar)
{
    return thumbLength(scrollbar) > 0;
}

IntRect ScrollbarThemeWin::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
{
    // Windows just has single arrows.
    if (part == BackButtonEndPart)
        return IntRect();

    // Our desired rect is essentially 17x17.

    // Our actual rect will shrink to half the available space when
    // we have < 34 pixels left.  This allows the scrollbar
    // to scale down and function even at tiny sizes.
    int thickness = scrollbarThickness();
    if (scrollbar->orientation() == HorizontalScrollbar)
        return IntRect(scrollbar->x(), scrollbar->y(),
                       scrollbar->width() < 2 * thickness ? scrollbar->width() / 2 : thickness, thickness);
    return IntRect(scrollbar->x(), scrollbar->y(),
                   thickness, scrollbar->height() < 2 * thickness ? scrollbar->height() / 2 : thickness);
}

IntRect ScrollbarThemeWin::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
{
    // Windows just has single arrows.
    if (part == ForwardButtonStartPart)
        return IntRect();

    // Our desired rect is essentially 17x17.

    // Our actual rect will shrink to half the available space when
    // we have < 34 pixels left.  This allows the scrollbar
    // to scale down and function even at tiny sizes.
    int thickness = scrollbarThickness();
    if (scrollbar->orientation() == HorizontalScrollbar) {
        int w = scrollbar->width() < 2 * thickness ? scrollbar->width() / 2 : thickness;
        return IntRect(scrollbar->x() + scrollbar->width() - w, scrollbar->y(), w, thickness);
    }

    int h = scrollbar->height() < 2 * thickness ? scrollbar->height() / 2 : thickness;
    return IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - h, thickness, h);
}

IntRect ScrollbarThemeWin::trackRect(Scrollbar* scrollbar, bool)
{
    int thickness = scrollbarThickness();
    if (scrollbar->orientation() == HorizontalScrollbar) {
        if (scrollbar->width() < 2 * thickness)
            return IntRect();
        return IntRect(scrollbar->x() + thickness, scrollbar->y(), scrollbar->width() - 2 * thickness, thickness);
    }
    if (scrollbar->height() < 2 * thickness)
        return IntRect();
    return IntRect(scrollbar->x(), scrollbar->y() + thickness, thickness, scrollbar->height() - 2 * thickness);
}

void ScrollbarThemeWin::paintTrack(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart partType)
{
    checkAndInitScrollbarTheme();

    bool start = partType == BackTrackPart;
    int part;
    if (scrollbar->orientation() == HorizontalScrollbar)
        part = start ? SP_TRACKSTARTHOR : SP_TRACKENDHOR;
    else
        part = start ? SP_TRACKSTARTVERT : SP_TRACKENDVERT;

    int state;
    if (!scrollbar->enabled())
        state = TS_DISABLED;
    else if ((scrollbar->hoveredPart() == BackTrackPart && start) ||
             (scrollbar->hoveredPart() == ForwardTrackPart && !start))
        state = (scrollbar->pressedPart() == scrollbar->hoveredPart() ? TS_ACTIVE : TS_HOVER);
    else
        state = TS_NORMAL;

    bool alphaBlend = false;
    if (scrollbarTheme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, part, state);
    HDC hdc = context->getWindowsContext(rect, alphaBlend);
    RECT themeRect(rect);
    if (scrollbarTheme)
        DrawThemeBackground(scrollbarTheme, hdc, part, state, &themeRect, 0);
    else {
        DWORD color3DFace = ::GetSysColor(COLOR_3DFACE);
        DWORD colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR);
        DWORD colorWindow = ::GetSysColor(COLOR_WINDOW);
        if ((color3DFace != colorScrollbar) && (colorWindow != colorScrollbar))
            ::FillRect(hdc, &themeRect, HBRUSH(COLOR_SCROLLBAR+1));
        else {
            static WORD patternBits[8] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
            HBITMAP patternBitmap = ::CreateBitmap(8, 8, 1, 1, patternBits);
            HBRUSH brush = ::CreatePatternBrush(patternBitmap);
            SaveDC(hdc);
            ::SetTextColor(hdc, ::GetSysColor(COLOR_3DHILIGHT));
            ::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE));
            ::SetBrushOrgEx(hdc, rect.x(), rect.y(), NULL);
            ::SelectObject(hdc, brush);
            ::FillRect(hdc, &themeRect, brush);
            ::RestoreDC(hdc, -1);
            ::DeleteObject(brush);
            ::DeleteObject(patternBitmap);
        }
    }
    context->releaseWindowsContext(hdc, rect, alphaBlend);
}

void ScrollbarThemeWin::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part)
{
    checkAndInitScrollbarTheme();

    bool start = (part == BackButtonStartPart);
    int xpState = 0;
    int classicState = 0;
    if (scrollbar->orientation() == HorizontalScrollbar)
        xpState = start ? TS_LEFT_BUTTON : TS_RIGHT_BUTTON;
    else
        xpState = start ? TS_UP_BUTTON : TS_DOWN_BUTTON;
    classicState = xpState / 4;

    if (!scrollbar->enabled()) {
        xpState += TS_DISABLED;
        classicState |= DFCS_INACTIVE;
    } else if ((scrollbar->hoveredPart() == BackButtonStartPart && start) ||
               (scrollbar->hoveredPart() == ForwardButtonEndPart && !start)) {
        if (scrollbar->pressedPart() == scrollbar->hoveredPart()) {
            xpState += TS_ACTIVE;
            classicState |= DFCS_PUSHED | DFCS_FLAT;
        } else
            xpState += TS_HOVER;
    } else {
        if (scrollbar->hoveredPart() == NoPart || !runningVista)
            xpState += TS_NORMAL;
        else {
            if (scrollbar->orientation() == HorizontalScrollbar)
                xpState = start ? TS_LEFT_BUTTON_HOVER : TS_RIGHT_BUTTON_HOVER;
            else
                xpState = start ? TS_UP_BUTTON_HOVER : TS_DOWN_BUTTON_HOVER;
        }
    }

    bool alphaBlend = false;
    if (scrollbarTheme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, SP_BUTTON, xpState);
    HDC hdc = context->getWindowsContext(rect, alphaBlend);

    RECT themeRect(rect);
    if (scrollbarTheme)
        DrawThemeBackground(scrollbarTheme, hdc, SP_BUTTON, xpState, &themeRect, 0);
    else
        ::DrawFrameControl(hdc, &themeRect, DFC_SCROLL, classicState);
    context->releaseWindowsContext(hdc, rect, alphaBlend);
}

static IntRect gripperRect(int thickness, const IntRect& thumbRect)
{
    // Center in the thumb.
    int gripperThickness = thickness / 2;
    return IntRect(thumbRect.x() + (thumbRect.width() - gripperThickness) / 2,
                   thumbRect.y() + (thumbRect.height() - gripperThickness) / 2,
                   gripperThickness, gripperThickness);
}

static void paintGripper(Scrollbar* scrollbar, HDC hdc, const IntRect& rect)
{
    if (!scrollbarTheme)
        return;  // Classic look has no gripper.

    int state;
    if (!scrollbar->enabled())
        state = TS_DISABLED;
    else if (scrollbar->pressedPart() == ThumbPart)
        state = TS_ACTIVE; // Thumb always stays active once pressed.
    else if (scrollbar->hoveredPart() == ThumbPart)
        state = TS_HOVER;
    else
        state = TS_NORMAL;

    RECT themeRect(rect);
    DrawThemeBackground(scrollbarTheme, hdc, scrollbar->orientation() == HorizontalScrollbar ? SP_GRIPPERHOR : SP_GRIPPERVERT, state, &themeRect, 0);
}

void ScrollbarThemeWin::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect)
{
    checkAndInitScrollbarTheme();

    int state;
    if (!scrollbar->enabled())
        state = TS_DISABLED;
    else if (scrollbar->pressedPart() == ThumbPart)
        state = TS_ACTIVE; // Thumb always stays active once pressed.
    else if (scrollbar->hoveredPart() == ThumbPart)
        state = TS_HOVER;
    else
        state = TS_NORMAL;

    bool alphaBlend = false;
    if (scrollbarTheme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, scrollbar->orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state);
    HDC hdc = context->getWindowsContext(rect, alphaBlend);
    RECT themeRect(rect);
    if (scrollbarTheme) {
        DrawThemeBackground(scrollbarTheme, hdc, scrollbar->orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state, &themeRect, 0);
        paintGripper(scrollbar, hdc, gripperRect(scrollbarThickness(), rect));
    } else
        ::DrawEdge(hdc, &themeRect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
    context->releaseWindowsContext(hdc, rect, alphaBlend);
}

bool ScrollbarThemeWin::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt)
{
    return evt.shiftKey() && evt.button() == LeftButton;
}

}

<commit_msg>Fix Windows bustage.<commit_after>/*
 * Copyright (C) 2008 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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.
 */

#include "config.h"
#include "ScrollbarThemeWin.h"

#include "GraphicsContext.h"
#include "PlatformMouseEvent.h"
#include "Scrollbar.h"
#include "SoftLinking.h"

// Generic state constants
#define TS_NORMAL    1
#define TS_HOVER     2
#define TS_ACTIVE    3
#define TS_DISABLED  4

#define SP_BUTTON          1
#define SP_THUMBHOR        2
#define SP_THUMBVERT       3
#define SP_TRACKSTARTHOR   4
#define SP_TRACKENDHOR     5
#define SP_TRACKSTARTVERT  6
#define SP_TRACKENDVERT    7
#define SP_GRIPPERHOR      8
#define SP_GRIPPERVERT     9

#define TS_UP_BUTTON       0
#define TS_DOWN_BUTTON     4
#define TS_LEFT_BUTTON     8
#define TS_RIGHT_BUTTON    12
#define TS_UP_BUTTON_HOVER   17
#define TS_DOWN_BUTTON_HOVER  18
#define TS_LEFT_BUTTON_HOVER  19
#define TS_RIGHT_BUTTON_HOVER   20

using namespace std;

namespace WebCore {

static HANDLE scrollbarTheme;
static bool haveTheme;
static bool runningVista;

// FIXME:  Refactor the soft-linking code so that it can be shared with RenderThemeWin
SOFT_LINK_LIBRARY(uxtheme)
SOFT_LINK(uxtheme, OpenThemeData, HANDLE, WINAPI, (HWND hwnd, LPCWSTR pszClassList), (hwnd, pszClassList))
SOFT_LINK(uxtheme, CloseThemeData, HRESULT, WINAPI, (HANDLE hTheme), (hTheme))
SOFT_LINK(uxtheme, DrawThemeBackground, HRESULT, WINAPI, (HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT* pRect, const RECT* pClipRect), (hTheme, hdc, iPartId, iStateId, pRect, pClipRect))
SOFT_LINK(uxtheme, IsThemeActive, BOOL, WINAPI, (), ())
SOFT_LINK(uxtheme, IsThemeBackgroundPartiallyTransparent, BOOL, WINAPI, (HANDLE hTheme, int iPartId, int iStateId), (hTheme, iPartId, iStateId))

static bool isRunningOnVistaOrLater()
{
    static bool os = false;
    static bool initialized = false;
    if (!initialized) {
        OSVERSIONINFOEX vi = {sizeof(vi), 0};
        GetVersionEx((OSVERSIONINFO*)&vi);

        // NOTE: This does not work under a debugger - Vista shims Visual Studio,
        // making it believe it is xpsp2, which is inherited by debugged applications
        os = vi.dwMajorVersion >= 6;
        initialized = true;
    }
    return os;
}

static void checkAndInitScrollbarTheme()
{
    if (uxthemeLibrary() && !scrollbarTheme)
        scrollbarTheme = OpenThemeData(0, L"Scrollbar");
    haveTheme = scrollbarTheme && IsThemeActive();
}

#if !USE(SAFARI_THEME)
ScrollbarTheme* ScrollbarTheme::nativeTheme()
{
    static SafariThemeWin winTheme;
    return &winTheme;
}
#endif

ScrollbarThemeWin::ScrollbarThemeWin()
{
    static bool initialized;
    if (!initialized) {
        initialized = true;
        checkAndInitScrollbarTheme();
        runningVista = isRunningOnVistaOrLater();
    }
}

ScrollbarThemeWin::~ScrollbarThemeWin()
{
}

int ScrollbarThemeWin::scrollbarThickness(ScrollbarControlSize)
{
    static int thickness;
    if (!thickness)
        thickness = ::GetSystemMetrics(SM_CXVSCROLL);
    return thickness;
}

void ScrollbarThemeWin::themeChanged()
{
    if (haveTheme)
        CloseThemeData(scrollbarTheme);
}

bool ScrollbarThemeWin::invalidateOnMouseEnterExit()
{
    return runningVista;
}

bool ScrollbarThemeWin::hasThumb(Scrollbar* scrollbar)
{
    return thumbLength(scrollbar) > 0;
}

IntRect ScrollbarThemeWin::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
{
    // Windows just has single arrows.
    if (part == BackButtonEndPart)
        return IntRect();

    // Our desired rect is essentially 17x17.

    // Our actual rect will shrink to half the available space when
    // we have < 34 pixels left.  This allows the scrollbar
    // to scale down and function even at tiny sizes.
    int thickness = scrollbarThickness();
    if (scrollbar->orientation() == HorizontalScrollbar)
        return IntRect(scrollbar->x(), scrollbar->y(),
                       scrollbar->width() < 2 * thickness ? scrollbar->width() / 2 : thickness, thickness);
    return IntRect(scrollbar->x(), scrollbar->y(),
                   thickness, scrollbar->height() < 2 * thickness ? scrollbar->height() / 2 : thickness);
}

IntRect ScrollbarThemeWin::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
{
    // Windows just has single arrows.
    if (part == ForwardButtonStartPart)
        return IntRect();

    // Our desired rect is essentially 17x17.

    // Our actual rect will shrink to half the available space when
    // we have < 34 pixels left.  This allows the scrollbar
    // to scale down and function even at tiny sizes.
    int thickness = scrollbarThickness();
    if (scrollbar->orientation() == HorizontalScrollbar) {
        int w = scrollbar->width() < 2 * thickness ? scrollbar->width() / 2 : thickness;
        return IntRect(scrollbar->x() + scrollbar->width() - w, scrollbar->y(), w, thickness);
    }

    int h = scrollbar->height() < 2 * thickness ? scrollbar->height() / 2 : thickness;
    return IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - h, thickness, h);
}

IntRect ScrollbarThemeWin::trackRect(Scrollbar* scrollbar, bool)
{
    int thickness = scrollbarThickness();
    if (scrollbar->orientation() == HorizontalScrollbar) {
        if (scrollbar->width() < 2 * thickness)
            return IntRect();
        return IntRect(scrollbar->x() + thickness, scrollbar->y(), scrollbar->width() - 2 * thickness, thickness);
    }
    if (scrollbar->height() < 2 * thickness)
        return IntRect();
    return IntRect(scrollbar->x(), scrollbar->y() + thickness, thickness, scrollbar->height() - 2 * thickness);
}

void ScrollbarThemeWin::paintTrackPiece(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart partType)
{
    checkAndInitScrollbarTheme();

    bool start = partType == BackTrackPart;
    int part;
    if (scrollbar->orientation() == HorizontalScrollbar)
        part = start ? SP_TRACKSTARTHOR : SP_TRACKENDHOR;
    else
        part = start ? SP_TRACKSTARTVERT : SP_TRACKENDVERT;

    int state;
    if (!scrollbar->enabled())
        state = TS_DISABLED;
    else if ((scrollbar->hoveredPart() == BackTrackPart && start) ||
             (scrollbar->hoveredPart() == ForwardTrackPart && !start))
        state = (scrollbar->pressedPart() == scrollbar->hoveredPart() ? TS_ACTIVE : TS_HOVER);
    else
        state = TS_NORMAL;

    bool alphaBlend = false;
    if (scrollbarTheme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, part, state);
    HDC hdc = context->getWindowsContext(rect, alphaBlend);
    RECT themeRect(rect);
    if (scrollbarTheme)
        DrawThemeBackground(scrollbarTheme, hdc, part, state, &themeRect, 0);
    else {
        DWORD color3DFace = ::GetSysColor(COLOR_3DFACE);
        DWORD colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR);
        DWORD colorWindow = ::GetSysColor(COLOR_WINDOW);
        if ((color3DFace != colorScrollbar) && (colorWindow != colorScrollbar))
            ::FillRect(hdc, &themeRect, HBRUSH(COLOR_SCROLLBAR+1));
        else {
            static WORD patternBits[8] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
            HBITMAP patternBitmap = ::CreateBitmap(8, 8, 1, 1, patternBits);
            HBRUSH brush = ::CreatePatternBrush(patternBitmap);
            SaveDC(hdc);
            ::SetTextColor(hdc, ::GetSysColor(COLOR_3DHILIGHT));
            ::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE));
            ::SetBrushOrgEx(hdc, rect.x(), rect.y(), NULL);
            ::SelectObject(hdc, brush);
            ::FillRect(hdc, &themeRect, brush);
            ::RestoreDC(hdc, -1);
            ::DeleteObject(brush);
            ::DeleteObject(patternBitmap);
        }
    }
    context->releaseWindowsContext(hdc, rect, alphaBlend);
}

void ScrollbarThemeWin::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part)
{
    checkAndInitScrollbarTheme();

    bool start = (part == BackButtonStartPart);
    int xpState = 0;
    int classicState = 0;
    if (scrollbar->orientation() == HorizontalScrollbar)
        xpState = start ? TS_LEFT_BUTTON : TS_RIGHT_BUTTON;
    else
        xpState = start ? TS_UP_BUTTON : TS_DOWN_BUTTON;
    classicState = xpState / 4;

    if (!scrollbar->enabled()) {
        xpState += TS_DISABLED;
        classicState |= DFCS_INACTIVE;
    } else if ((scrollbar->hoveredPart() == BackButtonStartPart && start) ||
               (scrollbar->hoveredPart() == ForwardButtonEndPart && !start)) {
        if (scrollbar->pressedPart() == scrollbar->hoveredPart()) {
            xpState += TS_ACTIVE;
            classicState |= DFCS_PUSHED | DFCS_FLAT;
        } else
            xpState += TS_HOVER;
    } else {
        if (scrollbar->hoveredPart() == NoPart || !runningVista)
            xpState += TS_NORMAL;
        else {
            if (scrollbar->orientation() == HorizontalScrollbar)
                xpState = start ? TS_LEFT_BUTTON_HOVER : TS_RIGHT_BUTTON_HOVER;
            else
                xpState = start ? TS_UP_BUTTON_HOVER : TS_DOWN_BUTTON_HOVER;
        }
    }

    bool alphaBlend = false;
    if (scrollbarTheme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, SP_BUTTON, xpState);
    HDC hdc = context->getWindowsContext(rect, alphaBlend);

    RECT themeRect(rect);
    if (scrollbarTheme)
        DrawThemeBackground(scrollbarTheme, hdc, SP_BUTTON, xpState, &themeRect, 0);
    else
        ::DrawFrameControl(hdc, &themeRect, DFC_SCROLL, classicState);
    context->releaseWindowsContext(hdc, rect, alphaBlend);
}

static IntRect gripperRect(int thickness, const IntRect& thumbRect)
{
    // Center in the thumb.
    int gripperThickness = thickness / 2;
    return IntRect(thumbRect.x() + (thumbRect.width() - gripperThickness) / 2,
                   thumbRect.y() + (thumbRect.height() - gripperThickness) / 2,
                   gripperThickness, gripperThickness);
}

static void paintGripper(Scrollbar* scrollbar, HDC hdc, const IntRect& rect)
{
    if (!scrollbarTheme)
        return;  // Classic look has no gripper.

    int state;
    if (!scrollbar->enabled())
        state = TS_DISABLED;
    else if (scrollbar->pressedPart() == ThumbPart)
        state = TS_ACTIVE; // Thumb always stays active once pressed.
    else if (scrollbar->hoveredPart() == ThumbPart)
        state = TS_HOVER;
    else
        state = TS_NORMAL;

    RECT themeRect(rect);
    DrawThemeBackground(scrollbarTheme, hdc, scrollbar->orientation() == HorizontalScrollbar ? SP_GRIPPERHOR : SP_GRIPPERVERT, state, &themeRect, 0);
}

void ScrollbarThemeWin::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect)
{
    checkAndInitScrollbarTheme();

    int state;
    if (!scrollbar->enabled())
        state = TS_DISABLED;
    else if (scrollbar->pressedPart() == ThumbPart)
        state = TS_ACTIVE; // Thumb always stays active once pressed.
    else if (scrollbar->hoveredPart() == ThumbPart)
        state = TS_HOVER;
    else
        state = TS_NORMAL;

    bool alphaBlend = false;
    if (scrollbarTheme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, scrollbar->orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state);
    HDC hdc = context->getWindowsContext(rect, alphaBlend);
    RECT themeRect(rect);
    if (scrollbarTheme) {
        DrawThemeBackground(scrollbarTheme, hdc, scrollbar->orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state, &themeRect, 0);
        paintGripper(scrollbar, hdc, gripperRect(scrollbarThickness(), rect));
    } else
        ::DrawEdge(hdc, &themeRect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
    context->releaseWindowsContext(hdc, rect, alphaBlend);
}

bool ScrollbarThemeWin::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt)
{
    return evt.shiftKey() && evt.button() == LeftButton;
}

}

<|endoftext|>


<commit_before>// fastfilters
// Copyright (c) 2016 Sven Peter
// sven.peter@iwr.uni-heidelberg.de or mail@svenpeter.me
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
// Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>

#include "fastfilters.h"
#include "common.h"

#include <string>
#include <stdlib.h>

namespace py = pybind11;

namespace
{

struct FIRKernel {
    fastfilters_kernel_fir_t kernel;
    const unsigned order;
    const double sigma;

    FIRKernel(unsigned order, double sigma) : order(order), sigma(sigma)
    {
        kernel = fastfilters_kernel_fir_gaussian(order, sigma);

        if (!kernel)
            throw std::runtime_error("fastfilters_kernel_fir_gaussian returned NULL.");
    }

    ~FIRKernel()
    {
        fastfilters_kernel_fir_free(kernel);
        kernel = NULL;
    }

    std::string __repr__()
    {
        std::stringstream oss;
        oss << "<fastfilters.FIRKernel with sigma = " << sigma << " and order = " << order << ">";

        return oss.str();
    }
};

py::array_t<float> linalg_ev2d(py::array_t<float> &mtx)
{
    py::buffer_info info = mtx.request();

    if (info.ndim != 2)
        throw std::runtime_error("matrix must have two dimensions.");

    if (info.shape[0] != 3)
        throw std::runtime_error("1st dimension must have len = 3.");

    auto result = py::array(py::buffer_info(nullptr, sizeof(float), py::format_descriptor<float>::value(), 2,
                                            {2, info.shape[1]}, {sizeof(float) * info.shape[1], sizeof(float)}));
    py::buffer_info info_out = result.request();

    float *inptr = (float *)info.ptr;
    float *xx = inptr;
    float *xy = inptr + info.strides[0] / sizeof(float);
    float *yy = inptr + 2 * info.strides[0] / sizeof(float);

    float *outptr = (float *)info_out.ptr;
    float *ev_small = outptr;
    float *ev_big = outptr + info_out.strides[0] / sizeof(float);

    fastfilters_linalg_ev2d(xx, xy, yy, ev_small, ev_big, info.shape[1]);

    return result;
}

template <typename fastfilters_array_t> struct ff_ndim_t {
};

template <> struct ff_ndim_t<fastfilters_array2d_t> {
    static const unsigned int ndim = 2;

    static void set_z(size_t /*n_z*/, fastfilters_array2d_t /*&k*/)
    {
    }
    static void set_stride_z(size_t /*n_z*/, fastfilters_array2d_t /*&k*/)
    {
    }
};

template <> struct ff_ndim_t<fastfilters_array3d_t> {
    static const unsigned int ndim = 3;

    static void set_z(size_t n_z, fastfilters_array3d_t &k)
    {
        k.n_z = n_z;
    }
    static void set_stride_z(size_t stride_z, fastfilters_array3d_t &k)
    {
        k.stride_z = stride_z;
    }
};

template <typename fastfilters_array_t> void convert_py2ff(py::array_t<float> &np, fastfilters_array_t &ff)
{
    const unsigned int ff_ndim = ff_ndim_t<fastfilters_array_t>::ndim;
    py::buffer_info np_info = np.request();

    if (np_info.ndim >= (int)ff_ndim) {
        ff.ptr = (float *)np_info.ptr;

        ff.n_x = np_info.shape[ff_ndim - 1];
        ff.stride_x = np_info.strides[ff_ndim - 1] / sizeof(float);

        ff.n_y = np_info.shape[ff_ndim - 2];
        ff.stride_y = np_info.strides[ff_ndim - 2] / sizeof(float);

        if (ff_ndim == 3) {
            ff_ndim_t<fastfilters_array_t>::set_z(np_info.shape[ff_ndim - 3], ff);
            ff_ndim_t<fastfilters_array_t>::set_stride_z(np_info.strides[ff_ndim - 3] / sizeof(float), ff);
        }
    } else {
        throw std::logic_error("Too few dimensions.");
    }

    if (np_info.ndim == ff_ndim) {
        ff.n_channels = 1;
    } else if ((np_info.ndim == ff_ndim + 1) && np_info.shape[ff_ndim] < 8 &&
               np_info.strides[ff_ndim + 1] == sizeof(float)) {
        ff.n_channels = np_info.shape[ff_ndim];
    } else {
        throw std::logic_error("Invalid number of dimensions or too many channels or stride between channels.");
    }
}

py::array_t<float> convolve_2d_fir(py::array_t<float> &input, FIRKernel *k0, FIRKernel *k1)
{
    fastfilters_array2d_t ff;
    convert_py2ff(input, ff);
    throw std::logic_error("All good.");
}

py::array_t<float> convolve_3d_fir(py::array_t<float> &input, FIRKernel *k0, FIRKernel *k1, FIRKernel *k2)
{
    fastfilters_array3d_t ff;
    convert_py2ff(input, ff);
    throw std::logic_error("All good.");
}

py::array_t<float> convolve_fir(py::array_t<float> &input, std::vector<FIRKernel *> k)
{
    if (k.size() == 2)
        return convolve_2d_fir(input, k[0], k[1]);
    else if (k.size() == 3)
        return convolve_3d_fir(input, k[0], k[1], k[2]);
    else
        throw std::logic_error("Invalid number of dimensions.");
}
};

PYBIND11_PLUGIN(fastfilters)
{
    py::module m_fastfilters("fastfilters", "fast gaussian kernel and derivative filters");

    fastfilters_init(PyMem_Malloc, PyMem_Free);

    py::class_<FIRKernel>(m_fastfilters, "FIRKernel")
        .def(py::init<unsigned, double>())
        .def_readonly("sigma", &FIRKernel::sigma)
        .def_readonly("order", &FIRKernel::order);

    m_fastfilters.def("linalg_ev2d", &linalg_ev2d);
    m_fastfilters.def("convolve_fir", &convolve_fir);

    return m_fastfilters.ptr();
}<commit_msg>update py bindings<commit_after>// fastfilters
// Copyright (c) 2016 Sven Peter
// sven.peter@iwr.uni-heidelberg.de or mail@svenpeter.me
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
// Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>

#include "fastfilters.h"
#include "common.h"

#include <string>
#include <stdlib.h>

namespace py = pybind11;

namespace
{

struct FIRKernel {
    fastfilters_kernel_fir_t kernel;
    const unsigned order;
    const double sigma;

    FIRKernel(unsigned order, double sigma) : order(order), sigma(sigma)
    {
        kernel = fastfilters_kernel_fir_gaussian(order, sigma);

        if (!kernel)
            throw std::runtime_error("fastfilters_kernel_fir_gaussian returned NULL.");
    }

    ~FIRKernel()
    {
        fastfilters_kernel_fir_free(kernel);
        kernel = NULL;
    }

    std::string __repr__()
    {
        std::stringstream oss;
        oss << "<fastfilters.FIRKernel with sigma = " << sigma << " and order = " << order << ">";

        return oss.str();
    }
};

py::array_t<float> linalg_ev2d(py::array_t<float> &mtx)
{
    py::buffer_info info = mtx.request();

    if (info.ndim != 2)
        throw std::runtime_error("matrix must have two dimensions.");

    if (info.shape[0] != 3)
        throw std::runtime_error("1st dimension must have len = 3.");

    auto result = py::array(py::buffer_info(nullptr, sizeof(float), py::format_descriptor<float>::value(), 2,
                                            {2, info.shape[1]}, {sizeof(float) * info.shape[1], sizeof(float)}));
    py::buffer_info info_out = result.request();

    float *inptr = (float *)info.ptr;
    float *xx = inptr;
    float *xy = inptr + info.strides[0] / sizeof(float);
    float *yy = inptr + 2 * info.strides[0] / sizeof(float);

    float *outptr = (float *)info_out.ptr;
    float *ev_small = outptr;
    float *ev_big = outptr + info_out.strides[0] / sizeof(float);

    fastfilters_linalg_ev2d(xx, xy, yy, ev_small, ev_big, info.shape[1]);

    return result;
}

template <typename fastfilters_array_t> struct ff_ndim_t {
};

template <> struct ff_ndim_t<fastfilters_array2d_t> {
    static const unsigned int ndim = 2;

    static void set_z(size_t /*n_z*/, fastfilters_array2d_t /*&k*/)
    {
    }
    static void set_stride_z(size_t /*n_z*/, fastfilters_array2d_t /*&k*/)
    {
    }
};

template <> struct ff_ndim_t<fastfilters_array3d_t> {
    static const unsigned int ndim = 3;

    static void set_z(size_t n_z, fastfilters_array3d_t &k)
    {
        k.n_z = n_z;
    }
    static void set_stride_z(size_t stride_z, fastfilters_array3d_t &k)
    {
        k.stride_z = stride_z;
    }
};

template <typename fastfilters_array_t> void convert_py2ff(py::array_t<float> &np, fastfilters_array_t &ff)
{
    const unsigned int ff_ndim = ff_ndim_t<fastfilters_array_t>::ndim;
    py::buffer_info np_info = np.request();

    if (np_info.ndim >= (int)ff_ndim) {
        ff.ptr = (float *)np_info.ptr;

        ff.n_x = np_info.shape[ff_ndim - 1];
        ff.stride_x = np_info.strides[ff_ndim - 1] / sizeof(float);

        ff.n_y = np_info.shape[ff_ndim - 2];
        ff.stride_y = np_info.strides[ff_ndim - 2] / sizeof(float);

        if (ff_ndim == 3) {
            ff_ndim_t<fastfilters_array_t>::set_z(np_info.shape[ff_ndim - 3], ff);
            ff_ndim_t<fastfilters_array_t>::set_stride_z(np_info.strides[ff_ndim - 3] / sizeof(float), ff);
        }
    } else {
        throw std::logic_error("Too few dimensions.");
    }

    if (np_info.ndim == ff_ndim) {
        ff.n_channels = 1;
    } else if ((np_info.ndim == ff_ndim + 1) && np_info.shape[ff_ndim] < 8 &&
               np_info.strides[ff_ndim + 1] == sizeof(float)) {
        ff.n_channels = np_info.shape[ff_ndim];
    } else {
        throw std::logic_error("Invalid number of dimensions or too many channels or stride between channels.");
    }
}

py::array_t<float> array_like(py::array_t<float> &base)
{
    py::buffer_info info = base.request();
    auto result = py::array(py::buffer_info(nullptr, sizeof(float), py::format_descriptor<float>::value(), info.ndim,
                                            info.shape, info.strides));

    return result;
}

py::array_t<float> convolve_2d_fir(py::array_t<float> &input, FIRKernel *k0, FIRKernel *k1)
{
    fastfilters_array2d_t ff;
    fastfilters_array2d_t ff_out;

    auto result = array_like(input);

    convert_py2ff(input, ff);
    convert_py2ff(result, ff_out);

    if (!fastfilters_fir_convolve2d(&ff, k0->kernel, k1->kernel, &ff_out, 0, 0, 0, 0))
        throw std::logic_error("fastfilters_fir_convolve2d returned false.");

    return result;
}

py::array_t<float> convolve_3d_fir(py::array_t<float> &input, FIRKernel *k0, FIRKernel *k1, FIRKernel *k2)
{
    fastfilters_array3d_t ff;
    convert_py2ff(input, ff);
    throw std::logic_error("3D unsupported.");
}

py::array_t<float> convolve_fir(py::array_t<float> &input, std::vector<FIRKernel *> k)
{
    if (k.size() == 2)
        return convolve_2d_fir(input, k[0], k[1]);
    else if (k.size() == 3)
        return convolve_3d_fir(input, k[0], k[1], k[2]);
    else
        throw std::logic_error("Invalid number of dimensions.");
}
};

PYBIND11_PLUGIN(fastfilters)
{
    py::module m_fastfilters("fastfilters", "fast gaussian kernel and derivative filters");

    fastfilters_init(PyMem_Malloc, PyMem_Free);

    py::class_<FIRKernel>(m_fastfilters, "FIRKernel")
        .def(py::init<unsigned, double>())
        .def_readonly("sigma", &FIRKernel::sigma)
        .def_readonly("order", &FIRKernel::order);

    m_fastfilters.def("linalg_ev2d", &linalg_ev2d);
    m_fastfilters.def("convolve_fir", &convolve_fir);

    return m_fastfilters.ptr();
}<|endoftext|>


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

// Config.cpp: Implements the egl::Config class, describing the format, type
// and size for an egl::Surface. Implements EGLConfig and related functionality.
// [EGL 1.5] section 3.4 page 19.

#include "libANGLE/Config.h"
#include "libANGLE/AttributeMap.h"

#include <algorithm>
#include <vector>

#include "angle_gl.h"
#include <EGL/eglext.h>

#include "common/debug.h"

namespace egl
{

Config::Config()
    : renderTargetFormat(GL_NONE),
      depthStencilFormat(GL_NONE),
      bufferSize(0),
      redSize(0),
      greenSize(0),
      blueSize(0),
      luminanceSize(0),
      alphaSize(0),
      alphaMaskSize(0),
      bindToTextureRGB(EGL_FALSE),
      bindToTextureRGBA(EGL_FALSE),
      colorBufferType(EGL_NONE),
      configCaveat(EGL_NONE),
      configID(0),
      conformant(0),
      depthSize(0),
      level(0),
      matchNativePixmap(EGL_FALSE),
      maxPBufferWidth(0),
      maxPBufferHeight(0),
      maxPBufferPixels(0),
      maxSwapInterval(0),
      minSwapInterval(0),
      nativeRenderable(EGL_FALSE),
      nativeVisualID(0),
      nativeVisualType(0),
      renderableType(0),
      sampleBuffers(0),
      samples(0),
      stencilSize(0),
      surfaceType(0),
      transparentType(EGL_NONE),
      transparentRedValue(0),
      transparentGreenValue(0),
      transparentBlueValue(0),
      optimalOrientation(0),
      colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
{
}

EGLint ConfigSet::add(const Config &config)
{
    // Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4)
    EGLint id = static_cast<EGLint>(mConfigs.size()) + 1;

    Config copyConfig(config);
    copyConfig.configID = id;
    mConfigs.insert(std::make_pair(id, copyConfig));

    return id;
}

const Config &ConfigSet::get(EGLint id) const
{
    ASSERT(mConfigs.find(id) != mConfigs.end());
    return mConfigs.find(id)->second;
}

void ConfigSet::clear()
{
    mConfigs.clear();
}

size_t ConfigSet::size() const
{
    return mConfigs.size();
}

bool ConfigSet::contains(const Config *config) const
{
    for (auto i = mConfigs.begin(); i != mConfigs.end(); i++)
    {
        const Config &item = i->second;
        if (config == &item)
        {
            return true;
        }
    }

    return false;
}

// Function object used by STL sorting routines for ordering Configs according to [EGL 1.5] section 3.4.1.2 page 28.
class ConfigSorter
{
  public:
    explicit ConfigSorter(const AttributeMap &attributeMap)
        : mWantRed(false),
          mWantGreen(false),
          mWantBlue(false),
          mWantAlpha(false),
          mWantLuminance(false)
    {
        scanForWantedComponents(attributeMap);
    }

    bool operator()(const Config *x, const Config *y) const
    {
        return (*this)(*x, *y);
    }

    bool operator()(const Config &x, const Config &y) const
    {
        #define SORT(attribute)                        \
            if (x.attribute != y.attribute)            \
            {                                          \
                return x.attribute < y.attribute;      \
            }

        static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "Unexpected EGL enum value.");
        SORT(configCaveat);

        static_assert(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT < EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
                      "Unexpected order of EGL enums.");
        SORT(colorComponentType);

        static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value.");
        SORT(colorBufferType);

        // By larger total number of color bits, only considering those that are requested to be > 0.
        EGLint xComponentsSize = wantedComponentsSize(x);
        EGLint yComponentsSize = wantedComponentsSize(y);
        if (xComponentsSize != yComponentsSize)
        {
            return xComponentsSize > yComponentsSize;
        }

        SORT(bufferSize);
        SORT(sampleBuffers);
        SORT(samples);
        SORT(depthSize);
        SORT(stencilSize);
        SORT(alphaMaskSize);
        SORT(nativeVisualType);
        SORT(configID);

        #undef SORT

        return false;
    }

  private:
    void scanForWantedComponents(const AttributeMap &attributeMap)
    {
        // [EGL 1.5] section 3.4.1.2 page 30
        // Sorting rule #3: by larger total number of color bits, not considering
        // components that are 0 or don't-care.
        for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
        {
            EGLAttrib attributeKey   = attribIter->first;
            EGLAttrib attributeValue = attribIter->second;
            if (attributeKey != 0 && attributeValue != EGL_DONT_CARE)
            {
                switch (attributeKey)
                {
                case EGL_RED_SIZE:       mWantRed = true; break;
                case EGL_GREEN_SIZE:     mWantGreen = true; break;
                case EGL_BLUE_SIZE:      mWantBlue = true; break;
                case EGL_ALPHA_SIZE:     mWantAlpha = true; break;
                case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
                }
            }
        }
    }

    EGLint wantedComponentsSize(const Config &config) const
    {
        EGLint total = 0;

        if (mWantRed)       total += config.redSize;
        if (mWantGreen)     total += config.greenSize;
        if (mWantBlue)      total += config.blueSize;
        if (mWantAlpha)     total += config.alphaSize;
        if (mWantLuminance) total += config.luminanceSize;

        return total;
    }

    bool mWantRed;
    bool mWantGreen;
    bool mWantBlue;
    bool mWantAlpha;
    bool mWantLuminance;
};

std::vector<const Config*> ConfigSet::filter(const AttributeMap &attributeMap) const
{
    std::vector<const Config*> result;
    result.reserve(mConfigs.size());

    for (auto configIter = mConfigs.begin(); configIter != mConfigs.end(); configIter++)
    {
        const Config &config = configIter->second;
        bool match = true;

        for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
        {
            EGLAttrib attributeKey   = attribIter->first;
            EGLAttrib attributeValue = attribIter->second;

            switch (attributeKey)
            {
              case EGL_BUFFER_SIZE:               match = config.bufferSize >= attributeValue;                        break;
              case EGL_ALPHA_SIZE:                match = config.alphaSize >= attributeValue;                         break;
              case EGL_BLUE_SIZE:                 match = config.blueSize >= attributeValue;                          break;
              case EGL_GREEN_SIZE:                match = config.greenSize >= attributeValue;                         break;
              case EGL_RED_SIZE:                  match = config.redSize >= attributeValue;                           break;
              case EGL_DEPTH_SIZE:                match = config.depthSize >= attributeValue;                         break;
              case EGL_STENCIL_SIZE:              match = config.stencilSize >= attributeValue;                       break;
              case EGL_CONFIG_CAVEAT:             match = config.configCaveat == (EGLenum)attributeValue;             break;
              case EGL_CONFIG_ID:                 match = config.configID == attributeValue;                          break;
              case EGL_LEVEL:                     match = config.level >= attributeValue;                             break;
              case EGL_NATIVE_RENDERABLE:         match = config.nativeRenderable == (EGLBoolean)attributeValue;      break;
              case EGL_NATIVE_VISUAL_TYPE:        match = config.nativeVisualType == attributeValue;                  break;
              case EGL_SAMPLES:                   match = config.samples >= attributeValue;                           break;
              case EGL_SAMPLE_BUFFERS:            match = config.sampleBuffers >= attributeValue;                     break;
              case EGL_SURFACE_TYPE:              match = (config.surfaceType & attributeValue) == attributeValue;    break;
              case EGL_TRANSPARENT_TYPE:          match = config.transparentType == (EGLenum)attributeValue;          break;
              case EGL_TRANSPARENT_BLUE_VALUE:    match = config.transparentBlueValue == attributeValue;              break;
              case EGL_TRANSPARENT_GREEN_VALUE:   match = config.transparentGreenValue == attributeValue;             break;
              case EGL_TRANSPARENT_RED_VALUE:     match = config.transparentRedValue == attributeValue;               break;
              case EGL_BIND_TO_TEXTURE_RGB:       match = config.bindToTextureRGB == (EGLBoolean)attributeValue;      break;
              case EGL_BIND_TO_TEXTURE_RGBA:      match = config.bindToTextureRGBA == (EGLBoolean)attributeValue;     break;
              case EGL_MIN_SWAP_INTERVAL:         match = config.minSwapInterval == attributeValue;                   break;
              case EGL_MAX_SWAP_INTERVAL:         match = config.maxSwapInterval == attributeValue;                   break;
              case EGL_LUMINANCE_SIZE:            match = config.luminanceSize >= attributeValue;                     break;
              case EGL_ALPHA_MASK_SIZE:           match = config.alphaMaskSize >= attributeValue;                     break;
              case EGL_COLOR_BUFFER_TYPE:         match = config.colorBufferType == (EGLenum)attributeValue;          break;
              case EGL_RENDERABLE_TYPE:           match = (config.renderableType & attributeValue) == attributeValue; break;
              case EGL_MATCH_NATIVE_PIXMAP:       match = false; UNIMPLEMENTED();                                     break;
              case EGL_CONFORMANT:                match = (config.conformant & attributeValue) == attributeValue;     break;
              case EGL_MAX_PBUFFER_WIDTH:         match = config.maxPBufferWidth >= attributeValue;                   break;
              case EGL_MAX_PBUFFER_HEIGHT:        match = config.maxPBufferHeight >= attributeValue;                  break;
              case EGL_MAX_PBUFFER_PIXELS:        match = config.maxPBufferPixels >= attributeValue;                  break;
              case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
                  match = config.optimalOrientation == attributeValue;
                  break;
              case EGL_COLOR_COMPONENT_TYPE_EXT:
                  match = config.colorComponentType == static_cast<EGLenum>(attributeValue);
                  break;
              default: UNREACHABLE();
            }

            if (!match)
            {
                break;
            }
        }

        if (match)
        {
            result.push_back(&config);
        }
    }

    // Sort the result
    std::sort(result.begin(), result.end(), ConfigSorter(attributeMap));

    return result;
}

}
<commit_msg>Fix scanForWantedComponents not ignoring attribute values of 0.<commit_after>//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Config.cpp: Implements the egl::Config class, describing the format, type
// and size for an egl::Surface. Implements EGLConfig and related functionality.
// [EGL 1.5] section 3.4 page 19.

#include "libANGLE/Config.h"
#include "libANGLE/AttributeMap.h"

#include <algorithm>
#include <vector>

#include "angle_gl.h"
#include <EGL/eglext.h>

#include "common/debug.h"

namespace egl
{

Config::Config()
    : renderTargetFormat(GL_NONE),
      depthStencilFormat(GL_NONE),
      bufferSize(0),
      redSize(0),
      greenSize(0),
      blueSize(0),
      luminanceSize(0),
      alphaSize(0),
      alphaMaskSize(0),
      bindToTextureRGB(EGL_FALSE),
      bindToTextureRGBA(EGL_FALSE),
      colorBufferType(EGL_NONE),
      configCaveat(EGL_NONE),
      configID(0),
      conformant(0),
      depthSize(0),
      level(0),
      matchNativePixmap(EGL_FALSE),
      maxPBufferWidth(0),
      maxPBufferHeight(0),
      maxPBufferPixels(0),
      maxSwapInterval(0),
      minSwapInterval(0),
      nativeRenderable(EGL_FALSE),
      nativeVisualID(0),
      nativeVisualType(0),
      renderableType(0),
      sampleBuffers(0),
      samples(0),
      stencilSize(0),
      surfaceType(0),
      transparentType(EGL_NONE),
      transparentRedValue(0),
      transparentGreenValue(0),
      transparentBlueValue(0),
      optimalOrientation(0),
      colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
{
}

EGLint ConfigSet::add(const Config &config)
{
    // Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4)
    EGLint id = static_cast<EGLint>(mConfigs.size()) + 1;

    Config copyConfig(config);
    copyConfig.configID = id;
    mConfigs.insert(std::make_pair(id, copyConfig));

    return id;
}

const Config &ConfigSet::get(EGLint id) const
{
    ASSERT(mConfigs.find(id) != mConfigs.end());
    return mConfigs.find(id)->second;
}

void ConfigSet::clear()
{
    mConfigs.clear();
}

size_t ConfigSet::size() const
{
    return mConfigs.size();
}

bool ConfigSet::contains(const Config *config) const
{
    for (auto i = mConfigs.begin(); i != mConfigs.end(); i++)
    {
        const Config &item = i->second;
        if (config == &item)
        {
            return true;
        }
    }

    return false;
}

// Function object used by STL sorting routines for ordering Configs according to [EGL 1.5] section 3.4.1.2 page 28.
class ConfigSorter
{
  public:
    explicit ConfigSorter(const AttributeMap &attributeMap)
        : mWantRed(false),
          mWantGreen(false),
          mWantBlue(false),
          mWantAlpha(false),
          mWantLuminance(false)
    {
        scanForWantedComponents(attributeMap);
    }

    bool operator()(const Config *x, const Config *y) const
    {
        return (*this)(*x, *y);
    }

    bool operator()(const Config &x, const Config &y) const
    {
        #define SORT(attribute)                        \
            if (x.attribute != y.attribute)            \
            {                                          \
                return x.attribute < y.attribute;      \
            }

        static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "Unexpected EGL enum value.");
        SORT(configCaveat);

        static_assert(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT < EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
                      "Unexpected order of EGL enums.");
        SORT(colorComponentType);

        static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value.");
        SORT(colorBufferType);

        // By larger total number of color bits, only considering those that are requested to be > 0.
        EGLint xComponentsSize = wantedComponentsSize(x);
        EGLint yComponentsSize = wantedComponentsSize(y);
        if (xComponentsSize != yComponentsSize)
        {
            return xComponentsSize > yComponentsSize;
        }

        SORT(bufferSize);
        SORT(sampleBuffers);
        SORT(samples);
        SORT(depthSize);
        SORT(stencilSize);
        SORT(alphaMaskSize);
        SORT(nativeVisualType);
        SORT(configID);

        #undef SORT

        return false;
    }

  private:
    static bool wantsComponent(const AttributeMap &attributeMap, EGLAttrib component)
    {
        // [EGL 1.5] section 3.4.1.2 page 30
        // Sorting rule #3: by larger total number of color bits, not considering
        // components that are 0 or don't-care.
        EGLAttrib value = attributeMap.get(component, 0);
        return value != 0 && value != EGL_DONT_CARE;
    }

    void scanForWantedComponents(const AttributeMap &attributeMap)
    {
        mWantRed       = wantsComponent(attributeMap, EGL_RED_SIZE);
        mWantGreen     = wantsComponent(attributeMap, EGL_GREEN_SIZE);
        mWantBlue      = wantsComponent(attributeMap, EGL_BLUE_SIZE);
        mWantAlpha     = wantsComponent(attributeMap, EGL_ALPHA_SIZE);
        mWantLuminance = wantsComponent(attributeMap, EGL_LUMINANCE_SIZE);
    }

    EGLint wantedComponentsSize(const Config &config) const
    {
        EGLint total = 0;

        if (mWantRed)       total += config.redSize;
        if (mWantGreen)     total += config.greenSize;
        if (mWantBlue)      total += config.blueSize;
        if (mWantAlpha)     total += config.alphaSize;
        if (mWantLuminance) total += config.luminanceSize;

        return total;
    }

    bool mWantRed;
    bool mWantGreen;
    bool mWantBlue;
    bool mWantAlpha;
    bool mWantLuminance;
};

std::vector<const Config*> ConfigSet::filter(const AttributeMap &attributeMap) const
{
    std::vector<const Config*> result;
    result.reserve(mConfigs.size());

    for (auto configIter = mConfigs.begin(); configIter != mConfigs.end(); configIter++)
    {
        const Config &config = configIter->second;
        bool match = true;

        for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
        {
            EGLAttrib attributeKey   = attribIter->first;
            EGLAttrib attributeValue = attribIter->second;

            switch (attributeKey)
            {
              case EGL_BUFFER_SIZE:               match = config.bufferSize >= attributeValue;                        break;
              case EGL_ALPHA_SIZE:                match = config.alphaSize >= attributeValue;                         break;
              case EGL_BLUE_SIZE:                 match = config.blueSize >= attributeValue;                          break;
              case EGL_GREEN_SIZE:                match = config.greenSize >= attributeValue;                         break;
              case EGL_RED_SIZE:                  match = config.redSize >= attributeValue;                           break;
              case EGL_DEPTH_SIZE:                match = config.depthSize >= attributeValue;                         break;
              case EGL_STENCIL_SIZE:              match = config.stencilSize >= attributeValue;                       break;
              case EGL_CONFIG_CAVEAT:             match = config.configCaveat == (EGLenum)attributeValue;             break;
              case EGL_CONFIG_ID:                 match = config.configID == attributeValue;                          break;
              case EGL_LEVEL:                     match = config.level >= attributeValue;                             break;
              case EGL_NATIVE_RENDERABLE:         match = config.nativeRenderable == (EGLBoolean)attributeValue;      break;
              case EGL_NATIVE_VISUAL_TYPE:        match = config.nativeVisualType == attributeValue;                  break;
              case EGL_SAMPLES:                   match = config.samples >= attributeValue;                           break;
              case EGL_SAMPLE_BUFFERS:            match = config.sampleBuffers >= attributeValue;                     break;
              case EGL_SURFACE_TYPE:              match = (config.surfaceType & attributeValue) == attributeValue;    break;
              case EGL_TRANSPARENT_TYPE:          match = config.transparentType == (EGLenum)attributeValue;          break;
              case EGL_TRANSPARENT_BLUE_VALUE:    match = config.transparentBlueValue == attributeValue;              break;
              case EGL_TRANSPARENT_GREEN_VALUE:   match = config.transparentGreenValue == attributeValue;             break;
              case EGL_TRANSPARENT_RED_VALUE:     match = config.transparentRedValue == attributeValue;               break;
              case EGL_BIND_TO_TEXTURE_RGB:       match = config.bindToTextureRGB == (EGLBoolean)attributeValue;      break;
              case EGL_BIND_TO_TEXTURE_RGBA:      match = config.bindToTextureRGBA == (EGLBoolean)attributeValue;     break;
              case EGL_MIN_SWAP_INTERVAL:         match = config.minSwapInterval == attributeValue;                   break;
              case EGL_MAX_SWAP_INTERVAL:         match = config.maxSwapInterval == attributeValue;                   break;
              case EGL_LUMINANCE_SIZE:            match = config.luminanceSize >= attributeValue;                     break;
              case EGL_ALPHA_MASK_SIZE:           match = config.alphaMaskSize >= attributeValue;                     break;
              case EGL_COLOR_BUFFER_TYPE:         match = config.colorBufferType == (EGLenum)attributeValue;          break;
              case EGL_RENDERABLE_TYPE:           match = (config.renderableType & attributeValue) == attributeValue; break;
              case EGL_MATCH_NATIVE_PIXMAP:       match = false; UNIMPLEMENTED();                                     break;
              case EGL_CONFORMANT:                match = (config.conformant & attributeValue) == attributeValue;     break;
              case EGL_MAX_PBUFFER_WIDTH:         match = config.maxPBufferWidth >= attributeValue;                   break;
              case EGL_MAX_PBUFFER_HEIGHT:        match = config.maxPBufferHeight >= attributeValue;                  break;
              case EGL_MAX_PBUFFER_PIXELS:        match = config.maxPBufferPixels >= attributeValue;                  break;
              case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
                  match = config.optimalOrientation == attributeValue;
                  break;
              case EGL_COLOR_COMPONENT_TYPE_EXT:
                  match = config.colorComponentType == static_cast<EGLenum>(attributeValue);
                  break;
              default: UNREACHABLE();
            }

            if (!match)
            {
                break;
            }
        }

        if (match)
        {
            result.push_back(&config);
        }
    }

    // Sort the result
    std::sort(result.begin(), result.end(), ConfigSorter(attributeMap));

    return result;
}

}
<|endoftext|>


<commit_before>/***********************************************************************
    filename:   Sample_FirstWindow.cpp
    created:    10/3/2005
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "Sample_FirstWindow.h"
#include "CEGUI.h"
#include <iostream>

int main(int /*argc*/, char* /*argv*/[])
{
    // This is a basic start-up for the sample application which is
    // object orientated in nature, so we just need an instance of
    // the CEGuiSample based object and then tell that sample application
    // to run.  All of the samples will use code similar to this in the
    // main/WinMain function.
    FirstWindowSample app;
    return app.run();
}

/*************************************************************************
    Sample specific initialisation goes here.
*************************************************************************/
bool FirstWindowSample::initialiseSample()
{
    using namespace CEGUI;

    WindowFactoryManager::getSingleton().addWindowTypeAlias("TaharezLook/WobblyFrameWindow", "TaharezLook/FrameWindow");

    SchemeManager::getSingleton().createFromFile("TaharezLook.scheme");
    System::getSingleton().setDefaultMouseCursor("TaharezLook/MouseArrow");
    WindowManager& winMgr = WindowManager::getSingleton();
    Window* root = winMgr.loadLayoutFromFile("Demo7Windows.layout");

    XMLSerializer s(std::cout);
    root->writeXMLToStream(s);

    return true;
}

/*************************************************************************
    Cleans up resources allocated in the initialiseSample call.
*************************************************************************/
void FirstWindowSample::cleanupSample()
{
    // nothing to do here!
}
<commit_msg>Revert my hacked FirstWindow sample code<commit_after>/***********************************************************************
    filename:   Sample_FirstWindow.cpp
    created:    10/3/2005
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "Sample_FirstWindow.h"
#include "CEGUI.h"

int main(int /*argc*/, char* /*argv*/[])
{
    // This is a basic start-up for the sample application which is
    // object orientated in nature, so we just need an instance of
    // the CEGuiSample based object and then tell that sample application
    // to run.  All of the samples will use code similar to this in the
    // main/WinMain function.
    FirstWindowSample app;
    return app.run();
}

/*************************************************************************
    Sample specific initialisation goes here.
*************************************************************************/
bool FirstWindowSample::initialiseSample()
{
    using namespace CEGUI;

    // CEGUI relies on various systems being set-up, so this is what we do
    // here first.
    //
    // The first thing to do is load a CEGUI 'scheme' this is basically a file
    // that groups all the required resources and definitions for a particular
    // skin so they can be loaded / initialised easily
    //
    // So, we use the SchemeManager singleton to load in a scheme that loads the
    // imagery and registers widgets for the TaharezLook skin.  This scheme also
    // loads in a font that gets used as the system default.
    SchemeManager::getSingleton().createFromFile("TaharezLook.scheme");

    // The next thing we do is to set a default mouse cursor image.  This is
    // not strictly essential, although it is nice to always have a visible
    // cursor if a window or widget does not explicitly set one of its own.
    //
    // The TaharezLook Imageset contains an Image named "MouseArrow" which is
    // the ideal thing to have as a defult mouse cursor image.
    System::getSingleton().setDefaultMouseCursor("TaharezLook/MouseArrow");

    // Now the system is initialised, we can actually create some UI elements, for
    // this first example, a full-screen 'root' window is set as the active GUI
    // sheet, and then a simple frame window will be created and attached to it.

    // All windows and widgets are created via the WindowManager singleton.
    WindowManager& winMgr = WindowManager::getSingleton();

    // Here we create a "DeafultWindow".  This is a native type, that is, it does
    // not have to be loaded via a scheme, it is always available.  One common use
    // for the DefaultWindow is as a generic container for other windows.  Its
    // size defaults to 1.0f x 1.0f using the Relative metrics mode, which means
    // when it is set as the root GUI sheet window, it will cover the entire display.
    // The DefaultWindow does not perform any rendering of its own, so is invisible.
    //
    // Create a DefaultWindow called 'Root'.
    DefaultWindow* root = (DefaultWindow*)winMgr.createWindow("DefaultWindow", "Root");

    // set the GUI root window (also known as the GUI "sheet"), so the gui we set up
    // will be visible.
    System::getSingleton().setGUISheet(root);

    // A FrameWindow is a window with a frame and a titlebar which may be moved around
    // and resized.
    //
    // Create a FrameWindow in the TaharezLook style, and name it 'Demo Window'
    FrameWindow* wnd = (FrameWindow*)winMgr.createWindow("TaharezLook/FrameWindow", "Demo Window");

    // Here we attach the newly created FrameWindow to the previously created
    // DefaultWindow which we will be using as the root of the displayed gui.
    root->addChild(wnd);

    // Windows are in Relative metrics mode by default.  This means that we can
    // specify sizes and positions without having to know the exact pixel size
    // of the elements in advance.  The relative metrics mode co-ordinates are
    // relative to the parent of the window where the co-ordinates are being set.
    // This means that if 0.5f is specified as the width for a window, that window
    // will be half as its parent window.
    //
    // Here we set the FrameWindow so that it is half the size of the display,
    // and centered within the display.
    wnd->setPosition(UVector2(cegui_reldim(0.25f), cegui_reldim( 0.25f)));
    wnd->setSize(USize(cegui_reldim(0.5f), cegui_reldim( 0.5f)));

    // now we set the maximum and minum sizes for the new window.  These are
    // specified using relative co-ordinates, but the important thing to note
    // is that these settings are aways relative to the display rather than the
    // parent window.
    //
    // here we set a maximum size for the FrameWindow which is equal to the size
    // of the display, and a minimum size of one tenth of the display.
    wnd->setMaxSize(USize(cegui_reldim(1.0f), cegui_reldim( 1.0f)));
    wnd->setMinSize(USize(cegui_reldim(0.1f), cegui_reldim( 0.1f)));

    // As a final step in the initialisation of our sample window, we set the window's
    // text to "Hello World!", so that this text will appear as the caption in the
    // FrameWindow's titlebar.
    wnd->setText("Hello World!");

    // return true so that the samples framework knows that initialisation was a
    // success, and that it should now run the sample.
    return true;
}

/*************************************************************************
    Cleans up resources allocated in the initialiseSample call.
*************************************************************************/
void FirstWindowSample::cleanupSample()
{
    // nothing to do here!
}
<|endoftext|>


<commit_before>#include"CentralWidget.hpp"
#include<iostream>
using std::cout;
using std::endl;

CentralWidget::CentralWidget(QWidget* parent):
    QWidget(parent){
    this->initEnvironments();
}

void CentralWidget::initEnvironments(){
    Environments::installNewEnvironment(QString("InitialEnv"),minecraft_dir);
    mcenvs = new Environments();
}

<commit_msg>今日の作業終わり。次はxmlのパースの確認をしてそろそろGUIの方を組んでいく<commit_after>#include"CentralWidget.hpp"

CentralWidget::CentralWidget(QWidget* parent):
    QWidget(parent){
    this->initEnvironments();
}

void CentralWidget::initEnvironments(){
    Environments::installNewEnvironment(QString("InitialEnv"),minecraft_dir);
    mcenvs = new Environments();
}

<|endoftext|>


<commit_before>// This is free and unencumbered software released into the public domain.
// For more information, please refer to <http://unlicense.org/>

#include "models/transmissionline/line_structure.h"

#include <cmath>

LineStructure::LineStructure() {
  height_adjustment_ = -999999;
  offset_ = -999999;
  rotation_ = -999999;
  station_ = -999999;
  structure_ = nullptr;
}

LineStructure::~LineStructure() {
}

void LineStructure::AttachHardware(const int& index,
                                   const Hardware* hardware) {
  // checks for valid structure attachment index
  if (IsValidIndex(index) == false) {
    return;
  }

  // replaces the current hardware assembly
  hardwares_.at(index) = hardware;
}

void LineStructure::DetachHardware(const int& index) {
  // checks for valid structure attachment index
  if (IsValidIndex(index) == false) {
    return;
  }

  // deletes the line hardware
  hardwares_.at(index) = nullptr;
}

bool LineStructure::Validate(
    const bool& is_included_warnings,
    std::list<ErrorMessage>* messages) const {
  // initializes
  bool is_valid = true;
  ErrorMessage message;
  message.title = "LINE STRUCTURE";

  // validates assemblies
  for (auto iter = hardwares_.cbegin(); iter != hardwares_.cend(); iter++) {
    const Hardware* hardware = *iter;
    if (hardware != nullptr) {
      if (hardware->Validate(is_included_warnings, messages) == false) {
        is_valid = false;
      }
    }
  }

  // validates height-adjustment
  if (height_adjustment_ < 0) {
    is_valid = false;
    if (messages != nullptr) {
      message.description = "Invalid height adjustment";
      messages->push_back(message);
    }
  }

  // validates rotation
  if (360 < std::abs(rotation_)) {
    is_valid = false;
    if (messages != nullptr) {
      message.description = "Invalid rotation";
      messages->push_back(message);
    }
  }

  // validates station
  if (station_ < 0) {
    is_valid = false;
    if (messages != nullptr) {
      message.description = "Invalid station";
      messages->push_back(message);
    }
  }

  // validates structure
  if (structure_ == nullptr) {
    is_valid = false;
    if (messages != nullptr) {
      message.description = "Invalid station";
      messages->push_back(message);
    }
  } else {
    if (structure_->Validate(is_included_warnings, messages) == false) {
      is_valid = false;
    }
  }

  return is_valid;
}

const std::vector<const Hardware*>* LineStructure::hardwares() const {
  return &hardwares_;
}

double LineStructure::height_adjustment() const {
  return height_adjustment_;
}

double LineStructure::offset() const {
  return offset_;
}

double LineStructure::rotation() const {
  return rotation_;
}

void LineStructure::set_height_adjustment(const double& height_adjustment) {
  height_adjustment_ = height_adjustment;
}

void LineStructure::set_offset(const double& offset) {
  offset_ = offset;
}

void LineStructure::set_rotation(const double& rotation) {
  rotation_ = rotation;
}

void LineStructure::set_station(const double& station) {
  station_ = station;
}

void LineStructure::set_structure(const Structure* structure) {
  structure_ = structure;

  // resizes hardware vector to match new attachment vector
  // any additions to the vector are set to null pointers
  hardwares_.resize(structure->attachments.size(), nullptr);
}

double LineStructure::station() const {
  return station_;
}

const Structure* LineStructure::structure() const {
  return structure_;
}

bool LineStructure::IsValidIndex(const int& index) const {
  // checks for valid structure attachment index
  const int kSize = structure_->attachments.size();
  if ((0 <= index) && (index < kSize)) {
    return true;
  } else {
    return false;
  }
}
<commit_msg>Fixed LineStructure bug when handling nullptr structure reference.<commit_after>// This is free and unencumbered software released into the public domain.
// For more information, please refer to <http://unlicense.org/>

#include "models/transmissionline/line_structure.h"

#include <cmath>

LineStructure::LineStructure() {
  height_adjustment_ = -999999;
  offset_ = -999999;
  rotation_ = -999999;
  station_ = -999999;
  structure_ = nullptr;
}

LineStructure::~LineStructure() {
}

void LineStructure::AttachHardware(const int& index,
                                   const Hardware* hardware) {
  // checks for valid structure attachment index
  if (IsValidIndex(index) == false) {
    return;
  }

  // replaces the current hardware assembly
  hardwares_.at(index) = hardware;
}

void LineStructure::DetachHardware(const int& index) {
  // checks for valid structure attachment index
  if (IsValidIndex(index) == false) {
    return;
  }

  // deletes the line hardware
  hardwares_.at(index) = nullptr;
}

bool LineStructure::Validate(
    const bool& is_included_warnings,
    std::list<ErrorMessage>* messages) const {
  // initializes
  bool is_valid = true;
  ErrorMessage message;
  message.title = "LINE STRUCTURE";

  // validates assemblies
  for (auto iter = hardwares_.cbegin(); iter != hardwares_.cend(); iter++) {
    const Hardware* hardware = *iter;
    if (hardware != nullptr) {
      if (hardware->Validate(is_included_warnings, messages) == false) {
        is_valid = false;
      }
    }
  }

  // validates height-adjustment
  if (height_adjustment_ < 0) {
    is_valid = false;
    if (messages != nullptr) {
      message.description = "Invalid height adjustment";
      messages->push_back(message);
    }
  }

  // validates rotation
  if (360 < std::abs(rotation_)) {
    is_valid = false;
    if (messages != nullptr) {
      message.description = "Invalid rotation";
      messages->push_back(message);
    }
  }

  // validates station
  if (station_ < 0) {
    is_valid = false;
    if (messages != nullptr) {
      message.description = "Invalid station";
      messages->push_back(message);
    }
  }

  // validates structure
  if (structure_ == nullptr) {
    is_valid = false;
    if (messages != nullptr) {
      message.description = "Invalid station";
      messages->push_back(message);
    }
  } else {
    if (structure_->Validate(is_included_warnings, messages) == false) {
      is_valid = false;
    }
  }

  return is_valid;
}

const std::vector<const Hardware*>* LineStructure::hardwares() const {
  return &hardwares_;
}

double LineStructure::height_adjustment() const {
  return height_adjustment_;
}

double LineStructure::offset() const {
  return offset_;
}

double LineStructure::rotation() const {
  return rotation_;
}

void LineStructure::set_height_adjustment(const double& height_adjustment) {
  height_adjustment_ = height_adjustment;
}

void LineStructure::set_offset(const double& offset) {
  offset_ = offset;
}

void LineStructure::set_rotation(const double& rotation) {
  rotation_ = rotation;
}

void LineStructure::set_station(const double& station) {
  station_ = station;
}

void LineStructure::set_structure(const Structure* structure) {
  structure_ = structure;

  if (structure_ == nullptr) {
    hardwares_.clear();
  } else {
    // resizes hardware vector to match new attachment vector
    // any additions to the vector are set to null pointers
    hardwares_.resize(structure->attachments.size(), nullptr);
  }
}

double LineStructure::station() const {
  return station_;
}

const Structure* LineStructure::structure() const {
  return structure_;
}

bool LineStructure::IsValidIndex(const int& index) const {
  if (structure_ == nullptr) {
    return false;
  }

  // checks for valid structure attachment index
  const int kSize = structure_->attachments.size();
  if ((0 <= index) && (index < kSize)) {
    return true;
  } else {
    return false;
  }
}
<|endoftext|>


<commit_before>//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//

#include "llvm-c/lto.h"
#include "llvm-c/Core.h"
#include "llvm-c/Target.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/LTO/LTOCodeGenerator.h"
#include "llvm/LTO/LTOModule.h"

// extra command-line flags needed for LTOCodeGenerator
static cl::opt<bool>
DisableOpt("disable-opt", cl::init(false),
  cl::desc("Do not run any optimization passes"));

static cl::opt<bool>
DisableInline("disable-inlining", cl::init(false),
  cl::desc("Do not run the inliner pass"));

static cl::opt<bool>
DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false),
  cl::desc("Do not run the GVN load PRE pass"));

// Holds most recent error string.
// *** Not thread safe ***
static std::string sLastErrorString;

// Holds the initialization state of the LTO module.
// *** Not thread safe ***
static bool initialized = false;

// Holds the command-line option parsing state of the LTO module.
static bool parsedOptions = false;

// Initialize the configured targets if they have not been initialized.
static void lto_initialize() {
  if (!initialized) {
    LLVMInitializeAllTargetInfos();
    LLVMInitializeAllTargets();
    LLVMInitializeAllTargetMCs();
    LLVMInitializeAllAsmParsers();
    LLVMInitializeAllAsmPrinters();
    LLVMInitializeAllDisassemblers();
    initialized = true;
  }
}

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOCodeGenerator, lto_code_gen_t);
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t);

// Convert the subtarget features into a string to pass to LTOCodeGenerator.
static void lto_add_attrs(lto_code_gen_t cg) {
  LTOCodeGenerator *CG = unwrap(cg);
  if (MAttrs.size()) {
    std::string attrs;
    for (unsigned i = 0; i < MAttrs.size(); ++i) {
      if (i > 0)
        attrs.append(",");
      attrs.append(MAttrs[i]);
    }

    CG->setAttr(attrs.c_str());
  }
}

extern const char* lto_get_version() {
  return LTOCodeGenerator::getVersionString();
}

const char* lto_get_error_message() {
  return sLastErrorString.c_str();
}

bool lto_module_is_object_file(const char* path) {
  return LTOModule::isBitcodeFile(path);
}

bool lto_module_is_object_file_for_target(const char* path,
                                          const char* target_triplet_prefix) {
  return LTOModule::isBitcodeFileForTarget(path, target_triplet_prefix);
}

bool lto_module_is_object_file_in_memory(const void* mem, size_t length) {
  return LTOModule::isBitcodeFile(mem, length);
}

bool
lto_module_is_object_file_in_memory_for_target(const void* mem,
                                            size_t length,
                                            const char* target_triplet_prefix) {
  return LTOModule::isBitcodeFileForTarget(mem, length, target_triplet_prefix);
}

lto_module_t lto_module_create(const char* path) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(LTOModule::makeLTOModule(path, Options, sLastErrorString));
}

lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(
      LTOModule::makeLTOModule(fd, path, size, Options, sLastErrorString));
}

lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path,
                                                 size_t file_size,
                                                 size_t map_size,
                                                 off_t offset) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(LTOModule::makeLTOModule(fd, path, map_size, offset, Options,
                                       sLastErrorString));
}

lto_module_t lto_module_create_from_memory(const void* mem, size_t length) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(LTOModule::makeLTOModule(mem, length, Options, sLastErrorString));
}

lto_module_t lto_module_create_from_memory_with_path(const void* mem,
                                                     size_t length,
                                                     const char *path) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(
      LTOModule::makeLTOModule(mem, length, Options, sLastErrorString, path));
}

void lto_module_dispose(lto_module_t mod) { delete unwrap(mod); }

const char* lto_module_get_target_triple(lto_module_t mod) {
  return unwrap(mod)->getTargetTriple();
}

void lto_module_set_target_triple(lto_module_t mod, const char *triple) {
  return unwrap(mod)->setTargetTriple(triple);
}

unsigned int lto_module_get_num_symbols(lto_module_t mod) {
  return unwrap(mod)->getSymbolCount();
}

const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) {
  return unwrap(mod)->getSymbolName(index);
}

lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
                                                      unsigned int index) {
  return unwrap(mod)->getSymbolAttributes(index);
}

unsigned int lto_module_get_num_deplibs(lto_module_t mod) {
  return unwrap(mod)->getDependentLibraryCount();
}

const char* lto_module_get_deplib(lto_module_t mod, unsigned int index) {
  return unwrap(mod)->getDependentLibrary(index);
}

unsigned int lto_module_get_num_linkeropts(lto_module_t mod) {
  return unwrap(mod)->getLinkerOptCount();
}

const char* lto_module_get_linkeropt(lto_module_t mod, unsigned int index) {
  return unwrap(mod)->getLinkerOpt(index);
}

void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
                                        lto_diagnostic_handler_t diag_handler,
                                        void *ctxt) {
  unwrap(cg)->setDiagnosticHandler(diag_handler, ctxt);
}

lto_code_gen_t lto_codegen_create(void) {
  lto_initialize();

  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();

  LTOCodeGenerator *CodeGen = new LTOCodeGenerator();
  if (CodeGen)
    CodeGen->setTargetOptions(Options);
  return wrap(CodeGen);
}

void lto_codegen_dispose(lto_code_gen_t cg) { delete unwrap(cg); }

bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) {
  return !unwrap(cg)->addModule(unwrap(mod), sLastErrorString);
}

bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) {
  unwrap(cg)->setDebugInfo(debug);
  return false;
}

bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) {
  unwrap(cg)->setCodePICModel(model);
  return false;
}

void lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) {
  return unwrap(cg)->setCpu(cpu);
}

void lto_codegen_set_attr(lto_code_gen_t cg, const char *attr) {
  return unwrap(cg)->setAttr(attr);
}

void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) {
  // In here only for backwards compatibility. We use MC now.
}

void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
                                    int nargs) {
  // In here only for backwards compatibility. We use MC now.
}

void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg,
                                          const char *symbol) {
  unwrap(cg)->addMustPreserveSymbol(symbol);
}

bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
  if (!parsedOptions) {
    unwrap(cg)->parseCodeGenDebugOptions();
    lto_add_attrs(cg);
    parsedOptions = true;
  }
  return !unwrap(cg)->writeMergedModules(path, sLastErrorString);
}

const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
  if (!parsedOptions) {
    unwrap(cg)->parseCodeGenDebugOptions();
    lto_add_attrs(cg);
    parsedOptions = true;
  }
  return unwrap(cg)->compile(length, DisableOpt, DisableInline,
                             DisableGVNLoadPRE, sLastErrorString);
}

bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
  if (!parsedOptions) {
    unwrap(cg)->parseCodeGenDebugOptions();
    lto_add_attrs(cg);
    parsedOptions = true;
  }
  return !unwrap(cg)->compile_to_file(name, DisableOpt, DisableInline,
                                      DisableGVNLoadPRE, sLastErrorString);
}

void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
  unwrap(cg)->setCodeGenDebugOptions(opt);
}
<commit_msg>Fix gcc -pedantic warning in lto.cpp.<commit_after>//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//

#include "llvm-c/lto.h"
#include "llvm-c/Core.h"
#include "llvm-c/Target.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/LTO/LTOCodeGenerator.h"
#include "llvm/LTO/LTOModule.h"

// extra command-line flags needed for LTOCodeGenerator
static cl::opt<bool>
DisableOpt("disable-opt", cl::init(false),
  cl::desc("Do not run any optimization passes"));

static cl::opt<bool>
DisableInline("disable-inlining", cl::init(false),
  cl::desc("Do not run the inliner pass"));

static cl::opt<bool>
DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false),
  cl::desc("Do not run the GVN load PRE pass"));

// Holds most recent error string.
// *** Not thread safe ***
static std::string sLastErrorString;

// Holds the initialization state of the LTO module.
// *** Not thread safe ***
static bool initialized = false;

// Holds the command-line option parsing state of the LTO module.
static bool parsedOptions = false;

// Initialize the configured targets if they have not been initialized.
static void lto_initialize() {
  if (!initialized) {
    LLVMInitializeAllTargetInfos();
    LLVMInitializeAllTargets();
    LLVMInitializeAllTargetMCs();
    LLVMInitializeAllAsmParsers();
    LLVMInitializeAllAsmPrinters();
    LLVMInitializeAllDisassemblers();
    initialized = true;
  }
}

DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOCodeGenerator, lto_code_gen_t)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t)

// Convert the subtarget features into a string to pass to LTOCodeGenerator.
static void lto_add_attrs(lto_code_gen_t cg) {
  LTOCodeGenerator *CG = unwrap(cg);
  if (MAttrs.size()) {
    std::string attrs;
    for (unsigned i = 0; i < MAttrs.size(); ++i) {
      if (i > 0)
        attrs.append(",");
      attrs.append(MAttrs[i]);
    }

    CG->setAttr(attrs.c_str());
  }
}

extern const char* lto_get_version() {
  return LTOCodeGenerator::getVersionString();
}

const char* lto_get_error_message() {
  return sLastErrorString.c_str();
}

bool lto_module_is_object_file(const char* path) {
  return LTOModule::isBitcodeFile(path);
}

bool lto_module_is_object_file_for_target(const char* path,
                                          const char* target_triplet_prefix) {
  return LTOModule::isBitcodeFileForTarget(path, target_triplet_prefix);
}

bool lto_module_is_object_file_in_memory(const void* mem, size_t length) {
  return LTOModule::isBitcodeFile(mem, length);
}

bool
lto_module_is_object_file_in_memory_for_target(const void* mem,
                                            size_t length,
                                            const char* target_triplet_prefix) {
  return LTOModule::isBitcodeFileForTarget(mem, length, target_triplet_prefix);
}

lto_module_t lto_module_create(const char* path) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(LTOModule::makeLTOModule(path, Options, sLastErrorString));
}

lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(
      LTOModule::makeLTOModule(fd, path, size, Options, sLastErrorString));
}

lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path,
                                                 size_t file_size,
                                                 size_t map_size,
                                                 off_t offset) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(LTOModule::makeLTOModule(fd, path, map_size, offset, Options,
                                       sLastErrorString));
}

lto_module_t lto_module_create_from_memory(const void* mem, size_t length) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(LTOModule::makeLTOModule(mem, length, Options, sLastErrorString));
}

lto_module_t lto_module_create_from_memory_with_path(const void* mem,
                                                     size_t length,
                                                     const char *path) {
  lto_initialize();
  llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  return wrap(
      LTOModule::makeLTOModule(mem, length, Options, sLastErrorString, path));
}

void lto_module_dispose(lto_module_t mod) { delete unwrap(mod); }

const char* lto_module_get_target_triple(lto_module_t mod) {
  return unwrap(mod)->getTargetTriple();
}

void lto_module_set_target_triple(lto_module_t mod, const char *triple) {
  return unwrap(mod)->setTargetTriple(triple);
}

unsigned int lto_module_get_num_symbols(lto_module_t mod) {
  return unwrap(mod)->getSymbolCount();
}

const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) {
  return unwrap(mod)->getSymbolName(index);
}

lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
                                                      unsigned int index) {
  return unwrap(mod)->getSymbolAttributes(index);
}

unsigned int lto_module_get_num_deplibs(lto_module_t mod) {
  return unwrap(mod)->getDependentLibraryCount();
}

const char* lto_module_get_deplib(lto_module_t mod, unsigned int index) {
  return unwrap(mod)->getDependentLibrary(index);
}

unsigned int lto_module_get_num_linkeropts(lto_module_t mod) {
  return unwrap(mod)->getLinkerOptCount();
}

const char* lto_module_get_linkeropt(lto_module_t mod, unsigned int index) {
  return unwrap(mod)->getLinkerOpt(index);
}

void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
                                        lto_diagnostic_handler_t diag_handler,
                                        void *ctxt) {
  unwrap(cg)->setDiagnosticHandler(diag_handler, ctxt);
}

lto_code_gen_t lto_codegen_create(void) {
  lto_initialize();

  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();

  LTOCodeGenerator *CodeGen = new LTOCodeGenerator();
  if (CodeGen)
    CodeGen->setTargetOptions(Options);
  return wrap(CodeGen);
}

void lto_codegen_dispose(lto_code_gen_t cg) { delete unwrap(cg); }

bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) {
  return !unwrap(cg)->addModule(unwrap(mod), sLastErrorString);
}

bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) {
  unwrap(cg)->setDebugInfo(debug);
  return false;
}

bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) {
  unwrap(cg)->setCodePICModel(model);
  return false;
}

void lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) {
  return unwrap(cg)->setCpu(cpu);
}

void lto_codegen_set_attr(lto_code_gen_t cg, const char *attr) {
  return unwrap(cg)->setAttr(attr);
}

void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) {
  // In here only for backwards compatibility. We use MC now.
}

void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
                                    int nargs) {
  // In here only for backwards compatibility. We use MC now.
}

void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg,
                                          const char *symbol) {
  unwrap(cg)->addMustPreserveSymbol(symbol);
}

bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
  if (!parsedOptions) {
    unwrap(cg)->parseCodeGenDebugOptions();
    lto_add_attrs(cg);
    parsedOptions = true;
  }
  return !unwrap(cg)->writeMergedModules(path, sLastErrorString);
}

const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
  if (!parsedOptions) {
    unwrap(cg)->parseCodeGenDebugOptions();
    lto_add_attrs(cg);
    parsedOptions = true;
  }
  return unwrap(cg)->compile(length, DisableOpt, DisableInline,
                             DisableGVNLoadPRE, sLastErrorString);
}

bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
  if (!parsedOptions) {
    unwrap(cg)->parseCodeGenDebugOptions();
    lto_add_attrs(cg);
    parsedOptions = true;
  }
  return !unwrap(cg)->compile_to_file(name, DisableOpt, DisableInline,
                                      DisableGVNLoadPRE, sLastErrorString);
}

void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
  unwrap(cg)->setCodeGenDebugOptions(opt);
}
<|endoftext|>