QScriptValue REcmaPatternLine::getClassName(QScriptContext *context, QScriptEngine *engine)

    {
        return qScriptValueFromValue(engine, QString("RPatternLine"));
    }

// ***** AUTOGENERATED CODE, DO NOT EDIT *****

        #include "REcmaPatternLine.h"
        #include "RMetaTypes.h"
        #include "../REcmaHelper.h"

        // forwards declarations mapped to includes

        // includes for base ecma wrapper classes
         void REcmaPatternLine::initEcma(QScriptEngine& engine, QScriptValue* proto

    )

    {

    bool protoCreated = false;
    if(proto == NULL){
        proto = new QScriptValue(engine.newVariant(qVariantFromValue(
                (RPatternLine*) 0)));
        protoCreated = true;
    }

    QScriptValue fun;

    REcmaHelper::registerFunction(&engine, proto, toString, "toString");

    REcmaHelper::registerFunction(&engine, proto, copy, "copy");

    REcmaHelper::registerFunction(&engine, proto, destroy, "destroy");

    // get class name
    REcmaHelper::registerFunction(&engine, proto, getClassName, "getClassName");

    // conversion to all base classes (multiple inheritance):
    REcmaHelper::registerFunction(&engine, proto, getBaseClasses, "getBaseClasses");

            REcmaHelper::registerFunction(&engine, proto, getPainterPath, "getPainterPath");

            REcmaHelper::registerFunction(&engine, proto, hasDots, "hasDots");

            REcmaHelper::registerFunction(&engine, proto, getLines, "getLines");

            REcmaHelper::registerFunction(&engine, proto, getLength, "getLength");

            REcmaHelper::registerFunction(&engine, proto, getAngle, "getAngle");

            REcmaHelper::registerFunction(&engine, proto, getOffset, "getOffset");

            REcmaHelper::registerFunction(&engine, proto, getBasePoint, "getBasePoint");

            REcmaHelper::registerFunction(&engine, proto, getDashes, "getDashes");

            REcmaHelper::registerFunction(&engine, proto, scale, "scale");

            REcmaHelper::registerFunction(&engine, proto, rotate, "rotate");

        engine.setDefaultPrototype(
            qMetaTypeId<RPatternLine*>(), *proto);

                engine.setDefaultPrototype(qMetaTypeId<
                RPatternLine
                > (), *proto);

    QScriptValue ctor = engine.newFunction(createEcma, *proto, 2);

    engine.globalObject().setProperty("RPatternLine",
    ctor, QScriptValue::SkipInEnumeration);

    if( protoCreated ){
       delete proto;
    }

    }
     QScriptValue REcmaPatternLine::createEcma(QScriptContext* context, QScriptEngine* engine)

    {
    if (context->thisObject().strictlyEquals(
       engine->globalObject())) {
       return REcmaHelper::throwError(
       QString::fromLatin1("RPatternLine(): Did you forget to construct with 'new'?"),
           context);
    }

    QScriptValue result;

            // constructor without variants:

    if( context->argumentCount() ==
        0
    ){
    // prepare arguments:

    // end of arguments

            RPatternLine
                    cppResult;

            result = engine->newVariant(
            context->thisObject(), qVariantFromValue(cppResult));

    } else

    {
       return REcmaHelper::throwError(
       QString::fromLatin1("RPatternLine(): no matching constructor found."),
           context);
    }

    return result;
    }

    // conversion functions for base classes:

    // returns all base classes (in case of multiple inheritance):
     QScriptValue REcmaPatternLine::getBaseClasses(QScriptContext *context, QScriptEngine *engine)

    {
        QStringList list;

        return qScriptValueFromSequence(engine, list);
    }

     QScriptValue
        REcmaPatternLine::getPainterPath
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getPainterPath", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    RPainterPath cppResult =

               self->getPainterPath();
                // not standard type nor reference
                result = qScriptValueFromValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getPainterPath().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::hasDots
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("hasDots", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    bool cppResult =

               self->hasDots();
                // standard Type
                result = QScriptValue(cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.hasDots().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getLines
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getLines", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    QList < RLine > cppResult =

               self->getLines();
                result = REcmaHelper::listToScriptValue(engine, cppResult);

    } else

    if( context->argumentCount() ==
    1 && (
            context->argument(0).isBool()
        ) /* type: bool */

    ){
    // prepare arguments:

                    // argument isStandardType
                    bool
                    a0 =
                    (bool)

                    context->argument( 0 ).
                    toBool();

    // end of arguments

    // call C++ function:
    QList < RLine > cppResult =

               self->getLines(a0);
                result = REcmaHelper::listToScriptValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getLines().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getLength
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getLength", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    double cppResult =

               self->getLength();
                // standard Type
                result = QScriptValue(cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getLength().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getAngle
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getAngle", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    double cppResult =

               self->getAngle();
                // standard Type
                result = QScriptValue(cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getAngle().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getOffset
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getOffset", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    RVector cppResult =

               self->getOffset();
                // not standard type nor reference
                result = qScriptValueFromValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getOffset().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getBasePoint
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getBasePoint", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    RVector cppResult =

               self->getBasePoint();
                // not standard type nor reference
                result = qScriptValueFromValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getBasePoint().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getDashes
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getDashes", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    QList < double > cppResult =

               self->getDashes();
                result = REcmaHelper::listToScriptValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getDashes().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::scale
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("scale", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    1 && (
            context->argument(0).isNumber()
        ) /* type: double */

    ){
    // prepare arguments:

                    // argument isStandardType
                    double
                    a0 =
                    (double)

                    context->argument( 0 ).
                    toNumber();

    // end of arguments

    // call C++ function:

               self->scale(a0);
    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.scale().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::rotate
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("rotate", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    1 && (
            context->argument(0).isNumber()
        ) /* type: double */

    ){
    // prepare arguments:

                    // argument isStandardType
                    double
                    a0 =
                    (double)

                    context->argument( 0 ).
                    toNumber();

    // end of arguments

    // call C++ function:

               self->rotate(a0);
    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.rotate().",
                   context);
            }
            return result;
        }
         QScriptValue REcmaPatternLine::toString
    (QScriptContext *context, QScriptEngine *engine)

    {

    RPatternLine* self = getSelf("toString", context);

    QString result;

            QDebug d(&result);
            if (self!=NULL) {
                d << *self;
            }
            else {
                d << "NULL";
            }

    return QScriptValue(result);
    }
     QScriptValue REcmaPatternLine::copy
    (QScriptContext *context, QScriptEngine *engine)

    {
        RPatternLine cp = qscriptvalue_cast<RPatternLine>(context->thisObject());
        return qScriptValueFromValue(engine, cp);
    }
     QScriptValue REcmaPatternLine::destroy(QScriptContext *context, QScriptEngine *engine)

    {

        RPatternLine* self = getSelf("RPatternLine", context);
        if (self==NULL) {
            return REcmaHelper::throwError("self is NULL", context);
        }

        delete self;
        context->thisObject().setData(engine->nullValue());
        context->thisObject().prototype().setData(engine->nullValue());
        context->thisObject().setPrototype(engine->nullValue());
        context->thisObject().setScriptClass(NULL);
        return engine->undefinedValue();
    }
    RPatternLine* REcmaPatternLine::getSelf(const QString& fName, QScriptContext* context)

        {
            RPatternLine* self = NULL;

                // self could be a normal object (e.g. from an UI file) or
                // an ECMA shell object (made from an ECMA script):

                self = REcmaHelper::scriptValueTo<RPatternLine >(context->thisObject())

                ;

            if (self == NULL){
                // avoid recursion (toString is used by the backtrace):
                if (fName!="toString") {
                    REcmaHelper::throwError(QString("RPatternLine.%1(): "
                        "This object is not a RPatternLine").arg(fName),
                        context);
                }
                return NULL;
            }

            return self;
        }
        RPatternLine* REcmaPatternLine::getSelfShell(const QString& fName, QScriptContext* context)

        {
          RPatternLine* selfBase = getSelf(fName, context);
                RPatternLine* self = dynamic_cast<RPatternLine*>(selfBase);
            if(self == NULL){
                REcmaHelper::throwError(QString("RPatternLine.%1(): "
                    "This object is not a RPatternLine").arg(fName),
                    context);
            }

            return self;

        }


if (context->thisObject().strictlyEquals(
       engine->globalObject())) {
       return REcmaHelper::throwError(
       QString::fromLatin1("RPatternLine(): Did you forget to construct with 'new'?"),
           context);
    }

// ***** AUTOGENERATED CODE, DO NOT EDIT *****

        #include "REcmaPatternLine.h"
        #include "RMetaTypes.h"
        #include "../REcmaHelper.h"

        // forwards declarations mapped to includes

        // includes for base ecma wrapper classes
         void REcmaPatternLine::initEcma(QScriptEngine& engine, QScriptValue* proto

    )

    {

    bool protoCreated = false;
    if(proto == NULL){
        proto = new QScriptValue(engine.newVariant(qVariantFromValue(
                (RPatternLine*) 0)));
        protoCreated = true;
    }

    QScriptValue fun;

    REcmaHelper::registerFunction(&engine, proto, toString, "toString");

    REcmaHelper::registerFunction(&engine, proto, copy, "copy");

    REcmaHelper::registerFunction(&engine, proto, destroy, "destroy");

    // get class name
    REcmaHelper::registerFunction(&engine, proto, getClassName, "getClassName");

    // conversion to all base classes (multiple inheritance):
    REcmaHelper::registerFunction(&engine, proto, getBaseClasses, "getBaseClasses");

            REcmaHelper::registerFunction(&engine, proto, getPainterPath, "getPainterPath");

            REcmaHelper::registerFunction(&engine, proto, hasDots, "hasDots");

            REcmaHelper::registerFunction(&engine, proto, getLines, "getLines");

            REcmaHelper::registerFunction(&engine, proto, getLength, "getLength");

            REcmaHelper::registerFunction(&engine, proto, getAngle, "getAngle");

            REcmaHelper::registerFunction(&engine, proto, getOffset, "getOffset");

            REcmaHelper::registerFunction(&engine, proto, getBasePoint, "getBasePoint");

            REcmaHelper::registerFunction(&engine, proto, getDashes, "getDashes");

            REcmaHelper::registerFunction(&engine, proto, scale, "scale");

            REcmaHelper::registerFunction(&engine, proto, rotate, "rotate");

        engine.setDefaultPrototype(
            qMetaTypeId<RPatternLine*>(), *proto);

                engine.setDefaultPrototype(qMetaTypeId<
                RPatternLine
                > (), *proto);

    QScriptValue ctor = engine.newFunction(createEcma, *proto, 2);

    engine.globalObject().setProperty("RPatternLine",
    ctor, QScriptValue::SkipInEnumeration);

    if( protoCreated ){
       delete proto;
    }

    }
     QScriptValue REcmaPatternLine::createEcma(QScriptContext* context, QScriptEngine* engine)

    {

    QScriptValue result;

            // constructor without variants:

    if( context->argumentCount() ==
        0
    ){
    // prepare arguments:

    // end of arguments

            RPatternLine
                    cppResult;

            result = engine->newVariant(
            context->thisObject(), qVariantFromValue(cppResult));

    } else

    {
       return REcmaHelper::throwError(
       QString::fromLatin1("RPatternLine(): no matching constructor found."),
           context);
    }

    return result;
    }

    // conversion functions for base classes:

     QScriptValue REcmaPatternLine::getClassName(QScriptContext *context, QScriptEngine *engine)

    {
        return qScriptValueFromValue(engine, QString("RPatternLine"));
    }

    // returns all base classes (in case of multiple inheritance):
     QScriptValue REcmaPatternLine::getBaseClasses(QScriptContext *context, QScriptEngine *engine)

    {
        QStringList list;

        return qScriptValueFromSequence(engine, list);
    }

     QScriptValue
        REcmaPatternLine::getPainterPath
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getPainterPath", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    RPainterPath cppResult =

               self->getPainterPath();
                // not standard type nor reference
                result = qScriptValueFromValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getPainterPath().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::hasDots
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("hasDots", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    bool cppResult =

               self->hasDots();
                // standard Type
                result = QScriptValue(cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.hasDots().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getLines
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getLines", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    QList < RLine > cppResult =

               self->getLines();
                result = REcmaHelper::listToScriptValue(engine, cppResult);

    } else

    if( context->argumentCount() ==
    1 && (
            context->argument(0).isBool()
        ) /* type: bool */

    ){
    // prepare arguments:

                    // argument isStandardType
                    bool
                    a0 =
                    (bool)

                    context->argument( 0 ).
                    toBool();

    // end of arguments

    // call C++ function:
    QList < RLine > cppResult =

               self->getLines(a0);
                result = REcmaHelper::listToScriptValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getLines().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getLength
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getLength", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    double cppResult =

               self->getLength();
                // standard Type
                result = QScriptValue(cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getLength().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getAngle
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getAngle", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    double cppResult =

               self->getAngle();
                // standard Type
                result = QScriptValue(cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getAngle().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getOffset
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getOffset", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    RVector cppResult =

               self->getOffset();
                // not standard type nor reference
                result = qScriptValueFromValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getOffset().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getBasePoint
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getBasePoint", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    RVector cppResult =

               self->getBasePoint();
                // not standard type nor reference
                result = qScriptValueFromValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getBasePoint().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::getDashes
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("getDashes", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    0
    ){
    // prepare arguments:

    // end of arguments

    // call C++ function:
    QList < double > cppResult =

               self->getDashes();
                result = REcmaHelper::listToScriptValue(engine, cppResult);

    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.getDashes().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::scale
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("scale", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    1 && (
            context->argument(0).isNumber()
        ) /* type: double */

    ){
    // prepare arguments:

                    // argument isStandardType
                    double
                    a0 =
                    (double)

                    context->argument( 0 ).
                    toNumber();

    // end of arguments

    // call C++ function:

               self->scale(a0);
    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.scale().",
                   context);
            }
            return result;
        }
         QScriptValue
        REcmaPatternLine::rotate
        (QScriptContext* context, QScriptEngine* engine)

        {

            QScriptValue result = engine->undefinedValue();

                    // public function: can be called from ECMA wrapper of ECMA shell:
                    RPatternLine* self =
                        getSelf("rotate", context);

                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }

    if( context->argumentCount() ==
    1 && (
            context->argument(0).isNumber()
        ) /* type: double */

    ){
    // prepare arguments:

                    // argument isStandardType
                    double
                    a0 =
                    (double)

                    context->argument( 0 ).
                    toNumber();

    // end of arguments

    // call C++ function:

               self->rotate(a0);
    } else

            {
               return REcmaHelper::throwError("Wrong number/types of arguments for RPatternLine.rotate().",
                   context);
            }
            return result;
        }
         QScriptValue REcmaPatternLine::toString
    (QScriptContext *context, QScriptEngine *engine)

    {

    RPatternLine* self = getSelf("toString", context);

    QString result;

            QDebug d(&result);
            if (self!=NULL) {
                d << *self;
            }
            else {
                d << "NULL";
            }

    return QScriptValue(result);
    }
     QScriptValue REcmaPatternLine::copy
    (QScriptContext *context, QScriptEngine *engine)

    {
        RPatternLine cp = qscriptvalue_cast<RPatternLine>(context->thisObject());
        return qScriptValueFromValue(engine, cp);
    }
     QScriptValue REcmaPatternLine::destroy(QScriptContext *context, QScriptEngine *engine)

    {

        RPatternLine* self = getSelf("RPatternLine", context);
        if (self==NULL) {
            return REcmaHelper::throwError("self is NULL", context);
        }

        delete self;
        context->thisObject().setData(engine->nullValue());
        context->thisObject().prototype().setData(engine->nullValue());
        context->thisObject().setPrototype(engine->nullValue());
        context->thisObject().setScriptClass(NULL);
        return engine->undefinedValue();
    }
    RPatternLine* REcmaPatternLine::getSelf(const QString& fName, QScriptContext* context)

        {
            RPatternLine* self = NULL;

                // self could be a normal object (e.g. from an UI file) or
                // an ECMA shell object (made from an ECMA script):

                self = REcmaHelper::scriptValueTo<RPatternLine >(context->thisObject())

                ;

            if (self == NULL){
                // avoid recursion (toString is used by the backtrace):
                if (fName!="toString") {
                    REcmaHelper::throwError(QString("RPatternLine.%1(): "
                        "This object is not a RPatternLine").arg(fName),
                        context);
                }
                return NULL;
            }

            return self;
        }
        RPatternLine* REcmaPatternLine::getSelfShell(const QString& fName, QScriptContext* context)

        {
          RPatternLine* selfBase = getSelf(fName, context);
                RPatternLine* self = dynamic_cast<RPatternLine*>(selfBase);
            if(self == NULL){
                REcmaHelper::throwError(QString("RPatternLine.%1(): "
                    "This object is not a RPatternLine").arg(fName),
                    context);
            }

            return self;

        }


/*
 *
 *
 */

#include "config.h"
#include <limits.h>
#if defined(TARGET_ANDROID)
#include <unistd.h>
#else
#include <sys/syscall.h>
#endif
#include <sys/resource.h>
#include <string.h>
#ifdef TARGET_FREEBSD
#include <sys/param.h>
#if __FreeBSD_version < 900031
#include <sys/thr.h>
#else
#include <pthread_np.h>
#endif
#endif

#include <signal.h>

void CThread::SpawnThread(unsigned stacksize)
{
  pthread_attr_t attr;
  pthread_attr_init(&attr);
#if !defined(TARGET_ANDROID) // http://example.com
  if (stacksize > PTHREAD_STACK_MIN)
    pthread_attr_setstacksize(&attr, stacksize);
#endif
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  if (pthread_create(&m_ThreadId, &attr, (void*(*)(void*))staticThread, this) != 0)
  {
    if (logger) logger->Log(LOGNOTICE, "%s - fatal error creating thread",__FUNCTION__);
  }
  pthread_attr_destroy(&attr);
}

void CThread::TermHandler() { }

void CThread::SetThreadInfo()
{
#ifdef TARGET_FREEBSD
#if __FreeBSD_version < 900031
  long lwpid;
  thr_self(&lwpid);
  m_ThreadOpaque.LwpId = lwpid;
#else
  m_ThreadOpaque.LwpId = pthread_getthreadid_np();
#endif
#elif defined(TARGET_ANDROID)
  m_ThreadOpaque.LwpId = gettid();
#else
  m_ThreadOpaque.LwpId = syscall(SYS_gettid);
#endif

#if defined(HAVE_PTHREAD_SETNAME_NP)
#ifdef TARGET_DARWIN
#if(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200)
  pthread_setname_np(m_ThreadName.c_str());
#endif
#else
  pthread_setname_np(m_ThreadId, m_ThreadName.c_str());
#endif
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
  pthread_set_name_np(m_ThreadId, m_ThreadName.c_str());
#endif

#ifdef RLIMIT_NICE
  // get user max prio
  struct rlimit limit;
  int userMaxPrio;
  if (getrlimit(RLIMIT_NICE, &limit) == 0)
  {
    userMaxPrio = limit.rlim_cur - 20;
    if (userMaxPrio < 0)
      userMaxPrio = 0;
  }
  else
    userMaxPrio = 0;

  if (geteuid() == 0)
    userMaxPrio = GetMaxPriority();

  // if the user does not have an entry in limits.conf the following
  // call will fail
  if (userMaxPrio > 0)
  {
    // start thread with nice level of appication
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, appNice) != 0)
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif
}

ThreadIdentifier CThread::GetCurrentThreadId()
{
  return pthread_self();
}

bool CThread::IsCurrentThread(const ThreadIdentifier tid)
{
  return pthread_equal(pthread_self(), tid);
}

int CThread::GetMinPriority(void)
{
  // one level lower than application
  return -1;
}

int CThread::GetMaxPriority(void)
{
  // one level higher than application
  return 1;
}

int CThread::GetNormalPriority(void)
{
  // same level as application
  return 0;
}

bool CThread::SetPriority(const int iPriority)
{
  bool bReturn = false;

  // wait until thread is running, it needs to get its lwp id
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  // get min prio for SCHED_RR
  int minRR = GetMaxPriority() + 1;

  if (!m_ThreadId)
    bReturn = false;
  else if (iPriority >= minRR)
    bReturn = SetPrioritySched_RR(iPriority);
#ifdef RLIMIT_NICE
  else
  {
    // get user max prio
    struct rlimit limit;
    int userMaxPrio;
    if (getrlimit(RLIMIT_NICE, &limit) == 0)
    {
      userMaxPrio = limit.rlim_cur - 20;
      // is a user has no entry in limits.conf rlim_cur is zero
      if (userMaxPrio < 0)
        userMaxPrio = 0;
    }
    else
      userMaxPrio = 0;

    if (geteuid() == 0)
      userMaxPrio = GetMaxPriority();

    // keep priority in bounds
    int prio = iPriority;
    if (prio >= GetMaxPriority())
      prio = std::min(GetMaxPriority(), userMaxPrio);
    if (prio < GetMinPriority())
      prio = GetMinPriority();

    // nice level of application
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (prio)
      prio = prio > 0 ? appNice-1 : appNice+1;

    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, prio) == 0)
      bReturn = true;
    else
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif

  return bReturn;
}

int CThread::GetPriority()
{
  int iReturn;

  // lwp id is valid after start signel has fired
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  int appNice = getpriority(PRIO_PROCESS, getpid());
  int prio = getpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId);
  iReturn = appNice - prio;

  return iReturn;
}

bool CThread::WaitForThreadExit(unsigned int milliseconds)
{
  bool bReturn = m_TermEvent.WaitMSec(milliseconds);

  return bReturn;
}

{
  CSingleLock lock(m_CriticalSection);

  if (!m_ThreadId)
  return 0;

  int64_t time = 0;
#ifdef TARGET_DARWIN
  thread_basic_info threadInfo;
  mach_msg_type_number_t threadInfoCount = THREAD_BASIC_INFO_COUNT;

  kern_return_t ret = thread_info(pthread_mach_thread_np(m_ThreadId),
    THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &threadInfoCount);

  if (ret == KERN_SUCCESS)
  {
    // User time.
    time = ((int64_t)threadInfo.user_time.seconds * 10000000L) + threadInfo.user_time.microseconds*10L;

    // System time.
    time += (((int64_t)threadInfo.system_time.seconds * 10000000L) + threadInfo.system_time.microseconds*10L);
  }

#else
  clockid_t clock;
  if (pthread_getcpuclockid(m_ThreadId, &clock) == 0)
  {
    struct timespec tp;
    clock_gettime(clock, &tp);
    time = (int64_t)tp.tv_sec * 10000000 + tp.tv_nsec/100;
  }
#endif

  return time;
}

float CThread::GetRelativeUsage()
{
  unsigned int iTime = XbmcThreads::SystemClockMillis();
  iTime *= 10000; // convert into 100ns tics

  // only update every 1 second
  if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;

  int64_t iUsage = GetAbsoluteUsage();

  if (m_iLastUsage > 0 && m_iLastTime > 0)
    m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );

  m_iLastUsage = iUsage;
  m_iLastTime = iTime;

  return m_fLastUsage;
}

void term_handler (int signum)
{
  XbmcCommons::ILogger* logger = CThread::GetLogger();
  if (logger)
    logger->Log(LOGERROR,"thread 0x%lx (%lu) got signal %d. calling OnException and terminating thread abnormally.", (long unsigned int)pthread_self(), (long unsigned int)pthread_self(), signum);
  CThread* curThread = CThread::GetCurrentThread();
  if (curThread)
  {
    curThread->StopThread(false);
    curThread->OnException();
    if( curThread->IsAutoDelete() )
      delete curThread;
  }
  pthread_exit(NULL);
}

void CThread::SetSignalHandlers()
{
  struct sigaction action;
  action.sa_handler = term_handler;
  sigemptyset (&action.sa_mask);
  action.sa_flags = 0;
}


{
  bool bReturn = m_TermEvent.WaitMSec(milliseconds);

  return bReturn;
}

/*
 *
 *
 */

#include "config.h"
#include <limits.h>
#if defined(TARGET_ANDROID)
#include <unistd.h>
#else
#include <sys/syscall.h>
#endif
#include <sys/resource.h>
#include <string.h>
#ifdef TARGET_FREEBSD
#include <sys/param.h>
#if __FreeBSD_version < 900031
#include <sys/thr.h>
#else
#include <pthread_np.h>
#endif
#endif

#include <signal.h>

void CThread::SpawnThread(unsigned stacksize)
{
  pthread_attr_t attr;
  pthread_attr_init(&attr);
#if !defined(TARGET_ANDROID) // http://example.com
  if (stacksize > PTHREAD_STACK_MIN)
    pthread_attr_setstacksize(&attr, stacksize);
#endif
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  if (pthread_create(&m_ThreadId, &attr, (void*(*)(void*))staticThread, this) != 0)
  {
    if (logger) logger->Log(LOGNOTICE, "%s - fatal error creating thread",__FUNCTION__);
  }
  pthread_attr_destroy(&attr);
}

void CThread::TermHandler() { }

void CThread::SetThreadInfo()
{
#ifdef TARGET_FREEBSD
#if __FreeBSD_version < 900031
  long lwpid;
  thr_self(&lwpid);
  m_ThreadOpaque.LwpId = lwpid;
#else
  m_ThreadOpaque.LwpId = pthread_getthreadid_np();
#endif
#elif defined(TARGET_ANDROID)
  m_ThreadOpaque.LwpId = gettid();
#else
  m_ThreadOpaque.LwpId = syscall(SYS_gettid);
#endif

#if defined(HAVE_PTHREAD_SETNAME_NP)
#ifdef TARGET_DARWIN
#if(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200)
  pthread_setname_np(m_ThreadName.c_str());
#endif
#else
  pthread_setname_np(m_ThreadId, m_ThreadName.c_str());
#endif
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
  pthread_set_name_np(m_ThreadId, m_ThreadName.c_str());
#endif

#ifdef RLIMIT_NICE
  // get user max prio
  struct rlimit limit;
  int userMaxPrio;
  if (getrlimit(RLIMIT_NICE, &limit) == 0)
  {
    userMaxPrio = limit.rlim_cur - 20;
    if (userMaxPrio < 0)
      userMaxPrio = 0;
  }
  else
    userMaxPrio = 0;

  if (geteuid() == 0)
    userMaxPrio = GetMaxPriority();

  // if the user does not have an entry in limits.conf the following
  // call will fail
  if (userMaxPrio > 0)
  {
    // start thread with nice level of appication
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, appNice) != 0)
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif
}

