180 lines
5.1 KiB
C
180 lines
5.1 KiB
C
|
#include "config.h"
|
||
|
|
||
|
/* Copyright (C) 2002 Brad Jorsch <anomie@users.sourceforge.net>
|
||
|
|
||
|
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 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*/
|
||
|
|
||
|
/* One-line algorithm from http://www.moonstick.com/moon_phase_emergency.htm
|
||
|
* It's a bit rough, but it works well enough */
|
||
|
|
||
|
#if TM_IN_SYS_TIME
|
||
|
# if TIME_WITH_SYS_TIME
|
||
|
# include <sys/time.h>
|
||
|
# include <time.h>
|
||
|
# else
|
||
|
# if HAVE_SYS_TIME_H
|
||
|
# include <sys/time.h>
|
||
|
# else
|
||
|
# include <time.h>
|
||
|
# endif
|
||
|
# endif
|
||
|
#else
|
||
|
#include <time.h>
|
||
|
#endif
|
||
|
#include <math.h>
|
||
|
|
||
|
#include <X11/Xlib.h>
|
||
|
#include <X11/xpm.h>
|
||
|
|
||
|
#include "convert.h"
|
||
|
|
||
|
#include "wmgeneral/wmgeneral-x11.h"
|
||
|
|
||
|
static double fpart(double t){
|
||
|
return t-trunc(t);
|
||
|
}
|
||
|
|
||
|
double calc_moon(int month, int day, int year, int hm){
|
||
|
time_t t=time(NULL);
|
||
|
struct tm *tm;
|
||
|
double p;
|
||
|
|
||
|
tm=gmtime(&t);
|
||
|
tm->tm_hour=hm/100;
|
||
|
tm->tm_min=hm%100;
|
||
|
tm->tm_sec=0;
|
||
|
tm->tm_mon=month-1;
|
||
|
tm->tm_mday=day;
|
||
|
tm->tm_year=year;
|
||
|
t=mkgmtime(tm);
|
||
|
|
||
|
/* This next line is the algorithm. */
|
||
|
p=fpart(((t/86400.0-11323.0)*850.0+5130.5769)/25101.0);
|
||
|
if(p>.5) return -.5+cos(2*PI*p)/2;
|
||
|
return .5-cos(2*PI*p)/2;
|
||
|
}
|
||
|
|
||
|
|
||
|
#define darkside 0.19921875
|
||
|
#define lightside (1-0.19921875)
|
||
|
#define maxwidth 17
|
||
|
static int widths[]={ 7, 11, 13, 15, 15, 17, 17, 17, 17, 17, 17, 17, 15, 15, 13, 11, 7, -1 };
|
||
|
extern int screen;
|
||
|
extern XpmIcon wmgen;
|
||
|
extern GC NormalGC;
|
||
|
|
||
|
/* Duplicates quite a bit of code from combineWithOpacity for speed */
|
||
|
void copySunMoon(int x, int y, double percent){
|
||
|
XImage *pix;
|
||
|
unsigned int w, h, bar;
|
||
|
int foo;
|
||
|
Window baz;
|
||
|
int rmask, gmask, bmask;
|
||
|
unsigned long spixel;
|
||
|
int xx, terminator, oflag;
|
||
|
int flag;
|
||
|
double frac;
|
||
|
|
||
|
if(isnan(percent)){
|
||
|
copyPixmapArea(164, 64, 26, 25, x, y);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
XGetGeometry(display, wmgen.pixmap, &baz, &foo, &foo, &w, &h, &bar, &bar);
|
||
|
pix=XGetImage(display, wmgen.pixmap, 0, 0, w, h, AllPlanes, ZPixmap);
|
||
|
|
||
|
if (pix->depth == DefaultDepth(display, screen)) {{
|
||
|
Visual *visual=DefaultVisual(display, screen);
|
||
|
rmask = visual->red_mask;
|
||
|
gmask = visual->green_mask;
|
||
|
bmask = visual->blue_mask;
|
||
|
}} else {
|
||
|
rmask = pix->red_mask;
|
||
|
gmask = pix->green_mask;
|
||
|
bmask = pix->blue_mask;
|
||
|
}
|
||
|
|
||
|
x+=4; y+=4;
|
||
|
flag=(percent<0);
|
||
|
if(flag) percent=-percent;
|
||
|
for(h=0; widths[h]>0; h++){
|
||
|
xx=(maxwidth-widths[h])>>1;
|
||
|
if(flag){
|
||
|
oflag=1;
|
||
|
terminator=widths[h]*percent;
|
||
|
} else {
|
||
|
oflag=0;
|
||
|
terminator=widths[h]-widths[h]*percent;
|
||
|
}
|
||
|
frac=lightside*fpart(widths[h]*percent)+darkside;
|
||
|
for(w=0; w<widths[h]; w++){
|
||
|
spixel=XGetPixel(pix, 168+xx+w, 93+h);
|
||
|
if(w==terminator){
|
||
|
oflag=!oflag;
|
||
|
XPutPixel(pix, x+xx+w, y+h,
|
||
|
(((unsigned long)((spixel&rmask)*frac))&rmask) |
|
||
|
(((unsigned long)((spixel&gmask)*frac))&gmask) |
|
||
|
(((unsigned long)((spixel&bmask)*frac))&bmask));
|
||
|
} else if(oflag){
|
||
|
XPutPixel(pix, x+xx+w, y+h, spixel);
|
||
|
} else {
|
||
|
XPutPixel(pix, x+xx+w, y+h,
|
||
|
(((unsigned long)((spixel&rmask)*darkside))&rmask) |
|
||
|
(((unsigned long)((spixel&gmask)*darkside))&gmask) |
|
||
|
(((unsigned long)((spixel&bmask)*darkside))&bmask));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
XPutImage(display, wmgen.pixmap, NormalGC, pix, 0, 0, 0, 0, pix->width, pix->height);
|
||
|
|
||
|
XDestroyImage(pix);
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
void copySunMoon(int x, int y, double percent){
|
||
|
int w, h;
|
||
|
int xx;
|
||
|
int frac;
|
||
|
int flag;
|
||
|
|
||
|
if(isnan(percent)){
|
||
|
copyPixmapArea(164, 64, 26, 25, x, y);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
combineWithOpacity(164, 89, 26, 25, x, y, 51);
|
||
|
x+=4; y+=4;
|
||
|
flag=(percent<0);
|
||
|
if(flag) percent=-percent;
|
||
|
for(h=0; h<=8; h++){
|
||
|
w=widths[h]*percent;
|
||
|
frac=(widths[h]*percent-w)*100;
|
||
|
if(flag) xx=(17-widths[h])/2;
|
||
|
else xx=(17+widths[h])/2-w;
|
||
|
copyPixmapArea(141+xx, 93+h, w, 1, x+xx, y+h);
|
||
|
copyPixmapArea(141+xx, 109-h, w, 1, x+xx, y+16-h);
|
||
|
if(flag){
|
||
|
combineWithOpacity(141+xx+w, 93+h, 1, 1, x+xx+w, y+h, frac);
|
||
|
combineWithOpacity(141+xx+w, 109-h, 1, 1, x+xx+w, y+16-h, frac);
|
||
|
} else {
|
||
|
combineWithOpacity(141+xx-1, 93+h, 1, 1, x+xx-1, y+h, frac);
|
||
|
combineWithOpacity(141+xx-1, 109-h, 1, 1, x+xx-1, y+16-h, frac);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|