static void scaleaddonHandleEvent (CompDisplay *d, XEvent *event) { ADDON_DISPLAY (d); UNWRAP (ad, d, handleEvent); (*d->handleEvent) (d, event); WRAP (ad, d, handleEvent, scaleaddonHandleEvent); switch (event->type) { case PropertyNotify: { if (event->xproperty.atom == XA_WM_NAME) { CompWindow *w; w = findWindowAtDisplay (d, event->xproperty.window); if (w) { SCALE_SCREEN (w->screen); if (ss->grabIndex) { scaleaddonRenderWindowTitle (w); addWindowDamage (w); } } } } break; case MotionNotify: { CompScreen *s; s = findScreenAtDisplay (d, event->xmotion.root); if (s) { SCALE_SCREEN (s); if (ss->grabIndex) { SCALE_DISPLAY (d); ad->highlightedWindow = sd->hoveredWindow; scaleaddonCheckWindowHighlight (s); } } } break; default: break; } }
static void scalefilterInitFilterInfo (CompScreen *s) { FILTER_SCREEN (s); SCALE_SCREEN (s); ScaleFilterInfo *info = fs->filterInfo; memset (info->filterString, 0, sizeof (info->filterString)); info->filterStringLength = 0; info->textPixmap = None; info->textWidth = 0; info->textHeight = 0; info->timeoutHandle = 0; info->outputDevice = s->currentOutputDev; initTexture (s, &info->textTexture); matchInit (&info->match); matchCopy (&info->match, &fs->scaleMatch); info->origMatch = ss->currentMatch; ss->currentMatch = &info->match; }
static Bool scaleaddonCloseWindow(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption) { CompScreen *s; Window xid; xid = getIntOptionNamed(option, nOption, "root", 0); s = findScreenAtDisplay(d, xid); if (s) { CompWindow *w; SCALE_SCREEN(s); ADDON_DISPLAY(d); if (!ss->grabIndex) return FALSE; w = findWindowAtDisplay(d, ad->highlightedWindow); if (w) { closeWindow(w, getCurrentTimeFromDisplay(d)); return TRUE; } } return FALSE; }
static Bool scalefilterSetScaledPaintAttributes (CompWindow *w, WindowPaintAttrib *attrib) { Bool ret; FILTER_SCREEN (w->screen); SCALE_SCREEN (w->screen); UNWRAP (fs, ss, setScaledPaintAttributes); ret = (*ss->setScaledPaintAttributes) (w, attrib); WRAP (fs, ss, setScaledPaintAttributes, scalefilterSetScaledPaintAttributes); if (fs->matchApplied || (fs->filterInfo && fs->filterInfo->filterStringLength)) { SCALE_WINDOW (w); if (ret && !sw->slot) { ret = FALSE; attrib->opacity = 0; } } return ret; }
static Bool scalefilterInitScreen (CompPlugin *p, CompScreen *s) { ScaleFilterScreen *fs; FILTER_DISPLAY (s->display); SCALE_SCREEN (s); fs = malloc (sizeof (ScaleFilterScreen)); if (!fs) return FALSE; fs->filterInfo = NULL; matchInit (&fs->scaleMatch); fs->matchApplied = FALSE; WRAP (fs, s, paintOutput, scalefilterPaintOutput); WRAP (fs, ss, setScaledPaintAttributes, scalefilterSetScaledPaintAttributes); scalefilterSetFontBoldNotify (s, scalefilterScreenOptionChanged); scalefilterSetFontSizeNotify (s, scalefilterScreenOptionChanged); scalefilterSetFontColorNotify (s, scalefilterScreenOptionChanged); scalefilterSetBackColorNotify (s, scalefilterScreenOptionChanged); s->privates[fd->screenPrivateIndex].ptr = fs; return TRUE; }
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 scalefilterHandleEvent (CompDisplay *d, XEvent *event) { FILTER_DISPLAY (d); switch (event->type) { case KeyPress: { CompScreen *s; s = findScreenAtDisplay (d, event->xkey.root); if (s) { SCALE_SCREEN (s); if (ss->grabIndex) { XKeyEvent *keyEvent = (XKeyEvent *) event; scalefilterHandleKeyPress (s, keyEvent); } } } break; default: break; } UNWRAP (fd, d, handleEvent); (*d->handleEvent) (d, event); WRAP (fd, d, handleEvent, scalefilterHandleEvent); }
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 Bool scaleSetScreenOption (CompPlugin *plugin, CompScreen *screen, const char *name, CompOptionValue *value) { CompOption *o; int index; SCALE_SCREEN (screen); o = compFindOption (ss->opt, NUM_OPTIONS (ss), name, &index); if (!o) return FALSE; switch (index) { case SCALE_SCREEN_OPTION_OPACITY: if (compSetIntOption (o, value)) { ss->opacity = (OPAQUE * o->value.i) / 100; return TRUE; } break; default: return compSetScreenOption (screen, o, value); } return FALSE; }
static void scaleaddonRenderWindowTitle (CompWindow *w) { CompTextAttrib attrib; float scale; CompScreen *s = w->screen; ScaleaddonWindowTitleEnum winTitleMode; ADDON_DISPLAY (s->display); SCALE_SCREEN (s); SCALE_WINDOW (w); ADDON_WINDOW (w); scaleaddonFreeWindowTitle (w); if (!ad->textFunc) return; if (!sw->slot) return; winTitleMode = scaleaddonGetWindowTitle (s); if (winTitleMode == WindowTitleNoDisplay) return; if (winTitleMode == WindowTitleHighlightedWindowOnly && ad->highlightedWindow != w->id) { return; } scale = sw->slot->scale; attrib.maxWidth = w->attrib.width * scale; attrib.maxHeight = w->attrib.height * scale; attrib.family = "Sans"; attrib.size = scaleaddonGetTitleSize (s); attrib.color[0] = scaleaddonGetFontColorRed (s); attrib.color[1] = scaleaddonGetFontColorGreen (s); attrib.color[2] = scaleaddonGetFontColorBlue (s); attrib.color[3] = scaleaddonGetFontColorAlpha (s); attrib.flags = CompTextFlagWithBackground | CompTextFlagEllipsized; if (scaleaddonGetTitleBold (s)) attrib.flags |= CompTextFlagStyleBold; attrib.bgHMargin = scaleaddonGetBorderSize (s); attrib.bgVMargin = scaleaddonGetBorderSize (s); attrib.bgColor[0] = scaleaddonGetBackColorRed (s); attrib.bgColor[1] = scaleaddonGetBackColorGreen (s); attrib.bgColor[2] = scaleaddonGetBackColorBlue (s); attrib.bgColor[3] = scaleaddonGetBackColorAlpha (s); aw->textData = (ad->textFunc->renderWindowTitle) (s, w->id, ss->type == ScaleTypeAll, &attrib); }
static CompOption * scaleGetScreenOptions (CompPlugin *plugin, CompScreen *screen, int *count) { SCALE_SCREEN (screen); *count = NUM_OPTIONS (ss); return ss->opt; }
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 void scalefilterHandleEcompEvent (CompDisplay *d, char *pluginName, char *eventName, CompOption *option, int nOption) { FILTER_DISPLAY (d); UNWRAP (fd, d, handleEcompEvent); (*d->handleEcompEvent) (d, pluginName, eventName, option, nOption); WRAP (fd, d, handleEcompEvent, scalefilterHandleEcompEvent); if ((strcmp (pluginName, "scale") == 0) && (strcmp (eventName, "activate") == 0)) { Window xid = getIntOptionNamed (option, nOption, "root", 0); Bool activated = getBoolOptionNamed (option, nOption, "active", FALSE); CompScreen *s = findScreenAtDisplay (d, xid); if (s) { FILTER_SCREEN (s); SCALE_SCREEN (s); if (activated) { matchFini (&fs->scaleMatch); matchInit (&fs->scaleMatch); matchCopy (&fs->scaleMatch, ss->currentMatch); matchUpdate (d, &fs->scaleMatch); fs->matchApplied = FALSE; } if (!activated) { if (fs->filterInfo) { ss->currentMatch = fs->filterInfo->origMatch; scalefilterFiniFilterInfo (s, TRUE); } fs->matchApplied = FALSE; } } } }
static Bool scalefilterFilterTimeout (void *closure) { CompScreen *s = (CompScreen *) closure; FILTER_SCREEN (s); SCALE_SCREEN (s); if (fs->filterInfo) { ss->currentMatch = fs->filterInfo->origMatch; scalefilterFiniFilterInfo (s, FALSE); scalefilterRelayout (s); } return FALSE; }
static void scalefilterFiniScreen (CompPlugin *p, CompScreen *s) { FILTER_SCREEN (s); SCALE_SCREEN (s); UNWRAP (fs, s, paintOutput); UNWRAP (fs, ss, setScaledPaintAttributes); if (fs->filterInfo) { ss->currentMatch = fs->filterInfo->origMatch; scalefilterFiniFilterInfo (s, TRUE); } free (fs); }
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 Bool setScaledPaintAttributes (CompWindow *w, WindowPaintAttrib *attrib) { Bool drawScaled = FALSE; SCALE_SCREEN (w->screen); SCALE_WINDOW (w); if (sw->adjust || sw->slot) { SCALE_DISPLAY (w->screen->display); if (w->id != sd->selectedWindow && ss->opacity != OPAQUE && ss->state != SCALE_STATE_IN) { /* modify opacity of windows that are not active */ attrib->opacity = (attrib->opacity * ss->opacity) >> 16; }
static Bool isScaleWin (CompWindow *w) { SCALE_SCREEN (w->screen); if (isNeverScaleWin (w)) return FALSE; if (!ss->type || ss->type == ScaleTypeOutput) { if (!(*w->screen->focusWindow) (w)) return FALSE; } if (w->state & CompWindowStateSkipPagerMask) return FALSE; if (w->state & CompWindowStateShadedMask) return FALSE; if (!w->mapNum || w->attrib.map_state != IsViewable) return FALSE; switch (ss->type) { case ScaleTypeGroup: if (ss->clientLeader != w->clientLeader && ss->clientLeader != w->id) return FALSE; break; case ScaleTypeOutput: if (outputDeviceForWindow(w) != w->screen->currentOutputDev) return FALSE; default: break; } if (!matchEval (ss->currentMatch, w)) return FALSE; return TRUE; }
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 scaleaddonInitScreen (CompPlugin *p, CompScreen *s) { ScaleAddonScreen *as; ADDON_DISPLAY (s->display); SCALE_SCREEN (s); as = malloc (sizeof (ScaleAddonScreen)); if (!as) return FALSE; as->windowPrivateIndex = allocateWindowPrivateIndex (s); if (as->windowPrivateIndex < 0) { free (as); return FALSE; } as->scale = 1.0f; as->lastState = SCALE_STATE_NONE; WRAP (as, s, donePaintScreen, scaleaddonDonePaintScreen); WRAP (as, ss, scalePaintDecoration, scaleaddonScalePaintDecoration); WRAP (as, ss, selectWindow, scaleaddonSelectWindow); WRAP (as, ss, layoutSlotsAndAssignWindows, scaleaddonLayoutSlotsAndAssignWindows); scaleaddonSetWindowTitleNotify (s, scaleaddonScreenOptionChanged); scaleaddonSetTitleBoldNotify (s, scaleaddonScreenOptionChanged); scaleaddonSetTitleSizeNotify (s, scaleaddonScreenOptionChanged); scaleaddonSetBorderSizeNotify (s, scaleaddonScreenOptionChanged); scaleaddonSetFontColorNotify (s, scaleaddonScreenOptionChanged); scaleaddonSetBackColorNotify (s, scaleaddonScreenOptionChanged); s->base.privates[ad->screenPrivateIndex].ptr = as; return TRUE; }
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 Bool layoutOrganicLocalSearch(CompScreen * s, int areaWidth, int areaHeight) { Bool improvement; int i; double totalOverlap; SCALE_SCREEN(s); do { improvement = FALSE; for (i = 0; i < ss->nWindows; i++) { Bool improved; do { int newX, newY; double oldOverlap, overlapH, overlapV; improved = FALSE; oldOverlap = layoutOrganicCalculateOverlap(s, i, ss-> slots [i]. x1, ss-> slots [i]. y1); overlapH = layoutOrganicFindBestHorizontalPosition(s, i, &newX, areaWidth); overlapV = layoutOrganicFindBestVerticalPosition(s, i, &newY, areaHeight); if (overlapH < oldOverlap - 0.1 || overlapV < oldOverlap - 0.1) { improved = TRUE; improvement = TRUE; if (overlapV > overlapH) ss->slots[i].x1 = newX; else ss->slots[i].y1 = newY; } } while (improved); } } while (improvement); totalOverlap = 0.0; for (i = 0; i < ss->nWindows; i++) { totalOverlap += layoutOrganicCalculateOverlap(s, i, ss->slots[i].x1, ss->slots[i].y1); } return (totalOverlap > 0.1); }
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; }
static void scalefilterHandleKeyPress (CompScreen *s, XKeyEvent *event) { ScaleFilterInfo *info; Bool needRelayout = FALSE; Bool dropKeyEvent = FALSE; int count, timeout; char buffer[10]; wchar_t wbuffer[10]; KeySym ks; FILTER_DISPLAY (s->display); FILTER_SCREEN (s); SCALE_SCREEN (s); info = fs->filterInfo; memset (buffer, 0, sizeof (buffer)); memset (wbuffer, 0, sizeof (wbuffer)); if (fd->xic) { Status status; XSetICFocus (fd->xic); count = Xutf8LookupString (fd->xic, event, buffer, 9, &ks, &status); XUnsetICFocus (fd->xic); } else { count = XLookupString (event, buffer, 9, &ks, NULL); } mbstowcs (wbuffer, buffer, 9); if (ks == XK_Escape) { if (info) { /* Escape key - drop current filter */ ss->currentMatch = info->origMatch; scalefilterFiniFilterInfo (s, TRUE); needRelayout = TRUE; dropKeyEvent = TRUE; } else if (fs->matchApplied) { /* remove filter applied previously if currently not in input mode */ matchFini (&ss->match); matchInit (&ss->match); matchCopy (&ss->match, &fs->scaleMatch); matchUpdate (s->display, &ss->match); ss->currentMatch = &ss->match; fs->matchApplied = FALSE; needRelayout = TRUE; dropKeyEvent = TRUE; } } else if (ks == XK_Return) { if (info) { /* Return key - apply current filter persistently */ matchFini (&ss->match); matchInit (&ss->match); matchCopy (&ss->match, &info->match); matchUpdate (s->display, &ss->match); ss->currentMatch = &ss->match; fs->matchApplied = TRUE; dropKeyEvent = TRUE; needRelayout = TRUE; scalefilterFiniFilterInfo (s, TRUE); } } else if (ks == XK_BackSpace) { if (info && info->filterStringLength > 0) { /* remove last character in string */ info->filterString[--(info->filterStringLength)] = '\0'; needRelayout = TRUE; } } else if (count > 0) { if (!info) { fs->filterInfo = info = malloc (sizeof (ScaleFilterInfo)); scalefilterInitFilterInfo (s); } else if (info->timeoutHandle) compRemoveTimeout (info->timeoutHandle); timeout = scalefilterGetTimeout (s); if (timeout > 0) info->timeoutHandle = compAddTimeout (timeout, scalefilterFilterTimeout, s); if (info->filterStringLength < MAX_FILTER_SIZE) { info->filterString[info->filterStringLength++] = wbuffer[0]; info->filterString[info->filterStringLength] = '\0'; needRelayout = TRUE; } } /* set the event type invalid if we don't want other plugins see it */ if (dropKeyEvent) event->type = LASTEvent+1; if (needRelayout) { scalefilterRenderFilterText (s); if (fs->filterInfo) scalefilterUpdateFilter (s, &fs->filterInfo->match); scalefilterRelayout (s); } }
static void scalePaintDecoration (CompWindow *w, const WindowPaintAttrib *attrib, const CompTransform *transform, Region region, unsigned int mask) { CompScreen *s = w->screen; SCALE_SCREEN (s); if (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i != SCALE_ICON_NONE) { WindowPaintAttrib sAttrib = *attrib; CompIcon *icon; SCALE_WINDOW (w); icon = getWindowIcon (w, 96, 96); if (!icon) icon = w->screen->defaultIcon; if (icon && (icon->texture.name || iconToTexture (w->screen, icon))) { REGION iconReg; float scale; float x, y; int width, height; int scaledWinWidth, scaledWinHeight; float ds; scaledWinWidth = w->width * sw->scale; scaledWinHeight = w->height * sw->scale; switch (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i) { case SCALE_ICON_NONE: case SCALE_ICON_EMBLEM: scale = 1.0f; break; case SCALE_ICON_BIG: default: sAttrib.opacity /= 3; scale = MIN (((float) scaledWinWidth / icon->width), ((float) scaledWinHeight / icon->height)); break; } width = icon->width * scale; height = icon->height * scale; switch (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i) { case SCALE_ICON_NONE: case SCALE_ICON_EMBLEM: x = w->attrib.x + scaledWinWidth - icon->width; y = w->attrib.y + scaledWinHeight - icon->height; break; case SCALE_ICON_BIG: default: x = w->attrib.x + scaledWinWidth / 2 - width / 2; y = w->attrib.y + scaledWinHeight / 2 - height / 2; break; } x += sw->tx; y += sw->ty; if (sw->slot) { sw->delta = fabs (sw->slot->x1 - w->attrib.x) + fabs (sw->slot->y1 - w->attrib.y) + fabs (1.0f - sw->slot->scale) * 500.0f; } if (sw->delta) { float o; ds = fabs (sw->tx) + fabs (sw->ty) + fabs (1.0f - sw->scale) * 500.0f; if (ds > sw->delta) ds = sw->delta; o = ds / sw->delta; if (sw->slot) { if (o < sw->lastThumbOpacity) o = sw->lastThumbOpacity; } else { if (o > sw->lastThumbOpacity) o = 0.0f; } sw->lastThumbOpacity = o; sAttrib.opacity = sAttrib.opacity * o; } mask |= PAINT_WINDOW_BLEND_MASK; iconReg.rects = &iconReg.extents; iconReg.numRects = 1; iconReg.extents.x1 = 0; iconReg.extents.y1 = 0; iconReg.extents.x2 = iconReg.extents.x1 + width; iconReg.extents.y2 = iconReg.extents.y1 + height; w->vCount = w->indexCount = 0; if (iconReg.extents.x1 < iconReg.extents.x2 && iconReg.extents.y1 < iconReg.extents.y2) (*w->screen->addWindowGeometry) (w, &icon->texture.matrix, 1, &iconReg, &iconReg); if (w->vCount) { FragmentAttrib fragment; CompTransform wTransform = *transform; initFragmentAttrib (&fragment, &sAttrib); matrixScale (&wTransform, scale, scale, 1.0f); matrixTranslate (&wTransform, x / scale, y / scale, 0.0f); glPushMatrix (); glLoadMatrixf (wTransform.m); (*w->screen->drawWindowTexture) (w, &icon->texture, &fragment, mask); glPopMatrix (); } } } }
static Bool scaleaddonZoomWindow(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption) { CompScreen *s; Window xid; xid = getIntOptionNamed(option, nOption, "root", 0); s = findScreenAtDisplay(d, xid); if (s) { CompWindow *w; SCALE_SCREEN(s); ADDON_DISPLAY(d); if (!ss->grabIndex) return FALSE; w = findWindowAtDisplay(d, ad->highlightedWindow); if (w) { SCALE_WINDOW(w); ADDON_WINDOW(w); XRectangle outputRect; BOX outputBox; int head; if (!sw->slot) return FALSE; head = outputDeviceForPoint(s, sw->slot->x1, sw->slot->y1); outputBox = w->screen->outputDev[head].region.extents; outputRect.x = outputBox.x1; outputRect.y = outputBox.y1; outputRect.width = outputBox.x2 - outputBox.x1; outputRect.height = outputBox.y2 - outputBox.y1; /* damage old rect */ addWindowDamage(w); if (!aw->rescaled) { aw->oldAbove = w->next; raiseWindow(w); /* backup old values */ aw->origSlot = *sw->slot; aw->rescaled = TRUE; sw->slot->x1 = (outputRect.width / 2) - (WIN_W(w) / 2) + w->input.left + outputRect.x; sw->slot->y1 = (outputRect.height / 2) - (WIN_H(w) / 2) + w->input.top + outputRect.y; sw->slot->x2 = sw->slot->x1 + WIN_W(w); sw->slot->y2 = sw->slot->y1 + WIN_H(w); sw->slot->scale = 1.0f; } else { if (aw->oldAbove) restackWindowBelow(w, aw->oldAbove); aw->rescaled = FALSE; *(sw->slot) = aw->origSlot; } sw->adjust = TRUE; ss->state = SCALE_STATE_OUT; /* slot size may have changed, so * update window title */ scaleaddonRenderWindowTitle(w); addWindowDamage(w); return TRUE; } } return FALSE; }
static Bool scaleaddonPullWindow(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption) { CompScreen *s; Window xid; xid = getIntOptionNamed(option, nOption, "root", 0); s = findScreenAtDisplay(d, xid); if (s) { CompWindow *w; SCALE_SCREEN(s); ADDON_DISPLAY(d); if (!ss->grabIndex) return FALSE; w = findWindowAtDisplay(d, ad->highlightedWindow); if (w) { int x, y, vx, vy; defaultViewportForWindow(w, &vx, &vy); x = w->attrib.x + (s->x - vx) * s->width; y = w->attrib.y + (s->y - vy) * s->height; if (scaleaddonGetConstrainPullToScreen(s)) { XRectangle workArea; CompWindowExtents extents; getWorkareaForOutput(s, outputDeviceForWindow(w), &workArea); extents.left = x - w->input.left; extents.right = x + w->width + w->input.right; extents.top = y - w->input.top; extents.bottom = y + w->height + w->input.bottom; if (extents.left < workArea.x) x += workArea.x - extents.left; else if (extents.right > workArea.x + workArea.width) x += workArea.x + workArea.width - extents.right; if (extents.top < workArea.y) y += workArea.y - extents.top; else if (extents.bottom > workArea.y + workArea.height) y += workArea.y + workArea.height - extents.bottom; } if (x != w->attrib.x || y != w->attrib.y) { SCALE_WINDOW(w); moveWindowToViewportPosition(w, x, y, TRUE); /* Select this window when ending scale */ (*ss->selectWindow) (w); /* stop scaled window dissapearing */ sw->tx -= (s->x - vx) * s->width; sw->ty -= (s->y - vy) * s->height; if (scaleaddonGetExitAfterPull(s)) { int opt; CompAction *action2; CompOption o[1]; SCALE_DISPLAY(d); opt = SCALE_DISPLAY_OPTION_INITIATE_KEY; action2 = &sd->opt[opt].value.action; o[0].type = CompOptionTypeInt; o[0].name = "root"; o[0].value.i = s->root; if (action2->terminate) (*action2->terminate) (d, action, 0, o, 1); } else { /* provide a simple animation */ addWindowDamage(w); sw->tx -= (sw->slot->x2 - sw->slot->x1) / 20; sw->ty -= (sw->slot->y2 - sw->slot->y1) / 20; sw->scale *= 1.1f; sw->adjust = TRUE; ss->state = SCALE_STATE_OUT; addWindowDamage(w); } return TRUE; } } } return FALSE; }