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 | 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 | 232 | static bool single_output_spanned(struct vo_wayland_state *wl); |
| 225 | 233 | |
| 226 | 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 | 697 | struct vo_wayland_seat *s = data; |
| 690 | 698 | struct vo_wayland_state *wl = s->wl; |
| 699 | + struct vo_wayland_data_offer *o = wl->dnd_offer; | |
| 691 | 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) { | |
| 693 | − wl->dnd_mime_score = score; | |
| 694 | − talloc_replace(wl, wl->dnd_mime_type, mime_type); | |
| 695 | − MP_VERBOSE(wl, "Given DND offer with mime type %s\n", wl->dnd_mime_type); | |
| 701 | + if (score > o->mime_score && wl->opts->drag_and_drop != -2) { | |
| 702 | + o->mime_score = score; | |
| 703 | + talloc_replace(wl, o->mime_type, 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 | 714 | struct vo_wayland_seat *s = data; |
| 706 | 715 | struct vo_wayland_state *wl = s->wl; |
| 716 | + struct vo_wayland_data_offer *o = wl->dnd_offer; | |
| 707 | 717 | if (dnd_action && wl->opts->drag_and_drop != -2) { |
| 708 | 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 | 720 | } else { |
| 711 | − wl->dnd_action = dnd_action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY ? | |
| 712 | − DND_REPLACE : DND_APPEND; | |
| 721 | + o->action = dnd_action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY ? | |
| 722 | + DND_REPLACE : DND_APPEND; | |
| 713 | 723 | } |
| 714 | 724 | |
| 715 | 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 | 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 | 744 | struct vo_wayland_seat *s = data; |
| 735 | 745 | struct vo_wayland_state *wl = s->wl; |
| 736 | − if (wl->dnd_offer) | |
| 737 | − wl_data_offer_destroy(wl->dnd_offer); | |
| 746 | + struct vo_wayland_data_offer *o = 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 | 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 | 759 | struct vo_wayland_seat *s = data; |
| 749 | 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 | 763 | MP_FATAL(wl, "DND offer ID mismatch!\n"); |
| 752 | 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 | 768 | wl_data_offer_set_actions(id, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | |
| 757 | 769 | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, |
| 758 | 770 | WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY); |
| 759 | − wl_data_offer_accept(id, serial, wl->dnd_mime_type); | |
| 760 | − MP_VERBOSE(wl, "Accepting DND offer with mime type %s\n", wl->dnd_mime_type); | |
| 771 | + wl_data_offer_accept(id, serial, o->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 | 779 | struct vo_wayland_seat *s = data; |
| 768 | 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) { | |
| 771 | − if (wl->dnd_fd != -1) | |
| 783 | + if (o->offer) { | |
| 784 | + if (o->fd != -1) | |
| 772 | 785 | return; |
| 773 | − wl_data_offer_destroy(wl->dnd_offer); | |
| 774 | − wl->dnd_offer = NULL; | |
| 786 | + wl_data_offer_destroy(o->offer); | |
| 787 | + o->offer = NULL; | |
| 775 | 788 | } |
| 776 | 789 | |
| 777 | 790 | if (wl->opts->drag_and_drop != -2) { |
| 778 | − MP_VERBOSE(wl, "Releasing DND offer with mime type %s\n", wl->dnd_mime_type); | |
| 779 | − if (wl->dnd_mime_type) | |
| 780 | − TA_FREEP(&wl->dnd_mime_type); | |
| 781 | − wl->dnd_mime_score = 0; | |
| 791 | + MP_VERBOSE(wl, "Releasing DND offer with mime type %s\n", o->mime_type); | |
| 792 | + if (o->mime_type) | |
| 793 | + TA_FREEP(&o->mime_type); | |
| 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 | 801 | struct vo_wayland_seat *s = data; |
| 789 | 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 | 807 | static void data_device_handle_drop(void *data, struct wl_data_device *wl_ddev) |
| 794 | 808 | { |
| 795 | 809 | struct vo_wayland_seat *s = data; |
| 796 | 810 | struct vo_wayland_state *wl = s->wl; |
| 811 | + struct vo_wayland_data_offer *o = wl->dnd_offer; | |
| 797 | 812 | |
| 798 | 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 | 820 | if (wl->opts->drag_and_drop != -2) { |
| 806 | − MP_VERBOSE(wl, "Receiving DND offer with mime %s\n", wl->dnd_mime_type); | |
| 807 | − wl_data_offer_receive(wl->dnd_offer, wl->dnd_mime_type, pipefd[1]); | |
| 821 | + MP_VERBOSE(wl, "Receiving DND offer with mime %s\n", o->mime_type); | |
| 822 | + wl_data_offer_receive(o->offer, o->mime_type, pipefd[1]); | |
| 808 | 823 | } |
| 809 | 824 | |
| 810 | 825 | close(pipefd[1]); |
| 811 | − wl->dnd_fd = pipefd[0]; | |
| 826 | + o->fd = pipefd[0]; | |
| 812 | 827 | } |
| 813 | 828 | |
| 814 | 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 | 832 | struct vo_wayland_seat *s = data; |
| 818 | 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) { | |
| 821 | − wl_data_offer_destroy(wl->dnd_offer); | |
| 822 | − wl->dnd_offer = NULL; | |
| 836 | + if (o->offer) { | |
| 837 | + wl_data_offer_destroy(o->offer); | |
| 838 | + o->offer = NULL; | |
| 823 | 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 | |
| 1836 | − | |
| 1837 | − wl->dnd_action = -1; | |
| 1838 | − TA_FREEP(&wl->dnd_mime_type); | |
| 1839 | − wl->dnd_mime_score = 0; | |
| 1851 | + TA_FREEP(&o->mime_type); | |
| 1852 | + if (o->fd != -1) | |
| 1853 | + close(o->fd); | |
| 1854 | + if (o->offer) | |
| 1855 | + wl_data_offer_destroy(o->offer); | |
| 1856 | + *o = (struct vo_wayland_data_offer){.fd = -1, .action = -1}; | |
| 1840 | 1857 | } |
| 1841 | 1858 | |
| 1842 | 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 | 1863 | return; |
| 1846 | 1864 | |
| 1847 | − struct pollfd fdp = { wl->dnd_fd, POLLIN | POLLHUP, 0 }; | |
| 1865 | + struct pollfd fdp = { o->fd, POLLIN | POLLHUP, 0 }; | |
| 1848 | 1866 | if (poll(&fdp, 1, 0) <= 0) |
| 1849 | 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 | 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 | 1878 | if (data_read == -1 && errno == EINTR) |
| 1861 | 1879 | continue; |
| 1862 | 1880 | else if (data_read <= 0) |
| @@ -1871,24 +1889,24 @@ static void check_dnd_fd(struct vo_wayland_state *wl) · 8 unmodified lines | ||
| 1871 | 1889 | } else { |
| 1872 | 1890 | MP_VERBOSE(wl, "Read %zu bytes from the DND fd\n", file_list.len); |
| 1873 | 1891 | |
| 1874 | − if (wl->dnd_offer) | |
| 1875 | − wl_data_offer_finish(wl->dnd_offer); | |
| 1892 | + if (o->offer) | |
| 1893 | + wl_data_offer_finish(o->offer); | |
| 1876 | 1894 | |
| 1877 | − assert(wl->dnd_action >= 0); | |
| 1878 | − mp_event_drop_mime_data(wl->vo->input_ctx, wl->dnd_mime_type, | |
| 1879 | − file_list, wl->dnd_action); | |
| 1895 | + assert(o->action >= 0); | |
| 1896 | + mp_event_drop_mime_data(wl->vo->input_ctx, o->mime_type, | |
| 1897 | + file_list, o->action); | |
| 1880 | 1898 | } |
| 1881 | 1899 | |
| 1882 | 1900 | talloc_free(file_list.start); |
| 1883 | − free_dnd_data(wl); | |
| 1901 | + free_offer_data(wl->dnd_offer); | |
| 1884 | 1902 | } |
| 1885 | 1903 | |
| 1886 | 1904 | if (fdp.revents & (POLLIN | POLLERR | POLLHUP)) { |
| 1887 | − if (wl->dnd_action >= 0) | |
| 1905 | + if (o->action >= 0) | |
| 1888 | 1906 | MP_VERBOSE(wl, "DND aborted (hang up or error)\n"); |
| 1889 | − free_dnd_data(wl); | |
| 1890 | − close(wl->dnd_fd); | |
| 1891 | − wl->dnd_fd = -1; | |
| 1907 | + free_offer_data(wl->dnd_offer); | |
| 1908 | + close(o->fd); | |
| 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 | 3058 | .scaling = WAYLAND_SCALE_FACTOR, |
| 3041 | 3059 | .wakeup_pipe = {-1, -1}, |
| 3042 | 3060 | .display_fd = -1, |
| 3043 | − .dnd_fd = -1, | |
| 3061 | + .dnd_offer = talloc_zero(wl, struct vo_wayland_data_offer), | |
| 3044 | 3062 | .cursor_visible = true, |
| 3045 | 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 | 3287 | if (!wl) |
| 3270 | 3288 | return; |
| 3271 | 3289 | |
| 3272 | − if (wl->dnd_fd != -1) | |
| 3273 | − close(wl->dnd_fd); | |
| 3274 | − free_dnd_data(wl); | |
| 3290 | + destroy_offer(wl->dnd_offer); | |
| 3275 | 3291 | |
| 3276 | 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 | 3329 | if (wl->dnd_devman) |
| 3314 | 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 | 3332 | if (wl->fback_pool) |
| 3320 | 3333 | clean_feedback_pool(wl->fback_pool); |
| 3321 | 3334 | |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | struct compositor_format; |
| 28 | 28 | struct vo_wayland_seat; |
| 29 | 29 | struct vo_wayland_tranche; |
| 30 | +struct vo_wayland_data_offer; | |
| 30 | 31 | |
| 31 | 32 | struct drm_format { |
| 32 | 33 | uint32_t format; |
| @@ -160,13 +161,9 @@ struct vo_wayland_state { · 127 unmodified lines | ||
| 160 | 161 | struct wl_list seat_list; |
| 161 | 162 | struct xkb_context *xkb_context; |
| 162 | 163 | |
| 163 | − /* DND */ | |
| 164 | + /* Data offer */ | |
| 164 | 165 | struct wl_data_device_manager *dnd_devman; |
| 165 | − struct wl_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; | |
| 166 | + struct vo_wayland_data_offer *dnd_offer; | |
| 170 | 167 | |
| 171 | 168 | /* Cursor */ |
| 172 | 169 | struct wl_cursor_theme *cursor_theme; |