2
* Copyright (C) 2015 Canonical, Ltd.
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU Lesser General Public License version 3, as published by
6
* the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include <mir_toolkit/mir_client_library.h>
24
UbuntuCursor::UbuntuCursor(MirConnection *connection)
25
: mConnection(connection)
27
mShapeToCursorName[Qt::ArrowCursor] = "left_ptr";
28
mShapeToCursorName[Qt::UpArrowCursor] = "up_arrow";
29
mShapeToCursorName[Qt::CrossCursor] = "cross";
30
mShapeToCursorName[Qt::WaitCursor] = "watch";
31
mShapeToCursorName[Qt::IBeamCursor] = "xterm";
32
mShapeToCursorName[Qt::SizeVerCursor] = "size_ver";
33
mShapeToCursorName[Qt::SizeHorCursor] = "size_hor";
34
mShapeToCursorName[Qt::SizeBDiagCursor] = "size_bdiag";
35
mShapeToCursorName[Qt::SizeFDiagCursor] = "size_fdiag";
36
mShapeToCursorName[Qt::SizeAllCursor] = "size_all";
37
mShapeToCursorName[Qt::BlankCursor] = "blank";
38
mShapeToCursorName[Qt::SplitVCursor] = "split_v";
39
mShapeToCursorName[Qt::SplitHCursor] = "split_h";
40
mShapeToCursorName[Qt::PointingHandCursor] = "hand";
41
mShapeToCursorName[Qt::ForbiddenCursor] = "forbidden";
42
mShapeToCursorName[Qt::WhatsThisCursor] = "whats_this";
43
mShapeToCursorName[Qt::BusyCursor] = "left_ptr_watch";
44
mShapeToCursorName[Qt::OpenHandCursor] = "openhand";
45
mShapeToCursorName[Qt::ClosedHandCursor] = "closedhand";
46
mShapeToCursorName[Qt::DragCopyCursor] = "dnd-copy";
47
mShapeToCursorName[Qt::DragMoveCursor] = "dnd-move";
48
mShapeToCursorName[Qt::DragLinkCursor] = "dnd-link";
52
#if !defined(QT_NO_DEBUG)
53
const char *qtCursorShapeToStr(Qt::CursorShape shape)
58
case Qt::UpArrowCursor:
66
case Qt::SizeVerCursor:
68
case Qt::SizeHorCursor:
70
case Qt::SizeBDiagCursor:
72
case Qt::SizeFDiagCursor:
74
case Qt::SizeAllCursor:
78
case Qt::SplitVCursor:
80
case Qt::SplitHCursor:
82
case Qt::PointingHandCursor:
83
return "PointingHand";
84
case Qt::ForbiddenCursor:
86
case Qt::WhatsThisCursor:
90
case Qt::OpenHandCursor:
92
case Qt::ClosedHandCursor:
94
case Qt::DragCopyCursor:
96
case Qt::DragMoveCursor:
98
case Qt::DragLinkCursor:
100
case Qt::BitmapCursor:
106
#endif // !defined(QT_NO_DEBUG)
107
} // anonymous namespace
109
void UbuntuCursor::changeCursor(QCursor *windowCursor, QWindow *window)
115
MirSurface *surface = static_cast<UbuntuWindow*>(window->handle())->mirSurface();
123
DLOG("[ubuntumirclient QPA] changeCursor shape=%s, window=%p\n", qtCursorShapeToStr(windowCursor->shape()), window);
124
if (!windowCursor->pixmap().isNull()) {
125
configureMirCursorWithPixmapQCursor(surface, *windowCursor);
126
} else if (windowCursor->shape() == Qt::BitmapCursor) {
127
// TODO: Implement bitmap cursor support
128
applyDefaultCursorConfiguration(surface);
130
const auto &cursorName = mShapeToCursorName.value(windowCursor->shape(), QByteArray("left_ptr"));
131
auto cursorConfiguration = mir_cursor_configuration_from_name(cursorName.data());
132
mir_surface_configure_cursor(surface, cursorConfiguration);
133
mir_cursor_configuration_destroy(cursorConfiguration);
136
applyDefaultCursorConfiguration(surface);
141
void UbuntuCursor::configureMirCursorWithPixmapQCursor(MirSurface *surface, QCursor &cursor)
143
QImage image = cursor.pixmap().toImage();
145
if (image.format() != QImage::Format_ARGB32) {
146
image.convertToFormat(QImage::Format_ARGB32);
149
MirBufferStream *bufferStream = mir_connection_create_buffer_stream_sync(mConnection,
150
image.width(), image.height(), mir_pixel_format_argb_8888, mir_buffer_usage_software);
153
MirGraphicsRegion region;
154
mir_buffer_stream_get_graphics_region(bufferStream, ®ion);
156
char *regionLine = region.vaddr;
157
Q_ASSERT(image.bytesPerLine() <= region.stride);
158
for (int i = 0; i < image.height(); ++i) {
159
memcpy(regionLine, image.scanLine(i), image.bytesPerLine());
160
regionLine += region.stride;
164
mir_buffer_stream_swap_buffers_sync(bufferStream);
167
auto configuration = mir_cursor_configuration_from_buffer_stream(bufferStream, cursor.hotSpot().x(), cursor.hotSpot().y());
168
mir_surface_configure_cursor(surface, configuration);
169
mir_cursor_configuration_destroy(configuration);
172
mir_buffer_stream_release_sync(bufferStream);
175
void UbuntuCursor::applyDefaultCursorConfiguration(MirSurface *surface)
177
auto cursorConfiguration = mir_cursor_configuration_from_name("left_ptr");
178
mir_surface_configure_cursor(surface, cursorConfiguration);
179
mir_cursor_configuration_destroy(cursorConfiguration);