void XWaylandManager::createWindowManager() { static const char name[] = "Green Island the Hawaii compositor"; m_wmWindow = new Xcb::Window(QRect(0, 0, 10, 10), XCB_WINDOW_CLASS_INPUT_OUTPUT, 0, Q_NULLPTR); xcb_window_t w = m_wmWindow->window(); m_wmWindow->changeProperty(Xcb::resources()->atoms->net_supporting_wm_check, XCB_ATOM_WINDOW, 32, 1, &w); m_wmWindow->changeProperty(Xcb::resources()->atoms->net_wm_name, Xcb::resources()->atoms->utf8_string, 8, strlen(name), name); xcb_change_property(Xcb::connection(), XCB_PROP_MODE_REPLACE, Xcb::rootWindow(), Xcb::resources()->atoms->net_supporting_wm_check, XCB_ATOM_WINDOW, 32, 1, &w); // Claim WM_S0 xcb_set_selection_owner(Xcb::connection(), w, Xcb::resources()->atoms->wm_s0, XCB_TIME_CURRENT_TIME); xcb_set_selection_owner(Xcb::connection(), w, Xcb::resources()->atoms->net_wm_cm_s0, XCB_TIME_CURRENT_TIME); }
static void weston_wm_set_selection(struct wl_listener *listener, void *data) { struct weston_seat *seat = data; struct weston_wm *wm = container_of(listener, struct weston_wm, selection_listener); struct weston_data_source *source = seat->selection_data_source; if (source == NULL) { if (wm->selection_owner == wm->selection_window) xcb_set_selection_owner(wm->conn, XCB_ATOM_NONE, wm->atom.clipboard, wm->selection_timestamp); return; } if (source->send == data_source_send) return; xcb_set_selection_owner(wm->conn, wm->selection_window, wm->atom.clipboard, XCB_TIME_CURRENT_TIME); }
/** Register systray in X. */ static void systray_register(void) { xcb_client_message_event_t ev; xcb_screen_t *xscreen = globalconf.screen; if(globalconf.systray.registered) return; globalconf.systray.registered = true; /* Fill event */ p_clear(&ev, 1); ev.response_type = XCB_CLIENT_MESSAGE; ev.window = xscreen->root; ev.format = 32; ev.type = MANAGER; ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[1] = globalconf.systray.atom; ev.data.data32[2] = globalconf.systray.window; ev.data.data32[3] = ev.data.data32[4] = 0; xcb_set_selection_owner(globalconf.connection, globalconf.systray.window, globalconf.systray.atom, XCB_CURRENT_TIME); xcb_send_event(globalconf.connection, false, xscreen->root, 0xFFFFFF, (char *) &ev); }
/** Remove systray information in X. */ void systray_cleanup(void) { xcb_intern_atom_reply_t *atom_systray_r; char *atom_name; if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", globalconf.default_screen)) || !(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name), NULL))) { warn("error getting systray atom"); p_delete(&atom_name); return; } p_delete(&atom_name); xcb_set_selection_owner(globalconf.connection, XCB_NONE, atom_systray_r->atom, XCB_CURRENT_TIME); p_delete(&atom_systray_r); xcb_unmap_window(globalconf.connection, globalconf.systray.window); }
void XWaylandManager::wmSelection() { m_selRequest.requestor = XCB_NONE; quint32 values[1]; values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE; m_selWindow = xcb_generate_id(Xcb::connection()); xcb_create_window(Xcb::connection(), XCB_COPY_FROM_PARENT, m_selWindow, Xcb::rootWindow(), 0, 0, 10, 10, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, Xcb::rootVisual(), XCB_CW_EVENT_MASK, values); xcb_set_selection_owner(Xcb::connection(), m_selWindow, Xcb::resources()->atoms->clipboard_manager, XCB_TIME_CURRENT_TIME); quint32 mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE; xcb_xfixes_select_selection_input(Xcb::connection(), m_selWindow, Xcb::resources()->atoms->clipboard, mask); //weston_wm_set_selection }
/** Remove systray information in X. * \param phys_screen Physical screen. */ void systray_cleanup(int phys_screen) { xcb_intern_atom_reply_t *atom_systray_r; char *atom_name; if(!globalconf.screens.tab[phys_screen].systray.registered) return; globalconf.screens.tab[phys_screen].systray.registered = false; if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen)) || !(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name), NULL))) { warn("error getting systray atom"); p_delete(&atom_name); return; } p_delete(&atom_name); xcb_set_selection_owner(globalconf.connection, XCB_NONE, atom_systray_r->atom, XCB_CURRENT_TIME); p_delete(&atom_systray_r); }
/* local functions */ static Eina_Bool _ecore_xcb_selection_set(Ecore_X_Window win, const void *data, int size, Ecore_X_Atom selection) { xcb_get_selection_owner_cookie_t cookie; xcb_get_selection_owner_reply_t *reply; int in = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; xcb_set_selection_owner(_ecore_xcb_conn, win, selection, XCB_CURRENT_TIME); cookie = xcb_get_selection_owner(_ecore_xcb_conn, selection); reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); if (!reply) return EINA_FALSE; if (reply->owner != win) { free(reply); return EINA_FALSE; } free(reply); if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) in = 0; else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) in = 1; else if (selection == ECORE_X_ATOM_SELECTION_XDND) in = 2; else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) in = 3; else return EINA_FALSE; if (data) { unsigned char *buff = NULL; _selections[in].win = win; _selections[in].selection = selection; _selections[in].length = size; _selections[in].time = _ecore_xcb_events_last_time_get(); buff = malloc(size); if (!buff) return EINA_FALSE; memcpy(buff, data, size); _selections[in].data = buff; } else if (_selections[in].data) { free(_selections[in].data); memset(&_selections[in], 0, sizeof(Ecore_X_Selection_Data)); } return EINA_TRUE; }
static void weston_wm_set_selection(struct wl_listener *listener, void *data) { struct weston_seat *seat = data; struct weston_wm *wm = container_of(listener, struct weston_wm, selection_listener); struct weston_data_source *source = seat->selection_data_source; const char **p, **end; int has_text_plain = 0; if (source == NULL) { if (wm->selection_owner == wm->selection_window) xcb_set_selection_owner(wm->conn, XCB_ATOM_NONE, wm->atom.clipboard, wm->selection_timestamp); return; } if (source->send == data_source_send) return; p = source->mime_types.data; end = (const char **) ((char *) source->mime_types.data + source->mime_types.size); while (p < end) { weston_log(" %s\n", *p); if (strcmp(*p, "text/plain") == 0 || strcmp(*p, "text/plain;charset=utf-8") == 0) has_text_plain = 1; p++; } if (has_text_plain) { xcb_set_selection_owner(wm->conn, wm->selection_window, wm->atom.clipboard, XCB_TIME_CURRENT_TIME); } else { xcb_set_selection_owner(wm->conn, XCB_ATOM_NONE, wm->atom.clipboard, XCB_TIME_CURRENT_TIME); } }
/** Initialize systray information in X. * \param phys_screen Physical screen. */ void systray_init(int phys_screen) { xcb_client_message_event_t ev; xcb_screen_t *xscreen = xutil_screen_get(globalconf.connection, phys_screen); char *atom_name; xcb_intern_atom_cookie_t atom_systray_q; xcb_intern_atom_reply_t *atom_systray_r; xcb_atom_t atom_systray; /* Send requests */ if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen))) { warn("error getting systray atom"); return; } atom_systray_q = xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name); p_delete(&atom_name); globalconf.screens[phys_screen].systray.window = xcb_generate_id(globalconf.connection); xcb_create_window(globalconf.connection, xscreen->root_depth, globalconf.screens[phys_screen].systray.window, xscreen->root, -1, -1, 1, 1, 0, XCB_COPY_FROM_PARENT, xscreen->root_visual, 0, NULL); /* Fill event */ p_clear(&ev, 1); ev.response_type = XCB_CLIENT_MESSAGE; ev.window = xscreen->root; ev.format = 32; ev.type = MANAGER; ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[2] = globalconf.screens[phys_screen].systray.window; ev.data.data32[3] = ev.data.data32[4] = 0; if(!(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, atom_systray_q, NULL))) { warn("error getting systray atom"); return; } ev.data.data32[1] = atom_systray = atom_systray_r->atom; p_delete(&atom_systray_r); xcb_set_selection_owner(globalconf.connection, globalconf.screens[phys_screen].systray.window, atom_systray, XCB_CURRENT_TIME); xcb_send_event(globalconf.connection, false, xscreen->root, 0xFFFFFF, (char *) &ev); }
EAPI void ecore_x_selection_owner_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Time tim) { LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; xcb_set_selection_owner(_ecore_xcb_conn, win, atom, tim); }
/** Register systray in X. * \param phys_screen Physical screen. */ void systray_register(int phys_screen) { xcb_client_message_event_t ev; xcb_screen_t *xscreen = xutil_screen_get(globalconf.connection, phys_screen); char *atom_name; xcb_intern_atom_cookie_t atom_systray_q; xcb_intern_atom_reply_t *atom_systray_r; xcb_atom_t atom_systray; /* Set registered even if it fails to don't try again unless forced */ if(globalconf.screens.tab[phys_screen].systray.registered) return; globalconf.screens.tab[phys_screen].systray.registered = true; /* Send requests */ if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen))) { warn("error getting systray atom"); return; } atom_systray_q = xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name); p_delete(&atom_name); /* Fill event */ p_clear(&ev, 1); ev.response_type = XCB_CLIENT_MESSAGE; ev.window = xscreen->root; ev.format = 32; ev.type = MANAGER; ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[2] = globalconf.screens.tab[phys_screen].systray.window; ev.data.data32[3] = ev.data.data32[4] = 0; if(!(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, atom_systray_q, NULL))) { warn("error getting systray atom"); return; } ev.data.data32[1] = atom_systray = atom_systray_r->atom; p_delete(&atom_systray_r); xcb_set_selection_owner(globalconf.connection, globalconf.screens.tab[phys_screen].systray.window, atom_systray, XCB_CURRENT_TIME); xcb_send_event(globalconf.connection, false, xscreen->root, 0xFFFFFF, (char *) &ev); }
/** Remove systray information in X. */ void systray_cleanup(void) { if(!globalconf.systray.registered) return; globalconf.systray.registered = false; xcb_set_selection_owner(globalconf.connection, XCB_NONE, globalconf.systray.atom, XCB_CURRENT_TIME); xcb_unmap_window(globalconf.connection, globalconf.systray.window); }
void weston_wm_selection_init(struct weston_wm *wm) { struct weston_seat *seat; uint32_t values[1], mask; wm->selection_request.requestor = XCB_NONE; values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE; wm->selection_window = xcb_generate_id(wm->conn); xcb_create_window(wm->conn, XCB_COPY_FROM_PARENT, wm->selection_window, wm->screen->root, 0, 0, 10, 10, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, wm->screen->root_visual, XCB_CW_EVENT_MASK, values); xcb_set_selection_owner(wm->conn, wm->selection_window, wm->atom.clipboard_manager, XCB_TIME_CURRENT_TIME); mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY | XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE; xcb_xfixes_select_selection_input(wm->conn, wm->selection_window, wm->atom.clipboard, mask); seat = weston_wm_pick_seat(wm); wm->selection_listener.notify = weston_wm_set_selection; wl_signal_add(&seat->selection_signal, &wm->selection_listener); weston_wm_set_selection(&wm->selection_listener, seat); }
void QXcbDrag::startDrag() { // #fixme enableEventFilter(); init(); xcb_set_selection_owner(xcb_connection(), connection()->clipboard()->owner(), atom(QXcbAtom::XdndSelection), connection()->time()); QStringList fmts = QXcbMime::formatsHelper(drag()->mimeData()); for (int i = 0; i < fmts.size(); ++i) { QVector<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), fmts.at(i)); for (int j = 0; j < atoms.size(); ++j) { if (!drag_types.contains(atoms.at(j))) drag_types.append(atoms.at(j)); } } if (drag_types.size() > 3) xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->clipboard()->owner(), atom(QXcbAtom::XdndTypelist), XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData()); QBasicDrag::startDrag(); }
// ===== startSystemTray() ===== WId LXCB::startSystemTray(int screen){ qDebug() << "Starting System Tray:" << screen; //Setup the freedesktop standards compliance //Get the appropriate atom for this screen QString str = QString("_NET_SYSTEM_TRAY_S%1").arg(QString::number(screen)); //qDebug() << "Default Screen Atom Name:" << str; xcb_intern_atom_reply_t *treply = xcb_intern_atom_reply(QX11Info::connection(), \ xcb_intern_atom(QX11Info::connection(), 0, str.length(), str.toLocal8Bit()), NULL); xcb_intern_atom_reply_t *oreply = xcb_intern_atom_reply(QX11Info::connection(), \ xcb_intern_atom(QX11Info::connection(), 0, 28, "_NET_SYSTEM_TRAY_ORIENTATION"), NULL); xcb_intern_atom_reply_t *vreply = xcb_intern_atom_reply(QX11Info::connection(), \ xcb_intern_atom(QX11Info::connection(), 0, 23, "_NET_SYSTEM_TRAY_VISUAL"), NULL); if(treply==0){ qDebug() << " - ERROR: Could not initialize _NET_SYSTEM_TRAY_S<num> atom"; return 0; } if(oreply==0){ qDebug() << " - ERROR: Could not initialize _NET_SYSTEM_TRAY_ORIENTATION atom"; return 0; } if(vreply==0){ qDebug() << " - ERROR: Could not initialize _NET_SYSTEM_TRAY_VISUAL atom"; return 0; } xcb_atom_t _NET_SYSTEM_TRAY_S = treply->atom; xcb_atom_t _NET_SYSTEM_TRAY_ORIENTATION = oreply->atom; xcb_atom_t _NET_SYSTEM_TRAY_VISUAL = vreply->atom; free(treply); //done with atom generation free(oreply); free(vreply); //Make sure that there is no other system tray running xcb_get_selection_owner_reply_t *ownreply = xcb_get_selection_owner_reply(QX11Info::connection(), \ xcb_get_selection_owner_unchecked(QX11Info::connection(), _NET_SYSTEM_TRAY_S), NULL); if(ownreply==0){ qWarning() << " - Could not get owner selection reply"; return 0; } if(ownreply->owner != 0){ free(ownreply); qWarning() << " - An alternate system tray is currently in use"; return 0; } free(ownreply); //Create a simple window to register as the tray (not visible - just off the screen) xcb_screen_t *root_screen = xcb_aux_get_screen(QX11Info::connection(), QX11Info::appScreen()); uint32_t params[] = {1}; WId LuminaSessionTrayID = xcb_generate_id(QX11Info::connection()); //need a new ID xcb_create_window(QX11Info::connection(), root_screen->root_depth, \ LuminaSessionTrayID, root_screen->root, -1, -1, 1, 1, 0, \ XCB_WINDOW_CLASS_INPUT_OUTPUT, root_screen->root_visual, \ XCB_CW_OVERRIDE_REDIRECT, params); //Now register this widget as the system tray xcb_set_selection_owner(QX11Info::connection(), LuminaSessionTrayID, _NET_SYSTEM_TRAY_S, XCB_CURRENT_TIME); //Make sure that it was registered properly ownreply = xcb_get_selection_owner_reply(QX11Info::connection(), \ xcb_get_selection_owner_unchecked(QX11Info::connection(), _NET_SYSTEM_TRAY_S), NULL); if(ownreply==0 || ownreply->owner != LuminaSessionTrayID){ if(ownreply!=0){ free(ownreply); } qWarning() << " - Could not register the system tray"; xcb_destroy_window(QX11Info::connection(), LuminaSessionTrayID); return 0; } free(ownreply); //done with structure //Now register the orientation of the system tray uint32_t orient = _NET_SYSTEM_TRAY_ORIENTATION_HORZ; xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, LuminaSessionTrayID, \ _NET_SYSTEM_TRAY_ORIENTATION, XCB_ATOM_CARDINAL, 32, 1, &orient); //Now set the visual ID for the system tray (same as the root window, but TrueColor) xcb_visualtype_t *type = xcb_aux_find_visual_by_attrs(root_screen, XCB_VISUAL_CLASS_TRUE_COLOR, 32); if(type!=0){ xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, LuminaSessionTrayID, \ _NET_SYSTEM_TRAY_VISUAL, XCB_ATOM_VISUALID, 32, 1, &type->visual_id); }else{ qWarning() << " - Could not set TrueColor visual for system tray"; } //Finally, send out an X event letting others know that the system tray is up and running xcb_client_message_event_t event; event.response_type = XCB_CLIENT_MESSAGE; event.format = 32; event.window = root_screen->root; event.type = EWMH.MANAGER; //MANAGER atom event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; event.data.data32[1] = _NET_SYSTEM_TRAY_S; //_NET_SYSTEM_TRAY_S atom event.data.data32[2] = LuminaSessionTrayID; event.data.data32[3] = 0; event.data.data32[4] = 0; xcb_send_event(QX11Info::connection(), 0, root_screen->root, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); //Success return LuminaSessionTrayID; }