modular dwmclocky
This commit is contained in:
		
						commit
						f6cba2c8a1
					
				
							
								
								
									
										3
									
								
								dwmclocky/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								dwmclocky/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
modules/*
 | 
			
		||||
dim
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								dwmclocky/build.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										11
									
								
								dwmclocky/build.sh
									
									
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
#!/usr/bin/bash
 | 
			
		||||
 | 
			
		||||
set -xe
 | 
			
		||||
 | 
			
		||||
CCARGS="-Isrc/include -Wall -pedantic"
 | 
			
		||||
 | 
			
		||||
cc -o dim src/main.c src/plug.c $CCARGS -lX11 -ldl
 | 
			
		||||
cc -o modules/clocky.dim src/modules/clock.c -rdynamic -shared -fPIC $CCARGS
 | 
			
		||||
cc -o modules/battery.dim src/modules/battery.c -rdynamic -shared -fPIC $CCARGS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								dwmclocky/src/include/plug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								dwmclocky/src/include/plug.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
 | 
			
		||||
#ifndef _H_PLUG
 | 
			
		||||
#define _H_PLUG
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
typedef void (*plug_init_f) ();
 | 
			
		||||
typedef void (*plug_reload_f) ();
 | 
			
		||||
typedef void (*plug_poll_f) (char*, size_t);
 | 
			
		||||
typedef void (*plug_free_f) ();
 | 
			
		||||
 | 
			
		||||
typedef struct plug_t {
 | 
			
		||||
    char* name;
 | 
			
		||||
    char* version;
 | 
			
		||||
} plug_t;
 | 
			
		||||
 | 
			
		||||
typedef struct plug_int_t {
 | 
			
		||||
    plug_init_f f_init;
 | 
			
		||||
    plug_reload_f f_reload;
 | 
			
		||||
    plug_poll_f f_poll;
 | 
			
		||||
    plug_free_f f_free;
 | 
			
		||||
    plug_t* s_plug_info;
 | 
			
		||||
} plug_int_t;
 | 
			
		||||
 | 
			
		||||
void setup_plugins(char* plugin_path);
 | 
			
		||||
char* poll_plugins();
 | 
			
		||||
void free_plugins();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										26
									
								
								dwmclocky/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								dwmclocky/src/main.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
#include <X11/Xlib.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include "plug.h"
 | 
			
		||||
 | 
			
		||||
int main(void) {
 | 
			
		||||
    setup_plugins("./modules");
 | 
			
		||||
    char* buffer;
 | 
			
		||||
 | 
			
		||||
    Display *display = XOpenDisplay(NULL);
 | 
			
		||||
    Window window = DefaultRootWindow(display);
 | 
			
		||||
 | 
			
		||||
    while (1) {
 | 
			
		||||
        buffer = poll_plugins("|");
 | 
			
		||||
        XStoreName(display, window, buffer);
 | 
			
		||||
        XFlush(display);
 | 
			
		||||
        sleep(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  XCloseDisplay(display);
 | 
			
		||||
  free_plugins();
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								dwmclocky/src/modules/battery.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								dwmclocky/src/modules/battery.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
#include "plug.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
plug_t PLUG = {0};
 | 
			
		||||
 | 
			
		||||
static FILE* fp = NULL;
 | 
			
		||||
 | 
			
		||||
char* batt_files[] = {
 | 
			
		||||
    "/sys/class/power_supply/BAT0/capacity",
 | 
			
		||||
    "/sys/class/power_supply/BAT1/capacity"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void plug_init(void) {
 | 
			
		||||
    PLUG.name = "Battery";
 | 
			
		||||
    PLUG.version = "0.0.1";
 | 
			
		||||
 | 
			
		||||
    for (size_t i = 0; i < sizeof(batt_files)/sizeof(batt_files[0]); i++) {
 | 
			
		||||
        if (access(batt_files[i], F_OK) == 0) {
 | 
			
		||||
            fp = fopen(batt_files[i], "r");
 | 
			
		||||
            if (fp) {
 | 
			
		||||
                printf("Opened %s\n", batt_files[i]);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!fp) {
 | 
			
		||||
        printf("MODULE: ERROR: Unable to find battery\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void plug_reload(void) { /* Unused */ }
 | 
			
		||||
 | 
			
		||||
