aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-02-04 17:14:39 -0500
committerB. Watson <urchlay@slackware.uk>2024-02-04 17:14:39 -0500
commit5442b754d70837d5fd8db1ee59a1649414f4bb77 (patch)
tree8e959f32dc856d4bcb3eeeb2fd3ad13fdd4af4e3
parent4b2687afb6ebb1bd288292f578a057ab175fc02e (diff)
downloadxdeadzone-5442b754d70837d5fd8db1ee59a1649414f4bb77.tar.gz
Simplify option parsing.
-rw-r--r--xdeadzone.c120
1 files changed, 65 insertions, 55 deletions
diff --git a/xdeadzone.c b/xdeadzone.c
index 70d57cd..dc787d1 100644
--- a/xdeadzone.c
+++ b/xdeadzone.c
@@ -8,6 +8,7 @@
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
+#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -27,9 +28,10 @@
# define DBG(x)
#endif
-enum { M_UNSET, M_ABS, M_NE, M_NW, M_SE, M_SW };
+const char *exe_name, *corner;
-const char *exe_name;
+#define GEOM_LEN 64
+char geom[GEOM_LEN+1];
void set_exe_name(const char *p) {
exe_name = p;
@@ -58,11 +60,6 @@ void errmsg(const char *msg) {
usage(1);
}
-void check_mode(int mode) {
- if(mode != M_ABS)
- errmsg("multiple modes given, only one of -ne -nw -se -sw is allowed");
-}
-
int streq(const char *s1, const char *s2) {
return !strcmp(s1, s2);
}
@@ -75,6 +72,39 @@ int ctrl_and_mod(unsigned int state) {
return 0;
}
+void set_corner(const char *geom) {
+ if(corner)
+ errmsg("multiple modes given, only one of -ne -nw -se -sw is allowed");
+ corner = geom;
+}
+
+/* XParseGeometry doesn't do enough error checking. It'll allow
+ stuff like 100x100x100, or 100x100+foo, with no complaint. */
+void preparse_geom(const char *geom) {
+ int x_count = 0, plus_minus_count = 0, bogus_count = 0, len = 0;
+ const char *p = geom;
+
+ while(*p) {
+ len++;
+ if(*p == 'x')
+ x_count++;
+ else if(*p == '+' || *p == '-')
+ plus_minus_count++;
+ else if(!isdigit(*p))
+ bogus_count++;
+ p++;
+ }
+
+ if(!x_count)
+ errmsg("bad geometry: no 'x' character");
+ else if(x_count > 1)
+ errmsg("bad geometry: multiple 'x' characters");
+ else if(plus_minus_count > 2)
+ errmsg("bad geometry: too many +/- characters");
+ else if(bogus_count)
+ errmsg("bad geometry: invalid characters, only digits, +, -, x allowed");
+}
+
int main(int argc, char **argv) {
Display *d;
Window w;
@@ -84,7 +114,7 @@ int main(int argc, char **argv) {
XSetWindowAttributes setattr;
XSizeHints hints;
- int x = -1, y = -1, gflags = -1, visible = 0, black = 0, mode = M_ABS, normal_window = 0;
+ int x = -1, y = -1, gflags = -1, visible = 0, black = 0, normal_window = 0;
unsigned int width, height;
int new_x, new_y;
@@ -109,53 +139,43 @@ int main(int argc, char **argv) {
visible = 1;
normal_window = 1;
} else if(streq(a, "-ne")) {
- check_mode(mode);
- mode = M_NE;
+ set_corner("-0+0");
} else if(streq(a, "-nw")) {
- check_mode(mode);
- mode = M_NW;
+ set_corner("+0+0");
} else if(streq(a, "-se")) {
- check_mode(mode);
- mode = M_SE;
+ set_corner("-0-0");
} else if(streq(a, "-sw")) {
- check_mode(mode);
- mode = M_SW;
+ set_corner("+0-0");
} else if(a[0] == '-') {
fprintf(stderr, "%s: invalid option: %s\n\n", exe_name, a);
usage(1);
} else { /* no dash, must be geometry */
- if(gflags == -1)
- gflags = XParseGeometry(a, &x, &y, &width, &height);
- else
+ if(geom[0])
errmsg("multiple geometry arguments given");
+ else
+ strncpy(geom, a, GEOM_LEN);
}
}
- if(gflags == -1)
+ if(!geom[0])
errmsg("missing required geometry argument");
- else
- DBG(printf("XParseGeometry got %d %d %d %d\n", x, y, width, height));
-
- if(mode != M_ABS && (gflags & (XValue | YValue)))
- errmsg("bad geometry: X and Y position not allowed with -ne -nw -se -sw");
-
- switch(mode) {
- case M_ABS:
- if(!(gflags & (XValue | YValue)))
- errmsg("bad geometry: requires X and Y position or -ne -nw -se -sw");
- break;
- case M_NW:
- x = 0; y = 0; break;
- case M_NE:
- x = -width; y = 0; break;
- case M_SW:
- x = 0; y = -height; break;
- case M_SE:
- x = -width; y = -height; break;
- default:
- errmsg("invalid mode (internal logic error, this should never happen)");
+
+ if(corner) {
+ if(strchr(geom, '+') || strchr(geom, '-'))
+ errmsg("bad geometry: X and Y position not allowed with -ne -nw -se -sw");
+ else
+ strncat(geom, corner, GEOM_LEN);
}
+ preparse_geom(geom);
+
+ gflags = XParseGeometry(geom, &x, &y, &width, &height);
+
+ if(gflags == -1)
+ errmsg("bad geometry (failed to parse)");
+ else
+ DBG(printf("XParseGeometry got %d %d %u %u\n", x, y, width, height));
+
if(width == 0 || height == 0)
errmsg("bad geometry: width and height must be non-zero");
@@ -163,24 +183,14 @@ int main(int argc, char **argv) {
errmsg("can't open X display");
XGetWindowAttributes(d, DefaultRootWindow(d), &root_attr);
- if(mode == M_ABS) {
- if(gflags & XNegative) x = (root_attr.width + x) - width;
- if(gflags & YNegative) y = (root_attr.height + y) - height;
- } else {
- if(x < 0) x = (root_attr.width + x);
- if(y < 0) y = (root_attr.height + y);
- }
+ if(gflags & XNegative) x = (root_attr.width + x) - width;
+ if(gflags & YNegative) y = (root_attr.height + y) - height;
DBG(printf("X size %d x %d, x %d, y %d, width %d, height %d\n",
root_attr.width, root_attr.height, x, y, width, height));
- /* Create window with override_redirect enabled, to tell the window
- manager not to decorate it with a titlebar or resize frame.
- Also, we really only care about EnterNotify events.
- Set the window to solid white, to make it easy to see during testing.
- In actual use, the window won't be visible, it'll be in the dead zone,
- right?
- */
+ /* without -n, create window with override_redirect enabled, to tell the window
+ manager not to decorate it with a titlebar or resize frame. */
setattr.override_redirect = normal_window ? False : True;
if(visible) {
setattr.background_pixel = black ?