ThreadIdentifier CThread::GetCurrentThreadId()
{
  return pthread_self();
}

bool CThread::IsCurrentThread(const ThreadIdentifier tid)
{
  return pthread_equal(pthread_self(), tid);
}

int CThread::GetMinPriority(void)
{
  // one level lower than application
  return -1;
}

int CThread::GetMaxPriority(void)
{
  // one level higher than application
  return 1;
}

int CThread::GetNormalPriority(void)
{
  // same level as application
  return 0;
}

bool CThread::SetPriority(const int iPriority)
{
  bool bReturn = false;

  // wait until thread is running, it needs to get its lwp id
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  // get min prio for SCHED_RR
  int minRR = GetMaxPriority() + 1;

  if (!m_ThreadId)
    bReturn = false;
  else if (iPriority >= minRR)
    bReturn = SetPrioritySched_RR(iPriority);
#ifdef RLIMIT_NICE
  else
  {
    // get user max prio
    struct rlimit limit;
    int userMaxPrio;
    if (getrlimit(RLIMIT_NICE, &limit) == 0)
    {
      userMaxPrio = limit.rlim_cur - 20;
      // is a user has no entry in limits.conf rlim_cur is zero
      if (userMaxPrio < 0)
        userMaxPrio = 0;
    }
    else
      userMaxPrio = 0;

    if (geteuid() == 0)
      userMaxPrio = GetMaxPriority();

    // keep priority in bounds
    int prio = iPriority;
    if (prio >= GetMaxPriority())
      prio = std::min(GetMaxPriority(), userMaxPrio);
    if (prio < GetMinPriority())
      prio = GetMinPriority();

    // nice level of application
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (prio)
      prio = prio > 0 ? appNice-1 : appNice+1;

    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, prio) == 0)
      bReturn = true;
    else
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif

  return bReturn;
}

