Compare commits

..

36 Commits
v1.0 ... master

Author SHA1 Message Date
Martin Tournoij
4a67d023ef
Use correct colormap with -t
Using the default colormap on a drawable w/ specific (ARGB) colormap for
rendering the arcs will lead to random colors being picked (typically
"white", but it can actually be anything) for the arcs. You have to use
the colormap specific to the drawawble (window)

Patch by luebking

Fixes #26
2024-04-08 17:43:36 +01:00
Martin Tournoij
925afa184f
Merge pull request #25 from qw3r3wq/patch-1
Added packages to install for Fedora 36
2022-05-09 17:56:54 +02:00
Ruslanas Gžibovskis
1d99800f94
Added packages to install for Fedora 36 2022-05-09 10:49:51 +03:00
Martin Tournoij
32f9e7f1d3
Merge pull request #24 from MikeWalrus/master
Specify the libraries after source files
2022-01-26 14:18:33 +01:00
Liao Junxuan
11ad767bd4 specify the libraries after source files 2022-01-24 00:16:43 +08:00
Martin Tournoij
a78c716475
Minor cleanup 2022-01-11 22:03:56 +01:00
Martin Tournoij
398e540c44
Merge pull request #23 from edsantiago/find_pointer_screen
Identify the correct screen
2022-01-11 22:00:36 +01:00
Eduardo Santiago
5fdb707a25 Identify the correct screen
On multiscreen systems, identify which screen the cursor is on.
Code copied shamelessly from xdotool.

Signed-off-by: Eduardo Santiago <ed@edsantiago.com>
2022-01-11 11:21:07 -07:00
Martin Tournoij
73fcc7d419 Accept argument in -o for outline width, add --outline-color
Fixes #21
2021-05-16 13:47:00 +08:00
Martin Tournoij
49f0ef9270 Don't really need a manpage 2020-12-06 17:24:38 +08:00
Martin Tournoij
9ed9ec581c
Mention how to toggle it on/off when repeating forever
Fixes #20
2020-05-28 20:21:27 +08:00
Martin Tournoij
1f32dd7238
Mention the Docker container
See #19
2020-05-19 09:58:36 +08:00
Martin Tournoij
cd2a08a96c
Mention -dev packages
Fixes #18
2020-05-05 11:08:15 +08:00
Martin Tournoij
45e937a7a3
Revert "Smoother experience when drawing a solid circle with --repeat 0 --follow"
This reverts commit 241ae5c0d4.
2020-04-21 23:34:57 +08:00
Martin Tournoij
241ae5c0d4
Smoother experience when drawing a solid circle with --repeat 0 --follow
Just move the window, instead of constantly creating and destroying new
ones.
2020-04-21 19:01:23 +08:00
Martin Tournoij
27f1a9699b
Fix some memory leaks
Not really noticeable when using it once since it's such a short-lived
program, but with "-r0" it can add up over time.

