|
21 | 21 | static const size_t MIME_LIST_SIZE_CAP = 1024 * 1024; |
22 | 22 | static const size_t PRESENT_DATA_CAP = 64 * 1024 * 1024; |
23 | 23 |
|
| 24 | +// Utils {{{ |
24 | 25 | // In test mode, this callable is invoked instead of schedule_write_to_child_if_possible. |
25 | 26 | // It receives (window_id: int, data: bytes) and its return value is ignored. |
26 | 27 | static PyObject *g_dnd_test_write_func = NULL; |
27 | 28 | static void drop_process_queue(Window *w); |
28 | 29 | static void drop_pop_request(Window *w); |
29 | 30 |
|
| 31 | +static const char* |
| 32 | +get_errno_name(int err) { |
| 33 | + switch (err) { |
| 34 | + case EPERM: return "EPERM"; |
| 35 | + case ENOENT: return "ENOENT"; |
| 36 | + case EIO: return "EIO"; |
| 37 | + case EINVAL: return "EINVAL"; |
| 38 | + case EMFILE: return "EMFILE"; |
| 39 | + case ENOMEM: return "ENOMEM"; |
| 40 | + case 0: return "OK"; |
| 41 | + default: return "EUNKNOWN"; |
| 42 | + } |
| 43 | +} |
| 44 | + |
30 | 45 | static const char* |
31 | 46 | machine_id(void) { |
32 | 47 | static bool done = false; |
@@ -56,96 +71,6 @@ dnd_set_test_write_func(PyObject *func) { |
56 | 71 | g_dnd_test_write_func = Py_XNewRef(func); |
57 | 72 | } |
58 | 73 |
|
59 | | -static void |
60 | | -drop_free_offered_mimes(Window *w) { |
61 | | - if (w->drop.offerred_mimes) { |
62 | | - for (size_t i = 0; i < w->drop.num_offerred_mimes; i++) free((void*)w->drop.offerred_mimes[i]); |
63 | | - free(w->drop.offerred_mimes); w->drop.offerred_mimes = NULL; |
64 | | - } |
65 | | - w->drop.num_offerred_mimes = 0; |
66 | | - w->drop.offered_mimes_total_size = 0; |
67 | | -} |
68 | | - |
69 | | -static void |
70 | | -drop_free_accepted_mimes(Window *w) { |
71 | | - free(w->drop.accepted_mimes); w->drop.accepted_mimes = NULL; |
72 | | - w->drop.accepted_mimes_sz = 0; |
73 | | -} |
74 | | - |
75 | | -static void |
76 | | -free_pending(PendingData *pending) { |
77 | | - if (pending->items) { |
78 | | - for (size_t i = 0; i < pending->count; i++) free(pending->items[i].buf); |
79 | | - free(pending->items); |
80 | | - } |
81 | | - zero_at_ptr(pending); |
82 | | -} |
83 | | - |
84 | | -static void |
85 | | -drop_free_dir_handle(DirHandle *h) { |
86 | | - free(h->path); |
87 | | - for (size_t i = 0; i < h->num_entries; i++) free(h->entries[i]); |
88 | | - free(h->entries); |
89 | | - zero_at_ptr(h); |
90 | | -} |
91 | | - |
92 | | -static void |
93 | | -drop_free_dir_handles(Window *w) { |
94 | | - for (size_t i = 0; i < w->drop.num_dir_handles; i++) |
95 | | - drop_free_dir_handle(&w->drop.dir_handles[i]); |
96 | | - free(w->drop.dir_handles); |
97 | | - w->drop.dir_handles = NULL; |
98 | | - w->drop.num_dir_handles = 0; |
99 | | - w->drop.dir_handles_capacity = 0; |
100 | | - w->drop.next_dir_handle_id = 0; |
101 | | -} |
102 | | - |
103 | | -static void |
104 | | -drop_close_file_fd(Window *w) { |
105 | | - if (w->drop.file_fd_plus_one) { |
106 | | - safe_close(w->drop.file_fd_plus_one - 1, __FILE__, __LINE__); |
107 | | - w->drop.file_fd_plus_one = 0; |
108 | | - } |
109 | | - if (w->drop.file_send_timer) { |
110 | | - remove_main_loop_timer(w->drop.file_send_timer); |
111 | | - w->drop.file_send_timer = 0; |
112 | | - } |
113 | | -} |
114 | | - |
115 | | -static void |
116 | | -drop_free_request_queue(Window *w) { |
117 | | - w->drop.num_data_requests = 0; |
118 | | - w->drop.current_request_x = 0; |
119 | | - w->drop.current_request_y = 0; |
120 | | - w->drop.current_request_Y = 0; |
121 | | -} |
122 | | - |
123 | | -void |
124 | | -drop_free_data(Window *w) { |
125 | | - drop_close_file_fd(w); |
126 | | - drop_free_offered_mimes(w); |
127 | | - drop_free_accepted_mimes(w); |
128 | | - free_pending(&w->drop.pending); |
129 | | - free(w->drop.registered_mimes); w->drop.registered_mimes = NULL; |
130 | | - free(w->drop.uri_list); w->drop.uri_list = NULL; |
131 | | - free(w->drop.getting_data_for_mime); w->drop.getting_data_for_mime = NULL; |
132 | | - drop_free_dir_handles(w); |
133 | | - drop_free_request_queue(w); |
134 | | -} |
135 | | - |
136 | | -static void |
137 | | -reset_drop(Window *w) { |
138 | | - bool wanted = w->drop.wanted; uint32_t cid = w->drop.client_id; |
139 | | - bool is_remote_client = w->drop.is_remote_client; |
140 | | - drop_free_data(w); |
141 | | - zero_at_ptr(&w->drop); |
142 | | - if (wanted) { |
143 | | - w->drop.wanted = wanted; |
144 | | - w->drop.client_id = cid; |
145 | | - w->drop.is_remote_client = is_remote_client; |
146 | | - } |
147 | | -} |
148 | | - |
149 | 74 | static int |
150 | 75 | string_arrays_cmp(const char **a, size_t an, const char **b, size_t bn) { |
151 | 76 | if (an != bn) return (int)an - (int)bn; |
@@ -269,6 +194,122 @@ is_same_machine(const char *client_machine_id, size_t sz) { |
269 | 194 | return sz == hsz && memcmp(client_machine_id, host_machine_id, sz) == 0; |
270 | 195 | } |
271 | 196 |
|
| 197 | +static void |
| 198 | +url_decode_inplace(char *str) { |
| 199 | + char *src = str, *dst = str; |
| 200 | + while (*src) { |
| 201 | + if (*src == '%' && src[1] && src[2]) { |
| 202 | + unsigned int hi = 0, lo = 0; |
| 203 | + char c1 = src[1], c2 = src[2]; |
| 204 | + if (c1 >= '0' && c1 <= '9') hi = c1 - '0'; |
| 205 | + else if (c1 >= 'a' && c1 <= 'f') hi = c1 - 'a' + 10; |
| 206 | + else if (c1 >= 'A' && c1 <= 'F') hi = c1 - 'A' + 10; |
| 207 | + else { *dst++ = *src++; continue; } |
| 208 | + if (c2 >= '0' && c2 <= '9') lo = c2 - '0'; |
| 209 | + else if (c2 >= 'a' && c2 <= 'f') lo = c2 - 'a' + 10; |
| 210 | + else if (c2 >= 'A' && c2 <= 'F') lo = c2 - 'A' + 10; |
| 211 | + else { *dst++ = *src++; continue; } |
| 212 | + *dst++ = (char)((hi << 4) | lo); |
| 213 | + src += 3; |
| 214 | + } else { |
| 215 | + *dst++ = *src++; |
| 216 | + } |
| 217 | + } |
| 218 | + *dst = 0; |
| 219 | +} |
| 220 | + |
| 221 | +// }}} |
| 222 | + |
| 223 | +// Dropping {{{ |
| 224 | +static void |
| 225 | +drop_free_offered_mimes(Window *w) { |
| 226 | + if (w->drop.offerred_mimes) { |
| 227 | + for (size_t i = 0; i < w->drop.num_offerred_mimes; i++) free((void*)w->drop.offerred_mimes[i]); |
| 228 | + free(w->drop.offerred_mimes); w->drop.offerred_mimes = NULL; |
| 229 | + } |
| 230 | + w->drop.num_offerred_mimes = 0; |
| 231 | + w->drop.offered_mimes_total_size = 0; |
| 232 | +} |
| 233 | + |
| 234 | +static void |
| 235 | +drop_free_accepted_mimes(Window *w) { |
| 236 | + free(w->drop.accepted_mimes); w->drop.accepted_mimes = NULL; |
| 237 | + w->drop.accepted_mimes_sz = 0; |
| 238 | +} |
| 239 | + |
| 240 | +static void |
| 241 | +free_pending(PendingData *pending) { |
| 242 | + if (pending->items) { |
| 243 | + for (size_t i = 0; i < pending->count; i++) free(pending->items[i].buf); |
| 244 | + free(pending->items); |
| 245 | + } |
| 246 | + zero_at_ptr(pending); |
| 247 | +} |
| 248 | + |
| 249 | +static void |
| 250 | +drop_free_dir_handle(DirHandle *h) { |
| 251 | + free(h->path); |
| 252 | + for (size_t i = 0; i < h->num_entries; i++) free(h->entries[i]); |
| 253 | + free(h->entries); |
| 254 | + zero_at_ptr(h); |
| 255 | +} |
| 256 | + |
| 257 | +static void |
| 258 | +drop_free_dir_handles(Window *w) { |
| 259 | + for (size_t i = 0; i < w->drop.num_dir_handles; i++) |
| 260 | + drop_free_dir_handle(&w->drop.dir_handles[i]); |
| 261 | + free(w->drop.dir_handles); |
| 262 | + w->drop.dir_handles = NULL; |
| 263 | + w->drop.num_dir_handles = 0; |
| 264 | + w->drop.dir_handles_capacity = 0; |
| 265 | + w->drop.next_dir_handle_id = 0; |
| 266 | +} |
| 267 | + |
| 268 | +static void |
| 269 | +drop_close_file_fd(Window *w) { |
| 270 | + if (w->drop.file_fd_plus_one) { |
| 271 | + safe_close(w->drop.file_fd_plus_one - 1, __FILE__, __LINE__); |
| 272 | + w->drop.file_fd_plus_one = 0; |
| 273 | + } |
| 274 | + if (w->drop.file_send_timer) { |
| 275 | + remove_main_loop_timer(w->drop.file_send_timer); |
| 276 | + w->drop.file_send_timer = 0; |
| 277 | + } |
| 278 | +} |
| 279 | + |
| 280 | +static void |
| 281 | +drop_free_request_queue(Window *w) { |
| 282 | + w->drop.num_data_requests = 0; |
| 283 | + w->drop.current_request_x = 0; |
| 284 | + w->drop.current_request_y = 0; |
| 285 | + w->drop.current_request_Y = 0; |
| 286 | +} |
| 287 | + |
| 288 | +void |
| 289 | +drop_free_data(Window *w) { |
| 290 | + drop_close_file_fd(w); |
| 291 | + drop_free_offered_mimes(w); |
| 292 | + drop_free_accepted_mimes(w); |
| 293 | + free_pending(&w->drop.pending); |
| 294 | + free(w->drop.registered_mimes); w->drop.registered_mimes = NULL; |
| 295 | + free(w->drop.uri_list); w->drop.uri_list = NULL; |
| 296 | + free(w->drop.getting_data_for_mime); w->drop.getting_data_for_mime = NULL; |
| 297 | + drop_free_dir_handles(w); |
| 298 | + drop_free_request_queue(w); |
| 299 | +} |
| 300 | + |
| 301 | +static void |
| 302 | +reset_drop(Window *w) { |
| 303 | + bool wanted = w->drop.wanted; uint32_t cid = w->drop.client_id; |
| 304 | + bool is_remote_client = w->drop.is_remote_client; |
| 305 | + drop_free_data(w); |
| 306 | + zero_at_ptr(&w->drop); |
| 307 | + if (wanted) { |
| 308 | + w->drop.wanted = wanted; |
| 309 | + w->drop.client_id = cid; |
| 310 | + w->drop.is_remote_client = is_remote_client; |
| 311 | + } |
| 312 | +} |
272 | 313 | void |
273 | 314 | drop_register_window(Window *w, const uint8_t *payload, size_t payload_sz, bool on, uint32_t client_id, bool more) { |
274 | 315 | w->drop.wanted = on; |
@@ -415,20 +456,6 @@ drop_update_mimes(Window *w, const char **allowed_mimes, size_t allowed_mimes_co |
415 | 456 | return allowed_mimes_count; |
416 | 457 | } |
417 | 458 |
|
418 | | -static const char* |
419 | | -get_errno_name(int err) { |
420 | | - switch (err) { |
421 | | - case EPERM: return "EPERM"; |
422 | | - case ENOENT: return "ENOENT"; |
423 | | - case EIO: return "EIO"; |
424 | | - case EINVAL: return "EINVAL"; |
425 | | - case EMFILE: return "EMFILE"; |
426 | | - case ENOMEM: return "ENOMEM"; |
427 | | - case 0: return "OK"; |
428 | | - default: return "EUNKNOWN"; |
429 | | - } |
430 | | -} |
431 | | - |
432 | 459 | /* Append the current request disambiguation keys (x, y, Y) to a header buffer. |
433 | 460 | * Returns the number of bytes written. */ |
434 | 461 | static int |
@@ -501,30 +528,6 @@ drop_dispatch_data(Window *w, const char *mime, const char *data, ssize_t sz) { |
501 | 528 |
|
502 | 529 | // ---- Remote file / directory transfer ---- |
503 | 530 |
|
504 | | -static void |
505 | | -url_decode_inplace(char *str) { |
506 | | - char *src = str, *dst = str; |
507 | | - while (*src) { |
508 | | - if (*src == '%' && src[1] && src[2]) { |
509 | | - unsigned int hi = 0, lo = 0; |
510 | | - char c1 = src[1], c2 = src[2]; |
511 | | - if (c1 >= '0' && c1 <= '9') hi = c1 - '0'; |
512 | | - else if (c1 >= 'a' && c1 <= 'f') hi = c1 - 'a' + 10; |
513 | | - else if (c1 >= 'A' && c1 <= 'F') hi = c1 - 'A' + 10; |
514 | | - else { *dst++ = *src++; continue; } |
515 | | - if (c2 >= '0' && c2 <= '9') lo = c2 - '0'; |
516 | | - else if (c2 >= 'a' && c2 <= 'f') lo = c2 - 'a' + 10; |
517 | | - else if (c2 >= 'A' && c2 <= 'F') lo = c2 - 'A' + 10; |
518 | | - else { *dst++ = *src++; continue; } |
519 | | - *dst++ = (char)((hi << 4) | lo); |
520 | | - src += 3; |
521 | | - } else { |
522 | | - *dst++ = *src++; |
523 | | - } |
524 | | - } |
525 | | - *dst = 0; |
526 | | -} |
527 | | - |
528 | 531 | /* Return the nth (0-based) file path from a text/uri-list. |
529 | 532 | * On success returns true and *path_out is a malloc'd absolute resolved path. |
530 | 533 | * On failure returns false and *error_out points to a static error string. */ |
@@ -1069,7 +1072,9 @@ drop_left_child(Window *w) { |
1069 | 1072 | queue_payload_to_child(w->id, w->drop.client_id, &w->drop.pending, buf, header_size, NULL, 0, false); |
1070 | 1073 | } |
1071 | 1074 | } |
| 1075 | +// }}} |
1072 | 1076 |
|
| 1077 | +// Dragging {{{ |
1073 | 1078 | #define ds w->drag_source |
1074 | 1079 |
|
1075 | 1080 | void |
@@ -1617,3 +1622,4 @@ drag_remote_file_data( |
1617 | 1622 | #undef img |
1618 | 1623 | #undef abrt |
1619 | 1624 | #undef ds |
| 1625 | +// }}} |
0 commit comments