Ejemplo n.º 1
0
WindowPixmapInterface::Ptr
PrivateCompositeWindow::getPixmap ()
{
    Pixmap pixmap = XCompositeNameWindowPixmap (screen->dpy (), ROOTPARENT (window));
    WindowPixmapInterface::Ptr p (new X11WindowPixmap (screen->dpy (), pixmap));
    return p;
}
Ejemplo n.º 2
0
void window_set_mapped(Window id, bool mapped)
{
	window_t *window = window_get(id);
	
	if (window == NULL)
		return;
	
	window->mapped = mapped;
	
	if (mapped == TRUE) {
		XRenderPictFormat *format;
		XRenderPictureAttributes pa;
		
		format = XRenderFindVisualFormat(conn, visual);
		pa.subwindow_mode = IncludeInferiors;
		
		if (window->picture != None)
			XRenderFreePicture(conn, window->picture);
		
		if (window->pixmap != None)
			XFreePixmap(conn, window->pixmap);
		
		window->pixmap = XCompositeNameWindowPixmap(conn, id);
		window->picture = XRenderCreatePicture(conn, window->pixmap,
				format, CPSubwindowMode, &pa);
		XDamageCreate(conn, window->pixmap, XDamageReportNonEmpty);
		
		window_list_remove(id);
		window_list_append(id);
	}
}
Ejemplo n.º 3
0
Archivo: main.c Proyecto: czaber/ogwm
void add(Window w) {
    XWindowAttributes attr;
	int i;
	if (w == root || w == overlay || w == canvas-1)
		return;

	debug("[AddWindow] Adding window 0x%x\n", w);

	if (workspace == NULL) {
		workspace = malloc(sizeof(Client) * MAX_CLIENTS);
		memset(workspace, 0, sizeof(Client) * MAX_CLIENTS);
	}

	for (i=0; i<MAX_CLIENTS && workspace[i].window != 0; i++)
		if (workspace[i].window == 0)
			break;
	
	unsigned int v;
    int target;
	GLuint texture;
	GLXFBConfig fbc = choose_fbconfig();
	Pixmap pixmap = XCompositeNameWindowPixmap(dpy, w);
    debug("Got pixmap 0x%x for 0x%x\n", pixmap, w);
    XGetWindowAttributes(dpy, w, &attr);
    if (attr.depth == 32)
        pixmap_attr[1] = GLX_TEXTURE_FORMAT_RGBA_EXT;
    else
        pixmap_attr[1] = GLX_TEXTURE_FORMAT_RGB_EXT;
	GLXPixmap glxpixmap = glXCreatePixmap(dpy, fbc, pixmap, pixmap_attr);
    debug("Got glxpixmap 0x%x for 0x%x\n", glxpixmap, pixmap);
	check_gl(__LINE__);
	glXQueryDrawable(dpy, glxpixmap, GLX_WIDTH, &v);
	check_gl(__LINE__); debug("GLX is %d width\n", v);
	glXQueryDrawable(dpy, glxpixmap, GLX_HEIGHT, &v);
	check_gl(__LINE__); debug("GLX is %d height\n", v);
    glXQueryDrawableProc(dpy, glxpixmap, GLX_TEXTURE_TARGET_EXT, &target);
	check_gl(__LINE__); debug("GLX is 0x%x\n", target);
	glGenTextures(1, &texture);
	check_gl(__LINE__);
	
	switch (target) {
		case GLX_TEXTURE_2D_EXT:
			warn("GLX_TEXTURE_2D_EXT requested but we don't support that yet\n");
			target = GL_TEXTURE_2D;
			break;
		case GLX_TEXTURE_RECTANGLE_EXT:
			target = GL_TEXTURE_RECTANGLE_ARB;
			break;
		default:
			die(ERR_INVALID_TEXTURE, "Invalid target: 0x%x\n", target);
	}

	info("Window 0x%x has glx = %x, target 0x%x and texture %d\n",
		w, glxpixmap, target, texture);
	workspace[i].window = w;
	workspace[i].glxpixmap = glxpixmap;
	workspace[i].target = target;
	workspace[i].texture = texture;
    XGetWindowAttributes(dpy, w, &(workspace[i].geom));
}
Ejemplo n.º 4
0
void
compzillaWindow::Resized (PRInt32 x, 
                          PRInt32 y,
                          PRInt32 width, 
                          PRInt32 height,
                          PRInt32 border)
{
    if (width != mAttr.width || 
        height != mAttr.height || 
        border != mAttr.border_width || 
        mAttr.override_redirect) {

        if (mIsRedirected) {
            ReleaseWindow ();

            mPixmap = XCompositeNameWindowPixmap (mDisplay, mWindow);
            if (mPixmap == None)
                return;

            for (PRUint32 i = mContentNodes.Count() - 1; i != PRUint32(-1); --i) {
                nsIDOMHTMLCanvasElement *aContent = mContentNodes.ObjectAt (i);
                aContent->SetWidth (width);
                aContent->SetHeight (height);
            }

            Damaged (NULL);
        }
    }

    mAttr.x = x;
    mAttr.y = y;
    mAttr.width = width;
    mAttr.height = height;
    mAttr.border_width = border;
}
Ejemplo n.º 5
0
static gboolean on_ref_mapped(GtkWidget *widget, GdkEvent  *event,
               gpointer   user_data)
{
    g_debug("%s", __func__);
    if (!back_pixmap) {
        g_assert(gtk_widget_is_visible(ref));
        GdkWindow* gdkwin = gtk_widget_get_window(ref);
        back_pixmap = XCompositeNameWindowPixmap(display, GDK_WINDOW_XID(gdkwin));
        glx_pm = glXCreatePixmap(display, bestFbc, back_pixmap, pixmap_attribs);
    }
    return FALSE;
}
cairo_surface_t* RedirectedXCompositeWindow::cairoSurfaceForWidget(GtkWidget* widget)
{
    if (!m_needsNewPixmapAfterResize && m_surface)
        return m_surface.get();

    m_needsNewPixmapAfterResize = false;

    // It's important that the new pixmap be created with the same Display pointer as the target
    // widget or else drawing speed can be 100x slower.
    Display* newPixmapDisplay = GDK_DISPLAY_XDISPLAY(gtk_widget_get_display(widget));
    Pixmap newPixmap = XCompositeNameWindowPixmap(newPixmapDisplay, m_window);
    if (!newPixmap) {
        cleanupPixmapAndPixmapSurface();
        return 0;
    }

    XWindowAttributes windowAttributes;
    if (!XGetWindowAttributes(newPixmapDisplay, m_window, &windowAttributes)) {
        cleanupPixmapAndPixmapSurface();
        XFreePixmap(newPixmapDisplay, newPixmap);
        return 0;
    }

    RefPtr<cairo_surface_t> newSurface = adoptRef(cairo_xlib_surface_create(newPixmapDisplay, newPixmap,
                                                                            windowAttributes.visual,
                                                                            m_size.width(), m_size.height()));

    // Nvidia drivers seem to prepare their redirected window pixmap asynchronously, so for a few fractions
    // of a second after each resize, while doing continuous resizing (which constantly destroys and creates
    // pixmap window-backings), the pixmap memory is uninitialized. To work around this issue, paint the old
    // pixmap to the new one to properly initialize it.
    if (m_surface) {
        RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
        cairo_set_source_rgb(cr.get(), 1, 1, 1);
        cairo_paint(cr.get());
        cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
        cairo_paint(cr.get());
    }

    cleanupPixmapAndPixmapSurface();
    m_pixmap = newPixmap;
    m_surface = newSurface;

    return m_surface.get();
}
static void
update_pixmap (MetaSurfaceActorX11 *self)
{
  MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
  MetaDisplay *display = priv->display;
  Display *xdisplay = meta_display_get_xdisplay (display);

  if (priv->size_changed)
    {
      detach_pixmap (self);
      priv->size_changed = FALSE;
    }

  if (priv->pixmap == None)
    {
      Pixmap new_pixmap;
      Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);

      meta_error_trap_push (display);
      new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow);

      if (meta_error_trap_pop_with_return (display) != Success)
        {
          /* Probably a BadMatch if the window isn't viewable; we could
           * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync
           * to avoid this, but there's no reason to take two round trips
           * when one will do. (We need that Sync if we want to handle failures
           * for any reason other than !viewable. That's unlikely, but maybe
           * we'll BadAlloc or something.)
           */
          new_pixmap = None;
        }

      if (new_pixmap == None)
        {
          meta_verbose ("Unable to get named pixmap for %s\n",
                        meta_window_get_description (priv->window));
          return;
        }

      set_pixmap (self, new_pixmap);
    }
}
Ejemplo n.º 8
0
cairo_surface_t* RedirectedXCompositeWindow::surface()
{
    // This should never be called with an empty size (not in Accelerated Compositing mode).
    ASSERT(!m_size.isEmpty());

    if (!m_needsNewPixmapAfterResize && m_surface)
        return m_surface.get();

    m_needsNewPixmapAfterResize = false;

    Pixmap newPixmap = XCompositeNameWindowPixmap(m_display, m_window);
    if (!newPixmap) {
        cleanupPixmapAndPixmapSurface();
        return nullptr;
    }

    XWindowAttributes windowAttributes;
    if (!XGetWindowAttributes(m_display, m_window, &windowAttributes)) {
        cleanupPixmapAndPixmapSurface();
        XFreePixmap(m_display, newPixmap);
        return nullptr;
    }

    RefPtr<cairo_surface_t> newSurface = adoptRef(cairo_xlib_surface_create(m_display, newPixmap, windowAttributes.visual, m_size.width(), m_size.height()));

    // Nvidia drivers seem to prepare their redirected window pixmap asynchronously, so for a few fractions
    // of a second after each resize, while doing continuous resizing (which constantly destroys and creates
    // pixmap window-backings), the pixmap memory is uninitialized. To work around this issue, paint the old
    // pixmap to the new one to properly initialize it.
    if (m_surface) {
        RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
        cairo_set_source_rgb(cr.get(), 1, 1, 1);
        cairo_paint(cr.get());
        cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
        cairo_paint(cr.get());
    }

    cleanupPixmapAndPixmapSurface();
    m_pixmap = newPixmap;
    m_surface = newSurface;
    return m_surface.get();
}
void MTexturePixmapPrivate::saveBackingStore()
{
    if (item->propertyCache()->isVirtual()) {
        TFP.bind(item->windowPixmap());
        return;
    }
    if ((item->propertyCache()->is_valid && !item->propertyCache()->isMapped())
        || item->propertyCache()->isInputOnly()
        || !window)
        return;

    if (TFP.drawable)
        XFreePixmap(QX11Info::display(), TFP.drawable);

    // Pixmap is already freed. No sense to bind it to texture
    if (item->isClosing() || item->window() < QX11Info::appRootWindow())
        return;

    Drawable pixmap = XCompositeNameWindowPixmap(QX11Info::display(), item->window());
    TFP.bind(pixmap);
}
Ejemplo n.º 10
0
    void createPixmap(uint32_t winId)
    {
        XWindowAttributes attr;
        XGetWindowAttributes(m_display, winId, &attr);

        XRenderPictFormat* format = XRenderFindVisualFormat(m_display, attr.visual);
        m_hasAlpha = (format->type == PictTypeDirect && format->direct.alphaMask);
        m_size = IntSize(attr.width, attr.height);

        int numberOfConfigs;
        GLXFBConfig* configs = glXChooseFBConfig(m_display, XDefaultScreen(m_display), glxSpec, &numberOfConfigs);

        m_xPixmap = XCompositeNameWindowPixmap(m_display, winId);
        m_glxPixmap = glXCreatePixmap(m_display, *configs, m_xPixmap, glxAttributes);

        uint inverted = 0;
        glXQueryDrawable(m_display, m_glxPixmap, GLX_Y_INVERTED_EXT, &inverted);
        m_textureIsYInverted = !!inverted;

        XFree(configs);
    }
