diff --git a/Makefile b/Makefile index 683f461..d340002 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CFLAGS = -Wall LDLIBS = -lX11 -all: xss xsswin xcursorpos magic +all: xss xsswin xcursorpos xkeygrab magic xss: LDLIBS += -lXss diff --git a/README b/README index d8f3848..8f3f943 100644 --- a/README +++ b/README @@ -5,16 +5,17 @@ program when the X server turns on the built-in screen saver. `xsswin` makes a full-screen black window and runs some other program, passing along the window ID in the environment ($XSS_WINDOW) and -possibly as an argument (XSS_WINDOW gets replaced with the id). It does -not grab keyboard or mouse focus: you'll have to run something else -(like `xtrlock`) to do this or other windows will continue to get -keyboard and mouse events. +possibly as an argument (XSS_WINDOW gets replaced with the id). + +`xkeygrab` grabs the keyboard and mouse, and echoes all typed lines to +stdout. `xcursorpos` prints out the x and y coordinates of the cursor. `magic` is a reimplementation of the "magic" screen saver from After Dark. + Examples -------- @@ -28,27 +29,37 @@ Run like `xautolock`: xss xlock -mode qix & -Shell script to run `magic` and `xtrlock` at the same time, but prevent -locking if the cursor is in the upper-left corner: +Shell script to run `magic` while waiting for a pass word from the keybord. Won't +do anything if the cursor is in the upper-left corner: #! /bin/sh xcursorpos | (read x y; [ $x -lt 20 -a $y -lt 20 ]) && exit 0 xsswin magic XSS_WINDOW & pid=$! - xtrlock + xkeygrab | (while [ "$l" != "secret" ]; do read l; done) kill $pid +Download +-------- + +You can download a [tarball of the latest +commit](http://woozle.org/~neale/repos/?p=xss;a=snapshot) or use git: + + git clone http://woozle.org/~neale/repos/xss/ + + History ------- AIX apparently had something also called `xss` which did almost exactly what mine does, but with command-line options. -I'm not aware of anything else like `xsswin` or `xcursorpos`. If there -is already something out there to do these jobs please let me know so I -can quit using my versions. +`magic` is similar to the `qix` hack from xscreensaver and xlock. + +I'm not aware of anything else like the rest of the programs, which is +why I wrote them. I lifted some code from `beforelight` from the X11 distribution, and from `slock` from [suckless.org](http://suckless.org/). Both have a diff --git a/magic.c b/magic.c index b0073a9..ccc85a7 100644 --- a/magic.c +++ b/magic.c @@ -74,7 +74,7 @@ main(int argc, char * const argv[]) } } if ((Window)-1 == w) { - fprintf(stderr, "Usage: %s [WINDOW_ID]\n", argv[0]); + (void)fprintf(stderr, "Usage: %s [WINDOW_ID]\n", argv[0]); return 64; /* EX_USAGE */ } @@ -188,7 +188,7 @@ main(int argc, char * const argv[]) } except { - fprintf(stderr, "Error: %s\n", exception); + (void)fprintf(stderr, "Error: %s\n", exception); return 69; /* EX_UNAVAILABLE */ } return 0; diff --git a/xcursorpos.c b/xcursorpos.c index 2f79a16..1a74195 100644 --- a/xcursorpos.c +++ b/xcursorpos.c @@ -25,7 +25,7 @@ main(int argc, char *argv[]) Display *display = NULL; if (argc != 1) { - fprintf(stderr, "Usage: %s\n", argv[0]); + (void)fprintf(stderr, "Usage: %s\n", argv[0]); return 64; /* EX_USAGE */ } @@ -39,7 +39,7 @@ main(int argc, char *argv[]) if (! XQueryPointer(display, root, &root, &win, &x, &y, &win_x, &win_y, &mask)) { raise("unable to query pointer"); } - printf("%d %d\n", x, y); + (void)printf("%d %d\n", x, y); } while (0); if (display) { @@ -47,7 +47,7 @@ main(int argc, char *argv[]) } except { - fprintf(stderr, "Error: %s\n", exception); + (void)fprintf(stderr, "Error: %s\n", exception); return 69; /* EX_UNAVAILABLE */ } diff --git a/xkeygrab.c b/xkeygrab.c new file mode 100644 index 0000000..9cf11b8 --- /dev/null +++ b/xkeygrab.c @@ -0,0 +1,123 @@ +/* xkeygrab -- grab keyboard and mouse, writing typed lines to stdout + * Copyright (C) 2008 Neale Pickett + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "obj.h" + +int +main(int argc, char *argv[]) +{ + Display *display = NULL; + + if (argc != 1) { + (void)fprintf(stderr, "Usage: %s\n", argv[0]); + return 64; /* EX_USAGE */ + } + + try { + Window root; + char obuf[4096]; + int obuflen = 0; + struct pollfd fds[2]; + + if (! (display = XOpenDisplay(NULL))) raise("cannot open display"); + root = DefaultRootWindow(display); + if (GrabSuccess != XGrabPointer(display, root, + False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, + None, None, CurrentTime)) { + raise("cannot grab pointer"); + } + if (GrabSuccess != XGrabKeyboard(display, root, + True, + GrabModeAsync, GrabModeAsync, + CurrentTime)) { + raise("cannot grab keyboard"); + } + + fds[0].fd = STDOUT_FILENO; + fds[0].events = 0; + fds[1].fd = ConnectionNumber(display); + fds[1].events = POLLIN; + while (1) { + int ret; + + ret = poll(fds, 2, -1); + + if (fds[0].revents & POLLERR) { + break; + } + if (fds[1].revents & POLLIN) { + XEvent event; + + (void)XNextEvent(display, &event); + if (KeyPress == event.type) { + char buf[32]; + KeySym ksym; + int i; + + if (obuflen == sizeof(obuf)) continue; + i = XLookupString(&event.xkey, buf, sizeof(buf), &ksym, NULL); + switch (ksym) { + case XK_Return: + if (obuflen) { + (void)write(STDOUT_FILENO, obuf, obuflen); + (void)write(STDOUT_FILENO, "\n", 1); + obuflen = 0; + } + break; + case XK_BackSpace: + if (obuflen) obuflen -= 1; + break; + default: + if (1 == i) { + switch (buf[0]) { + case '\025': + obuflen = 0; + break; + case ' ' ... '~': + obuf[obuflen++] = buf[0]; + break; + } + } + break; + } + } + } + } + } while (0); + + if (display) { + (void)XUngrabKeyboard(display, CurrentTime); + (void)XUngrabPointer(display, CurrentTime); + (void)XCloseDisplay(display); + } + + except { + (void)fprintf(stderr, "Error: %s\n", exception); + return 69; /* EX_UNAVAILABLE */ + } + + return 0; +} diff --git a/xss.c b/xss.c index 5fa434e..3a6ae9d 100644 --- a/xss.c +++ b/xss.c @@ -40,7 +40,7 @@ main(int argc, char *argv[]) Display *display = NULL; if (argc < 2) { - fprintf(stderr, "Usage: %s PROGRAM [ARGUMENT ...]\n", argv[0]); + (void)fprintf(stderr, "Usage: %s PROGRAM [ARGUMENT ...]\n", argv[0]); return 64; /* EX_USAGE */ } signal(SIGCHLD, sigchld); @@ -55,7 +55,7 @@ main(int argc, char *argv[]) } XScreenSaverSelectInput(display, DefaultRootWindow(display), ScreenSaverNotifyMask); while (! XNextEvent(display, &event)) { - if (event.type == ss_event) { + if (ss_event == event.type) { XScreenSaverNotifyEvent *sevent = (XScreenSaverNotifyEvent *)&event; if (ScreenSaverOn == sevent->state) { @@ -77,7 +77,7 @@ main(int argc, char *argv[]) } except { - fprintf(stderr, "Error: %s\n", exception); + (void)fprintf(stderr, "Error: %s\n", exception); return 69; /* EX_UNAVAILABLE */ } diff --git a/xsswin.c b/xsswin.c index 1498bb2..6b556ac 100644 --- a/xsswin.c +++ b/xsswin.c @@ -31,7 +31,7 @@ main(int argc, char * const argv[]) Window w; if (argc < 2) { - fprintf(stderr, "Usage: %s PROGRAM [ARGUMENT ...]\n", argv[0]); + (void)fprintf(stderr, "Usage: %s PROGRAM [ARGUMENT ...]\n", argv[0]); return 64; /* EX_USAGE */ } @@ -97,7 +97,7 @@ main(int argc, char * const argv[]) } except { - fprintf(stderr, "Error: %s\n", exception); + (void)fprintf(stderr, "Error: %s\n", exception); return 69; /* EX_UNAVAILABLE */ } return 0;