diff --git a/find-cursor.c b/find-cursor.c index d12c14d..dcaada7 100644 --- a/find-cursor.c +++ b/find-cursor.c @@ -20,7 +20,10 @@ void usage(char *name); int parse_num(int ch, char *opt, char *name); -void draw(char *name, int size, int distance, int wait, int line_width, char *color_name); +void draw( + char *name, + int size, int distance, int wait, int line_width, char *color_name, + int follow, int transparent); static struct option longopts[] = { {"help", no_argument, NULL, 'h'}, @@ -29,22 +32,32 @@ static struct option longopts[] = { {"wait", required_argument, NULL, 'w'}, {"line-width", required_argument, NULL, 'l'}, {"color", required_argument, NULL, 'c'}, + {"follow", no_argument, NULL, 'f'}, + {"transparent", no_argument, NULL, 't'}, {NULL, 0, NULL, 0} }; void usage(char *name) { printf("Usage: %s [-stplc]\n\n", name); printf(" -h, --help Show this help.\n"); + printf("\n"); + printf("Shape options:\n"); printf(" -s, --size Maximum size the circle will grow to in pixels.\n"); printf(" -d, --distance Distance between the circles in pixels.\n"); printf(" -l, --line-width Width of the lines in pixels.\n"); printf(" -w, --wait Time to wait before drawing the next circle in microseconds.\n"); printf(" -c, --color Color; can either be an X11 color name or RGB as hex (i.e. #ff0055).\n"); printf("\n"); - printf("The defaults:\n"); - printf(" %s --size 220 --distance 40 --wait 400 --line-width 2 --color black\n", name); - printf("Draw a circle\n"); - printf(" %s --size 100 --distance 1 --wait 20 --line-width 1 --color black\n", name); + printf("Extra options:\n"); + printf(" -f, --follow Follow the cursor position as the cursor is moving.\n"); + printf(" -t, --transparent Make the window truly 'transparent'. This helps with\n"); + printf(" some display issues when following the cursor position,\n"); + printf(" but it doesn't work well with all WMs, which is why\n"); + printf(" it's disabled by default.\n"); + printf("\n"); + printf("Examples:\n"); + printf(" Defaults: %s --size 220 --distance 40 --wait 400 --line-width 2 --color black\n", name); + printf(" Circle: %s --size 100 --distance 1 --wait 20 --line-width 1 --color black\n", name); printf("\n"); } @@ -68,9 +81,11 @@ int main(int argc, char* argv[]) { int wait = 400; int line_width = 2; char color_name[64] = "black"; + int follow = 0; + int transparent = 0; int ch; - while ((ch = getopt_long(argc, argv, "hs:d:w:l:c:r:", longopts, NULL)) != -1) + while ((ch = getopt_long(argc, argv, "hs:d:w:l:c:r:ft", longopts, NULL)) != -1) switch (ch) { case 's': size = parse_num(ch, optarg, argv[0]); @@ -90,6 +105,12 @@ int main(int argc, char* argv[]) { case 'h': usage(argv[0]); exit(0); + case 'f': + follow = 1; + break; + case 't': + transparent = 1; + break; default: usage(argv[0]); exit(1); @@ -97,10 +118,16 @@ int main(int argc, char* argv[]) { argc -= optind; argv += optind; - draw(argv[0], size, distance, wait, line_width, color_name); + draw(argv[0], + size, distance, wait, line_width, color_name, + follow, transparent); } -void draw(char *name, int size, int distance, int wait, int line_width, char *color_name) { +void draw( + char *name, + int size, int distance, int wait, int line_width, char *color_name, + int follow, int transparent +) { // Setup display and such char *display_name = getenv("DISPLAY"); if (!display_name) { @@ -125,24 +152,39 @@ void draw(char *name, int size, int distance, int wait, int line_width, char *co &child_win, &root_win, &root_x, &root_y, &win_x, &win_y, &mask); - XVisualInfo vinfo; - XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &vinfo); - // Create a window at the mouse position + Window window; XSetWindowAttributes window_attr; window_attr.override_redirect = 1; - window_attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone); - window_attr.background_pixel = 0; - Window window = XCreateWindow(display, XRootWindow(display, screen), - root_x - size/2, root_y - size/2, // x, y position - size, size, // width, height - 4, // border width - vinfo.depth, // depth - CopyFromParent, // class - vinfo.visual, // visual - CWColormap | CWBorderPixel | CWBackPixel | CWOverrideRedirect, // valuemask - &window_attr // attributes - ); + + if (transparent) { + XVisualInfo vinfo; + XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &vinfo); + window_attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone); + window_attr.background_pixel = 0; + window = XCreateWindow(display, XRootWindow(display, screen), + root_x - size/2, root_y - size/2, // x, y position + size, size, // width, height + 4, // border width + vinfo.depth, // depth + CopyFromParent, // class + vinfo.visual, // visual + CWColormap | CWBorderPixel | CWBackPixel | CWOverrideRedirect, // valuemask + &window_attr // attributes + ); + } + else { + window = XCreateWindow(display, XRootWindow(display, screen), + root_x - size/2, root_y - size/2, // x, y position + size, size, // width, height + 4, // border width + DefaultDepth(display, screen), // depth + CopyFromParent, // class + DefaultVisual(display, screen), // visual + CWOverrideRedirect, // valuemask + &window_attr // attributes + ); + } // Make round shaped window. XGCValues xgcv; @@ -213,16 +255,21 @@ void draw(char *name, int size, int distance, int wait, int line_width, char *co // Draw the circles int i = 1; for (i=1; i<=size; i+=distance) { - XClearWindow(display, window); + if (follow) { + XClearWindow(display, window); + } + XDrawArc(display, window, gc, size/2 - i/2, size/2 - i/2, // x, y position i, i, // Size 0, 360 * 64); // Make it a full circle - XQueryPointer(display, XRootWindow(display, screen), - &child_win, &root_win, - &root_x, &root_y, &win_x, &win_y, &mask); - XMoveWindow(display, window, root_x - size/2, root_y - size/2); + if (follow) { + XQueryPointer(display, XRootWindow(display, screen), + &child_win, &root_win, + &root_x, &root_y, &win_x, &win_y, &mask); + XMoveWindow(display, window, root_x - size/2, root_y - size/2); + } XSync(display, False); usleep(wait * 100);