From a041d9898e6d699bd8c0c25482ec574feb03c547 Mon Sep 17 00:00:00 2001 From: "John Ankarstr\\xf6m" Date: Sat, 29 May 2021 12:54:47 +0200 Subject: First commit This is the original state of the released tarball for JWM 1.8, which will serve as my starting point for further modifications. --- src/pager.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 src/pager.c (limited to 'src/pager.c') diff --git a/src/pager.c b/src/pager.c new file mode 100644 index 0000000..6c237bd --- /dev/null +++ b/src/pager.c @@ -0,0 +1,331 @@ +/**************************************************************************** + * Functions for displaying the pager. + * Copyright (C) 2004 Joe Wingbermuehle + ****************************************************************************/ + +#include "jwm.h" +#include "pager.h" +#include "tray.h" +#include "main.h" +#include "desktop.h" +#include "client.h" +#include "color.h" + +typedef struct PagerType { + + TrayComponentType *cp; + + int deskWidth; + int deskHeight; + double scalex, scaley; + LayoutType layout; + + Pixmap buffer; + + struct PagerType *next; + +} PagerType; + +static PagerType *pagers; + +static void Create(TrayComponentType *cp); +static void Destroy(TrayComponentType *cp); + +static void SetSize(TrayComponentType *cp, int width, int height); + +static void ProcessPagerButtonEvent(TrayComponentType *cp, + int x, int y, int mask); + +static void DrawPagerClient(const PagerType *pp, const ClientNode *np); + +/**************************************************************************** + ****************************************************************************/ +void InitializePager() { + pagers = NULL; +} + +/**************************************************************************** + ****************************************************************************/ +void StartupPager() { +} + +/**************************************************************************** + ****************************************************************************/ +void ShutdownPager() { + + PagerType *pp; + + for(pp = pagers; pp; pp = pp->next) { + JXFreePixmap(display, pp->buffer); + } + +} + +/**************************************************************************** + ****************************************************************************/ +void DestroyPager() { + + PagerType *pp; + + while(pagers) { + pp = pagers->next; + Release(pagers); + pagers = pp; + } + +} + +/**************************************************************************** + ****************************************************************************/ +TrayComponentType *CreatePager() { + + TrayComponentType *cp; + PagerType *pp; + + pp = Allocate(sizeof(PagerType)); + pp->next = pagers; + pagers = pp; + + cp = CreateTrayComponent(); + cp->object = pp; + pp->cp = cp; + cp->Create = Create; + cp->Destroy = Destroy; + cp->SetSize = SetSize; + cp->ProcessButtonEvent = ProcessPagerButtonEvent; + + return cp; +} + +/**************************************************************************** + ****************************************************************************/ +void Create(TrayComponentType *cp) { + + PagerType *pp; + + Assert(cp); + + pp = (PagerType*)cp->object; + + Assert(pp); + + Assert(cp->width > 0); + Assert(cp->height > 0); + + cp->pixmap = JXCreatePixmap(display, rootWindow, cp->width, + cp->height, rootDepth); + pp->buffer = cp->pixmap; + +} + +/**************************************************************************** + ****************************************************************************/ +void Destroy(TrayComponentType *cp) { + +} + +/**************************************************************************** + ****************************************************************************/ +void SetSize(TrayComponentType *cp, int width, int height) { + + PagerType *pp; + + Assert(cp); + + pp = (PagerType*)cp->object; + + Assert(pp); + + if(width) { + + /* Vertical pager, compute height from width. */ + cp->width = width; + pp->deskWidth = width; + pp->deskHeight = (cp->width * rootHeight) / rootWidth; + cp->height = (pp->deskHeight + 1) * desktopCount; + pp->layout = LAYOUT_VERTICAL; + + } else if(height) { + + /* Horizontal pager, compute width from height. */ + cp->height = height; + pp->deskHeight = height; + pp->deskWidth = (cp->height * rootWidth) / rootHeight; + cp->width = (pp->deskWidth + 1) * desktopCount; + pp->layout = LAYOUT_HORIZONTAL; + + } else { + Assert(0); + } + + pp->scalex = (double)(pp->deskWidth - 2) / rootWidth; + pp->scaley = (double)(pp->deskHeight - 2) / rootHeight; + +} + +/**************************************************************************** + ****************************************************************************/ +void ProcessPagerButtonEvent(TrayComponentType *cp, int x, int y, int mask) { + + PagerType *pp; + + switch(mask) { + case Button1: + case Button2: + case Button3: + pp = (PagerType*)cp->object; + if(pp->layout == LAYOUT_HORIZONTAL) { + ChangeDesktop(x / (pp->deskWidth + 1)); + } else { + ChangeDesktop(y / (pp->deskHeight + 1)); + } + break; + case Button4: + PreviousDesktop(); + break; + case Button5: + NextDesktop(); + break; + default: + break; + } +} + +/**************************************************************************** + ****************************************************************************/ +void UpdatePager() { + + PagerType *pp; + ClientNode *np; + Pixmap buffer; + int width, height; + int deskWidth, deskHeight; + unsigned int x; + + if(shouldExit) { + return; + } + + for(pp = pagers; pp; pp = pp->next) { + + buffer = pp->cp->pixmap; + width = pp->cp->width; + height = pp->cp->height; + deskWidth = pp->deskWidth; + deskHeight = pp->deskHeight; + + /* Draw the background. */ + JXSetForeground(display, rootGC, colors[COLOR_PAGER_BG]); + JXFillRectangle(display, buffer, rootGC, 0, 0, width, height); + + /* Highlight the current desktop. */ + JXSetForeground(display, rootGC, colors[COLOR_PAGER_ACTIVE_BG]); + if(pp->layout == LAYOUT_HORIZONTAL) { + JXFillRectangle(display, buffer, rootGC, + currentDesktop * (deskWidth + 1), 0, + deskWidth, height); + } else { + JXFillRectangle(display, buffer, rootGC, + 0, currentDesktop * (deskHeight + 1), + width, deskHeight); + } + + /* Draw the clients. */ + for(x = LAYER_BOTTOM; x <= LAYER_TOP; x++) { + for(np = nodeTail[x]; np; np = np->prev) { + DrawPagerClient(pp, np); + } + } + + /* Draw the desktop dividers. */ + JXSetForeground(display, rootGC, colors[COLOR_PAGER_FG]); + for(x = 1; x < desktopCount; x++) { + if(pp->layout == LAYOUT_HORIZONTAL) { + JXDrawLine(display, buffer, rootGC, + (deskWidth + 1) * x - 1, 0, + (deskWidth + 1) * x - 1, height); + } else { + JXDrawLine(display, buffer, rootGC, + 0, (deskHeight + 1) * x - 1, + width, (deskHeight + 1) * x - 1); + } + } + + /* Tell the tray to redraw. */ + UpdateSpecificTray(pp->cp->tray, pp->cp); + + } + +} + +/**************************************************************************** + ****************************************************************************/ +void DrawPagerClient(const PagerType *pp, const ClientNode *np) { + + int x, y; + int width, height; + int deskOffset; + ColorType fillColor; + + if(!(np->state.status & STAT_MAPPED)) { + return; + } + + if(np->state.status & STAT_STICKY) { + deskOffset = currentDesktop; + } else { + deskOffset = np->state.desktop; + } + if(pp->layout == LAYOUT_HORIZONTAL) { + deskOffset *= pp->deskWidth + 1; + } else { + deskOffset *= pp->deskHeight + 1; + } + + x = (int)((double)np->x * pp->scalex + 1.0); + y = (int)((double)np->y * pp->scaley + 1.0); + width = (int)((double)np->width * pp->scalex); + height = (int)((double)np->height * pp->scaley); + + if(x + width > pp->deskWidth) { + width = pp->deskWidth - x; + } + if(y + height > pp->deskHeight) { + height = pp->deskHeight - y; + } + if(x < 0) { + width += x; + x = 0; + } + if(y < 0) { + height += y; + y = 0; + } + if(width <= 0 || height <= 0) { + return; + } + + if(pp->layout == LAYOUT_HORIZONTAL) { + x += deskOffset; + } else { + y += deskOffset; + } + + JXSetForeground(display, rootGC, colors[COLOR_PAGER_OUTLINE]); + JXDrawRectangle(display, pp->cp->pixmap, rootGC, x, y, width, height); + + if(width > 1 && height > 1) { + if((np->state.status & STAT_ACTIVE) + && (np->state.desktop == currentDesktop + || (np->state.status & STAT_STICKY))) { + fillColor = COLOR_PAGER_ACTIVE_FG; + } else { + fillColor = COLOR_PAGER_FG; + } + JXSetForeground(display, rootGC, colors[fillColor]); + JXFillRectangle(display, pp->cp->pixmap, rootGC, x + 1, y + 1, + width - 1, height - 1); + } + +} + -- cgit v1.2.3