summaryrefslogtreecommitdiffstats
path: root/sway/old/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/old/output.c')
-rw-r--r--sway/old/output.c278
1 files changed, 0 insertions, 278 deletions
diff --git a/sway/old/output.c b/sway/old/output.c
deleted file mode 100644
index edfcac98..00000000
--- a/sway/old/output.c
+++ /dev/null
@@ -1,278 +0,0 @@
1#define _POSIX_C_SOURCE 200809L
2#include <strings.h>
3#include <ctype.h>
4#include <stdlib.h>
5#include "sway/output.h"
6#include "log.h"
7#include "list.h"
8
9void output_get_scaled_size(wlc_handle handle, struct wlc_size *size) {
10 *size = *wlc_output_get_resolution(handle);
11 uint32_t scale = wlc_output_get_scale(handle);
12 size->w /= scale;
13 size->h /= scale;
14}
15
16swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos) {
17 swayc_t *output = NULL;
18 // If there is no output directly next to the current one, use
19 // swayc_opposite_output to wrap.
20 if (strcasecmp(name, "left") == 0) {
21 output = swayc_adjacent_output(NULL, MOVE_LEFT, abs_pos, true);
22 if (!output) {
23 output = swayc_opposite_output(MOVE_RIGHT, abs_pos);
24 }
25 } else if (strcasecmp(name, "right") == 0) {
26 output = swayc_adjacent_output(NULL, MOVE_RIGHT, abs_pos, true);
27 if (!output) {
28 output = swayc_opposite_output(MOVE_LEFT, abs_pos);
29 }
30 } else if (strcasecmp(name, "up") == 0) {
31 output = swayc_adjacent_output(NULL, MOVE_UP, abs_pos, true);
32 if (!output) {
33 output = swayc_opposite_output(MOVE_DOWN, abs_pos);
34 }
35 } else if (strcasecmp(name, "down") == 0) {
36 output = swayc_adjacent_output(NULL, MOVE_DOWN, abs_pos, true);
37 if (!output) {
38 output = swayc_opposite_output(MOVE_UP, abs_pos);
39 }
40 } else {
41 for(int i = 0; i < root_container.children->length; ++i) {
42 swayc_t *c = root_container.children->items[i];
43 if (c->type == C_OUTPUT && strcasecmp(c->name, name) == 0) {
44 return c;
45 }
46 }
47 }
48 return output;
49}
50
51swayc_t *swayc_opposite_output(enum movement_direction dir,
52 const struct wlc_point *abs_pos) {
53
54 // Search through all the outputs and pick the output whose edge covers the
55 // given position, and is at leftmost/rightmost/upmost/downmost side of the
56 // screen (decided by the direction given).
57 swayc_t *opposite = NULL;
58 char *dir_text = NULL;
59 switch(dir) {
60 case MOVE_LEFT:
61 case MOVE_RIGHT: ;
62 for (int i = 0; i < root_container.children->length; ++i) {
63 swayc_t *c = root_container.children->items[i];
64 if (abs_pos->y >= c->y && abs_pos->y <= c->y + c->height) {
65 if (!opposite) {
66 opposite = c;
67 } else if ((dir == MOVE_LEFT && c->x < opposite->x)
68 || (dir == MOVE_RIGHT && c->x > opposite->x)) {
69 opposite = c;
70 }
71 }
72 }
73 dir_text = dir == MOVE_LEFT ? "leftmost" : "rightmost";
74 break;
75 case MOVE_UP:
76 case MOVE_DOWN: ;
77 for (int i = 0; i < root_container.children->length; ++i) {
78 swayc_t *c = root_container.children->items[i];
79 if (abs_pos->x >= c->x && abs_pos->x <= c->x + c->width) {
80 if (!opposite) {
81 opposite = c;
82 } else if ((dir == MOVE_UP && c->y < opposite->y)
83 || (dir == MOVE_DOWN && c->y > opposite->y)) {
84 opposite = c;
85 }
86 }
87 }
88 dir_text = dir == MOVE_UP ? "upmost" : "downmost";
89 break;
90 default:
91 sway_abort("Function called with invalid argument.");
92 break;
93 }
94 if (opposite) {
95 sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s from y-position %i",
96 opposite->name, opposite->width, opposite->height, opposite->x, opposite->y,
97 dir_text, abs_pos->y);
98 }
99 return opposite;
100}
101
102// Position is where on the edge (as absolute position) the adjacent output should be searched for.
103swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir,
104 const struct wlc_point *abs_pos, bool pick_closest) {
105
106 if (!output) {
107 output = swayc_active_output();
108 }
109 // In order to find adjacent outputs we need to test that the outputs are
110 // aligned on one axis (decided by the direction given) and that the given
111 // position is within the edge of the adjacent output. If no such output
112 // exists we pick the adjacent output within the edge that is closest to
113 // the given position, if any.
114 swayc_t *adjacent = NULL;
115 char *dir_text = NULL;
116 switch(dir) {
117 case MOVE_LEFT:
118 case MOVE_RIGHT: ;
119 double delta_y = 0;
120 for(int i = 0; i < root_container.children->length; ++i) {
121 swayc_t *c = root_container.children->items[i];
122 if (c == output || c->type != C_OUTPUT) {
123 continue;
124 }
125 bool x_aligned = dir == MOVE_LEFT ?
126 c->x + c->width == output->x :
127 c->x == output->x + output->width;
128 if (!x_aligned) {
129 continue;
130 }
131 if (abs_pos->y >= c->y && abs_pos->y <= c->y + c->height) {
132 delta_y = 0;
133 adjacent = c;
134 break;
135 } else if (pick_closest) {
136 // track closest adjacent output
137 double top_y = c->y, bottom_y = c->y + c->height;
138 if (top_y >= output->y && top_y <= output->y + output->height) {
139 double delta = top_y - abs_pos->y;
140 if (delta < 0) delta = -delta;
141 if (delta < delta_y || !adjacent) {
142 delta_y = delta;
143 adjacent = c;
144 }
145 }
146 // we check both points and pick the closest
147 if (bottom_y >= output->y && bottom_y <= output->y + output->height) {
148 double delta = bottom_y - abs_pos->y;
149 if (delta < 0) delta = -delta;
150 if (delta < delta_y || !adjacent) {
151 delta_y = delta;
152 adjacent = c;
153 }
154 }
155 }
156 }
157 dir_text = dir == MOVE_LEFT ? "left of" : "right of";
158 if (adjacent && delta_y == 0) {
159 sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s current output %s (y-position %i)",
160 adjacent->name, adjacent->width, adjacent->height, adjacent->x, adjacent->y,
161 dir_text, output->name, abs_pos->y);
162 } else if (adjacent) {
163 // so we end up picking the closest adjacent output because
164 // there is no directly adjacent to the given position
165 sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s current output %s (y-position %i, delta: %.0f)",
166 adjacent->name, adjacent->width, adjacent->height, adjacent->x, adjacent->y,
167 dir_text, output->name, abs_pos->y, delta_y);
168 }
169 break;
170 case MOVE_UP:
171 case MOVE_DOWN: ;
172 double delta_x = 0;
173 for(int i = 0; i < root_container.children->length; ++i) {
174 swayc_t *c = root_container.children->items[i];
175 if (c == output || c->type != C_OUTPUT) {
176 continue;
177 }
178 bool y_aligned = dir == MOVE_UP ?
179 c->y + c->height == output->y :
180 c->y == output->y + output->height;
181 if (!y_aligned) {
182 continue;
183 }
184 if (abs_pos->x >= c->x && abs_pos->x <= c->x + c->width) {
185 delta_x = 0;
186 adjacent = c;
187 break;
188 } else if (pick_closest) {
189 // track closest adjacent output
190 double left_x = c->x, right_x = c->x + c->width;
191 if (left_x >= output->x && left_x <= output->x + output->width) {
192 double delta = left_x - abs_pos->x;
193 if (delta < 0) delta = -delta;
194 if (delta < delta_x || !adjacent) {
195 delta_x = delta;
196 adjacent = c;
197 }
198 }
199 // we check both points and pick the closest
200 if (right_x >= output->x && right_x <= output->x + output->width) {
201 double delta = right_x - abs_pos->x;
202 if (delta < 0) delta = -delta;
203 if (delta < delta_x || !adjacent) {
204 delta_x = delta;
205 adjacent = c;
206 }
207 }
208 }
209 }
210 dir_text = dir == MOVE_UP ? "above" : "below";
211 if (adjacent && delta_x == 0) {
212 sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s current output %s (x-position %i)",
213 adjacent->name, adjacent->width, adjacent->height, adjacent->x, adjacent->y,
214 dir_text, output->name, abs_pos->x);
215 } else if (adjacent) {
216 // so we end up picking the closest adjacent output because
217 // there is no directly adjacent to the given position
218 sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s current output %s (x-position %i, delta: %.0f)",
219 adjacent->name, adjacent->width, adjacent->height, adjacent->x, adjacent->y,
220 dir_text, output->name, abs_pos->x, delta_x);
221 }
222 break;
223 default:
224 sway_abort("Function called with invalid argument.");
225 break;
226 }
227 return adjacent;
228}
229
230void get_absolute_position(swayc_t *container, struct wlc_point *point) {
231 if (!container || !point)
232 sway_abort("Need container and wlc_point (was %p, %p).", container, point);
233
234 if (container->type == C_OUTPUT) {
235 // Coordinates are already absolute.
236 point->x = container->x;
237 point->y = container->y;
238 } else {
239 swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
240 if (container->type == C_WORKSPACE) {
241 // Workspace coordinates are actually wrong/arbitrary, but should
242 // be same as output.
243 point->x = output->x;
244 point->y = output->y;
245 } else {
246 point->x = output->x + container->x;
247 point->y = output->y + container->y;
248 }
249 }
250}
251
252void get_absolute_center_position(swayc_t *container, struct wlc_point *point) {
253 get_absolute_position(container, point);
254 point->x += container->width/2;
255 point->y += container->height/2;
256}
257
258static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
259 swayc_t *a = *(void **)_a;
260 swayc_t *b = *(void **)_b;
261 int retval = 0;
262
263 if (isdigit(a->name[0]) && isdigit(b->name[0])) {
264 int a_num = strtol(a->name, NULL, 10);
265 int b_num = strtol(b->name, NULL, 10);
266 retval = (a_num < b_num) ? -1 : (a_num > b_num);
267 } else if (isdigit(a->name[0])) {
268 retval = -1;
269 } else if (isdigit(b->name[0])) {
270 retval = 1;
271 }
272
273 return retval;
274}
275
276void sort_workspaces(swayc_t *output) {
277 list_stable_sort(output->children, sort_workspace_cmp_qsort);
278}