blob: ca7edd92dd3ae26be54afc8cd1a6af069230463e [file] [log] [blame]
// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "window_manager/atom_cache.h"
#include <vector>
#include "base/logging.h"
#include "window_manager/util.h"
#include "window_manager/x11/x_connection.h"
using base::hash_map;
using std::string;
using std::vector;
using window_manager::util::FindWithDefault;
using window_manager::util::XidStr;
namespace window_manager {
// A value from the Atom enum and the actual name that should be used to
// look up its ID on the X server.
struct AtomInfo {
Atom atom;
const char* name;
};
// Each value from the Atom enum must be present here.
static const AtomInfo kAtomInfos[] = {
{ ATOM_ATOM, "ATOM" },
{ ATOM_CARDINAL, "CARDINAL" },
{ ATOM_CHROME_GET_SERVER_TIME, "_CHROME_GET_SERVER_TIME" },
{ ATOM_CHROME_LOGGED_IN, "_CHROME_LOGGED_IN" },
{ ATOM_CHROME_STATE, "_CHROME_STATE" },
{ ATOM_CHROME_STATE_COLLAPSED_PANEL, "_CHROME_STATE_COLLAPSED_PANEL" },
{ ATOM_CHROME_VIDEO_TIME, "_CHROME_VIDEO_TIME" },
{ ATOM_CHROME_WINDOW_TYPE, "_CHROME_WINDOW_TYPE" },
{ ATOM_CHROME_WM_MESSAGE, "_CHROME_WM_MESSAGE" },
{ ATOM_MANAGER, "MANAGER" },
{ ATOM_NET_ACTIVE_WINDOW, "_NET_ACTIVE_WINDOW" },
{ ATOM_NET_CLIENT_LIST, "_NET_CLIENT_LIST" },
{ ATOM_NET_CLIENT_LIST_STACKING, "_NET_CLIENT_LIST_STACKING" },
{ ATOM_NET_CURRENT_DESKTOP, "_NET_CURRENT_DESKTOP" },
{ ATOM_NET_DESKTOP_GEOMETRY, "_NET_DESKTOP_GEOMETRY" },
{ ATOM_NET_DESKTOP_VIEWPORT, "_NET_DESKTOP_VIEWPORT" },
{ ATOM_NET_NUMBER_OF_DESKTOPS, "_NET_NUMBER_OF_DESKTOPS" },
{ ATOM_NET_SUPPORTED, "_NET_SUPPORTED" },
{ ATOM_NET_SUPPORTING_WM_CHECK, "_NET_SUPPORTING_WM_CHECK" },
{ ATOM_NET_WM_CM_S0, "_NET_WM_CM_S0" },
{ ATOM_NET_WM_MOVERESIZE, "_NET_WM_MOVERESIZE" },
{ ATOM_NET_WM_NAME, "_NET_WM_NAME" },
{ ATOM_NET_WM_PID, "_NET_WM_PID" },
{ ATOM_NET_WM_PING, "_NET_WM_PING" },
{ ATOM_NET_WM_STATE, "_NET_WM_STATE" },
{ ATOM_NET_WM_STATE_FULLSCREEN, "_NET_WM_STATE_FULLSCREEN" },
{ ATOM_NET_WM_STATE_MAXIMIZED_HORZ, "_NET_WM_STATE_MAXIMIZED_HORZ" },
{ ATOM_NET_WM_STATE_MAXIMIZED_VERT, "_NET_WM_STATE_MAXIMIZED_VERT" },
{ ATOM_NET_WM_STATE_MODAL, "_NET_WM_STATE_MODAL" },
{ ATOM_NET_WM_SYNC_REQUEST, "_NET_WM_SYNC_REQUEST" },
{ ATOM_NET_WM_SYNC_REQUEST_COUNTER, "_NET_WM_SYNC_REQUEST_COUNTER" },
{ ATOM_NET_WM_USER_TIME, "_NET_WM_USER_TIME" },
{ ATOM_NET_WM_WINDOW_OPACITY, "_NET_WM_WINDOW_OPACITY" },
{ ATOM_NET_WM_WINDOW_TYPE, "_NET_WM_WINDOW_TYPE" },
{ ATOM_NET_WM_WINDOW_TYPE_COMBO, "_NET_WM_WINDOW_TYPE_COMBO" },
{ ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU" },
{ ATOM_NET_WM_WINDOW_TYPE_MENU, "_NET_WM_WINDOW_TYPE_MENU" },
{ ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU,
"_NET_WM_WINDOW_TYPE_POPUP_MENU" },
{ ATOM_NET_WORKAREA, "_NET_WORKAREA" },
{ ATOM_PRIMARY, "PRIMARY" },
{ ATOM_WM_CLIENT_MACHINE, "WM_CLIENT_MACHINE" },
{ ATOM_WM_DELETE_WINDOW, "WM_DELETE_WINDOW" },
{ ATOM_WM_HINTS, "WM_HINTS" },
{ ATOM_WM_NAME, "WM_NAME" },
{ ATOM_WM_NORMAL_HINTS, "WM_NORMAL_HINTS" },
{ ATOM_WM_PROTOCOLS, "WM_PROTOCOLS" },
{ ATOM_WM_S0, "WM_S0" },
{ ATOM_WM_STATE, "WM_STATE" },
{ ATOM_WM_TAKE_FOCUS, "WM_TAKE_FOCUS" },
{ ATOM_WM_TRANSIENT_FOR, "WM_TRANSIENT_FOR" },
};
AtomCache::AtomCache(XConnection* xconn)
: xconn_(xconn) {
CHECK(xconn_);
CHECK(sizeof(kAtomInfos) / sizeof(AtomInfo) == kNumAtoms)
<< "Each value in the Atom enum in atom_cache.h must have "
<< "a mapping in kAtomInfos in atom_cache.cc";
vector<string> names;
vector<XAtom> xatoms;
for (int i = 0; i < kNumAtoms; ++i)
names.push_back(kAtomInfos[i].name);
CHECK(xconn_->GetAtoms(names, &xatoms));
CHECK(xatoms.size() == kNumAtoms);
for (size_t i = 0; i < kNumAtoms; ++i) {
LOG(INFO) << "Registering atom " << XidStr(xatoms[i])
<< " (" << kAtomInfos[i].name << ")";
atom_to_xatom_[kAtomInfos[i].atom] = xatoms[i];
xatom_to_string_[xatoms[i]] = kAtomInfos[i].name;
}
}
XAtom AtomCache::GetXAtom(Atom atom) const {
XAtom xatom = FindWithDefault(atom_to_xatom_,
static_cast<int>(atom),
static_cast<XAtom>(0));
CHECK(xatom) << "Couldn't find X atom for Atom " << XidStr(atom);
return xatom;
}
const string& AtomCache::GetName(XAtom xatom) {
hash_map<XAtom, string>::const_iterator it = xatom_to_string_.find(xatom);
if (it != xatom_to_string_.end())
return it->second;
string name;
if (!xconn_->GetAtomName(xatom, &name)) {
LOG(ERROR) << "Unable to look up name for atom " << XidStr(xatom);
static const string kEmptyName = "";
return kEmptyName;
}
return xatom_to_string_.insert(make_pair(xatom, name)).first->second;
}
} // namespace window_manager