Fix handling of MULTIPLE selections and add test

* select.c (SignalConversionPerformed): Improve diagnostic
messages.
(ConvertSelectionMultiple): Use correct atoms.
(HandleSelectionRequest): Allow selection requests with target
MULTIPLE.

* tests/Imakefile (SRCS12, OBJS12): Add select_helper_multiple.c
and .o.
(PROGRAMS): Add select_helper_multiple.
(select_helper_multiple): New program.
* tests/select_helper.c (main): Fix typo.

* tests/select_test.c (verify_sample_text_multiple): New function.
(test_single_step): Call it.
* tests/svnignore.txt: Add select_helper_multiple.
This commit is contained in:
hujianwei 2022-11-12 08:07:43 +00:00
parent 8810afbe2d
commit b022f0dbd9
5 changed files with 93 additions and 12 deletions

View file

@ -23,9 +23,6 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
#include "compositor.h"
/* Caveat: the MULTIPLE target implementation is completely untested
and probably doesn't work. */
typedef struct _PropertyAtom PropertyAtom;
typedef struct _SelectInputData SelectInputData;
typedef struct _SelectionOwnerInfo SelectionOwnerInfo;
@ -808,8 +805,8 @@ SignalConversionPerformed (WriteTransfer *transfer)
are still pending. If there are no more pending conversions,
send the SelectionNotify event and return. */
DebugPrint ("Conversion complete; %d conversions are still pending\n",
transfer->record->pending);
DebugPrint ("Conversion complete; %d conversion(s) are still pending\n",
transfer->record->pending - 1);
if (!(--transfer->record->pending))
{
@ -1327,8 +1324,8 @@ ConvertSelectionMultiple (SelectionOwnerInfo *info, XEvent *event,
transfer->last = &write_transfers;
transfer->requestor = event->xselectionrequest.requestor;
transfer->selection = event->xselectionrequest.selection;
transfer->target = event->xselectionrequest.target;
transfer->property = atoms[1];
transfer->target = atoms[i + 0];
transfer->property = atoms[i + 1];
transfer->time = event->xselectionrequest.time;
transfer->buffer = XLMalloc (quantum);
transfer->size = quantum;
@ -1425,7 +1422,10 @@ HandleSelectionRequest (XEvent *event)
do anyway. */
|| (event->xselectionrequest.time != CurrentTime
&& TimeIs (event->xselectionrequest.time, Earlier, info->time))
|| !CanConvertTarget (info, event->xselectionrequest.target))
|| (!CanConvertTarget (info, event->xselectionrequest.target)
/* CanConvertTarget itself does not understand MULTIPLE,
because it itself is called while handling MULTIPLE. */
&& event->xselectionrequest.target != MULTIPLE))
{
DebugPrint ("Couldn't convert selection due to simple reason\n");

View file

@ -50,7 +50,9 @@ ScannerTarget(linux-dmabuf-unstable-v1)
OBJS10 = $(COMMONSRCS) select_test.o
SRCS11 = select_helper.c
OBJS11 = select_helper.o
PROGRAMS = imgview simple_test damage_test transform_test viewporter_test subsurface_test scale_test seat_test dmabuf_test select_test select_helper
SRCS12 = select_helper_multiple.c
OBJS12 = select_helper_multiple.o
PROGRAMS = imgview simple_test damage_test transform_test viewporter_test subsurface_test scale_test seat_test dmabuf_test select_test select_helper select_helper_multiple
/* Make all objects depend on HEADER. */
$(OBJS1): $(HEADER)
@ -69,10 +71,11 @@ NormalProgramTarget(seat_test,$(OBJS8),NullParameter,$(LOCAL_LIBRARIES),NullPara
NormalProgramTarget(dmabuf_test,$(OBJS9),NullParameter,$(LOCAL_LIBRARIES) $(GBM) $(DRM),NullParameter);
NormalProgramTarget(select_test,$(OBJS10),NullParameter,$(LOCAL_LIBRARIES) ThreadsLibraries,NullParameter);
NormalProgramTarget(select_helper,$(OBJS11),NullParameter,$(XLIB),NullParameter);
NormalProgramTarget(select_helper_multiple,$(OBJS12),NullParameter,$(XLIB),NullParameter);
DependTarget3($(SRCS1),$(SRCS2),$(SRCS3))
DependTarget3($(SRCS4),$(SRCS5),$(SRCS6))
DependTarget3($(SRCS7),$(SRCS8),$(SRCS9))
DependTarget3($(SRCS10),$(SRCS11),NullParameter)
DependTarget3($(SRCS10),$(SRCS11),$(SRCS12))
all:: $(PROGRAMS)

View file

@ -31,7 +31,6 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
There must be three arguments: the name of the display, the
timestamp at which the selection was acquired, and the target. */
/* The display connected to. */
static Display *display;
@ -130,7 +129,7 @@ main (int argc, char **argv)
atom_names[0] = argv[3];
atom_names[1] = (char *) "CLIPBOARD";
atom_names[2] = (char *) "CLIPBOARD";
atom_names[2] = (char *) "INCR";
XInternAtoms (display, atom_names, 3, False, atoms);
target_atom = atoms[0];
CLIPBOARD = atoms[1];

View file

@ -246,6 +246,79 @@ verify_sample_text (Time time)
close (pipefds[1]);
}
static void
verify_sample_text_multiple (Time time)
{
int pipefds[2], wstatus;
pid_t pid;
char *display_string;
char time_buffer[45], buffer[sizeof SAMPLE_TEXT];
ssize_t bytes_read;
const char *sample_text_buffer;
/* Run select_helper with the specified timestamp. Wait until
handle_data_source_send is called, and then begin reading from
the pipe. */
if (pipe (pipefds) < 0)
die ("pipe");
display_string = DisplayString (display->x_display);
time = sprintf (time_buffer, "%lu", time);
pid = fork ();
if (pid == -1)
die ("fork");
else if (!pid)
{
close (pipefds[0]);
if (!dup2 (pipefds[1], 1))
exit (1);
execlp ("./select_helper_multiple", "./select_helper",
display_string, time_buffer, "STRING", "UTF8_STRING",
NULL);
exit (1);
}
send_called = false;
while (!send_called)
{
if (wl_display_dispatch (display->display) == -1)
die ("wl_display_dispatch");
}
/* Now, start reading from the pipe and comparing the contents. */
sample_text_buffer = SAMPLE_TEXT;
bytes_read = read (pipefds[0], buffer, sizeof SAMPLE_TEXT - 1);
if (bytes_read != sizeof SAMPLE_TEXT - 1)
report_test_failure ("wanted %zu bytes, but got %zd",
sizeof SAMPLE_TEXT - 1, bytes_read);
/* Now compare the text. */
if (memcmp (buffer, sample_text_buffer, bytes_read))
report_test_failure ("read text differs from sample text!");
/* Compare the text again for the second target. */
bytes_read = read (pipefds[0], buffer, sizeof SAMPLE_TEXT - 1);
if (bytes_read != sizeof SAMPLE_TEXT - 1)
report_test_failure ("wanted %zu bytes, but got %zd",
sizeof SAMPLE_TEXT - 1, bytes_read);
waitpid (pid, &wstatus, 0);
if (WEXITSTATUS (wstatus))
report_test_failure ("child exited with failure: %d",
WEXITSTATUS (wstatus));
close (pipefds[0]);
close (pipefds[1]);
}
static void
@ -271,7 +344,12 @@ test_single_step (enum test_kind kind)
wl_display_roundtrip (display->display);
/* Now, verify the selection contents. */
test_log ("verifying sample text normally");
verify_sample_text (time);
/* And verify the selection contents for MULTIPLE. */
test_log ("verifying sample text via MULTIPLE");
verify_sample_text_multiple (time);
break;
}

View file

@ -11,6 +11,7 @@ seat_test
dmabuf_test
select_test
select_helper
select_helper_multiple
imgview
reject.dump
Makefile