Commit 2344456b authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

CDB: Support for displaying QImage.



Change-Id: Ic1a4a0e6767a0cecb1fd869bbcfd9673854631aa
Reviewed-by: default avatarhjk <qthjk@ovi.com>
Reviewed-by: default avatarFriedemann Kleint <Friedemann.Kleint@digia.com>
parent 99f54235
......@@ -80,7 +80,7 @@ enum KnownType
KT_QUrl = KT_Qt_Type + KT_Qt_MovableType + 31 + KT_HasSimpleDumper,
KT_QIcon = KT_Qt_Type + KT_Qt_MovableType + 32,
KT_QBrush = KT_Qt_Type + KT_Qt_MovableType + 33,
KT_QImage = KT_Qt_Type + KT_Qt_MovableType + 35,
KT_QImage = KT_Qt_Type + KT_HasSimpleDumper + KT_Qt_MovableType + 35,
KT_QLocale = KT_Qt_Type + KT_Qt_MovableType + 36,
KT_QMatrix = KT_Qt_Type + KT_Qt_MovableType + 37,
KT_QRegExp = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 38,
......
......@@ -2066,6 +2066,70 @@ static bool dumpQDateTime(const SymbolGroupValue &v, std::wostream &str)
return true;
}
static bool dumpQImage(const SymbolGroupValue &v, std::wostream &str, MemoryHandle **memoryHandle)
{
struct CreatorImageHeader { // Header for image display as edit format, followed by data.
int width;
int height;
int format;
};
const QtInfo &qtInfo(QtInfo::get(v.context()));
// Fetch data of unexported private class
const ULONG64 address = v["d"].pointerValue();
if (!address) {
str << L"<null>";
return true;
}
const std::string qImageDataType = qtInfo.prependQtGuiModule("QImageData");
const unsigned long size = SymbolGroupValue::sizeOf(qImageDataType.c_str());
if (!size)
return false;
unsigned char *qImageData = SymbolGroupValue::readMemory(v.context().dataspaces, address, size);
if (!qImageData)
return false;
// read size data
unsigned char *ptr = qImageData + qAtomicIntSize(v.context());
CreatorImageHeader header;
header.width = *(reinterpret_cast<int *>(ptr));
ptr += SymbolGroupValue::intSize();
header.height = *(reinterpret_cast<int *>(ptr));
ptr += SymbolGroupValue::intSize();
const int depth = *(reinterpret_cast<int *>(ptr));
ptr += SymbolGroupValue::intSize();
const int nbytes = *(reinterpret_cast<int *>(ptr));
const unsigned dataOffset = SymbolGroupValue::fieldOffset(qImageDataType.c_str(), "data");
// Qt 4 has a Qt 3 support pointer member between 'data' and 'format'.
const unsigned formatOffset = SymbolGroupValue::fieldOffset(qImageDataType.c_str(), "format");
if (!dataOffset || !formatOffset)
return false;
ptr = qImageData + dataOffset;
// read data pointer
ULONG64 data = 0;
memcpy(&data, ptr, SymbolGroupValue::pointerSize());
// read format
ptr = qImageData + formatOffset;
header.format = *(reinterpret_cast<int *>(ptr));
if (header.width < 0 || header.height < 0 || header.format < 0 || header.format > 255
|| nbytes < 0 || depth < 0) {
return false;
}
str << header.width << L'x' << header.height << L", depth: " << depth
<< L", format: " << header.format << L", "
<< nbytes << L" bytes @0x" << std::hex << data << std::dec;
delete [] qImageData;
// Create Creator Image data for display if reasonable size
if (memoryHandle && data && nbytes > 0 && nbytes < 205824) {
if (unsigned char *imageData = SymbolGroupValue::readMemory(v.context().dataspaces, data, nbytes)) {
unsigned char *creatorImageData = new unsigned char[sizeof(CreatorImageHeader) + nbytes];
memcpy(creatorImageData, &header, sizeof(CreatorImageHeader));
memcpy(creatorImageData + sizeof(CreatorImageHeader), imageData, nbytes);
delete [] imageData;
*memoryHandle = new MemoryHandle(creatorImageData, sizeof(CreatorImageHeader) + nbytes);
}
}
return true;
}
// Dump a rectangle in X11 syntax
template <class T>
inline void dumpRect(std::wostream &str, T x, T y, T width, T height)
......@@ -2564,6 +2628,9 @@ unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx,
case KT_QLineF:
rc = dumpQLine_F(v, str) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed;
break;
case KT_QImage:
rc = dumpQImage(v, str, memoryHandleIn) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed;
break;
case KT_QRect:
rc = dumpQRect(v, str) ? SymbolGroupNode::SimpleDumperOk : SymbolGroupNode::SimpleDumperFailed;
break;
......@@ -2654,6 +2721,11 @@ bool dumpEditValue(const SymbolGroupNode *n, const SymbolGroupValueContext &,
if (const MemoryHandle *mh = n->memory())
formatEditValue(DisplayLatin1String, mh, str);
break;
case KT_QImage:
if (desiredFormat == 1) // Image.
if (const MemoryHandle *mh = n->memory())
formatEditValue(DisplayImageData, mh, str);
break;
}
return true;
}
......
......@@ -625,14 +625,19 @@ void CdbEngine::setupEngine()
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupFailed")
notifyEngineSetupFailed();
}
const QString normalFormat = tr("Normal");
const QStringList stringFormats = QStringList()
<< tr("Normal") << tr("Separate Window");
<< normalFormat << tr("Separate Window");
WatchHandler *wh = watchHandler();
wh->addTypeFormats("QString", stringFormats);
wh->addTypeFormats("QString *", stringFormats);
wh->addTypeFormats("QByteArray", stringFormats);
wh->addTypeFormats("QByteArray *", stringFormats);
wh->addTypeFormats("std__basic_string", stringFormats); // Python dumper naming convention for std::[w]string
const QStringList imageFormats = QStringList()
<< normalFormat << tr("Image");
wh->addTypeFormats("QImage", imageFormats);
wh->addTypeFormats("QImage *", imageFormats);
}
bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessage)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment