|
|
|
@ -23,7 +23,7 @@
|
|
|
|
|
void usage(char *name);
|
|
|
|
|
int parse_num(int ch, char *opt, char *name);
|
|
|
|
|
void draw(
|
|
|
|
|
char *name,
|
|
|
|
|
char *name, Display *display, int screen,
|
|
|
|
|
int size, int distance, int wait, int line_width, char *color_name,
|
|
|
|
|
int follow, int transparent, int grow, int outline, int repeat);
|
|
|
|
|
|
|
|
|
@ -38,12 +38,12 @@ static struct option longopts[] = {
|
|
|
|
|
{"transparent", no_argument, NULL, 't'},
|
|
|
|
|
{"grow", no_argument, NULL, 'g'},
|
|
|
|
|
{"outline", no_argument, NULL, 'o'},
|
|
|
|
|
{"repeat", no_argument, NULL, 'r'},
|
|
|
|
|
{"repeat", required_argument, NULL, 'r'},
|
|
|
|
|
{NULL, 0, NULL, 0}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void usage(char *name) {
|
|
|
|
|
printf("Usage: %s [-stplcftg]\n\n", name);
|
|
|
|
|
printf("Usage: %s [-stplcftgr]\n\n", name);
|
|
|
|
|
printf(" -h, --help Show this help.\n");
|
|
|
|
|
printf("\n");
|
|
|
|
|
printf("Shape options:\n");
|
|
|
|
@ -63,15 +63,16 @@ void usage(char *name) {
|
|
|
|
|
printf(" it's disabled by default.\n");
|
|
|
|
|
printf(" -o, --outline Draw an outline in the opposite color as well. Helps\n");
|
|
|
|
|
printf(" visibility on all backgrounds.\n");
|
|
|
|
|
printf(" -r, --repeat Repeat the animation indefinitely.\n");
|
|
|
|
|
printf(" -r, --repeat Number of times to repeat the animation; use 0 to repeat\n");
|
|
|
|
|
printf(" indefinitely.\n");
|
|
|
|
|
printf("\n");
|
|
|
|
|
printf("Examples:\n");
|
|
|
|
|
printf(" The defaults:\n");
|
|
|
|
|
printf(" %s --size 320 --distance 40 --wait 400 --line-width 4 --color black\n\n", name);
|
|
|
|
|
printf(" Draw a solid circle:\n");
|
|
|
|
|
printf(" %s --size 100 --distance 1 --wait 20 --line-width 1\n\n", name);
|
|
|
|
|
printf(" Constantly highlight the cursor:\n");
|
|
|
|
|
printf(" %s -r -c white -o -l1 -s10 -d1 -w1000 -ft\n", name);
|
|
|
|
|
printf(" Always draw a full circle on top of the cursor:\n");
|
|
|
|
|
printf(" %s --repeat 0 --follow --distance 1 --wait 1 --line-width 16 --size 16", name);
|
|
|
|
|
printf("\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -102,7 +103,7 @@ int main(int argc, char* argv[]) {
|
|
|
|
|
int repeat = 0;
|
|
|
|
|
|
|
|
|
|
int ch;
|
|
|
|
|
while ((ch = getopt_long(argc, argv, "hs:d:w:l:c:r:ftgo", longopts, NULL)) != -1)
|
|
|
|
|
while ((ch = getopt_long(argc, argv, "hs:d:w:l:c:rftgo", longopts, NULL)) != -1)
|
|
|
|
|
switch (ch) {
|
|
|
|
|
case 's':
|
|
|
|
|
size = parse_num(ch, optarg, argv[0]);
|
|
|
|
@ -135,43 +136,50 @@ int main(int argc, char* argv[]) {
|
|
|
|
|
outline = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'r':
|
|
|
|
|
repeat = 1;
|
|
|
|
|
repeat = parse_num(ch, optarg, argv[0]);
|
|
|
|
|
if (repeat == 0)
|
|
|
|
|
repeat = -1;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
usage(argv[0]);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
draw(argv[0],
|
|
|
|
|
size, distance, wait, line_width, color_name,
|
|
|
|
|
follow, transparent, grow, outline, repeat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void draw(
|
|
|
|
|
char *name,
|
|
|
|
|
int size, int distance, int wait, int line_width, char *color_name,
|
|
|
|
|
int follow, int transparent, int grow, int outline, int repeat
|
|
|
|
|
) {
|
|
|
|
|
// Setup display and such
|
|
|
|
|
char *display_name = getenv("DISPLAY");
|
|
|
|
|
if (!display_name) {
|
|
|
|
|
fprintf(stderr, "%s: DISPLAY not set\n", name);
|
|
|
|
|
fprintf(stderr, "%s: DISPLAY not set\n", argv[0]);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Display *display = XOpenDisplay(display_name);
|
|
|
|
|
if (!display) {
|
|
|
|
|
fprintf(stderr, "%s: cannot open display '%s'\n", name, display_name);
|
|
|
|
|
fprintf(stderr, "%s: cannot open display '%s'\n", argv[0], display_name);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
int screen = DefaultScreen(display);
|
|
|
|
|
|
|
|
|
|
int shape_event_base, shape_error_base;
|
|
|
|
|
if (!XShapeQueryExtension(display, &shape_event_base, &shape_error_base)) {
|
|
|
|
|
fprintf(stderr, "%s: no XShape extension for display '%s'\n", name, display_name);
|
|
|
|
|
fprintf(stderr, "%s: no XShape extension for display '%s'\n", argv[0], display_name);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Actually draw.
|
|
|
|
|
do {
|
|
|
|
|
draw(argv[0], display, screen,
|
|
|
|
|
size, distance, wait, line_width, color_name,
|
|
|
|
|
follow, transparent, grow, outline, repeat);
|
|
|
|
|
} while (repeat == -1 || repeat--);
|
|
|
|
|
|
|
|
|
|
XCloseDisplay(display);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void draw(
|
|
|
|
|
char *name, Display *display, int screen,
|
|
|
|
|
int size, int distance, int wait, int line_width, char *color_name,
|
|
|
|
|
int follow, int transparent, int grow, int outline, int repeat
|
|
|
|
|
) {
|
|
|
|
|
// Get the mouse cursor position
|
|
|
|
|
int win_x, win_y, root_x, root_y = 0;
|
|
|
|
|
unsigned int mask = 0;
|
|
|
|
@ -187,7 +195,7 @@ void draw(
|
|
|
|
|
|
|
|
|
|
if (transparent) {
|
|
|
|
|
XVisualInfo vinfo;
|
|
|
|
|
XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &vinfo);
|
|
|
|
|
XMatchVisualInfo(display, screen, 32, TrueColor, &vinfo);
|
|
|
|
|
window_attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone);
|
|
|
|
|
window_attr.background_pixel = 0;
|
|
|
|
|
window = XCreateWindow(display, XRootWindow(display, screen),
|
|
|
|
@ -294,51 +302,49 @@ void draw(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw the circles
|
|
|
|
|
do {
|
|
|
|
|
int i = 1;
|
|
|
|
|
for (i=1; i<=size; i+=distance) {
|
|
|
|
|
if (follow) {
|
|
|
|
|
XClearWindow(display, window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int cs;
|
|
|
|
|
if (grow)
|
|
|
|
|
cs = i;
|
|
|
|
|
else
|
|
|
|
|
cs = size - i;
|
|
|
|
|
|
|
|
|
|
if (outline) {
|
|
|
|
|
XSetLineAttributes(display, gc, line_width+2, LineSolid, CapButt, JoinBevel);
|
|
|
|
|
XSetForeground(display, gc, color2.pixel);
|
|
|
|
|
XDrawArc(display, window, gc,
|
|
|
|
|
size/2 - cs/2, size/2 - cs/2, // x, y position
|
|
|
|
|
cs, cs, // Size
|
|
|
|
|
0, 360 * 64); // Make it a full circle
|
|
|
|
|
|
|
|
|
|
// Set color back for the normal circle.
|
|
|
|
|
XSetLineAttributes(display, gc, line_width, LineSolid, CapButt, JoinBevel);
|
|
|
|
|
XSetForeground(display, gc, color.pixel);
|
|
|
|
|
}
|
|
|
|
|
int i = 1;
|
|
|
|
|
for (i=1; i<=size; i+=distance) {
|
|
|
|
|
if (follow) {
|
|
|
|
|
XClearWindow(display, window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int cs;
|
|
|
|
|
if (grow)
|
|
|
|
|
cs = i;
|
|
|
|
|
else
|
|
|
|
|
cs = size - i;
|
|
|
|
|
|
|
|
|
|
if (outline) {
|
|
|
|
|
XSetLineAttributes(display, gc, line_width+2, LineSolid, CapButt, JoinBevel);
|
|
|
|
|
XSetForeground(display, gc, color2.pixel);
|
|
|
|
|
XDrawArc(display, window, gc,
|
|
|
|
|
size/2 - cs/2, size/2 - cs/2, // x, y position
|
|
|
|
|
cs, cs, // Size
|
|
|
|
|
0, 360 * 64); // Make it a full circle
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
// Set color back for the normal circle.
|
|
|
|
|
XSetLineAttributes(display, gc, line_width, LineSolid, CapButt, JoinBevel);
|
|
|
|
|
XSetForeground(display, gc, color.pixel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XDrawArc(display, window, gc,
|
|
|
|
|
size/2 - cs/2, size/2 - cs/2, // x, y position
|
|
|
|
|
cs, cs, // Size
|
|
|
|
|
0, 360 * 64); // Make it a full circle
|
|
|
|
|
|
|
|
|
|
XSync(display, False);
|
|
|
|
|
usleep(wait * 100);
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
} while (repeat);
|
|
|
|
|
|
|
|
|
|
XSync(display, False);
|
|
|
|
|
usleep(wait * 100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XFreeGC(display, gc);
|
|
|
|
|
XCloseDisplay(display);
|
|
|
|
|
XDestroyWindow(display, window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|