int CThread::GetPriority()
{
  int iReturn;

  // lwp id is valid after start signel has fired
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  int appNice = getpriority(PRIO_PROCESS, getpid());
  int prio = getpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId);
  iReturn = appNice - prio;

  return iReturn;
}

bool CThread::WaitForThreadExit(unsigned int milliseconds)

int64_t CThread::GetAbsoluteUsage()
{
  CSingleLock lock(m_CriticalSection);

  if (!m_ThreadId)
  return 0;

  int64_t time = 0;
#ifdef TARGET_DARWIN
  thread_basic_info threadInfo;
  mach_msg_type_number_t threadInfoCount = THREAD_BASIC_INFO_COUNT;

  kern_return_t ret = thread_info(pthread_mach_thread_np(m_ThreadId),
    THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &threadInfoCount);

  if (ret == KERN_SUCCESS)
  {
    // User time.
    time = ((int64_t)threadInfo.user_time.seconds * 10000000L) + threadInfo.user_time.microseconds*10L;

    // System time.
    time += (((int64_t)threadInfo.system_time.seconds * 10000000L) + threadInfo.system_time.microseconds*10L);
  }

#else
  clockid_t clock;
  if (pthread_getcpuclockid(m_ThreadId, &clock) == 0)
  {
    struct timespec tp;
    clock_gettime(clock, &tp);
    time = (int64_t)tp.tv_sec * 10000000 + tp.tv_nsec/100;
  }
#endif

  return time;
}

float CThread::GetRelativeUsage()
{
  unsigned int iTime = XbmcThreads::SystemClockMillis();
  iTime *= 10000; // convert into 100ns tics

  // only update every 1 second
  if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;

  int64_t iUsage = GetAbsoluteUsage();

  if (m_iLastUsage > 0 && m_iLastTime > 0)
    m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );

  m_iLastUsage = iUsage;
  m_iLastTime = iTime;

  return m_fLastUsage;
}

void term_handler (int signum)
{
  XbmcCommons::ILogger* logger = CThread::GetLogger();
  if (logger)
    logger->Log(LOGERROR,"thread 0x%lx (%lu) got signal %d. calling OnException and terminating thread abnormally.", (long unsigned int)pthread_self(), (long unsigned int)pthread_self(), signum);
  CThread* curThread = CThread::GetCurrentThread();
  if (curThread)
  {
    curThread->StopThread(false);
    curThread->OnException();
    if( curThread->IsAutoDelete() )
      delete curThread;
  }
  pthread_exit(NULL);
}

void CThread::SetSignalHandlers()
{
  struct sigaction action;
  action.sa_handler = term_handler;
  sigemptyset (&action.sa_mask);
  action.sa_flags = 0;
}


