From b49e5c471b7cecdb650e98f757d42c2773f9c2d7 Mon Sep 17 00:00:00 2001
From: Peter Gerwinski <peter.gerwinski@hs-bochum.de>
Date: Thu, 17 Dec 2020 17:00:47 +0100
Subject: [PATCH] Beispiele 17.12.2020

---
 20201217/Makefile        |   1 +
 20201217/Makefile-1      |   8 ++++
 20201217/Makefile-2      |  16 ++++++++
 20201217/Makefile-3      |  13 ++++++
 20201217/answer.c        |   6 +++
 20201217/answer.h        |   1 +
 20201217/gtk-14.c        |  60 +++++++++++++++++++++++++++
 20201217/gtk-15.c        |  60 +++++++++++++++++++++++++++
 20201217/gtk-16.c        |   6 +--
 20201217/gtk-17.c        |  65 +++++++++++++++++++++++++++++
 20201217/gtk-18.c        |  65 +++++++++++++++++++++++++++++
 20201217/gtk-19.c        |  65 +++++++++++++++++++++++++++++
 20201217/gtk-20.c        |  65 +++++++++++++++++++++++++++++
 20201217/gtk-21.c        |  67 ++++++++++++++++++++++++++++++
 20201217/gtk-22.c        |  67 ++++++++++++++++++++++++++++++
 20201217/gtk-23.c        |  67 ++++++++++++++++++++++++++++++
 20201217/hp-20201217.pdf | Bin 168561 -> 168551 bytes
 20201217/hp-20201217.tex |   2 +-
 20201217/make-1.txt      |  27 ++++++++++++
 20201217/make-10.txt     |  30 ++++++++++++++
 20201217/make-11.txt     |  32 +++++++++++++++
 20201217/make-2.txt      |  10 +++++
 20201217/make-3.txt      |  25 ++++++++++++
 20201217/make-4.txt      |  24 +++++++++++
 20201217/make-5.txt      |  25 ++++++++++++
 20201217/make-6.txt      |  14 +++++++
 20201217/make-7.txt      |  40 ++++++++++++++++++
 20201217/make-8.txt      |   5 +++
 20201217/make-9.txt      |  13 ++++++
 20201217/pendulum-0.c    |  69 +++++++++++++++++++++++++++++++
 20201217/pendulum-1.c    |  69 +++++++++++++++++++++++++++++++
 20201217/pendulum-2.c    |  69 +++++++++++++++++++++++++++++++
 20201217/pendulum-3.c    |  86 +++++++++++++++++++++++++++++++++++++++
 20201217/pendulum-4.c    |  86 +++++++++++++++++++++++++++++++++++++++
 20201217/philosophy.c    |   8 ++++
 35 files changed, 1262 insertions(+), 4 deletions(-)
 create mode 120000 20201217/Makefile
 create mode 100644 20201217/Makefile-1
 create mode 100644 20201217/Makefile-2
 create mode 100644 20201217/Makefile-3
 create mode 100644 20201217/answer.c
 create mode 100644 20201217/answer.h
 create mode 100644 20201217/gtk-14.c
 create mode 100644 20201217/gtk-15.c
 create mode 100644 20201217/gtk-17.c
 create mode 100644 20201217/gtk-18.c
 create mode 100644 20201217/gtk-19.c
 create mode 100644 20201217/gtk-20.c
 create mode 100644 20201217/gtk-21.c
 create mode 100644 20201217/gtk-22.c
 create mode 100644 20201217/gtk-23.c
 create mode 100644 20201217/make-1.txt
 create mode 100644 20201217/make-10.txt
 create mode 100644 20201217/make-11.txt
 create mode 100644 20201217/make-2.txt
 create mode 100644 20201217/make-3.txt
 create mode 100644 20201217/make-4.txt
 create mode 100644 20201217/make-5.txt
 create mode 100644 20201217/make-6.txt
 create mode 100644 20201217/make-7.txt
 create mode 100644 20201217/make-8.txt
 create mode 100644 20201217/make-9.txt
 create mode 100644 20201217/pendulum-0.c
 create mode 100644 20201217/pendulum-1.c
 create mode 100644 20201217/pendulum-2.c
 create mode 100644 20201217/pendulum-3.c
 create mode 100644 20201217/pendulum-4.c
 create mode 100644 20201217/philosophy.c

