Hi, Can someone pls have a look at this patch?
I implemented configuration options for relativ output positioning in weston.ini. Currently the implementation is private to the drm compositor, but i think this can be generalized for all output drivers. ATM it can only be configured in weston.ini, a dynamic way like xrandr would be nice (now idea how to). Next i want to introduce a concept of primary output, to center the mouse on the right monitor on start, draw the launcher only there and other stuff. I'm new to wayland/weston, so i'm not sure if this is even the right approach ... only tested with 2 monitors, sadly i don't have more :)
>From 4ee86a0b78a1c0d217cf5c973af0f3d50bd15c68 Mon Sep 17 00:00:00 2001 From: Florian Scandella <[email protected]> Date: Thu, 13 Jun 2013 21:23:51 +0200 Subject: [PATCH] [drm] Add support for output layout configuration Output configuration is specified by the "output" entries: above=<NAME> below=<NAME> left-of=<NAME> right-of=<NAME> where name references another output configuration. --- src/compositor-drm.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 76d0810..0823f54 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -187,6 +187,16 @@ struct drm_sprite { uint32_t formats[]; }; +struct drm_output_layout { + struct drm_output *output; + int visited; + int vx, vy; + struct drm_output_layout *left; + struct drm_output_layout *right; + struct drm_output_layout *top; + struct drm_output_layout *bottom; +}; + static const char default_seat[] = "seat0"; static void @@ -2031,6 +2041,182 @@ destroy_sprites(struct drm_compositor *compositor) } static int +drm_output_layout_init (struct drm_compositor *ec, struct drm_output_layout **map, int *n) +{ + struct drm_output *output; + int i = 0; + + *n = wl_list_length(&ec->base.output_list); + *map = malloc((*n) * sizeof **map); + + if (*map == NULL) + return -1; + + memset(*map, 0, (*n) * sizeof **map); + + wl_list_for_each(output, &ec->base.output_list, base.link) { + (*map)[i].output = output; + ++i; + } + + return 0; +} + +static int +drm_output_layout_find_index_by_name (struct drm_output_layout const *map, int n, char const *name) +{ + int j; + for (j=0; j < n; ++j) { + if (strcmp(name, map[j].output->base.name) == 0) { + return j; + } + } + return -1; +} + +static void +drm_output_layout_calculate_positions (struct drm_output_layout *current, int *minx, int *miny) +{ + current->visited = 1; + + if (current->vx < *minx) + *minx = current->vx; + if (current->vy < *miny) + *miny = current->vy; + + if (current->left && !current->left->visited) { + current->left->vx = current->vx - current->left->output->base.width; + current->left->vy = current->vy; + drm_output_layout_calculate_positions(current->left, minx, miny); + } + if (current->right && !current->right->visited) { + current->right->vx = current->vx + current->output->base.width; + current->right->vy = current->vy; + drm_output_layout_calculate_positions(current->right, minx, miny); + } + if (current->bottom && !current->bottom->visited) { + current->bottom->vx = current->vx; + current->bottom->vy = current->vy + current->output->base.height; + drm_output_layout_calculate_positions(current->bottom, minx, miny); + } + if (current->top && !current->top->visited) { + current->top->vx = current->vx; + current->top->vy = current->vy - current->top->output->base.height; + drm_output_layout_calculate_positions(current->top, minx, miny); + } +} + + +static void +drm_output_layout_put_left_of (struct drm_output_layout *map, int left_idx, int right_idx) +{ + map[left_idx].right = &map[right_idx]; + map[right_idx].left = &map[left_idx]; +} + + +static void +drm_output_layout_put_above (struct drm_output_layout *map, int bottom_idx, int top_idx) +{ + map[bottom_idx].top = &map[top_idx]; + map[top_idx].bottom = &map[bottom_idx]; +} + +/* merge defined und undefined output configurations */ +static void +drm_output_layout_prepare (struct drm_output_layout *map, int n) +{ + struct drm_output_layout *last_undefined = NULL; + struct drm_output_layout *last_defined = NULL; + + int i; + for (i = 0; i<n; ++i) { + if (map[i].left || map[i].right || map[i].bottom || map[i].top ) { + last_defined = &map[i]; + } else { + if (last_undefined) { + last_undefined->right = &map[i]; + map[i].left = last_undefined; + } + last_undefined = &map[i]; + } + } + + if (last_undefined && last_defined) { + + while(last_undefined->left) + last_undefined = last_undefined->left; + + while (last_defined->right) + last_defined = last_defined->right; + + last_defined->right = last_undefined; + last_undefined->left = last_defined; + } +} + + +static int +arrange_outputs(struct drm_compositor *ec) +{ + struct drm_output_layout *map; + int n_outputs, idx, minx = 0, miny = 0; + + if (drm_output_layout_init(ec, &map, &n_outputs)) + return -1; + + + for(idx=0; idx < n_outputs; ++idx) { + struct weston_config_section *current_section = weston_config_get_section(ec->base.config, "output", "name", map[idx].output->base.name); + char *option; + + if (current_section == NULL) + continue; + + weston_config_section_get_string(current_section, "left-of", &option, NULL); + if (option != NULL) { + int other_idx = drm_output_layout_find_index_by_name(map, n_outputs, option); + if (other_idx >= 0 && other_idx != idx) { + drm_output_layout_put_left_of(map, idx, other_idx); + } + } + weston_config_section_get_string(current_section, "right-of", &option, NULL); + if (option != NULL) { + int other_idx = drm_output_layout_find_index_by_name(map, n_outputs, option); + if (other_idx >= 0 && other_idx != idx) { + drm_output_layout_put_left_of(map, other_idx, idx); + } + } + weston_config_section_get_string(current_section, "above", &option, NULL); + if (option != NULL) { + int other_idx = drm_output_layout_find_index_by_name(map, n_outputs, option); + if (other_idx >= 0 && other_idx != idx) { + drm_output_layout_put_above(map, other_idx, idx); + } + } + weston_config_section_get_string(current_section, "below", &option, NULL); + if (option != NULL) { + int other_idx = drm_output_layout_find_index_by_name(map, n_outputs, option); + if (other_idx >= 0 && other_idx != idx) { + drm_output_layout_put_above(map, idx, other_idx); + } + } + } + + drm_output_layout_prepare(map, n_outputs); + drm_output_layout_calculate_positions(map, &minx, &miny); + + for(idx=0; idx < n_outputs; ++idx) { + weston_output_move(&map[idx].output->base, map[idx].vx - minx, map[idx].vy - miny); + } + + free(map); + + return 0; +} + + +static int create_outputs(struct drm_compositor *ec, uint32_t option_connector, struct udev_device *drm_device) { @@ -2088,6 +2274,7 @@ create_outputs(struct drm_compositor *ec, uint32_t option_connector, drmModeFreeResources(resources); return -1; } + arrange_outputs(ec); drmModeFreeResources(resources); @@ -2170,6 +2357,8 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device) /* FIXME: handle zero outputs, without terminating */ if (ec->connector_allocator == 0) wl_display_terminate(ec->base.wl_display); + + arrange_outputs(ec); } static int -- 1.8.3.1
_______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
