From 7451d8fce4c50729ab3192c93422fa79c9e4fe85 Mon Sep 17 00:00:00 2001 From: Nguyễn Gia Phong Date: Sat, 19 Jun 2021 15:23:47 +0700 Subject: Translate from C to Zig --- .build.yml | 11 +++++++++++ .gitignore | 2 ++ COPYING | 24 ++++++++++++++++++++++++ LICENSE | 5 ----- Makefile | 17 ----------------- README.md | 45 +++++++++++++++++++++++++++++++-------------- build.zig | 29 +++++++++++++++++++++++++++++ clipnotify.c | 28 ---------------------------- src/main.zig | 13 +++++++++++++ src/x11.zig | 14 ++++++++++++++ src/xfixes.zig | 18 ++++++++++++++++++ 11 files changed, 142 insertions(+), 64 deletions(-) create mode 100644 .build.yml create mode 100644 .gitignore create mode 100644 COPYING delete mode 100644 LICENSE delete mode 100644 Makefile create mode 100644 build.zig delete mode 100644 clipnotify.c create mode 100644 src/main.zig create mode 100644 src/x11.zig create mode 100644 src/xfixes.zig diff --git a/.build.yml b/.build.yml new file mode 100644 index 0000000..500a409 --- /dev/null +++ b/.build.yml @@ -0,0 +1,11 @@ +image: archlinux +packages: + - libx11 + - libxfixes + - zig +sources: + - https://git.sr.ht/~cnx/clipbuzz +tasks: + - build: | + cd clipbuzz + zig build diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e73c965 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +zig-cache/ +zig-out/ diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/COPYING @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/LICENSE b/LICENSE deleted file mode 100644 index ea9256a..0000000 --- a/LICENSE +++ /dev/null @@ -1,5 +0,0 @@ -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, -commercial or non-commercial, and by any means. diff --git a/Makefile b/Makefile deleted file mode 100644 index ae81666..0000000 --- a/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -PREFIX ?= /usr/local - -x11_bsd_flags = -I/usr/X11R6/include -L/usr/X11R6/lib - -all: - ${CC} ${CFLAGS} ${LDFLAGS} clipnotify.c -o clipnotify $(x11_bsd_flags) -lX11 -lXfixes - -install: all - mkdir -p ${DESTDIR}${PREFIX}/bin - cp -f clipnotify ${DESTDIR}${PREFIX}/bin - chmod 755 ${DESTDIR}${PREFIX}/bin/clipnotify - -uninstall: - rm -f ${DESTDIR}${PREFIX}/bin/clipnotify - -clean: - rm -f *.o *~ clipnotify diff --git a/README.md b/README.md index f86ef96..ef1e63d 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,35 @@ -clipnotify is a simple program that, using the -[XFIXES](https://cgit.freedesktop.org/xorg/proto/fixesproto/plain/fixesproto.txt) -extension to X11, waits until a new selection is available and then exits. +# clipbuzz +`clipbuzz` is a simple program that uses the [X Fixes Extension] +to wait until a new clipboard or primary selection is available and exit. +It was translated from [clipnotify] in C to Zig, and is intended for use +within a clipboard manager like [threa] to avoid polling for selections. -It was primarily designed for [clipmenu](https://github.com/cdown/clipmenu), to -avoid polling for new selections. +## Installation +`clipbuzz` depends on [Xlib] and an [implementation of Xfixes] +and uses [Zig] build tool: -Here's how it's intended to be used: +```sh +zig build install --prefix $PREFIX +``` - while clipnotify; do - [an event happened, do something with the selection] - done +where `$PREFIX` is usually `$HOME/.local`, `/usr/local` or `/usr` +depending on your preference. The dependencies can usually be +found in your operating system's repository, and if you are lucky, +`clipbuzz` itself as well! -clipnotify doesn't try to print anything about the contents of the selection, -it just exits when it changes. This is intentional -- X11's selection API is -verging on the insane, and there are plenty of others who have already lost -their sanity to bring us xclip/xsel/etc. Use one of those tools to complement -clipnotify. +## Usage +```sh +while clipbuzz +do # something with xclip or xsel +done +``` + +## Copying +This is free and unencumbered software released into the public domain. + +[X Fixes Extension]: https://gitlab.freedesktop.org/xorg/proto/fixesproto +[clipnotify]: https://github.com/cdown/clipnotify +[threa]: https://sr.ht/~cnx/threa +[Xlib]: https://gitlab.freedesktop.org/xorg/lib/libx11 +[implementation of Xfixes]: https://github.com/Airblader/unclutter-xfixes +[Zig]: https://ziglang.org diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..a0ba02c --- /dev/null +++ b/build.zig @@ -0,0 +1,29 @@ +const std = @import("std"); + +pub fn build(b: *std.build.Builder) void { + const exe = b.addExecutable("clipbuzz", "src/main.zig"); + exe.linkLibC(); + exe.linkSystemLibrary("X11"); + exe.linkSystemLibrary("Xfixes"); + + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + exe.setTarget(b.standardTargetOptions(.{})); + + // Standard release options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. + exe.setBuildMode(b.standardReleaseOptions()); + + exe.install(); + + const run_cmd = exe.run(); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| { + run_cmd.addArgs(args); + } + + const run_step = b.step("run", "Run the app"); + run_step.dependOn(&run_cmd.step); +} diff --git a/clipnotify.c b/clipnotify.c deleted file mode 100644 index f09583e..0000000 --- a/clipnotify.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include -#include -#include - -int main(void) { - Display *disp; - Window root; - Atom clip; - XEvent evt; - - disp = XOpenDisplay(NULL); - if (!disp) { - fprintf(stderr, "Can't open X display\n"); - exit(1); - } - - root = DefaultRootWindow(disp); - - clip = XInternAtom(disp, "CLIPBOARD", False); - - XFixesSelectSelectionInput(disp, root, XA_PRIMARY, XFixesSetSelectionOwnerNotifyMask); - XFixesSelectSelectionInput(disp, root, clip, XFixesSetSelectionOwnerNotifyMask); - - XNextEvent(disp, &evt); - XCloseDisplay(disp); -} diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..c5a23cc --- /dev/null +++ b/src/main.zig @@ -0,0 +1,13 @@ +const x11 = @import("x11.zig"); + +pub fn main() anyerror!void { + const display = x11.openDisplay(null) orelse return error.SystemResources; + defer _ = x11.closeDisplay(display); + + const root = x11.getDefaultRootWindow(display); + x11.getSelection(display, root, "PRIMARY"); + x11.getSelection(display, root, "CLIPBOARD"); + + var event: x11.Event = undefined; + _ = x11.nextEvent(display, &event); +} diff --git a/src/x11.zig b/src/x11.zig new file mode 100644 index 0000000..faea858 --- /dev/null +++ b/src/x11.zig @@ -0,0 +1,14 @@ +const xlib = @cImport({ @cInclude("X11/Xlib.h"); }); +pub const Atom = xlib.Atom; +pub const Display = xlib.Display; +pub const Event = xlib.XEvent; +pub const False = xlib.False; +pub const Window = xlib.Window; +pub const closeDisplay = xlib.XCloseDisplay; +pub const getAtom = xlib.XInternAtom; +pub const getDefaultRootWindow = xlib.XDefaultRootWindow; +pub const nextEvent = xlib.XNextEvent; +pub const openDisplay = xlib.XOpenDisplay; + +const xfixes = @import("xfixes.zig"); +pub const getSelection = xfixes.getSelection; diff --git a/src/xfixes.zig b/src/xfixes.zig new file mode 100644 index 0000000..9eb8afc --- /dev/null +++ b/src/xfixes.zig @@ -0,0 +1,18 @@ +const x11 = @import("x11.zig"); +const Atom = x11.Atom; +const Display = x11.Display; +const False = x11.False; +const Window = x11.Window; +const getAtom = x11.getAtom; + +const xfixes = @cImport({ @cInclude("X11/extensions/Xfixes.h"); }); +const SET_SELECTION_OWNER = xfixes.XFixesSetSelectionOwnerNotifyMask; + +extern fn XFixesSelectSelectionInput(display: *Display, window: Window, + selection: Atom, event_mask: c_ulong) void; + +pub fn getSelection(display: *Display, window: Window, + selection: [*c]const u8) void { + const atom = getAtom(display, selection, False); + XFixesSelectSelectionInput(display, window, atom, SET_SELECTION_OWNER); +} -- cgit 1.4.1