QImage QXlibScreen::grabWindow(Window window, int x, int y, int w, int h) { if (w == 0 || h ==0) return QImage(); //WinId 0 means the desktop widget if (!window) window = rootWindow(); XWindowAttributes window_attr; if (!XGetWindowAttributes(mDisplay->nativeDisplay(), window, &window_attr)) return QImage(); if (w < 0) w = window_attr.width - x; if (h < 0) h = window_attr.height - y; // Ideally, we should also limit ourselves to the screen area, but the Qt docs say // that it's "unsafe" to go outside the screen, so we can ignore that problem. //We're definitely not optimizing for speed... XImage *xi = XGetImage(mDisplay->nativeDisplay(), window, x, y, w, h, AllPlanes, ZPixmap); if (!xi) return QImage(); //taking a copy to make sure we have ownership -- not fast QImage result = QImage( (uchar*) xi->data, xi->width, xi->height, xi->bytes_per_line, QImage::Format_RGB32 ).copy(); XDestroyImage(xi); return result; }
void X11XRenderBackend::init(bool createOverlay) { if (m_front != XCB_RENDER_PICTURE_NONE) xcb_render_free_picture(connection(), m_front); bool haveOverlay = createOverlay ? m_overlayWindow->create() : (m_overlayWindow->window() != XCB_WINDOW_NONE); if (haveOverlay) { m_overlayWindow->setup(XCB_WINDOW_NONE); ScopedCPointer<xcb_get_window_attributes_reply_t> attribs(xcb_get_window_attributes_reply(connection(), xcb_get_window_attributes_unchecked(connection(), m_overlayWindow->window()), NULL)); if (!attribs) { setFailed("Failed getting window attributes for overlay window"); return; } m_format = XRenderUtils::findPictFormat(attribs->visual); if (m_format == 0) { setFailed("Failed to find XRender format for overlay window"); return; } m_front = xcb_generate_id(connection()); xcb_render_create_picture(connection(), m_front, m_overlayWindow->window(), m_format, 0, NULL); } else { // create XRender picture for the root window m_format = XRenderUtils::findPictFormat(defaultScreen()->root_visual); if (m_format == 0) { setFailed("Failed to find XRender format for root window"); return; // error } m_front = xcb_generate_id(connection()); const uint32_t values[] = {XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS}; xcb_render_create_picture(connection(), m_front, rootWindow(), m_format, XCB_RENDER_CP_SUBWINDOW_MODE, values); } createBuffer(); }
void XRandRScreens::update() { auto fallback = [this]() { m_geometries << QRect(); setCount(1); }; m_geometries.clear(); T resources(rootWindow()); if (resources.isNull()) { fallback(); return; } xcb_randr_crtc_t *crtcs = resources.crtcs(); QVector<Xcb::RandR::CrtcInfo> infos(resources->num_crtcs); for (int i = 0; i < resources->num_crtcs; ++i) { infos[i] = Xcb::RandR::CrtcInfo(crtcs[i], resources->config_timestamp); } for (int i = 0; i < resources->num_crtcs; ++i) { Xcb::RandR::CrtcInfo info(infos.at(i)); const QRect geo = info.rect(); if (geo.isValid()) { m_geometries << geo; } } if (m_geometries.isEmpty()) { fallback(); return; } setCount(m_geometries.count()); }
bool GlxBackend::initBuffer() { if (!initFbConfig()) return false; if (overlayWindow()->create()) { // Try to create double-buffered window in the overlay XVisualInfo* visual = glXGetVisualFromFBConfig(display(), fbconfig); if (!visual) { qCritical() << "Failed to get visual from fbconfig"; return false; } XSetWindowAttributes attrs; attrs.colormap = XCreateColormap(display(), rootWindow(), visual->visual, AllocNone); window = XCreateWindow(display(), overlayWindow()->window(), 0, 0, displayWidth(), displayHeight(), 0, visual->depth, InputOutput, visual->visual, CWColormap, &attrs); glxWindow = glXCreateWindow(display(), fbconfig, window, NULL); overlayWindow()->setup(window); XFree(visual); } else { qCritical() << "Failed to create overlay window"; return false; } int vis_buffer; glXGetFBConfigAttrib(display(), fbconfig, GLX_VISUAL_ID, &vis_buffer); XVisualInfo* visinfo_buffer = glXGetVisualFromFBConfig(display(), fbconfig); qDebug() << "Buffer visual (depth " << visinfo_buffer->depth << "): 0x" << QString::number(vis_buffer, 16); XFree(visinfo_buffer); return true; }
DBusInterface::~DBusInterface() { QDBusConnection::sessionBus().unregisterService(m_serviceName); // KApplication automatically also grabs org.kde.kwin, so it's often been used externally - ensure to free it as well QDBusConnection::sessionBus().unregisterService(QStringLiteral("org.kde.kwin")); xcb_delete_property(connection(), rootWindow(), atoms->kwin_dbus_service); }
void Compositor::startupWithWorkspace() { if (!m_starting) { return; } Q_ASSERT(m_scene); connect(workspace(), &Workspace::destroyed, this, [this] { compositeTimer.stop(); }); claimCompositorSelection(); m_xrrRefreshRate = KWin::currentRefreshRate(); fpsInterval = options->maxFpsInterval(); if (m_scene->syncsToVBlank()) { // if we do vsync, set the fps to the next multiple of the vblank rate vBlankInterval = milliToNano(1000) / m_xrrRefreshRate; fpsInterval = qMax((fpsInterval / vBlankInterval) * vBlankInterval, vBlankInterval); } else vBlankInterval = milliToNano(1); // no sync - DO NOT set "0", would cause div-by-zero segfaults. m_timeSinceLastVBlank = fpsInterval - (options->vBlankTime() + 1); // means "start now" - we don't have even a slight idea when the first vsync will occur scheduleRepaint(); xcb_composite_redirect_subwindows(connection(), rootWindow(), XCB_COMPOSITE_REDIRECT_MANUAL); new EffectsHandlerImpl(this, m_scene); // sets also the 'effects' pointer connect(Workspace::self(), &Workspace::deletedRemoved, m_scene, &Scene::windowDeleted); connect(effects, SIGNAL(screenGeometryChanged(QSize)), SLOT(addRepaintFull())); addRepaintFull(); foreach (Client * c, Workspace::self()->clientList()) { c->setupCompositing(); c->getShadow(); }
void WindowSelector::selectWindowUnderPointer() { Xcb::Pointer pointer(rootWindow()); if (!pointer.isNull() && pointer->child != XCB_WINDOW_NONE) { selectWindowId(pointer->child); } }
// Create the compositing buffer. The root window is not double-buffered, // so it is done manually using this buffer, void SceneXrender::createBuffer() { if (buffer != None) XRenderFreePicture(display(), buffer); Pixmap pixmap = XCreatePixmap(display(), rootWindow(), displayWidth(), displayHeight(), DefaultDepth(display(), DefaultScreen(display()))); buffer = XRenderCreatePicture(display(), pixmap, format, 0, 0); XFreePixmap(display(), pixmap); // The picture owns the pixmap now }
void X11XRenderBackend::createBuffer() { xcb_pixmap_t pixmap = xcb_generate_id(connection()); xcb_create_pixmap(connection(), Xcb::defaultDepth(), pixmap, rootWindow(), displayWidth(), displayHeight()); xcb_render_picture_t b = xcb_generate_id(connection()); xcb_render_create_picture(connection(), b, pixmap, m_format, 0, NULL); xcb_free_pixmap(connection(), pixmap); // The picture owns the pixmap now setBuffer(b); }
// Create the compositing buffer. The root window is not double-buffered, // so it is done manually using this buffer, void SceneXrender::createBuffer() { if (buffer != XCB_RENDER_PICTURE_NONE) xcb_render_free_picture(connection(), buffer); xcb_pixmap_t pixmap = xcb_generate_id(connection()); xcb_create_pixmap(connection(), Xcb::defaultDepth(), pixmap, rootWindow(), displayWidth(), displayHeight()); buffer = xcb_generate_id(connection()); xcb_render_create_picture(connection(), buffer, pixmap, format, 0, NULL); xcb_free_pixmap(connection(), pixmap); // The picture owns the pixmap now }
XRenderPicture xRenderFill(const XRenderColor *xc) { Pixmap pixmap = XCreatePixmap(display(), rootWindow(), 1, 1, 32); XRenderPictureAttributes pa; pa.repeat = True; XRenderPicture fill(pixmap, 32); XFreePixmap(display(), pixmap); XRenderChangePicture(display(), fill, CPRepeat, &pa); XRenderFillRectangle(display(), PictOpSrc, fill, xc, 0, 0, 1, 1); return fill; }
// create destination buffer bool SceneOpenGL::initBuffer() { if (!initBufferConfigs()) return false; if (fbcbuffer_db != NULL && m_overlayWindow->create()) { // we have overlay, try to create double-buffered window in it fbcbuffer = fbcbuffer_db; XVisualInfo* visual = glXGetVisualFromFBConfig(display(), fbcbuffer); XSetWindowAttributes attrs; attrs.colormap = XCreateColormap(display(), rootWindow(), visual->visual, AllocNone); buffer = XCreateWindow(display(), m_overlayWindow->window(), 0, 0, displayWidth(), displayHeight(), 0, visual->depth, InputOutput, visual->visual, CWColormap, &attrs); if (hasGLXVersion(1, 3)) glxbuffer = glXCreateWindow(display(), fbcbuffer, buffer, NULL); else glxbuffer = buffer; m_overlayWindow->setup(buffer); db = true; XFree(visual); } else if (fbcbuffer_nondb != NULL) { // cannot get any double-buffered drawable, will double-buffer using a pixmap fbcbuffer = fbcbuffer_nondb; XVisualInfo* visual = glXGetVisualFromFBConfig(display(), fbcbuffer); XGCValues gcattr; gcattr.subwindow_mode = IncludeInferiors; gcroot = XCreateGC(display(), rootWindow(), GCSubwindowMode, &gcattr); buffer = XCreatePixmap(display(), rootWindow(), displayWidth(), displayHeight(), visual->depth); glxbuffer = glXCreatePixmap(display(), fbcbuffer, buffer, NULL); db = false; XFree(visual); } else { kError(1212) << "Couldn't create output buffer (failed to create overlay window?) !"; return false; // error } int vis_buffer; glXGetFBConfigAttrib(display(), fbcbuffer, GLX_VISUAL_ID, &vis_buffer); XVisualInfo* visinfo_buffer = glXGetVisualFromFBConfig(display(), fbcbuffer); kDebug(1212) << "Buffer visual (depth " << visinfo_buffer->depth << "): 0x" << QString::number(vis_buffer, 16); XFree(visinfo_buffer); return true; }
int main(int argc, char **argv) { Adx a(argc, argv); deluxe = &a; //(void) QApplication::desktop(); prev_x11_event_filter = qApp->setEventFilter(Adx::x11_event_filter); XSelectInput(display(), rootWindow(), KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | KeymapStateMask | ButtonMotionMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | ExposureMask | StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask | PropertyChangeMask); XClearWindow(display(), rootWindow()); XSync(display(), FALSE); return a.exec(); }
void KscreenEffect::switchState() { long value = -1l; if (m_state == StateFadingOut) { m_state = StateFadedOut; value = 2l; } else if (m_state == StateFadingIn) { m_state = StateNormal; value = 0l; } if (value != -1l) { xcb_change_property(connection(), XCB_PROP_MODE_REPLACE, rootWindow(), m_atom, XCB_ATOM_CARDINAL, 32, 1, &value); } }
XRenderPicture::XRenderPicture(QPixmap pix) { if (Extensions::nonNativePixmaps()) { Pixmap xPix = XCreatePixmap(display(), rootWindow(), pix.width(), pix.height(), pix.depth()); QPixmap tempPix = QPixmap::fromX11Pixmap(xPix, QPixmap::ExplicitlyShared); tempPix.fill(Qt::transparent); QPainter p(&tempPix); p.drawPixmap(QPoint(0, 0), pix); p.end(); d = new XRenderPictureData(createPicture(tempPix.handle(), tempPix.depth())); XFreePixmap(display(), xPix); } else { d = new XRenderPictureData(createPicture(pix.handle(), pix.depth())); } }
void WindowButton::updateTip( const char * pTip ) { if ( strlen( pTip ) > 0 && rootWindow() != NULL ) { WindowTip * pWindow = WindowTip::getWindowTip( this ); if ( pWindow != NULL ) pWindow->setText( pTip ); else new WindowTip( this, pTip ); // clear any cursor tip.. setCursorTip( "" ); } }
Group::Group(Window leader_P) : leader_client(NULL), leader_wid(leader_P), leader_info(NULL), user_time(-1U), refcount(0) { if (leader_P != None) { leader_client = workspace()->findClient(Predicate::WindowMatch, leader_P); leader_info = new NETWinInfo(connection(), leader_P, rootWindow(), 0, NET::WM2StartupId); } effect_group = new EffectWindowGroupImpl(this); workspace()->addGroup(this); }
void ScreenEdge::update(bool force) { m_screenEdgeTimeFirst = xTime(); m_screenEdgeTimeLast = xTime(); m_screenEdgeTimeLastTrigger = xTime(); m_currentScreenEdge = ElectricNone; QRect r = QRect(0, 0, displayWidth(), displayHeight()); m_screenEdgeTop = r.top(); m_screenEdgeBottom = r.bottom(); m_screenEdgeLeft = r.left(); m_screenEdgeRight = r.right(); for (int pos = 0; pos < ELECTRIC_COUNT; ++pos) { if (force || m_screenEdgeReserved[pos] == 0) { if (m_screenEdgeWindows[pos] != None) XDestroyWindow(display(), m_screenEdgeWindows[pos]); m_screenEdgeWindows[pos] = None; } if (m_screenEdgeReserved[pos] == 0) { continue; } if (m_screenEdgeWindows[pos] != None) continue; XSetWindowAttributes attributes; attributes.override_redirect = True; attributes.event_mask = EnterWindowMask | LeaveWindowMask; unsigned long valuemask = CWOverrideRedirect | CWEventMask; int xywh[ELECTRIC_COUNT][4] = { { r.left() + 1, r.top(), r.width() - 2, 1 }, // Top { r.right(), r.top(), 1, 1 }, // Top-right { r.right(), r.top() + 1, 1, r.height() - 2 }, // Etc. { r.right(), r.bottom(), 1, 1 }, { r.left() + 1, r.bottom(), r.width() - 2, 1 }, { r.left(), r.bottom(), 1, 1 }, { r.left(), r.top() + 1, 1, r.height() - 2 }, { r.left(), r.top(), 1, 1 } }; m_screenEdgeWindows[pos] = XCreateWindow(display(), rootWindow(), xywh[pos][0], xywh[pos][1], xywh[pos][2], xywh[pos][3], 0, CopyFromParent, InputOnly, CopyFromParent, valuemask, &attributes); XMapWindow(display(), m_screenEdgeWindows[pos]); // Set XdndAware on the windows, so that DND enter events are received (#86998) Atom version = 4; // XDND version XChangeProperty(display(), m_screenEdgeWindows[pos], atoms->xdnd_aware, XA_ATOM, 32, PropModeReplace, (unsigned char*)(&version), 1); } }
bool grabXKeyboard(Window w) { if (QWidget::keyboardGrabber() != NULL) return false; if (keyboard_grabbed) return false; if (qApp->activePopupWidget() != NULL) return false; if (w == None) w = rootWindow(); if (XGrabKeyboard(display(), w, False, GrabModeAsync, GrabModeAsync, xTime()) != GrabSuccess) return false; keyboard_grabbed = true; return true; }
Group::Group(Window leader_P) : leader_client(NULL), leader_wid(leader_P), leader_info(NULL), user_time(-1U), refcount(0) { if (leader_P != None) { leader_client = workspace()->findClient(WindowMatchPredicate(leader_P)); unsigned long properties[ 2 ] = { 0, NET::WM2StartupId }; leader_info = new NETWinInfo(display(), leader_P, rootWindow(), properties, 2); } effect_group = new EffectWindowGroupImpl(this); workspace()->addGroup(this); }
bool EglOnXBackend::initBufferConfigs() { const EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_SWAP_BEHAVIOR_PRESERVED_BIT, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_ALPHA_SIZE, 0, #ifdef KWIN_HAVE_OPENGLES EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #else EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, #endif EGL_CONFIG_CAVEAT, EGL_NONE, EGL_NONE, }; EGLint count; EGLConfig configs[1024]; if (eglChooseConfig(dpy, config_attribs, configs, 1024, &count) == EGL_FALSE) { qCritical() << "choose config failed"; return false; } Xcb::WindowAttributes attribs(rootWindow()); if (!attribs) { qCritical() << "Failed to get window attributes of root window"; return false; } config = configs[0]; for (int i = 0; i < count; i++) { EGLint val; if (eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &val) == EGL_FALSE) { qCritical() << "egl get config attrib failed"; } if (uint32_t(val) == attribs->visual) { config = configs[i]; break; } } return true; }
void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString) { void *result = 0; switch (resourceType(resourceString)) { case StartupId: result = startupId(); break; case X11Screen: result = x11Screen(); break; case RootWindow: result = rootWindow(); break; default: break; } return result; }
void SceneXrender::Window::prepareTempPixmap() { const QSize oldSize = temp_visibleRect.size(); temp_visibleRect = toplevel->visibleRect().translated(-toplevel->pos()); if (s_tempPicture && (oldSize.width() < temp_visibleRect.width() || oldSize.height() < temp_visibleRect.height())) { delete s_tempPicture; s_tempPicture = NULL; scene_setXRenderOffscreenTarget(0); // invalidate, better crash than cause weird results for developers } if (!s_tempPicture) { xcb_pixmap_t pix = xcb_generate_id(connection()); xcb_create_pixmap(connection(), 32, pix, rootWindow(), temp_visibleRect.width(), temp_visibleRect.height()); s_tempPicture = new XRenderPicture(pix, 32); xcb_free_pixmap(connection(), pix); } const xcb_render_color_t transparent = {0, 0, 0, 0}; const xcb_rectangle_t rect = {0, 0, uint16_t(temp_visibleRect.width()), uint16_t(temp_visibleRect.height())}; xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, *s_tempPicture, transparent, 1, &rect); }
int currentRefreshRate() { int rate = -1; QString syncScreenName(QLatin1String("primary screen")); if (options->refreshRate() > 0) { // use manually configured refresh rate rate = options->refreshRate(); } else if (Screens::self()->count() > 0) { // prefer the refreshrate calculated from the screens mode information // at least the nvidia driver reports 50Hz BS ... *again*! int syncScreen = 0; if (Screens::self()->count() > 1) { const QByteArray syncDisplayDevice(qgetenv("__GL_SYNC_DISPLAY_DEVICE")); // if __GL_SYNC_DISPLAY_DEVICE is exported, the GPU shall sync to that device // so we try to use its refresh rate if (!syncDisplayDevice.isEmpty()) { for (int i = 0; i < Screens::self()->count(); ++i) { if (Screens::self()->name(i) == syncDisplayDevice) { syncScreenName = Screens::self()->name(i); syncScreen = i; break; } } } } rate = qRound(Screens::self()->refreshRate(syncScreen)); // TODO forward float precision? } else if (Xcb::Extensions::self()->isRandrAvailable()) { // last restort - query XRandR screenInfo rate - probably wrong on nvidia systems Xcb::RandR::ScreenInfo screenInfo(rootWindow()); rate = screenInfo->rate; } // 0Hz or less is invalid, so we fallback to a default rate if (rate <= 0) rate = 60; // and not shitty 50Hz for sure! *grrr* // QTimer gives us 1msec (1000Hz) at best, so we ignore anything higher; // however, additional throttling prevents very high rates from taking place anyway else if (rate > 1000) rate = 1000; qCDebug(KWIN_CORE) << "Vertical Refresh rate " << rate << "Hz (" << syncScreenName << ")"; return rate; }
QXlibScreen::QXlibScreen() : mFormat(QImage::Format_RGB32) #if !defined(QT_NO_OPENGL) && defined(QT_OPENGL_ES_2) , mEGLDisplay(0) #endif { char *display_name = getenv("DISPLAY"); Display *display = XOpenDisplay(display_name); mDisplay = new QXlibDisplay(display); #ifndef DONT_USE_MIT_SHM int MIT_SHM_extension_supported = XShmQueryExtension (mDisplay->nativeDisplay()); Q_ASSERT(MIT_SHM_extension_supported == True); #endif original_x_errhandler = XSetErrorHandler(qt_x_errhandler); if (qgetenv("DO_X_SYNCHRONIZE").toInt()) XSynchronize(mDisplay->nativeDisplay(), true); mScreen = DefaultScreen(mDisplay->nativeDisplay()); XSelectInput(mDisplay->nativeDisplay(),rootWindow(), KeymapStateMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask); int width = DisplayWidth(mDisplay->nativeDisplay(), mScreen); int height = DisplayHeight(mDisplay->nativeDisplay(), mScreen); mGeometry = QRect(0,0,width,height); int physicalWidth = DisplayWidthMM(mDisplay->nativeDisplay(), mScreen); int physicalHeight = DisplayHeightMM(mDisplay->nativeDisplay(), mScreen); mPhysicalSize = QSize(physicalWidth,physicalHeight); int xSocketNumber = XConnectionNumber(mDisplay->nativeDisplay()); mDepth = DefaultDepth(mDisplay->nativeDisplay(),mScreen); #ifdef MYX11_DEBUG qDebug() << "X socket:"<< xSocketNumber; #endif QSocketNotifier *sock = new QSocketNotifier(xSocketNumber, QSocketNotifier::Read, this); connect(sock, SIGNAL(activated(int)), this, SLOT(eventDispatcher())); mCursor = new QXlibCursor(this); mKeyboard = new QXlibKeyboard(this); }
/** * This app grabs the keyboard from X. * It is used from ksldtest to verify we report if grabbing failed when the keyboard has been grabbed by another * X Client. It needs to be another application, otherwise the grab cannot fail. **/ int main(int argc, char **argv) { QCoreApplication app(argc, argv); // connect to xcb int screen = 0; xcb_connection_t *c = xcb_connect(nullptr, &screen); Q_ASSERT(c); xcb_grab_keyboard(c, 1, rootWindow(c, screen), XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); xcb_flush(c); const int exitCode = app.exec(); xcb_ungrab_keyboard(c, XCB_CURRENT_TIME); xcb_flush(c); xcb_disconnect(c); return exitCode; }
bool grabXKeyboard(xcb_window_t w) { if (QWidget::keyboardGrabber() != NULL) return false; if (keyboard_grabbed) return false; if (qApp->activePopupWidget() != NULL) return false; if (w == XCB_WINDOW_NONE) w = rootWindow(); const xcb_grab_keyboard_cookie_t c = xcb_grab_keyboard_unchecked(connection(), false, w, xTime(), XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); ScopedCPointer<xcb_grab_keyboard_reply_t> grab(xcb_grab_keyboard_reply(connection(), c, NULL)); if (grab.isNull()) { return false; } if (grab->status != XCB_GRAB_STATUS_SUCCESS) { return false; } keyboard_grabbed = true; return true; }
QIcon Group::icon() const { if (leader_client != NULL) return leader_client->icon(); else if (leader_wid != None) { QIcon ic; NETWinInfo info(connection(), leader_wid, rootWindow(), NET::WMIcon, NET::WM2IconPixmap); auto readIcon = [&ic, &info, this](int size, bool scale = true) { const QPixmap pix = KWindowSystem::icon(leader_wid, size, size, scale, KWindowSystem::NETWM | KWindowSystem::WMHints, &info); if (!pix.isNull()) { ic.addPixmap(pix); } }; readIcon(16); readIcon(32); readIcon(48, false); readIcon(64, false); readIcon(128, false); return ic; } return QIcon(); }
bool X11Support::makeSystemTray(unsigned long window) { if(XGetSelectionOwner(QX11Info::display(), systemTrayAtom()) != 0) return false; XSetSelectionOwner(QX11Info::display(), systemTrayAtom(), window, CurrentTime); setWindowPropertyVisualId(window, "_NET_SYSTEM_TRAY_VISUAL", getARGBVisualId()); XSync(QX11Info::display(), False); // Inform other clients. XClientMessageEvent event; event.type = ClientMessage; event.window = rootWindow(); event.message_type = atom("MANAGER"); event.format = 32; event.data.l[0] = CurrentTime; event.data.l[1] = systemTrayAtom(); event.data.l[2] = window; event.data.l[3] = 0; event.data.l[4] = 0; XSendEvent(QX11Info::display(), X11Support::rootWindow(), False, StructureNotifyMask, reinterpret_cast<XEvent*>(&event)); return true; }
bool GlxBackend::initBuffer() { if (!initFbConfig()) return false; if (overlayWindow()->create()) { xcb_connection_t * const c = connection(); // Try to create double-buffered window in the overlay xcb_visualid_t visual; glXGetFBConfigAttrib(display(), fbconfig, GLX_VISUAL_ID, (int *) &visual); if (!visual) { qCCritical(KWIN_CORE) << "The GLXFBConfig does not have an associated X visual"; return false; } xcb_colormap_t colormap = xcb_generate_id(c); xcb_create_colormap(c, false, colormap, rootWindow(), visual); const QSize size = screens()->size(); window = xcb_generate_id(c); xcb_create_window(c, visualDepth(visual), window, overlayWindow()->window(), 0, 0, size.width(), size.height(), 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, XCB_CW_COLORMAP, &colormap); glxWindow = glXCreateWindow(display(), fbconfig, window, NULL); overlayWindow()->setup(window); } else { qCCritical(KWIN_CORE) << "Failed to create overlay window"; return false; } return true; }