static void scaleaddonScalePaintDecoration(CompWindow * w, const WindowPaintAttrib * attrib, const CompTransform * transform, Region region, unsigned int mask) { CompScreen *s = w->screen; ADDON_SCREEN(s); SCALE_SCREEN(s); ADDON_WINDOW(w); UNWRAP(as, ss, scalePaintDecoration); (*ss->scalePaintDecoration) (w, attrib, transform, region, mask); WRAP(as, ss, scalePaintDecoration, scaleaddonScalePaintDecoration); if ((ss->state == SCALE_STATE_WAIT) || (ss->state == SCALE_STATE_OUT)) { if (scaleaddonGetWindowHighlight(s)) { ADDON_DISPLAY(s->display); if (w->id == ad->highlightedWindow) scaleaddonDrawWindowHighlight(w); } if (aw->textData) scaleaddonDrawWindowTitle(w); } }
static void scaleaddonDonePaintScreen(CompScreen * s) { ADDON_SCREEN(s); SCALE_SCREEN(s); if (ss->state != SCALE_STATE_NONE && as->lastState == SCALE_STATE_NONE) { CompWindow *w; for (w = s->windows; w; w = w->next) scaleaddonRenderWindowTitle(w); } else if (ss->state == SCALE_STATE_NONE && as->lastState != SCALE_STATE_NONE) { CompWindow *w; for (w = s->windows; w; w = w->next) scaleaddonFreeWindowTitle(w); } if (ss->state == SCALE_STATE_OUT && as->lastState != SCALE_STATE_OUT) { ADDON_DISPLAY(s->display); ad->lastHighlightedWindow = None; scaleaddonCheckWindowHighlight(s); } as->lastState = ss->state; UNWRAP(as, s, donePaintScreen); (*s->donePaintScreen) (s); WRAP(as, s, donePaintScreen, scaleaddonDonePaintScreen); }
static void scaleaddonFiniScreen(CompPlugin * p, CompScreen * s) { ADDON_SCREEN(s); SCALE_SCREEN(s); UNWRAP(as, s, donePaintScreen); UNWRAP(as, ss, scalePaintDecoration); UNWRAP(as, ss, selectWindow); UNWRAP(as, ss, layoutSlotsAndAssignWindows); freeWindowPrivateIndex(s, as->windowPrivateIndex); free(as); }
static void scaleaddonSelectWindow(CompWindow * w) { CompScreen *s = w->screen; ADDON_DISPLAY(s->display); ADDON_SCREEN(s); SCALE_SCREEN(s); ad->highlightedWindow = w->id; scaleaddonCheckWindowHighlight(s); UNWRAP(as, ss, selectWindow); (*ss->selectWindow) (w); WRAP(as, ss, selectWindow, scaleaddonSelectWindow); }
static Bool scaleaddonInitWindow(CompPlugin * p, CompWindow * w) { ScaleAddonWindow *aw; ADDON_SCREEN(w->screen); aw = malloc(sizeof(ScaleAddonWindow)); if (!aw) return FALSE; aw->rescaled = FALSE; w->base.privates[as->windowPrivateIndex].ptr = aw; aw->textData = NULL; return TRUE; }
static double layoutOrganicCalculateOverlap(CompScreen * s, int win, int x, int y) { int i; int x1, y1, x2, y2; int overlapX, overlapY; int xMin, xMax, yMin, yMax; double result = -0.01; SCALE_SCREEN(s); ADDON_SCREEN(s); x1 = x; y1 = y; x2 = x1 + WIN_W(ss->windows[win]) * as->scale; y2 = y1 + WIN_H(ss->windows[win]) * as->scale; for (i = 0; i < ss->nWindows; i++) { if (i == win) continue; overlapX = overlapY = 0; xMax = MAX(ss->slots[i].x1, x1); xMin = MIN(ss->slots[i].x1 + WIN_W(ss->windows[i]) * as->scale, x2); if (xMax <= xMin) overlapX = xMin - xMax; yMax = MAX(ss->slots[i].y1, y1); yMin = MIN(ss->slots[i].y1 + WIN_H(ss->windows[i]) * as->scale, y2); if (yMax <= yMin) overlapY = yMin - yMax; result += (double)overlapX *overlapY; } return result; }
static void layoutOrganicRemoveOverlap (CompScreen *s, int areaWidth, int areaHeight) { int i, spacing; CompWindow *w; SCALE_SCREEN (s); ADDON_SCREEN (s); spacing = ss->opt[SCALE_SCREEN_OPTION_SPACING].value.i; while (layoutOrganicLocalSearch (s, areaWidth, areaHeight)) { for (i = 0; i < ss->nWindows; i++) { int centerX, centerY; int newX, newY, newWidth, newHeight; w = ss->windows[i]; centerX = ss->slots[i].x1 + WIN_W (w) / 2; centerY = ss->slots[i].y1 + WIN_H (w) / 2; newWidth = (int)((1.0 - ORGANIC_STEP) * (double)WIN_W (w)) - spacing / 2; newHeight = (int)((1.0 - ORGANIC_STEP) * (double)WIN_H (w)) - spacing / 2; newX = centerX - (newWidth / 2); newY = centerY - (newHeight / 2); ss->slots[i].x1 = newX; ss->slots[i].y1 = newY; ss->slots[i].x2 = newX + WIN_W (w); ss->slots[i].y2 = newY + WIN_H (w); } as->scale -= ORGANIC_STEP; } }
static Bool scaleaddonLayoutSlotsAndAssignWindows(CompScreen * s) { Bool status; ADDON_SCREEN(s); SCALE_SCREEN(s); switch (scaleaddonGetLayoutMode(s)) { case LayoutModeOrganicExperimental: status = layoutOrganicThumbs(s); break; case LayoutModeNormal: default: UNWRAP(as, ss, layoutSlotsAndAssignWindows); status = (*ss->layoutSlotsAndAssignWindows) (s); WRAP(as, ss, layoutSlotsAndAssignWindows, scaleaddonLayoutSlotsAndAssignWindows); break; } return status; }
static Bool layoutOrganicThumbs(CompScreen * s) { CompWindow *w; int i, moMode; XRectangle workArea; SCALE_SCREEN(s); ADDON_SCREEN(s); moMode = ss->opt[SCALE_SCREEN_OPTION_MULTIOUTPUT_MODE].value.i; switch (moMode) { case SCALE_MOMODE_ALL: workArea = s->workArea; break; case SCALE_MOMODE_CURRENT: default: workArea = s->outputDev[s->currentOutputDev].workArea; break; } as->scale = 1.0f; qsort(ss->windows, ss->nWindows, sizeof(CompWindow *), organicCompareWindows); for (i = 0; i < ss->nWindows; i++) { w = ss->windows[i]; SCALE_WINDOW(w); sw->slot = &ss->slots[i]; ss->slots[i].x1 = WIN_X(w) - workArea.x; ss->slots[i].y1 = WIN_Y(w) - workArea.y; ss->slots[i].x2 = WIN_X(w) + WIN_W(w) - workArea.x; ss->slots[i].y2 = WIN_Y(w) + WIN_H(w) - workArea.y; if (ss->slots[i].x1 < 0) { ss->slots[i].x2 += abs(ss->slots[i].x1); ss->slots[i].x1 = 0; } if (ss->slots[i].x2 > workArea.width - workArea.x) { ss->slots[i].x1 -= abs(ss->slots[i].x2 - workArea.width); ss->slots[i].x2 = workArea.width - workArea.x; } if (ss->slots[i].y1 < 0) { ss->slots[i].y2 += abs(ss->slots[i].y1); ss->slots[i].y1 = 0; } if (ss->slots[i].y2 > workArea.height - workArea.y) { ss->slots[i].y1 -= abs(ss->slots[i].y2 - workArea.height - workArea.y); ss->slots[i].y2 = workArea.height - workArea.y; } } ss->nSlots = ss->nWindows; layoutOrganicRemoveOverlap(s, workArea.width - workArea.x, workArea.height - workArea.y); for (i = 0; i < ss->nWindows; i++) { w = ss->windows[i]; SCALE_WINDOW(w); if (ss->type == ScaleTypeGroup) raiseWindow(ss->windows[i]); ss->slots[i].x1 += w->input.left + workArea.x; ss->slots[i].x2 += w->input.left + workArea.x; ss->slots[i].y1 += w->input.top + workArea.y; ss->slots[i].y2 += w->input.top + workArea.y; sw->adjust = TRUE; } return TRUE; }
static double layoutOrganicFindBestVerticalPosition(CompScreen * s, int win, int *bestY, int areaHeight) { int i, x1, x2, h; double bestOverlap = 1e31, overlap; SCALE_SCREEN(s); ADDON_SCREEN(s); x1 = ss->slots[win].x1; x2 = ss->slots[win].x1 + WIN_W(ss->windows[win]) * as->scale; h = WIN_H(ss->windows[win]) * as->scale; *bestY = ss->slots[win].y1; for (i = 0; i < ss->nWindows; i++) { CompWindow *w = ss->windows[i]; if (i == win) continue; if (ss->slots[i].x1 < x2 && ss->slots[i].x1 + WIN_W(w) * as->scale > x1) { if (ss->slots[i].y1 - h >= 0 && ss->slots[i].y1 < areaHeight) { overlap = layoutOrganicCalculateOverlap(s, win, x1, ss->slots[i]. y1 - h); if (overlap < bestOverlap) { *bestY = ss->slots[i].y1 - h; bestOverlap = overlap; } } if (WIN_H(w) * as->scale + ss->slots[i].y1 > 0 && WIN_H(w) * as->scale + h + ss->slots[i].y1 < areaHeight) { overlap = layoutOrganicCalculateOverlap(s, win, x1, WIN_H(w) * as->scale + ss->slots[i]. y1); if (overlap < bestOverlap) { *bestY = ss->slots[i].y1 + WIN_H(w) * as->scale; bestOverlap = overlap; } } } } overlap = layoutOrganicCalculateOverlap(s, win, x1, 0); if (overlap < bestOverlap) { *bestY = 0; bestOverlap = overlap; } overlap = layoutOrganicCalculateOverlap(s, win, x1, areaHeight - h); if (overlap < bestOverlap) { *bestY = areaHeight - h; bestOverlap = overlap; } return bestOverlap; }
static double layoutOrganicFindBestHorizontalPosition(CompScreen * s, int win, int *bestX, int areaWidth) { int i, y1, y2, w; double bestOverlap = 1e31, overlap; SCALE_SCREEN(s); ADDON_SCREEN(s); y1 = ss->slots[win].y1; y2 = ss->slots[win].y1 + WIN_H(ss->windows[win]) * as->scale; w = WIN_W(ss->windows[win]) * as->scale; *bestX = ss->slots[win].x1; for (i = 0; i < ss->nWindows; i++) { CompWindow *lw = ss->windows[i]; if (i == win) continue; if (ss->slots[i].y1 < y2 && ss->slots[i].y1 + WIN_H(lw) * as->scale > y1) { if (ss->slots[i].x1 - w >= 0) { overlap = layoutOrganicCalculateOverlap(s, win, ss-> slots [i].x1 - w, y1); if (overlap < bestOverlap) { *bestX = ss->slots[i].x1 - w; bestOverlap = overlap; } } if (WIN_W(lw) * as->scale + ss->slots[i].x1 + w < areaWidth) { overlap = layoutOrganicCalculateOverlap(s, win, ss->slots[i]. x1 + WIN_W(lw) * as->scale, y1); if (overlap < bestOverlap) { *bestX = ss->slots[i].x1 + WIN_W(lw) * as->scale; bestOverlap = overlap; } } } } overlap = layoutOrganicCalculateOverlap(s, win, 0, y1); if (overlap < bestOverlap) { *bestX = 0; bestOverlap = overlap; } overlap = layoutOrganicCalculateOverlap(s, win, areaWidth - w, y1); if (overlap < bestOverlap) { *bestX = areaWidth - w; bestOverlap = overlap; } return bestOverlap; }