The data offers can be either dnd or selection offers. Add a separate struct for it so that handling of selection offers can be added.
Unified · Split
| @@ -221,6 +221,14 @@ struct vo_wayland_tranche { · 220 unmodified lines | |||
| 221 | struct wl_list link; | 221 | struct wl_list link; |
| 222 | }; | 222 | }; |
| 223 | 223 | ||
| 224 | struct vo_wayland_data_offer { | ||
| 225 | struct wl_data_offer *offer; | ||
| 226 | int action; // actually enum mp_dnd_action | ||
| 227 | char *mime_type; | ||
| 228 | int fd; | ||
| 229 | int mime_score; | ||
| 230 | }; | ||
| 231 | |||
| 224 | static bool single_output_spanned(struct vo_wayland_state *wl); | 232 | static bool single_output_spanned(struct vo_wayland_state *wl); |
| 225 | 233 | ||
| 226 | static int check_for_resize(struct vo_wayland_state *wl, int edge_pixels, | 234 | static int check_for_resize(struct vo_wayland_state *wl, int edge_pixels, |
| @@ -688,11 +696,12 @@ static void data_offer_handle_offer(void *data, struct wl_data_offer *offer, · 461 unmodified lines | |||
| 688 | { | 696 | { |
| 689 | struct vo_wayland_seat *s = data; | 697 | struct vo_wayland_seat *s = data; |
| 690 | struct vo_wayland_state *wl = s->wl; | 698 | struct vo_wayland_state *wl = s->wl; |
| 699 | struct vo_wayland_data_offer *o = wl->dnd_offer; | ||
| 691 | int score = mp_event_get_mime_type_score(wl->vo->input_ctx, mime_type); | 700 | int score = mp_event_get_mime_type_score(wl->vo->input_ctx, mime_type); |
| 692 | if (score > wl->dnd_mime_score && wl->opts->drag_and_drop != -2) { | 701 | if (score > o->mime_score && wl->opts->drag_and_drop != -2) { |
| 693 | wl->dnd_mime_score = score; | 702 | o->mime_score = score; |
| 694 | talloc_replace(wl, wl->dnd_mime_type, mime_type); | 703 | talloc_replace(wl, o->mime_type, mime_type); |
| 695 | MP_VERBOSE(wl, "Given DND offer with mime type %s\n", wl->dnd_mime_type); | 704 | MP_VERBOSE(wl, "Given DND offer with mime type %s\n", o->mime_type); |
| 696 | } | 705 | } |
| 697 | } | 706 | } |
| 698 | 707 | ||
| @@ -704,12 +713,13 @@ static void data_offer_action(void *data, struct wl_data_offer *wl_data_offer, u · 5 unmodified lines | |||
| 704 | { | 713 | { |
| 705 | struct vo_wayland_seat *s = data; | 714 | struct vo_wayland_seat *s = data; |
| 706 | struct vo_wayland_state *wl = s->wl; | 715 | struct vo_wayland_state *wl = s->wl; |
| 716 | struct vo_wayland_data_offer *o = wl->dnd_offer; | ||
| 707 | if (dnd_action && wl->opts->drag_and_drop != -2) { | 717 | if (dnd_action && wl->opts->drag_and_drop != -2) { |
| 708 | if (wl->opts->drag_and_drop >= 0) { | 718 | if (wl->opts->drag_and_drop >= 0) { |
| 709 | wl->dnd_action = wl->opts->drag_and_drop; | 719 | o->action = wl->opts->drag_and_drop; |
| 710 | } else { | 720 | } else { |
| 711 | wl->dnd_action = dnd_action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY ? | 721 | o->action = dnd_action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY ? |
| 712 | DND_REPLACE : DND_APPEND; | 722 | DND_REPLACE : DND_APPEND; |
| 713 | } | 723 | } |
| 714 | 724 | ||
| 715 | static const char * const dnd_action_names[] = { | 725 | static const char * const dnd_action_names[] = { |
| @@ -718,7 +728,7 @@ static void data_offer_action(void *data, struct wl_data_offer *wl_data_offer, u · 2 unmodified lines | |||
| 718 | [DND_INSERT_NEXT] = "DND_INSERT_NEXT", | 728 | [DND_INSERT_NEXT] = "DND_INSERT_NEXT", |
| 719 | }; | 729 | }; |
| 720 | 730 | ||
| 721 | MP_VERBOSE(wl, "DND action is %s\n", dnd_action_names[wl->dnd_action]); | 731 | MP_VERBOSE(wl, "DND action is %s\n", dnd_action_names[o->action]); |
| 722 | } | 732 | } |
| 723 | } | 733 | } |
| 724 | 734 | ||
| @@ -733,10 +743,11 @@ static void data_device_handle_data_offer(void *data, struct wl_data_device *wl_ · 8 unmodified lines | |||
| 733 | { | 743 | { |
| 734 | struct vo_wayland_seat *s = data; | 744 | struct vo_wayland_seat *s = data; |
| 735 | struct vo_wayland_state *wl = s->wl; | 745 | struct vo_wayland_state *wl = s->wl; |
| 736 | if (wl->dnd_offer) | 746 | struct vo_wayland_data_offer *o = wl->dnd_offer; |
| 737 | wl_data_offer_destroy(wl->dnd_offer); | 747 | if (o->offer) |
| 748 | wl_data_offer_destroy(o->offer); | ||
| 738 | 749 | ||
| 739 | wl->dnd_offer = id; | 750 | o->offer = id; |
| 740 | wl_data_offer_add_listener(id, &data_offer_listener, s); | 751 | wl_data_offer_add_listener(id, &data_offer_listener, s); |
| 741 | } | 752 | } |
| 742 | 753 | ||
| @@ -747,7 +758,8 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_ddev, · 4 unmodified lines | |||
| 747 | { | 758 | { |
| 748 | struct vo_wayland_seat *s = data; | 759 | struct vo_wayland_seat *s = data; |
| 749 | struct vo_wayland_state *wl = s->wl; | 760 | struct vo_wayland_state *wl = s->wl; |
| 750 | if (wl->dnd_offer != id) { | 761 | struct vo_wayland_data_offer *o = wl->dnd_offer; |
| 762 | if (o->offer != id) { | ||
| 751 | MP_FATAL(wl, "DND offer ID mismatch!\n"); | 763 | MP_FATAL(wl, "DND offer ID mismatch!\n"); |
| 752 | return; | 764 | return; |
| 753 | } | 765 | } |
| @@ -756,8 +768,8 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_ddev, · 2 unmodified lines | |||
| 756 | wl_data_offer_set_actions(id, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | | 768 | wl_data_offer_set_actions(id, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | |
| 757 | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, | 769 | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, |
| 758 | WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY); | 770 | WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY); |
| 759 | wl_data_offer_accept(id, serial, wl->dnd_mime_type); | 771 | wl_data_offer_accept(id, serial, o->mime_type); |
| 760 | MP_VERBOSE(wl, "Accepting DND offer with mime type %s\n", wl->dnd_mime_type); | 772 | MP_VERBOSE(wl, "Accepting DND offer with mime type %s\n", o->mime_type); |
| 761 | } | 773 | } |
| 762 | 774 | ||
| 763 | } | 775 | } |
| @@ -766,19 +778,20 @@ static void data_device_handle_leave(void *data, struct wl_data_device *wl_ddev) · 2 unmodified lines | |||
| 766 | { | 778 | { |
| 767 | struct vo_wayland_seat *s = data; | 779 | struct vo_wayland_seat *s = data; |
| 768 | struct vo_wayland_state *wl = s->wl; | 780 | struct vo_wayland_state *wl = s->wl; |
| 781 | struct vo_wayland_data_offer *o = wl->dnd_offer; | ||
| 769 | 782 | ||
| 770 | if (wl->dnd_offer) { | 783 | if (o->offer) { |
| 771 | if (wl->dnd_fd != -1) | 784 | if (o->fd != -1) |
| 772 | return; | 785 | return; |
| 773 | wl_data_offer_destroy(wl->dnd_offer); | 786 | wl_data_offer_destroy(o->offer); |
| 774 | wl->dnd_offer = NULL; | 787 | o->offer = NULL; |
| 775 | } | 788 | } |
| 776 | 789 | ||
| 777 | if (wl->opts->drag_and_drop != -2) { | 790 | if (wl->opts->drag_and_drop != -2) { |
| 778 | MP_VERBOSE(wl, "Releasing DND offer with mime type %s\n", wl->dnd_mime_type); | 791 | MP_VERBOSE(wl, "Releasing DND offer with mime type %s\n", o->mime_type); |
| 779 | if (wl->dnd_mime_type) | 792 | if (o->mime_type) |
| 780 | TA_FREEP(&wl->dnd_mime_type); | 793 | TA_FREEP(&o->mime_type); |
| 781 | wl->dnd_mime_score = 0; | 794 | o->mime_score = 0; |
| 782 | } | 795 | } |
| 783 | } | 796 | } |
| 784 | 797 | ||
| @@ -787,13 +800,15 @@ static void data_device_handle_motion(void *data, struct wl_data_device *wl_ddev · 2 unmodified lines | |||
| 787 | { | 800 | { |
| 788 | struct vo_wayland_seat *s = data; | 801 | struct vo_wayland_seat *s = data; |
| 789 | struct vo_wayland_state *wl = s->wl; | 802 | struct vo_wayland_state *wl = s->wl; |
| 790 | wl_data_offer_accept(wl->dnd_offer, time, wl->dnd_mime_type); | 803 | struct vo_wayland_data_offer *o = wl->dnd_offer; |
| 804 | wl_data_offer_accept(o->offer, time, o->mime_type); | ||
| 791 | } | 805 | } |
| 792 | 806 | ||
| 793 | static void data_device_handle_drop(void *data, struct wl_data_device *wl_ddev) | 807 | static void data_device_handle_drop(void *data, struct wl_data_device *wl_ddev) |
| 794 | { | 808 | { |
| 795 | struct vo_wayland_seat *s = data; | 809 | struct vo_wayland_seat *s = data; |
| 796 | struct vo_wayland_state *wl = s->wl; | 810 | struct vo_wayland_state *wl = s->wl; |
| 811 | struct vo_wayland_data_offer *o = wl->dnd_offer; | ||
| 797 | 812 | ||
| 798 | int pipefd[2]; | 813 | int pipefd[2]; |
| 799 | 814 | ||
| @@ -803,12 +818,12 @@ static void data_device_handle_drop(void *data, struct wl_data_device *wl_ddev) · 3 unmodified lines | |||
| 803 | } | 818 | } |
| 804 | 819 | ||
| 805 | if (wl->opts->drag_and_drop != -2) { | 820 | if (wl->opts->drag_and_drop != -2) { |
| 806 | MP_VERBOSE(wl, "Receiving DND offer with mime %s\n", wl->dnd_mime_type); | 821 | MP_VERBOSE(wl, "Receiving DND offer with mime %s\n", o->mime_type); |
| 807 | wl_data_offer_receive(wl->dnd_offer, wl->dnd_mime_type, pipefd[1]); | 822 | wl_data_offer_receive(o->offer, o->mime_type, pipefd[1]); |
| 808 | } | 823 | } |
| 809 | 824 | ||
| 810 | close(pipefd[1]); | 825 | close(pipefd[1]); |
| 811 | wl->dnd_fd = pipefd[0]; | 826 | o->fd = pipefd[0]; |
| 812 | } | 827 | } |
| 813 | 828 | ||
| 814 | static void data_device_handle_selection(void *data, struct wl_data_device *wl_ddev, | 829 | static void data_device_handle_selection(void *data, struct wl_data_device *wl_ddev, |
| @@ -816,10 +831,11 @@ static void data_device_handle_selection(void *data, struct wl_data_device *wl_d · 1 unmodified line | |||
| 816 | { | 831 | { |
| 817 | struct vo_wayland_seat *s = data; | 832 | struct vo_wayland_seat *s = data; |
| 818 | struct vo_wayland_state *wl = s->wl; | 833 | struct vo_wayland_state *wl = s->wl; |
| 834 | struct vo_wayland_data_offer *o = wl->dnd_offer; | ||
| 819 | 835 | ||
| 820 | if (wl->dnd_offer) { | 836 | if (o->offer) { |
| 821 | wl_data_offer_destroy(wl->dnd_offer); | 837 | wl_data_offer_destroy(o->offer); |
| 822 | wl->dnd_offer = NULL; | 838 | o->offer = NULL; |
| 823 | MP_VERBOSE(wl, "Received a new DND offer. Releasing the previous offer.\n"); | 839 | MP_VERBOSE(wl, "Received a new DND offer. Releasing the previous offer.\n"); |
| 824 | } | 840 | } |
| 825 | 841 | ||
| @@ -1830,21 +1846,23 @@ static void apply_keepaspect(struct vo_wayland_state *wl, int *width, int *heigh · 1004 unmodified lines | |||
| 1830 | } | 1846 | } |
| 1831 | } | 1847 | } |
| 1832 | 1848 | ||
| 1833 | static void free_dnd_data(struct vo_wayland_state *wl) | 1849 | static void destroy_offer(struct vo_wayland_data_offer *o) |
| 1834 | { | 1850 | { |
| 1835 | // caller should close wl->dnd_fd if appropriate | 1851 | TA_FREEP(&o->mime_type); |
| 1836 | 1852 | if (o->fd != -1) | |
| 1837 | wl->dnd_action = -1; | 1853 | close(o->fd); |
| 1838 | TA_FREEP(&wl->dnd_mime_type); | 1854 | if (o->offer) |
| 1839 | wl->dnd_mime_score = 0; | 1855 | wl_data_offer_destroy(o->offer); |
| 1856 | *o = (struct vo_wayland_data_offer){.fd = -1, .action = -1}; | ||
| 1840 | } | 1857 | } |
| 1841 | 1858 | ||
| 1842 | static void check_dnd_fd(struct vo_wayland_state *wl) | 1859 | static void check_dnd_fd(struct vo_wayland_state *wl) |
| 1843 | { | 1860 | { |
| 1844 | if (wl->dnd_fd == -1) | 1861 | struct vo_wayland_data_offer *o = wl->dnd_offer; |
| 1862 | if (o->fd == -1) | ||
| 1845 | return; | 1863 | return; |
| 1846 | 1864 | ||
| 1847 | struct pollfd fdp = { wl->dnd_fd, POLLIN | POLLHUP, 0 }; | 1865 | struct pollfd fdp = { o->fd, POLLIN | POLLHUP, 0 }; |
| 1848 | if (poll(&fdp, 1, 0) <= 0) | 1866 | if (poll(&fdp, 1, 0) <= 0) |
| 1849 | return; | 1867 | return; |
| 1850 | 1868 | ||
| @@ -1856,7 +1874,7 @@ static void check_dnd_fd(struct vo_wayland_state *wl) · 5 unmodified lines | |||
| 1856 | }; | 1874 | }; |
| 1857 | 1875 | ||
| 1858 | while (1) { | 1876 | while (1) { |
| 1859 | data_read = read(wl->dnd_fd, file_list.start + file_list.len, chunk_size); | 1877 | data_read = read(o->fd, file_list.start + file_list.len, chunk_size); |
| 1860 | if (data_read == -1 && errno == EINTR) | 1878 | if (data_read == -1 && errno == EINTR) |
| 1861 | continue; | 1879 | continue; |
| 1862 | else if (data_read <= 0) | 1880 | else if (data_read <= 0) |
| @@ -1871,24 +1889,24 @@ static void check_dnd_fd(struct vo_wayland_state *wl) · 8 unmodified lines | |||
| 1871 | } else { | 1889 | } else { |
| 1872 | MP_VERBOSE(wl, "Read %zu bytes from the DND fd\n", file_list.len); | 1890 | MP_VERBOSE(wl, "Read %zu bytes from the DND fd\n", file_list.len); |
| 1873 | 1891 | ||
| 1874 | if (wl->dnd_offer) | 1892 | if (o->offer) |
| 1875 | wl_data_offer_finish(wl->dnd_offer); | 1893 | wl_data_offer_finish(o->offer); |
| 1876 | 1894 | ||
| 1877 | assert(wl->dnd_action >= 0); | 1895 | assert(o->action >= 0); |
| 1878 | mp_event_drop_mime_data(wl->vo->input_ctx, wl->dnd_mime_type, | 1896 | mp_event_drop_mime_data(wl->vo->input_ctx, o->mime_type, |
| 1879 | file_list, wl->dnd_action); | 1897 | file_list, o->action); |
| 1880 | } | 1898 | } |
| 1881 | 1899 | ||
| 1882 | talloc_free(file_list.start); | 1900 | talloc_free(file_list.start); |
| 1883 | free_dnd_data(wl); | 1901 | free_offer_data(wl->dnd_offer); |
| 1884 | } | 1902 | } |
| 1885 | 1903 | ||
| 1886 | if (fdp.revents & (POLLIN | POLLERR | POLLHUP)) { | 1904 | if (fdp.revents & (POLLIN | POLLERR | POLLHUP)) { |
| 1887 | if (wl->dnd_action >= 0) | 1905 | if (o->action >= 0) |
| 1888 | MP_VERBOSE(wl, "DND aborted (hang up or error)\n"); | 1906 | MP_VERBOSE(wl, "DND aborted (hang up or error)\n"); |
| 1889 | free_dnd_data(wl); | 1907 | free_offer_data(wl->dnd_offer); |
| 1890 | close(wl->dnd_fd); | 1908 | close(o->fd); |
| 1891 | wl->dnd_fd = -1; | 1909 | o->fd = -1; |
| 1892 | } | 1910 | } |
| 1893 | } | 1911 | } |
| 1894 | 1912 | ||
| @@ -3040,7 +3058,7 @@ bool vo_wayland_init(struct vo *vo) · 1145 unmodified lines | |||
| 3040 | .scaling = WAYLAND_SCALE_FACTOR, | 3058 | .scaling = WAYLAND_SCALE_FACTOR, |
| 3041 | .wakeup_pipe = {-1, -1}, | 3059 | .wakeup_pipe = {-1, -1}, |
| 3042 | .display_fd = -1, | 3060 | .display_fd = -1, |
| 3043 | .dnd_fd = -1, | 3061 | .dnd_offer = talloc_zero(wl, struct vo_wayland_data_offer), |
| 3044 | .cursor_visible = true, | 3062 | .cursor_visible = true, |
| 3045 | .opts_cache = m_config_cache_alloc(wl, vo->global, &vo_sub_opts), | 3063 | .opts_cache = m_config_cache_alloc(wl, vo->global, &vo_sub_opts), |
| 3046 | }; | 3064 | }; |
| @@ -3269,9 +3287,7 @@ void vo_wayland_uninit(struct vo *vo) · 222 unmodified lines | |||
| 3269 | if (!wl) | 3287 | if (!wl) |
| 3270 | return; | 3288 | return; |
| 3271 | 3289 | ||
| 3272 | if (wl->dnd_fd != -1) | 3290 | destroy_offer(wl->dnd_offer); |
| 3273 | close(wl->dnd_fd); | ||
| 3274 | free_dnd_data(wl); | ||
| 3275 | 3291 | ||
| 3276 | mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL); | 3292 | mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL); |
| 3277 | 3293 | ||
| @@ -3313,9 +3329,6 @@ void vo_wayland_uninit(struct vo *vo) · 35 unmodified lines | |||
| 3313 | if (wl->dnd_devman) | 3329 | if (wl->dnd_devman) |
| 3314 | wl_data_device_manager_destroy(wl->dnd_devman); | 3330 | wl_data_device_manager_destroy(wl->dnd_devman); |
| 3315 | 3331 | ||
| 3316 | if (wl->dnd_offer) | ||
| 3317 | wl_data_offer_destroy(wl->dnd_offer); | ||
| 3318 | |||
| 3319 | if (wl->fback_pool) | 3332 | if (wl->fback_pool) |
| 3320 | clean_feedback_pool(wl->fback_pool); | 3333 | clean_feedback_pool(wl->fback_pool); |
| 3321 | 3334 | ||
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | struct compositor_format; | 27 | struct compositor_format; |
| 28 | struct vo_wayland_seat; | 28 | struct vo_wayland_seat; |
| 29 | struct vo_wayland_tranche; | 29 | struct vo_wayland_tranche; |
| 30 | struct vo_wayland_data_offer; | ||
| 30 | 31 | ||
| 31 | struct drm_format { | 32 | struct drm_format { |
| 32 | uint32_t format; | 33 | uint32_t format; |
| @@ -160,13 +161,9 @@ struct vo_wayland_state { · 127 unmodified lines | |||
| 160 | struct wl_list seat_list; | 161 | struct wl_list seat_list; |
| 161 | struct xkb_context *xkb_context; | 162 | struct xkb_context *xkb_context; |
| 162 | 163 | ||
| 163 | /* DND */ | 164 | /* Data offer */ |
| 164 | struct wl_data_device_manager *dnd_devman; | 165 | struct wl_data_device_manager *dnd_devman; |
| 165 | struct wl_data_offer *dnd_offer; | 166 | struct vo_wayland_data_offer *dnd_offer; |
| 166 | int dnd_action; // actually enum mp_dnd_action | ||
| 167 | char *dnd_mime_type; | ||
| 168 | int dnd_fd; | ||
| 169 | int dnd_mime_score; | ||
| 170 | 167 | ||
| 171 | /* Cursor */ | 168 | /* Cursor */ |
| 172 | struct wl_cursor_theme *cursor_theme; | 169 | struct wl_cursor_theme *cursor_theme; |