diff options
Diffstat (limited to 'xutil.h')
| -rw-r--r-- | xutil.h | 94 | 
1 files changed, 94 insertions, 0 deletions
| @@ -0,0 +1,94 @@ +#pragma once + +#include <functional> +#include <X11/Xlib.h> + + +namespace x { + +	// Typed wrapper for an X keycode +	class Keycode { +	public: +		Keycode(); +		Keycode(unsigned int code); +		explicit operator unsigned int() const; +		bool operator==(Keycode other) const; +	private: +		unsigned int code; +	}; + +	// Typed wrapper for an X keysym +	class Keysym { +	public: +		Keysym(); +		Keysym(unsigned int sym); +		explicit operator unsigned int() const; +		Keycode toCode(Display *dpy) const; +		bool operator==(Keysym other) const; +	private: +		unsigned int sym; +	}; + +	// Play the system bell +	void bel(Display *dpy); + +	// Run a handler on scope exit +	template <typename Cleanup> +	class UponExit { +	public: +		UponExit(Cleanup cleanup) : cleanup{cleanup} {} +		~UponExit() { +			if (cleanup) (*cleanup)(); +		} +		UponExit(const UponExit&) = delete; +		UponExit(UponExit &&other) : cleanup{move(other.cleanup)} { +			other.cleanup.reset(); +		} +		UponExit& operator=(const UponExit&) = delete; +		UponExit& operator=(UponExit &&other) { +			cleanup = move(other.cleanup); +			other.cleanup.reset(); +		} + +	private: +		std::optional<Cleanup> cleanup; +	}; + +	// Grab a single key (code + modifier) on the X server in the given window. +	// Drop the UponExit to ungrab. For a global grab, use +	// DefaultRootWindow(dpy) as the window. +	UponExit<std::function<void()>> XGrabKeyRAII(Display *dpy, Keycode code, int modifier, Window win); + +	// Grab a the whole keyboard on the X server in the given window. Drop the +	// UponExit to ungrab. For a global grab, use DefaultRootWindow(dpy) as the +	// window. +	UponExit<std::function<void()>> XGrabKeyboardRAII(Display *dpy, Window win); + +	// Open the specified display (pass nullptr to use $DISPLAY). Drop the UponExit to close. +	std::pair<Display*, UponExit<std::function<void()>>> XOpenDisplayRAII(const char *name); + +	// Grab the specified key globally for any modifier combination, and run +	// the callback on every hit of that key. Ungrabs and returns when the +	// callback returns true. +	void globalKeyWatch(Display *dpy, Keysym keysym, std::function<bool(const XKeyEvent&)> callback); + +	// Grab the whole keyboard globally, and run the callback on every keyboard +	// key event. Ungrabs and returns when the callback returns true. +	void globalKeyboardGrab(Display *dpy, std::function<bool(const XKeyEvent&)> callback); + +} + +template <> +struct std::hash<x::Keycode> { +	size_t operator()(x::Keycode code) const { +		return std::hash<unsigned int>{}((unsigned int)code); +	} +}; + +template <> +struct std::hash<x::Keysym> { +	size_t operator()(x::Keysym sym) const { +		return std::hash<unsigned int>{}((unsigned int)sym); +	} +}; + | 