{
  unsigned int iTime = XbmcThreads::SystemClockMillis();
  iTime *= 10000; // convert into 100ns tics

/*
 *
 *
 */

#include "config.h"
#include <limits.h>
#if defined(TARGET_ANDROID)
#include <unistd.h>
#else
#include <sys/syscall.h>
#endif
#include <sys/resource.h>
#include <string.h>
#ifdef TARGET_FREEBSD
#include <sys/param.h>
#if __FreeBSD_version < 900031
#include <sys/thr.h>
#else
#include <pthread_np.h>
#endif
#endif

#include <signal.h>

void CThread::SpawnThread(unsigned stacksize)
{
  pthread_attr_t attr;
  pthread_attr_init(&attr);
#if !defined(TARGET_ANDROID) // http://example.com
  if (stacksize > PTHREAD_STACK_MIN)
    pthread_attr_setstacksize(&attr, stacksize);
#endif
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  if (pthread_create(&m_ThreadId, &attr, (void*(*)(void*))staticThread, this) != 0)
  {
    if (logger) logger->Log(LOGNOTICE, "%s - fatal error creating thread",__FUNCTION__);
  }
  pthread_attr_destroy(&attr);
}

void CThread::TermHandler() { }

void CThread::SetThreadInfo()
{
#ifdef TARGET_FREEBSD
#if __FreeBSD_version < 900031
  long lwpid;
  thr_self(&lwpid);
  m_ThreadOpaque.LwpId = lwpid;
#else
  m_ThreadOpaque.LwpId = pthread_getthreadid_np();
#endif
#elif defined(TARGET_ANDROID)
  m_ThreadOpaque.LwpId = gettid();
#else
  m_ThreadOpaque.LwpId = syscall(SYS_gettid);
#endif

#if defined(HAVE_PTHREAD_SETNAME_NP)
#ifdef TARGET_DARWIN
#if(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200)
  pthread_setname_np(m_ThreadName.c_str());
#endif
#else
  pthread_setname_np(m_ThreadId, m_ThreadName.c_str());
#endif
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
  pthread_set_name_np(m_ThreadId, m_ThreadName.c_str());
#endif

#ifdef RLIMIT_NICE
  // get user max prio
  struct rlimit limit;
  int userMaxPrio;
  if (getrlimit(RLIMIT_NICE, &limit) == 0)
  {
    userMaxPrio = limit.rlim_cur - 20;
    if (userMaxPrio < 0)
      userMaxPrio = 0;
  }
  else
    userMaxPrio = 0;

  if (geteuid() == 0)
    userMaxPrio = GetMaxPriority();

  // if the user does not have an entry in limits.conf the following
  // call will fail
  if (userMaxPrio > 0)
  {
    // start thread with nice level of appication
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, appNice) != 0)
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif
}

ThreadIdentifier CThread::GetCurrentThreadId()
{
  return pthread_self();
}

bool CThread::IsCurrentThread(const ThreadIdentifier tid)
{
  return pthread_equal(pthread_self(), tid);
}

int CThread::GetMinPriority(void)
{
  // one level lower than application
  return -1;
}

int CThread::GetMaxPriority(void)
{
  // one level higher than application
  return 1;
}

int CThread::GetNormalPriority(void)
{
  // same level as application
  return 0;
}

bool CThread::SetPriority(const int iPriority)
{
  bool bReturn = false;

  // wait until thread is running, it needs to get its lwp id
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  // get min prio for SCHED_RR
  int minRR = GetMaxPriority() + 1;

  if (!m_ThreadId)
    bReturn = false;
  else if (iPriority >= minRR)
    bReturn = SetPrioritySched_RR(iPriority);
#ifdef RLIMIT_NICE
  else
  {
    // get user max prio
    struct rlimit limit;
    int userMaxPrio;
    if (getrlimit(RLIMIT_NICE, &limit) == 0)
    {
      userMaxPrio = limit.rlim_cur - 20;
      // is a user has no entry in limits.conf rlim_cur is zero
      if (userMaxPrio < 0)
        userMaxPrio = 0;
    }
    else
      userMaxPrio = 0;

    if (geteuid() == 0)
      userMaxPrio = GetMaxPriority();

    // keep priority in bounds
    int prio = iPriority;
    if (prio >= GetMaxPriority())
      prio = std::min(GetMaxPriority(), userMaxPrio);
    if (prio < GetMinPriority())
      prio = GetMinPriority();

    // nice level of application
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (prio)
      prio = prio > 0 ? appNice-1 : appNice+1;

    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, prio) == 0)
      bReturn = true;
    else
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif

  return bReturn;
}

int CThread::GetPriority()
{
  int iReturn;

  // lwp id is valid after start signel has fired
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  int appNice = getpriority(PRIO_PROCESS, getpid());
  int prio = getpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId);
  iReturn = appNice - prio;

  return iReturn;
}

bool CThread::WaitForThreadExit(unsigned int milliseconds)
{
  bool bReturn = m_TermEvent.WaitMSec(milliseconds);

  return bReturn;
}

int64_t CThread::GetAbsoluteUsage()
{
  CSingleLock lock(m_CriticalSection);

  if (!m_ThreadId)
  return 0;

  int64_t time = 0;
#ifdef TARGET_DARWIN
  thread_basic_info threadInfo;
  mach_msg_type_number_t threadInfoCount = THREAD_BASIC_INFO_COUNT;

  kern_return_t ret = thread_info(pthread_mach_thread_np(m_ThreadId),
    THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &threadInfoCount);

  if (ret == KERN_SUCCESS)
  {
    // User time.
    time = ((int64_t)threadInfo.user_time.seconds * 10000000L) + threadInfo.user_time.microseconds*10L;

    // System time.
    time += (((int64_t)threadInfo.system_time.seconds * 10000000L) + threadInfo.system_time.microseconds*10L);
  }

#else
  clockid_t clock;
  if (pthread_getcpuclockid(m_ThreadId, &clock) == 0)
  {
    struct timespec tp;
    clock_gettime(clock, &tp);
    time = (int64_t)tp.tv_sec * 10000000 + tp.tv_nsec/100;
  }
#endif

  return time;
}

float CThread::GetRelativeUsage()

  // only update every 1 second
  if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;

  int64_t iUsage = GetAbsoluteUsage();

  if (m_iLastUsage > 0 && m_iLastTime > 0)
    m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );

  m_iLastUsage = iUsage;
  m_iLastTime = iTime;

  return m_fLastUsage;
}

void term_handler (int signum)
{
  XbmcCommons::ILogger* logger = CThread::GetLogger();
  if (logger)
    logger->Log(LOGERROR,"thread 0x%lx (%lu) got signal %d. calling OnException and terminating thread abnormally.", (long unsigned int)pthread_self(), (long unsigned int)pthread_self(), signum);
  CThread* curThread = CThread::GetCurrentThread();
  if (curThread)
  {
    curThread->StopThread(false);
    curThread->OnException();
    if( curThread->IsAutoDelete() )
      delete curThread;
  }
  pthread_exit(NULL);
}

void CThread::SetSignalHandlers()
{
  struct sigaction action;
  action.sa_handler = term_handler;
  sigemptyset (&action.sa_mask);
  action.sa_flags = 0;
}


// only update every 1 second
  if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;

  int64_t iUsage = GetAbsoluteUsage();

  if (m_iLastUsage > 0 && m_iLastTime > 0)
    m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );

/*
 *
 *
 */

#include "config.h"
#include <limits.h>
#if defined(TARGET_ANDROID)
#include <unistd.h>
#else
#include <sys/syscall.h>
#endif
#include <sys/resource.h>
#include <string.h>
#ifdef TARGET_FREEBSD
#include <sys/param.h>
#if __FreeBSD_version < 900031
#include <sys/thr.h>
#else
#include <pthread_np.h>
#endif
#endif

#include <signal.h>

void CThread::SpawnThread(unsigned stacksize)
{
  pthread_attr_t attr;
  pthread_attr_init(&attr);
#if !defined(TARGET_ANDROID) // http://example.com
  if (stacksize > PTHREAD_STACK_MIN)
    pthread_attr_setstacksize(&attr, stacksize);
#endif
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  if (pthread_create(&m_ThreadId, &attr, (void*(*)(void*))staticThread, this) != 0)
  {
    if (logger) logger->Log(LOGNOTICE, "%s - fatal error creating thread",__FUNCTION__);
  }
  pthread_attr_destroy(&attr);
}

void CThread::TermHandler() { }

void CThread::SetThreadInfo()
{
#ifdef TARGET_FREEBSD
#if __FreeBSD_version < 900031
  long lwpid;
  thr_self(&lwpid);
  m_ThreadOpaque.LwpId = lwpid;
#else
  m_ThreadOpaque.LwpId = pthread_getthreadid_np();
#endif
#elif defined(TARGET_ANDROID)
  m_ThreadOpaque.LwpId = gettid();
#else
  m_ThreadOpaque.LwpId = syscall(SYS_gettid);
#endif

#if defined(HAVE_PTHREAD_SETNAME_NP)
#ifdef TARGET_DARWIN
#if(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200)
  pthread_setname_np(m_ThreadName.c_str());
#endif
#else
  pthread_setname_np(m_ThreadId, m_ThreadName.c_str());
#endif
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
  pthread_set_name_np(m_ThreadId, m_ThreadName.c_str());
#endif

#ifdef RLIMIT_NICE
  // get user max prio
  struct rlimit limit;
  int userMaxPrio;
  if (getrlimit(RLIMIT_NICE, &limit) == 0)
  {
    userMaxPrio = limit.rlim_cur - 20;
    if (userMaxPrio < 0)
      userMaxPrio = 0;
  }
  else
    userMaxPrio = 0;

  if (geteuid() == 0)
    userMaxPrio = GetMaxPriority();

  // if the user does not have an entry in limits.conf the following
  // call will fail
  if (userMaxPrio > 0)
  {
    // start thread with nice level of appication
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, appNice) != 0)
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif
}

ThreadIdentifier CThread::GetCurrentThreadId()
{
  return pthread_self();
}

bool CThread::IsCurrentThread(const ThreadIdentifier tid)
{
  return pthread_equal(pthread_self(), tid);
}

int CThread::GetMinPriority(void)
{
  // one level lower than application
  return -1;
}

int CThread::GetMaxPriority(void)
{
  // one level higher than application
  return 1;
}

int CThread::GetNormalPriority(void)
{
  // same level as application
  return 0;
}

bool CThread::SetPriority(const int iPriority)
{
  bool bReturn = false;

  // wait until thread is running, it needs to get its lwp id
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  // get min prio for SCHED_RR
  int minRR = GetMaxPriority() + 1;

  if (!m_ThreadId)
    bReturn = false;
  else if (iPriority >= minRR)
    bReturn = SetPrioritySched_RR(iPriority);
#ifdef RLIMIT_NICE
  else
  {
    // get user max prio
    struct rlimit limit;
    int userMaxPrio;
    if (getrlimit(RLIMIT_NICE, &limit) == 0)
    {
      userMaxPrio = limit.rlim_cur - 20;
      // is a user has no entry in limits.conf rlim_cur is zero
      if (userMaxPrio < 0)
        userMaxPrio = 0;
    }
    else
      userMaxPrio = 0;

    if (geteuid() == 0)
      userMaxPrio = GetMaxPriority();

    // keep priority in bounds
    int prio = iPriority;
    if (prio >= GetMaxPriority())
      prio = std::min(GetMaxPriority(), userMaxPrio);
    if (prio < GetMinPriority())
      prio = GetMinPriority();

    // nice level of application
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (prio)
      prio = prio > 0 ? appNice-1 : appNice+1;

    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, prio) == 0)
      bReturn = true;
    else
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif

  return bReturn;
}

int CThread::GetPriority()
{
  int iReturn;

  // lwp id is valid after start signel has fired
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  int appNice = getpriority(PRIO_PROCESS, getpid());
  int prio = getpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId);
  iReturn = appNice - prio;

  return iReturn;
}

