x11.h
author František Kučera <franta-hg@frantovo.cz>
Sat, 23 Dec 2023 23:10:41 +0100
branchv_0
changeset 25 717653cedc4a
parent 0 bb715a82a8f1
permissions -rw-r--r--
set scaling filters according to the texture file extended attributes (xattr: shader-shark.texture.mag-filter = linear | nearest)

/**
 * ShaderShark
 * Copyright © 2023 František Kučera (Frantovo.cz, GlobalCode.info)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <cstring>

#include <X11/Xatom.h>
#include <X11/XKBlib.h>
#include <X11/keysymdef.h>

/**
 * Publish our PID (process ID) through the X11 window property.
 */
inline
void setX11PID(Display* dpy, Window win) {
	Atom _NET_WM_PID = XInternAtom(dpy, "_NET_WM_PID", False);
	pid_t pid = getpid();
	XChangeProperty(dpy, win, _NET_WM_PID, XA_CARDINAL,
			32, PropModeReplace, (unsigned char *) &pid, 1);
}

inline
bool setFullscreen(Display* dpy, Window win, bool fullscreen) {
	XEvent ev;
	Atom wmState = XInternAtom(dpy, "_NET_WM_STATE", False);
	Atom wmFullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
	ev.xclient.type = ClientMessage;
	ev.xclient.serial = 0; // TODO: serial?
	ev.xclient.send_event = True;
	ev.xclient.display = dpy;
	ev.xclient.window = win;
	ev.xclient.message_type = wmState;
	ev.xclient.format = 32;
	ev.xclient.data.l[0] = fullscreen;
	ev.xclient.data.l[1] = wmFullscreen;
	ev.xclient.data.l[2] = None;
	XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureNotifyMask, &ev);
	return fullscreen;
}

class DecodedKey {
public:
	unsigned int code;
	KeySym symbol;
	const char* name;

	bool matches(
			KeySym s1,
			KeySym s2 = XK_VoidSymbol,
			KeySym s3 = XK_VoidSymbol,
			KeySym s4 = XK_VoidSymbol,
			KeySym s5 = XK_VoidSymbol,
			KeySym s6 = XK_VoidSymbol,
			KeySym s7 = XK_VoidSymbol,
			KeySym s8 = XK_VoidSymbol
			) {
		return symbol == s1
				|| symbol == s2
				|| symbol == s3
				|| symbol == s4
				|| symbol == s5
				|| symbol == s6
				|| symbol == s7
				|| symbol == s8;
	}
};

inline
const DecodedKey decodeKeycode(Display * dpy, KeyCode keyCode) {
	DecodedKey dk = {};
	dk.code = keyCode;
	dk.symbol = XkbKeycodeToKeysym(dpy, keyCode, 0, 0);
	dk.name = XKeysymToString(dk.symbol);
	return dk;
}