mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 07:01:30 +00:00
[client] tests: cover Caja clipboard MIME handling
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Teach the X11 fixture about the MATE atom and verify import preference, source target advertisement, and copied-files delivery. Cover the same Wayland offer and source behavior. Assert that MATE reuses the single GNOME-style payload instead of fetching a duplicate representation. Exercise the core parser and generator with the MATE copied-files MIME, including invalid operation handling and byte-identical remote output.
This commit is contained in:
@@ -271,6 +271,13 @@ static void testLocalLifecycle(void)
|
||||
CHECK(notices == 2);
|
||||
CHECK(datasets[1] != datasets[0]);
|
||||
|
||||
clipboardFiles_clearLocal();
|
||||
CHECK(clipboardFiles_setLocal("x-special/mate-copied-files",
|
||||
gnome, (size_t)gnomeLength));
|
||||
CHECK(notices == 3);
|
||||
CHECK(datasets[2] != datasets[0]);
|
||||
CHECK(datasets[2] != datasets[1]);
|
||||
|
||||
static const char invalid[] = "file:///does/not/exist\n";
|
||||
CHECK(!clipboardFiles_setLocal(
|
||||
"text/uri-list", invalid, sizeof(invalid) - 1U));
|
||||
@@ -281,9 +288,10 @@ static void testLocalLifecycle(void)
|
||||
CHECK(clipboardFiles_testInit(UINT64_C(0x5678000056780000)));
|
||||
CHECK(clipboardFiles_setLocal(
|
||||
"text/uri-list", uri, (size_t)uriLength));
|
||||
CHECK(notices == 3);
|
||||
CHECK(datasets[2] != datasets[0]);
|
||||
CHECK(datasets[2] != datasets[1]);
|
||||
CHECK(notices == 4);
|
||||
CHECK(datasets[3] != datasets[0]);
|
||||
CHECK(datasets[3] != datasets[1]);
|
||||
CHECK(datasets[3] != datasets[2]);
|
||||
clipboardFiles_free();
|
||||
|
||||
CHECK(unlink(path) == 0);
|
||||
@@ -381,6 +389,8 @@ static void testLocalUriValidation(void)
|
||||
CHECK(length > 0 && (size_t)length < sizeof(uri));
|
||||
CHECK(!clipboardFiles_setLocal(
|
||||
"x-special/gnome-copied-files", uri, (size_t)length));
|
||||
CHECK(!clipboardFiles_setLocal(
|
||||
"x-special/mate-copied-files", uri, (size_t)length));
|
||||
CHECK(notices == before + 2U);
|
||||
|
||||
clipboardFiles_free();
|
||||
@@ -721,6 +731,27 @@ static void checkRemoteUri(uint64_t presentation, const char * name)
|
||||
free(uri);
|
||||
}
|
||||
|
||||
static void checkRemoteMate(uint64_t presentation, const char * name)
|
||||
{
|
||||
char * gnome = NULL;
|
||||
char * mate = NULL;
|
||||
size_t gnomeSize = 0;
|
||||
size_t mateSize = 0;
|
||||
CHECK(clipboardFiles_getRemotePresentation(presentation,
|
||||
"x-special/gnome-copied-files", &gnome, &gnomeSize));
|
||||
CHECK(clipboardFiles_getRemotePresentation(presentation,
|
||||
"x-special/mate-copied-files", &mate, &mateSize));
|
||||
CHECK(gnome);
|
||||
CHECK(mate);
|
||||
CHECK(gnomeSize == mateSize);
|
||||
CHECK(memcmp(gnome, mate, mateSize) == 0);
|
||||
CHECK(mateSize >= sizeof("copy\n") - 1U);
|
||||
CHECK(memcmp(mate, "copy\n", sizeof("copy\n") - 1U) == 0);
|
||||
CHECK(strstr(mate, name));
|
||||
free(mate);
|
||||
free(gnome);
|
||||
}
|
||||
|
||||
typedef struct ReleasePresentationTask
|
||||
{
|
||||
pthread_barrier_t * barrier;
|
||||
@@ -791,6 +822,7 @@ static void testRemoteLifecycle(void)
|
||||
clipboardFiles_remotePresentationAcquire();
|
||||
CHECK(firstPresentation == first);
|
||||
checkRemoteUri(firstPresentation, "first.txt");
|
||||
checkRemoteMate(firstPresentation, "first.txt");
|
||||
|
||||
const uint64_t secondDataset = KVMFR_CLIPBOARD_TRANSFER_HELPER |
|
||||
UINT64_C(0x73110002);
|
||||
|
||||
@@ -164,8 +164,10 @@ struct Log
|
||||
unsigned int presentationAcquireN;
|
||||
unsigned int presentationDeliveredN;
|
||||
unsigned int presentationReleaseN;
|
||||
unsigned int presentationMimeN;
|
||||
uint64_t presentationDelivered[MAX_SOURCE];
|
||||
uint64_t presentationReleased[MAX_SOURCE];
|
||||
char presentationMime[MAX_MIME][80];
|
||||
char fileMime[80];
|
||||
uint8_t fileData[MAX_TRANSFER];
|
||||
size_t fileSize;
|
||||
@@ -598,10 +600,14 @@ bool clipboardFiles_getRemotePresentation(uint64_t presentation,
|
||||
const char * mime, char ** data, size_t * size)
|
||||
{
|
||||
CHECK(presentation >= 1001U);
|
||||
CHECK(rec.presentationMimeN < MAX_MIME);
|
||||
snprintf(rec.presentationMime[rec.presentationMimeN++],
|
||||
sizeof(rec.presentationMime[0]), "%s", mime);
|
||||
const char * value;
|
||||
if (!strcmp(mime, "text/uri-list"))
|
||||
value = "file:///run/user/1000/looking-glass/guest.txt\r\n";
|
||||
else if (!strcmp(mime, "x-special/gnome-copied-files"))
|
||||
else if (!strcmp(mime, "x-special/gnome-copied-files") ||
|
||||
!strcmp(mime, "x-special/mate-copied-files"))
|
||||
value = "copy\nfile:///run/user/1000/looking-glass/guest.txt\r\n";
|
||||
else if (!strcmp(mime, "application/x-kde-cutselection"))
|
||||
value = "0";
|
||||
@@ -803,20 +809,59 @@ static void testFileImport(void)
|
||||
finish();
|
||||
}
|
||||
|
||||
static void testFileImportMate(void)
|
||||
{
|
||||
start();
|
||||
const char payload[] =
|
||||
"copy\nfile:///home/user/first.txt\r\n"
|
||||
"file:///home/user/second.txt\r\n";
|
||||
proto.receiveData = payload;
|
||||
proto.receiveSize = sizeof(payload) - 1U;
|
||||
|
||||
struct Proxy * offer = newOffer();
|
||||
offerMime(offer, "text/plain;charset=utf-8");
|
||||
offerMime(offer, "text/uri-list");
|
||||
offerMime(offer, "x-special/mate-copied-files");
|
||||
selectOffer(offer);
|
||||
|
||||
CHECK(rec.noticeN == 0);
|
||||
CHECK(proto.receiveN == 1);
|
||||
CHECK(strcmp(proto.receiveMime,
|
||||
"x-special/mate-copied-files") == 0);
|
||||
CHECK(rec.pollN == 1);
|
||||
pollFire(0, EPOLLIN);
|
||||
CHECK(rec.fileSetN == 1);
|
||||
CHECK(strcmp(rec.fileMime,
|
||||
"x-special/mate-copied-files") == 0);
|
||||
CHECK(rec.fileSize == sizeof(payload) - 1U);
|
||||
CHECK(memcmp(rec.fileData, payload, sizeof(payload) - 1U) == 0);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
static void testFileSource(void)
|
||||
{
|
||||
start();
|
||||
waylandCBNotice(LG_CLIPBOARD_DATA_FILES);
|
||||
CHECK(rec.presentationAcquireN == 1);
|
||||
CHECK(rec.presentationReleaseN == 0);
|
||||
CHECK(rec.presentationMimeN == 3);
|
||||
CHECK(strcmp(rec.presentationMime[0], "text/uri-list") == 0);
|
||||
CHECK(strcmp(rec.presentationMime[1],
|
||||
"x-special/gnome-copied-files") == 0);
|
||||
CHECK(strcmp(rec.presentationMime[2],
|
||||
"application/x-kde-cutselection") == 0);
|
||||
CHECK(proto.sourceN == 1);
|
||||
struct Proxy * source = &proto.source[0];
|
||||
CHECK(source->mimeN == 4);
|
||||
CHECK(source->mimeN == 5);
|
||||
CHECK(strcmp(source->mime[0],
|
||||
"x-special/gnome-copied-files") == 0);
|
||||
CHECK(strcmp(source->mime[1], "text/uri-list") == 0);
|
||||
CHECK(strcmp(source->mime[2],
|
||||
CHECK(strcmp(source->mime[1],
|
||||
"x-special/mate-copied-files") == 0);
|
||||
CHECK(strcmp(source->mime[2], "text/uri-list") == 0);
|
||||
CHECK(strcmp(source->mime[3],
|
||||
"application/x-kde-cutselection") == 0);
|
||||
CHECK(strcmp(source->mime[4], wlCb.lgMimetype) == 0);
|
||||
|
||||
int fds[2];
|
||||
CHECK(pipe(fds) == 0);
|
||||
@@ -836,14 +881,33 @@ static void testFileSource(void)
|
||||
CHECK(read(fds[0], actual, 1) == 0);
|
||||
CHECK(close(fds[0]) == 0);
|
||||
|
||||
int mate[2];
|
||||
CHECK(pipe(mate) == 0);
|
||||
sourceListener(source)->send(source->data,
|
||||
(struct wl_data_source *)source,
|
||||
"x-special/mate-copied-files", mate[1]);
|
||||
CHECK(rec.pollN == 2);
|
||||
pollFire(1, EPOLLOUT);
|
||||
CHECK(rec.presentationDeliveredN == 2);
|
||||
CHECK(rec.presentationDelivered[1] == 1001U);
|
||||
const char mateExpected[] =
|
||||
"copy\nfile:///run/user/1000/looking-glass/guest.txt\r\n";
|
||||
char mateActual[sizeof(mateExpected)] = { 0 };
|
||||
CHECK(read(mate[0], mateActual, sizeof(mateActual)) ==
|
||||
(ssize_t)(sizeof(mateExpected) - 1U));
|
||||
CHECK(memcmp(mateActual,
|
||||
mateExpected, sizeof(mateExpected) - 1U) == 0);
|
||||
CHECK(read(mate[0], mateActual, 1) == 0);
|
||||
CHECK(close(mate[0]) == 0);
|
||||
|
||||
int kde[2];
|
||||
CHECK(pipe(kde) == 0);
|
||||
sourceListener(source)->send(source->data,
|
||||
(struct wl_data_source *)source,
|
||||
"application/x-kde-cutselection", kde[1]);
|
||||
CHECK(rec.pollN == 2);
|
||||
pollFire(1, EPOLLOUT);
|
||||
CHECK(rec.presentationDeliveredN == 1);
|
||||
CHECK(rec.pollN == 3);
|
||||
pollFire(2, EPOLLOUT);
|
||||
CHECK(rec.presentationDeliveredN == 2);
|
||||
CHECK(read(kde[0], actual, sizeof(actual)) == 1);
|
||||
CHECK(actual[0] == '0');
|
||||
CHECK(read(kde[0], actual, 1) == 0);
|
||||
@@ -1573,6 +1637,7 @@ static const struct Test tests[] =
|
||||
{
|
||||
{ "mime" , testMime },
|
||||
{ "file-import", testFileImport },
|
||||
{ "file-mate-import", testFileImportMate },
|
||||
{ "file-source", testFileSource },
|
||||
{ "file-replace", testFileSourceReplacement },
|
||||
{ "replace" , testReplace },
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
#define A_JPEG 104UL
|
||||
#define A_URI 105UL
|
||||
#define A_GNOME 106UL
|
||||
#define A_KDE 107UL
|
||||
#define A_MATE 107UL
|
||||
#define A_KDE 108UL
|
||||
|
||||
struct WindowLog
|
||||
{
|
||||
@@ -223,6 +224,8 @@ Atom XInternAtom(Display * display, const char * name, Bool onlyIfExists)
|
||||
return A_URI;
|
||||
if (!strcmp(name, "x-special/gnome-copied-files"))
|
||||
return A_GNOME;
|
||||
if (!strcmp(name, "x-special/mate-copied-files"))
|
||||
return A_MATE;
|
||||
if (!strcmp(name, "application/x-kde-cutselection"))
|
||||
return A_KDE;
|
||||
CHECK(false);
|
||||
@@ -609,7 +612,8 @@ bool clipboardFiles_getRemotePresentation(uint64_t presentation,
|
||||
const char * value;
|
||||
if (!strcmp(mime, "text/uri-list"))
|
||||
value = "file:///run/user/1000/looking-glass/guest.txt\r\n";
|
||||
else if (!strcmp(mime, "x-special/gnome-copied-files"))
|
||||
else if (!strcmp(mime, "x-special/gnome-copied-files") ||
|
||||
!strcmp(mime, "x-special/mate-copied-files"))
|
||||
value = "copy\nfile:///run/user/1000/looking-glass/guest.txt\r\n";
|
||||
else if (!strcmp(mime, "application/x-kde-cutselection"))
|
||||
value = "0";
|
||||
@@ -887,6 +891,29 @@ static void testFileImportIncr(void)
|
||||
finish();
|
||||
}
|
||||
|
||||
static void testFileImportMate(void)
|
||||
{
|
||||
start();
|
||||
const unsigned long targets[] = { A_TEXT, A_URI, A_MATE };
|
||||
discover(603, targets, ARRAY_LENGTH(targets));
|
||||
CHECK(rec.convertN == 2);
|
||||
const struct ConvertLog * convert = &rec.convert[1];
|
||||
CHECK(convert->target == A_MATE);
|
||||
CHECK(convert->property == x11atoms.SEL_DATA);
|
||||
|
||||
const char payload[] =
|
||||
"copy\nfile:///home/user/first.txt\r\n"
|
||||
"file:///home/user/second.txt\r\n";
|
||||
prop8(A_MATE, payload, sizeof(payload) - 1U);
|
||||
selection(convert->requestor, A_MATE, x11atoms.SEL_DATA);
|
||||
CHECK(rec.fileSetN == 1);
|
||||
CHECK(strcmp(rec.fileMime, "x-special/mate-copied-files") == 0);
|
||||
CHECK(rec.fileSize == sizeof(payload) - 1U);
|
||||
CHECK(memcmp(rec.fileData, payload, sizeof(payload) - 1U) == 0);
|
||||
CHECK(rec.noticeN == 0);
|
||||
finish();
|
||||
}
|
||||
|
||||
static void testFileSource(void)
|
||||
{
|
||||
start();
|
||||
@@ -898,12 +925,13 @@ static void testFileSource(void)
|
||||
selectionRequest(x11atoms.TARGETS, 710);
|
||||
CHECK(rec.changeN == 1);
|
||||
CHECK(rec.change[0].format == 32);
|
||||
CHECK(rec.change[0].count == 4);
|
||||
CHECK(rec.change[0].count == 5);
|
||||
const Atom * targets = (const Atom *)rec.change[0].data;
|
||||
CHECK(targets[0] == x11atoms.TARGETS);
|
||||
CHECK(targets[1] == A_URI);
|
||||
CHECK(targets[2] == A_GNOME);
|
||||
CHECK(targets[3] == A_KDE);
|
||||
CHECK(targets[3] == A_MATE);
|
||||
CHECK(targets[4] == A_KDE);
|
||||
|
||||
selectionRequest(A_URI, 711);
|
||||
CHECK(rec.presentationAcquireN == 2);
|
||||
@@ -958,6 +986,46 @@ static void testFileSource(void)
|
||||
CHECK(rec.presentationReleaseN == 3);
|
||||
}
|
||||
|
||||
static void testFileSourceMate(void)
|
||||
{
|
||||
start();
|
||||
x11CBNotice(LG_CLIPBOARD_DATA_FILES);
|
||||
CHECK(rec.presentationAcquireN == 1);
|
||||
CHECK(rec.presentationReleaseN == 0);
|
||||
|
||||
selectionRequest(A_MATE, 713);
|
||||
CHECK(rec.presentationAcquireN == 2);
|
||||
CHECK(rec.structureSelectN == 1);
|
||||
CHECK(rec.changeN == 1);
|
||||
CHECK(rec.change[0].type == x11atoms.INCR);
|
||||
CHECK(rec.change[0].format == 32);
|
||||
CHECK(rec.change[0].count == 1);
|
||||
CHECK(rec.sendN == 1);
|
||||
|
||||
propertyState(900, 713, PropertyDelete);
|
||||
CHECK(rec.changeN == 2);
|
||||
CHECK(rec.change[1].type == A_MATE);
|
||||
CHECK(rec.change[1].format == 8);
|
||||
const char expected[] =
|
||||
"copy\nfile:///run/user/1000/looking-glass/guest.txt\r\n";
|
||||
CHECK(rec.change[1].size == sizeof(expected) - 1U);
|
||||
CHECK(memcmp(rec.change[1].data,
|
||||
expected, sizeof(expected) - 1U) == 0);
|
||||
|
||||
propertyState(900, 713, PropertyDelete);
|
||||
CHECK(rec.changeN == 3);
|
||||
CHECK(rec.change[2].type == A_MATE);
|
||||
CHECK(rec.change[2].count == 0);
|
||||
CHECK(rec.presentationDeliveredN == 1);
|
||||
CHECK(rec.presentationDelivered[0] == 2001U);
|
||||
CHECK(rec.presentationReleaseN == 1);
|
||||
CHECK(rec.presentationReleased[0] == 2001U);
|
||||
|
||||
finish();
|
||||
CHECK(rec.presentationReleaseN == 2);
|
||||
CHECK(rec.presentationReleased[1] == 2001U);
|
||||
}
|
||||
|
||||
static void testFileSourceActiveReplacement(void)
|
||||
{
|
||||
start();
|
||||
@@ -1434,7 +1502,9 @@ static const struct Test tests[] =
|
||||
{ "targets" , testTargets },
|
||||
{ "file-import" , testFileImport },
|
||||
{ "file-incr" , testFileImportIncr },
|
||||
{ "file-mate-import" , testFileImportMate },
|
||||
{ "file-source" , testFileSource },
|
||||
{ "file-mate-source" , testFileSourceMate },
|
||||
{ "file-source-active-replace", testFileSourceActiveReplacement },
|
||||
{ "normal" , testNormal },
|
||||
{ "incr" , testIncr },
|
||||
|
||||
Reference in New Issue
Block a user