diff --git a/20201217/Makefile b/20201217/Makefile
new file mode 120000
index 0000000..d5f315b
--- /dev/null
+++ b/20201217/Makefile
@@ -0,0 +1 @@
+Makefile-3
\ No newline at end of file
diff --git a/20201217/Makefile-1 b/20201217/Makefile-1
new file mode 100644
index 0000000..bfc1b10
--- /dev/null
+++ b/20201217/Makefile-1
@@ -0,0 +1,8 @@
+philosophy: philosophy.o answer.o
+	gcc philosophy.o answer.o -o philosophy
+
+answer.o: answer.c answer.h
+	gcc -Wall -O answer.c -c
+
+philosophy.o: philosophy.c answer.h
+	gcc -Wall -O philosophy.c -c
diff --git a/20201217/Makefile-2 b/20201217/Makefile-2
new file mode 100644
index 0000000..60aab7c
--- /dev/null
+++ b/20201217/Makefile-2
@@ -0,0 +1,16 @@
+TARGET = philosophy
+OBJECTS = philosophy.o answer.o
+HEADERS = answer.h
+CFLAGS = -Wall -O
+
+$(TARGET): $(OBJECTS)
+	gcc $(OBJECTS) -o $(TARGET)
+
+answer.o: answer.c $(HEADERS)
+	gcc $(CFLAGS) answer.c -c
+
+philosophy.o: philosophy.c $(HEADERS)
+	gcc $(CFLAGS) philosophy.c -c
+
+clean:
+	rm -f $(OBJECTS) $(TARGET)
diff --git a/20201217/Makefile-3 b/20201217/Makefile-3
new file mode 100644
index 0000000..0ac355b
--- /dev/null
+++ b/20201217/Makefile-3
@@ -0,0 +1,13 @@
+TARGET = philosophy
+OBJECTS = philosophy.o answer.o
+HEADERS = answer.h
+CFLAGS = -Wall -O
+
+$(TARGET): $(OBJECTS)
+	gcc $(OBJECTS) -o $(TARGET)
+
+%.o: %.c $(HEADERS)
+	gcc $(CFLAGS) $< -c
+
+clean:
+	rm -f $(OBJECTS) $(TARGET)
diff --git a/20201217/answer.c b/20201217/answer.c
new file mode 100644
index 0000000..65a1dc2
--- /dev/null
+++ b/20201217/answer.c
@@ -0,0 +1,6 @@
+#include "answer.h"
+
+int answer (void)
+{
+  return 23;
+}
diff --git a/20201217/answer.h b/20201217/answer.h
new file mode 100644
index 0000000..b6777e8
--- /dev/null
+++ b/20201217/answer.h
@@ -0,0 +1 @@
+extern int answer (void);
diff --git a/20201217/gtk-14.c b/20201217/gtk-14.c
new file mode 100644
index 0000000..75956a6
--- /dev/null
+++ b/20201217/gtk-14.c
@@ -0,0 +1,60 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+
+double x = 5;
+double y = 95;
+double vx = 50.0;
+double vy = 50.0;
+double dt = 0.05;
+double g = 9.81;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_arc (c, x, HEIGHT - y, 5, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += vx * dt;
+  y += vy * dt;
+  vx += 0.0 * dt;
+  vy += (-g) * dt;
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (50, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  GtkWidget *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+
+  g_timeout_add (5000, (GSourceFunc) timer, drawing_area);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/gtk-15.c b/20201217/gtk-15.c
new file mode 100644
index 0000000..abedb4d
--- /dev/null
+++ b/20201217/gtk-15.c
@@ -0,0 +1,60 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+
+double x = 5;
+double y = 95;
+double vx = 50.0;
+double vy = 50.0;
+double dt = 0.2;
+double g = 9.81;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_arc (c, x, HEIGHT - y, 5, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += vx * dt;
+  y += vy * dt;
+  vx += 0.0 * dt;
+  vy += (-g) * dt;
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (200, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  GtkWidget *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+
+  g_timeout_add (1000, (GSourceFunc) timer, drawing_area);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/gtk-16.c b/20201217/gtk-16.c
index 0901dd7..ccd1697 100644
--- a/20201217/gtk-16.c
+++ b/20201217/gtk-16.c
@@ -8,7 +8,7 @@ double x = 5;
 double y = 95;
 double vx = 50.0;
 double vy = 70.0;
-double dt = 0.05;
+double dt = 0.2;
 double g = 9.81;
 
 gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
@@ -29,7 +29,7 @@ gboolean timer (GtkWidget *widget)
   if (x + RADIUS >= WIDTH)
     vx = -vx;
   gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
-  g_timeout_add (50, (GSourceFunc) timer, widget);
+  g_timeout_add (200, (GSourceFunc) timer, widget);
   return FALSE;
 }
 
@@ -52,7 +52,7 @@ int main (int argc, char **argv)
   g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
   gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
 
-  g_timeout_add (50, (GSourceFunc) timer, drawing_area);
+  g_timeout_add (1000, (GSourceFunc) timer, drawing_area);
 
   gtk_widget_show (drawing_area);
   gtk_widget_show (button);
diff --git a/20201217/gtk-17.c b/20201217/gtk-17.c
new file mode 100644
index 0000000..21786c7
--- /dev/null
+++ b/20201217/gtk-17.c
@@ -0,0 +1,65 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+#define RADIUS 5
+
+double x = 5;
+double y = 95;
+double vx = 50.0;
+double vy = 70.0;
+double dt = 0.2;
+double g = 9.81;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_arc (c, x, HEIGHT - y, RADIUS, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += vx * dt;
+  y += vy * dt;
+  vx += 0.0 * dt;
+  vy += (-g) * dt;
+  if (x + RADIUS >= WIDTH)
+    vx = -vx;
+  if (y + RADIUS >= HEIGHT)
+    vy = -vy;
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (200, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  GtkWidget *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+
+  g_timeout_add (1000, (GSourceFunc) timer, drawing_area);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/gtk-18.c b/20201217/gtk-18.c
new file mode 100644
index 0000000..84f6081
--- /dev/null
+++ b/20201217/gtk-18.c
@@ -0,0 +1,65 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+#define RADIUS 5
+
+double x = 5;
+double y = 95;
+double vx = 50.0;
+double vy = 70.0;
+double dt = 0.2;
+double g = 9.81;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_arc (c, x, HEIGHT - y, RADIUS, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += vx * dt;
+  y += vy * dt;
+  vx += 0.0 * dt;
+  vy += (-g) * dt;
+  if (x + RADIUS >= WIDTH)
+    vx = -vx;
+  if (y + RADIUS <= 0)
+    vy = -vy;
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (200, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  GtkWidget *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+
+  g_timeout_add (1000, (GSourceFunc) timer, drawing_area);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/gtk-19.c b/20201217/gtk-19.c
new file mode 100644
index 0000000..488ecb2
--- /dev/null
+++ b/20201217/gtk-19.c
@@ -0,0 +1,65 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+#define RADIUS 5
+
+double x = 5;
+double y = 95;
+double vx = 50.0;
+double vy = 70.0;
+double dt = 0.2;
+double g = 9.81;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_arc (c, x, HEIGHT - y, RADIUS, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += vx * dt;
+  y += vy * dt;
+  vx += 0.0 * dt;
+  vy += (-g) * dt;
+  if (x + RADIUS >= WIDTH)
+    vx = -vx;
+  if (y - RADIUS <= 0)
+    vy = -vy;
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (200, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  GtkWidget *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+
+  g_timeout_add (1000, (GSourceFunc) timer, drawing_area);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/gtk-20.c b/20201217/gtk-20.c
new file mode 100644
index 0000000..cf4c99a
--- /dev/null
+++ b/20201217/gtk-20.c
@@ -0,0 +1,65 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+#define RADIUS 5
+
+double x = 5;
+double y = 95;
+double vx = 50.0;
+double vy = 70.0;
+double dt = 0.1;
+double g = 9.81;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_arc (c, x, HEIGHT - y, RADIUS, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += vx * dt;
+  y += vy * dt;
+  vx += 0.0 * dt;
+  vy += (-g) * dt;
+  if (x + RADIUS >= WIDTH)
+    vx = -vx;
+  if (y - RADIUS <= 0)
+    vy = -vy;
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (100, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  GtkWidget *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+
+  g_timeout_add (1000, (GSourceFunc) timer, drawing_area);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/gtk-21.c b/20201217/gtk-21.c
new file mode 100644
index 0000000..e522741
--- /dev/null
+++ b/20201217/gtk-21.c
@@ -0,0 +1,67 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+#define RADIUS 5
+
+double x = 5;
+double y = 95;
+double vx = 50.0;
+double vy = 70.0;
+double dt = 0.1;
+double g = 9.81;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_arc (c, x, HEIGHT - y, RADIUS, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += vx * dt;
+  y += vy * dt;
+  vx += 0.0 * dt;
+  vy += (-g) * dt;
+  if (x + RADIUS >= WIDTH)
+    vx = -vx;
+  if (x - RADIUS <= 0)
+    vx = -vx;
+  if (y - RADIUS <= 0)
+    vy = -vy;
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (100, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  GtkWidget *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+
+  g_timeout_add (1000, (GSourceFunc) timer, drawing_area);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/gtk-22.c b/20201217/gtk-22.c
new file mode 100644
index 0000000..5a141e5
--- /dev/null
+++ b/20201217/gtk-22.c
@@ -0,0 +1,67 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+#define RADIUS 5
+
+double x = 5;
+double y = 95;
+double vx = 50.0;
+double vy = 70.0;
+double dt = 0.1;
+double g = 9.81;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_arc (c, x, HEIGHT - y, RADIUS, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += vx * dt;
+  y += vy * dt;
+  vx += 0.0 * dt;
+  vy += (-g) * dt;
+  if (x + RADIUS >= WIDTH)
+    vx = -0.9 * vx;
+  if (x - RADIUS <= 0)
+    vx = -0.9 * vx;
+  if (y - RADIUS <= 0)
+    vy = -0.9 * vy;
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (100, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  GtkWidget *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+
+  g_timeout_add (1000, (GSourceFunc) timer, drawing_area);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/gtk-23.c b/20201217/gtk-23.c
new file mode 100644
index 0000000..0a92ba4
--- /dev/null
+++ b/20201217/gtk-23.c
@@ -0,0 +1,67 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+#define RADIUS 5
+
+double x = 5;
+double y = 95;
+double vx = 50.0;
+double vy = 70.0;
+double dt = 0.1;
+double g = 9.81;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_arc (c, x, HEIGHT - y, RADIUS, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += vx * dt;
+  y += vy * dt;
+  vx += 0.0 * dt;
+  vy += (-g) * dt;
+  if (x + RADIUS >= WIDTH && vx > 0)
+    vx = -0.9 * vx;
+  if (x - RADIUS <= 0 && vx < 0)
+    vx = -0.9 * vx;
+  if (y - RADIUS <= 0 && vy < 0)
+    vy = -0.9 * vy;
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (100, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+
+  GtkWidget *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (vbox), button);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+
+  g_timeout_add (1000, (GSourceFunc) timer, drawing_area);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/hp-20201217.pdf b/20201217/hp-20201217.pdf
index 173a2277de52dffc99c4e949574ebe3797c9d641..440d46e10981db443b7be234834f08ba026b94fc 100644
GIT binary patch
delta 2743
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

delta 2746
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

diff --git a/20201217/hp-20201217.tex b/20201217/hp-20201217.tex
index be44ed7..b64061a 100644
--- a/20201217/hp-20201217.tex
+++ b/20201217/hp-20201217.tex
@@ -208,7 +208,7 @@
       \begin{onlyenv}<3->
         \begin{lstlisting}[style=terminal,gobble=10]
           $ ¡gcc -Wall -O hello-gtk.c $(pkg-config --cflags --libs
-                 gtk+-3.0 -o hello-gtk¿
+                 gtk+-3.0) -o hello-gtk¿
         \end{lstlisting}
       \end{onlyenv}
       \begin{onlyenv}<3>
diff --git a/20201217/make-1.txt b/20201217/make-1.txt
new file mode 100644
index 0000000..a04a551
--- /dev/null
+++ b/20201217/make-1.txt
@@ -0,0 +1,27 @@
+cassini/home/peter/bo/2020ws/hp/20201217> cat philosophy.c
+#include <stdio.h>
+#include "answer.h"
+
+int main (void)
+{
+  printf ("The answer is %d.\n", answer ());
+  return 0;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> cat answer.h
+extern int answer (void);
+cassini/home/peter/bo/2020ws/hp/20201217> cat answer.c
+#include "answer.h"
+
+int answer (void)
+{
+  return 42;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c -o philosophy
+/usr/bin/ld: /tmp/ccCbFdy5.o: in function `main':
+philosophy.c:(.text+0x5): undefined reference to `answer'
+collect2: error: ld returned 1 exit status
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O answer.c -c
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 42.
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-10.txt b/20201217/make-10.txt
new file mode 100644
index 0000000..5a731bb
--- /dev/null
+++ b/20201217/make-10.txt
@@ -0,0 +1,30 @@
+TARGET = philosophy
+OBJECTS = philosophy.o answer.o
+HEADERS = answer.h
+CFLAGS = -Wall -O
+
+$(TARGET): $(OBJECTS)
+        gcc $(OBJECTS) -o $(TARGET)
+
+answer.o: answer.c $(HEADERS)
+        gcc $(CFLAGS) answer.c -c
+
+philosophy.o: philosophy.c $(HEADERS)
+        gcc $(CFLAGS) philosophy.c -c
+
+clean:
+        rm -f $(OBJECTS) $(TARGET)
+cassini/home/peter/bo/2020ws/hp/20201217> make -f Makefile-2
+make: „philosophy“ ist bereits aktuell.
+cassini/home/peter/bo/2020ws/hp/20201217> make answer.o -f Makefile-2
+make: „answer.o“ ist bereits aktuell.
+cassini/home/peter/bo/2020ws/hp/20201217> make clean -f Makefile-2
+rm -f philosophy.o answer.o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> make answer.o -f Makefile-2
+gcc -Wall -O answer.c -c
+cassini/home/peter/bo/2020ws/hp/20201217> make -f Makefile-2
+gcc -Wall -O philosophy.c -c
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 23.
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-11.txt b/20201217/make-11.txt
new file mode 100644
index 0000000..972907b
--- /dev/null
+++ b/20201217/make-11.txt
@@ -0,0 +1,32 @@
+cassini/home/peter/bo/2020ws/hp/20201217> cat Makefile-3
+TARGET = philosophy
+OBJECTS = philosophy.o answer.o
+HEADERS = answer.h
+CFLAGS = -Wall -O
+
+$(TARGET): $(OBJECTS)
+        gcc $(OBJECTS) -o $(TARGET)
+
+%.o: %.c $(HEADERS)
+        gcc $(CFLAGS) $< -c
+
+clean:
+        rm -f $(OBJECTS) $(TARGET)
+cassini/home/peter/bo/2020ws/hp/20201217> make clean
+make: *** Keine Regel, um „clean“ zu erstellen.  Schluss.
+cassini/home/peter/bo/2020ws/hp/20201217> make
+make: *** Es wurden keine Ziele angegeben und keine „make“-Steuerdatei gefunden.  Schluss.
+cassini/home/peter/bo/2020ws/hp/20201217> make -f Makefile-3 clean
+rm -f philosophy.o answer.o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> make -f Makefile-3
+gcc -Wall -O philosophy.c -c
+gcc -Wall -O answer.c -c
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ln -s Makefile-3 Makefile
+cassini/home/peter/bo/2020ws/hp/20201217> make clean
+rm -f philosophy.o answer.o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> make
+gcc -Wall -O philosophy.c -c
+gcc -Wall -O answer.c -c
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-2.txt b/20201217/make-2.txt
new file mode 100644
index 0000000..4143a77
--- /dev/null
+++ b/20201217/make-2.txt
@@ -0,0 +1,10 @@
+#include "answer.h"
+
+int answer (void)
+{
+  return 137;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 42.
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-3.txt b/20201217/make-3.txt
new file mode 100644
index 0000000..ac0a49d
--- /dev/null
+++ b/20201217/make-3.txt
@@ -0,0 +1,25 @@
+#include "answer.h"
+
+int answer (void)
+{
+  return 137;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 42.
+cassini/home/peter/bo/2020ws/hp/20201217> cat >> make-2.txt
+#include "answer.h"
+
+int answer (void)
+{
+  return 137;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 42.
+cassini/home/peter/bo/2020ws/hp/20201217>
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O answer.c -c
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 137.
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-4.txt b/20201217/make-4.txt
new file mode 100644
index 0000000..d07bb9f
--- /dev/null
+++ b/20201217/make-4.txt
@@ -0,0 +1,24 @@
+cassini/home/peter/bo/2020ws/hp/20201217> cat philosophy.c
+#include <stdio.h>
+#include "answer.h"
+
+int main (void)
+{
+  printf ("The answer is %d.\n", answer ());
+  return 0;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> cat answer.h
+extern int answer (void);
+cassini/home/peter/bo/2020ws/hp/20201217> cat answer.c
+#include "answer.h"
+
+int answer (void)
+{
+  return 137;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c -c
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O answer.c -c
+cassini/home/peter/bo/2020ws/hp/20201217> gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 137.
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-5.txt b/20201217/make-5.txt
new file mode 100644
index 0000000..7033a7f
--- /dev/null
+++ b/20201217/make-5.txt
@@ -0,0 +1,25 @@
+cassini/home/peter/bo/2020ws/hp/20201217> cat philosophy.c
+#include <stdio.h>
+#include "answer.h"
+
+int main (void)
+{
+  printf ("The answer is %d.\n", answer ());
+  return 0;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> cat answer.h
+extern int answer (void);
+cassini/home/peter/bo/2020ws/hp/20201217> cat answer.c
+#include "answer.h"
+
+int answer (void)
+{
+  return 137;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> for x in philsophy.c answer.c; do gcc -Wall -O $x -c; done
+gcc: error: philsophy.c: Datei oder Verzeichnis nicht gefunden
+gcc: fatal error: no input files
+compilation terminated.
+cassini/home/peter/bo/2020ws/hp/20201217> for x in philosophy.c answer.c; do gcc -Wall -O $x -c; done
+cassini/home/peter/bo/2020ws/hp/20201217> gcc -Wall -O philosophy.c answer.c -c
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-6.txt b/20201217/make-6.txt
new file mode 100644
index 0000000..8b369c1
--- /dev/null
+++ b/20201217/make-6.txt
@@ -0,0 +1,14 @@
+cassini/home/peter/bo/2020ws/hp/20201217> cat Makefile
+philosophy: philosophy.o answer.o
+        gcc philosophy.o answer.o -o philosophy
+
+answer.o: answer.c answer.h
+        gcc -Wall -O answer.c -c
+
+philosophy.o: philosophy.c answer.h
+        gcc -Wall -O philosophy.c -c
+cassini/home/peter/bo/2020ws/hp/20201217> make
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 137.
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-7.txt b/20201217/make-7.txt
new file mode 100644
index 0000000..2237b1b
--- /dev/null
+++ b/20201217/make-7.txt
@@ -0,0 +1,40 @@
+cassini/home/peter/bo/2020ws/hp/20201217> cat Makefile
+philosophy: philosophy.o answer.o
+        gcc philosophy.o answer.o -o philosophy
+
+answer.o: answer.c answer.h
+        gcc -Wall -O answer.c -c
+
+philosophy.o: philosophy.c answer.h
+        gcc -Wall -O philosophy.c -c
+cassini/home/peter/bo/2020ws/hp/20201217> make
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 137.
+cassini/home/peter/bo/2020ws/hp/20201217> cat >> make-6.txt
+cassini/home/peter/bo/2020ws/hp/20201217> cat Makefile
+philosophy: philosophy.o answer.o
+        gcc philosophy.o answer.o -o philosophy
+
+answer.o: answer.c answer.h
+        gcc -Wall -O answer.c -c
+
+philosophy.o: philosophy.c answer.h
+        gcc -Wall -O philosophy.c -c
+cassini/home/peter/bo/2020ws/hp/20201217> make
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> ./philosophy
+The answer is 137.
+cassini/home/peter/bo/2020ws/hp/20201217>
+cassini/home/peter/bo/2020ws/hp/20201217> sed -i answer.c -e 's/137/23/'
+cassini/home/peter/bo/2020ws/hp/20201217> cat answer.c
+#include "answer.h"
+
+int answer (void)
+{
+  return 23;
+}
+cassini/home/peter/bo/2020ws/hp/20201217> make
+gcc -Wall -O answer.c -c
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-8.txt b/20201217/make-8.txt
new file mode 100644
index 0000000..f2d502f
--- /dev/null
+++ b/20201217/make-8.txt
@@ -0,0 +1,5 @@
+cassini/home/peter/bo/2020ws/hp/20201217> touch philosophy.c
+cassini/home/peter/bo/2020ws/hp/20201217> make
+gcc -Wall -O philosophy.c -c
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/make-9.txt b/20201217/make-9.txt
new file mode 100644
index 0000000..13617e5
--- /dev/null
+++ b/20201217/make-9.txt
@@ -0,0 +1,13 @@
+cassini/home/peter/bo/2020ws/hp/20201217> touch philosophy.c
+cassini/home/peter/bo/2020ws/hp/20201217> make
+gcc -Wall -O philosophy.c -c
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217> cat >> make-8.txt
+cassini/home/peter/bo/2020ws/hp/20201217> touch philosophy.c
+cassini/home/peter/bo/2020ws/hp/20201217> make
+gcc -Wall -O philosophy.c -c
+gcc philosophy.o answer.o -o philosophy
+cassini/home/peter/bo/2020ws/hp/20201217>
+cassini/home/peter/bo/2020ws/hp/20201217> make -f Makefile-1
+make: „philosophy“ ist bereits aktuell.
+cassini/home/peter/bo/2020ws/hp/20201217>
diff --git a/20201217/pendulum-0.c b/20201217/pendulum-0.c
new file mode 100644
index 0000000..6faebdc
--- /dev/null
+++ b/20201217/pendulum-0.c
@@ -0,0 +1,69 @@
+#include <gtk/gtk.h>
+#include <math.h>
+
+int width = 320;
+int height = 240;
+int gap = height / 20;
+int r = gap;
+double visual_length = height - 2 * gap - r;
+
+double phi0 = -0.5;
+double omega0 = 0.0;
+double t0 = 0.0;
+double g = 9.81;
+double l = 1.0;
+double dt = 0.02;
+
+double t = t0;
+double phi = phi0;
+double omega = omega0;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+
+  int x = width / 2 + visual_length * sin (phi);
+  int y = gap + visual_length * cos (phi);
+
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_move_to (c, width / 2, gap);
+  cairo_line_to (c, x, y);
+  cairo_stroke (c);
+  cairo_arc (c, x, y, r, 0, 2 * G_PI);
+  cairo_fill (c);
+
+  return FALSE;  /* TRUE to stop other handlers from being invoked for the event.
+                    FALSE to propagate the event further. */
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  t += dt;
+  phi += omega * dt;
+  omega += - dt * g / l * sin (phi);
+
+  gtk_widget_queue_draw_area (widget, 0, 0, width, height);
+  g_timeout_add (50, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_show (window);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_widget_show (drawing_area);
+  gtk_container_add (GTK_CONTAINER (window), drawing_area);
+  gtk_widget_set_size_request (drawing_area, width, height);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+
+  g_timeout_add (50, (GSourceFunc) timer, drawing_area);
+
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/pendulum-1.c b/20201217/pendulum-1.c
new file mode 100644
index 0000000..44f4c4f
--- /dev/null
+++ b/20201217/pendulum-1.c
@@ -0,0 +1,69 @@
+#include <gtk/gtk.h>
+#include <math.h>
+
+#define WIDTH 320
+#define HEIGHT 240
+#define GAP (HEIGHT / 20)
+#define r GAP
+#define visual_length (HEIGHT - 2 * GAP - r)
+
+#define phi0 (-0.5)
+#define omega0 0.0
+#define t0 0.0
+#define g 9.81
+#define l 1.0
+#define dt 0.02
+
+double t = t0;
+double phi = phi0;
+double omega = omega0;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 1.0 };
+
+  int x = WIDTH / 2 + visual_length * sin (phi);
+  int y = GAP + visual_length * cos (phi);
+
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_move_to (c, WIDTH / 2, 10);
+  cairo_line_to (c, x, y);
+  cairo_stroke (c);
+  cairo_arc (c, x, y, r, 0, 2 * G_PI);
+  cairo_fill (c);
+
+  return FALSE;  /* TRUE to stop other handlers from being invoked for the event.
+                    FALSE to propagate the event further. */
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  t += dt;
+  phi += omega * dt;
+  omega += - dt * g / l * sin (phi);
+
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (50, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_show (window);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_widget_show (drawing_area);
+  gtk_container_add (GTK_CONTAINER (window), drawing_area);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+
+  g_timeout_add (50, (GSourceFunc) timer, drawing_area);
+
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/pendulum-2.c b/20201217/pendulum-2.c
new file mode 100644
index 0000000..4fbad9a
--- /dev/null
+++ b/20201217/pendulum-2.c
@@ -0,0 +1,69 @@
+#include <gtk/gtk.h>
+#include <math.h>
+
+#define WIDTH 320
+#define HEIGHT 240
+#define GAP (HEIGHT / 20)
+#define r GAP
+#define visual_length (HEIGHT - 2 * GAP - r)
+
+#define phi0 (-0.5)
+#define omega0 0.0
+#define t0 0.0
+#define g 9.81
+#define l 1.0
+#define dt 0.02
+
+double t = t0;
+double phi = phi0;
+double omega = omega0;
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA orange = { 1.0, 0.5, 0.0, 1.0 };
+
+  int x = WIDTH / 2 + visual_length * sin (phi);
+  int y = GAP + visual_length * cos (phi);
+
+  gdk_cairo_set_source_rgba (c, &orange);
+  cairo_move_to (c, WIDTH / 2, 10);
+  cairo_line_to (c, x, y);
+  cairo_stroke (c);
+  cairo_arc (c, x, y, r, 0, 2 * G_PI);
+  cairo_fill (c);
+
+  return FALSE;  /* TRUE to stop other handlers from being invoked for the event.
+                    FALSE to propagate the event further. */
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  t += dt;
+  phi += omega * dt;
+  omega += - dt * g / l * phi;
+
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (50, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_show (window);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_widget_show (drawing_area);
+  gtk_container_add (GTK_CONTAINER (window), drawing_area);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+
+  g_timeout_add (50, (GSourceFunc) timer, drawing_area);
+
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/pendulum-3.c b/20201217/pendulum-3.c
new file mode 100644
index 0000000..35b0b67
--- /dev/null
+++ b/20201217/pendulum-3.c
@@ -0,0 +1,86 @@
+#include <gtk/gtk.h>
+#include <math.h>
+
+#define WIDTH 320
+#define HEIGHT 240
+#define GAP (HEIGHT / 20)
+#define r GAP
+#define visual_length (HEIGHT - 2 * GAP - r)
+
+#define phi0 (-0.5)
+#define omega0 0.0
+#define t0 0.0
+#define g 9.81
+#define l 1.0
+#define dt 0.02
+
+double t = t0;
+double phi_with_sin = phi0;
+double omega_with_sin= omega0;
+double phi_without_sin = phi0;
+double omega_without_sin= omega0;
+
+void draw_pendulum (cairo_t *c, double phi, GdkRGBA *colour)
+{
+  int x = WIDTH / 2 + visual_length * sin (phi);
+  int y = GAP + visual_length * cos (phi);
+
+  gdk_cairo_set_source_rgba (c, colour);
+  cairo_move_to (c, WIDTH / 2, 10);
+  cairo_line_to (c, x, y);
+  cairo_stroke (c);
+  cairo_arc (c, x, y, r, 0, 2 * G_PI);
+  cairo_fill (c);
+}
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue   = { 0.0, 0.5, 1.0, 1.0 };
+  GdkRGBA orange = { 1.0, 0.5, 0.0, 1.0 };
+  GdkRGBA green  = { 0.0, 0.5, 0.0, 1.0 };
+
+  double A = phi0;
+  double B = 0.5 * M_PI;  /* 90° */
+  double phi_analytic = A * sin (sqrt (g / l) * t + B);
+
+  draw_pendulum (c, phi_with_sin, &blue);
+  draw_pendulum (c, phi_without_sin, &orange);
+  draw_pendulum (c, phi_analytic, &green);
+
+  return FALSE;  /* TRUE to stop other handlers from being invoked for the event.
+                    FALSE to propagate the event further. */
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  t += dt;
+  phi_with_sin += omega_with_sin * dt;
+  omega_with_sin += - dt * g / l * sin (phi_with_sin);
+  phi_without_sin += omega_without_sin * dt;
+  omega_without_sin += - dt * g / l * phi_without_sin;
+
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (50, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_show (window);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_widget_show (drawing_area);
+  gtk_container_add (GTK_CONTAINER (window), drawing_area);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+
+  g_timeout_add (50, (GSourceFunc) timer, drawing_area);
+
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/pendulum-4.c b/20201217/pendulum-4.c
new file mode 100644
index 0000000..1a08e32
--- /dev/null
+++ b/20201217/pendulum-4.c
@@ -0,0 +1,86 @@
+#include <gtk/gtk.h>
+#include <math.h>
+
+#define WIDTH 320
+#define HEIGHT 240
+#define GAP (HEIGHT / 20)
+#define r GAP
+#define visual_length (HEIGHT - 2 * GAP - r)
+
+#define phi0 (-5.0 / 180.0 * M_PI)
+#define omega0 0.0
+#define t0 0.0
+#define g 9.81
+#define l 1.0
+#define dt 0.02
+
+double t = t0;
+double phi_with_sin = phi0;
+double omega_with_sin= omega0;
+double phi_without_sin = phi0;
+double omega_without_sin= omega0;
+
+void draw_pendulum (cairo_t *c, double phi, GdkRGBA *colour)
+{
+  int x = WIDTH / 2 + visual_length * sin (phi);
+  int y = GAP + visual_length * cos (phi);
+
+  gdk_cairo_set_source_rgba (c, colour);
+  cairo_move_to (c, WIDTH / 2, 10);
+  cairo_line_to (c, x, y);
+  cairo_stroke (c);
+  cairo_arc (c, x, y, r, 0, 2 * G_PI);
+  cairo_fill (c);
+}
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA blue   = { 0.0, 0.5, 1.0, 1.0 };
+  GdkRGBA orange = { 1.0, 0.5, 0.0, 1.0 };
+  GdkRGBA green  = { 0.0, 0.5, 0.0, 1.0 };
+
+  double A = phi0;
+  double B = 0.5 * M_PI;  /* 90° */
+  double phi_analytic = A * sin (sqrt (g / l) * t + B);
+
+  draw_pendulum (c, phi_with_sin, &blue);
+  draw_pendulum (c, phi_without_sin, &orange);
+  draw_pendulum (c, phi_analytic, &green);
+
+  return FALSE;  /* TRUE to stop other handlers from being invoked for the event.
+                    FALSE to propagate the event further. */
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  t += dt;
+  phi_with_sin += omega_with_sin * dt;
+  omega_with_sin += - dt * g / l * sin (phi_with_sin);
+  phi_without_sin += omega_without_sin * dt;
+  omega_without_sin += - dt * g / l * phi_without_sin;
+
+  gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+  g_timeout_add (50, (GSourceFunc) timer, widget);
+  return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+
+  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_show (window);
+  gtk_window_set_title (GTK_WINDOW (window), "Hello");
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+  GtkWidget *drawing_area = gtk_drawing_area_new ();
+  gtk_widget_show (drawing_area);
+  gtk_container_add (GTK_CONTAINER (window), drawing_area);
+  gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
+  g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+
+  g_timeout_add (50, (GSourceFunc) timer, drawing_area);
+
+  gtk_main ();
+  return 0;
+}
diff --git a/20201217/philosophy.c b/20201217/philosophy.c
new file mode 100644
index 0000000..e9f508a
--- /dev/null
+++ b/20201217/philosophy.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include "answer.h"
+
+int main (void)
+{
+  printf ("The answer is %d.\n", answer ());
+  return 0;
+}
-- 
GitLab