static int weston_wm_handle_xfixes_selection_notify(struct weston_wm *wm, xcb_generic_event_t *event) { xcb_xfixes_selection_notify_event_t *xfixes_selection_notify = (xcb_xfixes_selection_notify_event_t *) event; struct weston_compositor *compositor; struct weston_seat *seat = weston_wm_pick_seat(wm); uint32_t serial; if (xfixes_selection_notify->selection != wm->atom.clipboard) return 0; weston_log("xfixes selection notify event: owner %d\n", xfixes_selection_notify->owner); if (xfixes_selection_notify->owner == XCB_WINDOW_NONE) { if (wm->selection_owner != wm->selection_window) { /* A real X client selection went away, not our * proxy selection. Clear the wayland selection. */ compositor = wm->server->compositor; serial = wl_display_next_serial(compositor->wl_display); weston_seat_set_selection(seat, NULL, serial); } wm->selection_owner = XCB_WINDOW_NONE; return 1; } wm->selection_owner = xfixes_selection_notify->owner; /* We have to use XCB_TIME_CURRENT_TIME when we claim the * selection, so grab the actual timestamp here so we can * answer TIMESTAMP conversion requests correctly. */ if (xfixes_selection_notify->owner == wm->selection_window) { wm->selection_timestamp = xfixes_selection_notify->timestamp; weston_log("our window, skipping\n"); return 1; } wm->incr = 0; xcb_convert_selection(wm->conn, wm->selection_window, wm->atom.clipboard, wm->atom.targets, wm->atom.wl_selection, xfixes_selection_notify->timestamp); xcb_flush(wm->conn); return 1; }
EAPI void ecore_x_selection_xdnd_request(Ecore_X_Window win, const char *target) { Ecore_X_Atom atom; Ecore_X_DND_Target *_target; LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; _target = _ecore_xcb_dnd_target_get(); atom = _ecore_xcb_selection_target_atom_get(target); xcb_convert_selection(_ecore_xcb_conn, win, ECORE_X_ATOM_SELECTION_XDND, atom, ECORE_X_ATOM_SELECTION_PROP_XDND, _target->time); }
static void data_source_send(struct weston_data_source *base, const char *mime_type, int32_t fd) { struct x11_data_source *source = (struct x11_data_source *) base; struct weston_wm *wm = source->wm; if (strcmp(mime_type, "text/plain;charset=utf-8") == 0) { /* Get data for the utf8_string target */ xcb_convert_selection(wm->conn, wm->selection_window, wm->atom.clipboard, wm->atom.utf8_string, wm->atom.wl_selection, XCB_TIME_CURRENT_TIME); xcb_flush(wm->conn); fcntl(fd, F_SETFL, O_WRONLY | O_NONBLOCK); wm->data_source_fd = fd; } }
static void data_source_send(struct weston_data_source *base, const char *mime_type, int32_t fd) { struct dnd_data_source *source = (struct dnd_data_source *) base; struct weston_wm *wm = source->wm; weston_log("got send, %s\n", mime_type); /* Get data for the utf8_string target */ xcb_convert_selection(wm->conn, wm->selection_window, wm->atom.xdnd_selection, wm->atom.utf8_string, wm->atom.wl_selection, XCB_TIME_CURRENT_TIME); xcb_flush(wm->conn); fcntl(fd, F_SETFL, O_WRONLY | O_NONBLOCK); wm->data_source_fd = fd; }
static void _ecore_xcb_selection_request(Ecore_X_Window win, Ecore_X_Atom selection, const char *target) { Ecore_X_Atom atarget, prop; LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY; else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY; else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD; else return; atarget = _ecore_xcb_selection_target_atom_get(target); xcb_convert_selection(_ecore_xcb_conn, win, selection, atarget, prop, XCB_CURRENT_TIME); }
/** Get the current X selection buffer. * \param L The Lua VM state. * \return The number of elements pushed on stack. * \luastack * \lreturn A string with the current X selection buffer. */ int luaA_selection_get(lua_State *L) { if(selection_window == XCB_NONE) { xcb_screen_t *screen = xutil_screen_get(globalconf.connection, globalconf.default_screen); uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK; uint32_t values[] = { screen->black_pixel, 1, XCB_EVENT_MASK_PROPERTY_CHANGE }; selection_window = xcb_generate_id(globalconf.connection); xcb_create_window(globalconf.connection, screen->root_depth, selection_window, screen->root, 0, 0, 1, 1, 0, XCB_COPY_FROM_PARENT, screen->root_visual, mask, values); } xcb_convert_selection(globalconf.connection, selection_window, PRIMARY, UTF8_STRING, XSEL_DATA, XCB_CURRENT_TIME); xcb_flush(globalconf.connection); xcb_generic_event_t *event; while(true) { event = xcb_wait_for_event(globalconf.connection); if(!event) return 0; if(XCB_EVENT_RESPONSE_TYPE(event) != XCB_SELECTION_NOTIFY) { /* \todo Eventually, this may be rewritten with adding a static * buffer, then a event handler for XCB_SELECTION_NOTIFY, then call * xcb_event_poll_for_event_loop() and awesome_refresh(), * then check if some static buffer has been filled with data. * If yes, that'd be the xsel data, otherwise, re-loop. * Anyway that's still brokes the socket or D-Bus, so maybe using * ev_loop() would be even better. */ xcb_event_handle(&globalconf.evenths, event); p_delete(&event); awesome_refresh(); continue; } xcb_selection_notify_event_t *event_notify = (xcb_selection_notify_event_t *) event; if(event_notify->selection == PRIMARY && event_notify->property != XCB_NONE) { xcb_get_text_property_reply_t prop; xcb_get_property_cookie_t cookie = xcb_get_text_property(globalconf.connection, event_notify->requestor, event_notify->property); if(xcb_get_text_property_reply(globalconf.connection, cookie, &prop, NULL)) { lua_pushlstring(L, prop.name, prop.name_len); xcb_get_text_property_reply_wipe(&prop); xcb_delete_property(globalconf.connection, event_notify->requestor, event_notify->property); p_delete(&event); return 1; } else break; } } p_delete(&event); return 0; }