Major refactoring of old library...

This commit is contained in:
xolatile 2024-09-01 00:29:59 -04:00
parent 693b765bfe
commit 1276db79b0
7 changed files with 179 additions and 221 deletions

0
LICENSE Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

2
compile.sh Normal file → Executable file
View File

@ -2,6 +2,6 @@
set -xe
gcc -g -ansi -Wall -Wextra -Wpedantic -Werror -Ofast -c -o xlesses.o xlesses.c
gcc -g -ansi -Wall -Wextra -Wpedantic -Werror -c -o xlesses.o xlesses.c
exit

13
example/blank.c Normal file
View File

@ -0,0 +1,13 @@
#include <xolatile/xlesses.c>
int main (void) {
xlesses_configure (640, 480, "Heyo world!");
while (xlesses_active == true) {
xlesses_render_background_colour (0xff00ff);
xlesses_synchronize ();
}
return (log_success);
}

8
install.sh Normal file → Executable file
View File

@ -2,10 +2,10 @@
set -xe
mkdir -p /usr/include/xolatile
mkdir -p /usr/local/include/xolatile
cp xlesses.h /usr/include/xolatile/xlesses.h
cp xlesses.c /usr/include/xolatile/xlesses.c
cp xlesses.o /usr/include/xolatile/xlesses.o
cp xlesses.h /usr/local/include/xolatile/xlesses.h
cp xlesses.c /usr/local/include/xolatile/xlesses.c
cp xlesses.o /usr/local/include/xolatile/xlesses.o
exit

313
xlesses.c Normal file → Executable file
View File