There may be other leaks, need to check/test to be sure (but valgrind
doesn't report any).

See: #17
2020-04-21 18:23:50 +08:00
Martin Tournoij
e2b8ae35da
Update funding 2020-03-30 20:39:33 +08:00
Martin Tournoij
21d69a8223
Centre on the mouse hotspot better
Use xhot and yhot to better get the "mouse hotspot". This should fix #15
2020-03-30 20:32:53 +08:00
Martin Tournoij
a22d1d1f0d
Fix typo in manpage 2020-03-30 19:31:41 +08:00
Martin Tournoij
87d9e18155
-r needs an argument
Fixes #16
2020-03-13 03:06:41 +08:00
Martin Tournoij
79f2a2f504
Update README 2019-12-05 16:16:34 +08:00
Martin Tournoij
e222a32479
Account for the cursor size
Should give a more accurate position most of the time. Also
XFixesGetCursorImage() is a lot simpler to use than XQueryPointer().
2019-12-05 16:09:32 +08:00
Martin Tournoij
49edf0b825
Update manpage 2019-12-05 04:22:27 +08:00
Martin Tournoij
49ce340e87
Make --repeat accept an argument 2019-12-05 04:15:35 +08:00
Kirill Bulygin
ff7be1dad0
Implement --repeat 2019-12-05 03:47:26 +08:00
Martin Tournoij
4951ce6718
Remove .travis.yml
Fails with:

	find-cursor.c:19:10: fatal error: 'X11/extensions/Xdamage.h' file not found

Travis just tests if it compiles anyway ... there's not much value here
and don't want to spend time fixing it.
2019-11-20 23:41:49 +08:00
Martin Tournoij
032ccd0256
Add funding file 2019-11-05 14:18:37 +08:00
Martin Tournoij
ba889debe4
Fix error message
Display correct error message;

	$ unset DISPLAY
	$ find-cursor
	find-cursor: DISPLAY not set

And no longer segfault

	$ DISPLAY=asdf find-cursor
	find-cursor: cannot open display 'asd'

Fixes #13
2019-07-10 22:37:30 +01:00
Markus Rinne
19c99b46b3 Remove unneeded statement (#14)
Variable 'argc' is never used after this statement.
2019-07-10 22:31:24 +01:00
Markus Rinne
db50bc256d
Don't print null display name (#11)
Variable 'display_name' is always null here.
2019-07-04 14:19:53 +01:00
Martin Tournoij
fcc5cb2534
Update README, add manpage 2019-03-05 11:02:51 +13:00
Martin Tournoij
222db0fb4d
Merge pull request #9 from 0mp/patch-1
Support LDFLAGS
2019-03-05 10:00:12 +13:00
Mateusz Piotrowski
19add1b666
Support LDFLAGS
This way it is easier to specify the path to libraries with -L.
2019-03-04 13:09:50 +01:00
Martin Tournoij
4a92f61bdf
Improve README 2018-09-20 12:16:10 +01:00
Martin Tournoij
eea197fbe1
Merge pull request #8 from maxice8/fix-makefile
Makefile: Fix installation and stripping
2018-09-20 12:12:13 +01:00
maxice8
3d5735acee
Makefile: Fix installation and stripping
- Separate stripping into another step of the package
- Conditionalize stripping the binary, distros don't like when packages do
it because they want the debug symbols included and do their own
stripping after extracting them
- use -Dm755 to create the directory (-D) and set the correct executable
mode
- respect PREFIX which can be set to /usr /usr/local and even /
- respect DESTDIR which is set by distros when they are packaging
2018-09-18 17:16:54 -03:00
8 changed files with 310 additions and 188 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
github: arp242

2
.gitignore vendored
View File

@ -1 +1 @@
find-cursor
/find-cursor

View File

@ -1,8 +0,0 @@
language: c
install: make
script: make
compiler:
- clang
- gcc
notifications:
email: false

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright © 2015-2017 Martin Tournoij
Copyright © Martin Tournoij
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to

View File

@ -1,8 +1,21 @@
CC?=cc
CFLAGS?=-std=c99 -pedantic -Wall -Os
CC ?= cc
PREFIX ?= /usr/local
NAME ?= find-cursor
CFLAGS += -std=c99 -pedantic -Wall -Wextra -Wpedantic -Os
LDFLAGS += -L/usr/lib
LIBS += -lX11 -lXext -lXfixes
.PHONY: all clean install uninstall
all:
${CC} ${CFLAGS} -o find-cursor find-cursor.c -lX11 -lXext -lXfixes
${CC} ${CFLAGS} ${LDFLAGS} -o ${NAME} *.c ${LIBS}
clean:
rm -f ${NAME}
install:
install --strip -o root -g root find-cursor /bin/
install -Dm755 ${NAME} ${DESTDIR}${PREFIX}/bin/${NAME}
uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/${NAME}

View File

@ -1,42 +0,0 @@
[![This project is considered stable](https://img.shields.io/badge/Status-stable-green.svg)](https://arp242.net/status/stable)
[![Build Status](https://travis-ci.org/Carpetsmoker/find-cursor.svg?branch=master)](https://travis-ci.org/Carpetsmoker/find-cursor)
Simple XLib program to highlight the cursor position. This is similar to the
feature found in Windows XP (and possibly later?)
![screenshot.gif](https://raw.githubusercontent.com/Carpetsmoker/find-cursor/master/screenshot.gif)
Using it
========
Compile it by typing `make`. Run `find-cursor -h to see some options for
controlling the appearance.
- The author runs it with [`xcape`][xcape]:
xcape -e 'Control_L=Escape;Shift_L=KP_Add'
When Left shift is tapped, a Keypad Add is sent I don't have a numpad on my
keyboard which we can then use to launch the program.
- I configured my window manager (PekWM) to pick up Numpad Add and launch this:
KeyPress = "KP_Add" { Actions = "Exec find-cursor" }
I'm not going to include instructions for every window manager out there.
I'm sure you can figure out how to use it with your WM ;-) You can also use
[`xbindkeys`](xbindkeys), which should work with `$any` window manager.
- You may want to disable shadows if you use compton or some other composite
manager; for example for compton start it with:
compton --shadow-exclude "class_g = 'find-cursor'"
Or, perhaps even better, disable it for all shaped windows:
compton --shadow-exclude 'bounding_shaped'
You can also put that in the compton config file. Other managers might have
different options/flags.
[xcape]: https://github.com/alols/xcape
[xbindkeys]: http://www.nongnu.org/xbindkeys/xbindkeys.html

70
README.md Normal file
View File

@ -0,0 +1,70 @@
Simple XLib program to highlight the cursor position. This is similar to the
feature found in Windows XP (and possibly later?)
![screenshot.gif](https://raw.githubusercontent.com/arp242/find-cursor/master/screenshot.gif)
Installation
------------
Compile it by typing `make`, install it with `make install`. There
[packages][pkg] for some platforms as well.
You'll need to install some X11 header files on some systems; e.g. on
Ubuntu/Debian: `libx11-dev`, `libxcomposite-dev`, `libxdamage-dev`, and
`libxrender-dev`. For Fedora 36 you might need to install following:
`libXext-devel`, `libXdamage-devel`, `libXrender-devel`, `libXext-devel`.
There is also a Docker container at [klo2k/find-cursor][d] if you want it. Note
this is NOT maintained (or supported) by me. See #19.
[d]: https://hub.docker.com/r/klo2k/find-cursor
[pkg]: https://repology.org/project/find-cursor/versions
Usage
-----
See `find-cursor -h` to see some options for controlling the appearance.
Launching
---------
You will want to map a key in your window manager to run `find-cursor`. You can
also use [`xbindkeys`](xbindkeys), which should work with `$any` window manager.
I run it with [`xcape`][xcape]:
xcape -e 'Control_L=Escape;Shift_L=KP_Add'
When `Left Shift` is tapped a `Keypad Add` is sent; I configured my window
manager to launch `find-cursor` with that.
I don't have a numpad on my keyboard; you can also use `F13` or some other
unused key.
You can use a little wrapper script if you want a "toggle" switch for when
repeating forever:
#!/bin/sh
if pgrep find-cursor; then
pkill find-cursor
else
find-cursor -r0 &
fi
Compton
-------
You may want to disable shadows if you use compton or some other composite
manager; for example for compton start it with:
compton --shadow-exclude "class_g = 'find-cursor'"
Or, perhaps even better, disable it for all shaped windows:
compton --shadow-exclude 'bounding_shaped'
You can also put that in the compton config file. Other managers might have
different options/flags.
[xcape]: https://github.com/alols/xcape
[xbindkeys]: http://www.nongnu.org/xbindkeys/xbindkeys.html

View File

@ -1,10 +1,10 @@
/*
* http://code.arp242.net/find-cursor
* Copyright © 2015-2017 Martin Tournoij <martin@arp242.net>
* Copyright © Martin Tournoij <martin@arp242.net>
* See below for full copyright
*/
#define _XOPEN_SOURCE 500
#define _DEFAULT_SOURCE
#include <getopt.h>
#include <stdint.h>
@ -22,12 +22,12 @@
void usage(char *name);
int parse_num(int ch, char *opt, char *name);
void draw(
char *name,
int pointer_screen(char *name, Display *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 follow, int transparent, int grow, int outline, char *ocolor_name);
static struct option longopts[] = {
static struct option longopts[] = {
{"help", no_argument, NULL, 'h'},
{"size", required_argument, NULL, 's'},
{"distance", required_argument, NULL, 'd'},
@ -37,53 +37,77 @@ static struct option longopts[] = {
{"follow", no_argument, NULL, 'f'},
{"transparent", no_argument, NULL, 't'},
{"grow", no_argument, NULL, 'g'},
{"outline", no_argument, NULL, 'o'},
{"outline", optional_argument, NULL, 'o'}, // Optional for compat, as previously it was hard-coded to 2px.
{"repeat", required_argument, NULL, 'r'},
{"outline-color", required_argument, NULL, 'O'},
{NULL, 0, NULL, 0}
};
};
void usage(char *name) {
printf("Usage: %s [-stplcftg]\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\n");
printf(" microseconds.\n");
printf(" -c, --color Color; can either be an X11 color name or RGB as hex.\n");
printf(" -g, --grow Grow the animation in size, rather than shrinking it.\n");
printf("\n");
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(" -o, --outline Draw an outline in the opposite color as well. Helps\n");
printf(" visibility on all backgrounds.\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", name);
printf("\n");
printf(""
"find-cursor highlights the cursor position by drawing circles around it.\n"
"https://github.com/arp242/find-cursor\n"
"\n"
"Flags:\n"
" -h, --help Show this help.\n"
"\n"
"Shape options:\n"
" -s, --size Maximum size the circle will grow to in pixels.\n"
" -d, --distance Distance between the circles in pixels.\n"
" -l, --line-width Width of the lines in pixels.\n"
" -w, --wait Time to wait before drawing the next circle in\n"
" tenths of milliseconds.\n"
" -c, --color Color as X11 color name or RGB (e.g. #ff0000)\n"
" -g, --grow Grow the animation in size, rather than shrinking it.\n"
"\n"
"Extra options:\n"
" -f, --follow Follow the cursor position as the cursor is moving.\n"
" -t, --transparent Make the window truly 'transparent'. This helps with\n"
" some display issues when following the cursor position,\n"
" but it doesn't work well with all WMs, which is why\n"
" it's disabled by default.\n"
" -o, --outline Width in pixels of outline; uses 2px if no value is given.\n"
" Helps visibility on all backgrounds.\n"
" -O, --outline-color Color of outline; if omitted it will automatically use\n"
" the opposite color. No effect if -o isn't set.\n"
" -r, --repeat Number of times to repeat the animation; use 0 to repeat\n"
" indefinitely.\n"
"\n"
"Examples:\n"
" The defaults:\n"
" %s --size 320 --distance 40 --wait 400 --line-width 4 --color black\n\n"
" Draw a solid circle:\n"
" %s --size 100 --distance 1 --wait 20 --line-width 1\n\n"
" Always draw a full circle on top of the cursor:\n"
" %s --repeat 0 --follow --distance 1 --wait 1 --line-width 16 --size 16\n"
"\n"
"Launching:\n"
" You will want to map a key in your window manager to run find-cursor.\n"
" You can also use xbindkeys, which should work with any window manager.\n"
"\n"
" I run it with xcape:\n"
" xcape -e 'Control_L=Escape;Shift_L=KP_Add'\n"
"\n"
" When Left Shift is tapped a Keypad Add is sent; I configured my window\n"
" manager to launch find-cursor with that.\n"
"\n"
" I don't have a numpad on my keyboard; you can also use F13 or some\n"
" other unused key.\n",
name, name, name);
}
// Parse number from commandline, or show error and exit if it's not a number.
int parse_num(int ch, char *opt, char *name) {
char *end;
long result = strtol(optarg, &end, 10);
long result = strtol(opt, &end, 10);
if (*end) {
fprintf(stderr, "%s: %d must be a number\n", name, ch);
fprintf(stderr, "%s: value for -%c must be a number\n\n", name, ch);
usage(name);
exit(1);
}
return result;
}
int main(int argc, char* argv[]) {
// Parse options
int size = 320;
@ -91,13 +115,16 @@ int main(int argc, char* argv[]) {
int wait = 400;
int line_width = 4;
char color_name[64] = "black";
char ocolor_name[64];
int follow = 0;
int transparent = 0;
int grow = 0;
int outline = 0;
int repeat = 0;
extern int optopt;
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:r:ftgo:O:", longopts, NULL)) != -1)
switch (ch) {
case 's':
size = parse_num(ch, optarg, argv[0]);
@ -127,82 +154,140 @@ int main(int argc, char* argv[]) {
grow = 1;
break;
case 'o':
outline = 1;
outline = parse_num(ch, optarg, argv[0]);
break;
case 'O':
strncpy(ocolor_name, optarg, sizeof(ocolor_name));
break;
case 'r':
repeat = parse_num(ch, optarg, argv[0]);
if (repeat == 0)
repeat = -1;
break;
case ':':
switch (optopt) {
case 'o':
outline = 2;
break;
default:
fprintf(stderr, "%s: missing required argument for -%c\n\n", argv[0], optopt);
usage(argv[0]);
exit(1);
}
break;
case '?':
fprintf(stderr, "%s: invalid option: -%c\n\n", argv[0], ch);
// fallthrough
default:
usage(argv[0]);
exit(1);
}
argc -= optind;
argv += optind;
draw(argv[0],
size, distance, wait, line_width, color_name,
follow, transparent, grow, outline);
}
void draw(
char *name,
int size, int distance, int wait, int line_width, char *color_name,
int follow, int transparent, int grow, int outline
) {
// Setup display and such
char *display_name = getenv("DISPLAY");
if (!display_name) {
fprintf(stderr, "%s: cannot connect to X server '%s'\n", name, display_name);
fprintf(stderr, "%s: DISPLAY not set\n\n", argv[0]);
exit(1);
}
Display *display = XOpenDisplay(display_name);
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);
if (!display) {
fprintf(stderr, "%s: cannot open display '%s'\n\n", argv[0], display_name);
exit(1);
}
// Get the mouse cursor position
int win_x, win_y, root_x, root_y = 0;
unsigned int mask = 0;
Window child_win, root_win;
XQueryPointer(display, XRootWindow(display, screen),
&child_win, &root_win,
&root_x, &root_y, &win_x, &win_y, &mask);
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\n", argv[0], display_name);
exit(1);
}
// Actually draw.
do
draw(argv[0], display, pointer_screen(argv[0], display),
size, distance, wait, line_width, color_name,
follow, transparent, grow, outline, ocolor_name);
while (repeat == -1 || repeat--);
XCloseDisplay(display);
}
// Identify which screen the cursor is on.
int pointer_screen(char *name, Display *display) {
int screencount = ScreenCount(display);
// The traditional case
if (screencount == 1)
return DefaultScreen(display);
// Multihead
for (int s=0; s < screencount; s++) {
Window root, win;
int unused = 0;
unsigned int unusedu = 0;
Screen *screen = ScreenOfDisplay(display, s);
int found = XQueryPointer(display, RootWindowOfScreen(screen),
&root, &win, &unused, &unused, &unused, &unused, &unusedu);
if (found)
return s;
}
// Fall through (should never happen)
fprintf(stderr, "%s: Unable to identify pointer screen, using Default\n", name);
return DefaultScreen(display);
}
// Try to get the centre of the cursor.
void cursor_center(Display *display, int size, int *x, int *y) {
XFixesCursorImage *c = XFixesGetCursorImage(display);
*x = c->x - size/2 - c->width/2 + c->xhot;
*y = c->y - size/2 - c->height/2 + c->yhot;
XFree(c);
}
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, char *ocolor_name
) {
// Get the mouse cursor position and size.
int center_x, center_y;
cursor_center(display, size, &center_x, &center_y);
// Create a window at the mouse position
Window window;
XSetWindowAttributes window_attr;
window_attr.override_redirect = 1;
Colormap colormap = DefaultColormap(display, screen);
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);
colormap = window_attr.colormap;
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
center_x, // x position
center_y, // 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
);
&window_attr); // attributes
}
else {
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
);
}
center_x, // x position
center_y, // 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;
@ -215,9 +300,10 @@ void draw(
0, 0, // x, y position
size, size, // Size
0, 360 * 64); // Make it a full circle
XFreeGC(display, part_shape);
XShapeCombineMask(display, window, ShapeBounding, 0,0, shape_mask, ShapeSet);
XShapeCombineMask(display, window, ShapeClip, 0,0, shape_mask, ShapeSet);
XShapeCombineMask(display, window, ShapeBounding, 0, 0, shape_mask, ShapeSet);
XShapeCombineMask(display, window, ShapeClip, 0, 0, shape_mask, ShapeSet);
XFreePixmap(display, shape_mask);
// Input region is small so we can pass input events.
@ -264,20 +350,31 @@ void draw(
unsigned long valuemask = 0;
GC gc = XCreateGC(display, window, valuemask, &values);
Colormap colormap = DefaultColormap(display, screen);
// Get colours.
XColor color;
XAllocNamedColor(display, colormap, color_name, &color, &color);
int err = XAllocNamedColor(display, colormap, color_name, &color, &color);
if (err == 0) {
fprintf(stderr, "%s: invalid color value for -c/--color: '%s'\n\n", name, color_name);
usage(name);
exit(1);
}
XColor color2;
char color2_name[14]; // hash + 3x4-digit hex
if (outline) {
// Insert and convert to XColor.
color2.red = 65535 - color.red;
color2.green = 65535 - color.green;
color2.blue = 65535 - color.blue;
sprintf(color2_name,"#%04X%04X%04X", color2.red,color2.green, color2.blue);
XAllocNamedColor(display, colormap, color2_name, &color2, &color2);
} else {
if (outline > 0) {
if (ocolor_name[0] == 0) { // Use opposite colour.
color2.red = 65535 - color.red;
color2.green = 65535 - color.green;
color2.blue = 65535 - color.blue;
sprintf(ocolor_name, "#%04X%04X%04X", color2.red, color2.green, color2.blue);
}
int err = XAllocNamedColor(display, colormap, ocolor_name, &color2, &color2);
if (err == 0) {
fprintf(stderr, "%s: invalid color value for -O/--outline-color: '%s'\n\n", name, ocolor_name);
usage(name);
exit(1);
}
}
else {
// Set colour only once if not outline.
XSetLineAttributes(display, gc, line_width, LineSolid, CapButt, JoinBevel);
XSetForeground(display, gc, color.pixel);
@ -285,19 +382,14 @@ void draw(
// Draw the circles
int i = 1;
for (i=1; i<=size; i+=distance) {
if (follow) {
for (i=1; i<=size; i+=distance) {
if (follow)
XClearWindow(display, window);
}
int cs;
if (grow)
cs = i;
else
cs = size - i;
int cs = grow ? i : size - i;
if (outline) {
XSetLineAttributes(display, gc, line_width+2, LineSolid, CapButt, JoinBevel);
if (outline > 0) {
XSetLineAttributes(display, gc, line_width+outline, LineSolid, CapButt, JoinBevel);
XSetForeground(display, gc, color2.pixel);
XDrawArc(display, window, gc,
size/2 - cs/2, size/2 - cs/2, // x, y position
@ -315,10 +407,8 @@ void draw(
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);
cursor_center(display, size, &center_x, &center_y);
XMoveWindow(display, window, center_x, center_y);
}
XSync(display, False);
@ -326,30 +416,28 @@ void draw(
}
XFreeGC(display, gc);
XCloseDisplay(display);
XDestroyWindow(display, window);
}
/*
* The MIT License (MIT)
/* The MIT License (MIT)
*
* Copyright © 2015-2017 Martin Tournoij
* Copyright © Martin Tournoij
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* The software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising
* from, out of or in connection with the software or the use or other dealings
* in the software.
*/
* The software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising
* from, out of or in connection with the software or the use or other dealings
* in the software. */