summaryrefslogtreecommitdiff
path: root/src/main/java/moe/nea/mossbar/concepts/Bar.java
blob: 7ce6591a51d73849b92cf5571ef51f2b02011afe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package moe.nea.mossbar.concepts;

import org.freedesktop.wayland.client.*;
import org.freedesktop.wayland.shared.WlOutputTransform;
import org.freedesktop.wayland.shared.ZwlrLayerShellV1Layer;
import org.freedesktop.wayland.shared.ZwlrLayerSurfaceV1Anchor;
import org.freedesktop.wayland.util.EnumUtil;

import java.io.IOException;
import java.nio.IntBuffer;
import java.util.EnumSet;

public class Bar extends Scope {
    private final Display display;
    private final WlSurfaceProxy surface;
    private final ZwlrLayerSurfaceV1Proxy layer;
    private final ShmBufferPool bufferPool;
    private WlCallbackProxy callbackProxy;

    public Bar(Display display, Output output) {
        this.display = display;
        this.surface = display.compositorProxy.createSurface(new WlSurfaceEventsV6() {
            @Override
            public void enter(WlSurfaceProxy emitter, WlOutputProxy output) {
                System.out.println("Surface entered");
            }

            @Override
            public void leave(WlSurfaceProxy emitter, WlOutputProxy output) {
                System.out.println("Left surface");
            }

            @Override
            public void preferredBufferScale(WlSurfaceProxy emitter, int factor) {
                System.out.println("Preferred buffer scale ${factor}");
            }

            @Override
            public void preferredBufferTransform(WlSurfaceProxy emitter, int transform) {
                var transforms = EnumUtil.decode(WlOutputTransform.class, transform);
                System.out.println("Preferred buffer transform ${transforms}");
            }
        }).bindTo(this);
        this.layer = display.layerShell.getLayerSurface(new ZwlrLayerSurfaceV1EventsV4() {
                    @Override
                    public void configure(ZwlrLayerSurfaceV1Proxy emitter, int serial, int width, int height) {
                        System.out.println("Configure layer ${serial} ${width}x${height}");
                        emitter.ackConfigure(serial);
                    }

                    @Override
                    public void closed(ZwlrLayerSurfaceV1Proxy emitter) {
                        System.out.println("layer closed");
                    }
                }, this.surface, output.proxy, ZwlrLayerShellV1Layer.OVERLAY.getValue(), "mossbar")
                .bindTo(this);
        if (output.width <= 0)
            throw new IllegalStateException("Monitor with 0 sized output");
        int width = output.width;
        int height = 30;
        layer.setSize(width, height); // TODO??? this should really not be a hardcoded width
        layer.setAnchor(EnumUtil.encode(EnumSet.of(ZwlrLayerSurfaceV1Anchor.TOP, ZwlrLayerSurfaceV1Anchor.RIGHT, ZwlrLayerSurfaceV1Anchor.LEFT)));
        layer.setExclusiveZone(height);
        surface.commit();
        try {
            bufferPool = ShmBufferPool.newARGBPool(display, width, height, 2);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        display.roundtrip();
    }

    public void renderOnce() {
        var nextBuffer = bufferPool.poll();
        assert nextBuffer != null;
        var pixels = nextBuffer.getByteBuffer().asIntBuffer();
        fill(pixels, 0xFFFF00A0);
        surface.attach(nextBuffer.getProxy(), 0, 0);
        surface.damage(0, 0, nextBuffer.width, nextBuffer.height);
        queueNextFrame();
        surface.commit();
    }

    private void queueNextFrame() {
        if (callbackProxy != null)
            callbackProxy.destroy();
        callbackProxy = surface.frame((_, _) -> renderOnce());
    }

    @Override
    public void closeObject() {
        callbackProxy.destroy();
        super.closeObject();
    }

    private static void fill(IntBuffer buffer, int value) {
        buffer.clear();
        buffer.limit(buffer.capacity());
        while (buffer.hasRemaining()) {
            buffer.put(value);
        }
    }
}