#include #include #include #include #include #include #include void sendmessage(Window window, Atom type, long data); Bool can_understand_delete(Window window); Display *display; Time current_time; Atom wm_protocols, wm_delete; int main(int argc, char **argv) { Window target; char buf[4096]; if (argc == 1 && snprintf(buf, sizeof(buf), "\"%s\" `xselect`", argv[0]) < sizeof(buf)) execlp("sh", "sh", "-c", buf, NULL); if (argc != 2) { char *name; name = strrchr(argv[0], '/'); name = name ? name+1 : argv[0]; fprintf(stderr, "usage: %s window-id\n", name); exit(1); } target = strtol(argv[1], NULL, 10); if ((display = XOpenDisplay(NULL)) == NULL) { fprintf(stderr, "cannot open display\n"); exit(1); } wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False); wm_delete = XInternAtom(display, "WM_DELETE_WINDOW", False); if (can_understand_delete(target)) { sendmessage(target, wm_protocols, wm_delete); } else { XKillClient(display, target); } XCloseDisplay(display); exit(0); } void sendmessage(Window window, Atom type, long data) { XEvent event; memset(&event, 0, sizeof(event)); event.xclient.type = ClientMessage; event.xclient.window = window; event.xclient.message_type = type; event.xclient.format = 32; event.xclient.data.l[0] = data; event.xclient.data.l[1] = current_time; if (XSendEvent(display, window, False, 0L, &event) == 0) { fprintf(stderr, "sendmessage failed\n"); } } Bool can_understand_delete(Window window) { unsigned long n, extra; Atom *properties; Bool result = False; Atom real_type; int format; int i; if (XGetWindowProperty( display, window, wm_protocols, 0L, 20L, False, XA_ATOM, &real_type, &format, &n, &extra, (unsigned char **)&properties) != Success) { return False; } for (i=0; i