diff --git a/20230417/bs-20230417.txt b/20230417/bs-20230417.txt
index 8e679b1561f9657120a6c08d0683b4440728be86..2db4716ef35f15c443a6131d21deaab059af7bb1 100644
--- a/20230417/bs-20230417.txt
+++ b/20230417/bs-20230417.txt
@@ -41,3 +41,22 @@ Aufgabe: Schreibe ein Progrämmchen, das eine float-Variable lesbar ausgibt,
 Die Aufgabe ist erfüllt, wenn wir die Mantisse (mit Vorzeichen) und den (binären)
 Exponenten kennen. Um danach die Dezimalzahl korrekt auszugeben, ist auch
 Gleitkommaarithmetik sowie printf() mit "%f" (oder besser: "%e") erlaubt.
+
+Ergebnis:
+
+  Format der Fließkommazahl: V EEEEEEEE 1.MMMMMMMMMMMMMMMMMMMMMMM
+
+  Fließkommazahl: 6.674300e-11
+  Bitmuster: 0x2e92c4f8
+  Vorzeichen: 0
+  Charakteristik: 93
+  Exponent, bezogen auf das zweitoberste Bit der Mantisse: -34
+
+    Ergebnis: 1.MMMMMMMMMMMMMMMMMMMMMMM · 2^(Charakteristik - B)  // B = 127 bei float
+
+  Exponent, bezogen auf das unterste Bit der Mantisse: -57
+
+    Ergebnis: 1MMMMMMMMMMMMMMMMMMMMMMM.0 · 2^(Charakteristik - B - 23)  // B = 127 bei float
+
+  Mantisse: 9618680  // bezogen auf das unterste Bit
+  Ergebnis: 9618680·2^-57
diff --git a/20230417/decode-float-01.c b/20230417/decode-float-01.c
index 9eaf2c84f453d41795332f3f6c8a94d94a4a0891..590de53f1dce6d1a0b60e9ec2713f0dd3e89e39e 100644
--- a/20230417/decode-float-01.c
+++ b/20230417/decode-float-01.c
@@ -6,13 +6,20 @@
 int main (void)
 {
   float G = 6.6743e-11;
+  printf ("Fließkommazahl: %e\n", G);
   uint32_t *g = (uint32_t *) &G;
+  printf ("Bitmuster: 0x%08x\n", *g);
   int8_t sign = !!(*g & (1 << 31));
-  uint8_t ch = (*g >> 23);
+  printf ("Vorzeichen: %d\n", sign);
+  uint8_t ch = ((*g & 0x7fffffff) >> 23);
+  printf ("Charakteristik: %d\n", ch);
   int ex = ch - B;
+  printf ("Exponent, bezogen auf das zweitoberste Bit der Mantisse: %d\n", ex);
+  printf ("Exponent, bezogen auf das unterste Bit der Mantisse: %d\n", ex - 23);
   int32_t mant = (*g & 0x7fffff) | 0x800000;
+  printf ("Mantisse: %d\n", mant);
   if (sign)
     mant *= -1;
-  printf ("%d·2^%d\n", mant, ex);
+  printf ("Ergebnis: %d·2^%d\n", mant, ex - 23);
   return 0;
 }
