Skip to content

Commit 5a84321

Browse files
author
nick
committed
stable codebase
1 parent a61398b commit 5a84321

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

awm.c

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
#include <inttypes.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <string.h>
5+
#include <time.h>
6+
#include <wayland-server-core.h>
7+
#include <wlr/backend.h>
8+
#include <wlr/backend/session.h>
9+
#include <wlr/render/allocator.h>
10+
#include <wlr/render/wlr_renderer.h>
11+
#include <wlr/types/wlr_output.h>
12+
#include <wlr/types/wlr_input_device.h>
13+
#include <wlr/types/wlr_keyboard.h>
14+
#include <wlr/util/log.h>
15+
#include <xkbcommon/xkbcommon.h>
16+
17+
struct sample_state {
18+
struct wl_display *display;
19+
struct wl_listener new_output;
20+
struct wl_listener new_input;
21+
struct wlr_renderer *renderer;
22+
struct wlr_allocator *allocator;
23+
struct timespec last_frame;
24+
float color[4];
25+
int dec;
26+
};
27+
28+
struct sample_output {
29+
struct sample_state *sample;
30+
struct wlr_output *output;
31+
struct wl_listener frame;
32+
struct wl_listener destroy;
33+
};
34+
35+
struct sample_keyboard {
36+
struct sample_state *sample;
37+
struct wlr_keyboard *wlr_keyboard;
38+
struct wl_listener key;
39+
struct wl_listener destroy;
40+
};
41+
42+
static void output_frame_notify(struct wl_listener *listener, void *data) {
43+
struct sample_output *sample_output =
44+
wl_container_of(listener, sample_output, frame);
45+
struct sample_state *sample = sample_output->sample;
46+
struct wlr_output *wlr_output = sample_output->output;
47+
48+
struct timespec now;
49+
clock_gettime(CLOCK_MONOTONIC, &now);
50+
51+
long ms = (now.tv_sec - sample->last_frame.tv_sec) * 1000 +
52+
(now.tv_nsec - sample->last_frame.tv_nsec) / 1000000;
53+
int inc = (sample->dec + 1) % 3;
54+
55+
sample->color[inc] += ms / 2000.0f;
56+
sample->color[sample->dec] -= ms / 2000.0f;
57+
58+
if (sample->color[sample->dec] < 0.0f) {
59+
sample->color[inc] = 1.0f;
60+
sample->color[sample->dec] = 0.0f;
61+
sample->dec = inc;
62+
}
63+
64+
struct wlr_output_state state;
65+
wlr_output_state_init(&state);
66+
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &state, NULL, NULL);
67+
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
68+
.box = { .width = wlr_output->width, .height = wlr_output->height },
69+
.color = {
70+
.r = sample->color[0],
71+
.g = sample->color[1],
72+
.b = sample->color[2],
73+
.a = sample->color[3],
74+
},
75+
});
76+
wlr_render_pass_submit(pass);
77+
78+
wlr_output_commit_state(wlr_output, &state);
79+
wlr_output_state_finish(&state);
80+
sample->last_frame = now;
81+
}
82+
83+
static void output_remove_notify(struct wl_listener *listener, void *data) {
84+
struct sample_output *sample_output =
85+
wl_container_of(listener, sample_output, destroy);
86+
wlr_log(WLR_DEBUG, "Output removed");
87+
wl_list_remove(&sample_output->frame.link);
88+
wl_list_remove(&sample_output->destroy.link);
89+
free(sample_output);
90+
}
91+
92+
static void new_output_notify(struct wl_listener *listener, void *data) {
93+
struct wlr_output *output = data;
94+
struct sample_state *sample =
95+
wl_container_of(listener, sample, new_output);
96+
97+
wlr_output_init_render(output, sample->allocator, sample->renderer);
98+
99+
struct sample_output *sample_output = calloc(1, sizeof(*sample_output));
100+
sample_output->output = output;
101+
sample_output->sample = sample;
102+
wl_signal_add(&output->events.frame, &sample_output->frame);
103+
sample_output->frame.notify = output_frame_notify;
104+
wl_signal_add(&output->events.destroy, &sample_output->destroy);
105+
sample_output->destroy.notify = output_remove_notify;
106+
107+
struct wlr_output_state state;
108+
wlr_output_state_init(&state);
109+
wlr_output_state_set_enabled(&state, true);
110+
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
111+
if (mode != NULL) {
112+
wlr_output_state_set_mode(&state, mode);
113+
}
114+
wlr_output_commit_state(output, &state);
115+
wlr_output_state_finish(&state);
116+
}
117+
118+
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
119+
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
120+
struct sample_state *sample = keyboard->sample;
121+
struct wlr_keyboard_key_event *event = data;
122+
uint32_t keycode = event->keycode + 8;
123+
const xkb_keysym_t *syms;
124+
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state,
125+
keycode, &syms);
126+
for (int i = 0; i < nsyms; i++) {
127+
xkb_keysym_t sym = syms[i];
128+
if (sym == XKB_KEY_Escape) {
129+
wl_display_terminate(sample->display);
130+
}
131+
}
132+
}
133+
134+
static void keyboard_destroy_notify(struct wl_listener *listener, void *data) {
135+
struct sample_keyboard *keyboard =
136+
wl_container_of(listener, keyboard, destroy);
137+
wl_list_remove(&keyboard->destroy.link);
138+
wl_list_remove(&keyboard->key.link);
139+
free(keyboard);
140+
}
141+
142+
static void new_input_notify(struct wl_listener *listener, void *data) {
143+
struct wlr_input_device *device = data;
144+
struct sample_state *sample = wl_container_of(listener, sample, new_input);
145+
switch (device->type) {
146+
case WLR_INPUT_DEVICE_KEYBOARD:;
147+
struct sample_keyboard *keyboard = calloc(1, sizeof(*keyboard));
148+
keyboard->wlr_keyboard = wlr_keyboard_from_input_device(device);
149+
keyboard->sample = sample;
150+
wl_signal_add(&device->events.destroy, &keyboard->destroy);
151+
keyboard->destroy.notify = keyboard_destroy_notify;
152+
wl_signal_add(&keyboard->wlr_keyboard->events.key, &keyboard->key);
153+
keyboard->key.notify = keyboard_key_notify;
154+
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
155+
if (!context) {
156+
wlr_log(WLR_ERROR, "Failed to create XKB context");
157+
exit(1);
158+
}
159+
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, NULL,
160+
XKB_KEYMAP_COMPILE_NO_FLAGS);
161+
if (!keymap) {
162+
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
163+
exit(1);
164+
}
165+
wlr_keyboard_set_keymap(keyboard->wlr_keyboard, keymap);
166+
xkb_keymap_unref(keymap);
167+
xkb_context_unref(context);
168+
break;
169+
default:
170+
break;
171+
}
172+
}
173+
174+
int main(void) {
175+
wlr_log_init(WLR_DEBUG, NULL);
176+
struct wl_display *display = wl_display_create();
177+
struct sample_state state = {
178+
.color = { 1.0, 0.0, 0.0, 1.0 },
179+
.dec = 0,
180+
.last_frame = { 0 },
181+
.display = display
182+
};
183+
struct wlr_backend *backend = wlr_backend_autocreate(wl_display_get_event_loop(display), NULL);
184+
if (!backend) {
185+
exit(1);
186+
}
187+
188+
state.renderer = wlr_renderer_autocreate(backend);
189+
state.allocator = wlr_allocator_autocreate(backend, state.renderer);
190+
191+
wl_signal_add(&backend->events.new_output, &state.new_output);
192+
state.new_output.notify = new_output_notify;
193+
wl_signal_add(&backend->events.new_input, &state.new_input);
194+
state.new_input.notify = new_input_notify;
195+
clock_gettime(CLOCK_MONOTONIC, &state.last_frame);
196+
197+
if (!wlr_backend_start(backend)) {
198+
wlr_log(WLR_ERROR, "Failed to start backend");
199+
wlr_backend_destroy(backend);
200+
exit(1);
201+
}
202+
wl_display_run(display);
203+
wl_display_destroy(display);
204+
}
205+

0 commit comments

Comments
 (0)