Skip to content

Commit

Permalink
Merge #1203
Browse files Browse the repository at this point in the history
1203: XWayland: XCBAtoms class r=AlanGriffiths a=wmww

Move atom management into its own class, and resolve atom cookies lazily when required.

Stacked on #1200

Co-authored-by: William Wold <wm@wmww.sh>
(cherry picked from commit 32a6fc5)
  • Loading branch information
bors[bot] authored and AlanGriffiths committed Feb 14, 2020
1 parent 702fdee commit 24b814f
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 156 deletions.
1 change: 1 addition & 0 deletions src/server/frontend_xwayland/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(
xwayland_default_configuration.cpp
xwayland_connector.cpp xwayland_connector.h
xwayland_server.cpp xwayland_server.h
xcb_atoms.cpp xcb_atoms.h
xwayland_wm.cpp xwayland_wm.h
xwayland_wm_surface.cpp xwayland_wm_surface.h
xwayland_wm_shellsurface.cpp xwayland_wm_shellsurface.h
Expand Down
115 changes: 115 additions & 0 deletions src/server/frontend_xwayland/xcb_atoms.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright (C) 2018 Marius Gripsgard <marius@ubports.com>
* Copyright (C) 2020 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 or 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

#include "xcb_atoms.h"
#include "boost/throw_exception.hpp"

namespace mf = mir::frontend;

mf::XCBAtoms::Atom::Atom(std::string const& name, Context const& context)
: context{context},
name_{name},
cookie{xcb_intern_atom(context.xcb_connection, 0, name_.size(), name_.c_str())}
{
}

mf::XCBAtoms::Atom::operator xcb_atom_t() const
{
if (!atom)
{
auto const reply = xcb_intern_atom_reply(context.xcb_connection, cookie, nullptr);
if (!reply)
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to look up atom " + name_));
atom = reply->atom;
free(reply);
}
return atom.value();
}

auto mf::XCBAtoms::Atom::name() const -> std::string
{
return name_;
}

mf::XCBAtoms::XCBAtoms(xcb_connection_t* xcb_connection)
: context{xcb_connection},
wm_protocols{"WM_PROTOCOLS", context},
wm_normal_hints{"WM_NORMAL_HINTS", context},
wm_take_focus{"WM_TAKE_FOCUS", context},
wm_delete_window{"WM_DELETE_WINDOW", context},
wm_state{"WM_STATE", context},
wm_s0{"WM_S0", context},
wm_client_machine{"WM_CLIENT_MACHINE", context},
net_wm_cm_s0{"_NET_WM_CM_S0", context},
net_wm_name{"_NET_WM_NAME", context},
net_wm_pid{"_NET_WM_PID", context},
net_wm_icon{"_NET_WM_ICON", context},
net_wm_state{"_NET_WM_STATE", context},
net_wm_state_maximized_vert{"_NET_WM_STATE_MAXIMIZED_VERT", context},
net_wm_state_maximized_horz{"_NET_WM_STATE_MAXIMIZED_HORZ", context},
net_wm_state_fullscreen{"_NET_WM_STATE_FULLSCREEN", context},
net_wm_user_time{"_NET_WM_USER_TIME", context},
net_wm_icon_name{"_NET_WM_ICON_NAME", context},
net_wm_desktop{"_NET_WM_DESKTOP", context},
net_wm_window_type{"_NET_WM_WINDOW_TYPE", context},
net_wm_window_type_desktop{"_NET_WM_WINDOW_TYPE_DESKTOP", context},
net_wm_window_type_dock{"_NET_WM_WINDOW_TYPE_DOCK", context},
net_wm_window_type_toolbar{"_NET_WM_WINDOW_TYPE_TOOLBAR", context},
net_wm_window_type_menu{"_NET_WM_WINDOW_TYPE_MENU", context},
net_wm_window_type_utility{"_NET_WM_WINDOW_TYPE_UTILITY", context},
net_wm_window_type_splash{"_NET_WM_WINDOW_TYPE_SPLASH", context},
net_wm_window_type_dialog{"_NET_WM_WINDOW_TYPE_DIALOG", context},
net_wm_window_type_dropdown{"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", context},
net_wm_window_type_popup{"_NET_WM_WINDOW_TYPE_POPUP_MENU", context},
net_wm_window_type_tooltip{"_NET_WM_WINDOW_TYPE_TOOLTIP", context},
net_wm_window_type_notification{"_NET_WM_WINDOW_TYPE_NOTIFICATION", context},
net_wm_window_type_combo{"_NET_WM_WINDOW_TYPE_COMBO", context},
net_wm_window_type_dnd{"_NET_WM_WINDOW_TYPE_DND", context},
net_wm_window_type_normal{"_NET_WM_WINDOW_TYPE_NORMAL", context},
net_wm_moveresize{"_NET_WM_MOVERESIZE", context},
net_supporting_wm_check{"_NET_SUPPORTING_WM_CHECK", context},
net_supported{"_NET_SUPPORTED", context},
net_active_window{"_NET_ACTIVE_WINDOW", context},
motif_wm_hints{"_MOTIF_WM_HINTS", context},
clipboard{"CLIPBOARD", context},
clipboard_manager{"CLIPBOARD_MANAGER", context},
targets{"TARGETS", context},
utf8_string{"UTF8_STRING", context},
wl_selection{"_WL_SELECTION", context},
incr{"INCR", context},
timestamp{"TIMESTAMP", context},
multiple{"MULTIPLE", context},
compound_text{"COMPOUND_TEXT", context},
text{"TEXT", context},
string{"STRING", context},
window{"WINDOW", context},
text_plain_utf8{"text/plain;charset=utf-8", context},
text_plain{"text/plain", context},
xdnd_selection{"XdndSelection", context},
xdnd_aware{"XdndAware", context},
xdnd_enter{"XdndEnter", context},
xdnd_leave{"XdndLeave", context},
xdnd_drop{"XdndDrop", context},
xdnd_status{"XdndStatus", context},
xdnd_finished{"XdndFinished", context},
xdnd_type_list{"XdndTypeList", context},
xdnd_action_copy{"XdndActionCopy", context},
wl_surface_id{"WL_SURFACE_ID", context},
allow_commits{"_XWAYLAND_ALLOW_COMMITS", context}
{
}
132 changes: 132 additions & 0 deletions src/server/frontend_xwayland/xcb_atoms.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright (C) 2018 Marius Gripsgard <marius@ubports.com>
* Copyright (C) 2020 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 or 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

#ifndef MIR_FRONTEND_XCB_ATOMS_H
#define MIR_FRONTEND_XCB_ATOMS_H

#include <xcb/xcb.h>
#include <string>
#include <experimental/optional>

namespace mir
{
namespace frontend
{
class XCBAtoms
{
private:
struct Context
{
xcb_connection_t* const xcb_connection;
} const context;

public:
XCBAtoms(xcb_connection_t* xcb_connection);

class Atom
{
public:
/// Context should outlive the atom
Atom(std::string const& name, Context const& context);
operator xcb_atom_t() const;
auto name() const -> std::string;

private:
Atom(Atom&) = delete;
Atom(Atom&&) = delete;
Atom& operator=(Atom&) = delete;

Context const& context;
std::string const name_;
xcb_intern_atom_cookie_t const cookie;
std::experimental::optional<xcb_atom_t> mutable atom;
};

Atom const wm_protocols;
Atom const wm_normal_hints;
Atom const wm_take_focus;
Atom const wm_delete_window;
Atom const wm_state;
Atom const wm_s0;
Atom const wm_client_machine;
Atom const net_wm_cm_s0;
Atom const net_wm_name;
Atom const net_wm_pid;
Atom const net_wm_icon;
Atom const net_wm_state;
Atom const net_wm_state_maximized_vert;
Atom const net_wm_state_maximized_horz;
Atom const net_wm_state_fullscreen;
Atom const net_wm_user_time;
Atom const net_wm_icon_name;
Atom const net_wm_desktop;
Atom const net_wm_window_type;
Atom const net_wm_window_type_desktop;
Atom const net_wm_window_type_dock;
Atom const net_wm_window_type_toolbar;
Atom const net_wm_window_type_menu;
Atom const net_wm_window_type_utility;
Atom const net_wm_window_type_splash;
Atom const net_wm_window_type_dialog;
Atom const net_wm_window_type_dropdown;
Atom const net_wm_window_type_popup;
Atom const net_wm_window_type_tooltip;
Atom const net_wm_window_type_notification;
Atom const net_wm_window_type_combo;
Atom const net_wm_window_type_dnd;
Atom const net_wm_window_type_normal;
Atom const net_wm_moveresize;
Atom const net_supporting_wm_check;
Atom const net_supported;
Atom const net_active_window;
Atom const motif_wm_hints;
Atom const clipboard;
Atom const clipboard_manager;
Atom const targets;
Atom const utf8_string;
Atom const wl_selection;
Atom const incr;
Atom const timestamp;
Atom const multiple;
Atom const compound_text;
Atom const text;
Atom const string;
Atom const window;
Atom const text_plain_utf8;
Atom const text_plain;
Atom const xdnd_selection;
Atom const xdnd_aware;
Atom const xdnd_enter;
Atom const xdnd_leave;
Atom const xdnd_drop;
Atom const xdnd_status;
Atom const xdnd_finished;
Atom const xdnd_type_list;
Atom const xdnd_action_copy;
Atom const wl_surface_id;
Atom const allow_commits;

private:
XCBAtoms(XCBAtoms&) = delete;
XCBAtoms(XCBAtoms&&) = delete;
XCBAtoms& operator=(XCBAtoms&) = delete;
};
}
}

#endif // MIR_FRONTEND_XCB_ATOMS_H
88 changes: 1 addition & 87 deletions src/server/frontend_xwayland/xwayland_wm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ auto data_buffer_to_debug_string(T* data, size_t elements) -> std::string
mf::XWaylandWM::XWaylandWM(std::shared_ptr<WaylandConnector> wayland_connector, wl_client* wayland_client, int fd)
: wm_fd{fd},
xcb_connection{xcb_connect_to_fd(wm_fd, nullptr)},
xcb_atom{xcb_connection},
wayland_connector(wayland_connector),
dispatcher{std::make_shared<mir::dispatch::MultiplexingDispatchable>()},
wayland_client{wayland_client}
Expand Down Expand Up @@ -731,85 +732,8 @@ xcb_cursor_t mf::XWaylandWM::xcb_cursor_library_load_cursor(const char *file)

void mf::XWaylandWM::wm_get_resources()
{

#define F(field) offsetof(struct atom_t, field)

static const struct
{
const char *name;
int offset;
} atoms[] = {{"WM_PROTOCOLS", F(wm_protocols)},
{"WM_NORMAL_HINTS", F(wm_normal_hints)},
{"WM_TAKE_FOCUS", F(wm_take_focus)},
{"WM_DELETE_WINDOW", F(wm_delete_window)},
{"WM_STATE", F(wm_state)},
{"WM_S0", F(wm_s0)},
{"WM_CLIENT_MACHINE", F(wm_client_machine)},
{"_NET_WM_CM_S0", F(net_wm_cm_s0)},
{"_NET_WM_NAME", F(net_wm_name)},
{"_NET_WM_PID", F(net_wm_pid)},
{"_NET_WM_ICON", F(net_wm_icon)},
{"_NET_WM_STATE", F(net_wm_state)},
{"_NET_WM_STATE_MAXIMIZED_VERT", F(net_wm_state_maximized_vert)},
{"_NET_WM_STATE_MAXIMIZED_HORZ", F(net_wm_state_maximized_horz)},
{"_NET_WM_STATE_FULLSCREEN", F(net_wm_state_fullscreen)},
{"_NET_WM_USER_TIME", F(net_wm_user_time)},
{"_NET_WM_ICON_NAME", F(net_wm_icon_name)},
{"_NET_WM_DESKTOP", F(net_wm_desktop)},
{"_NET_WM_WINDOW_TYPE", F(net_wm_window_type)},

{"_NET_WM_WINDOW_TYPE_DESKTOP", F(net_wm_window_type_desktop)},
{"_NET_WM_WINDOW_TYPE_DOCK", F(net_wm_window_type_dock)},
{"_NET_WM_WINDOW_TYPE_TOOLBAR", F(net_wm_window_type_toolbar)},
{"_NET_WM_WINDOW_TYPE_MENU", F(net_wm_window_type_menu)},
{"_NET_WM_WINDOW_TYPE_UTILITY", F(net_wm_window_type_utility)},
{"_NET_WM_WINDOW_TYPE_SPLASH", F(net_wm_window_type_splash)},
{"_NET_WM_WINDOW_TYPE_DIALOG", F(net_wm_window_type_dialog)},
{"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", F(net_wm_window_type_dropdown)},
{"_NET_WM_WINDOW_TYPE_POPUP_MENU", F(net_wm_window_type_popup)},
{"_NET_WM_WINDOW_TYPE_TOOLTIP", F(net_wm_window_type_tooltip)},
{"_NET_WM_WINDOW_TYPE_NOTIFICATION", F(net_wm_window_type_notification)},
{"_NET_WM_WINDOW_TYPE_COMBO", F(net_wm_window_type_combo)},
{"_NET_WM_WINDOW_TYPE_DND", F(net_wm_window_type_dnd)},
{"_NET_WM_WINDOW_TYPE_NORMAL", F(net_wm_window_type_normal)},

{"_NET_WM_MOVERESIZE", F(net_wm_moveresize)},
{"_NET_SUPPORTING_WM_CHECK", F(net_supporting_wm_check)},
{"_NET_SUPPORTED", F(net_supported)},
{"_NET_ACTIVE_WINDOW", F(net_active_window)},
{"_MOTIF_WM_HINTS", F(motif_wm_hints)},
{"CLIPBOARD", F(clipboard)},
{"CLIPBOARD_MANAGER", F(clipboard_manager)},
{"TARGETS", F(targets)},
{"UTF8_STRING", F(utf8_string)},
{"_WL_SELECTION", F(wl_selection)},
{"INCR", F(incr)},
{"TIMESTAMP", F(timestamp)},
{"MULTIPLE", F(multiple)},
{"UTF8_STRING", F(utf8_string)},
{"COMPOUND_TEXT", F(compound_text)},
{"TEXT", F(text)},
{"STRING", F(string)},
{"WINDOW", F(window)},
{"text/plain;charset=utf-8", F(text_plain_utf8)},
{"text/plain", F(text_plain)},
{"XdndSelection", F(xdnd_selection)},
{"XdndAware", F(xdnd_aware)},
{"XdndEnter", F(xdnd_enter)},
{"XdndLeave", F(xdnd_leave)},
{"XdndDrop", F(xdnd_drop)},
{"XdndStatus", F(xdnd_status)},
{"XdndFinished", F(xdnd_finished)},
{"XdndTypeList", F(xdnd_type_list)},
{"XdndActionCopy", F(xdnd_action_copy)},
{"_XWAYLAND_ALLOW_COMMITS", F(allow_commits)},
{"WL_SURFACE_ID", F(wl_surface_id)}};
#undef F

xcb_xfixes_query_version_cookie_t xfixes_cookie;
xcb_xfixes_query_version_reply_t *xfixes_reply;
xcb_intern_atom_cookie_t cookies[ARRAY_LENGTH(atoms)];
xcb_intern_atom_reply_t *reply;
xcb_render_query_pict_formats_reply_t *formats_reply;
xcb_render_query_pict_formats_cookie_t formats_cookie;
xcb_render_pictforminfo_t *formats;
Expand All @@ -820,16 +744,6 @@ void mf::XWaylandWM::wm_get_resources()

formats_cookie = xcb_render_query_pict_formats(xcb_connection);

for (i = 0; i < ARRAY_LENGTH(atoms); i++)
cookies[i] = xcb_intern_atom(xcb_connection, 0, strlen(atoms[i].name), atoms[i].name);

for (i = 0; i < ARRAY_LENGTH(atoms); i++)
{
reply = xcb_intern_atom_reply(xcb_connection, cookies[i], NULL);
*(xcb_atom_t *)((char *)&xcb_atom + atoms[i].offset) = reply->atom;
free(reply);
}

xfixes = xcb_get_extension_data(xcb_connection, &xcb_xfixes_id);
if (!xfixes || !xfixes->present)
log_warning("xfixes not available");
Expand Down
Loading

0 comments on commit 24b814f

Please sign in to comment.