17 #include "CursorImageProvider.h"
22 #include <QSvgRenderer>
24 CursorImageProvider *CursorImageProvider::m_instance =
nullptr;
29 BuiltInCursorImage::BuiltInCursorImage()
31 const char *svgString =
32 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
34 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\""
35 " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""
36 " xmlns:svg=\"http://www.w3.org/2000/svg\""
37 " xmlns=\"http://www.w3.org/2000/svg\""
40 " style=\"fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:40;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\""
41 " d=\"M 20.504,50.94931 460.42533,518.14486 266.47603,515.61948 366.48114,719.16522 274.05218,770.68296 172.53185,559.56112 20.504,716.13476 Z\" />"
44 qimage = QImage(20, 32, QImage::Format_ARGB32);
45 QPainter imagePainter(&qimage);
47 QSvgRenderer *svgRenderer =
new QSvgRenderer(QByteArray(svgString));
48 svgRenderer->render(&imagePainter);
55 XCursorImage::XCursorImage(
const QString &theme,
const QString &file)
56 : xcursorImages(nullptr)
58 xcursorImages = XcursorLibraryLoadImages(QFile::encodeName(file), QFile::encodeName(theme), 32);
64 for (
int i = 0; i < xcursorImages->nimage && !loaded; ++i) {
65 XcursorImage *xcursorImage = xcursorImages->images[i];
66 if (xcursorImage->size == 32) {
68 qimage = QImage((uchar*)xcursorImage->pixels,
69 xcursorImage->width, xcursorImage->height, QImage::Format_ARGB32);
71 hotspot.setX(xcursorImage->xhot);
72 hotspot.setY(xcursorImage->yhot);
79 XCursorImage::~XCursorImage()
81 XcursorImagesDestroy(xcursorImages);
87 CursorImageProvider::CursorImageProvider()
88 : QQuickImageProvider(QQuickImageProvider::Image)
91 qFatal(
"Cannot have multiple CursorImageProvider instances");
96 CursorImageProvider::~CursorImageProvider()
99 QList< QMap<QString, CursorImage*> > cursorList = m_cursors.values();
101 for (
int i = 0; i < cursorList.count(); ++i) {
102 QList<CursorImage*> cursorImageList = cursorList[i].values();
103 for (
int j = 0; j < cursorImageList.count(); ++j) {
104 delete cursorImageList[j];
110 m_instance =
nullptr;
113 QImage CursorImageProvider::requestImage(
const QString &cursorThemeAndName, QSize *size,
const QSize & )
115 CursorImage *cursorImage = fetchCursor(cursorThemeAndName);
116 size->setWidth(cursorImage->qimage.width());
117 size->setHeight(cursorImage->qimage.height());
119 return cursorImage->qimage;
122 QPoint CursorImageProvider::hotspot(
const QString &themeName,
const QString &cursorName)
124 CursorImage *cursorImage = fetchCursor(themeName, cursorName);
126 return cursorImage->hotspot;
132 CursorImage *CursorImageProvider::fetchCursor(
const QString &cursorThemeAndName)
137 QStringList themeAndNameList = cursorThemeAndName.split(
"/");
138 if (themeAndNameList.size() != 2) {
141 themeName = themeAndNameList[0];
142 cursorName = themeAndNameList[1];
145 return fetchCursor(themeName, cursorName);
148 CursorImage *CursorImageProvider::fetchCursor(
const QString &themeName,
const QString &cursorName)
150 CursorImage *cursorImage = fetchCursorHelper(themeName, cursorName);
153 if (cursorImage->qimage.isNull()) {
154 if (cursorName ==
"ibeam") {
155 qDebug() <<
"CursorImageProvider: \"ibeam\" not found, falling back to \"xterm\"";
156 cursorImage = fetchCursorHelper(themeName,
"xterm");
157 }
else if (cursorName ==
"xterm") {
158 qDebug() <<
"CursorImageProvider: \"xterm\" not found, falling back to \"ibeam\"";
159 cursorImage = fetchCursorHelper(themeName,
"ibeam");
164 if (cursorImage->qimage.isNull() && cursorName !=
"left_ptr") {
165 qDebug() <<
"CursorImageProvider:" << cursorName
166 <<
"not found (nor its fallbacks, if any). Going for \"left_ptr\" as a last resort.";
167 cursorImage = fetchCursorHelper(themeName,
"left_ptr");
170 if (cursorImage->qimage.isNull()) {
172 qWarning() <<
"CursorImageProvider: couldn't find any cursors. Using the built-in one";
173 if (!m_builtInCursorImage) {
174 m_builtInCursorImage.reset(
new BuiltInCursorImage);
176 cursorImage = m_builtInCursorImage.data();
182 CursorImage *CursorImageProvider::fetchCursorHelper(
const QString &themeName,
const QString &cursorName)
184 QMap<QString, CursorImage*> &themeCursors = m_cursors[themeName];
186 if (!themeCursors.contains(cursorName)) {
187 themeCursors[cursorName] =
new XCursorImage(themeName, cursorName);
190 return themeCursors[cursorName];