diff options
Diffstat (limited to 'fbgl.h')
| -rw-r--r-- | fbgl.h | 137 |
1 files changed, 135 insertions, 2 deletions
@@ -15,6 +15,10 @@ #include <linux/fb.h> #include <stddef.h> #include <stdio.h> +#include <termios.h> +#include <signal.h> + +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 <linux/kd.h> +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 |
