EAPI void ecore_x_region_subtract(Ecore_X_Region dest, Ecore_X_Region source1, Ecore_X_Region source2) { #ifdef ECORE_XFIXES LOGFN(__FILE__, __LINE__, __FUNCTION__); XFixesSubtractRegion(_ecore_x_disp, dest, source1, source2); #endif /* ifdef ECORE_XFIXES */ } /* ecore_x_region_subtract */
/* * Applies the current input shape base and stack to the stage input shape. * This function is for internal use only and should not be used outside of the * actual implementation of the input shape stack. */ static void mnb_input_manager_apply_stack (void) { Display *xdpy; GList *l; gint i; XserverRegion result; g_assert (mgr_singleton); xdpy = meta_plugin_get_xdisplay (mgr_singleton->plugin); if (mgr_singleton->current_region) XFixesDestroyRegion (xdpy, mgr_singleton->current_region); result = mgr_singleton->current_region = XFixesCreateRegion (xdpy, NULL, 0); for (i = 0; i <= MNB_INPUT_LAYER_TOP; ++i) { l = mgr_singleton->layers[i]; if (!l) continue; while (l) { MnbInputRegion *mir = l->data; if (mir->inverse) XFixesSubtractRegion (xdpy, result, result, mir->region); else XFixesUnionRegion (xdpy, result, result, mir->region); l = l->next; } } meta_plugin_set_stage_input_region (mgr_singleton->plugin, result); }
// 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() ); }