// https://github.com/cdown/clipnotify #define _DEFAULT_SOURCE #include #include #include #include #include #include #include static enum selections { NONE = 0, SELECTION_CLIPBOARD = (1 << 0), SELECTION_PRIMARY = (1 << 1), SELECTION_SECONDARY = (1 << 2) } selections = NONE; static int loop; int main(int argc, char *argv[]) { static const char *usage = "%s: Notify by exiting on clipboard events.\n\n" " -l Instead of exiting, print a newline when a new selection is available.\n" " -s The selection to use. Available selections:\n" " clipboard, primary, secondary\n" " The default is to monitor clipboard and primary.\n"; Display *disp; Window root; Atom clip; XEvent evt; int opt; while ((opt = getopt(argc, argv, "hs:l")) != -1) { switch (opt) { case 'h': printf(usage, argv[0]); return EXIT_SUCCESS; case 'l': loop = 1; break; case 's': { char *token = strtok(optarg, ","); while (token != NULL) { if (strcmp(token, "clipboard") == 0) { selections |= SELECTION_CLIPBOARD; } else if (strcmp(token, "primary") == 0) { selections |= SELECTION_PRIMARY; } else if (strcmp(token, "secondary") == 0) { selections |= SELECTION_SECONDARY; } else { fprintf(stderr, "Unknown selection '%s'\n", token); return EXIT_FAILURE; } token = strtok(NULL, ","); } break; } default: fprintf(stderr, usage, argv[0]); return EXIT_FAILURE; } } disp = XOpenDisplay(NULL); if (!disp) { fprintf(stderr, "Can't open X display\n"); return EXIT_FAILURE; } root = DefaultRootWindow(disp); clip = XInternAtom(disp, "CLIPBOARD", False); /* <= 1.0.2 backwards compatibility */ if (!selections) selections = SELECTION_CLIPBOARD | SELECTION_PRIMARY; if (selections & SELECTION_CLIPBOARD) XFixesSelectSelectionInput(disp, root, clip, XFixesSetSelectionOwnerNotifyMask); if (selections & SELECTION_PRIMARY) XFixesSelectSelectionInput(disp, root, XA_PRIMARY, XFixesSetSelectionOwnerNotifyMask); if (selections & SELECTION_SECONDARY) XFixesSelectSelectionInput(disp, root, XA_SECONDARY, XFixesSetSelectionOwnerNotifyMask); if (loop) { (void)setvbuf(stdout, NULL, _IONBF, 0); do { XNextEvent(disp, &evt); for (unsigned int i = 0; i < 2; i += 1) { printf("%c", 0); fflush(stdout); usleep(50000); } } while (1); } else { XNextEvent(disp, &evt); } XCloseDisplay(disp); }