Initial commit: Added current work
This commit is contained in:
commit
3fa9c8d193
10 changed files with 637 additions and 0 deletions
25
.clang-format
Normal file
25
.clang-format
Normal file
|
@ -0,0 +1,25 @@
|
|||
BasedOnStyle: Microsoft
|
||||
|
||||
UseTab: ForIndentation
|
||||
TabWidth: 4
|
||||
BreakBeforeBraces: Linux
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||
PointerAlignment: Left
|
||||
|
||||
AlignAfterOpenBracket: Align
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
|
||||
|
||||
AlignArrayOfStructures: Right
|
||||
AlignArrayOfStructures: Right
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
AlignConsecutiveBitFields: Consecutive
|
||||
AlignConsecutiveDeclarations: Consecutive
|
||||
AlignConsecutiveMacros: Consecutive
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: AlignAfterOperator
|
||||
AlignTrailingComments: true
|
||||
|
||||
ColumnLimit: 80
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
protocol/*.c
|
||||
protocol/*.h
|
||||
protocol/*.xml
|
||||
*~
|
||||
miix-wlr
|
162
accel_monitor.c
Normal file
162
accel_monitor.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
#include "accel_monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static char* sensor_get_axis_path(char const* const base, char axis)
|
||||
{
|
||||
// TODO: Be smarter about the buffer size
|
||||
char buffer[128];
|
||||
snprintf(buffer, sizeof(buffer), "%s/in_accel_%c_raw", base, axis);
|
||||
return strdup(buffer);
|
||||
}
|
||||
|
||||
static int monitor_thread(void* data)
|
||||
{
|
||||
struct accel_monitor* monitor = data;
|
||||
|
||||
while (!monitor->monitoring_thread_is_ready)
|
||||
;
|
||||
|
||||
char* x_axis_path = sensor_get_axis_path(monitor->sysfs_device_path, 'x');
|
||||
FILE* x_axis_fp = fopen(x_axis_path, "r");
|
||||
free(x_axis_path);
|
||||
|
||||
char* y_axis_path = sensor_get_axis_path(monitor->sysfs_device_path, 'y');
|
||||
FILE* y_axis_fp = fopen(y_axis_path, "r");
|
||||
free(y_axis_path);
|
||||
|
||||
char* z_axis_path = sensor_get_axis_path(monitor->sysfs_device_path, 'z');
|
||||
FILE* z_axis_fp = fopen(z_axis_path, "r");
|
||||
free(z_axis_path);
|
||||
|
||||
while (!monitor->monitoring_thread_should_exit) {
|
||||
fseek(x_axis_fp, 0, SEEK_SET);
|
||||
fseek(y_axis_fp, 0, SEEK_SET);
|
||||
fseek(z_axis_fp, 0, SEEK_SET);
|
||||
|
||||
int16_t x_axis;
|
||||
int16_t y_axis;
|
||||
int16_t z_axis;
|
||||
|
||||
fscanf(x_axis_fp, "%hd\n", &x_axis);
|
||||
fscanf(y_axis_fp, "%hd\n", &y_axis);
|
||||
fscanf(z_axis_fp, "%hd\n", &z_axis);
|
||||
|
||||
if (mtx_lock(&monitor->current_data_lock) != thrd_success) {
|
||||
fprintf(stderr,
|
||||
"Can't lock data from data monitoring thread. Something is "
|
||||
"going wrong. Giving up on monitoring sensor data.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
monitor->current_data.x = x_axis;
|
||||
monitor->current_data.y = y_axis;
|
||||
monitor->current_data.z = z_axis;
|
||||
|
||||
if (mtx_unlock(&monitor->current_data_lock) != thrd_success) {
|
||||
fprintf(stderr,
|
||||
"Can't unlock data from data monitoring thread. Something "
|
||||
"is going wrong. Giving up on monitoring sensor data.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
monitor->data_is_ready = true;
|
||||
}
|
||||
|
||||
fclose(x_axis_fp);
|
||||
fclose(y_axis_fp);
|
||||
fclose(z_axis_fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct accel_monitor* accel_start_monitor(
|
||||
char const* const sysfs_device_path)
|
||||
{
|
||||
mtx_t current_data_lock;
|
||||
if (mtx_init(¤t_data_lock, mtx_plain) != thrd_success) return 0;
|
||||
|
||||
if (mtx_lock(¤t_data_lock) != thrd_success) return 0;
|
||||
|
||||
struct accel_monitor* monitor = calloc(1, sizeof(struct accel_monitor));
|
||||
|
||||
monitor->monitoring_thread_is_ready = false;
|
||||
monitor->data_is_ready = false;
|
||||
|
||||
thrd_t monitoring_thread;
|
||||
if (thrd_create(&monitoring_thread, &monitor_thread, monitor) !=
|
||||
thrd_success) {
|
||||
free(monitor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
monitor->sysfs_device_path = sysfs_device_path;
|
||||
monitor->monitoring_thread = monitoring_thread;
|
||||
monitor->current_data_lock = current_data_lock;
|
||||
|
||||
monitor->current_data.x = 0;
|
||||
monitor->current_data.y = 0;
|
||||
monitor->current_data.z = 0;
|
||||
|
||||
monitor->monitoring_thread_should_exit = false;
|
||||
|
||||
if (mtx_unlock(&monitor->current_data_lock) != thrd_success)
|
||||
fprintf(stderr,
|
||||
"Unable to unlock the data after initialisation. We are in UB "
|
||||
"territory. Something must've went very wrong\n");
|
||||
|
||||
monitor->monitoring_thread_is_ready = true;
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
static bool axis_is_near_0(int16_t axis)
|
||||
{
|
||||
return (axis > -500) && (axis < 500);
|
||||
}
|
||||
|
||||
static bool axis_is_mostly_positive(int16_t axis)
|
||||
{
|
||||
return axis >= 500;
|
||||
}
|
||||
|
||||
static bool axis_is_mostly_negative(int16_t axis)
|
||||
{
|
||||
return axis <= -500;
|
||||
}
|
||||
|
||||
enum accel_rotation accel_get_current_rotation(
|
||||
struct accel_monitor* monitor)
|
||||
{
|
||||
if (mtx_lock(&monitor->current_data_lock) != thrd_success)
|
||||
return ACCEL_ROTATION_NO_CHANGE;
|
||||
struct accel_data data = monitor->current_data;
|
||||
if (mtx_unlock(&monitor->current_data_lock) != thrd_success)
|
||||
fprintf(stderr, "Can't unlock data, this is going to cause issues.\n");
|
||||
|
||||
if (axis_is_near_0(data.x)) {
|
||||
if (axis_is_mostly_positive(data.y)) return ACCEL_ROTATION_0DEG;
|
||||
if (axis_is_mostly_negative(data.y)) return ACCEL_ROTATION_180DEG;
|
||||
}
|
||||
|
||||
if (axis_is_mostly_positive(data.x)) return ACCEL_ROTATION_90DEG;
|
||||
|
||||
if (axis_is_mostly_negative(data.x)) return ACCEL_ROTATION_270DEG;
|
||||
|
||||
return ACCEL_ROTATION_NO_CHANGE;
|
||||
}
|
||||
|
||||
void accel_stop_monitor(struct accel_monitor* monitor)
|
||||
{
|
||||
monitor->monitoring_thread_should_exit = true;
|
||||
|
||||
if (thrd_join(monitor->monitoring_thread, NULL) != thrd_success)
|
||||
fprintf(stderr,
|
||||
"Can't join monitoring thread. The program may not exit "
|
||||
"cleanly.\n");
|
||||
|
||||
mtx_destroy(&monitor->current_data_lock);
|
||||
free(monitor);
|
||||
}
|
36
accel_monitor.h
Normal file
36
accel_monitor.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
#include <threads.h>
|
||||
|
||||
struct accel_data {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t z;
|
||||
};
|
||||
|
||||
enum accel_rotation : uint8_t {
|
||||
ACCEL_ROTATION_0DEG = 0,
|
||||
ACCEL_ROTATION_90DEG,
|
||||
ACCEL_ROTATION_180DEG,
|
||||
ACCEL_ROTATION_270DEG,
|
||||
ACCEL_ROTATION_NO_CHANGE,
|
||||
};
|
||||
|
||||
struct accel_monitor {
|
||||
atomic_bool monitoring_thread_should_exit;
|
||||
atomic_bool monitoring_thread_is_ready;
|
||||
thrd_t monitoring_thread;
|
||||
|
||||
char const* sysfs_device_path;
|
||||
|
||||
mtx_t current_data_lock;
|
||||
struct accel_data current_data;
|
||||
atomic_bool data_is_ready;
|
||||
};
|
||||
|
||||
struct accel_monitor* accel_start_monitor(
|
||||
char const* const sysfs_device_path);
|
||||
enum accel_rotation accel_get_current_rotation(struct accel_monitor*);
|
||||
void accel_stop_monitor(struct accel_monitor*);
|
10
build.sh
Executable file
10
build.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -ex;
|
||||
|
||||
SOURCES="main.c output_manager.c accel_monitor.c"
|
||||
CFLAGS="-std=c2x -Wall -Wextra -pedantic $CFLAGS"
|
||||
LIBS="-lwayland-client protocol/wlr-output-management-unstable-v1.c"
|
||||
OUTPUT=miix-wlr
|
||||
|
||||
clang $CFLAGS $LIBS $SOURCES -o $OUTPUT
|
45
main.c
Normal file
45
main.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "output_manager.h"
|
||||
|
||||
#include "accel_monitor.h"
|
||||
|
||||
static enum wl_output_transform const SENSOR_TO_OUTPUT_ROTATION[] = {
|
||||
[ACCEL_ROTATION_0DEG] = WL_OUTPUT_TRANSFORM_270,
|
||||
[ACCEL_ROTATION_90DEG] = WL_OUTPUT_TRANSFORM_NORMAL,
|
||||
[ACCEL_ROTATION_180DEG] = WL_OUTPUT_TRANSFORM_90,
|
||||
[ACCEL_ROTATION_270DEG] = WL_OUTPUT_TRANSFORM_180,
|
||||
};
|
||||
|
||||
static char const* const DEFAULT_OUTPUT = "DSI-1";
|
||||
static char const* const DEFAULT_MOTION_SENSOR =
|
||||
"/sys/bus/iio/devices/iio:device0";
|
||||
|
||||
static enum accel_rotation last_accel_rotation = ACCEL_ROTATION_NO_CHANGE;
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
struct accel_monitor* monitor =
|
||||
accel_start_monitor(DEFAULT_MOTION_SENSOR);
|
||||
|
||||
if (!monitor) {
|
||||
fprintf(stderr, "Failed to start iio motion monitoring\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct miix_wlr_state* state = miix_wlr_init();
|
||||
|
||||
for (;;) {
|
||||
if (!monitor->data_is_ready) continue;
|
||||
|
||||
enum accel_rotation rotation = accel_get_current_rotation(monitor);
|
||||
if (rotation == ACCEL_ROTATION_NO_CHANGE || rotation == last_accel_rotation) continue;
|
||||
miix_wlr_head_set_transform(
|
||||
state, DEFAULT_OUTPUT, SENSOR_TO_OUTPUT_ROTATION[rotation]);
|
||||
last_accel_rotation = rotation;
|
||||
}
|
||||
|
||||
accel_stop_monitor(monitor);
|
||||
miix_wlr_cleanup(state);
|
||||
}
|
311
output_manager.c
Normal file
311
output_manager.c
Normal file
|
@ -0,0 +1,311 @@
|
|||
// NOTE: Most of this code was stolen from wlr-randr, available at
|
||||
// https://git.sr.ht/~emersion/wlr-randr/tree/master/item/main.c
|
||||
|
||||
#include "output_manager.h"
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "protocol/wlr-output-management-unstable-v1.h"
|
||||
|
||||
static void head_handle_name(void* data,
|
||||
struct zwlr_output_head_v1*,
|
||||
const char* name)
|
||||
{
|
||||
struct miix_wlr_head* head = data;
|
||||
head->name = strdup(name);
|
||||
}
|
||||
|
||||
static void head_handle_description(void*,
|
||||
struct zwlr_output_head_v1*,
|
||||
const char*)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_physical_size(void*,
|
||||
struct zwlr_output_head_v1*,
|
||||
int32_t,
|
||||
int32_t)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_mode(void*,
|
||||
struct zwlr_output_head_v1*,
|
||||
struct zwlr_output_mode_v1*)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_enabled(void*, struct zwlr_output_head_v1*, int32_t)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_current_mode(void*,
|
||||
struct zwlr_output_head_v1*,
|
||||
struct zwlr_output_mode_v1*)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_position(void*,
|
||||
struct zwlr_output_head_v1*,
|
||||
int32_t,
|
||||
int32_t)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_transform(void*, struct zwlr_output_head_v1*, int32_t)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_scale(void*, struct zwlr_output_head_v1*, wl_fixed_t)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_finished(void*, struct zwlr_output_head_v1*)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_make(void*, struct zwlr_output_head_v1*, const char*)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_model(void*, struct zwlr_output_head_v1*, const char*)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_serial_number(void*,
|
||||
struct zwlr_output_head_v1*,
|
||||
const char*)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void head_handle_adaptive_sync(void*,
|
||||
struct zwlr_output_head_v1*,
|
||||
uint32_t)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static const struct zwlr_output_head_v1_listener head_listener = {
|
||||
.name = head_handle_name,
|
||||
.description = head_handle_description,
|
||||
.physical_size = head_handle_physical_size,
|
||||
.mode = head_handle_mode,
|
||||
.enabled = head_handle_enabled,
|
||||
.current_mode = head_handle_current_mode,
|
||||
.position = head_handle_position,
|
||||
.transform = head_handle_transform,
|
||||
.scale = head_handle_scale,
|
||||
.finished = head_handle_finished,
|
||||
.make = head_handle_make,
|
||||
.model = head_handle_model,
|
||||
.serial_number = head_handle_serial_number,
|
||||
.adaptive_sync = head_handle_adaptive_sync,
|
||||
};
|
||||
|
||||
static void output_manager_handle_head(void* data,
|
||||
struct zwlr_output_manager_v1*,
|
||||
struct zwlr_output_head_v1* wlr_head)
|
||||
{
|
||||
struct miix_wlr_state* state = data;
|
||||
|
||||
struct miix_wlr_head* head = calloc(1, sizeof(*head));
|
||||
head->wlr_head = wlr_head;
|
||||
wl_list_insert(state->heads.prev, &head->link);
|
||||
zwlr_output_head_v1_add_listener(wlr_head, &head_listener, head);
|
||||
}
|
||||
|
||||
static void output_manager_handle_done(void* data,
|
||||
struct zwlr_output_manager_v1*,
|
||||
uint32_t serial)
|
||||
{
|
||||
struct miix_wlr_state* state = data;
|
||||
state->serial = serial;
|
||||
}
|
||||
|
||||
static void output_manager_handle_finished(void*,
|
||||
struct zwlr_output_manager_v1*)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static const struct zwlr_output_manager_v1_listener output_manager_listener = {
|
||||
.head = output_manager_handle_head,
|
||||
.done = output_manager_handle_done,
|
||||
.finished = output_manager_handle_finished,
|
||||
};
|
||||
|
||||
static void registry_handle_global(void* data,
|
||||
struct wl_registry* registry,
|
||||
uint32_t name,
|
||||
const char* interface,
|
||||
uint32_t)
|
||||
{
|
||||
struct miix_wlr_state* state = data;
|
||||
|
||||
if (strcmp(interface, zwlr_output_manager_v1_interface.name) == 0) {
|
||||
// TODO: Don't always bind version 4?
|
||||
state->output_manager = wl_registry_bind(
|
||||
registry, name, &zwlr_output_manager_v1_interface, 4);
|
||||
zwlr_output_manager_v1_add_listener(
|
||||
state->output_manager, &output_manager_listener, state);
|
||||
}
|
||||
}
|
||||
|
||||
static void registry_handle_global_remove(void*, struct wl_registry*, uint32_t)
|
||||
{
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
static void config_handle_succeeded(void* data,
|
||||
struct zwlr_output_configuration_v1* config)
|
||||
{
|
||||
struct miix_wlr_state* state = data;
|
||||
state->is_working = false;
|
||||
zwlr_output_configuration_v1_destroy(config);
|
||||
printf("Applied configuration successfully!\n");
|
||||
}
|
||||
|
||||
static void config_handle_failed(void* data,
|
||||
struct zwlr_output_configuration_v1* config)
|
||||
{
|
||||
struct miix_wlr_state* state = data;
|
||||
state->is_working = false;
|
||||
zwlr_output_configuration_v1_destroy(config);
|
||||
fprintf(stderr, "Failed to apply configuration\n");
|
||||
}
|
||||
|
||||
static void config_handle_cancelled(void* data,
|
||||
struct zwlr_output_configuration_v1* config)
|
||||
{
|
||||
struct miix_wlr_state* state = data;
|
||||
state->is_working = false;
|
||||
zwlr_output_configuration_v1_destroy(config);
|
||||
fprintf(stderr, "Configuration cancelled\n");
|
||||
}
|
||||
|
||||
static const struct zwlr_output_configuration_v1_listener config_listener = {
|
||||
.succeeded = config_handle_succeeded,
|
||||
.failed = config_handle_failed,
|
||||
.cancelled = config_handle_cancelled,
|
||||
};
|
||||
|
||||
struct miix_wlr_state* miix_wlr_init()
|
||||
{
|
||||
struct wl_display* display = wl_display_connect(NULL);
|
||||
if (!display) {
|
||||
fprintf(stderr, "Couldn't connect to display\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct wl_registry* registry = wl_display_get_registry(display);
|
||||
if (!registry) {
|
||||
fprintf(stderr, "Couldn't get display registry\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct miix_wlr_state* state = calloc(1, sizeof(struct miix_wlr_state));
|
||||
|
||||
state->is_working = false;
|
||||
state->display = display;
|
||||
|
||||
wl_list_init(&state->heads);
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
.global = registry_handle_global,
|
||||
.global_remove = registry_handle_global_remove,
|
||||
};
|
||||
wl_registry_add_listener(registry, ®istry_listener, state);
|
||||
|
||||
wl_display_dispatch(display);
|
||||
wl_display_roundtrip(display);
|
||||
wl_registry_destroy(registry);
|
||||
|
||||
if (!state->output_manager) {
|
||||
fprintf(stderr,
|
||||
"Couldn't get output manager. Does your compositor support "
|
||||
"wlr-outpput-management-unstable-v1?\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
char** miix_wlr_get_head_names(struct miix_wlr_state const* state)
|
||||
{
|
||||
int head_count = wl_list_length(&state->heads);
|
||||
char** head_name_list = calloc(head_count + 1, sizeof(char*));
|
||||
size_t head_index = 0;
|
||||
|
||||
struct miix_wlr_head *head, *tmp_head;
|
||||
wl_list_for_each_safe(head, tmp_head, &state->heads, link)
|
||||
{
|
||||
head_name_list[head_index] = head->name;
|
||||
++head_index;
|
||||
}
|
||||
|
||||
head_name_list[head_index] = 0;
|
||||
return head_name_list;
|
||||
}
|
||||
|
||||
void miix_wlr_head_set_transform(struct miix_wlr_state* state,
|
||||
char const* const head_name,
|
||||
enum wl_output_transform transform)
|
||||
{
|
||||
struct zwlr_output_configuration_v1* output_config =
|
||||
zwlr_output_manager_v1_create_configuration(state->output_manager,
|
||||
state->serial);
|
||||
|
||||
zwlr_output_configuration_v1_add_listener(
|
||||
output_config, &config_listener, state);
|
||||
|
||||
struct miix_wlr_head* head;
|
||||
struct miix_wlr_head* tmp_head;
|
||||
wl_list_for_each_safe(head, tmp_head, &state->heads, link)
|
||||
{
|
||||
if (strcmp(head->name, head_name) != 0) continue;
|
||||
|
||||
printf("Found head %s\n", head->name);
|
||||
|
||||
struct zwlr_output_configuration_head_v1* config_head =
|
||||
zwlr_output_configuration_v1_enable_head(output_config,
|
||||
head->wlr_head);
|
||||
|
||||
state->is_working = true;
|
||||
|
||||
zwlr_output_configuration_head_v1_set_transform(config_head, transform);
|
||||
zwlr_output_configuration_v1_apply(output_config);
|
||||
}
|
||||
|
||||
while (state->is_working && wl_display_dispatch(state->display) > 0)
|
||||
;
|
||||
}
|
||||
|
||||
void miix_wlr_cleanup(struct miix_wlr_state* state)
|
||||
{
|
||||
struct miix_wlr_head* head;
|
||||
struct miix_wlr_head* tmp_head;
|
||||
wl_list_for_each_safe(head, tmp_head, &state->heads, link)
|
||||
{
|
||||
zwlr_output_head_v1_destroy(head->wlr_head);
|
||||
free(head->name);
|
||||
free(head);
|
||||
}
|
||||
|
||||
zwlr_output_manager_v1_destroy(state->output_manager);
|
||||
wl_display_disconnect(state->display);
|
||||
}
|
32
output_manager.h
Normal file
32
output_manager.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "protocol/wlr-output-management-unstable-v1.h"
|
||||
|
||||
struct miix_wlr_head {
|
||||
struct zwlr_output_head_v1* wlr_head;
|
||||
char* name;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct miix_wlr_state {
|
||||
bool is_working;
|
||||
|
||||
struct zwlr_output_manager_v1* output_manager;
|
||||
struct wl_display* display;
|
||||
uint32_t serial;
|
||||
|
||||
struct wl_list heads; // struct miix_wlr_head
|
||||
};
|
||||
|
||||
struct miix_wlr_state* miix_wlr_init();
|
||||
|
||||
char** miix_wlr_get_head_names(struct miix_wlr_state const*);
|
||||
void miix_wlr_head_set_transform(struct miix_wlr_state*,
|
||||
char const* const head_name,
|
||||
enum wl_output_transform);
|
||||
|
||||
void miix_wlr_cleanup(struct miix_wlr_state*);
|
6
protocol/codegen.sh
Executable file
6
protocol/codegen.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
PROTO_NAME=wlr-output-management-unstable-v1
|
||||
|
||||
wayland-scanner private-code $PROTO_NAME.xml $PROTO_NAME.c
|
||||
wayland-scanner client-header $PROTO_NAME.xml $PROTO_NAME.h
|
5
protocol/download_protocols.sh
Executable file
5
protocol/download_protocols.sh
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
URL="https://gitlab.freedesktop.org/wlroots/wlr-protocols/-/raw/master/unstable/wlr-output-management-unstable-v1.xml"
|
||||
|
||||
curl $URL > wlr-output-management-unstable-v1.xml
|
Loading…
Reference in a new issue