EAPI void ecore_x_region_picture_clip_set(Ecore_X_Region region, Ecore_X_Picture picture, int x_origin, int y_origin) { #ifdef ECORE_XFIXES LOGFN(__FILE__, __LINE__, __FUNCTION__); XFixesSetPictureClipRegion(_ecore_x_disp, picture, x_origin, y_origin, region); #endif /* ifdef ECORE_XFIXES */ } /* ecore_x_region_picture_clip_set */
gboolean expose_parent(GtkWidget * widget, GdkEventExpose * event) { OMWeather *plugin = OMWEATHER(widget); GdkDrawable *drawable; gint x_offset, y_offset; XRenderColor color; Picture picture; XserverRegion region; cairo_t *cr; gint radius = 0; gint width, height, x, y; if (GTK_WIDGET_DRAWABLE(widget) == FALSE) { return FALSE; } gtk_widget_set_size_request(GTK_WIDGET(widget), -1, -1); gdk_window_get_internal_paint_info(widget->window, &drawable, &x_offset, &y_offset); picture = hildon_desktop_picture_from_drawable(drawable); if (picture == None) { return FALSE; } plugin->clip.x = event->area.x - x_offset; plugin->clip.y = event->area.y - y_offset; plugin->clip.width = event->area.width + x_offset; plugin->clip.height = event->area.height + y_offset; region = XFixesCreateRegion(GDK_DISPLAY(), &plugin->clip, 1); XFixesSetPictureClipRegion(GDK_DISPLAY(), picture, 0, 0, region); color.red = color.blue = color.green = 0; color.alpha = 0; XRenderFillRectangle(GDK_DISPLAY(), PictOpSrc, picture, &color, 0, 0, widget->allocation.width, widget->allocation.height); if (app->config->icons_layout < PRESET_NOW){ radius = app->config->corner_radius; cr = gdk_cairo_create(drawable); cairo_set_source_rgba(cr, (double)app->config->background_color.red / (MAXSHORT * 2 + 1), (double)app->config->background_color.green / (MAXSHORT * 2 + 1), (double)app->config->background_color.blue / (MAXSHORT * 2 + 1), (double)app->config->alpha_comp / 100); width = plugin->clip.width; height = plugin->clip.height; x = plugin->clip.x; y = plugin->clip.y; if ((radius > height / 2) || (radius > width / 2)) { if (width < height) { radius = width / 2 - 1; } else { radius = height / 2 - 2; } } cairo_move_to(cr, x + radius, y); cairo_line_to(cr, x + width - radius, y); cairo_curve_to(cr, x + width - radius, y, x + width, y, x + width, y + radius); cairo_line_to(cr, x + width, y + height - radius); cairo_curve_to(cr, x + width, y + height - radius, x + width, y + height, x + width - radius, y + height); cairo_line_to(cr, x + radius, y + height); cairo_curve_to(cr, x + radius, y + height, x, y + height, x, y + height - radius); cairo_line_to(cr, x, y + radius); cairo_curve_to(cr, x, y + radius, x, y, x + radius, y); cairo_fill(cr); cairo_destroy(cr); } XFixesDestroyRegion(GDK_DISPLAY(), region); XRenderFreePicture(GDK_DISPLAY(), picture); if (plugin->queueRefresh) { redraw_home_window(TRUE); plugin->queueRefresh = FALSE; } return GTK_WIDGET_CLASS(g_type_class_peek_parent (GTK_FRAME_GET_CLASS(widget)))->expose_event (widget, event); }
/** Change the picture's list of clip rectangles. */ int dmxChangePictureClip(PicturePtr pPicture, int clipType, pointer value, int n) { ScreenPtr pScreen = pPicture->pDrawable->pScreen; DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; PictureScreenPtr ps = GetPictureScreen(pScreen); dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture); DMX_UNWRAP(ChangePictureClip, dmxScreen, ps); #if 1 if (ps->ChangePictureClip) ps->ChangePictureClip(pPicture, clipType, value, n); #endif /* Change picture clip rects on back-end server */ if (pPictPriv->pict) { /* The clip has already been changed into a region by the mi * routine called above. */ if (clipType == CT_NONE) { /* Disable clipping, show all */ XFixesSetPictureClipRegion(dmxScreen->beDisplay, pPictPriv->pict, 0, 0, None); } else if (pPicture->clientClip) { RegionPtr pClip = pPicture->clientClip; BoxPtr pBox = RegionRects(pClip); int nBox = RegionNumRects(pClip); XRectangle *pRects; XRectangle *pRect; int nRects; nRects = nBox; pRects = pRect = malloc(nRects * sizeof(*pRect)); while (nBox--) { pRect->x = pBox->x1; pRect->y = pBox->y1; pRect->width = pBox->x2 - pBox->x1; pRect->height = pBox->y2 - pBox->y1; pBox++; pRect++; } XRenderSetPictureClipRectangles(dmxScreen->beDisplay, pPictPriv->pict, 0, 0, pRects, nRects); free(pRects); } else { XRenderSetPictureClipRectangles(dmxScreen->beDisplay, pPictPriv->pict, 0, 0, NULL, 0); } dmxSync(dmxScreen, FALSE); } else { /* FIXME: Handle saving clip region when offscreen */ } DMX_WRAP(ChangePictureClip, dmxChangePictureClip, dmxScreen, ps); return Success; }
// This is the function that creates the screen presentation, by compositing the // top-level windows on the root window. void Workspace::repaint() { // If there's no damage, update the whole display if ( mDamage == None || mInitialRepaint ) { XRectangle r = { 0, 0, width(), height() }; XserverRegion region = XFixesCreateRegion( dpy, &r, 1 ); if ( mDamage ) XFixesDestroyRegion( dpy, mDamage ); mDamage = region; mInitialRepaint = false; } // Use the damage region as the clip region for the root window XFixesSetPictureClipRegion( dpy, frontBuffer(), 0, 0, mDamage ); // Client list for clients that are either translucent, or have a shadow ClientList translucents; // Draw each opaque window top to bottom, subtracting the bounding rect of // each drawn window from the clip region. ClientList::ConstIterator end = mList.constEnd(); for ( ClientList::ConstIterator it = mList.constBegin(); it != end; ++it ) { Client *client = *it; if ( !client->isVisible() || !client->isPainted() ) continue; // Update the region containing the area the window was last rendered at. client->updateOnScreenRegion(); // Only draw the window if it's opaque if ( client->isOpaque() ) { // Set the clip region for the backbuffer to the damage region, and // subtract the clients shape from the damage region XFixesSetPictureClipRegion( dpy, backBuffer(), 0, 0, mDamage ); XFixesSubtractRegion( dpy, mDamage, mDamage, client->shape() ); XRenderComposite( dpy, PictOpSrc, client->picture(), None, backBuffer(), 0, 0, 0, 0, client->x(), client->y(), client->width() + client->borderWidth() * 2, client->height() + client->borderWidth() * 2 ); } // Save the clip region before the next client shape is subtracted from it. // We need to restore it later when we're drawing the shadow. client->setShapeClip( mDamage ); translucents.prepend( client ); } // Draw any areas of the root window not covered by windows XFixesSetPictureClipRegion( dpy, backBuffer(), 0, 0, mDamage ); XRenderComposite( dpy, PictOpSrc, rootTile(), None, backBuffer(), 0, 0, 0, 0, 0, 0, width(), height() ); // Now walk the list backwards, drawing translucent windows and shadows. // That we draw bottom to top is important now since we're drawing translucent windows. end = translucents.constEnd(); for ( ClientList::ConstIterator it = translucents.constBegin(); it != end; ++it ) { Client *client = *it; // Restore the previously saved clip region XFixesSetPictureClipRegion( dpy, backBuffer(), 0, 0, client->shapeClip() ); // Only draw the window if it's translucent // (we drew the opaque ones in the previous loop) if ( !client->isOpaque() ) XRenderComposite( dpy, PictOpOver, client->picture(), client->alphaMask(), backBuffer(), 0, 0, 0, 0, client->x() + client->borderWidth(), client->y() + client->borderWidth(), client->width(), client->height() ); // We don't need the clip region anymore client->destroyShapeClip(); } translucents.clear(); // Destroy the damage region XFixesDestroyRegion( dpy, mDamage ); mDamage = None; // Copy the back buffer contents to the root window XFixesSetPictureClipRegion( dpy, backBuffer(), 0, 0, None ); XRenderComposite( dpy, PictOpSrc, backBuffer(), None, frontBuffer(), 0, 0, 0, 0, 0, 0, width(), height() ); }