diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2023-02-15 15:07:56 +0100 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2023-02-15 15:07:56 +0100 |
| commit | 1645da679ce50b13b6f19a062eabd2d869762a07 (patch) | |
| tree | 37e19f84000df69bb2a7d88a2f3db800ead6a85a /lib | |
| parent | 3a369468f7daae5b3a60feaa50c6050b240be6d4 (diff) | |
add framebuffer image support
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/fb/fb.c | 128 | ||||
| -rw-r--r-- | lib/fb/fb.h | 26 | ||||
| -rw-r--r-- | lib/ff/ff.c | 73 | ||||
| -rw-r--r-- | lib/ff/ff.h | 25 | ||||
| -rw-r--r-- | lib/sys/creat.h | 2 | ||||
| -rw-r--r-- | lib/sys/ioctl.h | 2 | ||||
| -rw-r--r-- | lib/sys/mkdir.h | 2 | ||||
| -rw-r--r-- | lib/sys/mknod.h | 2 | ||||
| -rw-r--r-- | lib/sys/mmap.h | 10 | ||||
| -rw-r--r-- | lib/sys/mount.h | 2 | ||||
| -rw-r--r-- | lib/sys/read.h | 3 | ||||
| -rw-r--r-- | lib/sys/rmdir.h | 2 | ||||
| -rw-r--r-- | lib/sys/sync.h | 2 | ||||
| -rw-r--r-- | lib/sys/syscalls.h | 2 | ||||
| -rw-r--r-- | lib/sys/types.h | 21 | ||||
| -rw-r--r-- | lib/sys/unlink.h | 2 | ||||
| -rw-r--r-- | lib/sys/unmount.h | 2 | ||||
| -rw-r--r-- | lib/sys/wait4.h | 6 |
18 files changed, 296 insertions, 16 deletions
diff --git a/lib/fb/fb.c b/lib/fb/fb.c new file mode 100644 index 0000000..aabe86e --- /dev/null +++ b/lib/fb/fb.c @@ -0,0 +1,128 @@ +#include "fb.h" + +#include "../sys/mmap.h" +#include "../sys/munmap.h" +#include "../io/io.h" +#include "../sys/ioctl.h" +#include "../sys/errno.h" + +#define FBIOGET_VSCREENINFO 0x4600 +#define FBIOGET_FSCREENINFO 0x4602 + +typedef struct { + char id[16]; + unsigned long smem_start; + u32 smem_len; + u32 type; + u32 type_aux; + u32 visual; + u16 xpanstep; + u16 ypanstep; + u16 ywrapstep; + u32 line_length; + unsigned long mmio_start; + u32 mmio_len; + u32 accel; + u16 capabilities; + u16 reserved[2]; +} fb_fscreeninfo_t; + +typedef struct { + u32 offset; + u32 length; + u32 msb_right; +} fb_bitfield_t; + +typedef struct { + u32 xres; + u32 yres; + u32 xres_virtual; + u32 yres_virtual; + u32 xoffset; + u32 yoffset; + + u32 bits_per_pixel; + u32 grayscale; + + fb_bitfield_t red; + fb_bitfield_t green; + fb_bitfield_t blue; + fb_bitfield_t transp; + + u32 nonstd; + + u32 activate; + + u32 height; + u32 width; + + u32 accel_flags; + + u32 pixclock; + u32 left_margin; + u32 right_margin; + u32 upper_margin; + u32 lower_margin; + u32 hsync_len; + u32 vsync_len; + u32 sync; + u32 vmode; + u32 rotate; + u32 colorspace; + u32 reserved[4]; +} fb_vscreeninfo_t; + +int fbfd = 0; + + +canvas_t open_framebuffer() +{ + fb_vscreeninfo_t vinfo; + fb_fscreeninfo_t finfo; + canvas_t canvas = { 0, 0, 0 }; + + fbfd = open("/system/devices/fb0", OPEN_READ_WRITE, 0); + + if (fbfd < 0) + return canvas; + + + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) != 0) + return canvas; + + if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) != 0) + return canvas; + + canvas.width = vinfo.xres; + canvas.height = vinfo.yres; + canvas.bits_per_pixel = vinfo.bits_per_pixel; + canvas.line_length = finfo.line_length; + + canvas.data = (canvas_pixel_t*)mmap(0, sizeof(u32) * canvas.width * canvas.height, + PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); + + if ((i64)canvas.data < 0) { + wff(STDERR_FD, "error: %s\n", errstr[-(i64)canvas.data]); + canvas.data = 0; + canvas.width = 0; + canvas.height = 0; + return canvas; + } + + return canvas; +} + + +void close_framebuffer(canvas_t canvas) +{ + munmap(canvas.data, sizeof(u32) * canvas.width * canvas.height); + close(fbfd); +} + + +void put_pixel(canvas_t canvas, u64 x, u64 y, canvas_pixel_t p) +{ + char *pos = (char*)canvas.data; + pos += (x * canvas.bits_per_pixel / 8) + (y * canvas.line_length); + *((canvas_pixel_t*) pos) = p; +} diff --git a/lib/fb/fb.h b/lib/fb/fb.h new file mode 100644 index 0000000..a11f29f --- /dev/null +++ b/lib/fb/fb.h @@ -0,0 +1,26 @@ +#ifndef FB_H +#define FB_H + +#include "../sys/types.h" + +typedef struct { + u8 b; + u8 g; + u8 r; + u8 a; +} canvas_pixel_t; + +typedef struct { + u32 width; + u32 height; + canvas_pixel_t *data; + u32 line_length; + u32 bits_per_pixel; +} canvas_t; + +canvas_t open_framebuffer(); +void close_framebuffer(canvas_t); + +void put_pixel(canvas_t canvas, u64 x, u64 y, canvas_pixel_t p); + +#endif diff --git a/lib/ff/ff.c b/lib/ff/ff.c new file mode 100644 index 0000000..aa85073 --- /dev/null +++ b/lib/ff/ff.c @@ -0,0 +1,73 @@ +#include "ff.h" +#include "../io/io.h" +#include "../cstr/cstr.h" +#include "../malloc/malloc.h" + +#define MAGIC_VALUE "farbfeld" + +u32 conv_to_int(u32 src) +{ + return ((src & 0xff) << 24) | ((src & 0xff00) << 8) | ((src & 0xff0000) >> 8) | ((src & 0xff000000) >> 24); +} + +u32 read_u32_from_fd(int fd) +{ + u32 src; + read(fd, (char *)&src, 4); + + return ((src & 0xff) << 24) | ((src & 0xff00) << 8) | ((src & 0xff0000) >> 8) | ((src & 0xff000000) >> 24); +} + + +image_t *new_image_from_fd(int fd) +{ + image_t *img = malloc(sizeof(image_t)); + char magic[9] = { 0 }; + + read(fd, magic, 8); + + if (cstr_compare(magic, MAGIC_VALUE) != 0) { + free(img); + return 0; + } + + img->width = read_u32_from_fd(fd); + img->height = read_u32_from_fd(fd); + + if (img->width * img->height == 0) { + free(img); + return 0; + } + + img->data = malloc(sizeof(image_pixel_t) * img->width * img->height); + u64 s = 0; + u64 rs = 0; + while ((rs = read(fd, (char*)(img->data) + s, sizeof(image_pixel_t) * img->width * img->height - s))) { + s += rs; + } + + return img; +} + + +void free_image(image_t *img) +{ + free(img->data); + free(img); +} + +canvas_pixel_t image_pixel_to_canvas_pixel(image_pixel_t p) +{ + canvas_pixel_t cp; + + cp.r = p.r; + cp.g = p.g; + cp.b = p.b; + cp.a = p.a; + + cp.r = (long double)(cp.r) * ((long double)(p.a) / 0xffff); + cp.g = (long double)(cp.g) * ((long double)(p.a) / 0xffff); + cp.b = (long double)(cp.b) * ((long double)(p.a) / 0xffff); + + return cp; +} diff --git a/lib/ff/ff.h b/lib/ff/ff.h new file mode 100644 index 0000000..756bd16 --- /dev/null +++ b/lib/ff/ff.h @@ -0,0 +1,25 @@ +#ifndef FARBFELD_H +#define FARBFELD_H + +#include "../sys/sizes.h" +#include "../fb/fb.h" + +typedef struct { + u16 r; + u16 g; + u16 b; + u16 a; +} image_pixel_t; + +typedef struct { + u32 width; + u32 height; + image_pixel_t *data; +} image_t; + + +image_t *new_image_from_fd(int fd); +void free_image(image_t*); +canvas_pixel_t image_pixel_to_canvas_pixel(image_pixel_t p); + +#endif diff --git a/lib/sys/creat.h b/lib/sys/creat.h index 9c6e492..b8c4650 100644 --- a/lib/sys/creat.h +++ b/lib/sys/creat.h @@ -3,7 +3,7 @@ #include "syscalls.h" -int creat(const char *pathname, unsigned int mode) +static int creat(const char *pathname, unsigned int mode) { return syscall(CREAT, pathname, mode); } diff --git a/lib/sys/ioctl.h b/lib/sys/ioctl.h index 4bf73f7..b3358d4 100644 --- a/lib/sys/ioctl.h +++ b/lib/sys/ioctl.h @@ -3,7 +3,7 @@ #include "syscalls.h" -int ioctl(unsigned int fd, unsigned int cmd, void *arg) +static int ioctl(unsigned int fd, unsigned int cmd, void *arg) { return syscall(IOCTL, fd, cmd, arg); } diff --git a/lib/sys/mkdir.h b/lib/sys/mkdir.h index 2de3b01..2505c97 100644 --- a/lib/sys/mkdir.h +++ b/lib/sys/mkdir.h @@ -3,7 +3,7 @@ #include "syscalls.h" -int mkdir(const char *pathname, unsigned int mode) +static int mkdir(const char *pathname, unsigned int mode) { return syscall(MKDIR, pathname, mode); } diff --git a/lib/sys/mknod.h b/lib/sys/mknod.h index b51c4ef..89efad9 100644 --- a/lib/sys/mknod.h +++ b/lib/sys/mknod.h @@ -5,7 +5,7 @@ #include "types.h" -int mknod(const char *filename, mode_t mode, unsigned int dev) +static int mknod(const char *filename, mode_t mode, unsigned int dev) { return syscall(MKNOD, filename, mode, dev); } diff --git a/lib/sys/mmap.h b/lib/sys/mmap.h index d555e68..f16493e 100644 --- a/lib/sys/mmap.h +++ b/lib/sys/mmap.h @@ -1,6 +1,7 @@ #ifndef MMAP_H #define MMAP_H #include "syscalls.h" +#include "sizes.h" #define PROT_READ 0x1 #define PROT_WRITE 0x2 @@ -10,9 +11,14 @@ #define MAP_SHARED 0x1 #define MAP_PRIVATE 0x2 -static void * mmap(void * addr, unsigned long size, int prot, int flags, int fd, int offset) +static void *mmap(void * addr, u64 size, u64 prot, u64 flags, u64 fd, u64 offset) { - return syscall(MMAP, size, prot, flags, fd, offset); + __asm__( + "mov $9, %rax\n" + "mov %rcx, %r10\n" + "syscall\n" + ); + //return syscall(MMAP, addr, size, prot, flags, fd, offset); } #endif diff --git a/lib/sys/mount.h b/lib/sys/mount.h index 6451b22..a5dd505 100644 --- a/lib/sys/mount.h +++ b/lib/sys/mount.h @@ -3,7 +3,7 @@ #include "syscalls.h" -int mount(const char *src, const char *target, const char *type, unsigned long flags, const void *data) +static int mount(const char *src, const char *target, const char *type, unsigned long flags, const void *data) { return syscall(MOUNT, src, target, type, flags, data); } diff --git a/lib/sys/read.h b/lib/sys/read.h index 61e5576..b7d0851 100644 --- a/lib/sys/read.h +++ b/lib/sys/read.h @@ -1,8 +1,9 @@ #ifndef READ_H #define READ_H #include "syscalls.h" +#include "sizes.h" -static int read(unsigned int fd, char * buf, unsigned long count) +static u64 read(unsigned int fd, char * buf, unsigned long count) { return syscall(READ, fd, buf, count, 0, 0); } diff --git a/lib/sys/rmdir.h b/lib/sys/rmdir.h index 1656ee9..70712c1 100644 --- a/lib/sys/rmdir.h +++ b/lib/sys/rmdir.h @@ -3,7 +3,7 @@ #include "syscalls.h" -int rmdir(const char *pathname) +static int rmdir(const char *pathname) { return syscall(RMDIR, pathname); } diff --git a/lib/sys/sync.h b/lib/sys/sync.h index fe61454..0039801 100644 --- a/lib/sys/sync.h +++ b/lib/sys/sync.h @@ -3,7 +3,7 @@ #include "syscalls.h" -void sync() +static void sync() { syscall(SYNC); } diff --git a/lib/sys/syscalls.h b/lib/sys/syscalls.h index 50e8a4f..4b1341a 100644 --- a/lib/sys/syscalls.h +++ b/lib/sys/syscalls.h @@ -7,7 +7,7 @@ __asm__ ( "mov %rsi, %rdi\n" "mov %rdx, %rsi\n" "mov %rcx, %rdx\n" - "mov %r8, %rcx\n" + "mov %r8, %r10\n" "mov %r9, %r8\n" "mov 8(%rsp), %r9\n" "syscall\n" diff --git a/lib/sys/types.h b/lib/sys/types.h index de8ce80..f9e3440 100644 --- a/lib/sys/types.h +++ b/lib/sys/types.h @@ -2,12 +2,32 @@ #define TYPES_H #include "sizes.h" +#include "time.h" #define BUFSIZ 16384 typedef u64 dev_t; typedef u32 mode_t; +struct rusage { + struct timespec ru_utime; + struct timespec ru_stime; + long int ru_maxrss; + long int ru_ixrss; + long int ru_idrss; + long int ru_isrss; + long int ru_minflt; + long int ru_majflt; + long int ru_nswap; + long int ru_inblock; + long int ru_oublock; + long int ru_msgsnd; + long int ru_msgrcv; + long int ru_nsignals; + long int ru_nvcsw; + long int ru_nivcsw; +}; + static dev_t inline device(dev_t major, dev_t minor) { dev_t dev; @@ -18,4 +38,5 @@ static dev_t inline device(dev_t major, dev_t minor) return dev; } + #endif diff --git a/lib/sys/unlink.h b/lib/sys/unlink.h index a0f66e3..7a143b0 100644 --- a/lib/sys/unlink.h +++ b/lib/sys/unlink.h @@ -3,7 +3,7 @@ #include "syscalls.h" -int unlink(const char *pathname) +static int unlink(const char *pathname) { return syscall(UNLINK, pathname); } diff --git a/lib/sys/unmount.h b/lib/sys/unmount.h index 1331e65..808c774 100644 --- a/lib/sys/unmount.h +++ b/lib/sys/unmount.h @@ -3,7 +3,7 @@ #include "syscalls.h" -int unmount(char *pathname, int flags) +static int unmount(char *pathname, int flags) { return syscall(UMOUNT2, pathname, flags); } diff --git a/lib/sys/wait4.h b/lib/sys/wait4.h index e70539e..673d259 100644 --- a/lib/sys/wait4.h +++ b/lib/sys/wait4.h @@ -2,11 +2,11 @@ #define WAIT4_H #include "syscall.h" -#include "sizes.h" +#include "types.h" -int wait4(u64 pid, int *stat_addr, int options) +static int wait4(u64 pid, int *stat_addr, int options, struct rusage *usage) { - return syscall(WAIT4, pid, stat_addr, options); + return syscall(WAIT4, pid, stat_addr, options, usage); } #endif |