aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/obscuren/qml/cpp/capi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/obscuren/qml/cpp/capi.cpp')
-rw-r--r--Godeps/_workspace/src/github.com/obscuren/qml/cpp/capi.cpp884
1 files changed, 0 insertions, 884 deletions
diff --git a/Godeps/_workspace/src/github.com/obscuren/qml/cpp/capi.cpp b/Godeps/_workspace/src/github.com/obscuren/qml/cpp/capi.cpp
deleted file mode 100644
index 024e5ec9c..000000000
--- a/Godeps/_workspace/src/github.com/obscuren/qml/cpp/capi.cpp
+++ /dev/null
@@ -1,884 +0,0 @@
-#include <QApplication>
-#include <QQuickView>
-#include <QQuickItem>
-#include <QtQml>
-#include <QDebug>
-#include <QQuickImageProvider>
-
-#include <string.h>
-
-#include "govalue.h"
-#include "govaluetype.h"
-#include "connector.h"
-#include "capi.h"
-
-static char *local_strdup(const char *str)
-{
- char *strcopy = 0;
- if (str) {
- size_t len = strlen(str) + 1;
- strcopy = (char *)malloc(len);
- memcpy(strcopy, str, len);
- }
- return strcopy;
-}
-
-error *errorf(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- QString str = QString().vsprintf(format, ap);
- va_end(ap);
- QByteArray ba = str.toUtf8();
- return local_strdup(ba.constData());
-}
-
-void panicf(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- QString str = QString().vsprintf(format, ap);
- va_end(ap);
- QByteArray ba = str.toUtf8();
- hookPanic(local_strdup(ba.constData()));
-}
-
-void newGuiApplication()
-{
- static char empty[1] = {0};
- static char *argv[] = {empty, 0};
- static int argc = 1;
- new QApplication(argc, argv);
-
- // The event loop should never die.
- qApp->setQuitOnLastWindowClosed(false);
-}
-
-void applicationExec()
-{
- qApp->exec();
-}
-
-void applicationExit()
-{
- qApp->exit(0);
-}
-
-void applicationFlushAll()
-{
- qApp->processEvents();
-}
-
-void *currentThread()
-{
- return QThread::currentThread();
-}
-
-void *appThread()
-{
- return QCoreApplication::instance()->thread();
-}
-
-QQmlEngine_ *newEngine(QObject_ *parent)
-{
- return new QQmlEngine(reinterpret_cast<QObject *>(parent));
-}
-
-QQmlContext_ *engineRootContext(QQmlEngine_ *engine)
-{
- return reinterpret_cast<QQmlEngine *>(engine)->rootContext();
-}
-
-void engineSetContextForObject(QQmlEngine_ *engine, QObject_ *object)
-{
- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
- QObject *qobject = reinterpret_cast<QObject *>(object);
-
- QQmlEngine::setContextForObject(qobject, qengine->rootContext());
-}
-
-void engineSetOwnershipCPP(QQmlEngine_ *engine, QObject_ *object)
-{
- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
- QObject *qobject = reinterpret_cast<QObject *>(object);
-
- qengine->setObjectOwnership(qobject, QQmlEngine::CppOwnership);
-}
-
-void engineSetOwnershipJS(QQmlEngine_ *engine, QObject_ *object)
-{
- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
- QObject *qobject = reinterpret_cast<QObject *>(object);
-
- qengine->setObjectOwnership(qobject, QQmlEngine::JavaScriptOwnership);
-}
-
-QQmlComponent_ *newComponent(QQmlEngine_ *engine, QObject_ *parent)
-{
- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
- //QObject *qparent = reinterpret_cast<QObject *>(parent);
- QQmlComponent *qcomponent = new QQmlComponent(qengine);
- // Qt 5.2.0 returns NULL on qmlEngine(qcomponent) without this.
- QQmlEngine::setContextForObject(qcomponent, qengine->rootContext());
- return qcomponent;
-}
-
-class GoImageProvider : public QQuickImageProvider {
-
- // TODO Destroy this when engine is destroyed.
-
- public:
-
- GoImageProvider(void *imageFunc) : QQuickImageProvider(QQmlImageProviderBase::Image), imageFunc(imageFunc) {};
-
- virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
- {
- QByteArray ba = id.toUtf8();
- int width = 0, height = 0;
- if (requestedSize.isValid()) {
- width = requestedSize.width();
- height = requestedSize.height();
- }
- QImage *ptr = reinterpret_cast<QImage *>(hookRequestImage(imageFunc, (char*)ba.constData(), ba.size(), width, height));
- QImage image = *ptr;
- delete ptr;
-
- *size = image.size();
- if (requestedSize.isValid() && requestedSize != *size) {
- image = image.scaled(requestedSize, Qt::KeepAspectRatio);
- }
- return image;
- };
-
- private:
-
- void *imageFunc;
-};
-
-void engineAddImageProvider(QQmlEngine_ *engine, QString_ *providerId, void *imageFunc)
-{
- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
- QString *qproviderId = reinterpret_cast<QString *>(providerId);
-
- qengine->addImageProvider(*qproviderId, new GoImageProvider(imageFunc));
-}
-
-void componentLoadURL(QQmlComponent_ *component, const char *url, int urlLen)
-{
- QByteArray qurl(url, urlLen);
- QString qsurl = QString::fromUtf8(qurl);
- reinterpret_cast<QQmlComponent *>(component)->loadUrl(qsurl);
-}
-
-void componentSetData(QQmlComponent_ *component, const char *data, int dataLen, const char *url, int urlLen)
-{
- QByteArray qdata(data, dataLen);
- QByteArray qurl(url, urlLen);
- QString qsurl = QString::fromUtf8(qurl);
- reinterpret_cast<QQmlComponent *>(component)->setData(qdata, qsurl);
-}
-
-char *componentErrorString(QQmlComponent_ *component)
-{
- QQmlComponent *qcomponent = reinterpret_cast<QQmlComponent *>(component);
- if (qcomponent->isReady()) {
- return NULL;
- }
- if (qcomponent->isError()) {
- QByteArray ba = qcomponent->errorString().toUtf8();
- return local_strdup(ba.constData());
- }
- return local_strdup("component is not ready (why!?)");
-}
-
-QObject_ *componentCreate(QQmlComponent_ *component, QQmlContext_ *context)
-{
- QQmlComponent *qcomponent = reinterpret_cast<QQmlComponent *>(component);
- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
-
- if (!qcontext) {
- qcontext = qmlContext(qcomponent);
- }
- return qcomponent->create(qcontext);
-}
-
-QQuickWindow_ *componentCreateWindow(QQmlComponent_ *component, QQmlContext_ *context)
-{
- QQmlComponent *qcomponent = reinterpret_cast<QQmlComponent *>(component);
- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
-
- if (!qcontext) {
- qcontext = qmlContext(qcomponent);
- }
- QObject *obj = qcomponent->create(qcontext);
- if (!objectIsWindow(obj)) {
- QQuickView *view = new QQuickView(qmlEngine(qcomponent), 0);
- view->setContent(qcomponent->url(), qcomponent, obj);
- view->setResizeMode(QQuickView::SizeRootObjectToView);
- obj = view;
- }
- return obj;
-}
-
-// Workaround for bug https://bugs.launchpad.net/bugs/1179716
-struct DoShowWindow : public QQuickWindow {
- void show() {
- QQuickWindow::show();
- QResizeEvent resize(size(), size());
- resizeEvent(&resize);
- }
-};
-
-void windowShow(QQuickWindow_ *win)
-{
- reinterpret_cast<DoShowWindow *>(win)->show();
-}
-
-void windowHide(QQuickWindow_ *win)
-{
- reinterpret_cast<QQuickWindow *>(win)->hide();
-}
-
-uintptr_t windowPlatformId(QQuickWindow_ *win)
-{
- return reinterpret_cast<QQuickWindow *>(win)->winId();
-}
-
-void windowConnectHidden(QQuickWindow_ *win)
-{
- QQuickWindow *qwin = reinterpret_cast<QQuickWindow *>(win);
- QObject::connect(qwin, &QWindow::visibleChanged, [=](bool visible){
- if (!visible) {
- hookWindowHidden(win);
- }
- });
-}
-
-QObject_ *windowRootObject(QQuickWindow_ *win)
-{
- if (objectIsView(win)) {
- return reinterpret_cast<QQuickView *>(win)->rootObject();
- }
- return win;
-}
-
-QImage_ *windowGrabWindow(QQuickWindow_ *win)
-{
- QQuickWindow *qwin = reinterpret_cast<QQuickWindow *>(win);
- QImage *image = new QImage;
- *image = qwin->grabWindow().convertToFormat(QImage::Format_ARGB32_Premultiplied);
- return image;
-}
-
-QImage_ *newImage(int width, int height)
-{
- return new QImage(width, height, QImage::Format_ARGB32_Premultiplied);
-}
-
-void delImage(QImage_ *image)
-{
- delete reinterpret_cast<QImage *>(image);
-}
-
-void imageSize(QImage_ *image, int *width, int *height)
-{
- QImage *qimage = reinterpret_cast<QImage *>(image);
- *width = qimage->width();
- *height = qimage->height();
-}
-
-unsigned char *imageBits(QImage_ *image)
-{
- QImage *qimage = reinterpret_cast<QImage *>(image);
- return qimage->bits();
-}
-
-const unsigned char *imageConstBits(QImage_ *image)
-{
- QImage *qimage = reinterpret_cast<QImage *>(image);
- return qimage->constBits();
-}
-
-void contextSetObject(QQmlContext_ *context, QObject_ *value)
-{
- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
- QObject *qvalue = reinterpret_cast<QObject *>(value);
-
- // Give qvalue an engine reference if it doesn't yet have one.
- if (!qmlEngine(qvalue)) {
- QQmlEngine::setContextForObject(qvalue, qcontext->engine()->rootContext());
- }
-
- qcontext->setContextObject(qvalue);
-}
-
-void contextSetProperty(QQmlContext_ *context, QString_ *name, DataValue *value)
-{
- const QString *qname = reinterpret_cast<QString *>(name);
- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
-
- QVariant var;
- unpackDataValue(value, &var);
-
- // Give qvalue an engine reference if it doesn't yet have one .
- QObject *obj = var.value<QObject *>();
- if (obj && !qmlEngine(obj)) {
- QQmlEngine::setContextForObject(obj, qcontext);
- }
-
- qcontext->setContextProperty(*qname, var);
-}
-
-void contextGetProperty(QQmlContext_ *context, QString_ *name, DataValue *result)
-{
- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
- const QString *qname = reinterpret_cast<QString *>(name);
-
- QVariant var = qcontext->contextProperty(*qname);
- packDataValue(&var, result);
-}
-
-QQmlContext_ *contextSpawn(QQmlContext_ *context)
-{
- QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);
- return new QQmlContext(qcontext);
-}
-
-void delObject(QObject_ *object)
-{
- delete reinterpret_cast<QObject *>(object);
-}
-
-void delObjectLater(QObject_ *object)
-{
- reinterpret_cast<QObject *>(object)->deleteLater();
-}
-
-const char *objectTypeName(QObject_ *object)
-{
- return reinterpret_cast<QObject *>(object)->metaObject()->className();
-}
-
-int objectGetProperty(QObject_ *object, const char *name, DataValue *result)
-{
- QObject *qobject = reinterpret_cast<QObject *>(object);
-
- QVariant var = qobject->property(name);
- packDataValue(&var, result);
-
- if (!var.isValid() && qobject->metaObject()->indexOfProperty(name) == -1) {
- // TODO May have to check the dynamic property names too.
- return 0;
- }
- return 1;
-}
-
-error *objectSetProperty(QObject_ *object, const char *name, DataValue *value)
-{
- QObject *qobject = reinterpret_cast<QObject *>(object);
- QVariant var;
- unpackDataValue(value, &var);
-
- // Give qvalue an engine reference if it doesn't yet have one.
- QObject *obj = var.value<QObject *>();
- if (obj && !qmlEngine(obj)) {
- QQmlContext *context = qmlContext(qobject);
- if (context) {
- QQmlEngine::setContextForObject(obj, context);
- }
- }
-
- // Check that the types are compatible. There's probably more to be done here.
- const QMetaObject *metaObject = qobject->metaObject();
- int propIndex = metaObject->indexOfProperty(name);
- if (propIndex == -1) {
- return errorf("cannot set non-existent property \"%s\" on type %s", name, qobject->metaObject()->className());
- }
-
- QMetaProperty prop = metaObject->property(propIndex);
- int propType = prop.userType();
- void *valueArg;
- if (propType == QMetaType::QVariant) {
- valueArg = (void *)&var;
- } else {
- int varType = var.userType();
- QVariant saved = var;
- if (propType != varType && !var.convert(propType)) {
- if (varType == QMetaType::QObjectStar) {
- return errorf("cannot set property \"%s\" with type %s to value of %s*",
- name, QMetaType::typeName(propType), saved.value<QObject*>()->metaObject()->className());
- } else {
- return errorf("cannot set property \"%s\" with type %s to value of %s",
- name, QMetaType::typeName(propType), QMetaType::typeName(varType));
- }
- }
- valueArg = (void *)var.constData();
- }
-
- int status = -1;
- int flags = 0;
- void *args[] = {valueArg, 0, &status, &flags};
- QMetaObject::metacall(qobject, QMetaObject::WriteProperty, propIndex, args);
- return 0;
-}
-
-error *objectInvoke(QObject_ *object, const char *method, int methodLen, DataValue *resultdv, DataValue *paramsdv, int paramsLen)
-{
- QObject *qobject = reinterpret_cast<QObject *>(object);
-
- QVariant result;
- QVariant param[MaxParams];
- QGenericArgument arg[MaxParams];
- for (int i = 0; i < paramsLen; i++) {
- unpackDataValue(&paramsdv[i], &param[i]);
- arg[i] = Q_ARG(QVariant, param[i]);
- }
- if (paramsLen > 10) {
- panicf("fix the parameter dispatching");
- }
-
- const QMetaObject *metaObject = qobject->metaObject();
- // Walk backwards so descendants have priority.
- for (int i = metaObject->methodCount()-1; i >= 0; i--) {
- QMetaMethod metaMethod = metaObject->method(i);
- QMetaMethod::MethodType methodType = metaMethod.methodType();
- if (methodType == QMetaMethod::Method || methodType == QMetaMethod::Slot) {
- QByteArray name = metaMethod.name();
- if (name.length() == methodLen && qstrncmp(name.constData(), method, methodLen) == 0) {
- if (metaMethod.parameterCount() < paramsLen) {
- // TODO Might continue looking to see if a different signal has the same name and enough arguments.
- return errorf("method \"%s\" has too few parameters for provided arguments", method);
- }
-
- bool ok;
- if (metaMethod.returnType() == QMetaType::Void) {
- ok = metaMethod.invoke(qobject, Qt::DirectConnection,
- arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]);
- } else {
- ok = metaMethod.invoke(qobject, Qt::DirectConnection, Q_RETURN_ARG(QVariant, result),
- arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]);
- }
- if (!ok) {
- return errorf("invalid parameters to method \"%s\"", method);
- }
-
- packDataValue(&result, resultdv);
- return 0;
- }
- }
- }
-
- return errorf("object does not expose a method \"%s\"", method);
-}
-
-void objectFindChild(QObject_ *object, QString_ *name, DataValue *resultdv)
-{
- QObject *qobject = reinterpret_cast<QObject *>(object);
- QString *qname = reinterpret_cast<QString *>(name);
-
- QVariant var;
- QObject *result = qobject->findChild<QObject *>(*qname);
- if (result) {
- var.setValue(result);
- }
- packDataValue(&var, resultdv);
-}
-
-void objectSetParent(QObject_ *object, QObject_ *parent)
-{
- QObject *qobject = reinterpret_cast<QObject *>(object);
- QObject *qparent = reinterpret_cast<QObject *>(parent);
-
- qobject->setParent(qparent);
-}
-
-error *objectConnect(QObject_ *object, const char *signal, int signalLen, QQmlEngine_ *engine, void *func, int argsLen)
-{
- QObject *qobject = reinterpret_cast<QObject *>(object);
- QQmlEngine *qengine = reinterpret_cast<QQmlEngine *>(engine);
- QByteArray qsignal(signal, signalLen);
-
- const QMetaObject *meta = qobject->metaObject();
- // Walk backwards so descendants have priority.
- for (int i = meta->methodCount()-1; i >= 0; i--) {
- QMetaMethod method = meta->method(i);
- if (method.methodType() == QMetaMethod::Signal) {
- QByteArray name = method.name();
- if (name.length() == signalLen && qstrncmp(name.constData(), signal, signalLen) == 0) {
- if (method.parameterCount() < argsLen) {
- // TODO Might continue looking to see if a different signal has the same name and enough arguments.
- return errorf("signal \"%s\" has too few parameters for provided function", name.constData());
- }
- Connector *connector = new Connector(qobject, method, qengine, func, argsLen);
- const QMetaObject *connmeta = connector->metaObject();
- QObject::connect(qobject, method, connector, connmeta->method(connmeta->methodOffset()));
- return 0;
- }
- }
- }
- // Cannot use constData here as the byte array is not null-terminated.
- return errorf("object does not expose a \"%s\" signal", qsignal.data());
-}
-
-QQmlContext_ *objectContext(QObject_ *object)
-{
- return qmlContext(static_cast<QObject *>(object));
-}
-
-int objectIsComponent(QObject_ *object)
-{
- QObject *qobject = static_cast<QObject *>(object);
- return dynamic_cast<QQmlComponent *>(qobject) ? 1 : 0;
-}
-
-int objectIsWindow(QObject_ *object)
-{
- QObject *qobject = static_cast<QObject *>(object);
- return dynamic_cast<QQuickWindow *>(qobject) ? 1 : 0;
-}
-
-int objectIsView(QObject_ *object)
-{
- QObject *qobject = static_cast<QObject *>(object);
- return dynamic_cast<QQuickView *>(qobject) ? 1 : 0;
-}
-
-error *objectGoAddr(QObject_ *object, GoAddr **addr)
-{
- QObject *qobject = static_cast<QObject *>(object);
- GoValue *goValue = dynamic_cast<GoValue *>(qobject);
- if (goValue) {
- *addr = goValue->addr;
- return 0;
- }
- GoPaintedValue *goPaintedValue = dynamic_cast<GoPaintedValue *>(qobject);
- if (goPaintedValue) {
- *addr = goPaintedValue->addr;
- return 0;
- }
- return errorf("QML object is not backed by a Go value");
-}
-
-QString_ *newString(const char *data, int len)
-{
- // This will copy data only once.
- QByteArray ba = QByteArray::fromRawData(data, len);
- return new QString(ba);
-}
-
-void delString(QString_ *s)
-{
- delete reinterpret_cast<QString *>(s);
-}
-
-GoValue_ *newGoValue(GoAddr *addr, GoTypeInfo *typeInfo, QObject_ *parent)
-{
- QObject *qparent = reinterpret_cast<QObject *>(parent);
- if (typeInfo->paint) {
- return new GoPaintedValue(addr, typeInfo, qparent);
- }
- return new GoValue(addr, typeInfo, qparent);
-}
-
-void goValueActivate(GoValue_ *value, GoTypeInfo *typeInfo, int addrOffset)
-{
- GoMemberInfo *fieldInfo = typeInfo->fields;
- for (int i = 0; i < typeInfo->fieldsLen; i++) {
- if (fieldInfo->addrOffset == addrOffset) {
- if (typeInfo->paint) {
- static_cast<GoPaintedValue *>(value)->activate(fieldInfo->metaIndex);
- } else {
- static_cast<GoValue *>(value)->activate(fieldInfo->metaIndex);
- }
- return;
- }
- fieldInfo++;
- }
-
- // TODO Return an error; probably an unexported field.
-}
-
-void unpackDataValue(DataValue *value, QVariant_ *var)
-{
- QVariant *qvar = reinterpret_cast<QVariant *>(var);
- switch (value->dataType) {
- case DTString:
- *qvar = QString::fromUtf8(*(char **)value->data, value->len);
- break;
- case DTBool:
- *qvar = bool(*(char *)(value->data) != 0);
- break;
- case DTInt64:
- *qvar = *(qint64*)(value->data);
- break;
- case DTInt32:
- *qvar = *(qint32*)(value->data);
- break;
- case DTUint64:
- *qvar = *(quint64*)(value->data);
- break;
- case DTUint32:
- *qvar = *(quint32*)(value->data);
- break;
- case DTFloat64:
- *qvar = *(double*)(value->data);
- break;
- case DTFloat32:
- *qvar = *(float*)(value->data);
- break;
- case DTColor:
- *qvar = QColor::fromRgba(*(QRgb*)(value->data));
- break;
- case DTVariantList:
- *qvar = **(QVariantList**)(value->data);
- delete *(QVariantList**)(value->data);
- break;
- case DTObject:
- qvar->setValue(*(QObject**)(value->data));
- break;
- case DTInvalid:
- // null would be more natural, but an invalid variant means
- // it has proper semantics when dealing with non-qml qt code.
- //qvar->setValue(QJSValue(QJSValue::NullValue));
- qvar->clear();
- break;
- default:
- panicf("unknown data type: %d", value->dataType);
- break;
- }
-}
-
-void packDataValue(QVariant_ *var, DataValue *value)
-{
- QVariant *qvar = reinterpret_cast<QVariant *>(var);
-
- // Some assumptions are made below regarding the size of types.
- // There's apparently no better way to handle this since that's
- // how the types with well defined sizes (qint64) are mapped to
- // meta-types (QMetaType::LongLong).
- switch ((int)qvar->type()) {
- case QVariant::Invalid:
- value->dataType = DTInvalid;
- break;
- case QMetaType::QUrl:
- *qvar = qvar->value<QUrl>().toString();
- // fallthrough
- case QMetaType::QString:
- {
- value->dataType = DTString;
- QByteArray ba = qvar->toByteArray();
- *(char**)(value->data) = local_strdup(ba.constData());
- value->len = ba.size();
- break;
- }
- case QMetaType::Bool:
- value->dataType = DTBool;
- *(qint8*)(value->data) = (qint8)qvar->toInt();
- break;
- case QMetaType::LongLong:
- // Some of these entries will have to be fixed when handling platforms
- // where sizeof(long long) != 8 or sizeof(int) != 4.
- value->dataType = DTInt64;
- *(qint64*)(value->data) = qvar->toLongLong();
- break;
- case QMetaType::ULongLong:
- value->dataType = DTUint64;
- *(quint64*)(value->data) = qvar->toLongLong();
- break;
- case QMetaType::Int:
- value->dataType = DTInt32;
- *(qint32*)(value->data) = qvar->toInt();
- break;
- case QMetaType::UInt:
- value->dataType = DTUint32;
- *(quint32*)(value->data) = qvar->toUInt();
- break;
- case QMetaType::VoidStar:
- value->dataType = DTUintptr;
- *(uintptr_t*)(value->data) = (uintptr_t)qvar->value<void *>();
- break;
- case QMetaType::Double:
- value->dataType = DTFloat64;
- *(double*)(value->data) = qvar->toDouble();
- break;
- case QMetaType::Float:
- value->dataType = DTFloat32;
- *(float*)(value->data) = qvar->toFloat();
- break;
- case QMetaType::QColor:
- value->dataType = DTColor;
- *(unsigned int*)(value->data) = qvar->value<QColor>().rgba();
- break;
- case QMetaType::QVariantList:
- {
- QVariantList varlist = qvar->toList();
- int len = varlist.size();
- DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
- for (int i = 0; i < len; i++) {
- packDataValue((void*)&varlist.at(i), &dvlist[i]);
- }
- value->dataType = DTValueList;
- value->len = len;
- *(DataValue**)(value->data) = dvlist;
- }
- break;
- case QMetaType::QVariantMap:
- {
- QVariantMap varmap = qvar->toMap();
- int len = varmap.size() * 2;
- DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
- QMapIterator<QString, QVariant> it(varmap);
- for (int i = 0; i < len; i += 2) {
- if (!it.hasNext()) {
- panicf("QVariantMap mutated during iteration");
- }
- it.next();
- QVariant key = it.key();
- QVariant val = it.value();
- packDataValue((void*)&key, &dvlist[i]);
- packDataValue((void*)&val, &dvlist[i+1]);
- }
- value->dataType = DTValueMap;
- value->len = len;
- *(DataValue**)(value->data) = dvlist;
- }
- break;
- case QMetaType::User:
- {
- static const int qjstype = QVariant::fromValue(QJSValue()).userType();
- if (qvar->userType() == qjstype) {
- auto var = qvar->value<QJSValue>().toVariant();
- packDataValue(&var, value);
- }
- }
- break;
- default:
- if (qvar->type() == (int)QMetaType::QObjectStar || qvar->canConvert<QObject *>()) {
- QObject *qobject = qvar->value<QObject *>();
- GoValue *goValue = dynamic_cast<GoValue *>(qobject);
- if (goValue) {
- value->dataType = DTGoAddr;
- *(void **)(value->data) = goValue->addr;
- break;
- }
- GoPaintedValue *goPaintedValue = dynamic_cast<GoPaintedValue *>(qobject);
- if (goPaintedValue) {
- value->dataType = DTGoAddr;
- *(void **)(value->data) = goPaintedValue->addr;
- break;
- }
- value->dataType = DTObject;
- *(void **)(value->data) = qobject;
- break;
- }
- {
- QQmlListReference ref = qvar->value<QQmlListReference>();
- if (ref.isValid() && ref.canCount() && ref.canAt()) {
- int len = ref.count();
- DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
- QVariant elem;
- for (int i = 0; i < len; i++) {
- elem.setValue(ref.at(i));
- packDataValue(&elem, &dvlist[i]);
- }
- value->dataType = DTValueList;
- value->len = len;
- *(DataValue**)(value->data) = dvlist;
- break;
- }
- }
- if (qstrncmp(qvar->typeName(), "QQmlListProperty<", 17) == 0) {
- QQmlListProperty<QObject> *list = reinterpret_cast<QQmlListProperty<QObject>*>(qvar->data());
- if (list->count && list->at) {
- int len = list->count(list);
- DataValue *dvlist = (DataValue *) malloc(sizeof(DataValue) * len);
- QVariant elem;
- for (int i = 0; i < len; i++) {
- elem.setValue(list->at(list, i));
- packDataValue(&elem, &dvlist[i]);
- }
- value->dataType = DTValueList;
- value->len = len;
- *(DataValue**)(value->data) = dvlist;
- break;
- }
- }
- panicf("unsupported variant type: %d (%s)", qvar->type(), qvar->typeName());
- break;
- }
-}
-
-QVariantList_ *newVariantList(DataValue *list, int len)
-{
- QVariantList *vlist = new QVariantList();
- vlist->reserve(len);
- for (int i = 0; i < len; i++) {
- QVariant var;
- unpackDataValue(&list[i], &var);
- vlist->append(var);
- }
- return vlist;
-}
-
-QObject *listPropertyAt(QQmlListProperty<QObject> *list, int i)
-{
- return reinterpret_cast<QObject *>(hookListPropertyAt(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2, i));
-}
-
-int listPropertyCount(QQmlListProperty<QObject> *list)
-{
- return hookListPropertyCount(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2);
-}
-
-void listPropertyAppend(QQmlListProperty<QObject> *list, QObject *obj)
-{
- hookListPropertyAppend(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2, obj);
-}
-
-void listPropertyClear(QQmlListProperty<QObject> *list)
-{
- hookListPropertyClear(list->data, (intptr_t)list->dummy1, (intptr_t)list->dummy2);
-}
-
-QQmlListProperty_ *newListProperty(GoAddr *addr, intptr_t reflectIndex, intptr_t setIndex)
-{
- QQmlListProperty<QObject> *list = new QQmlListProperty<QObject>();
- list->data = addr;
- list->dummy1 = (void*)reflectIndex;
- list->dummy2 = (void*)setIndex;
- list->at = listPropertyAt;
- list->count = listPropertyCount;
- list->append = listPropertyAppend;
- list->clear = listPropertyClear;
- return list;
-}
-
-void internalLogHandler(QtMsgType severity, const QMessageLogContext &context, const QString &text)
-{
- if (context.file == NULL) return;
-
- QByteArray textba = text.toUtf8();
- LogMessage message = {severity, textba.constData(), textba.size(), context.file, (int)strlen(context.file), context.line};
- hookLogHandler(&message);
-}
-
-void installLogHandler()
-{
- qInstallMessageHandler(internalLogHandler);
-}
-
-
-extern bool qRegisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data);
-extern bool qUnregisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data);
-
-void registerResourceData(int version, char *tree, char *name, char *data)
-{
- qRegisterResourceData(version, (unsigned char*)tree, (unsigned char*)name, (unsigned char*)data);
-}
-
-void unregisterResourceData(int version, char *tree, char *name, char *data)
-{
- qUnregisterResourceData(version, (unsigned char*)tree, (unsigned char*)name, (unsigned char*)data);
-}
-
-// vim:ts=4:sw=4:et:ft=cpp