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; +}