bool CThread::WaitForThreadExit(unsigned int milliseconds)
{
  bool bReturn = m_TermEvent.WaitMSec(milliseconds);

  return bReturn;
}

int64_t CThread::GetAbsoluteUsage()
{
  CSingleLock lock(m_CriticalSection);

  if (!m_ThreadId)
  return 0;

  int64_t time = 0;
#ifdef TARGET_DARWIN
  thread_basic_info threadInfo;
  mach_msg_type_number_t threadInfoCount = THREAD_BASIC_INFO_COUNT;

  kern_return_t ret = thread_info(pthread_mach_thread_np(m_ThreadId),
    THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &threadInfoCount);

  if (ret == KERN_SUCCESS)
  {
    // User time.
    time = ((int64_t)threadInfo.user_time.seconds * 10000000L) + threadInfo.user_time.microseconds*10L;

    // System time.
    time += (((int64_t)threadInfo.system_time.seconds * 10000000L) + threadInfo.system_time.microseconds*10L);
  }

#else
  clockid_t clock;
  if (pthread_getcpuclockid(m_ThreadId, &clock) == 0)
  {
    struct timespec tp;
    clock_gettime(clock, &tp);
    time = (int64_t)tp.tv_sec * 10000000 + tp.tv_nsec/100;
  }
#endif

  return time;
}

float CThread::GetRelativeUsage()
{
  unsigned int iTime = XbmcThreads::SystemClockMillis();
  iTime *= 10000; // convert into 100ns tics

  m_iLastUsage = iUsage;
  m_iLastTime = iTime;

  return m_fLastUsage;
}

void term_handler (int signum)
{
  XbmcCommons::ILogger* logger = CThread::GetLogger();
  if (logger)
    logger->Log(LOGERROR,"thread 0x%lx (%lu) got signal %d. calling OnException and terminating thread abnormally.", (long unsigned int)pthread_self(), (long unsigned int)pthread_self(), signum);
  CThread* curThread = CThread::GetCurrentThread();
  if (curThread)
  {
    curThread->StopThread(false);
    curThread->OnException();
    if( curThread->IsAutoDelete() )
      delete curThread;
  }
  pthread_exit(NULL);
}

void CThread::SetSignalHandlers()
{
  struct sigaction action;
  action.sa_handler = term_handler;
  sigemptyset (&action.sa_mask);
  action.sa_flags = 0;
}


m_iLastUsage = iUsage;
  m_iLastTime = iTime;

  return m_fLastUsage;
}

/*
 *
 *
 */

#include "config.h"
#include <limits.h>
#if defined(TARGET_ANDROID)
#include <unistd.h>
#else
#include <sys/syscall.h>
#endif
#include <sys/resource.h>
#include <string.h>
#ifdef TARGET_FREEBSD
#include <sys/param.h>
#if __FreeBSD_version < 900031
#include <sys/thr.h>
#else
#include <pthread_np.h>
#endif
#endif

#include <signal.h>

void CThread::SpawnThread(unsigned stacksize)
{
  pthread_attr_t attr;
  pthread_attr_init(&attr);
#if !defined(TARGET_ANDROID) // http://example.com
  if (stacksize > PTHREAD_STACK_MIN)
    pthread_attr_setstacksize(&attr, stacksize);
#endif
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  if (pthread_create(&m_ThreadId, &attr, (void*(*)(void*))staticThread, this) != 0)
  {
    if (logger) logger->Log(LOGNOTICE, "%s - fatal error creating thread",__FUNCTION__);
  }
  pthread_attr_destroy(&attr);
}

void CThread::TermHandler() { }

void CThread::SetThreadInfo()
{
#ifdef TARGET_FREEBSD
#if __FreeBSD_version < 900031
  long lwpid;
  thr_self(&lwpid);
  m_ThreadOpaque.LwpId = lwpid;
#else
  m_ThreadOpaque.LwpId = pthread_getthreadid_np();
#endif
#elif defined(TARGET_ANDROID)
  m_ThreadOpaque.LwpId = gettid();
#else
  m_ThreadOpaque.LwpId = syscall(SYS_gettid);
#endif

#if defined(HAVE_PTHREAD_SETNAME_NP)
#ifdef TARGET_DARWIN
#if(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200)
  pthread_setname_np(m_ThreadName.c_str());
#endif
#else
  pthread_setname_np(m_ThreadId, m_ThreadName.c_str());
#endif
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
  pthread_set_name_np(m_ThreadId, m_ThreadName.c_str());
#endif

#ifdef RLIMIT_NICE
  // get user max prio
  struct rlimit limit;
  int userMaxPrio;
  if (getrlimit(RLIMIT_NICE, &limit) == 0)
  {
    userMaxPrio = limit.rlim_cur - 20;
    if (userMaxPrio < 0)
      userMaxPrio = 0;
  }
  else
    userMaxPrio = 0;

  if (geteuid() == 0)
    userMaxPrio = GetMaxPriority();

  // if the user does not have an entry in limits.conf the following
  // call will fail
  if (userMaxPrio > 0)
  {
    // start thread with nice level of appication
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, appNice) != 0)
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif
}

ThreadIdentifier CThread::GetCurrentThreadId()
{
  return pthread_self();
}

bool CThread::IsCurrentThread(const ThreadIdentifier tid)
{
  return pthread_equal(pthread_self(), tid);
}

int CThread::GetMinPriority(void)
{
  // one level lower than application
  return -1;
}

int CThread::GetMaxPriority(void)
{
  // one level higher than application
  return 1;
}

int CThread::GetNormalPriority(void)
{
  // same level as application
  return 0;
}

bool CThread::SetPriority(const int iPriority)
{
  bool bReturn = false;

  // wait until thread is running, it needs to get its lwp id
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  // get min prio for SCHED_RR
  int minRR = GetMaxPriority() + 1;

  if (!m_ThreadId)
    bReturn = false;
  else if (iPriority >= minRR)
    bReturn = SetPrioritySched_RR(iPriority);
#ifdef RLIMIT_NICE
  else
  {
    // get user max prio
    struct rlimit limit;
    int userMaxPrio;
    if (getrlimit(RLIMIT_NICE, &limit) == 0)
    {
      userMaxPrio = limit.rlim_cur - 20;
      // is a user has no entry in limits.conf rlim_cur is zero
      if (userMaxPrio < 0)
        userMaxPrio = 0;
    }
    else
      userMaxPrio = 0;

    if (geteuid() == 0)
      userMaxPrio = GetMaxPriority();

    // keep priority in bounds
    int prio = iPriority;
    if (prio >= GetMaxPriority())
      prio = std::min(GetMaxPriority(), userMaxPrio);
    if (prio < GetMinPriority())
      prio = GetMinPriority();

    // nice level of application
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (prio)
      prio = prio > 0 ? appNice-1 : appNice+1;

    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, prio) == 0)
      bReturn = true;
    else
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif

  return bReturn;
}

int CThread::GetPriority()
{
  int iReturn;

  // lwp id is valid after start signel has fired
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  int appNice = getpriority(PRIO_PROCESS, getpid());
  int prio = getpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId);
  iReturn = appNice - prio;

  return iReturn;
}

bool CThread::WaitForThreadExit(unsigned int milliseconds)
{
  bool bReturn = m_TermEvent.WaitMSec(milliseconds);

  return bReturn;
}

int64_t CThread::GetAbsoluteUsage()
{
  CSingleLock lock(m_CriticalSection);

  if (!m_ThreadId)
  return 0;

  int64_t time = 0;
#ifdef TARGET_DARWIN
  thread_basic_info threadInfo;
  mach_msg_type_number_t threadInfoCount = THREAD_BASIC_INFO_COUNT;

  kern_return_t ret = thread_info(pthread_mach_thread_np(m_ThreadId),
    THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &threadInfoCount);

  if (ret == KERN_SUCCESS)
  {
    // User time.
    time = ((int64_t)threadInfo.user_time.seconds * 10000000L) + threadInfo.user_time.microseconds*10L;

    // System time.
    time += (((int64_t)threadInfo.system_time.seconds * 10000000L) + threadInfo.system_time.microseconds*10L);
  }

#else
  clockid_t clock;
  if (pthread_getcpuclockid(m_ThreadId, &clock) == 0)
  {
    struct timespec tp;
    clock_gettime(clock, &tp);
    time = (int64_t)tp.tv_sec * 10000000 + tp.tv_nsec/100;
  }
#endif

  return time;
}

float CThread::GetRelativeUsage()
{
  unsigned int iTime = XbmcThreads::SystemClockMillis();
  iTime *= 10000; // convert into 100ns tics

  // only update every 1 second
  if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;

  int64_t iUsage = GetAbsoluteUsage();

  if (m_iLastUsage > 0 && m_iLastTime > 0)
    m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );

void term_handler (int signum)
{
  XbmcCommons::ILogger* logger = CThread::GetLogger();
  if (logger)
    logger->Log(LOGERROR,"thread 0x%lx (%lu) got signal %d. calling OnException and terminating thread abnormally.", (long unsigned int)pthread_self(), (long unsigned int)pthread_self(), signum);
  CThread* curThread = CThread::GetCurrentThread();
  if (curThread)
  {
    curThread->StopThread(false);
    curThread->OnException();
    if( curThread->IsAutoDelete() )
      delete curThread;
  }
  pthread_exit(NULL);
}

void CThread::SetSignalHandlers()
{
  struct sigaction action;
  action.sa_handler = term_handler;
  sigemptyset (&action.sa_mask);
  action.sa_flags = 0;
}


/*
 *
 *
 */

#include "config.h"
#include <limits.h>
#if defined(TARGET_ANDROID)
#include <unistd.h>
#else
#include <sys/syscall.h>
#endif
#include <sys/resource.h>
#include <string.h>
#ifdef TARGET_FREEBSD
#include <sys/param.h>
#if __FreeBSD_version < 900031
#include <sys/thr.h>
#else
#include <pthread_np.h>
#endif
#endif

#include <signal.h>

