XLib - не могу отправить клиенту список selection TARGETS
Всех с Новым Годом!
У меня тут возникли некоторые трудности с использованием библиотеки XLib в Linux:
Есть С++ программа, содержащая строку с UTF8 текстом. Я хочу посредством XLib объявить эту программу как selection owner, чтобы все selection реквесты от клиентов поступали в программу. Программа должна предоставить клиентам текст из строки в ответ на selection request. Некоторые клиенты, отправляя selection request, сначала запрашивают у владельца лист атомов, описывающих типы данных, которые владелец может предоставить(selection TARGETS), и, если находят в этом списке интересующий их тип данных(строка, картинка…), запрашивают у владельца данные этого типа. Программа должна при запросе клиента предоставить ему список торгетов, состоящий из единственного атома «UTF8_STRING», и, если клиент пожелает запросить данные типа «UTF8_STRING», нужно ему эти данные любезно предоставить. Если вкратце, то что-то типа этого:
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
int selectionRequested(Display*, XEvent* event, XPointer arg)
{
return event->type == SelectionRequest;
}
int main()
{
// ...
Display* display = XOpenDisplay(NULL);
int screen = XDefaultScreen(display);
Window rootWindow = XRootWindow(display, screen);
Atom selection = XInternAtom(display, "CLIPBOARD", false);
Atom selectionType = XInternAtom(display, "UTF8_STRING", false);
Atom targets = XInternAtom(display, "TARGETS", false);
Window owner = XCreateSimpleWindow(display, rootWindow,
-10, -10, 1, 1, 0, 0, 0);
XSetSelectionOwner(display, selection, owner, CurrentTime);
XEvent event;
while (true)
{
XIfEvent(display, &event, selectionRequested, NULL);
XEvent selectionResponse;
selectionResponse.type = SelectionNotify;
selectionResponse.xselection.send_event = true;
selectionResponse.xselection.requestor =
event.xselectionrequest.requestor;
selectionResponse.xselection.property =
event.xselectionrequest.property;
selectionResponse.xselection.display =
event.xselectionrequest.display;
selectionResponse.xselection.selection =
event.xselectionrequest.selection;
selectionResponse.xselection.target =
event.xselectionrequest.target;
selectionResponse.xselection.time =
event.xselectionrequest.time;
Atom targetRequsted = event.xselectionrequest.target;
std::cout << "REQUESTED TARGET \"" <<
XGetAtomName(display, targetRequsted) << "\"" << '\n';
if (targetRequsted == targets)
{
XChangeProperty(selectionResponse.xselection.display,
selectionResponse.xselection.requestor,
selectionResponse.xselection.property,
XA_ATOM, 32, PropModeReplace,
reinterpret_cast<unsigned char*>(&selectionType), 1);
XSendEvent(selectionResponse.xselection.display,
selectionResponse.xselection.requestor, 0,
0, &selectionResponse);
}
else if (targetRequsted == selectionType)
{
// Code for sending data to the requestor...
}
else
{
// ...
}
}
return 0;
}
Здесь я, судя по всему, как-то некорректно использую XChangeProperty() в условном блоке if (targetRequested == targets), поскольку при попытке вставить строку в окно клиента, клиент продолжает многократно запрашивать selection targets после того, как я ему отвечаю, и, не добившись ответа, запрашивает типы, которые я не объявлял. Например, вот что я вижу, когда пытаюсь вставить текст в Firefox:
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "TARGETS"
REQUESTED TARGET "text/plain;charset=utf-8"
REQUESTED TARGET "text/plain;charset=utf-8"
REQUESTED TARGET "text/x-moz-text-internal"
Клиенты по какой-то причине не воспринимают атом, который я им отправляю в ответ на запрос торгетов, и, соответственно, не видят тип «UTF8_STRING», который я им предоставляю. Если же клиент не запрашивает сначала тип «TARGETS», а сразу запрашивает тип «UTF8_STRING», то дальнейший код(я его здесь опустил) работает прекрасно, и строка из программы успешно вставляется в окно клиента.
Я, если честно, только начал разбираться с XLib. Читал вот это - там всё, вроде бы, и расписано, но совсем нет даже элементарных примеров использования, одна сухая теория.
Может кто опытный подсказать, что я делаю не так?