Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile.ubuntu
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:20.04
FROM ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive

Expand Down
62 changes: 17 additions & 45 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,57 +1,36 @@
.PHONY: default
default: run

XSERVER=Xephyr
XSERVER=
XSERVEROPTS=
GLASS_DEBUGGER=
PYTHON=python3

ifeq ($(XSERVEROPTS),)
ifeq ($(XSERVER),Xephyr)
XSERVEROPTS= :100 -ac -screen 1280x768x24 -host-cursor -extension MIT-SHM -nolisten tcp
else
XSERVEROPTS= :100 -ac
endif
endif

XSERVERPATH=$(shell whereis -b $(XSERVER) | cut -f2 -d' ')

BUILD=build
BINDIR=build/env/bin
ENVDIR=env
BINDIR=$(ENVDIR)/bin
PREFIX=/usr/local

BINARIES_SUBDIRS := $(patsubst %/Makefile,%,$(wildcard */Makefile))
BINARIES := $(patsubst %,$(BINDIR)/%,$(BINARIES_SUBDIRS))

PYTHONAPPS_SUBDIRS := $(patsubst %/setup.py,%,$(wildcard */setup.py))
PYTHONAPPS := $(patsubst %,$(BUILD)/env/bin/%,$(PYTHONAPPS_SUBDIRS))
PYTHONAPPS := $(patsubst %,$(BINDIR)/%,$(PYTHONAPPS_SUBDIRS))