void CThread::SpawnThread(unsigned stacksize)
{
  pthread_attr_t attr;
  pthread_attr_init(&a

#if !defined(TARGET_ANDROID) // http://example.com
  if (stacksize > PTHREAD_STACK_MIN)
    pthread_attr_setstacksize(&attr, stacksize);
#endif
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  if (pthread_create(&m_ThreadId, &attr, (void*(*)(void*))staticThread, this) != 0)
  {
    if (logger) logger->Log(LOGNOTICE, "%s - fatal error creating thread",__FUNCTION__);
  }
  pthread_attr_destroy(&attr);
}

void CThread::TermHandler() { }

void CThread::SetThreadInfo()
{
#ifdef TARGET_FREEBSD
#if __FreeBSD_version < 900031
  long lwpid;
  thr_self(&lwpid);
  m_ThreadOpaque.LwpId = lwpid;
#else
  m_ThreadOpaque.LwpId = pthread_getthreadid_np();
#endif
#elif defined(TARGET_ANDROID)
  m_ThreadOpaque.LwpId = gettid();
#else
  m_ThreadOpaque.LwpId = syscall(SYS_gettid);
#endif

#if defined(HAVE_PTHREAD_SETNAME_NP)
#ifdef TARGET_DARWIN
#if(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200)
  pthread_setname_np(m_ThreadName.c_str());
#endif
#else
  pthread_setname_np(m_ThreadId, m_ThreadName.c_str());
#endif
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
  pthread_set_name_np(m_ThreadId, m_ThreadName.c_str());
#endif

#ifdef RLIMIT_NICE
  // get user max prio
  struct rlimit limit;
  int userMaxPrio;
  if (getrlimit(RLIMIT_NICE, &limit) == 0)
  {
    userMaxPrio = limit.rlim_cur - 20;
    if (userMaxPrio < 0)
      userMaxPrio = 0;
  }
  else
    userMaxPrio = 0;

  if (geteuid() == 0)
    userMaxPrio = GetMaxPriority();

  // if the user does not have an entry in limits.conf the following
  // call will fail
  if (userMaxPrio > 0)
  {
    // start thread with nice level of appication
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, appNice) != 0)
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif
}

ThreadIdentifier CThread::GetCurrentThreadId()
{
  return pthread_self();
}

bool CThread::IsCurrentThread(const ThreadIdentifier tid)
{
  return pthread_equal(pthread_self(), tid);
}

int CThread::GetMinPriority(void)
{
  // one level lower than application
  return -1;
}

int CThread::GetMaxPriority(void)
{
  // one level higher than application
  return 1;
}

int CThread::GetNormalPriority(void)
{
  // same level as application
  return 0;
}

bool CThread::SetPriority(const int iPriority)
{
  bool bReturn = false;

  // wait until thread is running, it needs to get its lwp id
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  // get min prio for SCHED_RR
  int minRR = GetMaxPriority() + 1;

  if (!m_ThreadId)
    bReturn = false;
  else if (iPriority >= minRR)
    bReturn = SetPrioritySched_RR(iPriority);
#ifdef RLIMIT_NICE
  else
  {
    // get user max prio
    struct rlimit limit;
    int userMaxPrio;
    if (getrlimit(RLIMIT_NICE, &limit) == 0)
    {
      userMaxPrio = limit.rlim_cur - 20;
      // is a user has no entry in limits.conf rlim_cur is zero
      if (userMaxPrio < 0)
        userMaxPrio = 0;
    }
    else
      userMaxPrio = 0;

    if (geteuid() == 0)
      userMaxPrio = GetMaxPriority();

    // keep priority in bounds
    int prio = iPriority;
    if (prio >= GetMaxPriority())
      prio = std::min(GetMaxPriority(), userMaxPrio);
    if (prio < GetMinPriority())
      prio = GetMinPriority();

    // nice level of application
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (prio)
      prio = prio > 0 ? appNice-1 : appNice+1;

    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, prio) == 0)
      bReturn = true;
    else
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif

  return bReturn;
}

int CThread::GetPriority()
{
  int iReturn;

  // lwp id is valid after start signel has fired
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  int appNice = getpriority(PRIO_PROCESS, getpid());
  int prio = getpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId);
  iReturn = appNice - prio;

  return iReturn;
}

bool CThread::WaitForThreadExit(unsigned int milliseconds)
{
  bool bReturn = m_TermEvent.WaitMSec(milliseconds);

  return bReturn;
}

int64_t CThread::GetAbsoluteUsage()
{
  CSingleLock lock(m_CriticalSection);

  if (!m_ThreadId)
  return 0;

  int64_t time = 0;
#ifdef TARGET_DARWIN
  thread_basic_info threadInfo;
  mach_msg_type_number_t threadInfoCount = THREAD_BASIC_INFO_COUNT;

  kern_return_t ret = thread_info(pthread_mach_thread_np(m_ThreadId),
    THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &threadInfoCount);

  if (ret == KERN_SUCCESS)
  {
    // User time.
    time = ((int64_t)threadInfo.user_time.seconds * 10000000L) + threadInfo.user_time.microseconds*10L;

    // System time.
    time += (((int64_t)threadInfo.system_time.seconds * 10000000L) + threadInfo.system_time.microseconds*10L);
  }

#else
  clockid_t clock;
  if (pthread_getcpuclockid(m_ThreadId, &clock) == 0)
  {
    struct timespec tp;
    clock_gettime(clock, &tp);
    time = (int64_t)tp.tv_sec * 10000000 + tp.tv_nsec/100;
  }
#endif

  return time;
}

float CThread::GetRelativeUsage()
{
  unsigned int iTime = XbmcThreads::SystemClockMillis();
  iTime *= 10000; // convert into 100ns tics

  // only update every 1 second
  if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;

  int64_t iUsage = GetAbsoluteUsage();

  if (m_iLastUsage > 0 && m_iLastTime > 0)
    m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );

  m_iLastUsage = iUsage;
  m_iLastTime = iTime;

  return m_fLastUsage;
}

void term_handler (int signum)
{
  XbmcCommons::ILogger* logger = CThread::GetLogger();
  if (logger)
    logger->Log(LOGERROR,"thread 0x%lx (%lu) got signal %d. calling OnException and terminating thread abnormally.", (long unsigned int)pthread_self(), (long unsigned int)pthread_self(), signum);
  CThread* curThread = CThread::GetCurrentThread();
  if (curThread)
  {
    curThread->StopThread(false);
    curThread->OnException();
    if( curThread->IsAutoDelete() )
      delete curThread;
  }
  pthread_exit(NULL);
}

void CThread::SetSignalHandlers()
{
  struct sigaction action;
  action.sa_handler = term_handler;
  sigemptyset (&action.sa_mask);
  action.sa_flags = 0;
}


if (userMaxPrio > 0)
  {
    // start thread with nice level of appication
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, appNice) != 0)
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }

/*
 *
 *
 */

#include "config.h"
#include <limits.h>
#if defined(TARGET_ANDROID)
#include <unistd.h>
#else
#include <sys/syscall.h>
#endif
#include <sys/resource.h>
#include <string.h>
#ifdef TARGET_FREEBSD
#include <sys/param.h>
#if __FreeBSD_version < 900031
#include <sys/thr.h>
#else
#include <pthread_np.h>
#endif
#endif

#include <signal.h>

void CThread::SpawnThread(unsigned stacksize)
{
  pthread_attr_t attr;
  pthread_attr_init(&attr);
#if !defined(TARGET_ANDROID) // http://example.com
  if (stacksize > PTHREAD_STACK_MIN)
    pthread_attr_setstacksize(&attr, stacksize);
#endif
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  if (pthread_create(&m_ThreadId, &attr, (void*(*)(void*))staticThread, this) != 0)
  {
    if (logger) logger->Log(LOGNOTICE, "%s - fatal error creating thread",__FUNCTION__);
  }
  pthread_attr_destroy(&attr);
}

void CThread::TermHandler() { }

void CThread::SetThreadInfo()
{
#ifdef TARGET_FREEBSD
#if __FreeBSD_version < 900031
  long lwpid;
  thr_self(&lwpid);
  m_ThreadOpaque.LwpId = lwpid;
#else
  m_ThreadOpaque.LwpId = pthread_getthreadid_np();
#endif
#elif defined(TARGET_ANDROID)
  m_ThreadOpaque.LwpId = gettid();
#else
  m_ThreadOpaque.LwpId = syscall(SYS_gettid);
#endif

#if defined(HAVE_PTHREAD_SETNAME_NP)
#ifdef TARGET_DARWIN
#if(__MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200)
  pthread_setname_np(m_ThreadName.c_str());
#endif
#else
  pthread_setname_np(m_ThreadId, m_ThreadName.c_str());
#endif
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
  pthread_set_name_np(m_ThreadId, m_ThreadName.c_str());
#endif

#ifdef RLIMIT_NICE
  // get user max prio
  struct rlimit limit;
  int userMaxPrio;
  if (getrlimit(RLIMIT_NICE, &limit) == 0)
  {
    userMaxPrio = limit.rlim_cur - 20;
    if (userMaxPrio < 0)
      userMaxPrio = 0;
  }
  else
    userMaxPrio = 0;

  if (geteuid() == 0)
    userMaxPrio = GetMaxPriority();

  // if the user does not have an entry in limits.conf the following
  // call will fail

#endif
}

ThreadIdentifier CThread::GetCurrentThreadId()
{
  return pthread_self();
}

bool CThread::IsCurrentThread(const ThreadIdentifier tid)
{
  return pthread_equal(pthread_self(), tid);
}

int CThread::GetMinPriority(void)
{
  // one level lower than application
  return -1;
}

int CThread::GetMaxPriority(void)
{
  // one level higher than application
  return 1;
}

int CThread::GetNormalPriority(void)
{
  // same level as application
  return 0;
}

bool CThread::SetPriority(const int iPriority)
{
  bool bReturn = false;

  // wait until thread is running, it needs to get its lwp id
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  // get min prio for SCHED_RR
  int minRR = GetMaxPriority() + 1;

  if (!m_ThreadId)
    bReturn = false;
  else if (iPriority >= minRR)
    bReturn = SetPrioritySched_RR(iPriority);
#ifdef RLIMIT_NICE
  else
  {
    // get user max prio
    struct rlimit limit;
    int userMaxPrio;
    if (getrlimit(RLIMIT_NICE, &limit) == 0)
    {
      userMaxPrio = limit.rlim_cur - 20;
      // is a user has no entry in limits.conf rlim_cur is zero
      if (userMaxPrio < 0)
        userMaxPrio = 0;
    }
    else
      userMaxPrio = 0;

    if (geteuid() == 0)
      userMaxPrio = GetMaxPriority();

    // keep priority in bounds
    int prio = iPriority;
    if (prio >= GetMaxPriority())
      prio = std::min(GetMaxPriority(), userMaxPrio);
    if (prio < GetMinPriority())
      prio = GetMinPriority();

    // nice level of application
    int appNice = getpriority(PRIO_PROCESS, getpid());
    if (prio)
      prio = prio > 0 ? appNice-1 : appNice+1;

    if (setpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId, prio) == 0)
      bReturn = true;
    else
      if (logger) logger->Log(LOGERROR, "%s: error %s", __FUNCTION__, strerror(errno));
  }
#endif

  return bReturn;
}

int CThread::GetPriority()
{
  int iReturn;

  // lwp id is valid after start signel has fired
  m_StartEvent.Wait();

  CSingleLock lock(m_CriticalSection);

  int appNice = getpriority(PRIO_PROCESS, getpid());
  int prio = getpriority(PRIO_PROCESS, m_ThreadOpaque.LwpId);
  iReturn = appNice - prio;

  return iReturn;
}

