util  Check-in [4dc779457a]

Overview
Comment:initial commit; add safekill
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 4dc779457a45c84fd327742efec3e9d2d96879ae14bb33e9a7bc217c9ca6ef79
User & Date: lexi on 2019-04-08 02:07:07
Other Links: manifest | tags
Context
2019-04-08
02:15
add licensing info check-in: e3a5a8ccea user: lexi tags: trunk
02:07
initial commit; add safekill check-in: 4dc779457a user: lexi tags: trunk
02:01
initial empty check-in check-in: 3b99e03c29 user: lexi tags: trunk
Changes

Added readme.md version [c82e74fe1c].

            1  +# util
            2  +various odds and ends
            3  +
            4  +* **safekill.c**: utility to help keep from accidentally killing important windows; compile with `cc -Ofast safekill.c -lX11 -lc -osafekill`

Added safekill.c version [77306fdca0].

            1  +#include <X11/Xlib.h>
            2  +#include <X11/Xutil.h>
            3  +#include <stdio.h>
            4  +#include <stdlib.h>
            5  +#include <string.h>
            6  +#include <errno.h>
            7  +typedef enum { false, true } bool;
            8  +char* isvital(char* str) {
            9  +	start: // tail calls for dipshits
           10  +		if (*str != '{') {
           11  +			if (*str == 0) return 0;
           12  +			++str; goto start;
           13  +		} else {
           14  +			if (str[1] == 'V' && str[2] == '}')
           15  +				return str;
           16  +			else { ++str; goto start; }
           17  +		}
           18  +}
           19  +int main(const int argc, const char** argv) {
           20  +	Display *display;
           21  +	Window focus;
           22  +	int revert;
           23  +
           24  +	bool active;
           25  +	enum { vitalize, devitalize, hardkill, softkill } op;
           26  +
           27  +	if (argc > 3) goto usage;
           28  +	if (argc == 1)
           29  +		op = softkill, active = true;
           30  +	else {
           31  +		if (argc == 2) active = true;
           32  +		else           active = false;
           33  +
           34  +		if (argv[1][0] == '-' && argv[1][2] == 0) { // opt is short switch
           35  +			switch (argv[1][1]) { // opt char
           36  +
           37  +				// make window mission-critical
           38  +				case 'v': op = vitalize; break;
           39  +
           40  +				// make window acceptable loss
           41  +				case 'c': op = devitalize; break;
           42  +
           43  +				// liquidate by any means necessary
           44  +				case 'q': op = hardkill; break;
           45  +
           46  +				// with all due respect sir what the fuck
           47  +				default: goto usage;
           48  +			}
           49  +		} else goto usage;
           50  +	}
           51  +
           52  +	display = XOpenDisplay(NULL);
           53  +
           54  +	if (active) {
           55  +		XGetInputFocus(display, &focus, &revert);
           56  +	} else {
           57  +		unsigned long temp = strtoul(argv[2], NULL, 0);
           58  +		if (errno == EINVAL || errno == ERANGE) goto usage;
           59  +		if (temp == 0) goto usage;
           60  +		focus = (Window)temp;
           61  +	}
           62  +
           63  +	if(op == hardkill) {
           64  +		XDestroyWindow(display,focus);
           65  +		XSync(display,false);
           66  +		return 0;
           67  +	}
           68  +
           69  +	XClassHint xclh;
           70  +	if (XGetClassHint(display,focus,&xclh)) {
           71  +		char* v;
           72  +		if(v = isvital(xclh.res_class)) {
           73  +
           74  +			if (op == vitalize) return 0; // nothing need be done
           75  +			else if (op == devitalize) {
           76  +				strcpy(v, v+3);
           77  +				XSetClassHint(display,focus,&xclh);
           78  +				XSync(display,false);
           79  +			} else if (op == softkill) {
           80  +				printf("softkill forbidden\n");
           81  +				return 1; // ACCESS DENIED
           82  +			}
           83  +		} else {
           84  +			if (op == vitalize) {
           85  +				size_t sz=strlen(xclh.res_class); // TODO: remove double-walk
           86  +				xclh.res_class=realloc(xclh.res_class, sz+4);
           87  +				xclh.res_class[sz]='{';
           88  +				xclh.res_class[sz+1]='V';
           89  +				xclh.res_class[sz+2]='}';
           90  +				xclh.res_class[sz+3]=0;
           91  +				XSetClassHint(display,focus,&xclh);
           92  +				XSync(display,false);
           93  +			} else if (op == devitalize) return 0;
           94  +			else if (op == softkill) {
           95  +				// ice that motherfucker
           96  +				XDestroyWindow(display,focus);
           97  +				XSync(display,false);
           98  +				return 3;
           99  +			}
          100  +		}
          101  +	} else {
          102  +		printf("\x1b[1merror:\x1b[m bad window\n");
          103  +		goto usage;
          104  +	}
          105  +
          106  +	return 0;
          107  +
          108  +usage:
          109  +	#define info  "\x1b[34m-- "
          110  +	#define param "\x1b[32m"
          111  +	#define eol   "\x1b[m\n"
          112  +	#define bold  "\x1b[1m"
          113  +	#define nl    "       "
          114  +	printf(bold "usage:\x1b[0m %s    "       "     " info "kill active window if non-vital" eol
          115  +						 nl "%1$s -v " param "[id] " info "make [id] or active window vital" eol
          116  +						 nl "%1$s -c " param "[id] " info "clear vital flag on [id] or active window" eol
          117  +						 nl "%1$s -q " param "[id] " info "'emergency' kill w/o reference to vital flag" eol,
          118  +				argv[0]);
          119  +	return 1;
          120  +}