static xcb_cursor_t create_empty_cursor(xcb_connection_t *conn, xcb_screen_t *screen) { xcb_cursor_t cursor = xcb_generate_id(conn); xcb_pixmap_t pixmap = xcb_generate_id(conn); xcb_create_pixmap_checked(conn, 1, pixmap, screen->root, 1, 1); xcb_create_cursor(conn, cursor, pixmap, pixmap, 0, 0, 0, 0, 0, 0, 0, 0); return cursor; }
void createBlankCursor() { cursor = xcb_generate_id(connection); xcb_pixmap_t pix = xcb_generate_id(connection); xcb_create_pixmap(connection, 1, pix, screen->root, 1, 1); xcb_create_cursor(connection, cursor, pix, pix, 0, 0, 0, 0, 0, 0, 1, 1); }
static void towel_window_hide_cursor(towel_window_t *win) { xcb_cursor_t cur = xcb_generate_id (win->conn); xcb_pixmap_t pix = xcb_generate_id (win->conn); xcb_create_pixmap(win->conn, 1, pix, win->screen->root, 1, 1); xcb_create_cursor(win->conn, cur, pix, pix, 0, 0, 0, 0, 0, 0, 0, 0); xcb_change_window_attributes(win->conn, win->id, XCB_CW_CURSOR, &(uint32_t){cur}); xcb_free_pixmap(win->conn, pix); }
internal void load_and_set_cursor(hhxcb_context *context) { context->cursor_pixmap_id = xcb_generate_id(context->connection); xcb_create_pixmap(context->connection, /*depth*/ 1, context->cursor_pixmap_id, context->window, /*width*/ 1, /*height*/ 1); context->cursor_id = xcb_generate_id(context->connection); xcb_create_cursor(context->connection, context->cursor_id, context->cursor_pixmap_id, context->cursor_pixmap_id, 0, 0, 0, 0, 0, 0, 0, 0); uint32_t values[1] = { context->cursor_id }; xcb_change_window_attributes( context->connection, context->window, XCB_CW_CURSOR, values); }
xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor) { xcb_connection_t *conn = xcb_connection(); QPoint spot = cursor->hotSpot(); xcb_cursor_t c = XCB_NONE; if (cursor->pixmap().depth() > 1) c = qt_xcb_createCursorXRender(m_screen, cursor->pixmap().toImage(), spot); if (!c) { xcb_pixmap_t cp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->bitmap()->toImage()); xcb_pixmap_t mp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->mask()->toImage()); c = xcb_generate_id(conn); xcb_create_cursor(conn, c, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, spot.x(), spot.y()); xcb_free_pixmap(conn, cp); xcb_free_pixmap(conn, mp); } return c; }
xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice) { xcb_pixmap_t bitmap; xcb_pixmap_t mask; xcb_cursor_t cursor; unsigned char *curs_bits; unsigned char *mask_bits; int curs_w, curs_h; switch (choice) { case CURS_NONE: curs_bits = curs_invisible_bits; mask_bits = curs_invisible_bits; curs_w = curs_invisible_width; curs_h = curs_invisible_height; break; case CURS_WIN: curs_bits = curs_windows_bits; mask_bits = mask_windows_bits; curs_w = curs_windows_width; curs_h = curs_windows_height; break; case CURS_DEFAULT: default: return XCB_NONE; /* XCB_NONE is xcb's way of saying "don't change the cursor" */ } bitmap = xcb_create_pixmap_from_bitmap_data(conn, win, curs_bits, curs_w, curs_h, 1, screen->white_pixel, screen->black_pixel, NULL); mask = xcb_create_pixmap_from_bitmap_data(conn, win, mask_bits, curs_w, curs_h, 1, screen->white_pixel, screen->black_pixel, NULL); cursor = xcb_generate_id(conn); xcb_create_cursor(conn, cursor, bitmap, mask, 65535, 65535, 65535, 0, 0, 0, 0, 0); xcb_free_pixmap(conn, bitmap); xcb_free_pixmap(conn, mask); return cursor; }
xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape) { xcb_cursor_t cursor = 0; xcb_connection_t *conn = xcb_connection(); if (cshape == Qt::BlankCursor) { xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16, 1, 0, 0, 0); xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16, 1, 0, 0, 0); cursor = xcb_generate_id(conn); xcb_create_cursor(conn, cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8); } else if (cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor) { int i = (cshape - Qt::SizeVerCursor) * 2; xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), const_cast<uint8_t*>(cursor_bits16[i]), 16, 16, 1, 0, 0, 0); xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), const_cast<uint8_t*>(cursor_bits16[i + 1]), 16, 16, 1, 0, 0, 0); cursor = xcb_generate_id(conn); xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8); } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor) || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) { int i = (cshape - Qt::SplitVCursor) * 2; xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), const_cast<uint8_t*>(cursor_bits32[i]), 32, 32, 1, 0, 0, 0); xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), const_cast<uint8_t*>(cursor_bits32[i + 1]), 32, 32, 1, 0, 0, 0); int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) ? 0 : 16; cursor = xcb_generate_id(conn); xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, hs, hs); } else if (cshape == Qt::ForbiddenCursor) { int i = (cshape - Qt::ForbiddenCursor) * 2; xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), const_cast<uint8_t*>(cursor_bits20[i]), 20, 20, 1, 0, 0, 0); xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), const_cast<uint8_t*>(cursor_bits20[i + 1]), 20, 20, 1, 0, 0, 0); cursor = xcb_generate_id(conn); xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 10, 10); } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) { bool open = cshape == Qt::OpenHandCursor; xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), const_cast<uint8_t*>(open ? openhand_bits : closedhand_bits), 16, 16, 1, 0, 0, 0); xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), const_cast<uint8_t*>(open ? openhandm_bits : closedhandm_bits), 16, 16, 1, 0, 0, 0); cursor = xcb_generate_id(conn); xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8); } else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor || cshape == Qt::DragLinkCursor) { QImage image = QGuiApplicationPrivate::instance()->getPixmapCursor(static_cast<Qt::CursorShape>(cshape)).toImage(); if (!image.isNull()) { xcb_pixmap_t pm = qt_xcb_XPixmapFromBitmap(m_screen, image); xcb_pixmap_t pmm = qt_xcb_XPixmapFromBitmap(m_screen, image.createAlphaMask()); cursor = xcb_generate_id(conn); xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8); xcb_free_pixmap(conn, pm); xcb_free_pixmap(conn, pmm); } } return cursor; }
//Output X11Output::X11Output(X11Backend& backend, unsigned int id, const nytl::Vec2i& pos, const nytl::Vec2ui& size) : Output(backend.compositor(), id, pos, size), backend_(&backend) { xcb_connection_t* connection = backend.xConnection(); xcb_screen_t* screen = backend.xScreen(); unsigned int mask = XCB_CW_EVENT_MASK; unsigned int values = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE; xWindow_ = xcb_generate_id(connection); xcb_create_window(connection, XCB_COPY_FROM_PARENT, xWindow_, screen->root, 0, 0, size_.x, size_.y ,10, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, &values); if(!xWindow_) { throw std::runtime_error("could not create xcb window"); return; } xcb_change_property(connection, XCB_PROP_MODE_REPLACE, xWindow_, atoms::protocols, XCB_ATOM_ATOM, 32, 1, &atoms::deleteWindow); //cant be resized xcb_size_hints_t sizeHints; sizeHints.max_width = size_.x; sizeHints.max_height = size_.y; sizeHints.min_width = size_.x; sizeHints.min_height = size_.y; sizeHints.flags = XCB_ICCCM_SIZE_HINT_P_MIN_SIZE | XCB_ICCCM_SIZE_HINT_P_MAX_SIZE; xcb_icccm_set_wm_size_hints(connection, xWindow_, XCB_ATOM_WM_NORMAL_HINTS, &sizeHints); //no mouse cursor xcb_pixmap_t cursorPixmap = xcb_generate_id(connection); xcb_create_pixmap(connection, 1, cursorPixmap, xWindow_, 1, 1); xcb_cursor_t hiddenCursor = xcb_generate_id(connection); xcb_create_cursor(connection, hiddenCursor, cursorPixmap, cursorPixmap, 0, 0, 0, 0, 0, 0, 0, 0); xcb_free_pixmap(connection, cursorPixmap); xcb_change_window_attributes(connection, xWindow_, XCB_CW_CURSOR, &hiddenCursor); xcb_map_window(connection, xWindow_); //EGL if(!backend.eglContext()) { throw std::runtime_error("x11Output::x11Output: backend ha no valid eglcontext"); return; } eglSurface_ = backend.eglContext()->createSurface(xWindow_); if(!eglSurface_) { throw std::runtime_error("x11Output::x11Output: failed to create egl surface"); return; } drawContext_ = std::make_unique<ny::GlDrawContext>(); if(!drawContext_) { throw std::runtime_error("x11Output::x11Output: failed to create ny::GlesDC"); return; } }
static void get_resources (el_backend_x11_t self) { #define F(field) offsetof(struct el_backend_x11, field) static const struct { const char* name; int offset; } atoms[] = { { "WM_PROTOCOLS", F(atom.wm_protocols) }, { "WM_NORMAL_HINTS", F(atom.wm_normal_hints) }, { "WM_SIZE_HINTS", F(atom.wm_size_hints) }, { "WM_DELETE_WINDOW", F(atom.wm_delete_window) }, { "WM_CLASS", F(atom.wm_class) }, { "_NET_WM_NAME", F(atom.net_wm_name) }, { "_NET_WM_ICON", F(atom.net_wm_icon) }, { "_NET_WM_STATE", F(atom.net_wm_state) }, { "_NET_WM_STATE_FULLSCREEN", F(atom.net_wm_state_fullscreen) }, { "_NET_SUPPORTING_WM_CHECK", F(atom.net_supporting_wm_check) }, { "_NET_SUPPORTED", F(atom.net_supported) }, { "_XKB_RULES_NAMES", F(atom.xkb_names) }, { "STRING", F(atom.string) }, { "UTF8_STRING", F(atom.utf8_string) }, { "CARDINAL", F(atom.cardinal) }, }; #undef F uint8_t data[] = { 0, 0, 0, 0 }; xcb_intern_atom_cookie_t cookies[lengthof(atoms)]; for (size_t i = 0; i < lengthof(atoms); i++) { cookies[i] = xcb_intern_atom(self->connection, 0, strlen(atoms[i].name), atoms[i].name); } for (size_t i = 0; i < lengthof(atoms); i++) { xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(self->connection, cookies[i], NULL); *(xcb_atom_t*) ((char*) self + atoms[i].offset) = reply->atom; free(reply); } xcb_pixmap_t pixmap = xcb_generate_id(self->connection); xcb_gc_t gc = xcb_generate_id(self->connection); xcb_create_pixmap(self->connection, 1, pixmap, self->screen->root, 1, 1); xcb_create_gc(self->connection, gc, pixmap, 0, NULL); xcb_put_image(self->connection, XCB_IMAGE_FORMAT_XY_PIXMAP, pixmap, gc, 1, 1, 0, 0, 0, 32, sizeof(data), data); self->cursor = xcb_generate_id(self->connection); xcb_create_cursor(self->connection, self->cursor, pixmap, pixmap, 0, 0, 0, 0, 0, 0, 1, 1); xcb_free_gc(self->connection, gc); xcb_free_pixmap(self->connection, pixmap); }