SCRIPTS := $(patsubst scripts/%,$(BINDIR)/%,$(wildcard scripts/*))

$(BINARIES): $(BINDIR)

$(BINDIR):
mkdir -p $(BINDIR)
$(BINDIR)/activate:
virtualenv --python=$(PYTHON) $(ENVDIR)
. $(BINDIR)/activate; pip install setuptools
. $(BINDIR)/activate; cd glass-lib; pip install -e .

.PHONY: $(BINARIES)
$(BINARIES):
$(MAKE) GLASS_DMALLOC="$(GLASS_DMALLOC)" -C $(notdir $@)

$(BUILD)/env/bin/activate:
virtualenv --python=$(PYTHON) $(BUILD)/env
. $(BUILD)/env/bin/activate; pip install setuptools
. $(BUILD)/env/bin/activate; cd glass-lib; pip install -e .

$(SCRIPTS):
$(SCRIPTS): $(BINDIR)/activate
cp scripts/* $(BINDIR)

$(PYTHONAPPS): $(BUILD)/env/bin/activate
. $(BUILD)/env/bin/activate; cd $(notdir $@); pip install -e .
$(PYTHONAPPS): $(BINDIR)/activate
. $(BINDIR)/activate; cd $(notdir $@); pip install -e .

.PHONY: all run run-in-docker install devinstall uninstall install-binaries uninstall-binaries
all: $(BINARIES) $(SCRIPTS) $(PYTHONAPPS)
all: $(SCRIPTS) $(PYTHONAPPS)

run: all
GLASS_DEBUGGER="$(GLASS_DEBUGGER)" BUILD="$(BUILD)" XSERVERPATH="$(XSERVERPATH)" XSERVEROPTS="$(XSERVEROPTS)" scripts/xstartup.sh
GLASS_DEBUGGER="$(GLASS_DEBUGGER)" XSERVEROPTS="$(XSERVEROPTS)" scripts/xstartup.sh

run-in-docker:
scripts/run-in-docker.sh
Expand All @@ -62,22 +41,18 @@ devinstall: install-binaries $(patsubst %,devinstall-%,$(PYTHONAPPS_SUBDIRS))

uninstall: uninstall-binaries $(patsubst %,uninstall-%,$(PYTHONAPPS_SUBDIRS))

install-binaries: $(BINARIES)
install-binaries:
mkdir -p $(PREFIX)/share/glass
mkdir -p $(PREFIX)/bin
mkdir -p /usr/share/xsessions
mkdir -p /usr/share/applications
mkdir -p /etc/emacs/site-start.d
cp $(BINDIR)/glass-renderer $(PREFIX)/bin/glass-renderer
cp $(BINDIR)/glass-annotator $(PREFIX)/bin/glass-annotator
cp scripts/glass-startup.sh $(PREFIX)/bin/glass-startup.sh
cp scripts/glass.desktop /usr/share/xsessions/glass.desktop
cp scripts/glass-chromium-browser.desktop /usr/share/applications/glass-chromium-browser.desktop
cp scripts/glass-emacs-xsession.el /etc/emacs/site-start.d/glass-emacs-xsession.el

uninstall-binaries:
rm $(PREFIX)/bin/glass-renderer
rm $(PREFIX)/bin/glass-annotator
rm -rf $(PREFIX)/share/glass
rm $(PREFIX)/bin/glass-startup.sh
rm /usr/share/xsessions/glass.desktop
Expand All @@ -93,13 +68,10 @@ $(patsubst %,devinstall-%,$(PYTHONAPPS_SUBDIRS)):
$(patsubst %,uninstall-%,$(PYTHONAPPS_SUBDIRS)):
pip3 uninstall $(patsubst uninstall-%,%,$@)

clean: clean-build clean-python clean-docker

clean-build:
rm -rf $(BUILD)
clean: clean-python clean-docker

clean-python:
rm -rf $(shell find . -name __pycache__) $(shell find . -name .eggs) $(shell find . -name dist) $(shell find . -name build | grep /glass)
rm -rf $(shell find . -name __pycache__) $(shell find . -name .eggs) $(shell find . -name *.egg-info) $(patsubst %,%/build,$(PYTHONAPPS_SUBDIRS)) $(patsubst %,%/dist,$(PYTHONAPPS_SUBDIRS))

clean-docker:
scripts/run-in-docker.sh clean
2 changes: 2 additions & 0 deletions dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,5 @@ xterm
zsh
xfonts-base
iproute2
x11-xserver-utils
xscreensaver
1 change: 1 addition & 0 deletions glass-annotator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
glass_annotator/lib/
16 changes: 16 additions & 0 deletions glass-annotator/glass_annotator/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from importlib.resources import files
import os

def substring_in_list(s, lst):
for item in lst:
if s in item:
return True
return False

def setup_annotator():
preloads = []
if "LD_PRELOAD" in os.environ:
preloads = os.environ["LD_PRELOAD"].split(" ")
if not substring_in_list('glass-annotator', preloads):
preloads.append(str(files("glass_annotator") / "lib" / "glass-annotator"))
os.environ["LD_PRELOAD"] = " ".join(preloads)
42 changes: 42 additions & 0 deletions glass-annotator/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from setuptools import setup
from setuptools.command.build_py import build_py
from setuptools.command.develop import develop
import pathlib
import subprocess
import shutil
import os
import tempfile

class BuildWithMake(build_py):
def run(self):
with tempfile.TemporaryDirectory() as build_temp:
subprocess.check_call(
["make", f"BUILD={build_temp}", f"BINDIR={build_temp}"],
cwd=pathlib.Path(__file__).parent)

pkg_src = pathlib.Path(__file__).parent / "glass_annotator"
(pkg_src / "lib").mkdir(parents=True, exist_ok=True)
shutil.copy2(pathlib.Path(build_temp) / "glass-annotator", pkg_src / "lib" / "glass-annotator")

super().run()

class DevelopWithMake(develop):
def run(self):
self.run_command("build_py")
super().run()

setup(
name="glass-annotator",
version='0.1',
description='Application and group ID:s for X application windows',
long_description='Adds application and group ID:s for X application windows using LD_PRELOAD',
long_description_content_type="text/markdown",
author='Egil Moeller',
author_email='redhog@redhog.org',
url='https://github.com/redhog/InfiniteGlass',
packages=["glass_annotator"],
cmdclass={
"build_py": BuildWithMake,
"develop": DevelopWithMake},
package_data={"glass_annotator": ["lib/*"]},
)
17 changes: 2 additions & 15 deletions glass-components/glass_components/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import InfiniteGlass
import glass_components.components
import glass_annotator
import distutils.spawn
import sys
import traceback
Expand All @@ -13,24 +14,10 @@
rpdb.handle_trap()
rpdb.handle_trap()

def substring_in_list(s, lst):
for item in lst:
if s in item:
return True
return False

def setup_annotator():
preloads = []
if "LD_PRELOAD" in os.environ:
preloads = os.environ["LD_PRELOAD"].split(" ")
if not substring_in_list('glass-annotator', preloads):
preloads.append(distutils.spawn.find_executable('glass-annotator'))
os.environ["LD_PRELOAD"] = " ".join(preloads)

@click.command()
@InfiniteGlass.profilable
def main(**kw):
setup_annotator()
glass_annotator.setup_annotator()
components = None
try:
with InfiniteGlass.Display() as display:
Expand Down
17 changes: 2 additions & 15 deletions glass-ghosts/glass_ghosts/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,17 @@
import os
import time
import click
import glass_annotator

if os.environ.get("GLASS_DEBUGGER", "") == "rpdb":
import rpdb
rpdb.handle_trap()
rpdb.handle_trap()

def substring_in_list(s, lst):
for item in lst:
if s in item:
return True
return False

def setup_annotator():
preloads = []
if "LD_PRELOAD" in os.environ:
preloads = os.environ["LD_PRELOAD"].split(" ")
if not substring_in_list('glass-annotator', preloads):
preloads.append(distutils.spawn.find_executable('glass-annotator'))
os.environ["LD_PRELOAD"] = " ".join(preloads)

@click.command()
@InfiniteGlass.profilable
def main(**kw):
setup_annotator()
glass_annotator.setup_annotator()
manager = None
try:
with InfiniteGlass.Display() as display:
Expand Down
12 changes: 1 addition & 11 deletions glass-lib/InfiniteGlass/mainloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,7 @@
import select
import os
import ctypes

libc = ctypes.CDLL("libc.so.6")
pidfd_open = libc.pidfd_open
pidfd_open.argtypes = [ctypes.c_int, ctypes.c_uint]
pidfd_open.restype = ctypes.c_int

def pidfd(pid):
fd = pidfd_open(pid, 0)
if fd == -1:
raise OSError(ctypes.get_errno())
return fd
from .utils import pidfd

class MainLoop(object):
def __init__(self):
Expand Down
55 changes: 55 additions & 0 deletions glass-lib/InfiniteGlass/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import os.path
import contextlib
import slugify
import ctypes
import os
import platform

def _generate_key_stringify(value):
if value is None:
Expand Down Expand Up @@ -33,3 +36,55 @@ def open_file(name):
def read_file(name):
with open_file(name) as f:
return f.read()



libc = ctypes.CDLL(None, use_errno=True)

# glibc ≥ 2.36
try:
_pidfd_open = libc.pidfd_open
_pidfd_open.argtypes = (ctypes.c_int, ctypes.c_uint)
_pidfd_open.restype = ctypes.c_int

def pidfd(pid: int) -> int:
fd = _pidfd_open(pid, 0)
if fd == -1:
err = ctypes.get_errno()
raise OSError(err, os.strerror(err))
return fd

except AttributeError:
# Syscall numbers by architecture (Linux)
SYS_PIDFD_OPEN = {
"x86_64": 434,
"aarch64": 434,
"armv7l": 434,
"armv6l": 434,
"riscv64": 434,
"ppc64le": 434,
"s390x": 434,
"loongarch64": 434,
"mips64": 434,
"mips64el": 434,
}

arch = platform.machine()
try:
syscall_nr = SYS_PIDFD_OPEN[arch]
except KeyError:
raise RuntimeError(f"pidfd_open syscall not supported on architecture: {arch}")

libc.syscall.argtypes = (
ctypes.c_long, # syscall
ctypes.c_int, # pid
ctypes.c_uint, # flags
)
libc.syscall.restype = ctypes.c_long

def pidfd(pid: int) -> int:
fd = libc.syscall(syscall_nr, pid, 0)
if fd == -1:
err = ctypes.get_errno()
raise OSError(err, os.strerror(err))
return fd
1 change: 1 addition & 0 deletions glass-renderer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
glass_renderer/bin/
7 changes: 7 additions & 0 deletions glass-renderer/glass_renderer/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import os
import sys
from importlib.resources import files

def main():
bin_path = str(files("glass_renderer") / "bin" / "glass-renderer")
os.execv(bin_path, [bin_path] + sys.argv[1:])
47 changes: 47 additions & 0 deletions glass-renderer/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from setuptools import setup
from setuptools.command.build_py import build_py
from setuptools.command.develop import develop
import pathlib
import subprocess
import shutil
import os
import tempfile

class BuildWithMake(build_py):
def run(self):
with tempfile.TemporaryDirectory() as build_temp:
subprocess.check_call(
["make", f"BUILD={build_temp}", f"BINDIR={build_temp}"],
cwd=pathlib.Path(__file__).parent)

pkg_src = pathlib.Path(__file__).parent / "glass_renderer"
(pkg_src / "bin").mkdir(parents=True, exist_ok=True)
shutil.copy2(pathlib.Path(build_temp) / "glass-renderer", pkg_src / "bin" / "glass-renderer")

super().run()

class DevelopWithMake(develop):
def run(self):
self.run_command("build_py")
super().run()

setup(
name="glass-renderer",
version='0.1',
description='The renderer process for InfiniteGlass',
long_description='A compositor, that is, the opengl rendering pipeline for InfiniteGlass',
long_description_content_type="text/markdown",
author='Egil Moeller',
author_email='redhog@redhog.org',
url='https://github.com/redhog/InfiniteGlass',
packages=["glass_renderer"],
cmdclass={
"build_py": BuildWithMake,
"develop": DevelopWithMake},
package_data={"glass_renderer": ["bin/*"]},
entry_points={
"console_scripts": [
"glass-renderer = glass_renderer:main"
]
},
)
Loading
Loading