Commit | Line | Data |
---|---|---|
21c4e167 H |
1 | #include <sys/types.h> |
2 | #include <stdio.h> | |
3 | #include <stdlib.h> | |
4 | #include <string.h> | |
5 | #include <ctype.h> | |
6 | #include <stdarg.h> | |
7 | ||
8 | #include <X11/X.h> | |
9 | #include <X11/Xlib.h> | |
10 | #include <X11/Xutil.h> | |
11 | ||
12 | void | |
13 | usage(const char *err, ...) | |
14 | { | |
15 | va_list va; | |
16 | va_start(va, err); | |
17 | ||
18 | fprintf(stderr, "ERROR: "); | |
19 | vfprintf(stderr, err, va); | |
20 | ||
21 | va_end(va); | |
22 | ||
23 | fprintf(stderr, "\n" | |
24 | "usage: xwarppointer <command> <args>\n\n" | |
25 | " commands:\n" | |
26 | " screen <+/-> | <screen #> Move cursor to specific screen, or \n" | |
27 | " relative to current one. Does not change \n" | |
28 | " the cursor's position on the screen. \n" | |
29 | "\n" | |
30 | " abspos <x|.> <y|.> Moves cursor to given X and Y coordinates.\n" | |
31 | " If . is specified instead of a #, it \n" | |
32 | " doesn't change that axis. \n" | |
33 | "\n" | |
34 | " relpos <x offset> <y offset> Move the cursor relative to its current \n" | |
35 | " position. \n" | |
36 | "\n" | |
37 | " get Return the cursors position. \n" | |
38 | "\n"); | |
39 | exit(1); | |
40 | } | |
41 | ||
42 | int | |
43 | myatoi(const char *str, int *ret) { | |
44 | char *p; | |
45 | int i; | |
46 | ||
47 | i = strtod(str, &p); | |
48 | if (p == str) | |
49 | return 0; | |
50 | *ret = i; | |
51 | return 1; | |
52 | } | |
53 | ||
54 | int | |
55 | main(int argc, char *argv[]) | |
56 | { | |
57 | Display *display; | |
58 | Window root; | |
59 | ||
60 | if ((display = XOpenDisplay(NULL)) == NULL) { | |
61 | fprintf(stderr, "Cannot open local X-display.\n"); | |
62 | exit(1); | |
63 | } | |
64 | root = DefaultRootWindow(display); | |
65 | ||
66 | if (argc < 2) usage("wrong number of args"); | |
67 | ||
68 | if (!strcasecmp(argv[1], "screen")) { | |
69 | Window fromroot, tmpwin; | |
70 | XWindowAttributes attr; | |
71 | int screen = -1, rot, x, y, tmp; | |
72 | ||
73 | if (argc != 3) | |
74 | usage("screen: wrong number of args"); | |
75 | ||
76 | if (*argv[2] == '+') | |
77 | rot = 1; | |
78 | else if (*argv[2] == '-') | |
79 | rot = -1; | |
80 | else | |
81 | screen = atoi(argv[2]); | |
82 | ||
83 | XQueryPointer(display, root, &fromroot, &tmpwin, &x, &y, &tmp, &tmp, &tmp); | |
84 | ||
85 | if (screen == -1) { | |
86 | XGetWindowAttributes(display, fromroot, &attr); | |
87 | screen = XScreenNumberOfScreen(attr.screen); | |
88 | ||
89 | screen += rot; | |
90 | if (screen >= ScreenCount(display)) | |
91 | screen -= ScreenCount(display); | |
92 | if (screen < 0) | |
93 | screen += ScreenCount(display); | |
94 | ||
95 | } else { | |
96 | if (screen >= ScreenCount(display) || screen < 0) { | |
97 | fprintf(stderr, "Cannot get root window of screen!\n"); | |
98 | exit(1); | |
99 | } | |
100 | } | |
101 | ||
102 | root = RootWindow(display, screen); | |
103 | XWarpPointer(display, None, root, 0, 0, 0, 0, x, y); | |
104 | XFlush(display); | |
105 | ||
106 | } else if (!strcasecmp(argv[1], "abspos")) { | |
107 | int x, y, tmp; | |
108 | Window fromroot, tmpwin; | |
109 | ||
110 | if (argc != 4) | |
111 | usage("abspos: wrong number of args"); | |
112 | ||
113 | XQueryPointer(display, root, &fromroot, &tmpwin, &x, &y, &tmp, &tmp, &tmp); | |
114 | ||
115 | if (argv[2][0] != '.') | |
116 | if (!myatoi(argv[2], &x)) | |
117 | usage("abspos: invalid x pos: %s", argv[2]); | |
118 | if (argv[3][0] != '.') | |
119 | if (!myatoi(argv[3], &y)) | |
120 | usage("abspos: invalid y pos: %s", argv[3]); | |
121 | ||
122 | XWarpPointer(display, None, root, 0, 0, 0, 0, x, y); | |
123 | XFlush(display); | |
124 | ||
125 | } else if (!strcasecmp(argv[1], "relpos")) { | |
126 | int x, y, tmp, x2, y2; | |
127 | Window fromroot, tmpwin; | |
128 | ||
129 | if (argc != 4) | |
130 | usage("relpos: wrong number of args"); | |
131 | ||
132 | XQueryPointer(display, root, &fromroot, &tmpwin, &x, &y, &tmp, &tmp, &tmp); | |
133 | ||
134 | if (!myatoi(argv[2], &x2)) usage("relpos: invalid x pos: %s", argv[2]); | |
135 | if (!myatoi(argv[3], &y2)) usage("relpos: invalid y pos: %s", argv[3]); | |
136 | x += x2; | |
137 | y += y2; | |
138 | ||
139 | XWarpPointer(display, None, root, 0, 0, 0, 0, x, y); | |
140 | XFlush(display); | |
141 | ||
142 | } else if (!strcasecmp(argv[1], "get")) { | |
143 | int x, y, tmp; | |
144 | Window fromroot, tmpwin; | |
145 | ||
146 | if (argc != 2) | |
147 | usage("get: wrong number of args"); | |
148 | ||
149 | XQueryPointer(display, root, &fromroot, &tmpwin, &x, &y, &tmp, &tmp, &tmp); | |
150 | ||
151 | printf("%d %d\n", x, y); | |
152 | ||
153 | } else { | |
154 | usage("invalid command: %s", argv[1]); | |
155 | } | |
156 | ||
157 | exit(0); | |
158 | } |