70 QImage::Format *imageFormat,
bool *needsRgbSwap)
72 Q_ASSERT(connection && visual && imageFormat);
75 *needsRgbSwap =
false;
76 *imageFormat = QImage::Format_Invalid;
79 if (visual->_class == XCB_VISUAL_CLASS_GRAY_SCALE) {
80 *imageFormat = QImage::Format_Grayscale8;
83#if QT_CONFIG(xcb_native_painting)
84 if (QXcbIntegration::instance() && QXcbIntegration::instance()->nativePaintingEnabled()) {
85 *imageFormat = QImage::Format_Indexed8;
92 const xcb_format_t *format = connection->formatForDepth(depth);
96 const bool connectionEndianSwap = connection->imageNeedsEndianSwap();
98 const quint32 red_mask = connectionEndianSwap ? qbswap(visual->red_mask) : visual->red_mask;
99 const quint32 blue_mask = connectionEndianSwap ? qbswap(visual->blue_mask) : visual->blue_mask;
101 *imageFormat = imageFormatForMasks(depth, format->bits_per_pixel, red_mask, blue_mask);
102 if (*imageFormat != QImage::Format_Invalid)
106 *imageFormat = imageFormatForMasks(depth, format->bits_per_pixel, blue_mask, red_mask);
107 if (*imageFormat != QImage::Format_Invalid) {
108 *needsRgbSwap =
true;
113 qWarning(
"Unsupported screen format: depth: %d, bits_per_pixel: %d, red_mask: %x, blue_mask: %x", depth, format->bits_per_pixel, red_mask, blue_mask);
119 int width,
int height,
int depth,
120 const xcb_visualtype_t *visual)
122 xcb_connection_t *conn = connection->xcb_connection();
125 0, 0, width, height, 0xffffffff);
130 uint8_t *data = xcb_get_image_data(image_reply.get());
131 uint32_t length = xcb_get_image_data_length(image_reply.get());
135 QImage::Format format;
137 if (qt_xcb_imageFormatForVisual(connection, depth, visual, &format, &needsRgbSwap)) {
138 uint32_t bytes_per_line = length / height;
139 QImage image(
const_cast<uint8_t *>(data), width, height, bytes_per_line, format);
142 image =
std::move(image).rgbSwapped();
145 if (format == QImage::Format_RGB32 || format == QImage::Format_RGBX8888) {
146 QRgb *p = (QRgb *)image.bits();
147 for (
int y = 0; y < height; ++y) {
148 for (
int x = 0; x < width; ++x)
150 p += bytes_per_line / 4;
152 }
else if (format == QImage::Format_BGR30 || format == QImage::Format_RGB30) {
153 QRgb *p = (QRgb *)image.bits();
154 for (
int y = 0; y < height; ++y) {
155 for (
int x = 0; x < width; ++x)
157 p += bytes_per_line / 4;
161 result = QPixmap::fromImage(image.copy());
169 xcb_connection_t *conn = screen->xcb_connection();
170 QImage bitmap = image.convertToFormat(QImage::Format_MonoLSB);
171 const QRgb c0 = QColor(Qt::black).rgb();
172 const QRgb c1 = QColor(Qt::white).rgb();
173 if (bitmap.color(0) == c0 && bitmap.color(1) == c1) {
174 bitmap.invertPixels();
175 bitmap.setColor(0, c1);
176 bitmap.setColor(1, c0);
178 const int width = bitmap.width();
179 const int height = bitmap.height();
180 const qsizetype bytesPerLine = bitmap.bytesPerLine();
181 int destLineSize = width / 8;
184 const uchar *map = bitmap.bits();
185 uint8_t *buf =
new uint8_t[height * destLineSize];
186 for (
int i = 0; i < height; i++)
187 memcpy(buf + (destLineSize * i), map + (bytesPerLine * i), destLineSize);
188 xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, screen->root(), buf,
189 width, height, 1, 0, 0,
nullptr);
197 xcb_connection_t *conn = screen->xcb_connection();
198 const int w = image.width();
199 const int h = image.height();
200 auto formats =
Q_XCB_REPLY(xcb_render_query_pict_formats, conn);
202 qWarning(
"qt_xcb_createCursorXRender: query_pict_formats failed");
205 xcb_render_pictforminfo_t *fmt = xcb_render_util_find_standard_format(formats.get(),
206 XCB_PICT_STANDARD_ARGB_32);
208 qWarning(
"qt_xcb_createCursorXRender: Failed to find format PICT_STANDARD_ARGB_32");
212 QImage img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
213 xcb_image_t *xi = xcb_image_create(w, h, XCB_IMAGE_FORMAT_Z_PIXMAP,
215 QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST,
216 XCB_IMAGE_ORDER_MSB_FIRST,
217 nullptr, 0,
nullptr);
219 qWarning(
"qt_xcb_createCursorXRender: xcb_image_create failed");
222 xi->data = (uint8_t *) malloc(xi->stride * h);
224 qWarning(
"qt_xcb_createCursorXRender: Failed to malloc() image data");
225 xcb_image_destroy(xi);
228 memcpy(xi->data, img.constBits(), img.sizeInBytes());
230 xcb_pixmap_t pix = xcb_generate_id(conn);
231 xcb_create_pixmap(conn, 32, pix, screen->root(), w, h);
233 xcb_render_picture_t pic = xcb_generate_id(conn);
234 xcb_render_create_picture(conn, pic, pix, fmt->id, 0,
nullptr);
236 xcb_gcontext_t gc = xcb_generate_id(conn);
237 xcb_create_gc(conn, gc, pix, 0,
nullptr);
238 xcb_image_put(conn, pix, gc, xi, 0, 0, 0);
239 xcb_free_gc(conn, gc);
241 xcb_cursor_t cursor = xcb_generate_id(conn);
242 xcb_render_create_cursor(conn, cursor, pic, spot.x(), spot.y());
245 xcb_image_destroy(xi);
246 xcb_render_free_picture(conn, pic);
247 xcb_free_pixmap(conn, pix);
QT_BEGIN_NAMESPACE bool qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth, const xcb_visualtype_t *visual, QImage::Format *imageFormat, bool *needsRgbSwap=nullptr)
QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap, int width, int height, int depth, const xcb_visualtype_t *visual)