3 * Warp pointer to a specific location
5 * (c) 2022 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the Edgeware X tools collection.
12 * X tools is free software: you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
17 * X tools is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * You should have received a copy of the GNU General Public License
23 * along with X tools. If not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 /*----- Header files ------------------------------------------------------*/
36 #include <mLib/alloc.h>
37 #include <mLib/macros.h>
38 #include <mLib/mdwopt.h>
39 #include <mLib/quis.h>
40 #include <mLib/report.h>
42 /*----- Help and version information --------------------------------------*/
44 static void version(void)
45 { pquis(stdout
, "$ version " VERSION
"\n"); }
47 static void usage(FILE *fp
)
48 { pquis(fp
, "Usage: $ [-r] [-d DISPLAY] X Y\n"); }
50 static void help(void)
52 version(); putchar('\n');
55 Warp mouse pointer to position X, Y on the screen.\n\
57 Command-line options:\n\
59 -h, --help Display this help.\n\
60 -v, --version Display program's version number.\n\
61 -u, --usage Display short usage summary.\n\
63 -d, --display=DISPLAY Connect to X DISPLAY.\n\
64 -r, --relative Move relative to its current position\n",
68 /*----- Main program ------------------------------------------------------*/
70 static int parse_int(const char *p
)
76 err
= errno
; errno
= 0;
77 if (!*p
|| ISSPACE(*p
)) goto bad
;
79 if (err
|| *q
|| i
< INT_MIN
|| i
> INT_MAX
) goto bad
;
83 die(1, "bad integer `%s'", p
);
86 int main(int argc
, char *argv
[])
88 const char *display
= 0;
92 char **fixups
; int nfixups
, i
;
93 int x
, y
, xmin
, xmax
, ymin
, ymax
, wd
, ht
;
102 /* An initial pass over the argument vector.
104 * Negative numbers look like options, but we don't want them treated that
105 * way. So we're going to hide them from the option parser for a bit.
107 fixups
= xmalloc(argc
*sizeof(char *));
108 for (i
= 0, nfixups
= 0; i
< argc
; i
++)
109 if (argv
[i
][0] == '-' && ISDIGIT(argv
[i
][1]))
110 { fixups
[nfixups
++] = argv
[i
]; argv
[i
][0] = '?'; }
112 /* Parse arguments. */
114 static struct option opt
[] = {
115 { "help", 0, 0, 'h' },
116 { "usage", 0, 0, 'u' },
117 { "version", 0, 0, 'v' },
118 { "display", OPTF_ARGREQ
, 0, 'd' },
119 { "relative", 0, 0, 'r' },
123 i
= mdwopt(argc
, argv
, "huvd:r", opt
, 0, 0, 0); if (i
< 0) break;
125 case 'h': help(); exit(0);
126 case 'u': usage(stdout
); exit(0);
127 case 'v': version(); exit(0);
128 case 'd': display
= optarg
; break;
129 case 'r': f
|= f_relative
; break;
130 default: f
|= f_bogus
; break;
133 if ((f
&f_bogus
) || argc
- optind
!= 2) {
138 /* Undo the fixups and fish out the numbers. */
139 for (i
= 0; i
< nfixups
; i
++) *fixups
[i
] = '-';
140 x
= parse_int(argv
[optind
]);
141 y
= parse_int(argv
[optind
+ 1]);
143 /* Open the display and the screen size. */
144 if ((dpy
= XOpenDisplay(display
)) == 0)
145 die(EXIT_FAILURE
, "couldn't open display");
146 sc
= DefaultScreen(dpy
);
147 wd
= DisplayWidth(dpy
, sc
);
148 ht
= DisplayHeight(dpy
, sc
);
150 /* Interpret the coordinates and check that they're in range. */
153 xmin
= -wd
+ 1; ymin
= -ht
+ 1; xmax
= wd
- 1; ymax
= ht
- 1;
157 w
= RootWindow(dpy
, sc
);
158 xmin
= ymin
= 0; xmax
= wd
- 1; ymax
= ht
- 1;
160 if (x
< xmin
|| x
> xmax
|| y
< ymin
|| y
> ymax
)
161 die(1, "coordinates out of range");
164 XWarpPointer(dpy
, None
, w
, 0, 0, 0, 0, x
, y
);
174 /*----- That's all, folks -------------------------------------------------*/