From 0fa46770ba044b95dd8c253b7d1e12ca324e1556 Mon Sep 17 00:00:00 2001 From: lvntky Date: Thu, 21 Nov 2024 19:01:50 +0300 Subject: [feature] basic rendering --- asset/font.psf | Bin 0 -> 29728 bytes example/empty_example | Bin 16128 -> 16824 bytes example/empty_example.c | 22 ++++++-- fbgl.h | 137 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 asset/font.psf diff --git a/asset/font.psf b/asset/font.psf new file mode 100644 index 0000000..071330e Binary files /dev/null and b/asset/font.psf differ diff --git a/example/empty_example b/example/empty_example index 9f9c717..8f1efd7 100755 Binary files a/example/empty_example and b/example/empty_example differ diff --git a/example/empty_example.c b/example/empty_example.c index 81f9c04..85aa2eb 100644 --- a/example/empty_example.c +++ b/example/empty_example.c @@ -1,19 +1,33 @@ #define FBGL_IMPLEMENTATION +//#define FBGL_HIDE_CURSOR #include "../fbgl.h" #include +#include int main() { printf("version %s\n", fbgl_version_info()); printf("name %s\n", fbgl_name_info()); fbgl_t buffer; - if( fbgl_init("/dev/fb0", &buffer) == -1) { - fprintf(stdout, "error could not oppen fb device"); - return -1; + if (fbgl_init("/dev/fb0", &buffer) == -1) { + fprintf(stdout, "error could not oppen fb device"); + return -1; } fbgl_set_bg(&buffer, 0xFF0000); - while(1){} + + for (size_t i = 0; i < 100; ++i) { + for (size_t j = 0; j < 100; ++j) { + fbgl_put_pixel(i, j, 0x00FFFF, &buffer); + } + } + int l = 0; + while (1) { + if(fbgl_check_esc_key()) { + fprintf(stdout, "esc pressed", fbgl_check_esc_key()); + + } + } return 0; } diff --git a/fbgl.h b/fbgl.h index 5d0d8ff..1057501 100644 --- a/fbgl.h +++ b/fbgl.h @@ -15,6 +15,10 @@ #include #include #include +#include +#include + +static struct termios orig_termios; /** * Structs @@ -29,6 +33,35 @@ typedef struct fbgl { struct fb_fix_screeninfo finfo; // Fixed screen information } fbgl_t; +typedef struct fbgl_window { + int x; // Top-left x-coordinate of the window + int y; // Top-left y-coordinate of the window + int width; // Width of the window + int height; // Height of the window + fbgl_t *fb; // Pointer to the framebuffer context +} fbgl_window_t; + +#ifdef FBGL_HIDE_CURSOR +#include +int fbgl_hide_cursor(int fd) +{ + int tty_fd = open("/dev/tty0", O_RDWR); + if (tty_fd == -1) { + perror("Error opening /dev/tty0"); + return -1; + } + + if (ioctl(tty_fd, KDSETMODE, KD_GRAPHICS) == -1) { + perror("Error setting graphics mode"); + close(tty_fd); + return -1; + } + + close(tty_fd); + return 0; +} +#endif //FBGL_HIDE_CURSOR + #ifdef __cplusplus extern "C" { #endif @@ -38,6 +71,11 @@ extern "C" { */ char const *fbgl_name_info(void); char const *fbgl_version_info(void); +void fbgl_enable_raw_mode(); +void fbgl_disable_raw_mode(); +void fbgl_cleanup(int sig); +int fbgl_check_esc_key(); +void fbgl_set_signal_handlers(); /*Create and destroy methods*/ int fbgl_init(const char *device, fbgl_t *fb); @@ -47,7 +85,7 @@ void fbgl_destroy(fbgl_t *fb); * Drawing functions */ void fbgl_clear(uint32_t color); -void fbgl_put_pixel(int x, int y, uint32_t color); +void fbgl_put_pixel(int x, int y, uint32_t color, fbgl_t *fb); void fbgl_draw_line(int x0, int y0, int x1, int y1, uint32_t color); void fbgl_set_bg(); @@ -90,7 +128,8 @@ int fbgl_init(const char *device, fbgl_t *fb) } if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->finfo) == -1) { - perror("Error: Reading fixed information."); close(fb->fd); + perror("Error: Reading fixed information."); + close(fb->fd); return -1; } if (ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vinfo) == -1) { @@ -99,6 +138,12 @@ int fbgl_init(const char *device, fbgl_t *fb) return -1; } +#ifdef FBGL_HIDE_CURSOR +fbgl_hide_cursor(fb->fd); + fbgl_set_signal_handlers(); + fbgl_enable_raw_mode(); +#endif //FBGL_HIDE_CURSOR + fb->width = fb->vinfo.xres; fb->height = fb->vinfo.yres; fb->screen_size = fb->finfo.smem_len; @@ -130,6 +175,10 @@ void fbgl_destroy(fbgl_t *fb) close(fb->fd); fb->fd = -1; + + #ifdef FBGL_HIDE_CURSOR + fbgl_disable_raw_mode(); + #endif // FBGL_HIDE_CURSOR } void fbgl_set_bg(fbgl_t *fb, uint32_t color) @@ -145,6 +194,90 @@ void fbgl_set_bg(fbgl_t *fb, uint32_t color) } } +void fbgl_put_pixel(int x, int y, uint32_t color, fbgl_t *fb) +{ + if (!fb || !fb->pixels) { + fprintf(stderr, "Error: framebuffer not initialized.\n"); + return; + } + + if (x < 0 || x >= fb->width || y < 0 || y >= fb->height) { + return; // Ignore out-of-bound coordinates + } + + size_t index = y * fb->width + x; + fb->pixels[index] = color; + } + + void fbgl_enable_raw_mode() +{ + struct termios raw; + + if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) { + perror("tcgetattr"); + exit(EXIT_FAILURE); + } + raw = orig_termios; + raw.c_lflag &= ~(ECHO | ICANON); + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) { + perror("tcsetattr"); + exit(EXIT_FAILURE); + } +} + +void fbgl_disable_raw_mode() +{ + if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) == -1) { + perror("tcsetattr"); + } +} + +void fbgl_cleanup(int sig) +{ + fbgl_disable_raw_mode(); + printf("\033[2J\033[H"); // Clear the terminal screen and move the cursor to top-left + exit(sig); +} + +int fbgl_check_esc_key() +{ + char c; + struct timeval tv = {0, 0}; + fd_set fds; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + + // Check if there's input available + if (select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv) == -1) { + perror("select"); + return 0; + } + + if (FD_ISSET(STDIN_FILENO, &fds)) { + if (read(STDIN_FILENO, &c, 1) == -1) { + perror("read"); + return 0; + } + return c == 27; // ASCII value of the `Esc` key + } + + return 0; +} + +void fbgl_set_signal_handlers() +{ + struct sigaction sa; + sa.sa_handler = fbgl_cleanup; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + + if (sigaction(SIGINT, &sa, NULL) == -1 || sigaction(SIGTERM, &sa, NULL) == -1) { + perror("sigaction"); + exit(EXIT_FAILURE); + } +} + + #endif #ifdef __cplusplus -- cgit v1.2.3