diff --git a/netwaresmp-xscreensaver-6.08.patch b/netwaresmp-xscreensaver-6.08.patch index 4be25b3..fe2032d 100644 --- a/netwaresmp-xscreensaver-6.08.patch +++ b/netwaresmp-xscreensaver-6.08.patch @@ -1,6 +1,6 @@ diff -Naur xscreensaver-6.08-orig/driver/XScreenSaver.ad.in xscreensaver-6.08/driver/XScreenSaver.ad.in --- xscreensaver-6.08-orig/driver/XScreenSaver.ad.in 2023-10-10 17:24:06.551773885 -0700 -+++ xscreensaver-6.08/driver/XScreenSaver.ad.in 2024-02-20 23:52:00.952904019 -0800 ++++ xscreensaver-6.08/driver/XScreenSaver.ad.in 2024-03-10 23:48:37.275926885 -0700 @@ -413,6 +413,7 @@ wander --root \n\ xflame --root \n\ @@ -19,8 +19,8 @@ diff -Naur xscreensaver-6.08-orig/driver/XScreenSaver.ad.in xscreensaver-6.08/dr *hacks.photopile.name: Photo Pile diff -Naur xscreensaver-6.08-orig/hacks/config/netwaresmp.xml xscreensaver-6.08/hacks/config/netwaresmp.xml --- xscreensaver-6.08-orig/hacks/config/netwaresmp.xml 1969-12-31 16:00:00.000000000 -0800 -+++ xscreensaver-6.08/hacks/config/netwaresmp.xml 2024-02-21 13:19:26.580364904 -0800 -@@ -0,0 +1,39 @@ ++++ xscreensaver-6.08/hacks/config/netwaresmp.xml 2024-03-10 23:49:16.241447436 -0700 +@@ -0,0 +1,50 @@ + + + @@ -44,8 +44,18 @@ diff -Naur xscreensaver-6.08-orig/hacks/config/netwaresmp.xml xscreensaver-6.08/ + + -+ -+ ++ ++ ++ ++ + + + @@ -54,15 +64,16 @@ diff -Naur xscreensaver-6.08-orig/hacks/config/netwaresmp.xml xscreensaver-6.08/ + <_description> +Draws a worm for each system cpu that grows longer and faster as the machine +load increases for a particular processor . A rewrite of the classic Novell -+Netware SMP console screensaver. Originally written at Novell for NetWare SMP -+in 1994 by Jeffrey V. Merkey. Re-written by Jeffrey Merkey and Cosimo Streppone -+for xscreensaver based on PopSquares, Deco hacks, loadsnake, and the original -+Netware SMP screensaver. ++Netware SMP console screensaver. ++ ++Originally written at Novell for NetWare SMP in 1994 by Jeffrey V. Merkey. ++Re-written by Jeffrey Merkey and Cosimo Streppone for xscreensaver based ++on PopSquares, Deco hacks, loadsnake, and the original Netware SMP screensaver; 2024. + + diff -Naur xscreensaver-6.08-orig/hacks/Makefile.in xscreensaver-6.08/hacks/Makefile.in --- xscreensaver-6.08-orig/hacks/Makefile.in 2023-10-10 17:37:05.846255309 -0700 -+++ xscreensaver-6.08/hacks/Makefile.in 2024-02-20 23:52:00.952904019 -0800 ++++ xscreensaver-6.08/hacks/Makefile.in 2024-03-10 23:48:37.276926898 -0700 @@ -111,7 +111,7 @@ demon.c loop.c t3d.c penetrate.c deluxe.c compass.c \ squiral.c xflame.c wander.c spotlight.c critical.c \ @@ -111,14 +122,15 @@ diff -Naur xscreensaver-6.08-orig/hacks/Makefile.in xscreensaver-6.08/hacks/Make diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/netwaresmp.c --- xscreensaver-6.08-orig/hacks/netwaresmp.c 1969-12-31 16:00:00.000000000 -0800 -+++ xscreensaver-6.08/hacks/netwaresmp.c 2024-02-21 13:19:09.974154353 -0800 -@@ -0,0 +1,963 @@ ++++ xscreensaver-6.08/hacks/netwaresmp.c 2024-03-10 23:48:54.760160462 -0700 +@@ -0,0 +1,1422 @@ +/*************************************************************************** +* +* Copyright(c) Jeff V. Merkey 1997-2024. All rights reserved. +* +* Portions adapted from xscreensaver loadsnake program is +* portions Copyright (c) 2007-2011 Cosimo Streppone ++* Portions adapted from XScreensaver Copyright (c) 2024 Jamie Zawinski +* +* Licensed under the MIT/X License +* @@ -161,21 +173,22 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +#include "screenhack.h" +#include "colors.h" +#include "textclient.h" ++#include "xft.h" +#include "utf8wc.h" + +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION +# include "xdbe.h" -+#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ ++#endif + +#define WORM_MIN_LEN 4 +#define WORM_MAX_LEN 36 +#define WORM_TAIL_LEN 3 +#define MAX_WORMS 64 + -+// adjust worm total length based on screen area size. smaller -+// displays have shorter worms. the current logic adjusts for -+// worm speedup based on the current max worm length. Here we -+// check a min and max screen area for worm length expansion. ++/* adjust worm total length based on screen area size. smaller ++ displays have shorter worms. the current logic adjusts for ++ worm speedup based on the current max worm length. Here we ++ check a min and max screen area for worm length expansion. */ + +#define AREA_BASE_LEN (WORM_MAX_LEN / 2) +#define AREA_MINLINES 19 @@ -195,9 +208,20 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +#define MAX_MICROSEC 100000 +#define MIN_MICROSEC 10000 +#define COLORSETS 16 -+#define VERBOSE 0 + -+// worm state structure ++#define VERBOSE 0 ++#define DEBUG 0 ++ ++/* worm drawing shapes */ ++#define SQUARES 0 ++#define CIRCLES 1 ++#define SNIPES 2 ++#define TRIANGLES 3 ++#define CLASSIC 4 ++#define ARROWS 5 ++#define BALLS3D 6 ++ ++/* worm state structure */ +typedef struct _WORM +{ + int cpu; @@ -205,28 +229,39 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + int limit; + int x[WORM_MAX_LEN]; + int y[WORM_MAX_LEN]; ++ int d[WORM_MAX_LEN]; + int x_prev[WORM_MAX_LEN]; + int y_prev[WORM_MAX_LEN]; ++ int d_prev[WORM_MAX_LEN]; + int length; + int length_prev; + int direction; + int runlength; + int windowlength; + int color; ++ unsigned long delta; +} WORM; + -+// Netware SMP Xscreesnaver state array ++/* Netware SMP Xscreesnaver state array */ +typedef struct _STATE +{ + Display *dpy; + Window window; + Visual *visual; + Screen *screen; ++ int scr; ++ Colormap cmap; ++ XftDraw *draw; ++ XftColor color; ++ XftFont *xftfont; ++ int hascolor; ++ + int delay, wormsize, ncolors, dbuf; + int cpus; + XWindowAttributes xgwa; + GC gc; + XColor **colors; ++ XColor *black; + Pixmap b, ba, bb; +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + XdbeBackBuffer backb; @@ -241,35 +276,50 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + int divisor; + int prio; + int mono; -+ int circles; ++ int stats; ++ int shape; ++ char *charset; + int sw, sh; -+ unsigned long long usr[MAX_WORMS]; -+ unsigned long long sys[MAX_WORMS]; -+ unsigned long long nice[MAX_WORMS]; -+ unsigned long long idle[MAX_WORMS]; -+ unsigned long long io[MAX_WORMS]; -+ unsigned long long irq[MAX_WORMS]; -+ unsigned long long sirq[MAX_WORMS]; -+ unsigned long long steal[MAX_WORMS]; -+ unsigned long long guest[MAX_WORMS]; -+ unsigned long long guest_nice[MAX_WORMS]; ++ unsigned long usr[MAX_WORMS]; ++ unsigned long sys[MAX_WORMS]; ++ unsigned long nice[MAX_WORMS]; ++ unsigned long idle[MAX_WORMS]; ++ unsigned long io[MAX_WORMS]; ++ unsigned long irq[MAX_WORMS]; ++ unsigned long sirq[MAX_WORMS]; ++ unsigned long steal[MAX_WORMS]; ++ unsigned long guest[MAX_WORMS]; ++ unsigned long guest_nice[MAX_WORMS]; + WORM *worms; +} STATE; + ++/* utf8 encoding for \u25C0\u25b6 C89 compliance */ ++unsigned char snipes_utf8_1[7] = { 0xE2, 0x97, 0x80, 0xE2, 0x96, 0xB6, 0 }; ++/* utf8 encoding for \u229A\u229A C89 compliance */ ++unsigned char snipes_utf8_2[7] = { 0xE2, 0x8A, 0x9A, 0xE2, 0x8A, 0x9A, 0 }; ++/* utf8 encoding for \u2588\u2588 C89 compliance */ ++unsigned char classic_utf8_1[7] = { 0xE2, 0x96, 0x88, 0xE2, 0x96, 0x88, 0 }; ++/* utf8 encoding for \u2593\u2593 C89 compliance */ ++unsigned char classic_utf8_2[7] = { 0xE2, 0x96, 0x93, 0xE2, 0x96, 0x93, 0 }; ++/* utf8 encoding for \u2592\u2592 C89 compliance */ ++unsigned char classic_utf8_3[7] = { 0xE2, 0x96, 0x92, 0xE2, 0x96, 0x92, 0 }; ++/* utf8 encoding for \u2591\u2591 C89 compliance */ ++unsigned char classic_utf8_4[7] = { 0xE2, 0x96, 0x91, 0xE2, 0x96, 0x91, 0 }; ++ +static XColor *make_colorset(STATE *st, const int *rgb, const int *rgb_low) +{ + int h1, h2 = 0; + double s1, v1, s2, v2 = 0; + XColor *colset = (XColor *)calloc(st->ncolors, sizeof(XColor)); + -+ // ramp the colors based on rgb_low array. If rgb_low not specified, -+ // then default to the color black as the ramp color to scale to. ++ /* ramp the colors based on rgb_low array. If rgb_low not specified, ++ then default to the color black as the ramp color to scale to. */ + if (rgb_low) + rgb_to_hsv(rgb_low[0], rgb_low[1], rgb_low[2], &h1, &s1, &v1); + else + rgb_to_hsv(0, 0, 0, &h1, &s1, &v1); + -+ // Finish: foreground, head ++ /* Finish: foreground, head */ + rgb_to_hsv(rgb[0], rgb[1], rgb[2], &h2, &s2, &v2); + + make_color_ramp( @@ -286,62 +336,84 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +{ + int n; + -+ // monochrome mode rgb bitmap (white) ++ /* monochrome mode rgb bitmap (white) */ + int rgbmono[3]= { + 0xFFFF, 0xFFFF, 0xFFFF + }; + + int rgb[COLORSETS][3] = { -+ { 0xFFFF, 0, 0 }, // red -+ { 0, 0, 0xFFFF }, // blue -+ { 0, 0xFFFF, 0 }, // green -+ { 0, 0xFFFF, 0xFFFF }, // cyan -+ -+ { 0xFFFF, 0xFFFF, 0 }, // yellow -+ { 0xFFFF, 0xFFFF, 0xFFFF }, // britewhite -+ { 0xFFFF, 0, 0xFFFF }, // magenta -+ { 0x7FFF, 0x7FFF, 0xFFFF }, // purple -+ -+ { 0xFFFF, 0x80FF, 0 }, // orange -+ { 0x0, 0x99FF, 0x4CFF }, // olive -+ { 0x99FF, 0, 0 }, // burgundy -+ { 0xFFFF, 0x99FF, 0x99FF }, // salmon -+ -+ { 0xCCFF, 0xFFFF, 0x99FF }, // yellowgreen -+ { 0x99FF, 0xCCFF, 0xFFFF }, // ltblue -+ { 0xFFFF, 0x99FF, 0xFFFF }, // ltmagenta -+ { 0xB8FF, 0x73FF, 0x33FF }, // copper ++ { 0xFFFF, 0, 0 }, /* red */ ++ { 0, 0x7FFF, 0xFFFF }, /* blue */ ++ { 0, 0xFFFF, 0 }, /* green */ ++ { 0, 0xFFFF, 0xFFFF }, /* cyan */ ++ ++ { 0xFFFF, 0xFFFF, 0 }, /* yellow */ ++ { 0xFFFF, 0xFFFF, 0xFFFF }, /* britewhite */ ++ { 0xFFFF, 0, 0xFFFF }, /* magenta */ ++ { 0x7FFF, 0x7FFF, 0xFFFF }, /* purple */ ++ ++ { 0xFFFF, 0x80FF, 0 }, /* orange */ ++ { 0x0, 0x99FF, 0x4CFF }, /* olive */ ++ { 0x99FF, 0, 0 }, /* burgundy */ ++ { 0xFFFF, 0x99FF, 0x99FF }, /* salmon */ ++ ++ { 0xCCFF, 0xFFFF, 0x99FF }, /* yellowgreen */ ++ { 0x99FF, 0xCCFF, 0xFFFF }, /* ltblue */ ++ { 0xFFFF, 0x99FF, 0xFFFF }, /* ltmagenta */ ++ { 0xB8FF, 0x73FF, 0x33FF }, /* copper */ + }; + -+ // ramp scaling to black for certain colors -+ // will induce too much green or yellow into -+ // the output color ramp array for certain colors. -+ // Set a more reasonable target since the -+ // color ramp libs with xscreensaver utils -+ // don't always handle the color black very -+ // well when scaling and add too much green -+ // or yellow to the ramp colorsets. ++ /* ramp scaling to black for certain colors ++ will induce too much green or yellow into ++ the output color ramp array for certain colors. ++ Set a more reasonable target since the ++ color ramp libs with xscreensaver utils ++ don't always handle the color black very ++ well when scaling and add too much green ++ or yellow to the ramp colorsets. */ + + int rgb_low[COLORSETS][3] = { -+ { 0x1, 0, 0 }, // red target -+ { 0, 0, 0x1 }, // blue target -+ { 0, 0x1, 0 }, // green target -+ { 0, 0x1, 0x1 }, // cyan target -+ -+ { 0x1, 0x1, 0 }, // yellow target -+ { 0, 0, 0 }, // britewhite targer -+ { 0x1, 0, 0x1 }, // magenta target -+ { 0, 0, 0x7 }, // purple target -+ -+ { 0x2, 0x1, 0 }, // orange target -+ { 0, 0x9, 0x4 }, // olive target -+ { 0x1, 0, 0 }, // burgundy target -+ { 0x2, 0x1, 0x1 }, // salmon target -+ -+ { 0x1, 0x1, 0 }, // yellowgreen target -+ { 0x1, 0x2, 0x2 }, // ltblue target -+ { 0x2, 0x1, 0x2 }, // ltmagenta target -+ { 0, 0, 0 }, // copper target ++ { 0x1, 0, 0 }, /* red target */ ++ { 0, 0x1, 0x2 }, /* blue target */ ++ { 0, 0x1, 0 }, /* green target */ ++ { 0, 0x1, 0x1 }, /* cyan target */ ++ ++ { 0x1, 0x1, 0 }, /* yellow target */ ++ { 0, 0, 0 }, /* britewhite targer */ ++ { 0x1, 0, 0x1 }, /* magenta target */ ++ { 0, 0, 0x7 }, /* purple target */ ++ ++ { 0x2, 0x1, 0 }, /* orange target */ ++ { 0, 0x9, 0x4 }, /* olive target */ ++ { 0x1, 0, 0 }, /* burgundy target */ ++ { 0x2, 0x1, 0x1 }, /* salmon target */ ++ ++ { 0x1, 0x1, 0 }, /* yellowgreen target */ ++ { 0x1, 0x2, 0x2 }, /* ltblue target */ ++ { 0x2, 0x1, 0x2 }, /* ltmagenta target */ ++ { 0, 0, 0 }, /* copper target */ ++ }; ++ ++ int rgb_low_snipes[COLORSETS][3] = { ++ { 0x7FFF, 0, 0 }, /* red target */ ++ { 0, 0x1, 0x2 }, /* blue target */ ++ { 0, 0x1, 0 }, /* green target */ ++ { 0, 0x1, 0x1 }, /* cyan target */ ++ ++ { 0x1, 0x1, 0 }, /* yellow target */ ++ { 0, 0, 0 }, /* britewhite targer */ ++ { 0x1, 0, 0x1 }, /* magenta target */ ++ { 0, 0, 0x7 }, /* purple target */ ++ ++ { 0x2, 0x1, 0 }, /* orange target */ ++ { 0, 0x9, 0x4 }, /* olive target */ ++ { 0x7FFF, 0, 0 }, /* burgundy target */ ++ { 0x2, 0x1, 0x1 }, /* salmon target */ ++ ++ { 0x1, 0x1, 0 }, /* yellowgreen target */ ++ { 0x1, 0x2, 0x2 }, /* ltblue target */ ++ { 0x2, 0x1, 0x2 }, /* ltmagenta target */ ++ { 0, 0, 0 }, /* copper target */ + }; + + XColor** colset = (XColor **)calloc(COLORSETS, sizeof(XColor *)); @@ -351,74 +423,428 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + colset[n] = make_colorset(st, rgbmono, NULL); + } + else { -+ for (n = 0; n < COLORSETS; n++) -+ colset[n] = make_colorset(st, rgb[n], rgb_low[n]); ++ for (n = 0; n < COLORSETS; n++) { ++ if (st->shape == SNIPES) ++ colset[n] = make_colorset(st, rgb[n], rgb_low_snipes[n]); ++ else ++ colset[n] = make_colorset(st, rgb[n], rgb_low[n]); ++ } + } + return colset; +} + -+static void worm_write(STATE *st, int c, long row, long col, WORM *s, int clear) ++static void xcolor_to_xftcolor(STATE *st, XColor *xcolor, unsigned short alpha) ++{ ++ st->color.color.red = xcolor->red; ++ st->color.color.green = xcolor->green; ++ st->color.color.blue = xcolor->blue; ++ st->color.color.alpha = alpha; ++ st->color.pixel = 0xFFFFFF00; ++} ++ ++static void set_xftcolor(STATE *st, unsigned long tcolor, unsigned short alpha) ++{ ++ st->color.color.red = ((tcolor & 0xFF0000) >> 16 ) * 0x101; ++ st->color.color.green = ((tcolor & 0x00FF00) >> 8 ) * 0x101; ++ st->color.color.blue = ((tcolor & 0x0000FF) ) * 0x101; ++ st->color.color.alpha = alpha; ++ st->color.pixel = 0xFFFFFF00; ++} ++ ++static int XLoadFonts(STATE *st) ++{ ++#if DEBUG ++ char **names = NULL, **names2 = NULL; ++ int count = 0, count2 = 0; ++ XFontStruct *info = 0; ++#endif ++ ++ char pattern[1024]; ++ const char *fontname = ++ "DejaVu Sans Mono:pixelsize=%d:antialias=false;style=bold;"; ++ ++#if DEBUG ++ sprintf (pattern, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", ++ "*", /* foundry */ ++ "*", /* family */ ++ "*", /* weight */ ++ "*", /* slant */ ++ "*", /* swidth */ ++ "*", /* adstyle */ ++ "0", /* pixel size */ ++ "0", /* point size */ ++ "0", /* resolution x */ ++ "0", /* resolution y */ ++ "m", /* spacing */ ++ "0", /* avg width */ ++ "*"); /* registry + encoding */ ++ ++ names = XListFonts (st->dpy, pattern, 1000, &count); ++ if (count > 0) { ++#if VERBOSE ++ int i; ++ ++ for (i=0; i < count; i++) { ++ printf("%s\n", names[i]); ++ } ++#endif ++ names2 = XListFontsWithInfo (st->dpy, names[0], 1000, &count2, &info); ++ if (count2 > 0) ++ XFreeFontInfo(names2, info, count2); ++ XFreeFontNames(names); ++ } ++#endif ++ ++ if (st->shape == CLASSIC) ++ sprintf(pattern, fontname, st->wormsize - 4); ++ else ++ sprintf(pattern, fontname, st->wormsize); ++#if VERBOSE ++ fprintf (stderr, "%s: xft pattern %s\n", progname, pattern); ++#endif ++ ++ st->scr = DefaultScreen(st->dpy); ++ st->cmap = DefaultColormap(st->dpy, st->scr); ++ ++ st->xftfont = XftFontOpenName(st->dpy, st->scr, pattern); ++ if (!st->xftfont) { ++ fprintf (stderr, "%s: could not load base font %s\n", ++ progname, fontname); ++ return 1; ++ } ++ ++ if (!(st->hascolor = XftColorAllocName(st->dpy, st->visual, st->cmap, ++ "white", &st->color))) { ++ fprintf (stderr, "%s: cannot allocate xft color\n", progname); ++ return 1; ++ } ++ ++ st->draw = XftDrawCreate(st->dpy, st->window, st->visual, st->cmap); ++ if (!st->draw) { ++ fprintf (stderr, "%s: cannot allocate XftDraw\n", progname); ++ return 1; ++ } ++ ++ /* reset height, width, lines, and columns based on font metrics */ ++ st->HEIGHT = ((st->xftfont->height + 1) * 2) / 2; ++ st->WIDTH = st->HEIGHT / 2; ++ ++ XGetWindowAttributes (st->dpy, st->window, &st->xgwa); ++ st->LINES = st->xgwa.height / st->HEIGHT; ++ st->COLS = st->xgwa.width / st->WIDTH; ++ ++ return 0; ++} ++ ++static void XArrow(STATE *st, int x, int y, int radius, int direction) ++{ ++ XPoint points[3]; ++ double th; ++ int radius2; ++ double tick = ((M_PI * 2) / 18) * 2; ++ ++ radius *= 0.9; ++ radius *= direction; ++ radius2 = radius - (radius / 8) * 3; ++ ++ th = 2 * M_PI * (1 / ((double) 360*64)); ++ ++ points[0].x = x + radius * cos(th); /* tip */ ++ points[0].y = y + radius * sin(th); ++ ++ points[1].x = x + radius2 * cos(th - tick); /* tip left */ ++ points[1].y = y + radius2 * sin(th - tick); ++ ++ points[2].x = x + radius2 * cos(th + tick); /* tip right */ ++ points[2].y = y + radius2 * sin(th + tick); ++ ++ XDrawLine (st->dpy, st->b, st->gc, ++ (int) (x + radius2 * cos(th)), ++ (int) (y + radius2 * sin(th)), ++ (int) (x + -radius * cos(th)), ++ (int) (y + -radius * sin(th))); ++ ++ XFillPolygon (st->dpy, st->b, st->gc, points, 3, Convex, CoordModeOrigin); ++} ++ ++static void Triangle(STATE *st, int x, int y, int direction, int c) ++{ ++ XPoint points[3]; ++ int npoints = 3; ++ int shape = Convex; ++ int mode = CoordModeOrigin; ++ int radius, d = -1; ++ ++ switch (c) { ++ default: ++ case 0: radius = (st->WIDTH * 7) / 8; break; ++ case 1: radius = (st->WIDTH * 6) / 8; break; ++ case 2: radius = (st->WIDTH * 5) / 8; break; ++ case 3: radius = (st->WIDTH * 4) / 8; break; ++ } ++ ++ /* 0=down, 1=down-right 2=right, 3=up-right */ ++ /* 4=up, 5=up-left 6=left 7-down-left */ ++ switch (direction) { ++ default: return; ++ case 0: d = 270; break; ++ case 1: d = 300; break; ++ case 2: d = 0; break; ++ case 3: d = 60; break; ++ case 4: d = 90; break; ++ case 5: d = 120; break; ++ case 6: d = 180; break; ++ case 7: d = 240; break; ++ } ++ ++ /* convert from unit circle x,y coordinates to screen x,y coordinates by ++ * making sin equal to abs -[sin]. */ ++ points[0].x = (short) x + (radius * cos(M_PI * 2 * (d % 360 ) / 360)); ++ points[0].y = (short) y + -(radius * sin(M_PI * 2 * (d % 360 ) / 360)); ++ points[1].x = (short) x + (radius * cos(M_PI * 2 * ((d + 120) % 360) / 360)); ++ points[1].y = (short) y + -(radius * sin(M_PI * 2 * ((d + 120) % 360) / 360)); ++ points[2].x = (short) x + (radius * cos(M_PI * 2 * ((d + 240) % 360) / 360)); ++ points[2].y = (short) y + -(radius * sin(M_PI * 2 * ((d + 240) % 360) / 360)); ++ XFillPolygon(st->dpy, st->b, st->gc, points, npoints, shape, mode); ++ ++} ++ ++static void worm_write(STATE *st, int c, long row, long col, WORM *s, ++ int clear, int direction, int head) +{ + int which; -+ XColor *snake_colset; ++ XColor *worm_colset; ++ XGlyphInfo extents1, extents2, extents3, extents4, extents5; ++#if VERBOSE ++ printf("Xfill(%d) direction %d col: %ld row: %ld COLS: %d LINES: %d\n", ++ s->cpu, direction, col, row, st->COLS, st->LINES); ++#endif ++ ++ if (!clear) { ++ if (col >= st->COLS) ++ return; ++ if (row >= st->LINES) ++ return; ++ } + -+ if (col >= st->COLS) ++ /* set defaults */ ++ if (!st->black || !st->colors) { ++ fprintf (stderr, "%s: basic colorsets not initialized\n", progname); + return; -+ if (row >= st->LINES) ++ } ++ ++ worm_colset = st->colors[s->color]; ++ if (!worm_colset) { ++ fprintf (stderr, "%s: worm colorsets not initialized\n", progname); + return; ++ } ++ which = st->ncolors >> 1; + + if (clear) { -+ // clear previous block -+ XSetForeground(st->dpy, st->gc, st->colors[0][0].pixel); ++ /* clear previous block */ ++ XSetForeground(st->dpy, st->gc, st->black[0].pixel); + } + else { -+ snake_colset = st->colors[s->color]; + switch (c) + { -+ // head block ++ /* head block */ + case 0: + default: + which = st->ncolors >> 1; + break; -+ // dark shade block ++ /* dark shade block */ + case 1: -+ st->mono -+ ? (which = (st->ncolors >> 1) + 2) -+ : (which = (st->ncolors >> 1) + 2); ++ which = (st->ncolors >> 1) + 2; + break; -+ // medium shade block ++ /* medium shade block */ + case 2: -+ st->mono -+ ? (which = (st->ncolors >> 1) + 3) -+ : (which = (st->ncolors >> 1) + 3); ++ which = (st->ncolors >> 1) + 3; + break; -+ // light shade block ++ /* light shade block */ + case 3: -+ st->mono -+ ? (which = (st->ncolors >> 1) + 4) -+ : (which = (st->ncolors >> 1) + 4); ++ which = (st->ncolors >> 1) + 4; + break; + } -+ XSetForeground (st->dpy, st->gc, snake_colset[which].pixel); ++ XSetForeground(st->dpy, st->gc, worm_colset[which].pixel); + } + -+ if (!st->circles) -+ XFillRectangle(st->dpy, st->b, st->gc, col * st->WIDTH, -+ row * st->HEIGHT, st->WIDTH, st->HEIGHT); -+ else ++ switch (st->shape) { ++ ++ /* from the Novell Netware Snipes Network Game */ ++ case SNIPES: ++ if (!st->xftfont || !st->hascolor || !st->draw) ++ break; ++ ++ /* if clear then set foreground to black */ ++ if (clear) ++ set_xftcolor(st, (unsigned long)0x000000, 0xFFFF); ++ else ++ xcolor_to_xftcolor(st, &worm_colset[which], 0xFFFF); ++ ++ XftTextExtentsUtf8(st->dpy, st->xftfont, ++ (FcChar8 *) "^^", 2, &extents1); ++ XftTextExtentsUtf8(st->dpy, st->xftfont, ++ (FcChar8 *) "oo", 2, &extents2); ++ XftTextExtentsUtf8(st->dpy, st->xftfont, ++ /* \u25C0\u25B6 */ ++ (FcChar8 *)snipes_utf8_1, 6, &extents3); ++ XftTextExtentsUtf8(st->dpy, st->xftfont, ++ /* \u229a\u229a */ ++ (FcChar8 *)snipes_utf8_2, 6, &extents4); ++ XftTextExtentsUtf8(st->dpy, st->xftfont, ++ (FcChar8 *)"<>", 2, &extents5); ++ if (head) ++ { ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, ++ (row * st->HEIGHT) + extents1.height + ++ extents1.height + (extents1.height / 2), ++ (const FcChar8 *)"^^", 2); ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, ++ (row * st->HEIGHT) + ++ extents1.height + extents2.height, ++ (const FcChar8 *)"oo", 2); ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, ++ (row * st->HEIGHT) + ++ extents2.height + extents3.height, ++ (const FcChar8 *)snipes_utf8_1, 6); ++ } ++ else { ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, ++ (row * st->HEIGHT) + extents1.height + ++ extents4.height - (extents1.height / 2), ++ (const FcChar8 *)snipes_utf8_2, 6); ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, ++ (row * st->HEIGHT) + ++ extents1.height + extents4.height + ++ extents5.height - (extents1.height / 2), ++ (const FcChar8 *)"<>", 2); ++ } ++ break; ++ ++ /* NetWare SMP classic screensaver */ ++ case CLASSIC: ++ if (!st->xftfont || !st->hascolor || !st->draw) ++ break; ++ ++ XftTextExtentsUtf8(st->dpy, st->xftfont, ++ (FcChar8 *)classic_utf8_1, 6, &extents1); ++ XftTextExtentsUtf8(st->dpy, st->xftfont, ++ (FcChar8 *)classic_utf8_2, 6, &extents2); ++ XftTextExtentsUtf8(st->dpy, st->xftfont, ++ (FcChar8 *)classic_utf8_3, 6, &extents3); ++ XftTextExtentsUtf8(st->dpy, st->xftfont, ++ (FcChar8 *)classic_utf8_4, 6, &extents4); ++ ++ /* if clear then set foreground to black */ ++ if (clear) { ++ set_xftcolor(st, (unsigned long)0x000000, 0xFFFF); ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, (row * st->HEIGHT) + ++ extents1.height, ++ (const FcChar8 *)classic_utf8_1, 6); ++ } ++ else { ++ xcolor_to_xftcolor(st, &worm_colset[which], 0xFFFF); ++ switch (c) { ++ case 0: ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, (row * st->HEIGHT) + ++ extents1.height, ++ (const FcChar8 *)classic_utf8_1, 3); ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH + st->WIDTH, ++ (row * st->HEIGHT) + ++ extents1.height, ++ (const FcChar8 *)classic_utf8_1, 3); ++ break; ++ case 1: ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, (row * st->HEIGHT) + ++ extents1.height, ++ (const FcChar8 *)classic_utf8_1, 3); ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH + st->WIDTH, ++ (row * st->HEIGHT) + ++ extents1.height, ++ (const FcChar8 *)classic_utf8_1, 3); ++ break; ++ case 2: ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, (row * st->HEIGHT) + ++ extents1.height, ++ (const FcChar8 *)classic_utf8_1, 3); ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH + st->WIDTH, ++ (row * st->HEIGHT) + ++ extents1.height, ++ (const FcChar8 *)classic_utf8_1, 3); ++ break; ++ case 3: ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH, (row * st->HEIGHT) + ++ extents1.height, ++ (const FcChar8 *)classic_utf8_1, 3); ++ XftDrawStringUtf8(st->draw, &st->color, st->xftfont, ++ col * st->WIDTH + st->WIDTH, ++ (row * st->HEIGHT) + ++ extents1.height, ++ (const FcChar8 *)classic_utf8_1, 3); ++ break; ++ } ++ } ++ break; ++ ++ default: ++ case SQUARES: ++ XSetForeground(st->dpy, st->gc, st->black[0].pixel); ++ XDrawRectangle(st->dpy, st->b, st->gc, col * st->WIDTH, ++ row * st->HEIGHT, st->HEIGHT, st->HEIGHT); ++ if (!clear) ++ XSetForeground (st->dpy, st->gc, worm_colset[which].pixel); ++ XFillRectangle(st->dpy, st->b, st->gc, col * st->WIDTH + 1, ++ row * st->HEIGHT + 1, st->HEIGHT - 1, st->HEIGHT - 1); ++ break; ++ ++ case BALLS3D: ++ break; ++ ++ case CIRCLES: + XFillArc(st->dpy, st->b, st->gc, col * st->WIDTH, row * st->HEIGHT, -+ st->HEIGHT, st->HEIGHT, 0, 360 * 64); -+ ++ st->HEIGHT, st->HEIGHT, 0, 360 * 64); ++ break; ++ ++ case ARROWS: ++ XSetLineAttributes(st->dpy, st->gc, 8, LineSolid, CapRound, ++ JoinRound); ++ XArrow(st, col * st->WIDTH, row * st->HEIGHT, 30, direction); ++ break; ++ ++ case TRIANGLES: ++ if (clear) ++ XFillArc(st->dpy, st->b, st->gc, col * st->WIDTH, row * st->HEIGHT, ++ st->HEIGHT, st->HEIGHT, 0, 360 * 64); ++ XSetLineAttributes(st->dpy, st->gc, ++ (st->HEIGHT / 10) ? (st->HEIGHT / 10) : 1, ++ LineSolid, CapRound, JoinRound); ++ XDrawArc(st->dpy, st->b, st->gc, col * st->WIDTH, row * st->HEIGHT, ++ st->HEIGHT, st->HEIGHT, 0, 360 * 64); ++ Triangle(st, (col * st->WIDTH) + st->WIDTH, ++ (row * st->HEIGHT) + st->HEIGHT / 2, direction, c); ++ break; ++ } + -+#if VERBOSE -+ printf("Xfill col: %ld row: %ld COLS: %d LINES: %d\n", col, row, st->COLS, st->LINES); -+#endif + return; +} + +static int get_processors(void) +{ + int cpus = 0; ++ + cpus = sysconf(_SC_NPROCESSORS_ONLN); + if (cpus < 1) + cpus = 1; @@ -428,10 +854,11 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +static int get_cpu_load(STATE *st, int cpu) +{ + static char line[1024], *s; -+ unsigned long long p_usr = 0, p_nice = 0, p_sys = 0, p_idle = 0; -+ unsigned long long load = 0, idle = 0, util = 0, len; -+ unsigned long long p_io = 0, p_irq = 0, p_sirq = 0; -+ unsigned long long p_steal = 0, p_guest = 0, p_guest_nice = 0; ++ unsigned long p_usr = 0, p_nice = 0, p_sys = 0, p_idle = 0; ++ unsigned long load = 0, idle = 0, util = 0; ++ unsigned long p_io = 0, p_irq = 0, p_sirq = 0; ++ unsigned long p_steal = 0, p_guest = 0, p_guest_nice = 0; ++ long len; + FILE *f; + char src[1024] = "\0"; + @@ -441,8 +868,8 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + if (cpu > MAX_WORMS) + return 0; + -+ // convert cpu num to ascii text number -+ // and null terminate ++ /* convert cpu num to ascii text number ++ and null terminate */ + snprintf(src, 100, "cpu%d", cpu); + len = strlen(src); + @@ -464,36 +891,37 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + p_guest = st->guest[cpu]; + p_guest_nice = st->guest_nice[cpu]; + -+ if (sscanf(&line[len + 1], "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", ++ if (sscanf(&line[len + 1], ++ "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", + &(st->usr[cpu]), &(st->nice[cpu]), + &(st->sys[cpu]), &(st->idle[cpu]), + &(st->io[cpu]), &(st->irq[cpu]), + &(st->sirq[cpu]), &(st->steal[cpu]), + &(st->guest[cpu]), &(st->guest_nice[cpu])) == 10) + { -+ // calculate total cycles -+ unsigned long long user, nice; -+ unsigned long long idletime; -+ unsigned long long deltaidle; -+ unsigned long long systime; -+ unsigned long long virtalltime; -+ unsigned long long totaltime; -+ unsigned long long deltatime; -+ -+ // Guest time is already accounted in usertime ++ /* calculate total cycles */ ++ unsigned long user, nice; ++ unsigned long idletime; ++ unsigned long deltaidle; ++ unsigned long systime; ++ unsigned long virtalltime; ++ unsigned long totaltime; ++ unsigned long deltatime; ++ ++ /* Guest time is already accounted in usertime */ + user = st->usr[cpu] - st->guest[cpu]; + nice = st->nice[cpu] - st->guest_nice[cpu]; -+ // io is added in the total idle time ++ /* io is added in the total idle time */ + idletime = st->idle[cpu] + st->io[cpu]; + systime = st->sys[cpu] + st->irq[cpu] + st->sirq[cpu]; + virtalltime = st->guest[cpu] + st->guest_nice[cpu]; + totaltime = user + nice + systime + idletime + + st->steal[cpu] + virtalltime; + -+ // Guest time is already accounted in usertime ++ /* Guest time is already accounted in usertime */ + user = p_usr - p_guest; + nice = p_nice - p_guest_nice; -+ // io is added in the total idle time ++ /* io is added in the total idle time */ + deltaidle = p_idle + p_io; + systime = p_sys + p_irq + p_sirq; + virtalltime = p_guest + p_guest_nice; @@ -502,14 +930,14 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + + load = totaltime - deltatime; + idle = idletime - deltaidle; -+ // prevent divide by zero if result is 0 ++ /* prevent divide by zero if result is 0 */ + if (!load) { + load = 1; + idle = 1; + } + -+ // subtract idle cycles from load and mulitply * 100 -+ // to express as percentage ++ /* subtract idle cycles from load and mulitply * 100 ++ to express as percentage */ + util = (load - idle) * 100 / load; + idle = (idle * 100) / load; + break; @@ -528,7 +956,8 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + if (len < WORM_MIN_LEN) + len = WORM_MIN_LEN; +#if VERBOSE -+ printf("Load on cpu %d is %lld%% length %lld idle %lld%%\n", cpu, util, len, idle); ++ printf("Load on cpu %d is %ld%% length %ld idle %ld%%\n", ++ cpu, util, len, idle); +#endif + return (len); +} @@ -555,7 +984,7 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + else + l1 = 0; + -+ // convert from float to integer ++ /* convert from float to integer */ + l1 *= 1000.0; + l2 = (int) l1; + l2 /= 1000; @@ -575,7 +1004,6 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + /* and direction */ + dir = s->direction; + -+ /* 0=up, 2=right, 4=down, 6=left */ + switch(dir) + { + case 0: y++; break; @@ -615,7 +1043,7 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + dir++; + else if(rnd == 2) + dir--; -+ // set this to the current worm length ++ /* set this to the current worm length */ + s->runlength = s->length; + } + else { @@ -632,18 +1060,23 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + if (dir < 0) + dir = -dir; + dir = dir % 8; -+ ++#if DEBUG ++ if (dir > 7 || dir < 0) ++ printf("move worm direction was %d\n", dir); ++#endif + s->direction = dir; + + /* Copy x,y coords in "tail" positions */ + for(n = s->length - 1; n > 0; n--) { + s->x[n] = s->x[n-1]; + s->y[n] = s->y[n-1]; ++ s->d[n] = s->d[n-1]; + } + + /* New head position */ + s->x[0] = x; + s->y[0] = y; ++ s->d[0] = s->direction; + +} + @@ -678,6 +1111,7 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + + s->x[len] = x; + s->y[len] = y; ++ s->d[len] = s->direction; + } + else if (newlen < len) { + len--; @@ -685,6 +1119,7 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + len = WORM_MIN_LEN; + s->x[len + 1] = 0; + s->y[len + 1] = 0; ++ s->d[len + 1] = 0; + } + s->length = len; + return (len); @@ -695,9 +1130,8 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + int n; + + for (n = s->length_prev - 1; n >= 0; n--) { -+ worm_write(st, ' ', s->y_prev[n], s->x_prev[n], s, 1); -+ if (!st->circles) -+ worm_write(st, ' ', s->y_prev[n], s->x_prev[n] + 1, s, 1); ++ worm_write(st, ' ', s->y_prev[n], s->x_prev[n], s, 1, ++ s->d_prev[n], n ? 0 : 1); + } +} + @@ -755,15 +1189,13 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +{ + int n, div, mod, c; + -+ // get character interval and draw worm it is -+ // assumed that the minimum worm length is 4 ++ /* get character interval and draw worm it is ++ assumed that the minimum worm length is 4 */ + div = s->length / 4; + mod = s->length % 4; + for (n = s->length - 1; n >= 0 && div; n--) { + c = n < (div + 1) * mod ? n / (div + 1) : (n - mod) / div; -+ worm_write(st, c % 4, s->y[n], s->x[n], s, 0); -+ if (!st->circles) -+ worm_write(st, c % 4, s->y[n], s->x[n] + 1, s, 0); ++ worm_write(st, c % 4, s->y[n], s->x[n], s, 0, s->d[n], n ? 0 : 1); +#if VERBOSE + printf("cpu %d x[n] = %d y[n] = %d n = %d\n", + s->cpu, s->x[n], s->y[n], n); @@ -778,11 +1210,12 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +{ + int n; + -+ // save last worm position and coordinates -+ // for clearing later ++ /* save last worm position and coordinates ++ for clearing later */ + for (n = s->length - 1; n >= 0; n--) { + s->x_prev[n] = s->x[n]; + s->y_prev[n] = s->y[n]; ++ s->d_prev[n] = s->d[n]; + } + s->length_prev = s->length; +} @@ -792,7 +1225,7 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + float range, increment; + int n; + -+ // reset columns and lines in case the screen was resized ++ /* reset columns and lines in case the screen was resized */ + st->worm_max_length = AREA_BASE_LEN + AREA_EXT_LEN; + if (st->worm_max_length > WORM_MAX_LEN) + st->worm_max_length = WORM_MAX_LEN; @@ -804,7 +1237,6 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + s->count = 0; + grow_worm(st, s); + move_worm(st, s); -+ //clear_worm(st, s); + s->limit = 4 - (s->length / (st->worm_max_length / 4)); +#if VERBOSE + printf("length %d limit %d\n", s->length, s->limit); @@ -814,16 +1246,16 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + clear_worm(st, s); + save_worm(s); + -+ // update all worms even those sleeping to -+ // maintain worm overwrite stacking order -+ // when one worm overwrites another during -+ // display ++ /* update all worms even those sleeping to ++ maintain worm overwrite stacking order ++ when one worm overwrites another during ++ display */ + draw_worm(st, s); + } + -+ // decrease base wait time if system load increases -+ // range is 0-100 load average before reaching -+ // minimum st->delay wait time ++ /* decrease base wait time if system load increases ++ range is 0-100 load average before reaching ++ minimum st->delay wait time */ + n = get_system_load(); + + range = MAX_MICROSEC - MIN_MICROSEC; @@ -842,6 +1274,11 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +{ + STATE *st; + int n, i; ++ XColor fg, bg; ++ XGCValues gcv; ++ int rgb_black[3]= { ++ 0xFFFF, 0xFFFF, 0xFFFF ++ }; + + st = (STATE *)calloc(1, sizeof(STATE)); + if (!st) { @@ -850,12 +1287,8 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + } + memset(st, 0, sizeof(STATE)); + -+ XColor fg, bg; -+ XGCValues gcv; -+ + st->dpy = dpy; + st->window = window; -+ + st->cpunum = get_integer_resource (st->dpy, "cpus", "Integer"); + st->speedup = get_integer_resource (st->dpy, "speedup", "Integer"); + st->delay = get_integer_resource (st->dpy, "delay", "Integer"); @@ -863,7 +1296,9 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + st->ncolors = 16; + st->dbuf = get_boolean_resource(st->dpy, "doubleBuffer", "Boolean"); + st->mono = get_boolean_resource (st->dpy, "mono", "Boolean"); -+ st->circles = get_boolean_resource (st->dpy, "circles", "Boolean"); ++ st->stats = get_boolean_resource (st->dpy, "stats", "Boolean"); ++ st->shape = get_integer_resource (st->dpy, "shape", "Integer"); ++ st->charset = get_string_resource (dpy, "fontCharset", "FontCharset"); + +#ifdef HAVE_COCO + st->dbuf = False; @@ -888,18 +1323,32 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + + if (st->wormsize < 10 || st->wormsize > 80) + { -+ fprintf(stderr, "%s: specified wormsize (%d) must be between 10 and 80, defaulting to 30\n", ++ fprintf(stderr, "%s: specified wormsize (%d) must be between 10 " ++ "d 80, defaulting to 30\n", + progname, st->wormsize); -+ st->HEIGHT = 30; -+ st->WIDTH = st->HEIGHT / 2; ++ st->wormsize = 30; + } -+ else -+ { -+ st->HEIGHT = st->wormsize; -+ st->WIDTH = st->wormsize / 2; ++ ++ st->HEIGHT = st->wormsize; ++ st->WIDTH = st->wormsize / 2; ++ ++ switch (st->shape) { ++ case SNIPES: ++ case CLASSIC: ++ if (!st->charset) ++ st->charset = "iso8859-1"; ++ if (XLoadFonts(st)) { ++ free(st); ++ fprintf (stderr, "%s: load fonts failed!\n", progname); ++ exit (1); ++ } ++ break; ++ default: ++ break; + } + + st->colors = init_colorsets(st); ++ st->black = make_colorset(st, rgb_black, NULL); + st->COLS = st->xgwa.width / st->WIDTH; + st->LINES = st->xgwa.height / st->HEIGHT; + @@ -947,12 +1396,17 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + s->cpu = n; + s->x[0] = random() % (st->COLS - 1); + s->y[0] = random() % st->LINES; ++ s->direction = (((random() % 9) >> 1) << 1) % 8; + for (i=1; i < WORM_MAX_LEN; i++) + { + s->x[i] = s->x[0]; + s->y[i] = s->y[0]; ++ s->d[i] = s->direction; ++#if DEBUG ++ if (s->direction > 7 || s->direction < 0) ++ printf("init move worm direction was %d\n", s->direction); ++#endif + } -+ s->direction = ((random() % 9) >> 1) << 1; + s->length = WORM_MIN_LEN; + s->runlength = WORM_MIN_LEN; + s->color = n % COLORSETS; @@ -982,9 +1436,9 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +{ + STATE *st = (STATE *) closure; + -+ // set nice value to highest priority since on a heavily loaded system -+ // we want the worms to get maximum cycles so the display is not jerky -+ // or intermitently freezes ++ /* set nice value to highest priority since on a heavily loaded system ++ we want the worms to get maximum cycles so the display is not jerky ++ or intermitently freezes */ + st->prio = getpriority(PRIO_PROCESS, 0); + setpriority(PRIO_PROCESS, 0, -20); + @@ -1037,8 +1491,19 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net + XColor **colset = st->colors; + int n = COLORSETS; + -+ while (n--) -+ free(colset[n]); ++ if (st->draw) ++ XftDrawDestroy(st->draw); ++ if (st->hascolor) ++ XftColorFree(st->dpy, st->visual, st->cmap, &st->color); ++ if (st->xftfont) ++ XftFontClose (st->dpy, st->xftfont); ++ ++ if (st->black) ++ free(st->black); ++ while (n--) { ++ if (colset[n]) ++ free(colset[n]); ++ } + if (st->colors) + free(st->colors); + if (st->worms) @@ -1049,11 +1514,15 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +static const char *netwaresmp_defaults [] = { + ".cpus: 1", + ".speedup: 1", ++ ".shape: 0", ++ ".mono: False", ++ ".stats: False", + ".background: #000000", -+ ".foreground: #FF0000", ++ ".foreground: #FFFFFF", + "*delay: 100000", + "*wormsize: 30", + "*doubleBuffer: False", ++ "*fontCharset: iso8859-1", +#ifdef HAVE_DOUBLE_BUFFER_EXTENSION + "*useDBE: True", + "*useDBEClear: True", @@ -1062,14 +1531,15 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +}; + +static XrmOptionDescRec netwaresmp_options [] = { -+ { "-cpus", ".cpus", XrmoptionSepArg, 0}, ++ { "-cpus", ".cpus", XrmoptionSepArg, 0}, + { "-speedup", ".speedup", XrmoptionSepArg, 0}, ++ { "-shape", ".shape", XrmoptionSepArg, 0}, + { "-fg", ".foreground", XrmoptionSepArg, 0}, + { "-bg", ".background", XrmoptionSepArg, 0}, + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-wormsize",".wormsize", XrmoptionSepArg, 0 }, + { "-mono", ".mono", XrmoptionNoArg, "True" }, -+ { "-circles", ".circles", XrmoptionNoArg, "True" }, ++ { "-stats", ".stats", XrmoptionNoArg, "True" }, + { "-db", ".doubleBuffer", XrmoptionNoArg, "True" }, + { "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" }, + { 0, 0, 0, 0 } @@ -1078,14 +1548,14 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.c xscreensaver-6.08/hacks/net +XSCREENSAVER_MODULE ("NetwareSMP", netwaresmp) diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.man xscreensaver-6.08/hacks/netwaresmp.man --- xscreensaver-6.08-orig/hacks/netwaresmp.man 1969-12-31 16:00:00.000000000 -0800 -+++ xscreensaver-6.08/hacks/netwaresmp.man 2024-02-21 13:19:16.578238090 -0800 -@@ -0,0 +1,63 @@ ++++ xscreensaver-6.08/hacks/netwaresmp.man 2024-03-10 23:49:00.903242529 -0700 +@@ -0,0 +1,70 @@ +.TH XScreenSaver 1 "27-Apr-97" "X Version 11" +.SH NAME +netwaresmp - Novell Netware SMP console screensaver +.SH SYNOPSIS +.B netwaresmp -+[\-cpus \fI number of cpus\fP] [-speedup \fI divisor\fP] [-wormsize \fI pixels\fP] [\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-window] [\-root] [\-mono] [\-circles] [\-install] [\-visual \fIvisual\fP] ++[\-cpus \fI number of cpus\fP] [-speedup \fI divisor\fP] [-wormsize \fI pixels\fP] [\-display \fIhost:display.screen\fP] [\-foreground \fIcolor\fP] [\-background \fIcolor\fP] [\-window] [\-root] [\-mono] [\-shape \fI <0-6>\fP] [\-install] [\-visual \fIvisual\fP] +.SH DESCRIPTION +The \fInetwaresmp\fP screensaver written by Jeffrey Merkey and Cosimo Streppone , based on PopSquares, Deco hacks, loadsnake, and Novell's Netware SMP. The original Netware SMP screensaver was written by Jeffrey Merkey at Novell in 1994. This version is a rewrite of the original which functions exactly the same way as it did in Netware SMP. Each worm represents a running system cpu processor. As system utilization increases for each cpu, the corresponding worm for that processor gets longer and moves more quicky across the screen. As overall system load increases, all the worms slightly increase in speed. This screensaver is very useful for monitoring cpu loading in a system since you can visually see processor utilization and loading by simply observing the worms. +.SH OPTIONS @@ -1110,8 +1580,15 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.man xscreensaver-6.08/hacks/n +.B \-mono +If on a color display, pretend we're on a monochrome display. +.TP 8 -+.B \-circles -+Use circles instead of squares to create the worms. ++.B \-shape ++Specify worm drawing mode: ++0 for squares, ++1 for circles, ++2 for snipes (from the NetWare game "Snipes", the first distributed network game run over a local area network), ++3 for triangles, ++4 for classic (retro text-based screensaver from NetWare SMP), ++5 for arrows ++6 for 3D balls, +.TP 8 +.B \-install +Install a private colormap for the window. @@ -1145,7 +1622,7 @@ diff -Naur xscreensaver-6.08-orig/hacks/netwaresmp.man xscreensaver-6.08/hacks/n +1994. diff -Naur xscreensaver-6.08-orig/xscreensaver.spec xscreensaver-6.08/xscreensaver.spec --- xscreensaver-6.08-orig/xscreensaver.spec 2023-10-10 17:24:04.989688938 -0700 -+++ xscreensaver-6.08/xscreensaver.spec 2024-02-20 23:52:00.953904032 -0800 ++++ xscreensaver-6.08/xscreensaver.spec 2024-03-10 23:48:37.277926911 -0700 @@ -1,10 +1,13 @@ %define name xscreensaver %define version 6.08