Ejemplo n.º 11
0
void RedirectedXCompositeWindow::createNewPixampAndPixampSurface()
{
    // This should never be called with an empty size (not in Accelerated Compositing mode).
    ASSERT(!m_size.isEmpty());
    XUniquePixmap newPixmap(XCompositeNameWindowPixmap(m_display, m_window.get()));
    if (!newPixmap) {
        cleanupPixmapAndPixmapSurface();
        return;
    }

    XWindowAttributes windowAttributes;
    if (!XGetWindowAttributes(m_display, m_window.get(), &windowAttributes)) {
        cleanupPixmapAndPixmapSurface();
        return;
    }

    RefPtr<cairo_surface_t> newSurface = adoptRef(cairo_xlib_surface_create(m_display, newPixmap.get(), windowAttributes.visual, m_size.width(), m_size.height()));
    cairoSurfaceSetDeviceScale(newSurface.get(), m_webPage.deviceScaleFactor(), m_webPage.deviceScaleFactor());

    RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
    if (!m_webPage.drawsBackground())
        cairo_set_operator(cr.get(), CAIRO_OPERATOR_CLEAR);
    else
        setSourceRGBAFromColor(cr.get(), m_webPage.backgroundColor());
    cairo_paint(cr.get());

    // Nvidia drivers seem to prepare their redirected window pixmap asynchronously, so for a few fractions
    // of a second after each resize, while doing continuous resizing (which constantly destroys and creates
    // pixmap window-backings), the pixmap memory is uninitialized. To work around this issue, paint the old
    // pixmap to the new one to properly initialize it.
    if (m_surface) {
        cairo_set_operator(cr.get(), CAIRO_OPERATOR_OVER);
        cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
        cairo_paint(cr.get());
    }

    cleanupPixmapAndPixmapSurface();
    m_pixmap = WTFMove(newPixmap);
    m_surface = WTFMove(newSurface);
}
Ejemplo n.º 12
0
static gboolean on_ref_configure(GtkWidget *widget, GdkEvent  *event,
               gpointer   user_data)
{
    g_debug("%s", __func__);
    GdkEventConfigure *gec = (GdkEventConfigure*)event;
    g_width = gec->width;
    g_height = gec->height;
    gtk_window_resize(GTK_WINDOW(top), g_width, g_height);

    if (!gtk_widget_get_mapped(ref)) return TRUE;

    if (back_pixmap) {
        glXDestroyPixmap(display, glx_pm);
        XFreePixmap(display, back_pixmap);

        GdkWindow* gdkwin = gtk_widget_get_window(ref);
        back_pixmap = XCompositeNameWindowPixmap(display, GDK_WINDOW_XID(gdkwin));
        glx_pm = glXCreatePixmap(display, bestFbc, back_pixmap, pixmap_attribs);
    }

    return TRUE;
}
Ejemplo n.º 13
0
void
compzillaWindow::BindWindow ()
{
    RedirectWindow ();

    if (!mPixmap) {
        XGrabServer (mDisplay);

        UpdateAttributes ();

        if (mAttr.map_state == IsViewable) {
            // Set up persistent offscreen window contents pixmap.
            mPixmap = XCompositeNameWindowPixmap (mDisplay, mWindow);

            if (mPixmap == None) {
                ERROR ("XCompositeNameWindowPixmap failed for window %p\n", mWindow);
            }
        }

        XUngrabServer (mDisplay);
    }
}
Ejemplo n.º 14
0
    void createPixmap(uint32_t winId)
    {
        XWindowAttributes attr;
        XGetWindowAttributes(m_display, winId, &attr);

        XRenderPictFormat* format = XRenderFindVisualFormat(m_display, attr.visual);
        m_hasAlpha = (format->type == PictTypeDirect && format->direct.alphaMask);

        int numberOfConfigs;
        GLXFBConfig* configs = glXChooseFBConfig(m_display, XDefaultScreen(m_display), glxSpec, &numberOfConfigs);

        // If origin window has alpha then find config with alpha.
        GLXFBConfig& config = m_hasAlpha ? findFBConfigWithAlpha(configs, numberOfConfigs) : configs[0];

        m_xPixmap = XCompositeNameWindowPixmap(m_display, winId);
        m_glxPixmap = glXCreatePixmap(m_display, config, m_xPixmap, glxAttributes);

        uint inverted = 0;
        glXQueryDrawable(m_display, m_glxPixmap, GLX_Y_INVERTED_EXT, &inverted);
        m_textureIsYInverted = !!inverted;

        XFree(configs);
    }
