1 /* 2 gcc -lX11 xurgent.c 3 */ 4 #include <X11/Xlib.h> 5 #include <X11/Xutil.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <signal.h> 9 #include <stdio.h> 10 11 static Bool set_urgent_hint(Display* dpy, Window wnd, Bool set) 12 { 13 XWMHints *hints = XAllocWMHints(); 14 15 if (!hints) { 16 fputs("error allocing WM hints!\n", stderr); 17 return False; 18 } 19 20 printf("%s urgent hint\n", set ? "setting" : "clearing"); 21 22 if (set) { 23 hints->flags |= XUrgencyHint; 24 } else { 25 hints->flags &= ~XUrgencyHint; 26 } 27 28 XSetWMHints(dpy, wnd, hints); 29 XFree(hints); 30 return True; 31 } 32 33 static Display* dpy; 34 static Window wnd; 35 static Bool urgent = False; 36 37 static void handle_sigint(int signo) 38 { 39 if (signo != SIGINT) 40 return; 41 42 if (set_urgent_hint(dpy, wnd, !urgent)) { 43 urgent = !urgent; 44 XStoreName(dpy, wnd, urgent ? "URGENT!" : "bored..."); 45 XFlush(dpy); 46 } 47 } 48 49 int main(void) 50 { 51 int run = 1, status = EXIT_FAILURE; 52 Atom atom_wm_delete; 53 struct sigaction sa; 54 XEvent e; 55 56 /* open a conenction to the display server */ 57 dpy = XOpenDisplay(NULL); 58 if (!dpy) { 59 fputs("cannot open display!\n", stderr); 60 return EXIT_FAILURE; 61 } 62 63 atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", True); 64 if (atom_wm_delete == None) { 65 fputs("cannot find WM_DELETE_WINDOW atom\n", stderr); 66 return EXIT_FAILURE; 67 } 68 69 /* create window */ 70 wnd = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 71 0, 0, 200, 100, 0, 0, 0); 72 if (!wnd) { 73 fputs("cannot create window!\n", stderr); 74 goto outdpy; 75 } 76 77 XSelectInput(dpy, wnd, ExposureMask | StructureNotifyMask); 78 XSetWMProtocols(dpy, wnd, &atom_wm_delete, 1); 79 XFlush(dpy); 80 81 XStoreName(dpy, wnd, "bored..."); 82 XMapWindow(dpy, wnd); 83 84 /* use CTRL+C to toggle urgent hint */ 85 memset(&sa, 0, sizeof(sa)); 86 sa.sa_handler = handle_sigint; 87 sigaction(SIGINT, &sa, NULL); 88 89 /* event loop */ 90 while (run) { 91 XNextEvent(dpy, &e); 92 93 switch (e.type) { 94 case Expose: 95 XClearWindow(dpy, e.xany.window); 96 break; 97 case ClientMessage: 98 if (e.xclient.data.l[0] == (long)atom_wm_delete) { 99 XUnmapWindow(dpy, wnd); 100 run = 0; 101 } 102 break; 103 } 104 } 105 106 /* cleanup */ 107 status = EXIT_SUCCESS; 108 XDestroyWindow(dpy, wnd); 109 outdpy: 110 XCloseDisplay(dpy); 111 return status; 112 }