@ -1,132 +1,112 @@
/*
Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic
Xlesses is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
*/
#ifndef XLESSES_SOURCE
#define XLESSES_SOURCE
#ifndef xlesses_source
#define xlesses_source
#include <xolatile/xtandard.c>
#include <xolatile/xlesses.h>
char * blesses_window_title = "xolatile";
int blesses_window_width = 1800;
int blesses_window_height = 900;
int blesses_active = 1;
int blesses_cursor_x = 0;
int blesses_cursor_y = 0;
int blesses_signal = 0;
int * blesses_sub_framebuffer = NULL;
int * blesses_framebuffer = NULL;
#include <xcb/xcb.h>
#include <xcb/xcb_atom.h>
#include <xcb/xcb_image.h>
void (* blesses_action [BLESSES_SIGNAL_COUNT]) (void) = { NULL };
xcb_window_t blesses_window = 0;
xcb_gcontext_t blesses_context = 0;
xcb_pixmap_t blesses_pixmap = 0;
xcb_connection_t * blesses_connection = NULL;
xcb_screen_t * blesses_screen = NULL;
xcb_image_t * blesses_image = NULL;
void blesses_initialize (void) {
unsigned int window_flags [2] = {
0,
XCB_EVENT_MASK_NO_EVENT |
XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_RESIZE_REDIRECT |
XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_BUTTON_RELEASE |
XCB_EVENT_MASK_BUTTON_PRESS
};
unsigned short int window_width = (unsigned short int) blesses_window_width;
unsigned short int window_height = (unsigned short int) blesses_window_height;
blesses_connection = xcb_connect (NULL, NULL);
log_in (LOG_FAILURE, blesses_connection == NULL, "blesses : blesses_initialize : XCB connection is null pointer.");
blesses_screen = xcb_setup_roots_iterator (xcb_get_setup (blesses_connection)).data;
blesses_window = xcb_generate_id (blesses_connection);
blesses_context = xcb_generate_id (blesses_connection);
blesses_pixmap = xcb_generate_id (blesses_connection);
window_flags [0] = blesses_screen->black_pixel;
xcb_create_window (blesses_connection, blesses_screen->root_depth, blesses_window, blesses_screen->root, 0, 0, window_width, window_height, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT,
blesses_screen->root_visual, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, window_flags);
xcb_map_window (blesses_connection, blesses_window);
xcb_change_property (blesses_connection, XCB_PROP_MODE_REPLACE, blesses_window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, string_length (blesses_window_title), blesses_window_title);
xcb_create_pixmap (blesses_connection, blesses_screen->root_depth, blesses_pixmap, blesses_window, window_width, window_height);
xcb_create_gc (blesses_connection, blesses_context, blesses_pixmap, 0, NULL);
xcb_flush (blesses_connection);
/*blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer) / 4);*/
blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer));
blesses_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_framebuffer));
log_out ("./blesses.log");
}
void blesses_deinitialize (void) {
blesses_sub_framebuffer = deallocate (blesses_sub_framebuffer);
blesses_framebuffer = deallocate (blesses_framebuffer);
xcb_free_gc (blesses_connection, blesses_context);
xcb_free_pixmap (blesses_connection, blesses_pixmap);
xcb_destroy_window (blesses_connection, blesses_window);
xcb_disconnect (blesses_connection);
}
void blesses_synchronize (void) {
int i = 0;
xcb_generic_event_t * generic_event = NULL;
#define xlesses_font_width (8)
#define xlesses_font_height (8)
#define xlesses_font_tabulator (4)
/*
for (i = 0; i != blesses_window_width * blesses_window_height; i++) {
blesses_framebuffer [i] = blesses_sub_framebuffer [((i / blesses_window_width) / 2) * (blesses_window_width / 2) + (i % blesses_window_width) / 2];
}
static void (* xlesses_action [signal_count]) (void) = { null };
*/
for (i = 0; i != blesses_window_width * blesses_window_height; i++) {
blesses_framebuffer [i] = blesses_sub_framebuffer [i];
static xcb_window_t xlesses_window = 0;
static xcb_gcontext_t xlesses_context = 0;
static xcb_pixmap_t xlesses_pixmap = 0;
static xcb_connection_t * xlesses_connection = null;
static xcb_screen_t * xlesses_screen = null;
static xcb_image_t * xlesses_image = null;
int xlesses_active = false;
int xlesses_window_width = 0;
int xlesses_window_height = 0;
int xlesses_cursor_x = 0;
int xlesses_cursor_y = 0;
int xlesses_signal = 0;
int * xlesses_framebuffer = null;
static void xlesses (void) {
xlesses_framebuffer = deallocate (xlesses_framebuffer);
xcb_free_gc (xlesses_connection, xlesses_context);
xcb_free_pixmap (xlesses_connection, xlesses_pixmap);
xcb_destroy_window (xlesses_connection, xlesses_window);
xcb_disconnect (xlesses_connection);
}
static int xlesses_screen_length (void) {
return (xlesses_window_width * xlesses_window_height * (int) sizeof (* xlesses_framebuffer));
}
void xlesses_configure (int width, int height, char * title) {
unsigned int window_flags [2];
if (xlesses_active == true) {
return;
} else {
clean_up (xlesses);
}
blesses_sub_framebuffer = deallocate (blesses_sub_framebuffer);
xlesses_window_width = width;
xlesses_window_height = height;
blesses_image = xcb_image_create_native (blesses_connection, blesses_window_width, blesses_window_height, XCB_IMAGE_FORMAT_Z_PIXMAP, blesses_screen->root_depth,
blesses_framebuffer, (unsigned int) (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_framebuffer)),
(unsigned char *) blesses_framebuffer);
xlesses_connection = xcb_connect (null, null);
xcb_image_put (blesses_connection, blesses_pixmap, blesses_context, blesses_image, 0, 0, 0);
xlesses_screen = xcb_setup_roots_iterator (xcb_get_setup (xlesses_connection)).data;
xcb_image_destroy (blesses_image);
xlesses_window = xcb_generate_id (xlesses_connection);
xlesses_context = xcb_generate_id (xlesses_connection);
xlesses_pixmap = xcb_generate_id (xlesses_connection);
xcb_copy_area (blesses_connection, blesses_pixmap, blesses_window, blesses_context, 0, 0, 0, 0, blesses_window_width, blesses_window_height);
window_flags [0] = xlesses_screen->black_pixel;
window_flags [1] = XCB_EVENT_MASK_NO_EVENT |
XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_RESIZE_REDIRECT |
XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_BUTTON_RELEASE |
XCB_EVENT_MASK_BUTTON_PRESS;
blesses_framebuffer = NULL;
xcb_create_window (xlesses_connection, xlesses_screen->root_depth, xlesses_window, xlesses_screen->root, 0, 0,
(unsigned short int) width, (unsigned short int) height, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT,
xlesses_screen->root_visual, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, window_flags);
generic_event = xcb_wait_for_event (blesses_connection);
xcb_map_window (xlesses_connection, xlesses_window);
xcb_change_property (xlesses_connection, XCB_PROP_MODE_REPLACE, xlesses_window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8,
string_length (title), title);
xcb_create_pixmap (xlesses_connection, xlesses_screen->root_depth, xlesses_pixmap, xlesses_window, (unsigned short int) width,
(unsigned short int) height);
xcb_create_gc (xlesses_connection, xlesses_context, xlesses_pixmap, 0, null);
xcb_flush (xlesses_connection);
xlesses_active = true;
}
void xlesses_synchronize (void) {
xcb_generic_event_t * generic_event;
if (xlesses_active == false) {
return;
}
generic_event = xcb_wait_for_event (xlesses_connection);
switch (generic_event->response_type & 127) {
case XCB_EXPOSE: {
xcb_flush (blesses_connection);
xcb_flush (xlesses_connection);
} break;
case XCB_KEY_PRESS: {
blesses_signal = (int) ((xcb_key_press_event_t *) generic_event)->detail;
if (blesses_signal == 24) {
blesses_active = 0;
xlesses_signal = (int) ((xcb_key_press_event_t *) generic_event)->detail;
if (xlesses_signal == 24) {
xlesses_active = false;
}
} break;
default: {
@ -135,83 +115,82 @@ void blesses_synchronize (void) {
generic_event = deallocate (generic_event);
if ((blesses_sub_framebuffer == NULL) && (blesses_framebuffer == NULL)) {
/*blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer) / 4);*/
blesses_sub_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_sub_framebuffer));
blesses_framebuffer = allocate (blesses_window_width * blesses_window_height * (int) sizeof (* blesses_framebuffer));
if (xlesses_framebuffer == null) {
return;
}
log_out ("./blesses.log");
xlesses_image = xcb_image_create_native (xlesses_connection, xlesses_window_width, xlesses_window_height, XCB_IMAGE_FORMAT_Z_PIXMAP,
xlesses_screen->root_depth, xlesses_framebuffer, (unsigned int) (xlesses_screen_length ()),
(unsigned char *) xlesses_framebuffer);
xcb_image_put (xlesses_connection, xlesses_pixmap, xlesses_context, xlesses_image, 0, 0, 0);
xcb_image_destroy (xlesses_image);
xcb_copy_area (xlesses_connection, xlesses_pixmap, xlesses_window, xlesses_context, 0, 0, 0, 0, xlesses_window_width,
xlesses_window_height);
xlesses_framebuffer = allocate (xlesses_screen_length ());
}
void blesses_render_background_colour (int colour) {
void xlesses_render_background_colour (int colour) {
int x, y;
for (y = 0; y != blesses_window_height/* / 2*/; ++y) {
for (x = 0; x != blesses_window_width/* / 2*/; ++x) {
blesses_sub_framebuffer [y * (blesses_window_width/* / 2*/) + x] = 0XFF000000 | colour;
if ((xlesses_framebuffer == null) || (xlesses_active == false)) {
return;
}
for (y = 0; y != xlesses_window_height; ++y) {
for (x = 0; x != xlesses_window_width; ++x) {
xlesses_framebuffer [y * (xlesses_window_width) + x] = 0xff000000 | colour;
}
}
}
void blesses_render_character (char character, int x, int y, int foreground, int background) {
void xlesses_render_character (char character, int foreground, int background, int x, int y) {
const unsigned long int font_code ['~' - ' ' + 2] = {
0X0000000000000000, 0X00180018183C3C18, 0X0000000000363636, 0X006C6CFE6CFE6C6C, 0X00187ED07C16FC30, 0X0060660C18306606, 0X00DC66B61C36361C, 0X0000000000181818,
0X0030180C0C0C1830, 0X000C18303030180C, 0X0000187E3C7E1800, 0X000018187E181800, 0X0C18180000000000, 0X000000007E000000, 0X0018180000000000, 0X0000060C18306000,
0X003C666E7E76663C, 0X007E181818181C18, 0X007E0C183060663C, 0X003C66603860663C, 0X0030307E363C3830, 0X003C6660603E067E, 0X003C66663E060C38, 0X000C0C0C1830607E,
0X003C66663C66663C, 0X001C30607C66663C, 0X0018180018180000, 0X0C18180018180000, 0X0030180C060C1830, 0X0000007E007E0000, 0X000C18306030180C, 0X001800181830663C,
0X003C06765676663C, 0X006666667E66663C, 0X003E66663E66663E, 0X003C66060606663C, 0X001E36666666361E, 0X007E06063E06067E, 0X000606063E06067E, 0X003C66667606663C,
0X006666667E666666, 0X007E18181818187E, 0X001C36303030307C, 0X0066361E0E1E3666, 0X007E060606060606, 0X00C6C6D6D6FEEEC6, 0X006666767E6E6666, 0X003C66666666663C,
0X000606063E66663E, 0X006C36566666663C, 0X006666363E66663E, 0X003C66603C06663C, 0X001818181818187E, 0X003C666666666666, 0X00183C6666666666, 0X00C6EEFED6D6C6C6,
0X0066663C183C6666, 0X001818183C666666, 0X007E060C1830607E, 0X003E06060606063E, 0X00006030180C0600, 0X007C60606060607C, 0X000000000000663C, 0XFFFF000000000000,
0X000000000030180C, 0X007C667C603C0000, 0X003E6666663E0606, 0X003C6606663C0000, 0X007C6666667C6060, 0X003C067E663C0000, 0X000C0C0C3E0C0C38, 0X3C607C66667C0000,
0X00666666663E0606, 0X003C1818181C0018, 0X0E181818181C0018, 0X0066361E36660606, 0X003C18181818181C, 0X00C6D6D6FE6C0000, 0X00666666663E0000, 0X003C6666663C0000,
0X06063E66663E0000, 0XE0607C66667C0000, 0X000606066E360000, 0X003E603C067C0000, 0X00380C0C0C3E0C0C, 0X007C666666660000, 0X00183C6666660000, 0X006CFED6D6C60000,
0X00663C183C660000, 0X3C607C6666660000, 0X007E0C18307E0000, 0X003018180E181830, 0X0018181818181818, 0X000C18187018180C, 0X000000000062D68C, 0X0000000000000000
0x0000000000000000, 0x00180018183c3c18, 0x0000000000363636, 0x006c6cfe6cfe6c6c,
0x00187ed07c16fc30, 0x0060660c18306606, 0x00dc66b61c36361c, 0x0000000000181818,
0x0030180c0c0c1830, 0x000c18303030180c, 0x0000187e3c7e1800, 0x000018187e181800,
0x0c18180000000000, 0x000000007e000000, 0x0018180000000000, 0x0000060c18306000,
0x003c666e7e76663c, 0x007e181818181c18, 0x007e0c183060663c, 0x003c66603860663c,
0x0030307e363c3830, 0x003c6660603e067e, 0x003c66663e060c38, 0x000c0c0c1830607e,
0x003c66663c66663c, 0x001c30607c66663c, 0x0018180018180000, 0x0c18180018180000,
0x0030180c060c1830, 0x0000007e007e0000, 0x000c18306030180c, 0x001800181830663c,
0x003c06765676663c, 0x006666667e66663c, 0x003e66663e66663e, 0x003c66060606663c,
0x001e36666666361e, 0x007e06063e06067e, 0x000606063e06067e, 0x003c66667606663c,
0x006666667e666666, 0x007e18181818187e, 0x001c36303030307c, 0x0066361e0e1e3666,
0x007e060606060606, 0x00c6c6d6d6feeec6, 0x006666767e6e6666, 0x003c66666666663c,
0x000606063e66663e, 0x006c36566666663c, 0x006666363e66663e, 0x003c66603c06663c,
0x001818181818187e, 0x003c666666666666, 0x00183c6666666666, 0x00c6eefed6d6c6c6,
0x0066663c183c6666, 0x001818183c666666, 0x007e060c1830607e, 0x003e06060606063e,
0x00006030180c0600, 0x007c60606060607c, 0x000000000000663c, 0xffff000000000000,
0x000000000030180c, 0x007c667c603c0000, 0x003e6666663e0606, 0x003c6606663c0000,
0x007c6666667c6060, 0x003c067e663c0000, 0x000c0c0c3e0c0c38, 0x3c607c66667c0000,
0x00666666663e0606, 0x003c1818181c0018, 0x0e181818181c0018, 0x0066361e36660606,
0x003c18181818181c, 0x00c6d6d6fe6c0000, 0x00666666663e0000, 0x003c6666663c0000,
0x06063e66663e0000, 0xe0607c66667c0000, 0x000606066e360000, 0x003e603c067c0000,
0x00380c0c0c3e0c0c, 0x007c666666660000, 0x00183c6666660000, 0x006cfed6d6c60000,
0x00663c183c660000, 0x3c607c6666660000, 0x007e0c18307e0000, 0x003018180e181830,
0x0018181818181818, 0x000c18187018180c, 0x000000000062d68c, 0x0000000000000000
};
int offset;
if ((x <= -1) || (x >= blesses_window_width/* / 2*/ - BLESSES_FONT_WIDTH)) return;
if ((y <= -1) || (y >= blesses_window_height/* / 2*/ - BLESSES_FONT_HEIGHT)) return;
log_in (LOG_WARNING, blesses_sub_framebuffer == NULL, "blesses : render_character : Sub framebuffer was not allocated.");
log_in (LOG_WARNING, blesses_framebuffer == NULL, "blesses : render_character : Framebuffer was not allocated.");
log_in (LOG_WARNING, character_is_invisible (character), "blesses : render_character : Character is not in visible ASCII range.");
log_in (LOG_WARNING, x <= -1, "blesses : render_character : X position is under lower limit.");
log_in (LOG_WARNING, y <= -1, "blesses : render_character : Y position is under lower limit.");
log_in (LOG_WARNING, x >= blesses_window_width - BLESSES_FONT_WIDTH, "blesses : render_character : X position is above upper limit.");
log_in (LOG_WARNING, y >= blesses_window_height - BLESSES_FONT_HEIGHT, "blesses : render_character : Y position is above upper limit.");
for (offset = 0; offset != BLESSES_FONT_WIDTH * BLESSES_FONT_HEIGHT; ++offset) {
int u = offset / BLESSES_FONT_WIDTH + y;
int v = offset % BLESSES_FONT_WIDTH + x;
blesses_sub_framebuffer [u * (blesses_window_width/* / 2*/) + v] = ((font_code [(int) (character - ' ')] >> offset) % 2) ? foreground : background;
if ((xlesses_active == false)
|| ((x < 0) || (x > xlesses_window_width - xlesses_font_width - 1))
|| ((y < 0) || (y > xlesses_window_height - xlesses_font_height - 1))) {
return;
}
log_out ("./blesses.log");
}
for (offset = 0; offset != xlesses_font_width * xlesses_font_height; ++offset) {
int u = offset / xlesses_font_width + y;
int v = offset % xlesses_font_width + x;
void blesses_render_string_limit (char * string, int limit, int * x, int * y, int foreground, int background) {
int offset;
int code = (font_code [(int) (character - ' ')] >> offset) & 1;
for (offset = 0; offset != limit; ++offset) {
if (string [offset] == '\t') {
* x += BLESSES_FONT_WIDTH * BLESSES_FONT_TABULATOR;
} else if (string [offset] == '\n') {
* y += BLESSES_FONT_HEIGHT;
* x *= 0;
} else {
blesses_render_character (string [offset], * x, * y, foreground, background);
* x += BLESSES_FONT_WIDTH;
}
xlesses_framebuffer [u * (xlesses_window_width) + v] = (code) ? foreground : background;
}
}
void blesses_render_string (char * string, int * x, int * y, int foreground, int background) {
blesses_render_string_limit (string, string_length (string), x, y, foreground, background);
}
#endif

64
xlesses.h Normal file → Executable file
View File

@ -1,55 +1,21 @@
/*
Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic
#ifndef xlesses_header
#define xlesses_header
Xlesses is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
*/
extern int xlesses_active;
extern int xlesses_window_width;
extern int xlesses_window_height;
extern int xlesses_cursor_x;
extern int xlesses_cursor_y;
extern int xlesses_signal;
extern int * xlesses_framebuffer;
#ifndef XLESSES_HEADER
#define XLESSES_HEADER
extern void xlesses_configure (int width, int height, char * title);
extern void xlesses_synchronize (void);
#include <xolatile/xtandard.h>
extern void xlesses_render_background_colour (int colour);
#include <xcb/xcb.h>
#include <xcb/xcb_atom.h>
#include <xcb/xcb_image.h>
#define BLESSES_FONT_WIDTH (8)
#define BLESSES_FONT_HEIGHT (8)
#define BLESSES_FONT_TABULATOR (4)
#define BLESSES_SIGNAL_COUNT (144)
extern char * blesses_window_title;
extern int blesses_window_width;
extern int blesses_window_height;
extern int blesses_active;
extern int blesses_cursor_x;
extern int blesses_cursor_y;
extern int blesses_signal;
extern int * blesses_sub_framebuffer;
extern int * blesses_framebuffer;
extern void (* blesses_action [BLESSES_SIGNAL_COUNT]) (void);
extern xcb_window_t blesses_window;
extern xcb_gcontext_t blesses_context;
extern xcb_pixmap_t blesses_pixmap;
extern xcb_connection_t * blesses_connection;
extern xcb_screen_t * blesses_screen;
extern xcb_image_t * blesses_image;
extern void blesses_initialize (void);
extern void blesses_deinitialize (void);
extern void blesses_synchronize (void);
extern void blesses_render_background_colour (int);
extern void blesses_render_character (char, int, int, int, int);
extern void blesses_render_string_limit (char *, int, int *, int *, int, int);
extern void blesses_render_string (char *, int *, int *, int, int);
extern void xlesses_render_character (char character, int foreground, int background, int x, int y);
/*extern void xlesses_render_string (char * string, int foreground, int background, int x, int y);
extern void xlesses_render_string_crop (char * string, int foreground, int background, int x, int y, int crop);*/
#endif