commit 1b087d360270683d066f091675072419df65c281
parent baebf0e284c8608e3c1ae9ed37a9f58436f44b3a
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 25 Apr 2019 13:40:20 -0400
Add output configuration options
Diffstat:
M | include/server.h | | | 10 | ++++++++++ |
M | main.c | | | 61 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
M | output.c | | | 52 | ++++++++++++++++++++++++++++++++++++++++++++++------ |
3 files changed, 113 insertions(+), 10 deletions(-)
diff --git a/include/server.h b/include/server.h
@@ -44,6 +44,7 @@ struct wio_server {
struct wlr_xdg_shell *xdg_shell;
struct wl_list outputs;
+ struct wl_list output_configs;
struct wl_list inputs;
struct wl_list pointers;
struct wl_list keyboards;
@@ -86,6 +87,15 @@ struct wio_output {
struct wl_listener frame;
};
+struct wio_output_config {
+ const char *name;
+ int x, y;
+ int width, height;
+ int scale;
+ enum wl_output_transform transform;
+ struct wl_list link;
+};
+
struct wio_keyboard {
struct wl_list link;
diff --git a/main.c b/main.c
@@ -1,7 +1,9 @@
-#define _POSIX_C_SOURCE 200112L
+#define _POSIX_C_SOURCE 200809L
+#include <assert.h>
#include <cairo/cairo.h>
#include <getopt.h>
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#include <wayland-server.h>
#include <wlr/backend.h>
@@ -72,14 +74,38 @@ static void gen_menu_textures(struct wio_server *server) {
cairo_surface_destroy(surf);
}
+static enum wl_output_transform str_to_transform(const char *str) {
+ if (strcmp(str, "normal") == 0 || strcmp(str, "0") == 0) {
+ return WL_OUTPUT_TRANSFORM_NORMAL;
+ } else if (strcmp(str, "90") == 0) {
+ return WL_OUTPUT_TRANSFORM_90;
+ } else if (strcmp(str, "180") == 0) {
+ return WL_OUTPUT_TRANSFORM_180;
+ } else if (strcmp(str, "270") == 0) {
+ return WL_OUTPUT_TRANSFORM_270;
+ } else if (strcmp(str, "flipped") == 0) {
+ return WL_OUTPUT_TRANSFORM_FLIPPED;
+ } else if (strcmp(str, "flipped-90") == 0) {
+ return WL_OUTPUT_TRANSFORM_FLIPPED_90;
+ } else if (strcmp(str, "flipped-180") == 0) {
+ return WL_OUTPUT_TRANSFORM_FLIPPED_180;
+ } else if (strcmp(str, "flipped-270") == 0) {
+ return WL_OUTPUT_TRANSFORM_FLIPPED_270;
+ } else {
+ fprintf(stderr, "Invalid output transform %s\n", str);
+ exit(1);
+ }
+}
+
int main(int argc, char **argv) {
struct wio_server server = { 0 };
server.cage = "cage -d";
server.term = "alacritty";
wlr_log_init(WLR_DEBUG, NULL);
+ wl_list_init(&server.output_configs);
int c;
- while ((c = getopt(argc, argv, "c:t:h")) != -1) {
+ while ((c = getopt(argc, argv, "c:t:o:h")) != -1) {
switch (c) {
case 'c':
server.cage = optarg;
@@ -87,10 +113,37 @@ int main(int argc, char **argv) {
case 't':
server.term = optarg;
break;
+ case 'o':;
+ // name:x:y:width:height:scale:transform
+ struct wio_output_config *config =
+ calloc(1, sizeof(struct wio_output_config));
+ wl_list_insert(&server.output_configs, &config->link);
+ const char *tok = strtok(optarg, ":");
+ assert(tok);
+ config->name = strdup(tok);
+ tok = strtok(NULL, ":");
+ assert(tok);
+ config->x = atoi(tok);
+ tok = strtok(NULL, ":");
+ assert(tok);
+ config->y = atoi(tok);
+ tok = strtok(NULL, ":");
+ if (!tok) break;
+ config->width = atoi(tok);
+ tok = strtok(NULL, ":");
+ assert(tok);
+ config->height = atoi(tok);
+ tok = strtok(NULL, ":");
+ if (!tok) break;
+ config->scale = atoi(tok);
+ tok = strtok(NULL, ":");
+ if (!tok) break;
+ config->transform = str_to_transform(tok);
+ break;
case 'h':
- printf("Usage: %s [-t terminal command] [-c cage command]\n",
+ printf("Usage: %s [-t <term>] [-c <cage>] [-o <output config>...]\n",
argv[0]);
- break;
+ return 0;
default:
fprintf(stderr, "Unrecognized option %c\n", c);
return 1;
diff --git a/output.c b/output.c
@@ -244,11 +244,6 @@ void server_new_output(struct wl_listener *listener, void *data) {
wl_container_of(listener, server, new_output);
struct wlr_output *wlr_output = data;
- if (!wl_list_empty(&wlr_output->modes)) {
- struct wlr_output_mode *mode =
- wl_container_of(wlr_output->modes.prev, mode, link);
- wlr_output_set_mode(wlr_output, mode);
- }
struct wio_output *output = calloc(1, sizeof(struct wio_output));
output->wlr_output = wlr_output;
@@ -257,6 +252,51 @@ void server_new_output(struct wl_listener *listener, void *data) {
wl_signal_add(&wlr_output->events.frame, &output->frame);
wl_list_insert(&server->outputs, &output->link);
- wlr_output_layout_add_auto(server->output_layout, wlr_output);
+ struct wio_output_config *_config, *config = NULL;
+ wl_list_for_each(_config, &server->output_configs, link) {
+ if (strcmp(_config->name, wlr_output->name) == 0) {
+ config = _config;
+ break;
+ }
+ }
+
+ if (config) {
+ if (config->x == -1 && config->y == -1) {
+ wlr_output_layout_add_auto(server->output_layout, wlr_output);
+ } else {
+ wlr_output_layout_add(server->output_layout, wlr_output,
+ config->x, config->y);
+ }
+ if (config->width && config->height
+ && !wl_list_empty(&wlr_output->modes)) {
+ bool set = false;
+ struct wlr_output_mode *mode;
+ wl_list_for_each(mode, &wlr_output->modes, link) {
+ if (mode->width == config->width
+ && mode->height == config->height) {
+ wlr_output_set_mode(wlr_output, mode);
+ set = true;
+ }
+ }
+ if (!set) {
+ mode = wl_container_of(wlr_output->modes.prev, mode, link);
+ wlr_output_set_mode(wlr_output, mode);
+ }
+ }
+ if (config->scale) {
+ wlr_output_set_scale(wlr_output, config->scale);
+ }
+ if (config->transform) {
+ wlr_output_set_transform(wlr_output, config->transform);
+ }
+ } else {
+ if (!wl_list_empty(&wlr_output->modes)) {
+ struct wlr_output_mode *mode =
+ wl_container_of(wlr_output->modes.prev, mode, link);
+ wlr_output_set_mode(wlr_output, mode);
+ }
+ wlr_output_layout_add_auto(server->output_layout, wlr_output);
+ }
+
wlr_output_create_global(wlr_output);
}