Last active
August 11, 2024 13:00
-
-
Save anonymix007/ec38b2d99f45032c299b90ceb4d14e11 to your computer and use it in GitHub Desktop.
Wayland monitor size and position
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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, ®istry_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