From 2a1142c709bc7795d800f8c3e80ab9851fa8a166 Mon Sep 17 00:00:00 2001 From: itycodes Date: Sun, 26 Mar 2023 00:16:54 +0100 Subject: [PATCH] Initial work on Lua-configured rendering --- compile.sh | 2 +- main.c | 298 ++++++++++++++++++++++++++++++++++++++++++++++------- shell.nix | 5 +- 3 files changed, 267 insertions(+), 38 deletions(-) diff --git a/compile.sh b/compile.sh index fe986e3..6b2ca53 100755 --- a/compile.sh +++ b/compile.sh @@ -1,2 +1,2 @@ #!/usr/bin/env bash -gcc `pkg-config --cflags --libs cairo x11` -w -g -lpthread main.c -o main.o +gcc `pkg-config --cflags --libs cairo x11 lua` -w -g -lpthread main.c -o main.o diff --git a/main.c b/main.c index 921567b..4915f02 100644 --- a/main.c +++ b/main.c @@ -12,7 +12,7 @@ */ // -------------- -// TextBar v0.1.2 +// LuaBar v0.2.0 // -------------- // Usage: | textbar | // @@ -23,6 +23,10 @@ // Line buffered // Prints all mouse clicks to stdout // In the format of `X Y` (without the '`') +// Rendering handled by config.lua +// File dofile'd every render +// Called as draw(ctx, width, text_conf, text, text_other) +// Some cairo bindings provided (see below) #include @@ -42,14 +46,22 @@ #include #include +#include +#include +#include + Display* dpy; +lua_State *lua; Window win; cairo_surface_t* sfc; -cairo_surface_t* sfc2; cairo_t* ctx; -cairo_t* ctx2; char text[256] = {0}; char text_other[256] = {0}; +char text_other2[256] = {0}; +char text_conf[256] = {0}; +float b_col_r = 0.157; +float b_col_g = 0.165; +float b_col_b = 0.212; int width; @@ -57,13 +69,198 @@ int width; #define POSITION 0 // 1 means top, 0 means bottom. Blame C. #define FONT "Fira Code" #define FONT_SIZE 16 -#define BG_COLOR 0.157, 0.165, 0.212, 0.950 +#define FONT_SIZE2 16 +#define BG_COLOR b_col_r, b_col_g, b_col_b, 0.950 #define FG_COLOR 0.973, 0.973, 0.949, 1.000 // COMPUTATION #define HEIGHT FONT_SIZE*2 #define FONT_POS FONT_SIZE*1.4 +#define FONT_POS2 FONT_SIZE2*1.4 +//#define FONT_POS2 FONT_SIZE2*2.2/2.0 + +int l_cairo_set_source_rgba(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + double r = lua_tonumber(L, 2); + double g = lua_tonumber(L, 3); + double b = lua_tonumber(L, 4); + double a = lua_tonumber(L, 5); + + //printf("set_source_rgba(%d, %f, %f, %f, %f)\n", ctx, r, g, b, a); + + cairo_set_source_rgba(ctx, r, g, b, a); + + return 0; +} + +int l_cairo_arc(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + double xc = lua_tonumber(L, 2); + double yc = lua_tonumber(L, 3); + double r = lua_tonumber(L, 4); + double a1 = lua_tonumber(L, 5); + double a2 = lua_tonumber(L, 6); + + //printf("set_source_rgba(%d, %f, %f, %f, %f)\n", ctx, r, g, b, a); + + cairo_arc(ctx, xc, yc, r, a1, a2); + + return 0; +} + +int l_cairo_rectangle(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + double x = lua_tonumber(L, 2); + double y = lua_tonumber(L, 3); + double w = lua_tonumber(L, 4); + double h = lua_tonumber(L, 5); + + //printf("set_source_rgba(%d, %f, %f, %f, %f)\n", ctx, r, g, b, a); + + cairo_rectangle(ctx, x, y, w, h); + + return 0; +} + +int l_cairo_paint(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + + //printf("paint()\n"); + + cairo_paint(ctx); + + return 0; +} + +int l_cairo_fill(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + + //printf("fill()\n"); + + cairo_fill(ctx); + + return 0; +} + +int l_cairo_stroke(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + + //printf("stroke()\n"); + + cairo_stroke(ctx); + + return 0; +} + +int l_cairo_rel_line_to(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + double x = lua_tonumber(L, 2); + double y = lua_tonumber(L, 3); + + //printf("move_to(%f, %f)\n", x, y); + + cairo_rel_line_to(ctx, x, y); + + return 0; +} + + +int l_cairo_move_to(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + double x = lua_tonumber(L, 2); + double y = lua_tonumber(L, 3); + + //printf("move_to(%f, %f)\n", x, y); + + cairo_move_to(ctx, x, y); + + return 0; +} + +int l_cairo_select_font_face(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + char* fm = lua_tostring(L, 2); + cairo_font_slant_t sl = lua_tonumber(L, 3); + cairo_font_weight_t wg = lua_tonumber(L, 4); + + //printf("select_font_face(%s, %d, %d)\n", fm, sl, wg); + + cairo_select_font_face(ctx, fm, sl, wg); + + return 0; +} + +int l_cairo_set_font_size(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + double sz = lua_tonumber(L, 2); + + //printf("set_font_size(%f)\n", sz); + + cairo_set_font_size(ctx, sz); + + return 0; +} + +int l_cairo_set_line_width(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + double wh = lua_tonumber(L, 2); + + //printf("set_line_width(%f)\n", wh); + + cairo_set_line_width(ctx, wh); + + return 0; +} + +int l_cairo_show_text(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + char* txt = lua_tostring(L, 2); + + //printf("show_text(%s)\n", txt); + + cairo_show_text(ctx, txt); + + return 0; +} + +int l_cairo_text_extents(lua_State *L) { + void* ctx = (uint64_t)lua_tonumber(L, 1); + char* txt = lua_tostring(L, 2); + + + cairo_text_extents_t extents; + cairo_text_extents(ctx, txt, &extents); + + lua_createtable(L, 0, 6); + + lua_pushstring(L, "x_bearing"); + lua_pushinteger(L, extents.x_bearing); + lua_settable(L, -3); + + lua_pushstring(L, "y_bearing"); + lua_pushinteger(L, extents.y_bearing); + lua_settable(L, -3); + + lua_pushstring(L, "width"); + lua_pushinteger(L, extents.width); + lua_settable(L, -3); + + lua_pushstring(L, "height"); + lua_pushinteger(L, extents.height); + lua_settable(L, -3); + + lua_pushstring(L, "x_advance"); + lua_pushinteger(L, extents.x_advance); + lua_settable(L, -3); + + lua_pushstring(L, "y_advance"); + lua_pushinteger(L, extents.y_advance); + lua_settable(L, -3); + + return 1; +} + void init() { dpy = XOpenDisplay(NULL); int screen = DefaultScreen(dpy); @@ -73,8 +270,8 @@ void init() { XMatchVisualInfo(dpy, screen, 32, TrueColor, &visualinfo); XSetWindowAttributes attr; attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), visualinfo.visual, AllocNone); - attr.background_pixel = 0; - attr.border_pixel = 0; + attr.background_pixel = 0; + attr.border_pixel = 0; win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, HEIGHT, 0, visualinfo.depth, InputOutput, visualinfo.visual, CWBackPixel | CWColormap | CWBorderPixel, &attr); @@ -101,43 +298,70 @@ void init() { XMapWindow(dpy, win); sfc = cairo_xlib_surface_create(dpy, win, visualinfo.visual, DisplayWidth(dpy, screen), HEIGHT); - sfc2 = cairo_surface_create_similar(sfc, CAIRO_CONTENT_COLOR_ALPHA, DisplayWidth(dpy, screen), HEIGHT); ctx = cairo_create(sfc); - ctx2 = cairo_create(sfc2); + + lua = luaL_newstate(); + luaL_openlibs(lua); + + //luaL_dofile(lua, "config.lua"); + + lua_pushcfunction(lua, l_cairo_set_source_rgba); + lua_setglobal(lua, "cairo_set_source_rgba"); + lua_pushcfunction(lua, l_cairo_paint); + lua_setglobal(lua, "cairo_paint"); + lua_pushcfunction(lua, l_cairo_move_to); + lua_setglobal(lua, "cairo_move_to"); + lua_pushcfunction(lua, l_cairo_select_font_face); + lua_setglobal(lua, "cairo_select_font_face"); + lua_pushcfunction(lua, l_cairo_set_font_size); + lua_setglobal(lua, "cairo_set_font_size"); + lua_pushcfunction(lua, l_cairo_show_text); + lua_setglobal(lua, "cairo_show_text"); + lua_pushcfunction(lua, l_cairo_text_extents); + lua_setglobal(lua, "cairo_text_extents"); + lua_pushcfunction(lua, l_cairo_fill); + lua_setglobal(lua, "cairo_fill"); + lua_pushcfunction(lua, l_cairo_stroke); + lua_setglobal(lua, "cairo_stroke"); + lua_pushcfunction(lua, l_cairo_arc); + lua_setglobal(lua, "cairo_arc"); + lua_pushcfunction(lua, l_cairo_rectangle); + lua_setglobal(lua, "cairo_rectangle"); + lua_pushcfunction(lua, l_cairo_set_line_width); + lua_setglobal(lua, "cairo_set_line_width"); + lua_pushcfunction(lua, l_cairo_rel_line_to); + lua_setglobal(lua, "cairo_rel_line_to"); } pthread_mutex_t do_paint; void paint(Display* dpy) { if(!pthread_mutex_lock(&do_paint)) { - // Clear - cairo_set_source_rgba(ctx2, 0.0, 0.0, 0.0, 0.0); - cairo_set_operator(ctx2, CAIRO_OPERATOR_SOURCE); - cairo_paint(ctx2); - cairo_set_operator(ctx2, CAIRO_OPERATOR_OVER); - - // Background - cairo_set_source_rgba(ctx2, BG_COLOR); - cairo_paint(ctx2); - - // Left text - cairo_move_to(ctx2, FONT_SIZE / 2, FONT_POS); - cairo_select_font_face(ctx2, FONT, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - cairo_set_font_size(ctx2, FONT_SIZE); - cairo_set_source_rgba(ctx2, FG_COLOR); - cairo_show_text(ctx2, text); - - // Right text - cairo_text_extents_t extents; - cairo_text_extents(ctx2, text_other, &extents); - cairo_move_to(ctx2, (width-extents.width) - FONT_SIZE / 2, FONT_POS); - cairo_show_text(ctx2, text_other); - - // Backbuffer -> Frontbuffer - cairo_set_source_surface(ctx, sfc2, 0, 0); + + cairo_push_group(ctx); + + cairo_set_source_rgba(ctx, 0.0, 0.0, 0.0, 0.0); + + cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE); + cairo_paint(ctx); + + cairo_set_operator(ctx, CAIRO_OPERATOR_OVER); + + luaL_dofile(lua, "config.lua"); + + lua_getglobal(lua, "draw"); + lua_pushinteger(lua, ctx); + lua_pushinteger(lua, width); + lua_pushstring(lua, text_conf); + lua_pushstring(lua, text); + lua_pushstring(lua, text_other); + + lua_pcall(lua, 5, 0, 0); + + cairo_pop_group_to_source(ctx); + cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE); cairo_paint(ctx); - // Flushing cairo_surface_flush(sfc); XFlush(dpy); @@ -149,9 +373,13 @@ void update() { while(1) { fgets(text, 256, stdin); fgets(text_other, 256, stdin); + fgets(text_other2, 256, stdin); + fgets(text_conf, 256, stdin); text[strcspn(text, "\n")] = 0; text_other[strcspn(text_other, "\n")] = 0; + text_other2[strcspn(text_other2, "\n")] = 0; + text_conf[strcspn(text_conf, "\n")] = 0; paint(dpy); } @@ -163,7 +391,7 @@ void x_loop() { while(1) { XEvent e; XNextEvent(x_dpy, &e); - if(e.type == ButtonPress) { + if(e.type == ButtonPress && e.xbutton.button == Button1) { printf("%d %d\n", e.xbutton.x, e.xbutton.y); fflush(stdout); } else if(e.type == ConfigureNotify) { diff --git a/shell.nix b/shell.nix index 32d1bfb..db295c8 100644 --- a/shell.nix +++ b/shell.nix @@ -9,8 +9,9 @@ pkgs.mkShell { cairo.dev cairo.devdoc pkg-config - python39 - python39Packages.i3ipc + python310 + lua5_4 + (python310Packages.i3ipc.overrideAttrs(old:{patches=[(fetchpatch{url="https://github.com/altdesktop/i3ipc-python/pull/200.patch";sha256="sha256-kAPg4KTpmVtegoRErJJaFcxXBGXHdJlZZd/HqdY3LHs=";})];})) acpi ]; shellHook = ''