/*****************************************************************************/ /* XBlood Copyright (c) 1998-2000 Sakai Hiroaki. */ /* All Rights Reserved. */ /*===========================================================================*/ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2, or (at your option) */ /* any later version. */ /*****************************************************************************/ /*****************************************************************************/ /* Include Header Files */ /*****************************************************************************/ #include #include #include #include /*****************************************************************************/ /* Difinitions of Some Parameters */ /*****************************************************************************/ #define ON 1 #define OFF 0 #define DEFAULT_NUMBER 30 #define DEFAULT_SIZE 20 #define DEFAULT_SPEED 100 #define DEFAULT_SCATTER_NUMBER 150 #define DEFAULT_SCATTER_RADIUS 200 #define DEFAULT_SCATTER_SIZE 60 #define DEFAULT_COLOR "red" #define DEFAULT_STAY_FLAG OFF #define DEFAULT_QUIT_FLAG OFF #define DEFAULT_WAIT 10000 typedef struct XBlood { Display * display; int screen; Colormap colormap; int width, height; Window root_window; char * display_name; GC gc; } XBlood; typedef struct Blood { int number, size, speed_max; int scatter_number, scatter_radius, scatter_size; char * color; int stay_flag, quit_flag; int wait; XArc * point; int * speed; int * count; int depth; } Blood; static char * help_string = "\n" VERSION " Sakai Hiroaki\n\n" "XBlood fills the root window with blood.\n" "Red, blue or green bloody window is very bad taste!\n" "\n" "-display [displayname] The name of the X server to use.\n" "-h, -help Output help message.\n" "-stay, -noflow Blood stays the bottom of the root window.\n" "-nostay, -flow Blood flows down through the root window. (Default)\n" "-quit Draw blood and quit.\n" "-noquit Draw blood and they flow. (Default)\n" "-number [x] The number of bloody drops. (30)\n" "-size [x] The maximum size of bloody drops\' width. (20)\n" "-speed [x] The speed of droping. (100)\n" "-scatter-number [x] The maximum number of scatters. (150)\n" "-scatter-radius [x] The maximum radius of scatters. (200)\n" "-scatter-size [x] The maximum size of scatters. (60)\n" "-color [color] Bloody drops\' color. (red)\n" "-wait [x] Wait time. (10000)\n" "\n"; /*****************************************************************************/ /* Definitions of Functions */ /*****************************************************************************/ void SetDefaultValue(XBlood * xbp, Blood * bp) { xbp->display_name = NULL; bp->number = DEFAULT_NUMBER; bp->size = DEFAULT_SIZE; bp->speed_max = DEFAULT_SPEED; bp->scatter_number = DEFAULT_SCATTER_NUMBER; bp->scatter_radius = DEFAULT_SCATTER_RADIUS; bp->scatter_size = DEFAULT_SCATTER_SIZE; bp->color = DEFAULT_COLOR; bp->stay_flag = DEFAULT_STAY_FLAG; bp->quit_flag = DEFAULT_QUIT_FLAG; bp->wait = DEFAULT_WAIT; bp->depth = 0; } void Help() { printf("%s", help_string); exit (0); } void ReadParameter(XBlood * xbp, Blood * bp, int ac, char ** av) { int i; for (i = 0; i < ac; i++) { if (!strcmp(av[i], "-h" )) Help(); else if (!strcmp(av[i], "-help" )) Help(); else if (!strcmp(av[i], "-stay" )) bp->stay_flag = ON; else if (!strcmp(av[i], "-nostay")) bp->stay_flag = OFF; else if (!strcmp(av[i], "-flow" )) bp->stay_flag = OFF; else if (!strcmp(av[i], "-noflow")) bp->stay_flag = ON; else if (!strcmp(av[i], "-quit" )) bp->quit_flag = ON; else if (!strcmp(av[i], "-noquit")) bp->quit_flag = OFF; if (i < ac - 1) { if (!strcmp(av[i],"-display")) xbp->display_name = av[++i]; else if (!strcmp(av[i],"-number" )) bp->number = atoi(av[++i]); else if (!strcmp(av[i],"-size" )) bp->size = atoi(av[++i]); else if (!strcmp(av[i],"-speed" )) bp->speed_max = atoi(av[++i]); else if (!strcmp(av[i],"-scatter-number")) bp->scatter_number = atoi(av[++i]); else if (!strcmp(av[i],"-scatter-radius")) bp->scatter_radius = atoi(av[++i]); else if (!strcmp(av[i],"-scatter-size")) bp->scatter_size = atoi(av[++i]); else if (!strcmp(av[i],"-color" )) bp->color = av[++i]; else if (!strcmp(av[i],"-wait" )) bp->wait = atoi(av[++i]); } } } void InitializeDisplay(XBlood * xbp) { xbp->display = XOpenDisplay(xbp->display_name); xbp->screen = DefaultScreen(xbp->display); xbp->colormap = DefaultColormap(xbp->display, xbp->screen); xbp->width = DisplayWidth( xbp->display, xbp->screen); xbp->height = DisplayHeight(xbp->display, xbp->screen); xbp->root_window = RootWindow(xbp->display, xbp->screen); } int RandomValue(int n) { return ((rand() / 256) % n); } void MakeBlood(XBlood * xbp, Blood * bp, int i) { int n, num, w, r, d; int x0, y0, x, y; bp->point[i].width = RandomValue(bp->size) + 2; bp->point[i].height = bp->point[i].width * 2; bp->point[i].x = RandomValue(xbp->width) - bp->point[i].width / 2; bp->point[i].y = RandomValue(xbp->height + 100) - bp->depth - 100; bp->point[i].angle1 = 0; bp->point[i].angle2 = 360 * 64; bp->speed[i] = RandomValue(bp->speed_max) + 1; bp->count[i] = 0; w = bp->point[i].width * (RandomValue(4) + 5) / 4; x0 = bp->point[i].x - (w - bp->point[i].width) / 2; y0 = bp->point[i].y; XFillArc(xbp->display, xbp->root_window, xbp->gc, x0, y0, w, w, 0, 360 * 64); num = RandomValue(bp->scatter_number); for (n = 0; n < num; n++) { r = RandomValue(bp->point[i].width * bp->scatter_size / 100) + 1; x = x0 + w / 2 - r / 2 + RandomValue(bp->point[i].width * bp->scatter_radius / 100) - RandomValue(bp->point[i].width * bp->scatter_radius / 100); y = y0 + w / 2 - r / 2 + RandomValue(bp->point[i].width * bp->scatter_radius / 100) - RandomValue(bp->point[i].width * bp->scatter_radius / 100); XFillArc(xbp->display, xbp->root_window, xbp->gc, x, y, r, r, 0, 360 * 64); } } unsigned long int GetColor(XBlood * xbp, char * color) { XColor c0, c1; XAllocNamedColor(xbp->display, xbp->colormap, color, &c0, &c1); return (c0.pixel); } void InitializeBlood(XBlood * xbp, Blood * bp) { int i; srand((unsigned)time(NULL)); bp->point = (XArc *)malloc(sizeof(XArc) * bp->number); bp->speed = (int *)malloc(sizeof(int ) * bp->number); bp->count = (int *)malloc(sizeof(int ) * bp->number); xbp->gc = XCreateGC(xbp->display, xbp->root_window, 0, 0); XSetForeground(xbp->display, xbp->gc, GetColor(xbp, bp->color)); XSetArcMode(xbp->display, xbp->gc, ArcPieSlice); for (i = 0; i < bp->number; i++) MakeBlood(xbp, bp, i); } void BloodMain(XBlood * xbp, Blood * bp) { int i, j; if (bp->quit_flag) return; while (bp->depth < xbp->height) { XFillArcs(xbp->display, xbp->root_window, xbp->gc, bp->point, bp->number); for (j = 0; j < bp->number; j++) { bp->count[j] += bp->speed[j]; while (bp->count[j] >= 200) { bp->count[j] -= 200; (bp->point[j].y)++; } if (bp->point[j].y >= xbp->height - bp->depth) { if (bp->stay_flag == ON) { (bp->depth)++; XFillRectangle(xbp->display, xbp->root_window, xbp->gc, 0, xbp->height - bp->depth, xbp->width, bp->depth); } MakeBlood(xbp, bp, j); } } XFlush(xbp->display); usleep(bp->wait); } } void BloodQuit(XBlood * xbp, Blood * bp) { free(bp->point); free(bp->speed); free(bp->count); XCloseDisplay(xbp->display); exit (0); } main(int argc, char ** argv) { XBlood xblood; Blood blood; SetDefaultValue(&xblood, &blood); ReadParameter(&xblood, &blood, argc, argv); InitializeDisplay(&xblood); InitializeBlood(&xblood, &blood); BloodMain(&xblood, &blood); BloodQuit(&xblood, &blood); } /*****************************************************************************/ /* End of XBlood */ /*****************************************************************************/