Initial work on Lua-configured rendering

This commit is contained in:
itycodes 2023-03-26 00:16:54 +01:00
parent db4159c546
commit 2a1142c709
3 changed files with 263 additions and 34 deletions

View file

@ -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

290
main.c
View file

@ -12,7 +12,7 @@
*/
// --------------
// TextBar v0.1.2
// LuaBar v0.2.0
// --------------
// Usage: <text generator> | textbar | <input handler>
//
@ -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 <pthread.h>
@ -42,14 +46,22 @@
#include <cairo.h>
#include <cairo-xlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
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);
cairo_push_group(ctx);
// 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);
cairo_set_source_rgba(ctx, 0.0, 0.0, 0.0, 0.0);
// 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);
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);
// Backbuffer -> Frontbuffer
cairo_set_source_surface(ctx, sfc2, 0, 0);
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) {

View file

@ -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 = ''