commit 52e085886d9c0af301f8e34b0e899ad5e50042ff
parent 6e53850c21f0ee6325b8267188592f34b7612071
Author: Pollux <pollux@pollux.codes>
Date: Sun, 20 Jul 2025 23:55:56 -0500
docs: Added man page, usage, and arg parsing
Signed-off-by: Pollux <pollux@pollux.codes>
Diffstat:
M | Makefile | | | 24 | +++++++++++++++++++++--- |
M | config.mk | | | 19 | +++++++++++++------ |
A | morph.1.in | | | 29 | +++++++++++++++++++++++++++++ |
M | morph.c | | | 41 | ++++++++++++++++++++++++++++++++++++----- |
4 files changed, 99 insertions(+), 14 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,9 +1,27 @@
+# See LICENSE file for copyright and license details
+
include config.mk
-all: morph
+all: morph docs
+
+docs: morph.1
morph: morph.c
- $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) morph.c -o morph
+ $(CC) $(CFLAGS) morph.c -o morph $(LDFLAGS)
+
+morph.1: morph.1.in
+ sed 's/VERSION/$(VERSION)/g' < morph.1.in > morph.1
clean:
- rm morph
+ -rm morph morph.1
+
+install: all
+ install -d $(DESTDIR)$(PREFIX)/bin/ $(DESTDIR)$(MANPREFIX)/man1
+ install -s -m 755 morph $(DESTDIR)$(PREFIX)/bin/morph
+ install -m 644 morph.1 $(DESTDIR)$(MANPREFIX)/man1/morph.1
+
+uninstall:
+ -rm -f $(DESTDIR)$(PREFIX)/bin/morph
+ -rm -f $(DESTDIR)$(MANPREFIX)/man1/morph.1
+
+.PHONY: all docs clean install uninstall
diff --git a/config.mk b/config.mk
@@ -1,9 +1,16 @@
-CPPFLAGS =
+# morph version
+VERSION = 0.0
-# Debug (for development only)
-# CFLAGS = -std=c99 -g3 -O0 -fsanitize=address -Wall -Wpedantic -Werror
+PREFIX = /usr/local
+MANPREFIX = $(PREFIX)/share/man
-# Release
-CFLAGS = -std=c99 -O3 -Wall -Werror
+# includes and libs
+INCS =
+LIBS = -lImlib2 -lm
-LDFLAGS = -lImlib2 -lm
+# flags
+CPPFLAGS = -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\"
+CFLAGS = -std=c99 -O3 -Wall -Wpedantic -Werror $(INCS) $(CPPFLAGS)
+LDFLAGS = $(LIBS)
+
+CC = cc
diff --git a/morph.1.in b/morph.1.in
@@ -0,0 +1,29 @@
+.TH MORPH 1 morph\-VERSION
+.SH "NAME"
+morph \- xresources theme generator
+.SH "SYNOPSIS"
+.B morph
+.RB [ \-hV ]
+.IR <image>
+.SH "DESCRIPTION"
+.B morph
+is an xresources theme generator. It takes a path to an image from the command
+line and prints out an xresources file with colors extracted from the image.
+This output can be piped into a file and loaded with
+.B xrdb,
+or simply piped into
+.B xrdb
+directly.
+.SH "OPTIONS"
+.TP
+.B \-h
+prints usage information to stdout, then exits.
+.TP
+.B \-V
+prints version to stdout, then exits.
+.SH "AUTHORS"
+.B morph
+was written by
+.I Pollux <pollux@pollux.codes>.
+.SH "SEE ALSO"
+.BR xrdb (1)
diff --git a/morph.c b/morph.c
@@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <Imlib2.h>
@@ -18,7 +19,8 @@
#define max(a, b) ((a) > (b) ? (a) : (b))
#define TARGET_COLOR(name, cr, cg, cb, cl) \
- color = match_color(palette, palette_weights, PRIMARY_COLOR_COUNT*4, rgb_to_lab((col_rgb_t){ .r = cr, .g = cg, .b = cb}));\
+ color = match_color(palette, palette_weights, PRIMARY_COLOR_COUNT*4,\
+ rgb_to_lab((col_rgb_t){ .r = cr, .g = cg, .b = cb}));\
color.l = cl;\
export_color(name, color);
@@ -61,6 +63,12 @@ die(const char *fmt, ...) {
exit(1);
}
+void
+usage() {
+ printf("morph [-hV] <image>\n");
+ exit(0);
+}
+
/// Compare the luminances of the two given colors. Returns 1 if the first has
/// a larger luminance, returns -1 otherwise.
int
@@ -187,6 +195,7 @@ get_image_pixel_data(const char *path, int *pixel_count) {
Imlib_Image image;
image = imlib_load_image(path);
+
if(image == NULL)
return NULL;
@@ -389,9 +398,33 @@ export_color(const char *name, col_lab_t color) {
printf("%s: #%02x%02x%02x\n", name, red, green, blue);
}
+void
+parse_argv(int argc, char **argv, char **filepath) {
+
+ int c;
+
+ opterr = 0;
+
+ while((c = getopt(argc, argv, "hV")) != -1) {
+ switch (c) {
+ case 'V':
+ printf("morph-" VERSION "\n");
+ exit(0);
+ default:
+ usage();
+ }
+ }
+
+ if(optind >= argc)
+ usage();
+
+ *filepath = argv[optind];
+}
+
int
main(int argc, char **argv) {
+ char *filepath;
int pixel_count;
int i;
col_rgb_t *image_pixels_rgb;
@@ -404,11 +437,9 @@ main(int argc, char **argv) {
col_lab_t color;
- // TODO v1.0: Proper input argement handling.
- if(argc <= 1)
- die("No image provided.");
+ parse_argv(argc, argv, &filepath);
- image_pixels_rgb = get_image_pixel_data(argv[1], &pixel_count);
+ image_pixels_rgb = get_image_pixel_data(filepath, &pixel_count);
if(image_pixels_rgb == NULL)
die("Image failed to load.");