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 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 scaleaddonCheckWindowHighlight (CompScreen *s) { CompDisplay *d = s->display; ADDON_DISPLAY (d); if (ad->highlightedWindow != ad->lastHighlightedWindow) { CompWindow *w; w = findWindowAtDisplay (d, ad->highlightedWindow); if (w) { scaleaddonRenderWindowTitle (w); addWindowDamage (w); } w = findWindowAtDisplay (d, ad->lastHighlightedWindow); if (w) { scaleaddonRenderWindowTitle (w); addWindowDamage (w); } ad->lastHighlightedWindow = ad->highlightedWindow; } }
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 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 void scaleaddonFiniDisplay(CompPlugin * p, CompDisplay * d) { ADDON_DISPLAY(d); UNWRAP(ad, d, handleEvent); UNWRAP(ad, d, handleCompizEvent); freeScreenPrivateIndex(d, ad->screenPrivateIndex); free(ad); }
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 scaleaddonFreeWindowTitle(CompWindow * w) { CompScreen *s = w->screen; ADDON_WINDOW(w); ADDON_DISPLAY(s->display); if (!aw->textData) return; (ad->textFunc->finiTextData) (s, aw->textData); aw->textData = NULL; }
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 scaleaddonDrawWindowTitle(CompWindow * w) { float x, y, width, height; CompScreen *s = w->screen; SCALE_WINDOW(w); ADDON_WINDOW(w); ADDON_DISPLAY(s->display); width = aw->textData->width; height = aw->textData->height; x = sw->tx + w->attrib.x + ((WIN_W(w) * sw->scale) / 2) - (width / 2); y = sw->ty + w->attrib.y + ((WIN_H(w) * sw->scale) / 2) - (height / 2); (ad->textFunc->drawText) (s, aw->textData, floor(x), floor(y), 1.0f); }
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 void scaleaddonHandleCompizEvent(CompDisplay * d, const char *pluginName, const char *eventName, CompOption * option, int nOption) { ADDON_DISPLAY(d); UNWRAP(ad, d, handleCompizEvent); (*d->handleCompizEvent) (d, pluginName, eventName, option, nOption); WRAP(ad, d, handleCompizEvent, scaleaddonHandleCompizEvent); if ((strcmp(pluginName, "scale") == 0) && (strcmp(eventName, "activate") == 0)) { Window xid; Bool activated; CompScreen *s; xid = getIntOptionNamed(option, nOption, "root", 0); activated = getBoolOptionNamed(option, nOption, "active", FALSE); s = findScreenAtDisplay(d, xid); if (s) { if (activated) { addScreenAction(s, scaleaddonGetCloseKey(d)); addScreenAction(s, scaleaddonGetZoomKey(d)); addScreenAction(s, scaleaddonGetPullKey(d)); addScreenAction(s, scaleaddonGetCloseButton(d)); addScreenAction(s, scaleaddonGetZoomButton(d)); addScreenAction(s, scaleaddonGetPullButton(d)); /* TODO: or better ad->highlightedWindow = sd->selectedWindow; here? do we want to show up the highlight without mouse move initially? */ ad->highlightedWindow = None; ad->lastHighlightedWindow = None; scaleaddonCheckWindowHighlight(s); } else { CompWindow *w; for (w = s->windows; w; w = w->next) { ADDON_WINDOW(w); aw->rescaled = FALSE; } removeScreenAction(s, scaleaddonGetCloseKey(d)); removeScreenAction(s, scaleaddonGetZoomKey(d)); removeScreenAction(s, scaleaddonGetPullKey(d)); removeScreenAction(s, scaleaddonGetCloseButton(d)); removeScreenAction(s, scaleaddonGetZoomButton(d)); removeScreenAction(s, scaleaddonGetPullButton(d)); } } } }
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; }