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
const char *qtCursorShapeToStr(Qt::CursorShape shape)
57
case Qt::UpArrowCursor:
65
case Qt::SizeVerCursor:
67
case Qt::SizeHorCursor:
69
case Qt::SizeBDiagCursor:
71
case Qt::SizeFDiagCursor:
73
case Qt::SizeAllCursor:
77
case Qt::SplitVCursor:
79
case Qt::SplitHCursor:
81
case Qt::PointingHandCursor:
82
return "PointingHand";
83
case Qt::ForbiddenCursor:
85
case Qt::WhatsThisCursor:
89
case Qt::OpenHandCursor:
91
case Qt::ClosedHandCursor:
93
case Qt::DragCopyCursor:
95
case Qt::DragMoveCursor:
97
case Qt::DragLinkCursor:
99
case Qt::BitmapCursor:
105
} // anonymous namespace
107
void UbuntuCursor::changeCursor(QCursor *windowCursor, QWindow *window)
113
MirSurface *surface = static_cast<UbuntuWindow*>(window->handle())->mirSurface();
121
qCDebug(ubuntumirclient, "changeCursor shape=%s, window=%p", qtCursorShapeToStr(windowCursor->shape()), window);
122
if (!windowCursor->pixmap().isNull()) {
123
configureMirCursorWithPixmapQCursor(surface, *windowCursor);
124
} else if (windowCursor->shape() == Qt::BitmapCursor) {
125
// TODO: Implement bitmap cursor support
126
applyDefaultCursorConfiguration(surface);
128
const auto &cursorName = mShapeToCursorName.value(windowCursor->shape(), QByteArray("left_ptr"));
129
auto cursorConfiguration = mir_cursor_configuration_from_name(cursorName.data());
130
mir_surface_configure_cursor(surface, cursorConfiguration);
131
mir_cursor_configuration_destroy(cursorConfiguration);
134
applyDefaultCursorConfiguration(surface);
139
void UbuntuCursor::configureMirCursorWithPixmapQCursor(MirSurface *surface, QCursor &cursor)
141
QImage image = cursor.pixmap().toImage();
143
if (image.format() != QImage::Format_ARGB32) {
144
image.convertToFormat(QImage::Format_ARGB32);
147
MirBufferStream *bufferStream = mir_connection_create_buffer_stream_sync(mConnection,
148
image.width(), image.height(), mir_pixel_format_argb_8888, mir_buffer_usage_software);
151
MirGraphicsRegion region;
152
mir_buffer_stream_get_graphics_region(bufferStream, ®ion);
154
char *regionLine = region.vaddr;
155
Q_ASSERT(image.bytesPerLine() <= region.stride);
156
for (int i = 0; i < image.height(); ++i) {
157
memcpy(regionLine, image.scanLine(i), image.bytesPerLine());
158
regionLine += region.stride;
162
mir_buffer_stream_swap_buffers_sync(bufferStream);
165
auto configuration = mir_cursor_configuration_from_buffer_stream(bufferStream, cursor.hotSpot().x(), cursor.hotSpot().y());
166
mir_surface_configure_cursor(surface, configuration);
167
mir_cursor_configuration_destroy(configuration);
170
mir_buffer_stream_release_sync(bufferStream);
173
void UbuntuCursor::applyDefaultCursorConfiguration(MirSurface *surface)
175
auto cursorConfiguration = mir_cursor_configuration_from_name("left_ptr");
176
mir_surface_configure_cursor(surface, cursorConfiguration);
177
mir_cursor_configuration_destroy(cursorConfiguration);