Ejemplo n.º 15
0
void SceneXrender::selfCheckSetup()
    {
    KXErrorHandler err;
    QImage img( selfCheckWidth(), selfCheckHeight(), QImage::Format_RGB32 );
    img.setPixel( 0, 0, QColor( Qt::red ).rgb());
    img.setPixel( 1, 0, QColor( Qt::green ).rgb());
    img.setPixel( 2, 0, QColor( Qt::blue ).rgb());
    img.setPixel( 0, 1, QColor( Qt::white ).rgb());
    img.setPixel( 1, 1, QColor( Qt::black ).rgb());
    img.setPixel( 2, 1, QColor( Qt::white ).rgb());
    QPixmap pix = QPixmap::fromImage( img );
    foreach( const QPoint& p, selfCheckPoints())
        {
        XSetWindowAttributes wa;
        wa.override_redirect = True;
        ::Window window = XCreateWindow( display(), rootWindow(), 0, 0, selfCheckWidth(), selfCheckHeight(),
            0, QX11Info::appDepth(), CopyFromParent, CopyFromParent, CWOverrideRedirect, &wa );
        XSetWindowBackgroundPixmap( display(), window, pix.handle());
        XClearWindow( display(), window );
        XMapWindow( display(), window );
        // move the window one down to where the result will be rendered too, just in case
        // the render would fail completely and eventual check would try to read this window's contents
        XMoveWindow( display(), window, p.x() + 1, p.y());
        XCompositeRedirectWindow( display(), window, CompositeRedirectAutomatic );
        Pixmap wpix = XCompositeNameWindowPixmap( display(), window );
        XWindowAttributes attrs;
        XGetWindowAttributes( display(), window, &attrs );
        XRenderPictFormat* format = XRenderFindVisualFormat( display(), attrs.visual );
        Picture pic = XRenderCreatePicture( display(), wpix, format, 0, 0 );
        QRect rect( p.x(), p.y(), selfCheckWidth(), selfCheckHeight());
        XRenderComposite( display(), PictOpSrc, pic, None, buffer, 0, 0, 0, 0,
            rect.x(), rect.y(), rect.width(), rect.height());
        XRenderFreePicture( display(), pic );
        XFreePixmap( display(), wpix );
        XDestroyWindow( display(), window );
        }
Ejemplo n.º 16
0
void XCompositeEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
{
    XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer);
    Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window());

    QVector<EGLint> eglConfigSpec = eglbuildSpec();

    EGLint matching = 0;
    EGLConfig config;
    bool matched = eglChooseConfig(mEglDisplay,eglConfigSpec.constData(),&config,1,&matching);
    if (!matched || !matching) {
        qWarning("Could not retrieve a suitable EGL config");
        return;
    }

    QVector<EGLint> attribList;

    attribList.append(EGL_TEXTURE_FORMAT);
    attribList.append(EGL_TEXTURE_RGBA);
    attribList.append(EGL_TEXTURE_TARGET);
    attribList.append(EGL_TEXTURE_2D);
    attribList.append(EGL_NONE);

    EGLSurface surface = eglCreatePixmapSurface(mEglDisplay,config,pixmap,attribList.constData());
    if (surface == EGL_NO_SURFACE) {
        qDebug() << "Failed to create eglsurface" << pixmap << compositorBuffer->window();
    }

    compositorBuffer->setInvertedY(true);

    if (!eglBindTexImage(mEglDisplay,surface,EGL_BACK_BUFFER)) {
        qDebug() << "Failed to bind";
    }

    //    eglDestroySurface(mEglDisplay,surface);
}
GLboolean
stubIsWindowVisible(WindowInfo *win)
{
#if defined(WINDOWS)
# ifdef VBOX_WITH_WDDM
    if (stub.bRunningUnderWDDM)
        return win->mapped;
# endif
    return GL_TRUE;
#elif defined(Darwin)
    return GL_TRUE;
#elif defined(GLX)
    Display *dpy = stubGetWindowDisplay(win);
    if (dpy) 
    {
        XWindowAttributes attr;
        XLOCK(dpy);
        XGetWindowAttributes(dpy, win->drawable, &attr);
        XUNLOCK(dpy);

        if (attr.map_state == IsUnmapped)
        {
            return GL_FALSE;
        }
# if 1
        return GL_TRUE;
# else
        if (attr.override_redirect)
        {
            return GL_TRUE;
        }

        if (!stub.bXExtensionsChecked)
        {
            stubCheckXExtensions(win);
        }

        if (!stub.bHaveXComposite)
        {
            return GL_TRUE;
        }
        else
        {
            Pixmap p;

            crLockMutex(&stub.mutex);

            XLOCK(dpy);
            XSync(dpy, false);
            oldErrorHandler = XSetErrorHandler(errorHandler);
            /*@todo this will create new pixmap for window every call*/
            p = XCompositeNameWindowPixmap(dpy, win->drawable);
            XSync(dpy, false);
            XSetErrorHandler(oldErrorHandler);
            XUNLOCK(dpy);

            switch (lastXError)
            {
                case Success:
                    XFreePixmap(dpy, p);
                    crUnlockMutex(&stub.mutex);
                    return GL_FALSE;
                    break;
                case BadMatch:
                    /*Window isn't redirected*/
                    lastXError = Success;
                    break;
                default:
                    crWarning("Unexpected XError %i", (int)lastXError);
                    lastXError = Success;
            }

            crUnlockMutex(&stub.mutex);

            return GL_TRUE;
        }
# endif
    }
    else {
        /* probably created by crWindowCreate() */
        return win->mapped;
    }
#endif
}
Ejemplo n.º 18
0
int xcomposite_get_widow_contents()
{
	int ret = 0;

	int ver, rev, eventB, baseB;
	int x, y;
	Pixmap pxm = 0;
	window_struct params;

	if(create_window(&params, "Test Window"))
	{
		ret = -1;
		goto cleanup;
	}

	if(!XCompositeQueryExtension(params.display, &eventB, &baseB))
	{
		BLTS_ERROR("XCompositeQueryExtension failed\n");
		ret = -1;
		goto cleanup;
	}

	if(!XCompositeQueryVersion(params.display, &ver, &rev))
	{
		BLTS_ERROR("XCompositeQueryVersion failed\n");
		ret = -1;
		goto cleanup;
	}

	BLTS_DEBUG("XComposite Extension version %i.%i\n", ver, rev);

	/* Redirect window to off-screen storage (the window might be already
	redirected when using composite window manager) */
	XCompositeRedirectWindow(params.display, params.window, 0);

	/* Draw rectangle pattern */
	for(x = 0; x < params.window_attributes.width; x+=20)
	{
		for(y = 0; y < params.window_attributes.height; y+=20)
		{
			XFillRectangle(params.display, params.window, params.gc, x, y,
				10, 10);
		}
	}
	XFlush(params.display);

	sleep(1);

	/* Get pixmap of window contents */
	pxm = XCompositeNameWindowPixmap(params.display, params.window);
	XCompositeUnredirectWindow(params.display, params.window, 0);

	/* Copy the pixmap over the window (you should see white/black stripes
	 * after this)
	 */
	for(y = 0; y < params.window_attributes.height; y++)
	{
		XCopyArea(params.display, pxm, params.window, params.gc, 0, 0,
			params.window_attributes.width, params.window_attributes.height,
			0, y );
	}
	XFlush(params.display);

	sleep(1);

cleanup:
	if(params.display && pxm)
	{
		XFreePixmap(params.display, pxm);
	}
	close_window(&params);

	return ret;
}
/**
 * clutter_x11_texture_pixmap_sync_window:
 * @texture: the texture to bind
 *
 * Resets the texture's pixmap from its window, perhaps in response to the
 * pixmap's invalidation as the window changed size.
 *
 * Since: 0.8
 **/
