/* lpStruct - (REGION32) Destination Region */ DWORD DrvRegionsXORRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct) { XXorRegion((Region)dwParm1, (Region)dwParm2, (Region)lpStruct); return (DWORD)(XEmptyRegion((Region)lpStruct)? NULLREGION:COMPLEXREGION); }
static PyObject * region_EmptyRegion(PaxRegionObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; return PyInt_FromLong(XEmptyRegion(self->region)); }
static void fxDodgeProcessSubject (CompWindow *wCur, Region wRegion, Region dodgeRegion, Bool alwaysInclude) { XRectangle rect; rect.x = WIN_X(wCur); rect.y = WIN_Y(wCur); rect.width = WIN_W(wCur); rect.height = WIN_H(wCur); Region wCurRegion = XCreateRegion(); if (!wCurRegion) return; XUnionRectWithRegion(&rect, &emptyRegion, wCurRegion); if (!alwaysInclude) { Region intersectionRegion = XCreateRegion(); if (intersectionRegion) { XIntersectRegion(wRegion, wCurRegion, intersectionRegion); if (!XEmptyRegion(intersectionRegion)) XUnionRegion(dodgeRegion, wCurRegion, dodgeRegion); XDestroyRegion (intersectionRegion); } } else XUnionRegion(dodgeRegion, wCurRegion, dodgeRegion); XDestroyRegion (wCurRegion); }
bool wxRegion::IsEmpty() const { if (!m_refData) return true; return XEmptyRegion( M_REGIONDATA->m_region ) == True; }
// Return true if region is empty FXbool FXRegion::empty() const { #ifdef WIN32 return OffsetRgn((HRGN)region,0,0)==NULLREGION; #else return XEmptyRegion((Region)region); #endif }
/* lpStruct - Destination Region */ DWORD DrvRegionsDiffRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct) { XSubtractRegion((Region)dwParm1, (Region)dwParm2, (Region)lpStruct); return (DWORD)(XEmptyRegion((Region)lpStruct)? NULLREGION:COMPLEXREGION); }
bool wxRegion::Empty() const { if (!m_refData) return TRUE; #if 0 return XEmptyRegion( M_REGIONDATA->m_region ); #endif }
EAPI Eina_Bool ecore_x_xregion_is_empty(Ecore_X_XRegion *region) { if (!region) return EINA_TRUE; LOGFN(__FILE__, __LINE__, __FUNCTION__); return XEmptyRegion((Region)region) ? EINA_TRUE : EINA_FALSE; } /* ecore_x_xregion_is_empty */
/* dwParm2 - Destination Region */ DWORD DrvRegionsCopyRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct) { static Region EmptyRegion; if (EmptyRegion == None) EmptyRegion = XCreateRegion(); XUnionRegion((Region)dwParm1, EmptyRegion,(Region)dwParm2); return (DWORD)(XEmptyRegion((Region)dwParm2)? NULLREGION:COMPLEXREGION); }
/* lpStruct - Pointer to RECT */ DWORD DrvRegionsUnionRectWithRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct) { LPRECT lpRect; XRectangle xRect; if (!(lpRect = (LPRECT)lpStruct)) return (DWORD)ERROR; xRect.x = lpRect->left; xRect.y = lpRect->top; xRect.width = lpRect->right - lpRect->left; xRect.height = lpRect->bottom - lpRect->top; XUnionRectWithRegion(&xRect, (Region)dwParm1, (Region)dwParm1); return (DWORD)(XEmptyRegion((Region)dwParm1)? NULLREGION:COMPLEXREGION); }
int TkScrollWindow( Tk_Window tkwin, /* The window to be scrolled. */ GC gc, /* GC for window to be scrolled. */ int x, int y, int width, int height, /* Position rectangle to be scrolled. */ int dx, int dy, /* Distance rectangle should be moved. */ TkRegion damageRgn) /* Region to accumulate damage in. */ { Tk_RestrictProc *oldProc; ClientData oldArg, dummy; ScrollInfo info; XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc, x, y, (unsigned) width, (unsigned) height, x+dx, y+dy); info.done = 0; info.window = Tk_WindowId(tkwin); info.display = Tk_Display(tkwin); info.region = damageRgn; info.dx = dx; info.dy = dy; /* * Sync the event stream so all of the expose events will be on the Tk * event queue before we start filtering. This avoids busy waiting while * we filter events. */ TkpSync(info.display); oldProc = Tk_RestrictEvents(ScrollRestrictProc, (ClientData) &info, &oldArg); while (!info.done) { Tcl_ServiceEvent(TCL_WINDOW_EVENTS); } Tk_RestrictEvents(oldProc, oldArg, &dummy); if (XEmptyRegion((Region) damageRgn)) { return 0; } else { return 1; } }
/* Walk through all windows, skip until we've passed the active * window, skip if it's invisible, hidden or minimized, skip if * it's not a window type we're looking for. * Dim it if it intersects. * * Returns number of changed windows. */ static int passiveWindows (CompScreen *s, Region region) { CompWindow *w; Bool flag = FALSE; int i = 0; OPACIFY_SCREEN (s); for (w = s->windows; w; w = w->next) { if (w->id == os->active) { flag = TRUE; continue; } if (!flag) continue; if (!matchEval (&os->window_match, w)) continue; if (w->invisible || w->hidden || w->minimized) continue; XIntersectRegion (w->region, region, os->intersect); if (!XEmptyRegion (os->intersect)) { dimWindow (w); i++; } } return i; }
*/ static void process_gobs(REBCMP_CTX* ctx, REBGOB* gob) /* ** Recursively process and compose gob and its children. ** ** NOTE: this function is used internally by rebcmp_compose() call only. ** ***********************************************************************/ { //RL_Print("process_gobs: %x\n", gob); REBINT x = ROUND_TO_INT(ctx->absOffset.x); REBINT y = ROUND_TO_INT(ctx->absOffset.y); REBYTE* color; Region saved_win_region = XCreateRegion(); if (GET_GOB_STATE(gob, GOBS_NEW)){ //reset old-offset and old-size if newly added GOB_XO(gob) = GOB_LOG_X(gob); GOB_YO(gob) = GOB_LOG_Y(gob); GOB_WO(gob) = GOB_LOG_W(gob); GOB_HO(gob) = GOB_LOG_H(gob); CLR_GOB_STATE(gob, GOBS_NEW); } //intersect gob dimensions with actual window clip region REBOOL valid_intersection = 1; //------------------------------ //Put backend specific code here //------------------------------ XRectangle rect; rect.x = x; rect.y = y; rect.width = GOB_LOG_W(gob); rect.height = GOB_LOG_H(gob); /* RL_Print("gob , left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n", rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); */ Region reg = XCreateRegion(); XUnionRectWithRegion(&rect, reg, reg); /* XClipBox(ctx->Win_Region, &rect); RL_Print("Win Region , left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n", rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); */ XUnionRegion(saved_win_region, ctx->Win_Region, saved_win_region); XIntersectRegion(reg, ctx->Win_Region, ctx->Win_Region); XClipBox(ctx->Win_Region, &rect); /* RL_Print("Win and Gob, left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n", rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); */ //get the current Window clip box REBRECT gob_clip = { rect.x, //left rect.y, //top rect.width + rect.x, //right rect.height + rect.y //bottom /* GOB_LOG_X(gob), //left GOB_LOG_Y(gob), //top GOB_LOG_W(gob) + GOB_LOG_X(gob), //right GOB_LOG_H(gob) + GOB_LOG_Y(gob), //bottom */ }; //RL_Print("Window_Buffer: 0x%x\n", ctx->Window_Buffer); /* RL_Print("gob clip , left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n", gob_clip.left, gob_clip.top, gob_clip.right, gob_clip.bottom); */ if (!XEmptyRegion(ctx->Win_Region)) //if (valid_intersection) { //render GOB content switch (GOB_TYPE(gob)) { case GOBT_COLOR: //------------------------------ //Put backend specific code here //------------------------------ // or use the similar draw api call: //RL_Print("Draw Color at: %d, %d\n", x, y); rebdrw_gob_color(gob, ctx->Window_Buffer, ctx->winBufSize, (REBXYI){x,y}, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom}); break; case GOBT_IMAGE: { //RL_Print("Draw Image\n"); //------------------------------ //Put backend specific code here //------------------------------ // or use the similar draw api call: rebdrw_gob_image(gob, ctx->Window_Buffer, ctx->winBufSize, (REBXYI){x,y}, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom}); } break; case GOBT_DRAW: { //RL_Print("Draw Draw at: %d, %d\n", x, y); //------------------------------ //Put backend specific code here //------------------------------ // or use the similar draw api call: rebdrw_gob_draw(gob, ctx->Window_Buffer ,ctx->winBufSize, (REBXYI){x,y}, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom}); } break; case GOBT_TEXT: case GOBT_STRING: //RL_Print("Draw Text at: %d, %d\n", x, y); //------------------------------ //Put backend specific code here //------------------------------ // or use the similar draw api call: rt_gob_text(gob, ctx->Window_Buffer ,ctx->winBufSize,ctx->absOffset, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom}); break; case GOBT_EFFECT: //RL_Print("Draw Effect\n"); //not yet implemented break; } //recursively process sub GOBs if (GOB_PANE(gob)) { REBINT n; REBINT len = GOB_TAIL(gob); REBGOB **gp = GOB_HEAD(gob); for (n = 0; n < len; n++, gp++) { REBINT g_x = GOB_LOG_X(*gp); REBINT g_y = GOB_LOG_Y(*gp); //restore the "parent gob" clip region //------------------------------ //Put backend specific code here //------------------------------ ctx->absOffset.x += g_x; ctx->absOffset.y += g_y; process_gobs(ctx, *gp); ctx->absOffset.x -= g_x; ctx->absOffset.y -= g_y; } } } XDestroyRegion(reg); XDestroyRegion(ctx->Win_Region); ctx->Win_Region = saved_win_region; }
/* * groupHandleButtonReleaseEvent * */ static void groupHandleButtonReleaseEvent (CompScreen *s, XEvent *event) { GroupSelection *group; int vx, vy; Region newRegion; Bool inserted = FALSE; Bool wasInTabBar = FALSE; GROUP_SCREEN (s); if (event->xbutton.button != 1) return; if (!gs->draggedSlot) return; if (!gs->dragged) { groupChangeTab (gs->draggedSlot, RotateUncertain); gs->draggedSlot = NULL; if (gs->grabState == ScreenGrabTabDrag) groupGrabScreen (s, ScreenGrabNone); return; } GROUP_WINDOW (gs->draggedSlot->window); newRegion = XCreateRegion (); if (!newRegion) return; XUnionRegion (newRegion, gs->draggedSlot->region, newRegion); groupGetDrawOffsetForSlot (gs->draggedSlot, &vx, &vy); XOffsetRegion (newRegion, vx, vy); for (group = gs->groups; group; group = group->next) { Bool inTabBar; Region clip, buf; GroupTabBarSlot *slot; if (!group->tabBar || !HAS_TOP_WIN (group)) continue; /* create clipping region */ clip = groupGetClippingRegion (TOP_TAB (group)); if (!clip) continue; buf = XCreateRegion (); if (!buf) { XDestroyRegion (clip); continue; } XIntersectRegion (newRegion, group->tabBar->region, buf); XSubtractRegion (buf, clip, buf); XDestroyRegion (clip); inTabBar = !XEmptyRegion (buf); XDestroyRegion (buf); if (!inTabBar) continue; wasInTabBar = TRUE; for (slot = group->tabBar->slots; slot; slot = slot->next) { GroupTabBarSlot *tmpDraggedSlot; GroupSelection *tmpGroup; Region slotRegion, buf; XRectangle rect; Bool inSlot; if (slot == gs->draggedSlot) continue; slotRegion = XCreateRegion (); if (!slotRegion) continue; if (slot->prev && slot->prev != gs->draggedSlot) { rect.x = slot->prev->region->extents.x2; } else if (slot->prev && slot->prev == gs->draggedSlot && gs->draggedSlot->prev) { rect.x = gs->draggedSlot->prev->region->extents.x2; } else rect.x = group->tabBar->region->extents.x1; rect.y = slot->region->extents.y1; if (slot->next && slot->next != gs->draggedSlot) { rect.width = slot->next->region->extents.x1 - rect.x; } else if (slot->next && slot->next == gs->draggedSlot && gs->draggedSlot->next) { rect.width = gs->draggedSlot->next->region->extents.x1 - rect.x; } else rect.width = group->tabBar->region->extents.x2; rect.height = slot->region->extents.y2 - slot->region->extents.y1; XUnionRectWithRegion (&rect, slotRegion, slotRegion); buf = XCreateRegion (); if (!buf) continue; XIntersectRegion (newRegion, slotRegion, buf); inSlot = !XEmptyRegion (buf); XDestroyRegion (buf); XDestroyRegion (slotRegion); if (!inSlot) continue; tmpDraggedSlot = gs->draggedSlot; if (group != gw->group) { CompWindow *w = gs->draggedSlot->window; GroupSelection *tmpGroup = gw->group; int oldPosX = WIN_CENTER_X (w); int oldPosY = WIN_CENTER_Y (w); /* if the dragged window is not the top tab, move it onscreen */ if (tmpGroup->topTab && !IS_TOP_TAB (w, tmpGroup)) { CompWindow *tw = TOP_TAB (tmpGroup); oldPosX = WIN_CENTER_X (tw) + gw->mainTabOffset.x; oldPosY = WIN_CENTER_Y (tw) + gw->mainTabOffset.y; groupSetWindowVisibility (w, TRUE); } /* Change the group. */ groupDeleteGroupWindow (gs->draggedSlot->window); groupAddWindowToGroup (gs->draggedSlot->window, group, 0); /* we saved the original center position in oldPosX/Y before - now we should apply that to the new main tab offset */ if (HAS_TOP_WIN (group)) { CompWindow *tw = TOP_TAB (group); gw->mainTabOffset.x = oldPosX - WIN_CENTER_X (tw); gw->mainTabOffset.y = oldPosY - WIN_CENTER_Y (tw); } } else groupUnhookTabBarSlot (group->tabBar, gs->draggedSlot, TRUE); gs->draggedSlot = NULL; gs->dragged = FALSE; inserted = TRUE; if ((tmpDraggedSlot->region->extents.x1 + tmpDraggedSlot->region->extents.x2 + (2 * vx)) / 2 > (slot->region->extents.x1 + slot->region->extents.x2) / 2) { groupInsertTabBarSlotAfter (group->tabBar, tmpDraggedSlot, slot); } else groupInsertTabBarSlotBefore (group->tabBar, tmpDraggedSlot, slot); groupDamageTabBarRegion (group); /* Hide tab-bars. */ for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next) { if (group == tmpGroup) groupTabSetVisibility (tmpGroup, TRUE, 0); else groupTabSetVisibility (tmpGroup, FALSE, PERMANENT); } break; } if (inserted) break; } XDestroyRegion (newRegion); if (!inserted) { CompWindow *draggedSlotWindow = gs->draggedSlot->window; GroupSelection *tmpGroup; for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next) groupTabSetVisibility (tmpGroup, FALSE, PERMANENT); gs->draggedSlot = NULL; gs->dragged = FALSE; const BananaValue * option_dnd_ungroup_window = bananaGetOption (bananaIndex, "dnd_ungroup_window", s->screenNum); if (option_dnd_ungroup_window->b && !wasInTabBar) { groupRemoveWindowFromGroup (draggedSlotWindow); } else if (gw->group && gw->group->topTab) { groupRecalcTabBarPos (gw->group, (gw->group->tabBar->region->extents.x1 + gw->group->tabBar->region->extents.x2) / 2, gw->group->tabBar->region->extents.x1, gw->group->tabBar->region->extents.x2); } /* to remove the painted slot */ damageScreen (s); } if (gs->grabState == ScreenGrabTabDrag) groupGrabScreen (s, ScreenGrabNone); if (gs->dragHoverTimeoutHandle) { compRemoveTimeout (gs->dragHoverTimeoutHandle); gs->dragHoverTimeoutHandle = 0; } }
/* dwParm1 - dwParm1 - (REGION32) Region */ DWORD DrvRegionsIsEmptyRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct) { return (DWORD)XEmptyRegion((Region)dwParm1); }
static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h) { XTransform transform; Picture windowPicture; Picture primaryPicture; XRenderPictureAttributes pa; XRenderPictFormat* picFormat; double xScalingFactor; double yScalingFactor; int x2; int y2; if (xfc->scaledWidth <= 0 || xfc->scaledHeight <= 0) { WLog_ERR(TAG, "the current window dimensions are invalid"); return; } if (xfc->sessionWidth <= 0 || xfc->sessionHeight <= 0) { WLog_ERR(TAG, "the window dimensions are invalid"); return; } xScalingFactor = xfc->sessionWidth / (double)xfc->scaledWidth; yScalingFactor = xfc->sessionHeight / (double)xfc->scaledHeight; XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, 0); /* Black out possible space between desktop and window borders */ { XRectangle box1 = { 0, 0, xfc->window->width, xfc->window->height }; XRectangle box2 = { xfc->offset_x, xfc->offset_y, xfc->scaledWidth, xfc->scaledHeight }; Region reg1 = XCreateRegion(); Region reg2 = XCreateRegion(); XUnionRectWithRegion(&box1, reg1, reg1); XUnionRectWithRegion(&box2, reg2, reg2); if (XSubtractRegion(reg1, reg2, reg1) && !XEmptyRegion(reg1)) { XSetRegion(xfc->display, xfc->gc, reg1); XFillRectangle(xfc->display, xfc->window->handle, xfc->gc, 0, 0, xfc->window->width, xfc->window->height); XSetClipMask(xfc->display, xfc->gc, None); } XDestroyRegion(reg1); XDestroyRegion(reg2); } picFormat = XRenderFindVisualFormat(xfc->display, xfc->visual); pa.subwindow_mode = IncludeInferiors; primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, CPSubwindowMode, &pa); windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, picFormat, CPSubwindowMode, &pa); XRenderSetPictureFilter(xfc->display, primaryPicture, FilterBilinear, 0, 0); transform.matrix[0][0] = XDoubleToFixed(xScalingFactor); transform.matrix[0][1] = XDoubleToFixed(0.0); transform.matrix[0][2] = XDoubleToFixed(0.0); transform.matrix[1][0] = XDoubleToFixed(0.0); transform.matrix[1][1] = XDoubleToFixed(yScalingFactor); transform.matrix[1][2] = XDoubleToFixed(0.0); transform.matrix[2][0] = XDoubleToFixed(0.0); transform.matrix[2][1] = XDoubleToFixed(0.0); transform.matrix[2][2] = XDoubleToFixed(1.0); /* calculate and fix up scaled coordinates */ x2 = x + w; y2 = y + h; x = floor(x / xScalingFactor) - 1; y = floor(y / yScalingFactor) - 1; w = ceil(x2 / xScalingFactor) + 1 - x; h = ceil(y2 / yScalingFactor) + 1 - y; XRenderSetPictureTransform(xfc->display, primaryPicture, &transform); XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, x, y, 0, 0, xfc->offset_x + x, xfc->offset_y + y, w, h); XRenderFreePicture(xfc->display, primaryPicture); XRenderFreePicture(xfc->display, windowPicture); }
Bool apc_region_is_empty( Handle self) { return XEmptyRegion( REGION ); }
sBool sXUpdateEmpty() { return XEmptyRegion(UpdateRegion) != 0; }
/* * Loop on outputDevs and add the extents as edges * Note that left side is a right edge, right side a left edge, * top side a bottom edge and bottom side a top edge, * since they will be snapped as the right/left/bottom/top edge of a window */ static void snapUpdateScreenEdges(CompWindow * w) { CompWindow *c = NULL; Edge *e = NULL, *next = NULL; SNAP_WINDOW(w); Region edgeRegion, resultRegion; XRectangle rect; Bool remove = FALSE; XRectangle area; int i; for (i = 0; i < w->screen->nOutputDev; i++) { snapScreenGetOutputDevRect(w->screen, i, &area); snapAddEdge(&sw->edges, &sw->reverseEdges, 0, area.y, area.x, area.x + area.width - 1, BottomEdge, TRUE); snapAddEdge(&sw->edges, &sw->reverseEdges, 0, area.y + area.height, area.x, area.x + area.width - 1, TopEdge, TRUE); snapAddEdge(&sw->edges, &sw->reverseEdges, 0, area.x, area.y, area.y + area.height - 1, RightEdge, TRUE); snapAddEdge(&sw->edges, &sw->reverseEdges, 0, area.x + area.width, area.y, area.y + area.height - 1, LeftEdge, TRUE); } // Drop screen edges parts that are under struts, basically apply the // same strategy than for windows edges visibility for (c = w->screen->windows; c; c = c->next) { if (c == w || !c->struts) continue; for (e = sw->edges; e; e = next) { if (!e->screenEdge) { next = e->next; continue; } switch (e->type) { case LeftEdge: case RightEdge: rect.x = e->position; rect.y = e->start; rect.width = 1; rect.height = e->end - e->start; break; case TopEdge: case BottomEdge: default: rect.x = e->start; rect.y = e->position; rect.width = e->end - e->start; rect.height = 1; } edgeRegion = XCreateRegion(); resultRegion = XCreateRegion(); XUnionRectWithRegion(&rect, edgeRegion, edgeRegion); XSubtractRegion(edgeRegion, c->region, resultRegion); if (XEmptyRegion(resultRegion)) remove = TRUE; else if (!XEqualRegion(edgeRegion, resultRegion)) { snapAddRegionEdges(sw, e, resultRegion); remove = TRUE; } next = e->next; if (remove) { if (e->prev == NULL) sw->edges = e->next; if (e->next == NULL) sw->reverseEdges = e->prev; snapRemoveEdge(e); remove = FALSE; } XDestroyRegion(resultRegion); XDestroyRegion(edgeRegion); } } }
bool CompRegion::isEmpty () const { return XEmptyRegion (handle ()); }
*/ void rebcmp_compose(REBCMP_CTX* ctx, REBGOB* winGob, REBGOB* gob, REBOOL only) /* ** Compose content of the specified gob. Main compositing function. ** ** If the ONLY arg is TRUE then the specified gob area will be ** rendered to the buffer at 0x0 offset.(used by TO-IMAGE) ** ***********************************************************************/ { REBINT max_depth = 1000; // avoid infinite loops REBD32 abs_x = 0; REBD32 abs_y = 0; REBD32 abs_ox; REBD32 abs_oy; REBGOB* parent_gob = gob; REBINT x = GOB_LOG_X_INT(gob); REBINT y = GOB_LOG_Y_INT(gob); REBINT w = GOB_LOG_W_INT(gob); REBINT h = GOB_LOG_H_INT(gob); /* RL_Print("Composing gob: %x (%dx%d, %dx%d) in wingob %x\n", gob, (int)GOB_LOG_X(gob), (int)GOB_LOG_Y(gob), GOB_W_INT(gob), GOB_H_INT(gob), winGob); */ //reset clip region to window area if (ctx->Win_Region != NULL){ XDestroyRegion(ctx->Win_Region); } ctx->Win_Region = XCreateRegion(); //calculate absolute offset of the gob while (GOB_PARENT(parent_gob) && (max_depth-- > 0) && !GET_GOB_FLAG(parent_gob, GOBF_WINDOW)) { abs_x += GOB_LOG_X(parent_gob); abs_y += GOB_LOG_Y(parent_gob); parent_gob = GOB_PARENT(parent_gob); } assert(max_depth > 0); //the offset is shifted to render given gob at offset 0x0 (used by TO-IMAGE) if (only){ ctx->absOffset.x = -abs_x; ctx->absOffset.y = -abs_y; abs_x = 0; abs_y = 0; } else { ctx->absOffset.x = 0; ctx->absOffset.y = 0; } ctx->New_Clip.x = abs_x; ctx->New_Clip.y = abs_y; ctx->New_Clip.width = GOB_LOG_W_INT(gob); ctx->New_Clip.height = GOB_LOG_H_INT(gob); //handle newly added gob case if (!GET_GOB_STATE(gob, GOBS_NEW)){ //calculate absolute old offset of the gob abs_ox = abs_x + (GOB_XO(gob) - GOB_LOG_X(gob)); abs_oy = abs_y + (GOB_YO(gob) - GOB_LOG_Y(gob)); //set region with old gob location and dimensions ctx->Old_Clip.x = abs_ox; ctx->Old_Clip.y = abs_oy; ctx->Old_Clip.width = GOB_WO_INT(gob); ctx->Old_Clip.height = GOB_HO_INT(gob); XUnionRectWithRegion(&ctx->Old_Clip, ctx->Win_Region, ctx->Win_Region); //RL_Print("OLD: %dx%d %dx%d\n",(REBINT)abs_ox, (REBINT)abs_oy, (REBINT)abs_ox + GOB_WO_INT(gob), (REBINT)abs_oy + GOB_HO_INT(gob)); } //RL_Print("NEW: %dx%d %dx%d\n",(REBINT)abs_x, (REBINT)abs_y, (REBINT)abs_x + GOB_LOG_W_INT(gob), (REBINT)abs_y + GOB_LOG_H_INT(gob)); //Create union of "new" and "old" gob location XUnionRectWithRegion(&ctx->New_Clip, ctx->Win_Region, ctx->Win_Region); /* XClipBox(ctx->Win_Region, &win_rect); RL_Print("Old+New, %dx%d,%dx%d\n", win_rect.x, win_rect.y, win_rect.x + win_rect.width, win_rect.y + win_rect.height); */ if (!XEmptyRegion(ctx->Win_Region)) { swap_buffer(ctx); ctx->Window_Buffer = rebcmp_get_buffer(ctx); if (gob == winGob) { memset(ctx->Window_Buffer, 0, ctx->pixbuf_len); } //redraw gobs process_gobs(ctx, winGob); rebcmp_release_buffer(ctx); ctx->Window_Buffer = NULL; } //update old GOB area GOB_XO(gob) = GOB_LOG_X(gob); GOB_YO(gob) = GOB_LOG_Y(gob); GOB_WO(gob) = GOB_LOG_W(gob); GOB_HO(gob) = GOB_LOG_H(gob); }
/* * Detect visible windows edges */ static void snapUpdateWindowsEdges(CompWindow * w) { CompWindow *c = NULL; Edge *e = NULL, *next = NULL; SNAP_WINDOW(w); Region edgeRegion, resultRegion; XRectangle rect; Bool remove = FALSE; // First add all the windows c = w->screen->windows; while (c) { // Just check that we're not trying to snap to current window, // that the window is not invisible and of a valid type if (c == w || !isSnapWindow(c)) { c = c->next; continue; } snapAddEdge(&sw->edges, &sw->reverseEdges, c->id, WIN_Y(c), WIN_X(c), WIN_X(c) + WIN_W(c), TopEdge, FALSE); snapAddEdge(&sw->edges, &sw->reverseEdges, c->id, WIN_Y(c) + WIN_H(c), WIN_X(c), WIN_X(c) + WIN_W(c), BottomEdge, FALSE); snapAddEdge(&sw->edges, &sw->reverseEdges, c->id, WIN_X(c), WIN_Y(c), WIN_Y(c) + WIN_H(c), LeftEdge, FALSE); snapAddEdge(&sw->edges, &sw->reverseEdges, c->id, WIN_X(c) + WIN_W(c), WIN_Y(c), WIN_Y(c) + WIN_H(c), RightEdge, FALSE); c = c->next; } // Now strip invisible edges // Loop through all the windows stack, and through all the edges // If an edge has been passed, check if it's in the region window, // if the edge is fully under the window, drop it, or if it's only // partly covered, cut it/split it in one/two smaller visible edges for (c = w->screen->windows; c; c = c->next) { if (c == w || !isSnapWindow(c)) continue; for (e = sw->edges; e; e = next) { if (!e->passed) { if (e->id == c->id) e->passed = TRUE; next = e->next; continue; } switch (e->type) { case LeftEdge: case RightEdge: rect.x = e->position; rect.y = e->start; rect.width = 1; rect.height = e->end - e->start; break; case TopEdge: case BottomEdge: default: rect.x = e->start; rect.y = e->position; rect.width = e->end - e->start; rect.height = 1; } // If the edge is in the window region, remove it, // if it's partly in the region, split it edgeRegion = XCreateRegion(); resultRegion = XCreateRegion(); XUnionRectWithRegion(&rect, edgeRegion, edgeRegion); XSubtractRegion(edgeRegion, c->region, resultRegion); if (XEmptyRegion(resultRegion)) remove = TRUE; else if (!XEqualRegion(edgeRegion, resultRegion)) { snapAddRegionEdges(sw, e, resultRegion); remove = TRUE; } next = e->next; if (remove) { if (e->prev == NULL) sw->edges = e->next; if (e->next == NULL) sw->reverseEdges = e->prev; snapRemoveEdge(e); remove = FALSE; } XDestroyRegion(resultRegion); XDestroyRegion(edgeRegion); } } }