diff options
Diffstat (limited to 'sway/old/output.c')
-rw-r--r-- | sway/old/output.c | 278 |
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 | |||
9 | void 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 | |||
16 | swayc_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 | |||
51 | swayc_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. | ||
103 | swayc_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 | |||
230 | void 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 | |||
252 | void 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 | |||
258 | static 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 | |||
276 | void sort_workspaces(swayc_t *output) { | ||
277 | list_stable_sort(output->children, sort_workspace_cmp_qsort); | ||
278 | } | ||