bool CThread::WaitForThreadExit(unsigned int milliseconds)
{
  bool bReturn = m_TermEvent.WaitMSec(milliseconds);

  return bReturn;
}

int64_t CThread::GetAbsoluteUsage()
{
  CSingleLock lock(m_CriticalSection);

  if (!m_ThreadId)
  return 0;

  int64_t time = 0;
#ifdef TARGET_DARWIN
  thread_basic_info threadInfo;
  mach_msg_type_number_t threadInfoCount = THREAD_BASIC_INFO_COUNT;

  kern_return_t ret = thread_info(pthread_mach_thread_np(m_ThreadId),
    THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &threadInfoCount);

  if (ret == KERN_SUCCESS)
  {
    // User time.
    time = ((int64_t)threadInfo.user_time.seconds * 10000000L) + threadInfo.user_time.microseconds*10L;

    // System time.
    time += (((int64_t)threadInfo.system_time.seconds * 10000000L) + threadInfo.system_time.microseconds*10L);
  }

#else
  clockid_t clock;
  if (pthread_getcpuclockid(m_ThreadId, &clock) == 0)
  {
    struct timespec tp;
    clock_gettime(clock, &tp);
    time = (int64_t)tp.tv_sec * 10000000 + tp.tv_nsec/100;
  }
#endif

  return time;
}

float CThread::GetRelativeUsage()
{
  unsigned int iTime = XbmcThreads::SystemClockMillis();
  iTime *= 10000; // convert into 100ns tics

  // only update every 1 second
  if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;

  int64_t iUsage = GetAbsoluteUsage();

  if (m_iLastUsage > 0 && m_iLastTime > 0)
    m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );

  m_iLastUsage = iUsage;
  m_iLastTime = iTime;

  return m_fLastUsage;
}

void term_handler (int signum)
{
  XbmcCommons::ILogger* logger = CThread::GetLogger();
  if (logger)
    logger->Log(LOGERROR,"thread 0x%lx (%lu) got signal %d. calling OnException and terminating thread abnormally.", (long unsigned int)pthread_self(), (long unsigned int)pthread_self(), signum);
  CThread* curThread = CThread::GetCurrentThread();
  if (curThread)
  {
    curThread->StopThread(false);
    curThread->OnException();
    if( curThread->IsAutoDelete() )
      delete curThread;
  }
  pthread_exit(NULL);
}

void CThread::SetSignalHandlers()
{
  struct sigaction action;
  action.sa_handler = term_handler;
  sigemptyset (&action.sa_mask);
  action.sa_flags = 0;
}


void Gradient::addColorStop(const Gradient::ColorStop& stop)

/*
 *
 */

#include "config.h"
#include "Gradient.h"

#include "Color.h"
#include "FloatRect.h"
#include <wtf/UnusedParam.h>

namespace WebCore {

Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
    : m_radial(false)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(0)
    , m_r1(0)
    , m_aspectRatio(1)
    , m_stopsSorted(false)
    , m_lastStop(0)
    , m_spreadMethod(SpreadMethodPad)
{
    platformInit();
}

Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio)
    : m_radial(true)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(r0)
    , m_r1(r1)
    , m_aspectRatio(aspectRatio)
    , m_stopsSorted(false)
    , m_lastStop(0)
    , m_spreadMethod(SpreadMethodPad)
{
    platformInit();
}

Gradient::~Gradient()
{
    platformDestroy();
}

void Gradient::adjustParametersForTiledDrawing(IntSize& size, FloatRect& srcRect)
{
    if (m_radial)
        return;

    if (srcRect.isEmpty())
        return;

    if (m_p0.x() == m_p1.x()) {
        size.setWidth(1);
        srcRect.setWidth(1);
        srcRect.setX(0);
        return;
    }
    if (m_p0.y() != m_p1.y())
        return;

    size.setHeight(1);
    srcRect.setHeight(1);
    srcRect.setY(0);
}

void Gradient::addColorStop(float value, const Color& color)
{
    float r;
    float g;
    float b;
    float a;
    color.getRGBA(r, g, b, a);
    m_stops.append(ColorStop(value, r, g, b, a));

    m_stopsSorted = false;
    platformDestroy();
}

{
    m_stops.append(stop);

    m_stopsSorted = false;
    platformDestroy();
}

static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
{
    return a.stop < b.stop;
}

void Gradient::sortStopsIfNecessary()
{
    if (m_stopsSorted)
        return;

    m_stopsSorted = true;

    if (!m_stops.size())
        return;

    if (m_stops.size() == 2 && compareStops(*m_stops.begin(), *m_stops.end()))
        return;

    std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
}

void Gradient::getColor(float value, float* r, float* g, float* b, float* a) const
{
    ASSERT(value >= 0);
    ASSERT(value <= 1);

    if (m_stops.isEmpty()) {
        *r = 0;
        *g = 0;
        *b = 0;
        *a = 0;
        return;
    }
    if (!m_stopsSorted) {
        if (m_stops.size())
            std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
        m_stopsSorted = true;
    }
    if (value <= 0 || value <= m_stops.first().stop) {
        *r = m_stops.first().red;
        *g = m_stops.first().green;
        *b = m_stops.first().blue;
        *a = m_stops.first().alpha;
        return;
    }
    if (value >= 1 || value >= m_stops.last().stop) {
        *r = m_stops.last().red;
        *g = m_stops.last().green;
        *b = m_stops.last().blue;
        *a = m_stops.last().alpha;
        return;
    }

    // Find stop before and stop after and interpolate.
    int stop = findStop(value);
    const ColorStop& lastStop = m_stops[stop];
    const ColorStop& nextStop = m_stops[stop + 1];
    float stopFraction = (value - lastStop.stop) / (nextStop.stop - lastStop.stop);
    *r = lastStop.red + (nextStop.red - lastStop.red) * stopFraction;
    *g = lastStop.green + (nextStop.green - lastStop.green) * stopFraction;
    *b = lastStop.blue + (nextStop.blue - lastStop.blue) * stopFraction;
    *a = lastStop.alpha + (nextStop.alpha - lastStop.alpha) * stopFraction;
}

int Gradient::findStop(float value) const
{
    ASSERT(value >= 0);
    ASSERT(value <= 1);
    ASSERT(m_stopsSorted);

    int numStops = m_stops.size();
    ASSERT(numStops >= 2);
    ASSERT(m_lastStop < numStops - 1);

    int i = m_lastStop;
    if (value < m_stops[i].stop)
        i = 1;
    else
        i = m_lastStop + 1;

    for (; i < numStops - 1; ++i)
        if (value < m_stops[i].stop)
            break;

    m_lastStop = i - 1;
    return m_lastStop;
}

bool Gradient::hasAlpha() const
{
    for (size_t i = 0; i < m_stops.size(); i++) {
        if (m_stops[i].alpha < 1)
            return true;
    }

    return false;
}

void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
{
    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
    ASSERT(m_gradient == 0);
    m_spreadMethod = spreadMethod;
}

void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
{
    m_gradientSpaceTransformation = gradientSpaceTransformation;
    setPlatformGradientSpaceTransform(gradientSpaceTransformation);
}

#if !(USE(SKIA) && !PLATFORM(ANDROID)) && !USE(CAIRO)
void Gradient::setPlatformGradientSpaceTransform(const AffineTransform&)
{
}
#endif

} //namespace


/*
 *
 */

#include "config.h"
#include "Gradient.h"

#include "Color.h"
#include "FloatRect.h"
#include <wtf/UnusedParam.h>

namespace WebCore {

Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
    : m_radial(false)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(0)
    , m_r1(0)
    , m_aspectRatio(1)
    , m_stopsSorted(false)
    , m_lastStop(0)
    , m_spreadMethod(SpreadMethodPad)
{
    platformInit();
}

Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio)
    : m_radial(true)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(r0)
    , m_r1(r1)
    , m_aspectRatio(aspectRatio)
    , m_stopsSorted(false)
    , m_lastStop(0)
    , m_spreadMethod(SpreadMethodPad)
{
    platformInit();
}

Gradient::~Gradient()
{
    platformDestroy();
}

void Gradient::adjustParametersForTiledDrawing(IntSize& size, FloatRect& srcRect)
{
    if (m_radial)
        return;

    if (srcRect.isEmpty())
        return;

    if (m_p0.x() == m_p1.x()) {
        size.setWidth(1);
        srcRect.setWidth(1);
        srcRect.setX(0);
        return;
    }
    if (m_p0.y() != m_p1.y())
        return;

    size.setHeight(1);
    srcRect.setHeight(1);
    srcRect.setY(0);
}

void Gradient::addColorStop(float value, const Color& color)
{
    float r;
    float g;
    float b;
    float a;
    color.getRGBA(r, g, b, a);
    m_stops.append(ColorStop(value, r, g, b, a));

    m_stopsSorted = false;
    platformDestroy();
}

void Gradient::addColorStop(const Gradient::ColorStop& stop)
{
    m_stops.append(stop);

    m_stopsSorted = false;
    platformDestroy();
}

static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)

void Gradient::sortStopsIfNecessary()
{
    if (m_stopsSorted)
        return;

    m_stopsSorted = true;

    if (!m_stops.size())
        return;

    if (m_stops.size() == 2 && compareStops(*m_stops.begin(), *m_stops.end()))
        return;

    std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
}

void Gradient::getColor(float value, float* r, float* g, float* b, float* a) const
{
    ASSERT(value >= 0);
    ASSERT(value <= 1);

    if (m_stops.isEmpty()) {
        *r = 0;
        *g = 0;
        *b = 0;
        *a = 0;
        return;
    }
    if (!m_stopsSorted) {
        if (m_stops.size())
            std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
        m_stopsSorted = true;
    }
    if (value <= 0 || value <= m_stops.first().stop) {
        *r = m_stops.first().red;
        *g = m_stops.first().green;
        *b = m_stops.first().blue;
        *a = m_stops.first().alpha;
        return;
    }
    if (value >= 1 || value >= m_stops.last().stop) {
        *r = m_stops.last().red;
        *g = m_stops.last().green;
        *b = m_stops.last().blue;
        *a = m_stops.last().alpha;
        return;
    }

    // Find stop before and stop after and interpolate.
    int stop = findStop(value);
    const ColorStop& lastStop = m_stops[stop];
    const ColorStop& nextStop = m_stops[stop + 1];
    float stopFraction = (value - lastStop.stop) / (nextStop.stop - lastStop.stop);
    *r = lastStop.red + (nextStop.red - lastStop.red) * stopFraction;
    *g = lastStop.green + (nextStop.green - lastStop.green) * stopFraction;
    *b = lastStop.blue + (nextStop.blue - lastStop.blue) * stopFraction;
    *a = lastStop.alpha + (nextStop.alpha - lastStop.alpha) * stopFraction;
}

