From c857efe2a30ea81440a60e49be6117a44f8e28e4 Mon Sep 17 00:00:00 2001
From: Sebastian Schauer <sebschauer@sebschauer.de>
Date: Tue, 14 Dec 2021 14:51:16 +0100
Subject: [PATCH] adding clock

---
 hacks/Makefile.in      |  113 +-
 hacks/clock.c          | 1017 ++++++++++++++
 hacks/clock.h          |  462 +++++++
 hacks/clock.man        |   69 +
 hacks/config/clock.xml |   38 +
 6 files changed, 4627 insertions(+), 34 deletions(-)


diff --git a/hacks/clock.c b/hacks/clock.c
new file mode 100644
index 0000000..d621ff3
--- /dev/null
+++ b/hacks/clock.c
@@ -0,0 +1,1017 @@
+/* xscreensaver, Copyright (c) 1992-2008 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.No representations are made about the suitability of this
+ * software for any purpose.It is provided "as is" without express or 
+ * implied warranty.
+ * 
+ * This hack "clock" 2017 by Sebastian Schauer <sebschauer@sebschauer.de>
+ * 
+ */
+
+#include "screenhack.h"
+#include "clock.h"
+#include <time.h>
+
+
+/* State of the screensaver */
+struct state {
+	/* 
+	 * Used for all clocks
+	 */
+	Display *dpy;
+	Window window;
+	GC gc;
+	int delay;
+	int start;
+	unsigned long fg, bg;
+	Colormap cmap;
+	/* maximum width/height of screen */
+	int xlim, ylim;
+	/* time of last drawing */
+	int last_second;
+	/* switching mode? */
+	int mode_switch;
+	/* time of last switch */
+	time_t last_switch;
+	/* waiting time before next mode switching (min) */
+	int switchtime;
+	/* size factor to be set by user (percent of screen) */
+	int scale;
+	/* colors */
+	unsigned long white, black, grey, red, green;
+	/* mode: ANALOG/DIGITAL/BINARY/HUMAN */
+	int mode;
+	
+	
+	/* 
+	 * Analog clock 
+	 */
+	/* diameter of the clock hands */
+	int r_hour, r_minute, r_second, r_max;
+	/* diameter of the middle circle */
+	int r_middle;
+	/* center of screen */
+	int xcenter, ycenter;
+	
+	
+	/* 
+	 * Digital clock 
+	 */
+	/* lenght of long segment side, short square */
+	int seg_l, seg_d;
+	/* diameter of points */
+	int r;
+	/* center of points */
+	XPoint circle[2];
+	/* Segments of the digits: XPoint list
+	 * 6 Digits, 7 Segments, 7 Points */
+	XPoint segment[6][7][7];
+	
+	
+	/* 
+	 * Binary clock 
+	 */
+	/* x- and y-offsets of the points */
+	int x[6], y[3];
+	/* radius of the circles */
+	int rad;
+	
+	
+	/* 
+	 * Human clock 
+	 */
+	 /* time of last drawing (this clock changes only each minute */
+	int last_minute;
+	struct h_font * h_alphabet;
+	int h_char, w_char, d_char, h_pix, d_pix, top_char, top_circle;
+	int h_firstrun;
+};
+
+static int max(int a , int b)
+{
+	return (a>b) ? a : b;
+}
+
+static int min(int a , int b)
+{
+	return (a<b) ? a : b;
+}
+
+/*
+ * 
+ * Analog clock
+ * 
+ */
+
+static XPoint hand_top(float value, int radius, int cx, int cy, int type) {
+	/* calculates the x/y-coordinates of a point of a clock hand
+	 * needs the distance from the center (radius), the center (cx/cy),
+	 * the type (e.g. HOUR) and a value (the time the hand is showing,
+	 * e.g. 27 minutes) */
+	XPoint p;
+	int factor = 1;
+
+	switch (type) 
+	{
+		case SECOND:
+		case MINUTE:
+			factor = 60;
+			break;
+		case HOUR:
+			factor = 12;
+			if (value >= 12) value -= 12;
+	}
+	p.x = (short) cx + sin((value / factor) * 2 * M_PI) * radius;
+	p.y = (short) cy - cos((value / factor) * 2 * M_PI) * radius;
+	return p;
+}
+
+static void
+draw_analog_hand(int type, float time, struct state *st, struct tm *tm)
+{
+	float thick = 0;
+	int color = 0, r = 0, rt = 0;
+	XPoint hand[4], shape[5];
+
+	switch (type)
+	{
+		case HOUR:
+			thick = 0.35;
+			color = st->green;
+			r = st->r_hour;
+			rt = st->r_hour * 70 / 100;
+			break;
+		case MINUTE:
+			thick = 0.8;
+			color = st->green;
+			r = st->r_minute;
+			rt = st->r_hour * 80 / 100;
+			break;
+		case SECOND:
+			thick = 0.5;
+			color = st->green;
+			r = st->r_second;
+			rt = st->r_hour * 85 / 100;
+	}
+	/* calculate positions of the four points of the hand */
+	hand[0].x = shape[0].x = shape[4].x = st->xcenter;
+	hand[0].y = shape[0].y = shape[4].y = st->ycenter;
+	shape[2] = hand[2] = hand_top(time, r, st->xcenter, st->ycenter, type);
+	shape[1] = hand[1] = hand_top(time - thick, rt, st->xcenter, st->ycenter, type);
+	shape[3] = hand[3] = hand_top(time + thick, rt, st->xcenter, st->ycenter, type);
+	/* Draw it (polygon and shaping line) */
+	XSetForeground(st->dpy, st->gc, color);
+	XFillPolygon(st->dpy, st->window, st->gc, hand, 4, Convex, CoordModeOrigin);
+	XSetForeground(st->dpy, st->gc, st->black);
+	XDrawLines(st->dpy, st->window, st->gc, shape, 5, CoordModeOrigin);
+}
+
+static void
+draw_analog_clock(struct state *st, struct tm *tm)
+{
+	int r = (st->r_max + st->r_second) / 2;
+
+	/* Overpaint last hands */
+	XSetForeground(st->dpy, st->gc, st->black);
+	XFillArc(st->dpy, st->window, st->gc, 
+		st->xcenter - r, st->ycenter - r, 
+		2 * r, 2 * r, 
+		0, 360*64
+	);
+	
+	/* Draw the clock: */
+	draw_analog_hand(HOUR, tm->tm_hour + (tm->tm_min / 60.0), st, tm);
+	draw_analog_hand(MINUTE, tm->tm_min, st, tm);
+	draw_analog_hand(SECOND, tm->tm_sec, st, tm);
+	
+	/* Draw middle circles */
+	XSetForeground(st->dpy, st->gc, st->green);
+	XFillArc(st->dpy, st->window, st->gc, st->xcenter-(st->r_middle*0.5), st->ycenter-(st->r_middle*0.5), st->r_middle, st->r_middle, 0, 360*64);
+	XSetForeground(st->dpy, st->gc, st->black);
+	XDrawArc(st->dpy, st->window, st->gc, st->xcenter-(st->r_middle*0.5), st->ycenter-(st->r_middle*0.5), st->r_middle, st->r_middle, 0, 360*64);
+	XSetForeground(st->dpy, st->gc, st->green);
+	XFillArc(st->dpy, st->window, st->gc, st->xcenter-(st->r_middle*0.125), st->ycenter-(st->r_middle*0.125), st->r_middle/4, st->r_middle/4, 0, 360*64);
+	XSetForeground(st->dpy, st->gc, st->black);
+	XDrawArc(st->dpy, st->window, st->gc, st->xcenter-(st->r_middle*0.125), st->ycenter-(st->r_middle*0.125), st->r_middle/4, st->r_middle/4, 0, 360*64);
+}
+
+static void
+analog_clock_draw_signs(struct state *st)
+{
+	int i, r;
+	XPoint top, down;
+
+	/* Signs */
+	for (i=0; i<60; i++) 
+	{	
+		XSetForeground(st->dpy, st->gc, st->green);
+		top = hand_top((float) i, st->r_max, st->xcenter, st->ycenter, MINUTE);
+		r = (st->r_max + st->r_second) / 2;
+		if (i % 5 != 0) 
+		{
+			r += (st->r_max - st->r_second) / 3;
+			XSetForeground(st->dpy, st->gc, st->green);
+		}
+		down = hand_top((float) i, r, st->xcenter, st->ycenter, MINUTE);
+		XDrawLine(st->dpy, st->window, st->gc, down.x, down.y, top.x, top.y);
+	}
+}
+
+static void
+analog_clock_init(struct state *st)
+{
+	int rmax;
+
+	st->xcenter = st->xlim / 2; /* middle of the screen */
+	st->ycenter = st->ylim / 2;
+	
+	rmax = min( st->xlim / 2, st->ylim / 2) * st->scale / 100.0;
+	
+	st->r_max = rmax * (100 - MAG_RAND) / 100.0; 
+	/* defining lengths of the hands and the whole clock */
+	st->r_hour = st->r_max * AN_MAG_HOUR / 100.0;
+	st->r_minute = st->r_max * AN_MAG_MINUTE / 100.0;
+	st->r_second = st->r_max * AN_MAG_SECOND / 100.0;
+	st->r_middle = st->r_max * AN_MAG_MIDDLE / 50.0;
+	
+	/* Start: Clear window, Draw signs, go on! */
+	XClearWindow(st->dpy, st->window);
+	analog_clock_draw_signs(st);
+	return;
+}
+
+/*
+ * 
+ * Digital clock
+ * 
+ */
+
+/* Returns "18:2358" or "18 2359" (the time as string) */
+static void
+get_digital_time_string(char * s, struct tm *tm)
+{
+	char c = (tm->tm_sec % 2 == 1) ? ' ' : ':';
+	sprintf(
+		s, 
+		"%02d%c%02d%02d", 
+		tm->tm_hour, c, tm->tm_min, tm->tm_sec
+	);
+	return;
+}
+
+static void
+draw_points(struct state *st, char c)
+{
+	int i;
+	/* Get color of the dots */
+	int color = (c == ':') ? st->green : st->grey;
+
+	/* Draw them */
+	for (i=0; i<2; i++)
+	{
+		XSetForeground(st->dpy, st->gc, color);
+		XFillArc(st->dpy, st->window, st->gc, st->circle[i].x, st->circle[i].y, st->r, st->r, 0, 360*64);
+	}
+	return;
+}
+
+static void
+draw_digit(int position, int value, struct state *st)
+{
+	int seg, color;
+
+	for (seg=0; seg<7; seg++)
+	{
+		/* Get color of the segment   */
+		color = (digits[value][seg]==1)?st->green:st->grey;
+		XSetForeground(st->dpy, st->gc, color);
+		/* Draw */
+		XFillPolygon(
+			st->dpy, st->window, st->gc, 
+			st->segment[position][seg], 7, 
+			Convex, CoordModePrevious
+		);
+	}
+}
+
+/* Draw the digital clock */
+static void 
+draw_digital_clock(struct state *st, struct tm *tm)
+{
+	char *time_string = calloc(10, sizeof(char));
+	int i;
+
+	get_digital_time_string(time_string, tm);	/* 23:5959 */
+	
+	for (i=0; i<7; i++) 
+	{
+		if (i==2) 	/* Blinking dots */
+			draw_points(st, time_string[2]);
+		else 		/* Digit #0-5 */
+			draw_digit( (i>2)?i-1:i, time_string[i]-'0', st);
+	}
+	return;
+}
+
+static void
+digital_clock_init(struct state *st)
+{
+	int box_digit_w, box_time_w, space;
+	int d, l, bottom, left, right;
+	int dig, seg;
+	int xoff[6];
+	int i;
+	XPoint point;
+
+	/* Let's calculate the surrounding box depending on screen and scale */
+	box_time_w = st->xlim * st->scale / 100.0;
+	d = box_time_w * 2.0 / (19 * (6 + DI_MAG_SEG));
+	l = d * DI_MAG_SEG;
+
+	/* The box around the digits, offsets... */
+	box_digit_w = l + 6 * d;
+	space = box_digit_w / 2.0; 
+	bottom = st->ylim / 2 + l + 5 * d;
+	/* Digits 0-3: 2x hour, 2x minute */
+	for(i=0; i<4; i++) 
+		xoff[i] = i * box_digit_w + space * (i + i / 2);
+	/* Digits 4-5: 2x second (smaller) */
+	for(i=4;i<6;i++) 
+		xoff[i] = xoff[3] 
+		          + box_digit_w + space * 1.5 
+		          + (i - 4.0) * DI_MAG_SEC * (box_digit_w + space) / 100.0 
+		;
+	/* centering the clock */
+	right = xoff[5] + box_digit_w * DI_MAG_SEC / 100.0;
+	left = (st->xlim - right) / 2;
+	for(i=0; i<6; i++) xoff[i] += left;
+	
+	/* the blinking dots */
+	st->r = 2.5 * d;
+	st->circle[0].x = st->circle[1].x = xoff[1] + box_digit_w + space - st->r / 2;
+	st->circle[0].y = st->ylim / 2 + l / 2 - st->r / 2;
+	st->circle[1].y = st->ylim / 2 - l / 2 - st->r / 2;
+	
+	/* now the segments of the digits */
+	for (dig=0; dig<6; dig++)
+	{
+		if (dig == 4) /* Seconds should be smaller */
+		{
+			d *= DI_MAG_SEC / 100.0;
+			l *= DI_MAG_SEC / 100.0;
+		}
+		for (seg=0; seg<8; seg++)
+		{
+			if (seg%3 == 0) 		/* horizontal segment */
+			{
+				point.x = xoff[dig] + 1.75 * d;
+				point.y = bottom - (d + (seg / 3) * (l + 4 * d));
+				st->segment[dig][seg][0] = point;
+				
+				point.x = d; point.y = -d;
+				st->segment[dig][seg][1] = point;
+				
+				point.x = l+d / 2.0; point.y = 0;
+				st->segment[dig][seg][2] = point;
+				
+				point.x = d; point.y = d;
+				st->segment[dig][seg][3] = point;
+				
+				point.x = -d; point.y = d;
+				st->segment[dig][seg][4] = point;
+				
+				point.x = -l-d / 2.0; point.y = 0;
+				st->segment[dig][seg][5] = point;
+				
+				point.x = -d; point.y = -d;
+				st->segment[dig][seg][6] = point;
+			}
+			else 
+			{
+				if (seg%3 == 1) 	/* left segment */
+					point.x = xoff[dig] + d;
+				else 				/* right segment */
+					point.x = xoff[dig] + 5.0 * d + l;
+				if (seg<3) 			/* lower segment */
+					point.y = bottom - 1.75 * d;
+				else 				/* upper segment */
+					point.y = bottom - (5.75 * d + l);
+				st->segment[dig][seg][0] = point;
+				
+				point.x = -d; point.y = -d;
+				st->segment[dig][seg][1] = point;
+				
+				point.x = 0; point.y = -l - d / 2.0;
+				st->segment[dig][seg][2] = point;
+				
+				point.x = d; point.y = -d;
+				st->segment[dig][seg][3] = point;
+				
+				point.x = d; point.y = d;
+				st->segment[dig][seg][4] = point;
+				
+				point.x = 0; point.y = l + d / 2.0;
+				st->segment[dig][seg][5] = point;
+				
+				point.x = -d; point.y = d;
+				st->segment[dig][seg][6] = point;
+			}
+		}
+	}
+	
+	/* Start: Clear window, go on! */
+	XClearWindow(st->dpy, st->window);
+	return;
+}
+
+
+/*
+ * 
+ * Binary clock
+ * 
+ */
+
+static void
+draw_binary_clock(struct state *st, struct tm *tm)
+{
+	int i, j, val = 0, color;
+	for(i=0; i<3; i++) /* let's draw three binary digits one by one */
+	{
+		switch (i+1) /* HOUR = 1, not 0 (unfortunately) */
+		{
+			case HOUR: 		val = tm->tm_hour; break;
+			case MINUTE:	val = tm->tm_min; break;
+			case SECOND:	val = tm->tm_sec;
+		}
+		
+		for(j=0; j<6; j++) /* let's draw 6 points per digit one by one */
+		{
+			/* choose color */
+			color = (val >> j & 0x01) ? st->green : st->grey;
+			XSetForeground(st->dpy, st->gc, color);
+			XFillArc(st->dpy, st->window, st->gc, st->x[j], st->y[i] , 2 * st->rad, 2 * st->rad, 0, 360*64);
+		}
+	}
+}
+
+static void
+binary_clock_init(struct state *st)
+{
+	int w, h, i; /* w: width of the clock, h: height */
+	/* scaling */
+	w = st->scale * st->xlim / 100.0;
+	h = st->scale * st->ylim / 100.0;
+	st->rad = w / 30;
+	for(i=0; i<6; i++) /* horizontal offsets of the dots */
+	{
+		st->x[5-i] = (i + 1) * w / 7.0 - st->rad + (st->xlim - w) / 2;
+	}
+	for(i=0; i<3; i++) /* vertical offsets of the dots */
+	{
+		st->y[i] = (i + 1) * h / 4.0 - st->rad + (st->ylim - h) / 2;
+	}
+	/* Start: Clear window, go on! */
+	XClearWindow(st->dpy, st->window);
+}
+
+
+/*
+ * 
+ * Human clock (only in German)
+ * 
+ */
+
+static void get_human_time_string(char *einsvor, char *halbzwei, struct tm *tm)
+{
+	/* Returns something like "fünf vor halb sechs" from time *tm */
+	char *min, *vor, *halb, *std, um = 0; /* Fünf, vor, halb, sechs, (!) */
+	einsvor[0] = '\0';
+	halbzwei[0] = '\0';
+	min = NULL;
+	/* Now a lot of cases, german isn't easy ;-) */
+	if (tm->tm_min == 0)
+	{
+		min = zahlwort[13];
+		vor = vorwort[0];
+		if (tm->tm_hour == 0)
+		{
+			halb = halbwort[0];
+			std = zahlwort[tm->tm_hour];
+		}
+		else
+		{
+			halb = halbwort[4];
+			std = (tm->tm_hour > 12) ? zahlwort[tm->tm_hour - 12] : zahlwort[tm->tm_hour];
+		}		
+		um = 1;
+	}
+	else if (tm->tm_min < 11)
+	{
+		min = zahlwort[tm->tm_min];
+		vor = vorwort[2];
+		halb = halbwort[0];
+		std = (tm->tm_hour > 12) ? zahlwort[tm->tm_hour - 12] : zahlwort[tm->tm_hour];
+	}
+	else if (tm->tm_min < 15)
+	{
+		min = zahlwort[15 - tm->tm_min];
+		vor = vorwort[1];
+		halb = halbwort[1];
+		std = zahlwort[(tm->tm_hour % 12) + 1];
+	}
+	else if (tm->tm_min % 15 == 0)
+	{
+		min = zahlwort[13];
+		vor = vorwort[0];
+		halb = halbwort[tm->tm_min / 15];
+		std = zahlwort[(tm->tm_hour % 12) + 1];
+	}
+	else if (tm->tm_min < 20)
+	{
+		min = zahlwort[tm->tm_min - 15];
+		vor = vorwort[2];
+		halb = halbwort[1];
+		std = zahlwort[(tm->tm_hour % 12) + 1];
+	}
+	else if (tm->tm_min < 30)
+	{
+		min = zahlwort[30 - tm->tm_min];
+		vor = vorwort[1];
+		halb = halbwort[2];
+		std = zahlwort[(tm->tm_hour % 12) + 1];
+	}
+	else if (tm->tm_min == 30)
+	{
+		min = zahlwort[13];
+		vor = vorwort[0];
+		halb = halbwort[2];
+		std = zahlwort[(tm->tm_hour % 12) + 1];
+	}
+	else if (tm->tm_min < 41)
+	{
+		min = zahlwort[tm->tm_min - 30];
+		vor = vorwort[2];
+		halb = halbwort[2];
+		std = zahlwort[(tm->tm_hour % 12) + 1];
+	}
+	else if (tm->tm_min < 45)
+	{
+		min = zahlwort[45 - tm->tm_min];
+		vor = vorwort[1];
+		halb = halbwort[3];
+		std = zahlwort[(tm->tm_hour % 12) + 1];
+	}
+	else if (tm->tm_min == 45)
+	{
+		min = zahlwort[13];
+		vor = vorwort[0];
+		halb = halbwort[3];
+		std = zahlwort[(tm->tm_hour % 12) + 1];
+	}
+	else if (tm->tm_min < 50)
+	{
+		min = zahlwort[tm->tm_min - 45];
+		vor = vorwort[2];
+		halb = halbwort[3];
+		std = zahlwort[(tm->tm_hour % 12) + 1];
+	}
+	else if (tm->tm_min < 60)
+	{
+		min = zahlwort[60 - tm->tm_min];
+		vor = vorwort[1];
+		halb = halbwort[0];
+		if (tm->tm_hour == 23)
+		{
+			std = zahlwort[0];
+		}
+		else
+		{
+			std = (tm->tm_hour > 11) ? zahlwort[tm->tm_hour - 11] : zahlwort[tm->tm_hour + 1];
+		}	
+	}
+	
+	/* Concatenating results */
+	strcat(einsvor, min);
+	if (min != zahlwort[13]) strcat(einsvor, " ");
+	strcat(einsvor, vor);
+	strcat(halbzwei, halb);	
+	strcat(halbzwei, std);
+	if (um) strcat(halbzwei, "!");
+	
+	return;
+}
+
+static struct h_font * getFontEntry(char c, struct state * st)
+{
+	/* returns the "font" entry from given character */
+	int i;
+	for(i=0;i<31;i++) if (st->h_alphabet[i].letter == c) return &st->h_alphabet[i];
+	return NULL;
+}
+
+static void
+draw_human_line(struct state *st, int sec, int lenght, int y)
+{
+	/* Draw the lines of seconds. */
+	int i;
+	/* First overpaint existing lines. */
+	XSetForeground(st->dpy, st->gc, st->black);
+	XDrawLine(st->dpy, st->window, st->gc,
+		(st->xlim - lenght) / 2, y,
+		(st->xlim - lenght) / 2 + lenght, y
+	);
+	/* Now draw the new lines - grey or green. */
+	for (i=0;i<60;i++)
+	{
+		XSetForeground(st->dpy, st->gc, (i == sec) ? st->green : st->grey);
+		XDrawLine(st->dpy, st->window, st->gc,
+			(st->xlim - lenght) / 2 + lenght * i / 60.0, y,
+			(st->xlim - lenght) / 2 + lenght * (i + 1) / 60.0 - st->d_char, y
+		);
+	}
+	return;
+}	
+
+static void
+draw_human_character(struct h_display_char * ch, struct state * st)
+{
+	/* Drawing one single character. */
+	int r, c, color;
+	for (r=0; r<9; r++)
+	{
+		for (c=0; c<7; c++)
+		{
+			color = (pixelstructure[ch->character->pxfield][r][c]) ? st->green : st->grey;
+			XSetForeground(st->dpy, st->gc, color);
+			XFillRectangle(st->dpy, st->window, st->gc,
+				ch->offset.x + c * (ch->square_lenght + ch->distance),
+				ch->offset.y + r * (ch->square_lenght + ch->distance),
+				ch->square_lenght,
+				ch->square_lenght
+			);
+		}
+	}
+	return;
+}
+
+static void add_spaces(char *s1, char *s2)
+{
+	/* add spaces on both ends of the smaller string until they have equal size */
+	int l1 = strlen(s1), l2 = strlen(s2), i, d, lmin, lmax;
+	char *t, *temp;
+	if (l1 == l2) return;
+	t = (l1 < l2) ? s1 : s2;
+	d = (l1 < l2) ? l2 -l1 : l1 - l2;
+	lmin = (l1 < l2) ? l1 : l2;
+	lmax = (l1 < l2) ? l2 : l1;
+	
+	temp = malloc((lmax + 1) * sizeof(char));
+	for (i=0; i < lmax; i++) {
+		if (i < d/2) temp[i] = ' ';
+		else if (i < d/2 + lmin) temp[i] = t[i-d/2];
+		else temp[i] = ' ';
+	}
+	temp[i] = '\0';
+
+	if (l1 < l2) strncpy(s1, temp, l2); else strncpy(s2, temp, l1);
+	free(temp);
+	return;
+}
+
+static void
+draw_human_clock(struct state *st, struct tm *tm)
+{
+	char *einsvor = (char *) calloc(100, sizeof(char));
+	char *halbzwei = (char *) calloc(100, sizeof(char));
+	struct h_display_char *disp_char;
+	int i, j, l[2], left[2], lenght[2];	
+	
+	/* The text to draw */
+
+	get_human_time_string(einsvor, halbzwei, tm);
+	add_spaces(einsvor, halbzwei);
+	
+	l[0] = strlen(einsvor);
+	l[1] = strlen(halbzwei);
+	
+	/* centering coordinates */
+	for (i=0;i<2;i++)
+	{
+		lenght[i] = l[i] * st->w_char + (l[i] - 1) * st->d_char;
+		left[i] = (st->xlim - lenght[i]) / 2;
+	}
+	
+	/* No new text? Draw line, exit. */
+	if (st->last_minute == tm->tm_min)
+	{
+		draw_human_line(st, tm->tm_sec, max(lenght[0], lenght[1]), st->top_char + st->h_char * 1.2);
+		goto end;
+	}
+	
+	/* Draw text. */
+	st->last_minute = tm->tm_min;
+	XClearWindow(st->dpy, st->window);
+	
+	disp_char = (struct h_display_char *) calloc(max(l[0], l[1]), sizeof(struct h_display_char));
+	for (i=0; i<2; i++)
+	{
+		for(j=0;j<l[i];j++)
+		{
+			int offx = left[i], offy = st->top_char + i * 1.4 * st->h_char;
+			char *text = (i==0) ? einsvor : halbzwei;
+			disp_char[j].character = getFontEntry(text[j], st);
+			disp_char[j].square_lenght = st->h_pix;
+			disp_char[j].distance = st->d_pix;
+			disp_char[j].offset.x = offx + (j * (st->w_char + st->d_char));
+			disp_char[j].offset.y = offy;
+			draw_human_character(&disp_char[j], st);
+		}
+	}
+	free(disp_char);
+	/* Draw line. */
+	draw_human_line(st, tm->tm_sec, max(lenght[0], lenght[1]), st->top_char + st->h_char * 1.2);
+	
+	/* Exit */
+	end:
+	free(einsvor);
+	free(halbzwei);
+	
+	return;
+}
+
+static void
+human_clock_init(struct state *st)
+{
+
+	/* initialize alphabet */
+	char c;
+	st->h_firstrun = 0;
+	st->start = 0;
+	st->h_alphabet = (struct h_font *) calloc(31, sizeof(struct h_font));
+	for (c='a'; c<= 'z'; c++)
+	{
+		st->h_alphabet[c-'a'].letter = c;
+		st->h_alphabet[c-'a'].pxfield = c-'a';
+	}
+	st->h_alphabet[26].letter = 'M';
+	st->h_alphabet[26].pxfield = 26;
+	st->h_alphabet[27].letter = 'O'; /* means ö */
+	st->h_alphabet[27].pxfield = 27;
+	st->h_alphabet[28].letter = 'U'; /* means ü */
+	st->h_alphabet[28].pxfield = 28;
+	st->h_alphabet[29].letter = ' ';
+	st->h_alphabet[29].pxfield = 29;
+	st->h_alphabet[30].letter = '!';
+	st->h_alphabet[30].pxfield = 30;
+
+	/* char size */
+	st->w_char = st->xlim * st->scale / (100.0 * (18 + 17 / ( 7.0 + 6 * 0.25)));
+	st->h_pix = st->w_char / (7.0 + 6 * 0.25);
+	st->d_pix = st->h_pix * 0.25;
+	st->h_char = 9 * st->h_pix + 8 * st->d_pix;
+	st->d_char = st->h_pix;
+	st->top_char = (st->ylim - st->h_char) / 2 - st->h_char * 1.2;
+	
+	XClearWindow(st->dpy, st->window);
+	st->last_minute--;
+	return;
+}
+
+static void human_clock_free(struct state * st)
+{
+	free(st->h_alphabet);
+	return;
+}
+
+
+
+/*
+ * 
+ * Handling the clocks
+ * 
+ */
+
+/* choose the correct function (drawing/init for each clock) */
+static void
+clock_func(int action, struct state *st)
+{
+	if (action == INIT)
+	{	
+		switch (st->mode) 
+		{
+			case ANALOG: analog_clock_init(st);	break;
+			case DIGITAL: digital_clock_init(st); break;
+			case BINARY: binary_clock_init(st); break;
+			case HUMAN: human_clock_init(st);
+		}
+	}
+	else if (action == DRAW)
+	{
+		/* Drawing a clock needs a time to draw */
+		time_t now = time ((time_t *) 0);
+		struct tm *tm = localtime (&now);
+		switch (st->mode) 
+		{
+			case ANALOG: draw_analog_clock(st, tm); break;
+			case DIGITAL: draw_digital_clock(st, tm); break;
+			case BINARY: draw_binary_clock(st, tm); break;
+			case HUMAN: draw_human_clock(st, tm);
+		}
+	}
+	return;
+}
+
+/* Change the clock mode */
+static void
+switch_mode(time_t time, struct state *st) 
+{
+	st->last_switch = time;
+	switch (st->mode)
+	{
+		case ANALOG: st->mode = DIGITAL; break;
+		case DIGITAL: st->mode = BINARY; break;
+		case BINARY: st->mode = HUMAN; break;
+		case HUMAN: st->mode = ANALOG; 
+					human_clock_free(st);
+	}
+	clock_func(INIT, st);
+	return;
+}
+
+
+/*
+ * 
+ * Xscreensaver API
+ * 
+ */
+
+static void *
+clock_init (Display *dpy, Window window)
+{
+	struct state *st = (struct state *) calloc (1, sizeof(*st));
+	XGCValues gcv;
+	XWindowAttributes xgwa;
+	time_t now = time ((time_t *) 0);
+	struct tm *tm = localtime (&now);
+	char *s;
+	int problems = 0;
+
+	st->dpy = dpy;
+	st->window = window;
+	
+	/* get user defined values */
+	st->mode_switch = 0;
+	
+	s = get_string_resource(st->dpy, "mode", "Mode");
+	if (!s || !*s || !strcasecmp(s, "analog"))
+		st->mode = ANALOG;
+	else if (!strcasecmp(s, "digital"))
+		st->mode = DIGITAL;
+	else if (!strcasecmp(s, "binary"))
+		st->mode = BINARY;
+	else if (!strcasecmp(s, "human"))
+		st->mode = HUMAN;
+	else if (!strcasecmp(s, "switch"))
+	{
+		st->mode = tm->tm_sec % NUMBER_OF_CLOCKS ;
+		st->mode_switch = 1;
+		st->last_switch = now;
+	}
+	else
+	{
+		fprintf(stderr, "%s: unknown mode \"%s\"\n", progname, s);
+		problems++;
+	}
+	free(s);
+	
+	st->delay = get_integer_resource (st->dpy, "delay", "Integer");
+	if (st->delay > 10000) st->delay = 10000;
+	
+	st->switchtime = get_integer_resource (st->dpy, "switchtime", "Integer");
+	if (st->switchtime > 60) st->switchtime = 60;
+	if (st->switchtime < 1) st->switchtime = 1;
+	
+	st->scale = get_integer_resource(st->dpy, "scale", "Integer");
+	if (st->scale == 0) st->scale = 85;
+	if (st->scale < 10) st->scale = 10;
+	if (st->scale > 100) st->scale = 100;
+	
+	/* we have to know later that we are starting the program */
+	st->start = 1;
+	st->h_firstrun = 1;
+	/* we need a first drawing, so we calculate a wrong time */
+	st->last_second = tm->tm_sec - 2; 
+	st->last_minute = tm->tm_min - 2;
+	
+	/* initialize display */
+	XGetWindowAttributes (st->dpy, st->window, &xgwa);
+	st->cmap = xgwa.colormap;
+	gcv.foreground= st->fg= get_pixel_resource(st->dpy, st->cmap, "foreground","Foreground");
+	gcv.background= st->bg= get_pixel_resource(st->dpy, st->cmap, "background","Background");
+	st->gc = XCreateGC (st->dpy, st->window, GCForeground, &gcv);
+	XSetLineAttributes(st->dpy, st->gc, 3, LineSolid, CapNotLast, JoinRound);
+	
+	/* initialize state */
+	st->xlim = xgwa.width;
+	st->ylim = xgwa.height;
+	
+	st->white = 0xFFFFFF;
+	st->black = 0x000000;
+	st->grey = 0x181818;
+	st->red = 0xE12418;
+	st->green = 0x21A61B; 
+	
+	XSetWindowBackground(st->dpy, st->window, st->black);
+	XClearWindow(st->dpy, st->window);
+	
+	/* initialize the chosen clock*/
+	clock_func(INIT, st);
+	
+	if (problems) 
+		exit (1);
+
+	return st;
+}
+
+static unsigned long
+clock_draw (Display *dpy, Window window, void *closure)
+{
+	struct state *st = (struct state *) closure;
+
+	time_t now = time ((time_t *) 0);
+	struct tm *tm = localtime (&now);
+
+	if (st->mode_switch && (difftime(now, st->last_switch) >= 60 * st->switchtime))
+		switch_mode(now, st);
+	
+	if (st->start == 0)
+	{
+		/* Is there need to draw again? */
+		if (st->last_second == tm->tm_sec) return st->delay;
+		st->last_second = tm->tm_sec;
+	}
+	else
+		st->start = 0;
+	
+	clock_func(DRAW, st);	
+	
+	return st->delay;
+}
+
+static XrmOptionDescRec clock_options [] = {
+	{ "-delay",		".delay",	XrmoptionSepArg, 0 },
+	{ "-switchtime",		".switchtime",	XrmoptionSepArg, 0 },
+	{ "-scale",		".scale",	XrmoptionSepArg, 0 },
+	{ "-mode",		".mode",	XrmoptionSepArg, 0 },
+	{ "-analog", 		".mode",	XrmoptionNoArg, "analog" },
+	{ "-digital",		".mode",	XrmoptionNoArg, "digital" },
+	{ "-binary",		".mode",	XrmoptionNoArg, "binary" },
+	{ "-human",		".mode",	XrmoptionNoArg, "human" },
+	{ "-switch",		".mode",	XrmoptionNoArg, "switch" },
+	{ 0, 0, 0, 0 }
+};
+
+static const char *clock_defaults [] = {
+	".background:	black",
+	".foreground:	white",
+	"*fpsSolid:	true",
+	"*delay:	10000",
+	"*switchtime:	5",
+	"*scale:	90",
+	"*mode:	analog",
+	#ifdef USE_IPHONE
+	"*ignoreRotation: True",
+	#endif
+	0
+};
+
+static void
+clock_reshape (Display *dpy, Window window, void *closure, 
+ unsigned int w, unsigned int h)
+{
+	struct state *st = (struct state *) closure;
+	st->xlim = w;
+	st->ylim = h;
+	clock_func(INIT, st);
+	return;
+}
+
+static Bool
+clock_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+	return False;
+}
+
+static void
+clock_free (Display *dpy, Window window, void *closure)
+{
+	struct state *st = (struct state *) closure;
+	XFreeGC (st->dpy, st->gc);
+	free (st); 
+}
+
+XSCREENSAVER_MODULE ("Clock", clock)
diff --git a/hacks/clock.h b/hacks/clock.h
new file mode 100644
index 0000000..35b8e86
--- /dev/null
+++ b/hacks/clock.h
@@ -0,0 +1,462 @@
+/* clock.h - Definitions & more for clock screensaver */
+
+/* 
+ * Global definitions
+ */
+
+/* constants for internal use */
+#define HOUR 1
+#define MINUTE 2
+#define SECOND 3
+#define ANALOG 0
+#define DIGITAL 1
+#define BINARY 2
+#define HUMAN 3
+#define INIT 0
+#define DRAW 1
+#define NUMBER_OF_CLOCKS 4
+
+/* 
+ * The analog clock
+ */
+
+/* Intend (percent of smaller screen length) */
+#define MAG_RAND 5
+/* Length of the clock hands (percent of (smaller) screen length) */
+#define AN_MAG_HOUR 60
+#define AN_MAG_MINUTE 83
+#define AN_MAG_SECOND 85
+#define AN_MAG_MIDDLE 10
+
+/* 
+ * The digital clock
+ */
+
+/* (Reference length: width of a normalsize digit) */
+/* Lengt of the space between two digits in percent */
+#define DI_MAG_SPACE 50
+#define DI_MAG_SEC 70
+/* Proportion of a segment; bigger values make it slimmer. */
+#define DI_MAG_SEG 7
+
+/* The segments for each digit (on/off) */
+int digits[10][7] = {
+	{1, 1, 1, 0, 1, 1, 1}, /*0*/
+	{0, 0, 1, 0, 0, 1, 0}, /*1*/
+	{1, 1, 0, 1, 0, 1, 1}, /*2*/
+	{1, 0, 1, 1, 0, 1, 1}, /*3*/
+	{0, 0, 1, 1, 1, 1, 0}, /*4*/
+	{1, 0, 1, 1, 1, 0, 1}, /*5*/
+	{1, 1, 1, 1, 1, 0, 1}, /*6*/
+	{0, 0, 1, 0, 0, 1, 1}, /*7*/
+	{1, 1, 1, 1, 1, 1, 1}, /*8*/
+	{1, 0, 1, 1, 1, 1, 1}  /*9*/
+};
+
+
+
+/* 
+ * The binary clock
+ */
+ 
+
+/* 
+ * The human clock
+ */
+ 
+char *zahlwort[] = {
+	"Mitternacht",
+	"eins",
+	"zwei",
+	"drei",
+	"vier",
+	"fUnf",
+	"sechs",
+	"sieben",
+	"acht",
+	"neun",
+	"zehn",
+	"elf",
+	"zwOlf",
+	""
+};
+
+char *vorwort[] = 
+{
+	"",
+	"vor",
+	"nach"
+};
+
+char *halbwort[] = 
+{
+	"",
+	"viertel ",
+	"halb ",
+	"dreiviertel ",
+	"um "
+};
+
+char *satzwort[] = 
+{
+	"",
+	"!"
+};
+
+int pixelstructure[][9][7] = 
+{
+	{	/* a */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,1,1,1,0,0},
+		{0,0,0,0,0,1,0},
+		{0,0,1,1,1,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,1,1,1,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* b */
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,0,0},
+		{0,1,0,0,0,0,0},
+		{0,1,0,1,1,0,0},
+		{0,1,1,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,1,1,1,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* c */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,1,1,1,0},
+		{0,0,1,0,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,0,1,1,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* d */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,1,0},
+		{0,0,0,0,0,1,0},
+		{0,0,0,1,1,1,0},
+		{0,0,1,0,0,1,0},
+		{0,0,1,0,0,1,0},
+		{0,0,1,0,0,1,0},
+		{0,0,0,1,1,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* e */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,1,1,1,0,0},
+		{0,1,0,0,0,1,0},
+		{0,1,1,1,1,0,0},
+		{0,1,0,0,0,0,0},
+		{0,0,1,1,1,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* f */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,1,1,0},
+		{0,0,0,1,0,0,0},
+		{0,0,1,1,1,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* g */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,1,1,1,0,0},
+		{0,1,0,0,1,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,1,1,1,1,0},
+		{0,0,0,0,1,0,0},
+		{0,0,1,1,0,0,0}
+	},
+	{	/* h */
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,0,0},
+		{0,1,0,0,0,0,0},
+		{0,1,1,1,1,0,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* i */
+		{0,0,0,0,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,1,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,1,1,1,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* j */
+		{0,0,0,0,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,1,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,1,0,0,0,0}
+	},
+	{	/* k */
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,0,0},
+		{0,1,0,0,0,0,0},
+		{0,1,0,0,1,0,0},
+		{0,1,0,1,0,0,0},
+		{0,1,1,0,0,0,0},
+		{0,1,0,1,0,0,0},
+		{0,1,0,0,1,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* l */
+		{0,0,0,0,0,0,0},
+		{0,1,1,0,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,1,1,0,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* m */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{1,1,1,0,1,1,0},
+		{1,0,0,1,0,0,1},
+		{1,0,0,1,0,0,1},
+		{1,0,0,1,0,0,1},
+		{1,0,0,1,0,0,1},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* n */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,1,0,1,1,0,0},
+		{0,1,1,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* o */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,1,1,1,0,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,1,1,1,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* p */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,1,1,1,0,0,0},
+		{0,1,0,0,1,0,0},
+		{0,1,0,0,1,0,0},
+		{0,1,0,0,1,0,0},
+		{0,1,1,1,0,0,0},
+		{0,1,0,0,0,0,0}
+	},
+	{	/* q */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,1,1,1,0},
+		{0,0,1,0,0,1,0},
+		{0,0,1,0,0,1,0},
+		{0,0,1,0,0,1,0},
+		{0,0,0,1,1,1,0},
+		{0,0,0,0,0,1,0}
+	},
+	{	/* r */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,1,0,1,1,0},
+		{0,0,1,1,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* s */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,1,1,1,1,0},
+		{0,1,0,0,0,0,0},
+		{0,0,1,1,1,0,0},
+		{0,0,0,0,0,1,0},
+		{0,1,1,1,1,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* t */
+		{0,0,0,0,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,1,1,1,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,1,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* u */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,1,1,1,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* v */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,1,0,1,0,0},
+		{0,0,1,0,1,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* w */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{1,0,0,0,0,0,1},
+		{1,0,0,0,0,0,1},
+		{0,1,0,1,0,1,0},
+		{0,1,0,1,0,1,0},
+		{0,0,1,0,1,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* x */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,1,0},
+		{0,0,1,0,1,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,1,0,1,0,0},
+		{0,1,0,0,0,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* y */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,1,0,1,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,1,0,0,0,0}
+	},
+	{	/* z */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,1,1,1,1,1,0},
+		{0,0,0,0,1,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,1,0,0,0,0},
+		{0,1,1,1,1,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* M */
+		{0,0,0,0,0,0,0},
+		{1,0,0,0,0,0,1},
+		{1,1,0,0,0,1,1},
+		{1,0,1,0,1,0,1},
+		{1,0,0,1,0,0,1},
+		{1,0,0,0,0,0,1},
+		{1,0,0,0,0,0,1},
+		{1,0,0,0,0,0,1},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* ö (letter O) */
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,1,0},
+		{0,0,0,0,0,0,0},
+		{0,0,1,1,1,0,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,1,1,1,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* ü (letter U) */
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,1,0},
+		{0,0,0,0,0,0,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,1,0,0,0,1,0},
+		{0,0,1,1,1,1,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* ' ' (space) */
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,0,0,0,0}
+	},
+	{	/* ! */
+		{0,0,0,0,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,0,0,0,0},
+		{0,0,0,1,0,0,0},
+		{0,0,0,0,0,0,0}
+	}
+	
+};
+
+struct h_font {
+	char letter;
+	int pxfield;
+};
+
+struct h_display_char {
+	struct h_font * character;
+	XPoint offset;
+	int square_lenght, distance;
+};
+
diff --git a/hacks/clock.man b/hacks/clock.man
new file mode 100644
index 0000000..d9aa2fd
--- /dev/null
+++ b/hacks/clock.man
@@ -0,0 +1,69 @@
+.TH XScreenSaver 1 "" "X Version 11"
+.SH NAME
+clock - three clocks (analog/digital/binary)
+.SH SYNOPSIS
+.B clock
+[\-display \fIhost:display.screen\fP]
+[\-visual \fIvisual\fP]
+[\-window]
+[\-root]
+[\-delay \fInumber\fP]
+[\-mode \fImode\fP]
+[\-switchtime \fIswitchtime\fP]
+[\-scale \fIscale\fP]
+[\-fps]
+.SH DESCRIPTION
+This draws three different kinds of a clock: an analog one, a digital one,
+and one showing dots symbolizing the binary numbers of the time.
+.SH OPTIONS
+.TP 8
+.B \-visual \fIvisual\fP
+Specify which visual to use.  Legal values are the name of a visual class,
+or the id number (decimal or hex) of a specific visual.
+.TP 8
+.B \-window
+Draw on a newly-created window.  This is the default.
+.TP 8
+.B \-root
+Draw on the root window.
+.TP 8
+.B \-delay \fInumber\fP
+Per-frame delay, in microseconds.  Default: 10000 (0.02 seconds.).
+.TP 8
+.B \-mode \fImode\fP
+Choose the kind of clock. Values: \fIanalog\fP, \fIdigital\fP, \fIbinary\fP, \fIswitch\fP
+(changes the clock mode every \fIswitchtime\fP minutes)
+.TP 8
+.B \-switchtime \fIswitchtime\fP
+Sets the time (minutes) after which the clock mode is changed. \fI\-mode\fP has to be set to \fIswitch\fP.
+.TP 8
+.B \-scale \fIscale\fP
+Set the size of the clock. Values: 10\-100.
+.TP 8
+.B \-fps
+Display the current frame rate and CPU load.
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH SEE ALSO
+.BR X (1),
+.BR xscreensaver (1)
+.SH COPYRIGHT
+Copyright \(co 2017 by Sebastian Schauer <sebschauer@sebschauer.de>.  Based on
+examples from the hacks directory of xscreensaver,
+Copyright (c) 1997, 1998, 2002 Jamie Zawinski
+<jwz@jwz.org>
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation.
+.SH AUTHOR
+Sebastian Schauer
diff --git a/hacks/config/clock.xml b/hacks/config/clock.xml
new file mode 100644
index 0000000..df8c441
--- /dev/null
+++ b/hacks/config/clock.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<screensaver name="clock" _label="Clock">
+
+  <command arg="-root"/>
+
+  <number id="delay" type="slider" arg="-delay %"
+          _label="Frame rate" _low-label="Low" _high-label="High"
+          low="0" high="100000" default="10000"
+          convert="invert"/>
+
+  <number id="scale" type="slider" arg="-scale %"
+          _label="Size" _low-label="10%" _high-label="100%"
+          low="10" high="100" default="85"/>
+
+  <select id="mode">
+    <option id="analog"  _label="Analog"	arg-set="-mode analog"	/>
+    <option id="digital"  _label="Digital"            arg-set="-mode digital"/>
+    <option id="binary"  _label="Binary"            arg-set="-mode binary"/>
+    <option id="human"  _label="Human language"            arg-set="-mode human"/>
+    <option id="switch"  _label="Switch mode"            arg-set="-mode switch"/>
+  </select>
+  
+  <number id="switchtime" type="slider" arg="-switchtime %"
+          _label="Time before switch mode" _low-label="1 min" _high-label="1 h"
+          low="1" high="60" default="5"/>
+
+
+  <boolean id="showfps" _label="Show frame rate" arg-set="-fps"/>
+
+  <xscreensaver-updater />
+
+  <_description>
+Simple clock.
+
+Written by Sebastian Schauer; 2017.
+  </_description>
+</screensaver>
-- 
2.17.1

