//______________________________________________________________________________ void ArgusWindow::CloseWindow() { if (fTabWindow) { gROME->WindowClosed(); } else { ArgusTab* tab = GetTabObjectAt(fCurrentTabIndex); ROMEString str; gROME->GetWindow()->SetSubWindowRunningAt(fWindowId, kFALSE); ClearEventHandlingRequest(); ClearEventHandlingForced(); // When a sub window is newly opened or it is closed, // calling TGMainFrame::CloseWindow() causes BadWindow // and/or BadDrawable error on X11, which terminates // the program. In order avoid this, just unmap the sub // window rather than closing it. This also makes it // possible to map the sub window again instead of // creating a new sub window. // TGMainFrame::CloseWindow(); UnmapWindow(); tab->SetRegisteringActive(true); if (!tab->IsTabActive()) { tab->UnRegisterObjects(); } } }
/* * Free one of the per-client per-window resources, clearing * redirect and the per-window pointer as appropriate */ void compFreeClientWindow (WindowPtr pWin, XID id) { CompWindowPtr cw = GetCompWindow (pWin); CompClientWindowPtr ccw, *prev; Bool wasMapped = pWin->mapped; if (!cw) return; for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next) { if (ccw->id == id) { *prev = ccw->next; if (ccw->update == CompositeRedirectManual) cw->update = CompositeRedirectAutomatic; free(ccw); break; } } if (!cw->clients) { if (wasMapped) { DisableMapUnmapEvents (pWin); UnmapWindow (pWin, FALSE); EnableMapUnmapEvents (pWin); } if (pWin->redirectDraw != RedirectDrawNone) compFreePixmap (pWin); if (cw->damage) DamageDestroy (cw->damage); RegionUninit(&cw->borderClip); dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL); free(cw); } else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone) { DamageRegister (&pWin->drawable, cw->damage); cw->damageRegistered = TRUE; pWin->redirectDraw = RedirectDrawAutomatic; DamageRegionAppend(&pWin->drawable, &pWin->borderSize); } if (wasMapped && !pWin->mapped) { Bool overrideRedirect = pWin->overrideRedirect; pWin->overrideRedirect = TRUE; DisableMapUnmapEvents (pWin); MapWindow (pWin, clients[CLIENT_ID(id)]); EnableMapUnmapEvents (pWin); pWin->overrideRedirect = overrideRedirect; } }
static int FreeCompositeClientOverlay (pointer value, XID ccwid) { CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; ScreenPtr pScreen = pOc->pScreen; CompScreenPtr cs; deleteCompOverlayClient(pOc, pScreen); /* Unmap overlay window when there are no more clients using it */ cs = GetCompScreen(pScreen); if (cs->pOverlayClients == NULL) { if (cs->pOverlayWin != NULL) { UnmapWindow(cs->pOverlayWin, FALSE); } } return Success; }
int ProcCompositeReleaseOverlayWindow (ClientPtr client) { REQUEST(xCompositeReleaseOverlayWindowReq); WindowPtr pWin; ScreenPtr pScreen; CompOverlayClientPtr pOc; CompScreenPtr cs; REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); if (!pWin) { client->errorValue = stuff->window; return BadWindow; } pScreen = pWin->drawable.pScreen; /* * Has client queried a reference to the overlay window * on this screen? If not, generate an error. */ pOc = findCompOverlayClient(client, pWin->drawable.pScreen); if (pOc == NULL) { return BadMatch; } FreeResource(pOc->resource, 0); cs = GetCompScreen(pScreen); if (cs->pOverlayClients == NULL) { UnmapWindow(cs->pOverlayWin, FALSE); } return client->noClientException; }
/* * Redirect one window for one client */ int compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update) { CompWindowPtr cw = GetCompWindow (pWin); CompClientWindowPtr ccw; Bool wasMapped = pWin->mapped; CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); if (pWin == cs->pOverlayWin) { return Success; } if (!pWin->parent) return BadMatch; /* * Only one Manual update is allowed */ if (cw && update == CompositeRedirectManual) for (ccw = cw->clients; ccw; ccw = ccw->next) if (ccw->update == CompositeRedirectManual) return BadAccess; /* * Allocate per-client per-window structure * The client *could* allocate multiple, but while supported, * it is not expected to be common */ ccw = malloc(sizeof (CompClientWindowRec)); if (!ccw) return BadAlloc; ccw->id = FakeClientID (pClient->index); ccw->update = update; /* * Now make sure there's a per-window structure to hang this from */ if (!cw) { cw = malloc(sizeof (CompWindowRec)); if (!cw) { free(ccw); return BadAlloc; } cw->damage = DamageCreate (compReportDamage, compDestroyDamage, DamageReportNonEmpty, FALSE, pWin->drawable.pScreen, pWin); if (!cw->damage) { free(ccw); free(cw); return BadAlloc; } if (wasMapped) { DisableMapUnmapEvents (pWin); UnmapWindow (pWin, FALSE); EnableMapUnmapEvents (pWin); } RegionNull(&cw->borderClip); cw->borderClipX = 0; cw->borderClipY = 0; cw->update = CompositeRedirectAutomatic; cw->clients = 0; cw->oldx = COMP_ORIGIN_INVALID; cw->oldy = COMP_ORIGIN_INVALID; cw->damageRegistered = FALSE; cw->damaged = FALSE; cw->pOldPixmap = NullPixmap; dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw); } ccw->next = cw->clients; cw->clients = ccw; if (!AddResource (ccw->id, CompositeClientWindowType, pWin)) return BadAlloc; if (ccw->update == CompositeRedirectManual) { /* If the window was CompositeRedirectAutomatic, then * unmap the window so that the parent clip list will * be correctly recomputed. */ if (pWin->mapped) { DisableMapUnmapEvents (pWin); UnmapWindow (pWin, FALSE); EnableMapUnmapEvents (pWin); } if (cw->damageRegistered) { DamageUnregister (&pWin->drawable, cw->damage); cw->damageRegistered = FALSE; } cw->update = CompositeRedirectManual; } if (!compCheckRedirect (pWin)) { FreeResource (ccw->id, RT_NONE); return BadAlloc; } if (wasMapped && !pWin->mapped) { Bool overrideRedirect = pWin->overrideRedirect; pWin->overrideRedirect = TRUE; DisableMapUnmapEvents (pWin); MapWindow (pWin, pClient); EnableMapUnmapEvents (pWin); pWin->overrideRedirect = overrideRedirect; } return Success; }
virtual void CloseWindow() { UnmapWindow(); // capture the close window }
void miSlideAndSizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, WindowPtr pSib) { WindowPtr pParent; Bool WasViewable = (Bool)(pWin->viewable); unsigned short width = pWin->drawable.width, height = pWin->drawable.height; short oldx = pWin->drawable.x, oldy = pWin->drawable.y; int bw = wBorderWidth (pWin); short dw, dh; DDXPointRec oldpt; RegionPtr oldRegion = NULL; Bool anyMarked = FALSE; ScreenPtr pScreen; WindowPtr pFirstChange; WindowPtr pChild; RegionPtr gravitate[StaticGravity + 1]; unsigned g; int nx, ny; /* destination x,y */ int newx, newy; /* new inner window position */ RegionPtr pRegion = NULL; RegionPtr destClip; /* portions of destination already written */ RegionPtr oldWinClip = NULL; /* old clip list for window */ RegionPtr borderVisible = NullRegion; /* visible area of the border */ Bool shrunk = FALSE; /* shrunk in an inner dimension */ Bool moved = FALSE; /* window position changed */ WindowPtr pLayerWin; /* if this is a root window, can't be resized */ if (!(pParent = pWin->parent)) return ; pScreen = pWin->drawable.pScreen; newx = pParent->drawable.x + x + bw; newy = pParent->drawable.y + y + bw; if (WasViewable) { anyMarked = FALSE; /* * save the visible region of the window */ oldRegion = REGION_CREATE(pScreen, NullBox, 1); REGION_COPY(pScreen, oldRegion, &pWin->winSize); /* * categorize child windows into regions to be moved */ for (g = 0; g <= StaticGravity; g++) gravitate[g] = (RegionPtr) NULL; for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { g = pChild->winGravity; if (g != UnmapGravity) { if (!gravitate[g]) gravitate[g] = REGION_CREATE(pScreen, NullBox, 1); REGION_UNION(pScreen, gravitate[g], gravitate[g], &pChild->borderClip); } else { UnmapWindow(pChild, TRUE); anyMarked = TRUE; } } anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin); oldWinClip = NULL; if (pWin->bitGravity != ForgetGravity) { oldWinClip = REGION_CREATE(pScreen, NullBox, 1); REGION_COPY(pScreen, oldWinClip, &pWin->clipList); } /* * if the window is changing size, borderExposed * can't be computed correctly without some help. */ if (pWin->drawable.height > h || pWin->drawable.width > w) shrunk = TRUE; if (newx != oldx || newy != oldy) moved = TRUE; if ((pWin->drawable.height != h || pWin->drawable.width != w) && HasBorder (pWin)) { borderVisible = REGION_CREATE(pScreen, NullBox, 1); /* for tiled borders, we punt and draw the whole thing */ if (pWin->borderIsPixel || !moved) { if (shrunk || moved) REGION_SUBTRACT(pScreen, borderVisible, &pWin->borderClip, &pWin->winSize); else REGION_COPY(pScreen, borderVisible, &pWin->borderClip); } } } pWin->origin.x = x + bw; pWin->origin.y = y + bw; pWin->drawable.height = h; pWin->drawable.width = w; x = pWin->drawable.x = newx; y = pWin->drawable.y = newy; SetWinSize (pWin); SetBorderSize (pWin); dw = (int)w - (int)width; dh = (int)h - (int)height; ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh); /* let the hardware adjust background and border pixmaps, if any */ (*pScreen->PositionWindow)(pWin, x, y); pFirstChange = MoveWindowInStack(pWin, pSib); if (WasViewable) { pRegion = REGION_CREATE(pScreen, NullBox, 1); if (pLayerWin == pWin) anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, NULL); else anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin, NULL); if (pWin->valdata) { pWin->valdata->before.resized = TRUE; pWin->valdata->before.borderVisible = borderVisible; } if (anyMarked) (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther); /* * the entire window is trashed unless bitGravity * recovers portions of it */ REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList); } GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); if (WasViewable) { /* avoid the border */ if (HasBorder (pWin)) { int offx, offy, dx, dy; /* kruft to avoid double translates for each gravity */ offx = 0; offy = 0; for (g = 0; g <= StaticGravity; g++) { if (!gravitate[g]) continue; /* align winSize to gravitate[g]. * winSize is in new coordinates, * gravitate[g] is still in old coordinates */ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); dx = (oldx - nx) - offx; dy = (oldy - ny) - offy; if (dx || dy) { REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy); offx += dx; offy += dy; } REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], &pWin->winSize); } /* get winSize back where it belongs */ if (offx || offy) REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy); } /* * add screen bits to the appropriate bucket */ if (oldWinClip) { /* * clip to new clipList */ REGION_COPY(pScreen, pRegion, oldWinClip); REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy); REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList); /* * don't step on any gravity bits which will be copied after this * region. Note -- this assumes that the regions will be copied * in gravity order. */ for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) { if (gravitate[g]) REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip, gravitate[g]); } REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny); g = pWin->bitGravity; if (!gravitate[g]) gravitate[g] = oldWinClip; else { REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip); REGION_DESTROY(pScreen, oldWinClip); } } /* * move the bits on the screen */ destClip = NULL; for (g = 0; g <= StaticGravity; g++) { if (!gravitate[g]) continue; GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny); oldpt.x = oldx + (x - nx); oldpt.y = oldy + (y - ny); /* Note that gravitate[g] is *translated* by CopyWindow */ /* only copy the remaining useful bits */ REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion); /* clip to not overwrite already copied areas */ if (destClip) { REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y); REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip); REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y); } /* and move those bits */ if (oldpt.x != x || oldpt.y != y #ifdef COMPOSITE || pWin->redirectDraw #endif ) { (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]); } /* remove any overwritten bits from the remaining useful bits */ REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]); /* * recompute exposed regions of child windows */ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { if (pChild->winGravity != g) continue; REGION_INTERSECT(pScreen, pRegion, &pChild->borderClip, gravitate[g]); TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion); } /* * remove the successfully copied regions of the * window from its exposed region */ if (g == pWin->bitGravity) REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed, &pWin->valdata->after.exposed, gravitate[g]); if (!destClip) destClip = gravitate[g]; else { REGION_UNION(pScreen, destClip, destClip, gravitate[g]); REGION_DESTROY(pScreen, gravitate[g]); } } REGION_DESTROY(pScreen, oldRegion); REGION_DESTROY(pScreen, pRegion); if (destClip) REGION_DESTROY(pScreen, destClip); if (anyMarked) (*pScreen->HandleExposures)(pLayerWin->parent); if (anyMarked && pScreen->PostValidateTree) (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, VTOther); } if (pWin->realized) WindowsRestructured (); }