From 3b0d1fa80566c53a6991a3c2480094d233ae1088 Mon Sep 17 00:00:00 2001 From: Benjamin Mugnier Date: Sun, 17 Jan 2021 13:18:48 +0100 Subject: [PATCH 1/3] add help --- stint.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/stint.c b/stint.c index ea435ec..1d5c877 100644 --- a/stint.c +++ b/stint.c @@ -22,11 +22,36 @@ #include #include +#define HELP_PARAM "--help" +#define HELP_SHORT_PARAM "-h" + +void +help() +{ + printf("Usage: stint [OPTIONS]\n"); + printf("Simple, suckless-style color grabber for X11\n"); + printf("\n"); + + printf("When run, waits for the user to press the left mouse button. As long as the\n\ +button is held down, it will continue to print the color under the pointer in\n\ +decimal \"RRR GGG BBB\" format. Exits when the button is released.\n"); + printf("\n"); + + printf("\t%s, %s\tShow this help\n", HELP_SHORT_PARAM, HELP_PARAM); +} + int main(int argc, char *argv[]) { int rv = 0; + //Display help + if (argc > 1 && ((strcmp(argv[1], HELP_PARAM) == 0) || + (strcmp(argv[1], HELP_SHORT_PARAM) == 0))) { + help(); + return 0; + } + // Get display, root window, and crosshair cursor Display *dpy = XOpenDisplay(NULL); if (!dpy) { From 6ac477bfd3a8f00534c839fa739e202dd5048b78 Mon Sep 17 00:00:00 2001 From: Benjamin Mugnier Date: Sun, 17 Jan 2021 13:22:37 +0100 Subject: [PATCH 2/3] add x and y parameters Allow to get the color of a pixel from defined positions instead of clicking with the mouse User needs to specify both x and y --- stint.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 12 deletions(-) diff --git a/stint.c b/stint.c index 1d5c877..2c6ccad 100644 --- a/stint.c +++ b/stint.c @@ -17,6 +17,10 @@ */ #include +#include +#include +#include +#include #include #include #include @@ -24,6 +28,8 @@ #define HELP_PARAM "--help" #define HELP_SHORT_PARAM "-h" +#define X_PARAM "-x" +#define Y_PARAM "-y" void help() @@ -38,12 +44,52 @@ decimal \"RRR GGG BBB\" format. Exits when the button is released.\n"); printf("\n"); printf("\t%s, %s\tShow this help\n", HELP_SHORT_PARAM, HELP_PARAM); + printf("\t%s \tUse x location instead of cursor x position (requires %s)\n", X_PARAM, Y_PARAM); + printf("\t%s \tUse y location instead of cursor y position (requires %s)\n", Y_PARAM, X_PARAM); +} + +void +print_pixel(Display *dpy, Window root, int x, int y) +{ + XColor c; + + // Grab a 1x1 screenshot located at (x, y) and find the color + c.pixel = XGetPixel(XGetImage(dpy, root, x, y, 1, 1, AllPlanes, + ZPixmap), 0, 0); + XQueryColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), &c); + + // What color is it? + printf("%d %d %d\n", c.red >> 8, c.green >> 8, c.blue >> 8); + fflush(stdout); +} + +int +get_loc(char *loc_param, int *loc, char *value_param, char *value) +{ + char *endptr; + + if (strcmp(loc_param, value_param) == 0) { + *loc = strtol(value, &endptr, 0); + if (errno != 0) { + perror("strtol"); + return 1; + } + if (endptr == value) { + fprintf(stderr, "no digits were found for %s\n", loc_param); + return 1; + } + } + return 0; } int main(int argc, char *argv[]) { int rv = 0; + int fixed_pos = false; + int x = -1; + int y = -1; + int ret; //Display help if (argc > 1 && ((strcmp(argv[1], HELP_PARAM) == 0) || @@ -52,6 +98,27 @@ main(int argc, char *argv[]) return 0; } + //Get arguments + for (int i=0; i < argc; i++) { + if (i != argc - 1) { + ret = get_loc(X_PARAM, &x, argv[i], argv[i+1]); + if (ret != 0) + return ret; + ret = get_loc(Y_PARAM, &y, argv[i], argv[i+1]); + if (ret != 0) + return ret; + } + } + + // Check arguments are valid + if ((x == -1) ^ (y == -1)) { + fprintf(stderr, "must supply either both x and y coordinates or none\n"); + return 3; + } + if (x != -1 && y != -1) { + fixed_pos = true; + } + // Get display, root window, and crosshair cursor Display *dpy = XOpenDisplay(NULL); if (!dpy) { @@ -60,6 +127,12 @@ main(int argc, char *argv[]) } Window root = DefaultRootWindow(dpy); + + if(fixed_pos) { + print_pixel(dpy, root, x, y); + goto out_close; + } + Cursor cross = XCreateFontCursor(dpy, XC_crosshair); // Grab pointer clicking and motion events @@ -95,17 +168,7 @@ main(int argc, char *argv[]) // Print colors until Button1 is released while (ev.type != ButtonRelease || ev.xbutton.button != 1) { - XColor c; - - // Grab a 1x1 screenshot located at (x, y) and find the color - c.pixel = XGetPixel(XGetImage(dpy, root, ev.xbutton.x_root, ev.xbutton.y_root, - 1, 1, AllPlanes, ZPixmap), 0, 0); - XQueryColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), &c); - - // What color is it? - printf("%d %d %d\n", c.red >> 8, c.green >> 8, c.blue >> 8); - fflush(stdout); - + print_pixel(dpy, root, ev.xbutton.x_root, ev.xbutton.y_root); XNextEvent(dpy, &ev); } @@ -115,7 +178,7 @@ main(int argc, char *argv[]) out_free: // Clean up XFreeCursor(dpy, cross); - +out_close: XCloseDisplay(dpy); return rv; } From 9157b3d9ec248260a8d16907f69ec4acb18ba6fa Mon Sep 17 00:00:00 2001 From: Benjamin Mugnier Date: Sun, 17 Jan 2021 13:23:03 +0100 Subject: [PATCH 3/3] add show location parameter When specified, display the position of the grabbed pixel --- stint.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/stint.c b/stint.c index 2c6ccad..69456d2 100644 --- a/stint.c +++ b/stint.c @@ -30,6 +30,8 @@ #define HELP_SHORT_PARAM "-h" #define X_PARAM "-x" #define Y_PARAM "-y" +#define SHOW_LOC_PARAM "--show-location" +#define SHOW_LOC_SHORT_PARAM "-s" void help() @@ -46,10 +48,11 @@ decimal \"RRR GGG BBB\" format. Exits when the button is released.\n"); printf("\t%s, %s\tShow this help\n", HELP_SHORT_PARAM, HELP_PARAM); printf("\t%s \tUse x location instead of cursor x position (requires %s)\n", X_PARAM, Y_PARAM); printf("\t%s \tUse y location instead of cursor y position (requires %s)\n", Y_PARAM, X_PARAM); + printf("\t%s, %s\tDisplay fetched location\n", SHOW_LOC_SHORT_PARAM, SHOW_LOC_PARAM); } void -print_pixel(Display *dpy, Window root, int x, int y) +print_pixel(Display *dpy, Window root, int x, int y, bool show_loc) { XColor c; @@ -58,6 +61,10 @@ print_pixel(Display *dpy, Window root, int x, int y) ZPixmap), 0, 0); XQueryColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), &c); + // Show pixel coordinates if asked + if (show_loc) { + printf("%d %d\n", x, y); + } // What color is it? printf("%d %d %d\n", c.red >> 8, c.green >> 8, c.blue >> 8); fflush(stdout); @@ -87,6 +94,7 @@ main(int argc, char *argv[]) { int rv = 0; int fixed_pos = false; + int show_loc = false; int x = -1; int y = -1; int ret; @@ -108,6 +116,10 @@ main(int argc, char *argv[]) if (ret != 0) return ret; } + if (strcmp(argv[i], SHOW_LOC_PARAM) == 0 || + strcmp(argv[i], SHOW_LOC_SHORT_PARAM) == 0) { + show_loc = true; + } } // Check arguments are valid @@ -129,7 +141,7 @@ main(int argc, char *argv[]) Window root = DefaultRootWindow(dpy); if(fixed_pos) { - print_pixel(dpy, root, x, y); + print_pixel(dpy, root, x, y, show_loc); goto out_close; } @@ -168,7 +180,7 @@ main(int argc, char *argv[]) // Print colors until Button1 is released while (ev.type != ButtonRelease || ev.xbutton.button != 1) { - print_pixel(dpy, root, ev.xbutton.x_root, ev.xbutton.y_root); + print_pixel(dpy, root, ev.xbutton.x_root, ev.xbutton.y_root, show_loc); XNextEvent(dpy, &ev); }