Skip to content

Instantly share code, notes, and snippets.

@anonymix007
Last active August 11, 2024 13:00
Show Gist options
  • Save anonymix007/ec38b2d99f45032c299b90ceb4d14e11 to your computer and use it in GitHub Desktop.
Save anonymix007/ec38b2d99f45032c299b90ceb4d14e11 to your computer and use it in GitHub Desktop.
Wayland monitor size and position
// gcc -o main main.c -std=gnu23 -lwayland-client
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wayland-client-protocol.h>
#define MAX_NAME_SIZE 512
#define MAX_MONITORS 42
typedef struct {
int x, y, w, h;
int scale;
char name[MAX_NAME_SIZE];
struct wl_output *wl_output;
} monitor_t;
monitor_t monitors[MAX_MONITORS];
size_t monitor_count = 0;
static void geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char *make, const char *model, int32_t transform) {
monitors[monitor_count].x = x;
monitors[monitor_count].y = y;
}
static void pixel_contexts(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
monitors[monitor_count].w = width;
monitors[monitor_count].h = height;
}
static void done(void *data, struct wl_output *wl_output) {
monitors[monitor_count].wl_output = wl_output;
monitor_count++;
assert(monitor_count < MAX_MONITORS);
}
static void scale(void *data, struct wl_output *wl_output, int32_t factor) {
monitors[monitor_count].scale = factor;
}
static void name(void *data, struct wl_output *wl_output, const char *name) {
strncpy(monitors[monitor_count].name, name, MAX_NAME_SIZE);
}
static void description(void *data, struct wl_output *wl_output, const char *description) {
// nop
}
const struct wl_output_listener listener = {
geometry,
pixel_contexts,
done,
scale,
name,
description
};
static void interface_added(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) {
if (strcmp(interface, wl_output_interface.name) == 0) {
struct wl_output *wl_output = wl_registry_bind(registry, name, &wl_output_interface, version);
wl_output_add_listener(wl_output, &listener, NULL);
}
}
static const struct wl_registry_listener registry_listener = {
interface_added,
};
int moncmp(const void *a, const void *b) {
const monitor_t *ma = a, *mb = b;
return strcmp(ma->name, mb->name);
}
int main(void) {
struct wl_display *display = wl_display_connect(NULL);
struct wl_registry *registry = wl_display_get_registry(display);
wl_registry_add_listener(registry, &registry_listener, nullptr);
wl_display_roundtrip(display);
while (wl_display_dispatch(display) == -1) {}
for (size_t i = 0; i < monitor_count; i++) {
wl_output_release(monitors[i].wl_output);
}
wl_registry_destroy(registry);
wl_display_disconnect(display);
printf("Monitor count: %zu\n", monitor_count);
qsort(monitors, monitor_count, sizeof(monitors[0]), moncmp);
for (size_t i = 0; i < monitor_count; i++) {
monitor_t m = monitors[i];
printf("\"%s\": %dx%d at (%d,%d) (scaled by %d)\n", m.name, m.w / m.scale, m.h / m.scale, m.x, m.y, m.scale);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment