我目前正在开发一个跨主机剪贴板共享工具,可以共享文本、富文本或文件。 根据我目前所学,我已经知道需要处理哪些 X11 事件,但我无法听取它们。 我当前的代码我只能捕获选择文本的事件。
我想知道如何获得 ctrl+c 事件?
#include <QCoreApplication>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <xcb/xcb.h>
#include <xcb/xfixes.h>
/**
* Enumeration of standard X11 atom identifiers
*/
typedef enum std_x_atoms {
/** The TARGETS atom identifier **/
X_ATOM_TARGETS = 0,
/** The MULTIPLE atom identifier **/
X_ATOM_MULTIPLE,
/** The TIMESTAMP atom identifier **/
X_ATOM_TIMESTAMP,
/** The INCR atom identifier **/
X_ATOM_INCR,
/** The CLIPBOARD atom identifier **/
X_ATOM_CLIPBOARD,
/** The UTF8_STRING atom identifier **/
X_ATOM_UTF8_STRING,
X_ATOM_XCLIPD,
/** End marker sentinel **/
X_ATOM_END
} std_x_atoms;
/**
* Union to simplify getting interned atoms from XCB
*/
typedef union atom_c {
/** The atom **/
xcb_atom_t atom;
/** The cookie returned by xcb_intern_atom **/
xcb_intern_atom_cookie_t cookie;
} atom_c;
/**
* The standard atom names. These values should match the
* std_x_atoms enumeration.
*/
const char * const g_std_atom_names[X_ATOM_END] = {
"TARGETS", "MULTIPLE", "TIMESTAMP", "INCR",
"CLIPBOARD", "UTF8_STRING", "XCLIPD"
};
atom_c std_atoms[X_ATOM_END];
/**
* \brief Interns the list of atoms
*
* \param [in] xc The XCB connection.
* \param [out] atoms The location to store interned atoms.
* \param [in] atom_names The names of the atoms to intern.
* \param [in] number The number of atoms to intern.
* \return true iff all atoms were interned.
*/
static bool x11_intern_atoms(xcb_connection_t *xc, atom_c *atoms, const char * const *atom_names, int number) {
for (int i = 0; i < number; i++) {
atoms[i].cookie = xcb_intern_atom(xc, 0,
strlen(atom_names[i]), atom_names[i]);
}
for (int i = 0; i < number; i++) {
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xc,
atoms[i].cookie, NULL);
if (reply == NULL) {
return false;
}
atoms[i].atom = reply->atom;
free(reply); /* XCB: Do not use custom allocators */
}
return true;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
xcb_connection_t *c;
xcb_screen_t *screen;
xcb_window_t win;
xcb_generic_event_t *e;
uint32_t mask = 0;
uint32_t values[2];
/* Create the window */
c = xcb_connect (NULL, NULL);
screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
if (!x11_intern_atoms(c, std_atoms, g_std_atom_names, X_ATOM_END))
return 1;
// xcb_flush (c);
win = xcb_generate_id (c);
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
values[0] = screen->white_pixel;
values[1] = XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;;
xcb_create_window (c, /* Connection */
XCB_COPY_FROM_PARENT, /* depth */
win, /* window Id */
screen->root, /* parent window */
0, 0, /* x, y */
150, 150, /* width, height */
10, /* border_width */
XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
screen->root_visual, /* visual */
mask, values); /* masks */
xcb_map_window (c, win);
xcb_flush (c);
// init xfixes
xcb_generic_error_t *error = 0;
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(c, &xcb_xfixes_id);
if (!reply || !reply->present) {
return -1;
}
xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(c,
XCB_XFIXES_MAJOR_VERSION,
XCB_XFIXES_MINOR_VERSION);
xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (c,
xfixes_query_cookie, &error);
if (!xfixes_query || error || xfixes_query->major_version < 2) {
free(error);
}
free(xfixes_query);
// delivers request
mask = XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE
| XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY
| XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER;
xcb_xfixes_select_selection_input_checked(c, win, XCB_ATOM_NONE, mask);
xcb_flush(c);
// recevie events
uint response_type;
while (e = xcb_wait_for_event(c)) {
xcb_xfixes_selection_notify_event_t *notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(e);
printf("response_type = %d\n", response_type);
response_type = notify_event->response_type & ~0x80;
printf("response_type = %d\n", response_type);
if (response_type == reply->first_event + XCB_XFIXES_SELECTION_NOTIFY) {
printf("notify\n");
} else {
printf("code:%d\n", response_type);
}
}
return a.exec();
}