clipnotify

Notify on new X clipboard events
git clone https://git.sinitax.com/cdown/clipnotify
Log | Files | Refs | README | LICENSE | sfeed.txt

clipnotify.c (3047B)


      1#include <X11/Xatom.h>
      2#include <X11/Xlib.h>
      3#include <X11/extensions/Xfixes.h>
      4#include <stdio.h>
      5#include <stdlib.h>
      6#include <string.h>
      7#include <unistd.h>
      8
      9static enum selections {
     10    NONE = 0,
     11    SELECTION_CLIPBOARD = (1 << 0),
     12    SELECTION_PRIMARY = (1 << 1),
     13    SELECTION_SECONDARY = (1 << 2)
     14} selections = NONE;
     15
     16static int loop;
     17
     18int main(int argc, char *argv[]) {
     19    static const char *usage =
     20        "%s: Notify by exiting on clipboard events.\n\n"
     21        "  -l    Instead of exiting, print a newline when a new selection is available.\n"
     22        "  -s    The selection to use. Available selections:\n"
     23        "        clipboard, primary, secondary\n"
     24        "        The default is to monitor clipboard and primary.\n";
     25    Display *disp;
     26    Window root;
     27    Atom clip;
     28    XEvent evt;
     29    int opt;
     30
     31    while ((opt = getopt(argc, argv, "hs:l")) != -1) {
     32        switch (opt) {
     33            case 'h':
     34                printf(usage, argv[0]);
     35                return EXIT_SUCCESS;
     36            case 'l':
     37                loop = 1;
     38                break;
     39            case 's': {
     40                char *token = strtok(optarg, ",");
     41                while (token != NULL) {
     42                    if (strcmp(token, "clipboard") == 0) {
     43                        selections |= SELECTION_CLIPBOARD;
     44                    } else if (strcmp(token, "primary") == 0) {
     45                        selections |= SELECTION_PRIMARY;
     46                    } else if (strcmp(token, "secondary") == 0) {
     47                        selections |= SELECTION_SECONDARY;
     48                    } else {
     49                        fprintf(stderr, "Unknown selection '%s'\n", token);
     50                        return EXIT_FAILURE;
     51                    }
     52                    token = strtok(NULL, ",");
     53                }
     54                break;
     55            }
     56            default:
     57                fprintf(stderr, usage, argv[0]);
     58                return EXIT_FAILURE;
     59        }
     60    }
     61
     62    disp = XOpenDisplay(NULL);
     63    if (!disp) {
     64        fprintf(stderr, "Can't open X display\n");
     65        return EXIT_FAILURE;
     66    }
     67
     68    root = DefaultRootWindow(disp);
     69
     70    clip = XInternAtom(disp, "CLIPBOARD", False);
     71
     72    /* <= 1.0.2 backwards compatibility */
     73    if (!selections)
     74        selections = SELECTION_CLIPBOARD | SELECTION_PRIMARY;
     75
     76    if (selections & SELECTION_CLIPBOARD)
     77        XFixesSelectSelectionInput(disp, root, clip,
     78                                   XFixesSetSelectionOwnerNotifyMask);
     79    if (selections & SELECTION_PRIMARY)
     80        XFixesSelectSelectionInput(disp, root, XA_PRIMARY,
     81                                   XFixesSetSelectionOwnerNotifyMask);
     82    if (selections & SELECTION_SECONDARY)
     83        XFixesSelectSelectionInput(disp, root, XA_SECONDARY,
     84                                   XFixesSetSelectionOwnerNotifyMask);
     85
     86    if (loop) {
     87        (void)setvbuf(stdout, NULL, _IONBF, 0);
     88        do {
     89            XNextEvent(disp, &evt);
     90            printf("\n");
     91        } while (1);
     92    } else {
     93        XNextEvent(disp, &evt);
     94    }
     95    XCloseDisplay(disp);
     96}