--- gnome-core-1.4.0.1/applets/gen_util/clock.c	Mon Feb 12 23:05:45 2001
+++ gnome-core-1.4.0.1-colin/applets/gen_util/clock.c	Thu May 23 16:33:26 2002
@@ -68,6 +68,7 @@
 
 static void clock_properties (AppletWidget *applet, gpointer data);
 static void clock_about      (AppletWidget *applet, gpointer data);
+static void clock_calendar   (AppletWidget *applet, gpointer data);
 static void help_cb	     (AppletWidget *w, gpointer data);
 static void phelp_cb	     (GtkWidget *w, gint tab, gpointer data);
 
@@ -577,7 +578,6 @@
 			   GTK_SIGNAL_FUNC(applet_save_session),
 			   cd);
 
-
 	applet_widget_register_stock_callback(APPLET_WIDGET(applet),
 					      "properties",
 					      GNOME_STOCK_MENU_PROP,
@@ -620,6 +620,13 @@
 					      clock_about,
 					      NULL);
 
+	applet_widget_register_stock_callback(APPLET_WIDGET(applet),
+					      "calendar",
+					      GNOME_STOCK_MENU_PROP,
+					      _("Calendar..."),
+					      clock_calendar,
+					      cd);
+
 	gtk_selection_add_targets (GTK_WIDGET (applet), GDK_SELECTION_PRIMARY,
 				   targets, n_targets);
 
@@ -969,6 +976,7 @@
 		"Federico Mena <quartic@gimp.org>",
 		"Stuart Parmenter <pavlov@innerx.net>",
 		"George Lebl <jirka@5z.com>",
+		"Colin Leroy <colin@colino.net>",
 		NULL
 	};
 
@@ -979,7 +987,7 @@
 		return;
 	}
 	
-	about = gnome_about_new (_("Clock Applet"), "1.0",
+	about = gnome_about_new (_("Clock Applet"), "1.01",
 				 _("(c) 1998-2001 the Free Software Foundation"),
 				 authors,
 				 _("The clock applet gives your panel a lightweight and simple display of the date and time"),
@@ -990,4 +998,137 @@
 	gtk_signal_connect (GTK_OBJECT(about), "destroy",
 			    GTK_SIGNAL_FUNC(gtk_widget_destroyed), &about);
 	gtk_widget_show (about);
+}
+
+/* Zeller's Congruence returns the day of week 0-6 (Sun-Sat) 
+   on which a date occurs */
+int zeller(int m, int d, int y)
+{
+	if (m < 3) {
+		m += 12;
+		y -= 1;
+	}
+	return (d + 2*m + ((m + 1) * 3)/5 + y + y/4 - y/100 + y/400 + 1) % 7;
+}
+
+static GtkWidget   *calendar     = NULL;
+
+static void destroy_calendar()
+{
+	if (calendar)
+		gtk_widget_destroy(calendar);
+	calendar = NULL;
+}
+
+
+static void
+clock_calendar (AppletWidget *applet, gpointer data)
+{
+	GtkWidget *vbox = NULL;
+	GtkWidget *label = NULL;
+	GtkWidget *table = NULL;
+	GtkWidget *ok = NULL;
+	struct tm *tm;
+	time_t cur_time;
+	char month[256];
+	char * days[] = {"sun", "mon", "tue", "wed", "thu", "fri", "sat"};
+	int nb_day_per_mon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+	int nb_beg_spaces, nb_end_spaces, nb_lines;
+	int i;
+	int year;
+	ClockData * cd = (ClockData *)data;
+	cur_time = time(0L);
+	
+	if (cd->gmt_time)
+		tm = gmtime(&cur_time);
+	else
+		tm = localtime(&cur_time);
+		
+	year = tm->tm_year + 1900;
+	
+	if ( (year % 100 ? year % 4 : year % 400) == 0)
+		nb_day_per_mon[2] = 29;
+		
+	
+	nb_beg_spaces = zeller (tm->tm_mon + 1, 1, tm->tm_year + 1900);
+	nb_end_spaces = 0;
+	nb_lines = nb_beg_spaces+nb_day_per_mon[tm->tm_mon + 1];
+	while (nb_lines % 7 != 0) {
+		nb_lines ++;
+		nb_end_spaces ++;
+	}	
+	nb_lines = nb_lines/7;
+			
+	if (strftime(month, sizeof (month), ("%B"), tm) <= 0)
+		strcpy (month, "???");
+
+	if (calendar != NULL)
+	{
+		gtk_widget_show_now (calendar);
+		gdk_window_raise (calendar->window);
+		return;
+	}
+	calendar = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+	gtk_widget_realize (calendar);
+
+	vbox = gtk_vbox_new (FALSE, 0);
+
+	label = gtk_label_new (month);
+
+	gtk_box_pack_start (GTK_BOX(vbox), label, TRUE, TRUE, 5);
+
+	table = gtk_table_new (nb_lines+1, 7, FALSE);
+	
+	for (i = 0; i < 7; i++) {
+	 	GtkWidget *l;
+		l = gtk_label_new (days[i]);
+		gtk_table_attach ((GtkTable *)table, l, 
+				 i, i+1, 0, 1,
+				 GTK_EXPAND, GTK_EXPAND, 10, 0);
+		gtk_widget_show (l);
+	}  
+	
+	for (i = 0; i <= nb_beg_spaces+nb_day_per_mon[tm->tm_mon + 1]; i++) {
+		GtkWidget *l;
+		if(i < nb_beg_spaces)
+			l = gtk_label_new (" ");
+		else {
+			char buf[3];
+			sprintf (buf, "%d", i-nb_beg_spaces+1);
+			l = gtk_label_new (buf);
+			if (i-nb_beg_spaces+1 == tm->tm_mday)
+				gtk_label_set_pattern (GTK_LABEL(l),"__");
+		}
+		gtk_table_attach ((GtkTable *)table, l, 
+				 (i%7), 1+(i%7), 1+(i/7), 2+(i/7),
+				 GTK_EXPAND, GTK_EXPAND, 10, 0);
+		gtk_widget_show (l);
+	}
+	
+	gtk_box_pack_start (GTK_BOX(vbox), table, TRUE, TRUE, 5);
+
+	ok = gtk_button_new_with_label (_("Close"));
+	gtk_signal_connect_object (GTK_OBJECT(ok), "clicked",
+		                   GTK_SIGNAL_FUNC(destroy_calendar), 
+				   GTK_OBJECT(calendar));
+
+	gtk_box_pack_start (GTK_BOX(vbox), ok, TRUE, FALSE, 0);
+	GTK_WIDGET_SET_FLAGS (ok, GTK_CAN_DEFAULT);
+	gtk_widget_grab_default (ok);
+	gtk_widget_show (ok);
+
+	
+	gtk_signal_connect_object (GTK_OBJECT(calendar), "destroy",
+                                   GTK_SIGNAL_FUNC(destroy_calendar), 
+				   GTK_OBJECT(calendar));
+
+	gtk_widget_show (label);
+	gtk_widget_show (table);
+	gtk_widget_show (vbox);
+
+	gtk_window_set_title (GTK_WINDOW(calendar), "Calendar");
+	gtk_container_border_width (GTK_CONTAINER(calendar), 2);
+	gtk_container_add (GTK_CONTAINER(calendar), vbox);
+	gtk_widget_show (calendar);
+	
 }
