| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/wm_ipc.h" | 5 #include "chrome/browser/chromeos/wm_ipc.h" |
| 6 | 6 |
| 7 #include <gdk/gdkx.h> | 7 #include <gdk/gdkx.h> |
| 8 extern "C" { | 8 extern "C" { |
| 9 #include <X11/Xlib.h> | 9 #include <X11/Xlib.h> |
| 10 } | 10 } |
| 11 | 11 |
| 12 #include "app/x11_util.h" | |
| 13 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 14 #include "base/logging.h" | 13 #include "base/logging.h" |
| 15 #include "base/scoped_ptr.h" | 14 #include "base/scoped_ptr.h" |
| 15 #include "ui/base/x/x11_util.h" |
| 16 | 16 |
| 17 namespace chromeos { | 17 namespace chromeos { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 // A value from the Atom enum and the actual name that should be used to | 21 // A value from the Atom enum and the actual name that should be used to |
| 22 // look up its ID on the X server. | 22 // look up its ID on the X server. |
| 23 struct AtomInfo { | 23 struct AtomInfo { |
| 24 WmIpc::AtomType atom; | 24 WmIpc::AtomType atom; |
| 25 const char* name; | 25 const char* name; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 bool SetIntProperty(XID xid, Atom xatom, const std::vector<int>& values) { | 39 bool SetIntProperty(XID xid, Atom xatom, const std::vector<int>& values) { |
| 40 DCHECK(!values.empty()); | 40 DCHECK(!values.empty()); |
| 41 | 41 |
| 42 // XChangeProperty expects values of type 32 to be longs. | 42 // XChangeProperty expects values of type 32 to be longs. |
| 43 scoped_array<long> data(new long[values.size()]); | 43 scoped_array<long> data(new long[values.size()]); |
| 44 for (size_t i = 0; i < values.size(); ++i) | 44 for (size_t i = 0; i < values.size(); ++i) |
| 45 data[i] = values[i]; | 45 data[i] = values[i]; |
| 46 | 46 |
| 47 // TODO: Trap errors and return false on failure. | 47 // TODO: Trap errors and return false on failure. |
| 48 XChangeProperty(x11_util::GetXDisplay(), | 48 XChangeProperty(ui::GetXDisplay(), |
| 49 xid, | 49 xid, |
| 50 xatom, | 50 xatom, |
| 51 xatom, | 51 xatom, |
| 52 32, // size in bits of items in 'value' | 52 32, // size in bits of items in 'value' |
| 53 PropModeReplace, | 53 PropModeReplace, |
| 54 reinterpret_cast<const unsigned char*>(data.get()), | 54 reinterpret_cast<const unsigned char*>(data.get()), |
| 55 values.size()); // num items | 55 values.size()); // num items |
| 56 XFlush(x11_util::GetXDisplay()); | 56 XFlush(ui::GetXDisplay()); |
| 57 return true; | 57 return true; |
| 58 } | 58 } |
| 59 | 59 |
| 60 } // namespace | 60 } // namespace |
| 61 | 61 |
| 62 static base::LazyInstance<WmIpc> g_wm_ipc(base::LINKER_INITIALIZED); | 62 static base::LazyInstance<WmIpc> g_wm_ipc(base::LINKER_INITIALIZED); |
| 63 | 63 |
| 64 // static | 64 // static |
| 65 WmIpc* WmIpc::instance() { | 65 WmIpc* WmIpc::instance() { |
| 66 return g_wm_ipc.Pointer(); | 66 return g_wm_ipc.Pointer(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 bool WmIpc::SetWindowType(GtkWidget* widget, | 69 bool WmIpc::SetWindowType(GtkWidget* widget, |
| 70 WmIpcWindowType type, | 70 WmIpcWindowType type, |
| 71 const std::vector<int>* params) { | 71 const std::vector<int>* params) { |
| 72 std::vector<int> values; | 72 std::vector<int> values; |
| 73 values.push_back(type); | 73 values.push_back(type); |
| 74 if (params) | 74 if (params) |
| 75 values.insert(values.end(), params->begin(), params->end()); | 75 values.insert(values.end(), params->begin(), params->end()); |
| 76 return SetIntProperty(x11_util::GetX11WindowFromGtkWidget(widget), | 76 return SetIntProperty(ui::GetX11WindowFromGtkWidget(widget), |
| 77 type_to_atom_[ATOM_CHROME_WINDOW_TYPE], values); | 77 type_to_atom_[ATOM_CHROME_WINDOW_TYPE], values); |
| 78 } | 78 } |
| 79 | 79 |
| 80 WmIpcWindowType WmIpc::GetWindowType(GtkWidget* widget, | 80 WmIpcWindowType WmIpc::GetWindowType(GtkWidget* widget, |
| 81 std::vector<int>* params) { | 81 std::vector<int>* params) { |
| 82 std::vector<int> properties; | 82 std::vector<int> properties; |
| 83 if (x11_util::GetIntArrayProperty( | 83 if (ui::GetIntArrayProperty( |
| 84 x11_util::GetX11WindowFromGtkWidget(widget), | 84 ui::GetX11WindowFromGtkWidget(widget), |
| 85 atom_to_string_[type_to_atom_[ATOM_CHROME_WINDOW_TYPE]], | 85 atom_to_string_[type_to_atom_[ATOM_CHROME_WINDOW_TYPE]], |
| 86 &properties)) { | 86 &properties)) { |
| 87 int type = properties.front(); | 87 int type = properties.front(); |
| 88 if (params) { | 88 if (params) { |
| 89 params->clear(); | 89 params->clear(); |
| 90 params->insert(params->begin(), properties.begin() + 1, properties.end()); | 90 params->insert(params->begin(), properties.begin() + 1, properties.end()); |
| 91 } | 91 } |
| 92 return static_cast<WmIpcWindowType>(type); | 92 return static_cast<WmIpcWindowType>(type); |
| 93 } else { | 93 } else { |
| 94 return WM_IPC_WINDOW_UNKNOWN; | 94 return WM_IPC_WINDOW_UNKNOWN; |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 | 97 |
| 98 void WmIpc::SendMessage(const Message& msg) { | 98 void WmIpc::SendMessage(const Message& msg) { |
| 99 XEvent e; | 99 XEvent e; |
| 100 e.xclient.type = ClientMessage; | 100 e.xclient.type = ClientMessage; |
| 101 e.xclient.window = wm_; | 101 e.xclient.window = wm_; |
| 102 e.xclient.message_type = type_to_atom_[ATOM_CHROME_WM_MESSAGE]; | 102 e.xclient.message_type = type_to_atom_[ATOM_CHROME_WM_MESSAGE]; |
| 103 e.xclient.format = 32; // 32-bit values | 103 e.xclient.format = 32; // 32-bit values |
| 104 e.xclient.data.l[0] = msg.type(); | 104 e.xclient.data.l[0] = msg.type(); |
| 105 | 105 |
| 106 // XClientMessageEvent only gives us five 32-bit items, and we're using | 106 // XClientMessageEvent only gives us five 32-bit items, and we're using |
| 107 // the first one for our message type. | 107 // the first one for our message type. |
| 108 DCHECK_LE(msg.max_params(), 4); | 108 DCHECK_LE(msg.max_params(), 4); |
| 109 for (int i = 0; i < msg.max_params(); ++i) | 109 for (int i = 0; i < msg.max_params(); ++i) |
| 110 e.xclient.data.l[i+1] = msg.param(i); | 110 e.xclient.data.l[i+1] = msg.param(i); |
| 111 | 111 |
| 112 XSendEvent(x11_util::GetXDisplay(), | 112 XSendEvent(ui::GetXDisplay(), |
| 113 wm_, | 113 wm_, |
| 114 False, // propagate | 114 False, // propagate |
| 115 0, // empty event mask | 115 0, // empty event mask |
| 116 &e); | 116 &e); |
| 117 } | 117 } |
| 118 | 118 |
| 119 bool WmIpc::DecodeMessage(const GdkEventClient& event, Message* msg) { | 119 bool WmIpc::DecodeMessage(const GdkEventClient& event, Message* msg) { |
| 120 if (wm_message_atom_ != gdk_x11_atom_to_xatom(event.message_type)) | 120 if (wm_message_atom_ != gdk_x11_atom_to_xatom(event.message_type)) |
| 121 return false; | 121 return false; |
| 122 | 122 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 | 170 |
| 171 WmIpc::WmIpc() { | 171 WmIpc::WmIpc() { |
| 172 scoped_array<char*> names(new char*[kNumAtoms]); | 172 scoped_array<char*> names(new char*[kNumAtoms]); |
| 173 scoped_array<Atom> atoms(new Atom[kNumAtoms]); | 173 scoped_array<Atom> atoms(new Atom[kNumAtoms]); |
| 174 | 174 |
| 175 for (int i = 0; i < kNumAtoms; ++i) { | 175 for (int i = 0; i < kNumAtoms; ++i) { |
| 176 // Need to const_cast because XInternAtoms() wants a char**. | 176 // Need to const_cast because XInternAtoms() wants a char**. |
| 177 names[i] = const_cast<char*>(kAtomInfos[i].name); | 177 names[i] = const_cast<char*>(kAtomInfos[i].name); |
| 178 } | 178 } |
| 179 | 179 |
| 180 XInternAtoms(x11_util::GetXDisplay(), names.get(), kNumAtoms, | 180 XInternAtoms(ui::GetXDisplay(), names.get(), kNumAtoms, |
| 181 False, // only_if_exists | 181 False, // only_if_exists |
| 182 atoms.get()); | 182 atoms.get()); |
| 183 | 183 |
| 184 for (int i = 0; i < kNumAtoms; ++i) { | 184 for (int i = 0; i < kNumAtoms; ++i) { |
| 185 type_to_atom_[kAtomInfos[i].atom] = atoms[i]; | 185 type_to_atom_[kAtomInfos[i].atom] = atoms[i]; |
| 186 atom_to_string_[atoms[i]] = kAtomInfos[i].name; | 186 atom_to_string_[atoms[i]] = kAtomInfos[i].name; |
| 187 } | 187 } |
| 188 | 188 |
| 189 wm_message_atom_ = type_to_atom_[ATOM_CHROME_WM_MESSAGE]; | 189 wm_message_atom_ = type_to_atom_[ATOM_CHROME_WM_MESSAGE]; |
| 190 | 190 |
| 191 // Make sure that we're selecting structure changes on the root window; | 191 // Make sure that we're selecting structure changes on the root window; |
| 192 // the window manager uses StructureNotifyMask when sending the ClientMessage | 192 // the window manager uses StructureNotifyMask when sending the ClientMessage |
| 193 // event to announce that it's taken the manager selection. | 193 // event to announce that it's taken the manager selection. |
| 194 GdkWindow* root = gdk_get_default_root_window(); | 194 GdkWindow* root = gdk_get_default_root_window(); |
| 195 GdkEventMask event_mask = gdk_window_get_events(root); | 195 GdkEventMask event_mask = gdk_window_get_events(root); |
| 196 gdk_window_set_events( | 196 gdk_window_set_events( |
| 197 root, static_cast<GdkEventMask>(event_mask | GDK_STRUCTURE_MASK)); | 197 root, static_cast<GdkEventMask>(event_mask | GDK_STRUCTURE_MASK)); |
| 198 | 198 |
| 199 InitWmInfo(); | 199 InitWmInfo(); |
| 200 } | 200 } |
| 201 | 201 |
| 202 void WmIpc::InitWmInfo() { | 202 void WmIpc::InitWmInfo() { |
| 203 wm_ = XGetSelectionOwner(x11_util::GetXDisplay(), type_to_atom_[ATOM_WM_S0]); | 203 wm_ = XGetSelectionOwner(ui::GetXDisplay(), type_to_atom_[ATOM_WM_S0]); |
| 204 | 204 |
| 205 // Let the window manager know which version of the IPC messages we support. | 205 // Let the window manager know which version of the IPC messages we support. |
| 206 Message msg(chromeos::WM_IPC_MESSAGE_WM_NOTIFY_IPC_VERSION); | 206 Message msg(chromeos::WM_IPC_MESSAGE_WM_NOTIFY_IPC_VERSION); |
| 207 // TODO: The version number is the latest listed in wm_ipc.h -- | 207 // TODO: The version number is the latest listed in wm_ipc.h -- |
| 208 // ideally, once this header is shared between Chrome and the Chrome OS window | 208 // ideally, once this header is shared between Chrome and the Chrome OS window |
| 209 // manager, we'll just define the version statically in the header. | 209 // manager, we'll just define the version statically in the header. |
| 210 msg.set_param(0, 1); | 210 msg.set_param(0, 1); |
| 211 SendMessage(msg); | 211 SendMessage(msg); |
| 212 } | 212 } |
| 213 | 213 |
| 214 } // namespace chromeos | 214 } // namespace chromeos |
| OLD | NEW |