diff --git a/20230417/deriv-01a.c b/20230417/deriv-01a.c
new file mode 100644
index 0000000000000000000000000000000000000000..e81208ba088d062487d9764abfe92e6c3fc8ee1a
--- /dev/null
+++ b/20230417/deriv-01a.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+float f (float x)
+{
+  return x * x;
+}
+
+int main (void)
+{
+  const float dx = 0.0000001;
+  float x = 0.9;
+  printf ("%10f%10f\n", x, f (x));
+  x += dx;
+  printf ("%10f%10f\n", x, f (x));
+  return 0;
+}
diff --git a/20230424/Makefile b/20230424/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..6a174068b972826533722de4ce0d45808895798c
--- /dev/null
+++ b/20230424/Makefile
@@ -0,0 +1,10 @@
+obj-m += chardev-1.o
+obj-m += chardev-2.o
+obj-m += chardev-3.o
+obj-m += chardev-3x.o
+
+all:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
+
+clean:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
diff --git a/20230424/chardev-1.c b/20230424/chardev-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..a809bffbac6fb448de18708bf1a53a52187f5a8e
--- /dev/null
+++ b/20230424/chardev-1.c
@@ -0,0 +1,168 @@
+/*
+ *  chardev.c: Creates a read-only char device that says how many times
+ *  you've read from the dev file
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>	/* for put_user */
+
+MODULE_LICENSE("GPL");
+
+/*  
+ *  Prototypes - this would normally go in a .h file
+ */
+int init_module(void);
+void cleanup_module(void);
+static int device_open(struct inode *, struct file *);
+static int device_release(struct inode *, struct file *);
+static ssize_t device_read(struct file *, char *, size_t, loff_t *);
+static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
+
+#define SUCCESS 0
+#define DEVICE_NAME "chardev"	/* Dev name as it appears in /proc/devices   */
+#define BUF_LEN 80		/* Max length of the message from the device */
+
+/* 
+ * Global variables are declared as static, so are global within the file. 
+ */
+
+static int Major;		/* Major number assigned to our device driver */
+static int Device_Open = 0;	/* Is device open?  
+				 * Used to prevent multiple access to device */
+static char msg[BUF_LEN];	/* The msg the device will give when asked */
+static char *msg_Ptr;
+
+static struct file_operations fops = {
+	.read = device_read,
+	.write = device_write,
+	.open = device_open,
+	.release = device_release
+};
+
+/*
+ * This function is called when the module is loaded
+ */
+int init_module(void)
+{
+        Major = register_chrdev(0, DEVICE_NAME, &fops);
+
+	if (Major < 0) {
+	  printk(KERN_ALERT "Registering char device failed with %d\n", Major);
+	  return Major;
+	}
+
+	printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major);
+	printk(KERN_INFO "the driver, create a dev file with\n");
+	printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major);
+	printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n");
+	printk(KERN_INFO "the device file.\n");
+	printk(KERN_INFO "Remove the device file and module when done.\n");
+
+	return SUCCESS;
+}
+
+/*
+ * This function is called when the module is unloaded
+ */
+void cleanup_module(void)
+{
+	/* 
+	 * Unregister the device 
+	 */
+	unregister_chrdev(Major, DEVICE_NAME);
+}
+
+/*
+ * Methods
+ */
+
+/* 
+ * Called when a process tries to open the device file, like
+ * "cat /dev/mycharfile"
+ */
+static int device_open(struct inode *inode, struct file *file)
+{
+	static int counter = 0;
+
+	if (Device_Open)
+		return -EBUSY;
+
+	Device_Open++;
+	sprintf(msg, "I already told you %d times Hello world!\n", counter++);
+	msg_Ptr = msg;
+	try_module_get(THIS_MODULE);
+
+	return SUCCESS;
+}
+
+/* 
+ * Called when a process closes the device file.
+ */
+static int device_release(struct inode *inode, struct file *file)
+{
+	Device_Open--;		/* We're now ready for our next caller */
+
+	/* 
+	 * Decrement the usage count, or else once you opened the file, you'll
+	 * never get get rid of the module. 
+	 */
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+/* 
+ * Called when a process, which already opened the dev file, attempts to
+ * read from it.
+ */
+static ssize_t device_read(struct file *filp,	/* see include/linux/fs.h   */
+			   char *buffer,	/* buffer to fill with data */
+			   size_t length,	/* length of the buffer     */
+			   loff_t *offset)
+{
+	/*
+	 * Number of bytes actually written to the buffer 
+	 */
+	int bytes_read = 0;
+
+	/*
+	 * If we're at the end of the message, 
+	 * return 0 signifying end of file 
+	 */
+	if (*msg_Ptr == 0)
+		return 0;
+
+	/* 
+	 * Actually put the data into the buffer 
+	 */
+	while (length && *msg_Ptr) {
+
+		/* 
+		 * The buffer is in the user data segment, not the kernel 
+		 * segment so "*" assignment won't work.  We have to use 
+		 * put_user which copies data from the kernel data segment to
+		 * the user data segment. 
+		 */
+		put_user(*(msg_Ptr++), buffer++);
+
+		length--;
+		bytes_read++;
+	}
+
+	/* 
+	 * Most read functions return the number of bytes put into the buffer
+	 */
+	return bytes_read;
+}
+
+/*  
+ * Called when a process writes to dev file: echo "hi" > /dev/hello 
+ */
+static ssize_t
+device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+{
+	printk(KERN_ALERT "Sorry, this operation isn't supported.\n");
+	return -EINVAL;
+}
diff --git a/20230424/chardev-1.txt b/20230424/chardev-1.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a2b8075ddff5a93e0147f62b3b3868040f1c4e93
--- /dev/null
+++ b/20230424/chardev-1.txt
@@ -0,0 +1,41 @@
+[300030.570357] chardev_1: loading out-of-tree module taints kernel.
+[300030.570409] chardev_1: module verification failed: signature and/or required key missing - tainting kernel
+[300030.570636] I was assigned major number 241. To talk to
+[300030.570637] the driver, create a dev file with
+[300030.570637] 'mknod /dev/chardev c 241 0'.
+[300030.570638] Try various minor numbers. Try to cat and echo to
+[300030.570638] the device file.
+[300030.570638] Remove the device file and module when done.
+cassini/home/peter/bo/2023ss/bs/20230424> mkdir dev
+cassini/home/peter/bo/2023ss/bs/20230424> mknod dev/chardev c 241 0
+mknod: dev/chardev: Die Operation ist nicht erlaubt
+cassini/home/peter/bo/2023ss/bs/20230424> sudo mknod dev/chardev c 241 0
+cassini/home/peter/bo/2023ss/bs/20230424> ls -l dev
+insgesamt 0
+crw-r--r-- 1 root root 241, 0 Apr 24 17:16 chardev
+cassini/home/peter/bo/2023ss/bs/20230424>
+cassini/home/peter/bo/2023ss/bs/20230424> ls -l dev/
+insgesamt 0
+crw-r--r-- 1 root root 241, 0 Apr 24 17:16 chardev
+cassini/home/peter/bo/2023ss/bs/20230424> #sudo mknod dev/chardev c 241 0
+cassini/home/peter/bo/2023ss/bs/20230424> echo "Hallo!" > dev/chardev
+bash: dev/chardev: Keine Berechtigung
+cassini/home/peter/bo/2023ss/bs/20230424> sudo echo "Hallo!" > dev/chardev
+bash: dev/chardev: Keine Berechtigung
+cassini/home/peter/bo/2023ss/bs/20230424> echo "Hallo!" | sudo tee dev/chardev
+Hallo!
+tee: dev/chardev: Das Argument ist ungültig
+cassini/home/peter/bo/2023ss/bs/20230424> LANG=C echo "Hallo!" | sudo tee dev/chardev
+Hallo!
+tee: dev/chardev: Das Argument ist ungültig
+cassini/home/peter/bo/2023ss/bs/20230424> echo "Hallo!" | LANG=C sudo tee dev/chardev        Hallo!
+tee: dev/chardev: Invalid argument
+cassini/home/peter/bo/2023ss/bs/20230424>
+cassini/home/peter/bo/2023ss/bs/20230424> ls -l dev/
+insgesamt 0
+crw-r--r-- 1 root root 241, 0 Apr 24 17:16 chardev
+cassini/home/peter/bo/2023ss/bs/20230424> cat dev/chardev
+I already told you 3 times Hello world!
+cassini/home/peter/bo/2023ss/bs/20230424> cat dev/chardev
+I already told you 4 times Hello world!
+cassini/home/peter/bo/2023ss/bs/20230424>
diff --git a/20230417/chardev-2.c b/20230424/chardev-2.c
similarity index 100%
rename from 20230417/chardev-2.c
rename to 20230424/chardev-2.c
diff --git a/20230424/chardev-3.c b/20230424/chardev-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..663c4a555ba554c69b8a3ac41228254e40f643e3
--- /dev/null
+++ b/20230424/chardev-3.c
@@ -0,0 +1,198 @@
+/*
+ *  chardev.c: Creates a read-only char device that says how many times
+ *  you've read from the dev file
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>	/* for put_user */
+
+MODULE_LICENSE("GPL");
+
+/*  
+ *  Prototypes - this would normally go in a .h file
+ */
+int init_module(void);
+void cleanup_module(void);
+static int device_open(struct inode *, struct file *);
+static int device_release(struct inode *, struct file *);
+static ssize_t device_read(struct file *, char *, size_t, loff_t *);
+static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
+
+struct class *dev_Class;
+struct device *chr_dev;
+
+#define SUCCESS 0
+#define DEVICE_NAME "chardev"	/* Dev name as it appears in /proc/devices   */
+#define BUF_LEN 80		/* Max length of the message from the device */
+
+/* 
+ * Global variables are declared as static, so are global within the file. 
+ */
+
+static int Major;		/* Major number assigned to our device driver */
+static int Device_Open = 0;	/* Is device open?  
+				 * Used to prevent multiple access to device */
+static char msg[BUF_LEN];	/* The msg the device will give when asked */
+static char *msg_Ptr;
+
+static struct file_operations fops = {
+	.read = device_read,
+	.write = device_write,
+	.open = device_open,
+	.release = device_release
+};
+
+/*
+ * This function is called when the module is loaded
+ */
+int init_module(void)
+{
+        Major = register_chrdev(0, DEVICE_NAME, &fops);
+
+	if (Major < 0) {
+	  printk(KERN_ALERT "Registering char device failed with %d\n", Major);
+	  return Major;
+	}
+
+        // Create module class
+        printk (KERN_INFO "Creating device class \"chardev\" ...\n");
+        dev_Class = class_create (THIS_MODULE,DEVICE_NAME);
+        if( dev_Class == NULL)
+        {
+            printk (KERN_ALERT "Error! Class couldn't be created!\n");
+            return 1;
+        }
+        printk (KERN_INFO "Class created!\n");
+        // Create device in /dev/...
+        printk (KERN_INFO "Creating device\n");
+        chr_dev = device_create (dev_Class, NULL, MKDEV (Major,0), NULL, DEVICE_NAME);
+        if (chr_dev == NULL)
+        {
+            printk( KERN_ALERT "Error! Device couldn't be created!\n" );
+            return 1 ;
+        }
+
+	return SUCCESS;
+}
+
+/*
+ * This function is called when the module is unloaded
+ */
+void cleanup_module(void)
+{
+        printk(KERN_INFO "module chardev-3 cleanup\n");
+        //Unregister the device
+        if (chr_dev)
+          {
+            printk(KERN_INFO "Unregister device ...\n");
+            device_unregister(chr_dev);
+            printk(KERN_INFO "OK\n");
+          }
+
+        if (dev_Class)
+          {
+            printk(KERN_INFO "Unregister class ...\n");
+            class_unregister(dev_Class);
+            printk(KERN_INFO "OK\n");
+          }
+
+        printk(KERN_INFO "Unregister Chardev ...\n");
+        unregister_chrdev(Major, DEVICE_NAME);
+        printk(KERN_INFO "Device %s unregistered!\n", DEVICE_NAME);
+}
+
+/*
+ * Methods
+ */
+
+/* 
+ * Called when a process tries to open the device file, like
+ * "cat /dev/mycharfile"
+ */
+static int device_open(struct inode *inode, struct file *file)
+{
+	static int counter = 0;
+
+	if (Device_Open)
+		return -EBUSY;
+
+	Device_Open++;
+	sprintf(msg, "I already told you %d times Hello world!\n", counter++);
+	msg_Ptr = msg;
+	try_module_get(THIS_MODULE);
+
+	return SUCCESS;
+}
+
+/* 
+ * Called when a process closes the device file.
+ */
+static int device_release(struct inode *inode, struct file *file)
+{
+	Device_Open--;		/* We're now ready for our next caller */
+
+	/* 
+	 * Decrement the usage count, or else once you opened the file, you'll
+	 * never get get rid of the module. 
+	 */
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+/* 
+ * Called when a process, which already opened the dev file, attempts to
+ * read from it.
+ */
+static ssize_t device_read(struct file *filp,	/* see include/linux/fs.h   */
+			   char *buffer,	/* buffer to fill with data */
+			   size_t length,	/* length of the buffer     */
+			   loff_t * offset)
+{
+	/*
+	 * Number of bytes actually written to the buffer 
+	 */
+	int bytes_read = 0;
+
+	/*
+	 * If we're at the end of the message, 
+	 * return 0 signifying end of file 
+	 */
+	if (*msg_Ptr == 0)
+		return 0;
+
+	/* 
+	 * Actually put the data into the buffer 
+	 */
+	while (length && *msg_Ptr) {
+
+		/* 
+		 * The buffer is in the user data segment, not the kernel 
+		 * segment so "*" assignment won't work.  We have to use 
+		 * put_user which copies data from the kernel data segment to
+		 * the user data segment. 
+		 */
+		put_user(*(msg_Ptr++), buffer++);
+
+		length--;
+		bytes_read++;
+	}
+
+	/* 
+	 * Most read functions return the number of bytes put into the buffer
+	 */
+	return bytes_read;
+}
+
+/*  
+ * Called when a process writes to dev file: echo "hi" > /dev/hello 
+ */
+static ssize_t
+device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+{
+	printk(KERN_ALERT "Sorry, this operation isn't supported.\n");
+	return -EINVAL;
+}
diff --git a/20230424/chardev-3x.c b/20230424/chardev-3x.c
new file mode 100644
index 0000000000000000000000000000000000000000..741fb3a646d616f01fdca1bbac2a6f0e7d97e439
--- /dev/null
+++ b/20230424/chardev-3x.c
@@ -0,0 +1,198 @@
+/*
+ *  chardev.c: Creates a read-only char device that says how many times
+ *  you've read from the dev file
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>	/* for put_user */
+
+MODULE_LICENSE("GPL");
+
+/*  
+ *  Prototypes - this would normally go in a .h file
+ */
+int init_module(void);
+void cleanup_module(void);
+static int device_open(struct inode *, struct file *);
+static int device_release(struct inode *, struct file *);
+static ssize_t device_read(struct file *, char *, size_t, loff_t *);
+static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
+
+struct class *dev_Class;
+struct device *chr_dev;
+
+#define SUCCESS 0
+#define DEVICE_NAME "chardevx"	/* Dev name as it appears in /proc/devices   */
+#define BUF_LEN 80		/* Max length of the message from the device */
+
+/* 
+ * Global variables are declared as static, so are global within the file. 
+ */
+
+static int Major;		/* Major number assigned to our device driver */
+static int Device_Open = 0;	/* Is device open?  
+				 * Used to prevent multiple access to device */
+static char msg[BUF_LEN];	/* The msg the device will give when asked */
+static char *msg_Ptr;
+
+static struct file_operations fops = {
+	.read = device_read,
+	.write = device_write,
+	.open = device_open,
+	.release = device_release
+};
+
+/*
+ * This function is called when the module is loaded
+ */
+int init_module(void)
+{
+        Major = register_chrdev(0, DEVICE_NAME, &fops);
+
+	if (Major < 0) {
+	  printk(KERN_ALERT "Registering char device failed with %d\n", Major);
+	  return Major;
+	}
+
+        // Create module class
+        printk (KERN_INFO "Creating device class \"chardev\" ...\n");
+        dev_Class = class_create (THIS_MODULE,DEVICE_NAME);
+        if( dev_Class == NULL)
+        {
+            printk (KERN_ALERT "Error! Class couldn't be created!\n");
+            return 1;
+        }
+        printk (KERN_INFO "Class created!\n");
+        // Create device in /dev/...
+        printk (KERN_INFO "Creating device\n");
+        chr_dev = device_create (dev_Class, NULL, MKDEV (Major,0), NULL, DEVICE_NAME);
+        if (chr_dev == NULL)
+        {
+            printk( KERN_ALERT "Error! Device couldn't be created!\n" );
+            return 1 ;
+        }
+
+	return SUCCESS;
+}
+
+/*
+ * This function is called when the module is unloaded
+ */
+void cleanup_module(void)
+{
+        printk(KERN_INFO "module chardev-3 cleanup\n");
+        //Unregister the device
+        if (chr_dev)
+          {
+            printk(KERN_INFO "Unregister device ...\n");
+            device_unregister(chr_dev);
+            printk(KERN_INFO "OK\n");
+          }
+
+        if (dev_Class)
+          {
+            printk(KERN_INFO "Unregister class ...\n");
+            class_unregister(dev_Class);
+            printk(KERN_INFO "OK\n");
+          }
+
+        printk(KERN_INFO "Unregister Chardev ...\n");
+        unregister_chrdev(Major, DEVICE_NAME);
+        printk(KERN_INFO "Device %s unregistered!\n", DEVICE_NAME);
+}
+
+/*
+ * Methods
+ */
+
+/* 
+ * Called when a process tries to open the device file, like
+ * "cat /dev/mycharfile"
+ */
+static int device_open(struct inode *inode, struct file *file)
+{
+	static int counter = 0;
+
+	if (Device_Open)
+		return -EBUSY;
+
+	Device_Open++;
+	sprintf(msg, "I already told you %d times Hello world!\n", counter++);
+	msg_Ptr = msg;
+	try_module_get(THIS_MODULE);
+
+	return SUCCESS;
+}
+
+/* 
+ * Called when a process closes the device file.
+ */
+static int device_release(struct inode *inode, struct file *file)
+{
+	Device_Open--;		/* We're now ready for our next caller */
+
+	/* 
+	 * Decrement the usage count, or else once you opened the file, you'll
+	 * never get get rid of the module. 
+	 */
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+/* 
+ * Called when a process, which already opened the dev file, attempts to
+ * read from it.
+ */
+static ssize_t device_read(struct file *filp,	/* see include/linux/fs.h   */
+			   char *buffer,	/* buffer to fill with data */
+			   size_t length,	/* length of the buffer     */
+			   loff_t * offset)
+{
+	/*
+	 * Number of bytes actually written to the buffer 
+	 */
+	int bytes_read = 0;
+
+	/*
+	 * If we're at the end of the message, 
+	 * return 0 signifying end of file 
+	 */
+	if (*msg_Ptr == 0)
+		return 0;
+
+	/* 
+	 * Actually put the data into the buffer 
+	 */
+	while (length && *msg_Ptr) {
+
+		/* 
+		 * The buffer is in the user data segment, not the kernel 
+		 * segment so "*" assignment won't work.  We have to use 
+		 * put_user which copies data from the kernel data segment to
+		 * the user data segment. 
+		 */
+		put_user(*(msg_Ptr++), buffer++);
+
+		length--;
+		bytes_read++;
+	}
+
+	/* 
+	 * Most read functions return the number of bytes put into the buffer
+	 */
+	return bytes_read;
+}
+
+/*  
+ * Called when a process writes to dev file: echo "hi" > /dev/hello 
+ */
+static ssize_t
+device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+{
+	printk(KERN_ALERT "Sorry, this operation isn't supported.\n");
+	return -EINVAL;
+}
diff --git a/20230424/chardev-4.c b/20230424/chardev-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..91f261b7e380395f10a73f5a7fb574d0993a60d7
--- /dev/null
+++ b/20230424/chardev-4.c
@@ -0,0 +1,200 @@
+/*
+ *  chardev.c: Creates a read-only char device that says how many times
+ *  you've read from the dev file
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>	/* for put_user */
+
+MODULE_LICENSE("GPL");
+
+/*  
+ *  Prototypes - this would normally go in a .h file
+ */
+int init_module(void);
+void cleanup_module(void);
+static int device_open(struct inode *, struct file *);
+static int device_release(struct inode *, struct file *);
+static ssize_t device_read(struct file *, char *, size_t, loff_t *);
+static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
+
+struct class *dev_Class;
+struct device *chr_dev;
+
+#define SUCCESS 0
+#define DEVICE_NAME "chardev"	/* Dev name as it appears in /proc/devices   */
+#define BUF_LEN 80		/* Max length of the message from the device */
+
+/* 
+ * Global variables are declared as static, so are global within the file. 
+ */
+
+static int Major;		/* Major number assigned to our device driver */
+static int Device_Open = 0;	/* Is device open?  
+				 * Used to prevent multiple access to device */
+static char msg[BUF_LEN];	/* The msg the device will give when asked */
+static char *msg_Ptr;
+
+static struct file_operations fops = {
+	.read = device_read,
+	.write = device_write,
+	.open = device_open,
+	.release = device_release
+};
+
+/*
+ * This function is called when the module is loaded
+ */
+int init_module(void)
+{
+        Major = register_chrdev(0, DEVICE_NAME, &fops);
+
+	if (Major < 0) {
+	  printk(KERN_ALERT "Registering char device failed with %d\n", Major);
+	  return Major;
+	}
+
+        // Create module class
+        printk (KERN_INFO "Creating device class \"chardev\" ...\n");
+        dev_Class = class_create (THIS_MODULE,DEVICE_NAME);
+        if( dev_Class == NULL)
+        {
+            printk (KERN_ALERT "Error! Class couldn't be created!\n");
+            return 1;
+        }
+        printk (KERN_INFO "Class created!\n");
+        // Create device in /dev/...
+        printk (KERN_INFO "Creating device\n");
+        chr_dev = device_create (dev_Class, NULL, MKDEV (Major,0), NULL, DEVICE_NAME);
+        if (chr_dev == NULL)
+        {
+            printk( KERN_ALERT "Error! Device couldn't be created!\n" );
+            return 1 ;
+        }
+
+	return SUCCESS;
+}
+
+/*
+ * This function is called when the module is unloaded
+ */
+void cleanup_module(void)
+{
+        printk(KERN_INFO "module chardev-4 cleanup\n");
+        //Unregister the device
+        if (chr_dev)
+          {
+            printk(KERN_INFO "Unregister device ...\n");
+            device_unregister(chr_dev);
+            printk(KERN_INFO "OK\n");
+          }
+
+        if (dev_Class)
+          {
+            printk(KERN_INFO "Unregister class ...\n");
+            class_unregister(dev_Class);
+            printk(KERN_INFO "OK\n");
+          }
+
+        printk(KERN_INFO "Unregister Chardev ...\n");
+        unregister_chrdev(Major, DEVICE_NAME);
+        printk(KERN_INFO "Device %s unregistered!\n", DEVICE_NAME);
+}
+
+/*
+ * Methods
+ */
+
+/* 
+ * Called when a process tries to open the device file, like
+ * "cat /dev/mycharfile"
+ */
+static int device_open(struct inode *inode, struct file *file)
+{
+	static int counter = 0;
+
+	if (Device_Open)
+		return -EBUSY;
+
+	Device_Open++;
+	sprintf(msg, "I already told you %d times Hello world!\n", counter++);
+	msg_Ptr = msg;
+	try_module_get(THIS_MODULE);
+
+	return SUCCESS;
+}
+
+/* 
+ * Called when a process closes the device file.
+ */
+static int device_release(struct inode *inode, struct file *file)
+{
+	Device_Open--;		/* We're now ready for our next caller */
+
+	/* 
+	 * Decrement the usage count, or else once you opened the file, you'll
+	 * never get get rid of the module. 
+	 */
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+/* 
+ * Called when a process, which already opened the dev file, attempts to
+ * read from it.
+ */
+static ssize_t device_read(struct file *filp,	/* see include/linux/fs.h   */
+			   char *buffer,	/* buffer to fill with data */
+			   size_t length,	/* length of the buffer     */
+			   loff_t * offset)
+{
+	/*
+	 * Number of bytes actually written to the buffer 
+	 */
+	int bytes_read = 0;
+
+	/*
+	 * If we're at the end of the message, 
+	 * return 0 signifying end of file 
+	 */
+	if (*msg_Ptr == 0)
+		return 0;
+
+	/* 
+	 * Actually put the data into the buffer 
+	 */
+	while (length && *msg_Ptr) {
+
+		/* 
+		 * The buffer is in the user data segment, not the kernel 
+		 * segment so "*" assignment won't work.  We have to use 
+		 * put_user which copies data from the kernel data segment to
+		 * the user data segment. 
+		 */
+/*		put_user(*(msg_Ptr++), buffer++); */
+
+                *buffer++ = *(msg_Ptr++);   /* Sicherheitsloch! */
+
+		length--;
+		bytes_read++;
+	}
+
+	/* 
+	 * Most read functions return the number of bytes put into the buffer
+	 */
+	return bytes_read;
+}
+
+/*  
+ * Called when a process writes to dev file: echo "hi" > /dev/hello 
+ */
+static ssize_t
+device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+{
+	printk(KERN_ALERT "Sorry, this operation isn't supported.\n");
+	return -EINVAL;
+}
diff --git a/20230424/floats-08.c b/20230424/floats-08.c
new file mode 100644
index 0000000000000000000000000000000000000000..43a20bf58a7203111465e9713d54e93ff6001e4a
--- /dev/null
+++ b/20230424/floats-08.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main (void)
+{
+  float fifth = 1.0 / 5.0;
+  printf ("1/5 = %f\n", fifth);
+  return 0;
+}
diff --git a/20230424/floats-08.s b/20230424/floats-08.s
new file mode 100644
index 0000000000000000000000000000000000000000..a3e3f181cde0802ecd035a35a6751fc9bbc2b3f6
--- /dev/null
+++ b/20230424/floats-08.s
@@ -0,0 +1,31 @@
+	.file	"floats-08.c"
+	.text
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC1:
+	.string	"1/5 = %f\n"
+	.text
+	.globl	main
+	.type	main, @function
+main:
+.LFB11:
+	.cfi_startproc
+	subq	$8, %rsp
+	.cfi_def_cfa_offset 16
+	movsd	.LC0(%rip), %xmm0
+	leaq	.LC1(%rip), %rdi
+	movl	$1, %eax
+	call	printf@PLT
+	movl	$0, %eax
+	addq	$8, %rsp
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE11:
+	.size	main, .-main
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align 8
+.LC0:
+	.long	2684354560
+	.long	1070176665
+	.ident	"GCC: (Debian 8.3.0-6) 8.3.0"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/20230424/floats-09.c b/20230424/floats-09.c
new file mode 100644
index 0000000000000000000000000000000000000000..1861417aa45c3a02f1ef2869682d15c4113e436b
--- /dev/null
+++ b/20230424/floats-09.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main (void)
+{
+  volatile float fifth = 1.0 / 5.0;
+  printf ("1/5 = %f\n", fifth);
+  return 0;
+}
diff --git a/20230424/floats-09.s b/20230424/floats-09.s
new file mode 100644
index 0000000000000000000000000000000000000000..873ce9ebcb7f93f32719e7033e7021bee48f9416
--- /dev/null
+++ b/20230424/floats-09.s
@@ -0,0 +1,33 @@
+	.file	"floats-09.c"
+	.text
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC1:
+	.string	"1/5 = %f\n"
+	.text
+	.globl	main
+	.type	main, @function
+main:
+.LFB11:
+	.cfi_startproc
+	subq	$24, %rsp
+	.cfi_def_cfa_offset 32
+	movss	.LC0(%rip), %xmm0
+	movss	%xmm0, 12(%rsp)
+	movss	12(%rsp), %xmm0
+	cvtss2sd	%xmm0, %xmm0
+	leaq	.LC1(%rip), %rdi
+	movl	$1, %eax
+	call	printf@PLT
+	movl	$0, %eax
+	addq	$24, %rsp
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE11:
+	.size	main, .-main
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align 4
+.LC0:
+	.long	1045220557
+	.ident	"GCC: (Debian 8.3.0-6) 8.3.0"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/20230424/gtk-01.c b/20230424/gtk-01.c
new file mode 100644
index 0000000000000000000000000000000000000000..884a14ea528431e54f8391c801958a6e494dfe43
--- /dev/null
+++ b/20230424/gtk-01.c
@@ -0,0 +1,11 @@
+#include <gtk/gtk.h>
+
+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");
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20230424/gtk-02.c b/20230424/gtk-02.c
new file mode 100644
index 0000000000000000000000000000000000000000..c5db19f8d7e859ff12b08ffd6425b84deab35d07
--- /dev/null
+++ b/20230424/gtk-02.c
@@ -0,0 +1,12 @@
+#include <gtk/gtk.h>
+
+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);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20230424/gtk-03.c b/20230424/gtk-03.c
new file mode 100644
index 0000000000000000000000000000000000000000..26fcdd9bf83023b4f3e704a93218134149829f83
--- /dev/null
+++ b/20230424/gtk-03.c
@@ -0,0 +1,16 @@
+#include <gtk/gtk.h>
+
+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 *button = gtk_button_new_with_label ("Quit");
+  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_container_add (GTK_CONTAINER (window), button);
+  gtk_widget_show (button);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20230424/gtk-04.c b/20230424/gtk-04.c
new file mode 100644
index 0000000000000000000000000000000000000000..132dbcb61fb979372da88225e8cb881d2b81a2d4
--- /dev/null
+++ b/20230424/gtk-04.c
@@ -0,0 +1,26 @@
+#include <gtk/gtk.h>
+
+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);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20230424/gtk-05.c b/20230424/gtk-05.c
new file mode 100644
index 0000000000000000000000000000000000000000..c77feaac44766ae3e7b157d3a72e03f62c9c687b
--- /dev/null
+++ b/20230424/gtk-05.c
@@ -0,0 +1,27 @@
+#include <gtk/gtk.h>
+
+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);
+  gtk_widget_set_size_request (drawing_area, 100, 100);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20230424/gtk-06.c b/20230424/gtk-06.c
new file mode 100644
index 0000000000000000000000000000000000000000..81e12e6958d3c0adbed8d315927104482bc4c681
--- /dev/null
+++ b/20230424/gtk-06.c
@@ -0,0 +1,53 @@
+#include <gtk/gtk.h>
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA red = { 1.0, 0.0, 0.0, 0.8 };
+  GdkRGBA yellow = { 1.0, 1.0, 0.0, 0.6 };
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 0.4 };
+
+  gdk_cairo_set_source_rgba (c, &red);
+  cairo_rectangle (c, 10, 10, 60, 40);
+  cairo_fill (c);
+
+  gdk_cairo_set_source_rgba (c, &yellow);
+  cairo_arc (c, 65, 50, 30, 0, 2 * G_PI);
+  cairo_fill (c);
+
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_move_to (c, 10, 70);
+  cairo_line_to (c, 70, 70);
+  cairo_line_to (c, 40, 18);
+  cairo_close_path (c);
+  cairo_fill (c);
+
+  return FALSE;  /* TRUE to stop other handlers from being invoked for the event.
+                    FALSE to propagate the event further. */
+}
+
+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, 100, 100);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20230424/gtk-07.c b/20230424/gtk-07.c
new file mode 100644
index 0000000000000000000000000000000000000000..11041fbe1d27585ca4edb951f195f114ddad126e
--- /dev/null
+++ b/20230424/gtk-07.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <gtk/gtk.h>
+
+gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+{
+  GdkRGBA red = { 1.0, 0.0, 0.0, 0.8 };
+  GdkRGBA yellow = { 1.0, 1.0, 0.0, 0.6 };
+  GdkRGBA blue = { 0.0, 0.5, 1.0, 0.4 };
+
+  gdk_cairo_set_source_rgba (c, &red);
+  cairo_rectangle (c, 10, 10, 60, 40);
+  cairo_fill (c);
+
+  gdk_cairo_set_source_rgba (c, &yellow);
+  cairo_arc (c, 65, 50, 30, 0, 2 * G_PI);
+  cairo_fill (c);
+
+  gdk_cairo_set_source_rgba (c, &blue);
+  cairo_move_to (c, 10, 70);
+  cairo_line_to (c, 70, 70);
+  cairo_line_to (c, 40, 18);
+  cairo_close_path (c);
+  cairo_fill (c);
+
+  return FALSE;  /* TRUE to stop other handlers from being invoked for the event.
+                    FALSE to propagate the event further. */
+}
+
+gboolean button_press (GtkWidget *widget, GdkEventButton *e, gpointer data)
+{
+  printf ("button %d pressed at (%lf, %lf)\n", e->button, e->x, e->y);
+  return FALSE;
+}
+
+gboolean key_press (GtkWidget *widget, GdkEventKey *e, gpointer data)
+{
+  printf ("key '%c' (%d) pressed\n", e->keyval, e->keyval);
+  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, 100, 100);
+  gtk_widget_add_events (drawing_area, GDK_BUTTON_PRESS_MASK);
+  g_signal_connect (drawing_area, "button_press_event", G_CALLBACK (button_press), NULL);
+
+  gtk_widget_add_events (window, GDK_KEY_PRESS_MASK);
+  g_signal_connect (window, "key_press_event", G_CALLBACK (key_press), NULL);
+
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (button);
+  gtk_widget_show (vbox);
+  gtk_widget_show (window);
+  gtk_main ();
+  return 0;
+}
diff --git a/20230424/gtk-08.c b/20230424/gtk-08.c
new file mode 100644
index 0000000000000000000000000000000000000000..d3092d009f1b20909a96ed89be3cfe971c11263f
--- /dev/null
+++ b/20230424/gtk-08.c
@@ -0,0 +1,54 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 320
+#define HEIGHT 240
+
+double x = 5;
+double y = 95;
+
+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, y, 5, 0, 2 * G_PI);
+  cairo_fill (c);
+  return FALSE;
+}
+
+gboolean timer (GtkWidget *widget)
+{
+  x += 0.5;
+  y -= 0.7;
+  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 (50, (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/20230424/gtk-09.c b/20230424/gtk-09.c
new file mode 100644
index 0000000000000000000000000000000000000000..91af21857c6bb810659fbb4c11afbcab293fa188
--- /dev/null
+++ b/20230424/gtk-09.c
@@ -0,0 +1,60 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 320
+#define HEIGHT 240
+
+double x = 5;
+double y = 95;
+double vx = 0.5;
+double vy = 0.7;
+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, 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 (50, (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/20230424/gtk-10.c b/20230424/gtk-10.c
new file mode 100644
index 0000000000000000000000000000000000000000..f7fb2d5b1c4d3f1082a15b8f3a23fb5480fdd4f1
--- /dev/null
+++ b/20230424/gtk-10.c
@@ -0,0 +1,60 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 320
+#define HEIGHT 240
+
+double x = 5;
+double y = 95;
+double vx = 0.5;
+double vy = 0.7;
+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 (50, (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/20230424/gtk-11.c b/20230424/gtk-11.c
new file mode 100644
index 0000000000000000000000000000000000000000..1fa3d7169dc09ed0a5e89abffdce3cb297509842
--- /dev/null
+++ b/20230424/gtk-11.c
@@ -0,0 +1,60 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+
+double x = 5;
+double y = 95;
+double vx = 0.5;
+double vy = 0.7;
+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 (50, (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/20230424/gtk-12.c b/20230424/gtk-12.c
new file mode 100644
index 0000000000000000000000000000000000000000..e0c274336e1ea7a21983daaa95a563796b532e25
--- /dev/null
+++ b/20230424/gtk-12.c
@@ -0,0 +1,60 @@
+#include <gtk/gtk.h>
+
+#define WIDTH 640
+#define HEIGHT 480
+
+double x = 5;
+double y = 95;
+double vx = 5.0;
+double vy = 0.7;
+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 (50, (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/20230424/hello-42.c b/20230424/hello-42.c
new file mode 100644
index 0000000000000000000000000000000000000000..83395b991f2a7b91b2c063d1f691b55dd7c07554
--- /dev/null
+++ b/20230424/hello-42.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int main (void)
+{
+  printf ("The answer is: ");
+  printf (42);
+  printf ("\n");
+  return 0;
+}
diff --git a/20230424/hello-43.c b/20230424/hello-43.c
new file mode 100644
index 0000000000000000000000000000000000000000..eac8ce442d46a7bc465234efbeadd81843f0b5eb
--- /dev/null
+++ b/20230424/hello-43.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int main (void)
+{
+  printf ("The answer is: ");
+  printf ((char *) 42);
+  printf ("\n");
+  return 0;
+}