void
clutter_x11_texture_pixmap_sync_window (ClutterX11TexturePixmap *texture)
{
  ClutterX11TexturePixmapPrivate *priv;
  Pixmap pixmap;

  g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture));

  priv = texture->priv;

  if (priv->destroyed)
    return;

  if (!clutter_x11_has_composite_extension())
    {
      clutter_x11_texture_pixmap_set_pixmap (texture, priv->window);
      return;
    }

  if (priv->window)
    {
      XWindowAttributes attr;
      Display *dpy = clutter_x11_get_default_display ();
      gboolean mapped, notify_x, notify_y, notify_override_redirect;

      /* We may get a BadMatch error here if the window is not mapped.
       * If so, ignore it - pixmap should be set to None in that case anyway */
      XSync (dpy, FALSE);
      clutter_x11_trap_x_errors ();
      XGetWindowAttributes (dpy, priv->window, &attr);
      mapped = attr.map_state == IsViewable;
      if (mapped)
        pixmap = XCompositeNameWindowPixmap (dpy, priv->window);
      else
        pixmap = None;
      XSync (dpy, FALSE);
      if (clutter_x11_untrap_x_errors() && pixmap!=None)
        g_warning("%s: Got X error but pixmap is still set", __FUNCTION__);

      notify_x = attr.x != priv->window_x;
      notify_y = attr.y != priv->window_y;
      notify_override_redirect = attr.override_redirect != priv->override_redirect;
      priv->window_x = attr.x;
      priv->window_y = attr.y;
      priv->override_redirect = attr.override_redirect;

      g_object_ref (texture); /* guard against unparent */
      if (pixmap)
        {
          clutter_x11_texture_pixmap_set_pixmap (texture, pixmap);
          priv->owns_pixmap = TRUE;
        }
      clutter_x11_texture_pixmap_set_mapped (texture, mapped);
      /* could do more clever things with a signal, i guess.. */
      if (notify_override_redirect)
        g_object_notify (G_OBJECT (texture), "window-override-redirect");
      if (notify_x)
        g_object_notify (G_OBJECT (texture), "window-x");
      if (notify_y)
        g_object_notify (G_OBJECT (texture), "window-y");
      g_object_unref (texture);
    }
}
Ejemplo n.º 20
0
void XCompcapMain::updateSettings(obs_data_t *settings)
{
	PLock lock(&p->lock);
	XErrorLock xlock;
	ObsGsContextHolder obsctx;

	blog(LOG_DEBUG, "Settings updating");

	Window prevWin = p->win;

	xcc_cleanup(p);

	if (settings) {
		const char *windowName = obs_data_get_string(settings,
				"capture_window");

		p->windowName = windowName;
		p->win = getWindowFromString(windowName);

		p->cut_top = obs_data_get_int(settings, "cut_top");
		p->cut_left = obs_data_get_int(settings, "cut_left");
		p->cut_right = obs_data_get_int(settings, "cut_right");
		p->cut_bot = obs_data_get_int(settings, "cut_bot");
		p->lockX = obs_data_get_bool(settings, "lock_x");
		p->swapRedBlue = obs_data_get_bool(settings, "swap_redblue");
		p->show_cursor = obs_data_get_bool(settings, "show_cursor");
		p->include_border = obs_data_get_bool(settings, "include_border");
		p->exclude_alpha = obs_data_get_bool(settings, "exclude_alpha");
	} else {
		p->win = prevWin;
	}

	xlock.resetError();

	if (p->win)
		XCompositeRedirectWindow(xdisp, p->win,
				CompositeRedirectAutomatic);

	if (xlock.gotError()) {
		blog(LOG_ERROR, "XCompositeRedirectWindow failed: %s",
				xlock.getErrorText().c_str());
		return;
	}

	if (p->win)
		XSelectInput(xdisp, p->win, StructureNotifyMask | ExposureMask);
	XSync(xdisp, 0);

	XWindowAttributes attr;
	if (!p->win || !XGetWindowAttributes(xdisp, p->win, &attr)) {
		p->win = 0;
		p->width = 0;
		p->height = 0;
		return;
	}

	if (p->win && p->cursor && p->show_cursor) {
		Window child;
		int x, y;

		XTranslateCoordinates(xdisp, p->win, attr.root, 0, 0, &x, &y,
				&child);
		xcursor_offset(p->cursor, x, y);
	}

	gs_color_format cf = GS_RGBA;

	if (p->exclude_alpha) {
		cf = GS_BGRX;
	}

	p->border = attr.border_width;

	if (p->include_border) {
		p->width = attr.width + p->border * 2;
		p->height = attr.height + p->border * 2;
	} else {
		p->width = attr.width;
		p->height = attr.height;
	}

	if (p->cut_top + p->cut_bot < (int)p->height) {
		p->cur_cut_top = p->cut_top;
		p->cur_cut_bot = p->cut_bot;
	} else {
		p->cur_cut_top = 0;
		p->cur_cut_bot = 0;
	}

	if (p->cut_left + p->cut_right < (int)p->width) {
		p->cur_cut_left = p->cut_left;
		p->cur_cut_right = p->cut_right;
	} else {
		p->cur_cut_left = 0;
		p->cur_cut_right = 0;
	}

	if (p->tex)
		gs_texture_destroy(p->tex);

	uint8_t *texData = new uint8_t[width() * height() * 4];

	memset(texData, 0, width() * height() * 4);

	const uint8_t* texDataArr[] = { texData, 0 };

	p->tex = gs_texture_create(width(), height(), cf, 1,
			texDataArr, 0);

	delete[] texData;

	if (p->swapRedBlue) {
		GLuint tex = *(GLuint*)gs_texture_get_obj(p->tex);
		glBindTexture(GL_TEXTURE_2D, tex);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
		glBindTexture(GL_TEXTURE_2D, 0);
	}

	const int attrs[] =
	{
		GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE,
		GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
		GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
		GLX_DOUBLEBUFFER, GL_FALSE,
		None
	};

	int nelem = 0;
	GLXFBConfig* configs = glXChooseFBConfig(xdisp,
			XCompcap::getRootWindowScreen(attr.root),
			attrs, &nelem);

	if (nelem <= 0) {
		blog(LOG_ERROR, "no matching fb config found");
		p->win = 0;
		p->height = 0;
		p->width = 0;
		return;
	}

	glXGetFBConfigAttrib(xdisp, configs[0], GLX_Y_INVERTED_EXT, &nelem);
	p->inverted = nelem != 0;

	xlock.resetError();

	p->pixmap = XCompositeNameWindowPixmap(xdisp, p->win);

	if (xlock.gotError()) {
		blog(LOG_ERROR, "XCompositeNameWindowPixmap failed: %s",
				xlock.getErrorText().c_str());
		p->pixmap = 0;
		XFree(configs);
		return;
	}

	const int attribs[] =
	{
		GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
		GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
		None
	};

	p->glxpixmap = glXCreatePixmap(xdisp, configs[0], p->pixmap, attribs);

	if (xlock.gotError()) {
		blog(LOG_ERROR, "glXCreatePixmap failed: %s",
				xlock.getErrorText().c_str());
		XFreePixmap(xdisp, p->pixmap);
		XFree(configs);
		p->pixmap = 0;
		p->glxpixmap = 0;
		return;
	}

	XFree(configs);

	p->gltex = gs_texture_create(p->width, p->height, cf, 1, 0,
			GS_GL_DUMMYTEX);

	GLuint gltex = *(GLuint*)gs_texture_get_obj(p->gltex);
	glBindTexture(GL_TEXTURE_2D, gltex);
	glXBindTexImageEXT(xdisp, p->glxpixmap, GLX_FRONT_LEFT_EXT, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
Ejemplo n.º 21
0
QPixmap X11Support::getWindowPixmap(unsigned long window)
{
	return QPixmap::fromX11Pixmap(XCompositeNameWindowPixmap(QX11Info::display(), window));
}
Ejemplo n.º 22
0
void X11EmbedContainer::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    if (!d->updatesEnabled) {
        return;
    }

    if (!d->picture) {
        FdoSelectionManager::painter()->updateContainer(this);
        return;
    }

    QPainter p(this);

    // Paint the background
    // Translate the painter to ensure the background brush is aligned with the
    // rest of the panel
    p.translate(-x(), -y());
    p.eraseRect(0, 0, x() + width(), y() + height());
    p.translate(x(), y());

    // Taking a detour via a QPixmap is unfortunately the only way we can get
    // the window contents into Qt's backing store.
    QPixmap pixmap(size());
    if (pixmap.paintEngine()->type() != QPaintEngine::X11) {
        // If we're using the raster or OpenGL graphics systems, a QPixmap isn't an X pixmap,
        // so we have to get the window contents into a QImage and then draw that.
        Display *dpy = x11Info().display();

        // XXX We really should keep a cached copy of the image client side, and only
        //     update it in response to a damage event.
        Pixmap pixmap = XCompositeNameWindowPixmap(dpy, clientWinId());

        // Extract XImage from pixmap, trying to cope with different behaviors.
        // There are two possible sizes: 
        // #1: width() x height(), which is 24 x 24 in our situation
        // #2: d->attr.width x d->attr.height
        //
        // - Mumble 1.2.3 returns a correct image when asked for an image of
        // size #1 , but returns a 22 x 22 cropped icon when asked for an image
        // of size #2.
        //
        // - Pidgin 2.7.9 returns a NULL image when asked for an image of size
        // #1 but returns a correct 16 x 16 image when asked for an image of
        // size #2.
        XImage *ximage = XGetImage(dpy, pixmap, 0, 0, width(), height(), AllPlanes, ZPixmap);
        if (!ximage) {
            int ximageWidth = qMin(d->attr.width, width());
            int ximageHeight = qMin(d->attr.height, height());
            ximage = XGetImage(dpy, pixmap, 0, 0, ximageWidth, ximageHeight, AllPlanes, ZPixmap);
        }
        XFreePixmap(dpy, pixmap);
        if (!ximage) {
            //UQ_WARNING << "Failed to get an XImage from X11 window with XID=" << clientWinId();
            return;
        }
        // This is safe to do since we only composite ARGB32 windows, and PictStandardARGB32
        // matches QImage::Format_ARGB32_Premultiplied.
        QImage image((const uchar*)ximage->data, ximage->width, ximage->height, ximage->bytes_per_line,
                     QImage::Format_ARGB32_Premultiplied);

        p.drawImage((width() - image.width()) / 2, (height() - image.height()) / 2, image);

        XDestroyImage(ximage);
    } else {
        pixmap.fill(Qt::transparent);

        XRenderComposite(x11Info().display(), PictOpSrc, d->picture, None, pixmap.x11PictureHandle(),
                         0, 0, 0, 0, 0, 0, width(), height());

        p.drawPixmap(0, 0, pixmap);
    }
}
Ejemplo n.º 23
0
// -----------------------------------------------------------------------------
// Internal stuff
// -----------------------------------------------------------------------------
static void
create_texture(riftwm_t *wm, riftwin_t *win)
{
  XWindowAttributes attr;

  // Retrieve properties
  if (!XGetWindowAttributes(wm->dpy, win->window, &attr)) {
    riftwm_error(wm, "Cannot retrieve window attributes");
  }

  win->width = attr.width;
  win->height = attr.height;
  if (attr.map_state != IsViewable) {
    return;
  }

  // Free old resources
  if (win->glx_pixmap) {
    glBindTexture(GL_TEXTURE_2D, win->texture);
    wm->glXReleaseTexImageEXT(wm->dpy, win->glx_pixmap, GLX_FRONT_LEFT_EXT);
    glBindTexture(GL_TEXTURE_2D, 0);

    glXDestroyPixmap(wm->dpy, win->glx_pixmap);
    win->glx_pixmap = 0;
  }

  if (win->pixmap) {
    XFreePixmap(wm->dpy, win->pixmap);
    win->pixmap = 0;
  }

  if (!win->texture) {
    glGenTextures(1, &win->texture);
  }

  // Retrieve the pixmap from the XComposite
  win->pixmap = XCompositeNameWindowPixmap(wm->dpy, win->window);

  // Create a backing OpenGL pixmap
  const int ATTR[] =
  {
    GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
    GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
    None
  };

  if (!(win->glx_pixmap = glXCreatePixmap(wm->dpy, wm->fb_config[1].config,
                                          win->pixmap, ATTR)))
  {
    riftwm_error(wm, "Cannot create GLX pixmap");
  }

  // Create the texture
  glBindTexture(GL_TEXTURE_2D, win->texture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  wm->glXBindTexImageEXT(wm->dpy, win->glx_pixmap, GLX_FRONT_LEFT_EXT, NULL);
  glBindTexture(GL_TEXTURE_2D, 0);

  win->dirty = 0;
}
Ejemplo n.º 24
0
static DFBResult
x11AllocateKey( CoreSurfacePool       *pool,
                void                  *pool_data,
                void                  *pool_local,
                CoreSurfaceBuffer     *buffer,
                const char            *key,
                u64                    handle,
                CoreSurfaceAllocation *allocation,
                void                  *alloc_data )
{
     CoreSurface       *surface;
     x11AllocationData *alloc = alloc_data;
     x11PoolLocalData  *local = pool_local;
     DFBX11            *x11   = local->x11;

     D_DEBUG_AT( X11_Surfaces, "%s( %s, 0x%08llx )\n", __FUNCTION__, key, (unsigned long long) handle );
     D_DEBUG_AT( X11_Surfaces, "  -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     surface = buffer->surface;
     D_MAGIC_ASSERT( surface, CoreSurface );

     if (!strcmp( key, "Pixmap/X11" )) {
          D_DEBUG_AT( X11_Surfaces, "  -> Pixmap/X11\n" );

          alloc->type = X11_ALLOC_PIXMAP;
     }
     else if (!strcmp( key, "Window/X11" )) {
          D_DEBUG_AT( X11_Surfaces, "  -> Window/X11\n" );

          alloc->type = X11_ALLOC_WINDOW;
     }
     else {
          D_BUG( "unexpected key '%s'", key );
          return DFB_BUG;
     }

     dfb_surface_calc_buffer_size( surface, 8, 8, &alloc->pitch, &allocation->size );

//     alloc->depth  = DefaultDepthOfScreen( x11->screenptr );
//     alloc->visual = DefaultVisualOfScreen( x11->screenptr );
     alloc->visual = x11->visuals[DFB_PIXELFORMAT_INDEX(buffer->format)];
     alloc->depth  = DFB_COLOR_BITS_PER_PIXEL( buffer->format ) + DFB_ALPHA_BITS_PER_PIXEL( buffer->format );

     if (alloc->depth == DefaultDepthOfScreen( x11->screenptr ))
          alloc->visual = DefaultVisualOfScreen( x11->screenptr );

     D_DEBUG_AT( X11_Surfaces, "  -> visual %p (id %lu), depth %d\n", alloc->visual, alloc->visual->visualid, alloc->depth );

     if (handle) {
          switch (alloc->type) {
               case X11_ALLOC_PIXMAP:
                    XLockDisplay( x11->display );

                    alloc->xid = (unsigned long) handle;
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> pixmap 0x%08lx\n", (long) alloc->xid );

                    XUnlockDisplay( x11->display );

                    D_INFO( "X11/Windows: Import Pixmap 0x%08lx\n", alloc->xid );
                    break;

               case X11_ALLOC_WINDOW: {
                    XLockDisplay( x11->display );

                    alloc->window = (unsigned long) handle;
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> window 0x%08lx\n", (long) alloc->window );

                    XCompositeRedirectWindow( x11->display, alloc->window, CompositeRedirectManual );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> redirected\n" );

                    alloc->xid = XCompositeNameWindowPixmap( x11->display, alloc->window );
//                    alloc->xid = alloc->window;
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> pixmap 0x%08lx\n", (long) alloc->xid );

                    XUnmapWindow( x11->display, alloc->window );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> unmapped\n" );

                    XUnlockDisplay( x11->display );

                    D_INFO( "X11/Windows: Import Window 0x%08lx with Pixmap handle 0x%08lx\n", alloc->window, alloc->xid );
                    break;
               }

               default:
                    D_BUG( "unexpected allocation type %d\n", alloc->type );
                    return DFB_BUG;
          }
     }
     else {
//          alloc->type = X11_ALLOC_PIXMAP;

          switch (alloc->type) {
               case X11_ALLOC_PIXMAP:
                    XLockDisplay( x11->display );

                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> creating pixmap...\n" );

                    alloc->xid = XCreatePixmap( x11->display, DefaultRootWindow(x11->display),
                                                allocation->config.size.w, allocation->config.size.h, alloc->depth );
                    x11->Sync( x11 );
                    XSync( x11->display, False );
                    D_DEBUG_AT( X11_Surfaces, "  -> pixmap 0x%08lx\n", (long) alloc->xid );

                    XUnlockDisplay( x11->display );

                    D_INFO( "X11/Windows: New Pixmap 0x%08lx\n", alloc->xid );

                    alloc->created = true;
                    break;

               case X11_ALLOC_WINDOW: {
                    Window w = (Window) (long) buffer->surface->data;


                    XSetWindowAttributes attr;

                    attr.event_mask =
                           ButtonPressMask
                         | ButtonReleaseMask
                         | PointerMotionMask
                         | KeyPressMask
                         | KeyReleaseMask
                         | ExposureMask
                         | StructureNotifyMask;

                    attr.background_pixmap = 0;

                    XLockDisplay( x11->display );

                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> creating window...\n" );

                    alloc->window = w?:XCreateWindow( x11->display,
                                                   DefaultRootWindow(x11->display),
                                                   600, 200, allocation->config.size.w, allocation->config.size.h, 0,
                                                   alloc->depth, InputOutput,
                                                   alloc->visual, CWEventMask, &attr );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> window 0x%08lx\n", (long) alloc->window );
                    buffer->surface->data = (void*) (long) alloc->window;

                    XMapRaised( x11->display, alloc->window );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> raised\n" );

                    XCompositeRedirectWindow( x11->display, alloc->window, CompositeRedirectManual );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> redirected\n" );

                    alloc->xid = XCompositeNameWindowPixmap( x11->display, alloc->window );
//                    alloc->xid = alloc->window;
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> pixmap 0x%08lx\n", (long) alloc->xid );

                    XUnmapWindow( x11->display, alloc->window );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> unmapped\n" );

                    XUnlockDisplay( x11->display );

                    D_INFO( "X11/Windows: New Window 0x%08lx with Pixmap handle 0x%08lx\n", alloc->window, alloc->xid );

                    alloc->created = !w;
                    break;
               }

               default:
                    D_BUG( "unexpected allocation type %d\n", alloc->type );
                    return DFB_BUG;
          }
     }

     alloc->gc = XCreateGC( x11->display, alloc->xid, 0, NULL );

     allocation->offset = alloc->type;

     return DFB_OK;
}
Ejemplo n.º 25
0
ClientWin *
clientwin_create(MainWin *mw, Window client) {
	session_t *ps = mw->ps;
	ClientWin *cw = allocchk(malloc(sizeof(ClientWin)));
	{
		static const ClientWin CLIENTWT_DEF = CLIENTWT_INIT;
		memcpy(cw, &CLIENTWT_DEF, sizeof(ClientWin));
	}

	XWindowAttributes attr;
	
	cw->mainwin = mw;
	cw->wid_client = client;
	if (ps->o.includeFrame)
		cw->src.window = wm_find_frame(ps, client);
	if (!cw->src.window)
		cw->src.window = client;
	cw->mini.format = mw->format;
	{
		XSetWindowAttributes sattr = {
			.border_pixel = 0,
			.background_pixel = 0,
			.colormap = mw->colormap,
			.event_mask = ButtonPressMask | ButtonReleaseMask | KeyPressMask
				| KeyReleaseMask | EnterWindowMask | LeaveWindowMask
				| PointerMotionMask | ExposureMask | FocusChangeMask,
			.override_redirect = ps->o.lazyTrans,
		};
		cw->mini.window = XCreateWindow(ps->dpy,
				(ps->o.lazyTrans ? ps->root : mw->window), 0, 0, 1, 1, 0,
				mw->depth, InputOutput, mw->visual,
				CWColormap | CWBackPixel | CWBorderPixel | CWEventMask | CWOverrideRedirect, &sattr);
	}
	if (!cw->mini.window)
		goto clientwin_create_err;
	
	{
		static const char *PREFIX = "mini window of ";
		const int len = strlen(PREFIX) + 20;
		char *str = allocchk(malloc(len));
		snprintf(str, len, "%s%#010lx", PREFIX, cw->src.window);
		wm_wid_set_info(cw->mainwin->ps, cw->mini.window, str, None);
		free(str);
	}

	// Listen to events on the window. We don't want to miss any changes so
	// this is to be done as early as possible
	XSelectInput(cw->mainwin->ps->dpy, cw->src.window, SubstructureNotifyMask | StructureNotifyMask);

	XGetWindowAttributes(ps->dpy, client, &attr);
	if (IsViewable != attr.map_state)
		goto clientwin_create_err;
	clientwin_update(cw);
	
	// Get window pixmap
	if (ps->o.useNameWindowPixmap) {
		XCompositeRedirectWindow(ps->dpy, cw->src.window, CompositeRedirectAutomatic);
		cw->redirected = true;
		cw->cpixmap = XCompositeNameWindowPixmap(ps->dpy, cw->src.window);
	}
	// Create window picture
	{
		Drawable draw = cw->cpixmap;
		if (!draw) draw = cw->src.window;
		XRenderPictureAttributes pa = { .subwindow_mode = IncludeInferiors };
		cw->origin = XRenderCreatePicture(cw->mainwin->ps->dpy,
				draw, cw->src.format, CPSubwindowMode, &pa);
	}
	if (!cw->origin)
		goto clientwin_create_err;

	XRenderSetPictureFilter(cw->mainwin->ps->dpy, cw->origin, FilterBest, 0, 0);


	return cw;

clientwin_create_err:
	if (cw)
		clientwin_destroy(cw, False);

	return NULL;
}

void
clientwin_update(ClientWin *cw) {
	Window tmpwin;
	XWindowAttributes wattr;

	XGetWindowAttributes(cw->mainwin->ps->dpy, cw->src.window, &wattr);
	XTranslateCoordinates(cw->mainwin->ps->dpy, cw->src.window, wattr.root,
			-wattr.border_width, -wattr.border_width,
			&cw->src.x, &cw->src.y, &tmpwin);
	cw->src.width = wattr.width;
	cw->src.height = wattr.height;
	cw->src.format = XRenderFindVisualFormat(cw->mainwin->ps->dpy, wattr.visual);

	cw->mini.x = cw->mini.y = 0;
	cw->mini.width = cw->mini.height = 1;
}