void plug_poll(char* buf, size_t len) {
 | 
			
		||||
    int perc = 0;
 | 
			
		||||
    fseek(fp, 0, SEEK_SET);
 | 
			
		||||
    fscanf(fp, "%d", &perc);
 | 
			
		||||
    snprintf(buf, len, "Batt: %d%%", perc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void plug_free(void) {}
 | 
			
		||||
							
								
								
									
										23
									
								
								dwmclocky/src/modules/clock.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								dwmclocky/src/modules/clock.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
#include "plug.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
plug_t PLUG = {0};
 | 
			
		||||
 | 
			
		||||
void plug_init(void) {
 | 
			
		||||
    PLUG.name = "time";
 | 
			
		||||
    PLUG.version = "0.0.1";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void plug_reload(void) { /* Unused */ }
 | 
			
		||||
 | 
			
		||||
void plug_poll(char* buf, size_t len) {
 | 
			
		||||
    time_t rawtime;
 | 
			
		||||
    struct tm *timeinfo;
 | 
			
		||||
    
 | 
			
		||||
    time(&rawtime);
 | 
			
		||||
    timeinfo = localtime(&rawtime);
 | 
			
		||||
 | 
			
		||||
    strftime(buf, len, "Time: %H:%M (%Y-%m-%d)", timeinfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void plug_free(void) {}
 | 
			
		||||
							
								
								
									
										168
									
								
								dwmclocky/src/plug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								dwmclocky/src/plug.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,168 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include "plug.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define PLUG_PATH_MAX 255
 | 
			
		||||
#define PLUG_MAX_COUNT (PLUG_PATH_MAX+255)
 | 
			
		||||
#define PLUG_POLL_BUF_SZ 1024
 | 
			
		||||
 | 
			
		||||
typedef struct PlugMan {
 | 
			
		||||
    plug_int_t* plugs[PLUG_MAX_COUNT];
 | 
			
		||||
    size_t plug_count;
 | 
			
		||||
    void* plug_objs[PLUG_MAX_COUNT];
 | 
			
		||||
    size_t plug_obj_count;
 | 
			
		||||
} plugman_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static plugman_t PLUGMAN = {0};
 | 
			
		||||
 | 
			
		||||
void* load_plug_sym(void* plug_f, char* fn_name);
 | 
			
		||||
plug_int_t* load_plugin(char* path);
 | 
			
		||||
 | 
			
		||||
void load_plugins(const char* mod_dir_p) {
 | 
			
		||||
    DIR* dir = {0};
 | 
			
		||||
 | 
			
		||||
    dir = opendir(mod_dir_p);
 | 
			
		||||
 | 
			
		||||
    if (!dir) {
 | 
			
		||||
        printf("ERROR: Failed to open dir %s\n", mod_dir_p);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct dirent* dir_entry;
 | 
			
		||||
 | 
			
		||||
    while ((dir_entry = readdir(dir)) != NULL) {
 | 
			
		||||
        if (!(dir_entry->d_type == DT_REG ||
 | 
			
		||||
                dir_entry->d_type == DT_LNK)) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (strcmp(dir_entry->d_name, ".") == 0 ||
 | 
			
		||||
                strcmp(dir_entry->d_name, "..") == 0) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        char* dot = strchr(dir_entry->d_name, '.');
 | 
			
		||||
        
 | 
			
		||||
        if (!dot || dot == dir_entry->d_name) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        char* ext = dot+1;
 | 
			
		||||
        if (strcmp(ext, "dim") != 0) continue;
 | 
			
		||||
        
 | 
			
		||||
        printf("INFO: Found plugin: %s/%s\n", mod_dir_p, dir_entry->d_name);
 | 
			
		||||
 | 
			
		||||
        char full_path[PLUG_MAX_COUNT] = {0};
 | 
			
		||||
        snprintf(full_path, PLUG_MAX_COUNT, "%s/%s", mod_dir_p, dir_entry->d_name);
 | 
			
		||||
        plug_int_t* plug = load_plugin(full_path);
 | 
			
		||||
 | 
			
		||||
        if (!plug) {
 | 
			
		||||
            printf("ERROR: Failed to load plugin %s, skipping\n", full_path);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        PLUGMAN.plugs[PLUGMAN.plug_count++] = plug;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
plug_int_t* load_plugin(char* path) {
 | 
			
		||||
    plug_int_t* plug = malloc(sizeof(plug_int_t));
 | 
			
		||||
    void* plug_f = dlopen(path, RTLD_NOW);
 | 
			
		||||
    
 | 
			
		||||
    if (!plug_f) {
 | 
			
		||||
        printf("ERROR: Failed to load plugin %s\n", path);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // "technically" couldnt run on very niche platforms but idc
 | 
			
		||||
    #pragma GCC diagnostic push
 | 
			
		||||
    #pragma GCC diagnostic ignored "-Wpedantic"
 | 
			
		||||
    
 | 
			
		||||
    plug->f_init = (plug_init_f)load_plug_sym(plug_f, "plug_init");
 | 
			
		||||
    plug->f_reload = (plug_reload_f)load_plug_sym(plug_f, "plug_reload");
 | 
			
		||||
    plug->f_poll = (plug_poll_f)load_plug_sym(plug_f, "plug_poll");
 | 
			
		||||
    plug->f_free = (plug_free_f)load_plug_sym(plug_f, "plug_free");
 | 
			
		||||
    plug->s_plug_info = (plug_t*)load_plug_sym(plug_f, "PLUG");
 | 
			
		||||
 | 
			
		||||
    #pragma GCC diagnostic pop
 | 
			
		||||
 | 
			
		||||
    if (!plug->f_init || !plug->f_reload ||
 | 
			
		||||
            !plug->f_poll || !plug->f_free ||
 | 
			
		||||
            !plug->s_plug_info) {
 | 
			
		||||
        dlclose(plug_f);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PLUGMAN.plug_objs[PLUGMAN.plug_obj_count++] = plug_f;
 | 
			
		||||
    return plug;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void* load_plug_sym(void* plug_f, char* fn_name) {
 | 
			
		||||
    void* f = dlsym(plug_f, fn_name);
 | 
			
		||||
    char* err = dlerror();
 | 
			
		||||
 | 
			
		||||
    if (err){
 | 
			
		||||
       printf("ERROR: Could not load plug symbol '%s': %s\n", fn_name, err);
 | 
			
		||||
       return NULL;
 | 
			
		||||
    } 
 | 
			
		||||
    return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void setup_plugins(char* plugin_path) {
 | 
			
		||||
    load_plugins(plugin_path);
 | 
			
		||||
    printf("INFO: Loaded %zu plugins:\n", PLUGMAN.plug_count);
 | 
			
		||||
    for (size_t i = 0; i < PLUGMAN.plug_count; i++) {
 | 
			
		||||
        plug_int_t* plug = PLUGMAN.plugs[i]; 
 | 
			
		||||
 | 
			
		||||
        (plug->f_init)();
 | 
			
		||||
        printf(" - %s (%s)\n", plug->s_plug_info->name, plug->s_plug_info->version);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void free_plugins() {
 | 
			
		||||
    for (size_t i = 0; i < PLUGMAN.plug_count; i++) {
 | 
			
		||||
        plug_int_t* plug = PLUGMAN.plugs[i];
 | 
			
		||||
        (plug->f_free)();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (size_t i = 0; i < PLUGMAN.plug_obj_count; i++) {
 | 
			
		||||
        dlclose(PLUGMAN.plug_objs[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char* poll_plugins(char* sep) {
 | 
			
		||||
    char* buf = malloc(PLUG_POLL_BUF_SZ * sizeof(char));
 | 
			
		||||
 | 
			
		||||
    if (!buf) {
 | 
			
		||||
        printf("Unable to allocate buffer for polling\n");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (size_t i = 0; i < PLUGMAN.plug_count; i++) {
 | 
			
		||||
        plug_int_t* plug = PLUGMAN.plugs[i];
 | 
			
		||||
        
 | 
			
		||||
        printf("Polling plug id %zu\n", i);
 | 
			
		||||
 | 
			
		||||
        size_t len = strlen(buf);
 | 
			
		||||
        (plug->f_poll)(buf + len, PLUG_POLL_BUF_SZ - len);
 | 
			
		||||
        
 | 
			
		||||
        if (i < PLUGMAN.plug_count - 1) {
 | 
			
		||||
            size_t len_post = strlen(buf);
 | 
			
		||||
            snprintf(buf + len_post, PLUG_POLL_BUF_SZ - len_post, " %s ", sep);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("Setting title: '%s'\n", buf);
 | 
			
		||||
 | 
			
		||||
    return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								dwmclocky/test.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								dwmclocky/test.sh
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
 | 
			
		||||
while true; do
 | 
			
		||||
    clear -x
 | 
			
		||||
    xprop -root | grep -Po "WM_NAME\(STRING\) = \"\K.*(?=\")"
 | 
			
		||||
    sleep 0.5
 | 
			
		||||
done
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user