int Gradient::findStop(float value) const
{
    ASSERT(value >= 0);
    ASSERT(value <= 1);
    ASSERT(m_stopsSorted);

    int numStops = m_stops.size();
    ASSERT(numStops >= 2);
    ASSERT(m_lastStop < numStops - 1);

    int i = m_lastStop;
    if (value < m_stops[i].stop)
        i = 1;
    else
        i = m_lastStop + 1;

    for (; i < numStops - 1; ++i)
        if (value < m_stops[i].stop)
            break;

    m_lastStop = i - 1;
    return m_lastStop;
}

bool Gradient::hasAlpha() const
{
    for (size_t i = 0; i < m_stops.size(); i++) {
        if (m_stops[i].alpha < 1)
            return true;
    }

    return false;
}

void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
{
    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
    ASSERT(m_gradient == 0);
    m_spreadMethod = spreadMethod;
}

void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
{
    m_gradientSpaceTransformation = gradientSpaceTransformation;
    setPlatformGradientSpaceTransform(gradientSpaceTransformation);
}

#if !(USE(SKIA) && !PLATFORM(ANDROID)) && !USE(CAIRO)
void Gradient::setPlatformGradientSpaceTransform(const AffineTransform&)
{
}
#endif

} //namespace


{
    for (size_t i = 0; i < m_stops.size(); i++) {
        if (m_stops[i].alpha < 1)
            return true;
    }

/*
 *
 */

#include "config.h"
#include "Gradient.h"

#include "Color.h"
#include "FloatRect.h"
#include <wtf/UnusedParam.h>

namespace WebCore {

Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
    : m_radial(false)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(0)
    , m_r1(0)
    , m_aspectRatio(1)
    , m_stopsSorted(false)
    , m_lastStop(0)
    , m_spreadMethod(SpreadMethodPad)
{
    platformInit();
}

Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio)
    : m_radial(true)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(r0)
    , m_r1(r1)
    , m_aspectRatio(aspectRatio)
    , m_stopsSorted(false)
    , m_lastStop(0)
    , m_spreadMethod(SpreadMethodPad)
{
    platformInit();
}

Gradient::~Gradient()
{
    platformDestroy();
}

void Gradient::adjustParametersForTiledDrawing(IntSize& size, FloatRect& srcRect)
{
    if (m_radial)
        return;

    if (srcRect.isEmpty())
        return;

    if (m_p0.x() == m_p1.x()) {
        size.setWidth(1);
        srcRect.setWidth(1);
        srcRect.setX(0);
        return;
    }
    if (m_p0.y() != m_p1.y())
        return;

    size.setHeight(1);
    srcRect.setHeight(1);
    srcRect.setY(0);
}

void Gradient::addColorStop(float value, const Color& color)
{
    float r;
    float g;
    float b;
    float a;
    color.getRGBA(r, g, b, a);
    m_stops.append(ColorStop(value, r, g, b, a));

    m_stopsSorted = false;
    platformDestroy();
}

void Gradient::addColorStop(const Gradient::ColorStop& stop)
{
    m_stops.append(stop);

    m_stopsSorted = false;
    platformDestroy();
}

static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
{
    return a.stop < b.stop;
}

void Gradient::sortStopsIfNecessary()
{
    if (m_stopsSorted)
        return;

    m_stopsSorted = true;

    if (!m_stops.size())
        return;

    if (m_stops.size() == 2 && compareStops(*m_stops.begin(), *m_stops.end()))
        return;

    std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
}

void Gradient::getColor(float value, float* r, float* g, float* b, float* a) const
{
    ASSERT(value >= 0);
    ASSERT(value <= 1);

    if (m_stops.isEmpty()) {
        *r = 0;
        *g = 0;
        *b = 0;
        *a = 0;
        return;
    }
    if (!m_stopsSorted) {
        if (m_stops.size())
            std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
        m_stopsSorted = true;
    }
    if (value <= 0 || value <= m_stops.first().stop) {
        *r = m_stops.first().red;
        *g = m_stops.first().green;
        *b = m_stops.first().blue;
        *a = m_stops.first().alpha;
        return;
    }
    if (value >= 1 || value >= m_stops.last().stop) {
        *r = m_stops.last().red;
        *g = m_stops.last().green;
        *b = m_stops.last().blue;
        *a = m_stops.last().alpha;
        return;
    }

    // Find stop before and stop after and interpolate.
    int stop = findStop(value);
    const ColorStop& lastStop = m_stops[stop];
    const ColorStop& nextStop = m_stops[stop + 1];
    float stopFraction = (value - lastStop.stop) / (nextStop.stop - lastStop.stop);
    *r = lastStop.red + (nextStop.red - lastStop.red) * stopFraction;
    *g = lastStop.green + (nextStop.green - lastStop.green) * stopFraction;
    *b = lastStop.blue + (nextStop.blue - lastStop.blue) * stopFraction;
    *a = lastStop.alpha + (nextStop.alpha - lastStop.alpha) * stopFraction;
}

int Gradient::findStop(float value) const
{
    ASSERT(value >= 0);
    ASSERT(value <= 1);
    ASSERT(m_stopsSorted);

    int numStops = m_stops.size();
    ASSERT(numStops >= 2);
    ASSERT(m_lastStop < numStops - 1);

    int i = m_lastStop;
    if (value < m_stops[i].stop)
        i = 1;
    else
        i = m_lastStop + 1;

    for (; i < numStops - 1; ++i)
        if (value < m_stops[i].stop)
            break;

    m_lastStop = i - 1;
    return m_lastStop;
}

bool Gradient::hasAlpha() const

    return false;
}

void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
{
    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
    ASSERT(m_gradient == 0);
    m_spreadMethod = spreadMethod;
}

void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
{
    m_gradientSpaceTransformation = gradientSpaceTransformation;
    setPlatformGradientSpaceTransform(gradientSpaceTransformation);
}

#if !(USE(SKIA) && !PLATFORM(ANDROID)) && !USE(CAIRO)
void Gradient::setPlatformGradientSpaceTransform(const AffineTransform&)
{
}
#endif

} //namespace


/*
 *
 */

#include "config.h"
#include "Gradient.h"

#include "Color.h"
#include "FloatRect.h"
#include <wtf/UnusedParam.h>

namespace WebCore {

Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
    : m_radial(false)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(0)
    , m_r1(0)
    , m_aspectRatio(1)
    , m_stopsSorted(false)
    , m_lastStop(0)
    , m_spreadMethod(SpreadMethodPad)
{
    platformInit();
}

Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio)
    : m_radial(true)
    , m_p0(p0)
    , m_p1(p1)
    , m_r0(r0)
    , m_r1(r1)
    , m_aspectRatio(aspectRatio)
    , m_stopsSorted(false)
    , m_lastStop(0)
    , m_spreadMethod(SpreadMethodPad)
{
    platformInit();
}

Gradient::~Gradient()
{
    platformDestroy();
}

void Gradient::adjustParametersForTiledDrawing(IntSize& size, FloatRect& srcRect)
{
    if (m_radial)
        return;

    if (srcRect.isEmpty())
        return;

    if (m_p0.x() == m_p1.x()) {
        size.setWidth(1);
        srcRect.setWidth(1);
        srcRect.setX(0);
        return;
    }
    if (m_p0.y() != m_p1.y())
        return;

    size.setHeight(1);
    srcRect.setHeight(1);
    srcRect.setY(0);
}

void Gradient::addColorStop(float value, const Color& color)
{
    float r;
    float g;
    float b;
    float a;
    color.getRGBA(r, g, b, a);
    m_stops.append(ColorStop(value, r, g, b, a));

    m_stopsSorted = false;
    platformDestroy();
}

void Gradient::addColorStop(const Gradient::ColorStop& stop)
{
    m_stops.append(stop);

    m_stopsSorted = false;
    platformDestroy();
}

static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
{
    return a.stop < b.stop;
}

void Gradient::sortStopsIfNecessary()
{
    if (m_stopsSorted)
        return;

    m_stopsSorted = true;

    if (!m_stops.size())
        return;

    if (m_stops.size() == 2 && compareStops(*m_stops.begin(), *m_stops.end()))
        return;

    std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
}

void Gradient::getColor(float value, float* r, float* g, float* b, float* a) const
{
    ASSERT(value >= 0);
    ASSERT(value <= 1);

    if (m_stops.isEmpty()) {
        *r = 0;
        *g = 0;
        *b = 0;
        *a = 0;
        return;
    }
    if (!m_stopsSorted) {
        if (m_stops.size())
            std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
        m_stopsSorted = true;
    }
    if (value <= 0 || value <= m_stops.first().stop) {
        *r = m_stops.first().red;
        *g = m_stops.first().green;
        *b = m_stops.first().blue;
        *a = m_stops.first().alpha;
        return;
    }
    if (value >= 1 || value >= m_stops.last().stop) {
        *r = m_stops.last().red;
        *g = m_stops.last().green;
        *b = m_stops.last().blue;
        *a = m_stops.last().alpha;
        return;
    }

    // Find stop before and stop after and interpolate.
    int stop = findStop(value);
    const ColorStop& lastStop = m_stops[stop];
    const ColorStop& nextStop = m_stops[stop + 1];
    float stopFraction = (value - lastStop.stop) / (nextStop.stop - lastStop.stop);
    *r = lastStop.red + (nextStop.red - lastStop.red) * stopFraction;
    *g = lastStop.green + (nextStop.green - lastStop.green) * stopFraction;
    *b = lastStop.blue + (nextStop.blue - lastStop.blue) * stopFraction;
    *a = lastStop.alpha + (nextStop.alpha - lastStop.alpha) * stopFraction;
}

int Gradient::findStop(float value) const
{
    ASSERT(value >= 0);
    ASSERT(value <= 1);
    ASSERT(m_stopsSorted);

    int numStops = m_stops.size();
    ASSERT(numStops >= 2);
    ASSERT(m_lastStop < numStops - 1);

    int i = m_lastStop;
    if (value < m_stops[i].stop)
        i = 1;
    else
        i = m_lastStop + 1;

    for (; i < numStops - 1; ++i)
        if (value < m_stops[i].stop)
            break;

    m_lastStop = i - 1;
    return m_lastStop;
}

bool Gradient::hasAlpha() const
{
    for (size_t i = 0; i < m_stops.size(); i++) {
        if (m_stops[i].alpha < 1)
            return true;
    }

}

void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
{
    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
    ASSERT(m_gradient == 0);
    m_spreadMethod = spreadMethod;
}

void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
{
    m_gradientSpaceTransformation = gradientSpaceTransformation;
    setPlatformGradientSpaceTransform(gradientSpaceTransformation);
}

#if !(USE(SKIA) && !PLATFORM(ANDROID)) && !USE(CAIRO)
void Gradient::setPlatformGradientSpaceTransform(const AffineTransform&)
{
}
#endif

} //namespace