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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_CHROMEOS_WM_IPC_H_
6#define CHROME_BROWSER_CHROMEOS_WM_IPC_H_
7#pragma once
8
9#include <gtk/gtk.h>
10#include <map>
11#include <string>
12#include <vector>
13
14#include "base/logging.h"
15#include "third_party/cros/chromeos_wm_ipc_enums.h"
16
17typedef unsigned long Atom;
18typedef unsigned long XID;
19
20namespace base {
21template <typename T> struct DefaultLazyInstanceTraits;
22}
23
24namespace chromeos {
25
26class WmIpc {
27 public:
28  enum AtomType {
29    ATOM_CHROME_LOGGED_IN = 0,
30    ATOM_CHROME_WINDOW_TYPE,
31    ATOM_CHROME_WM_MESSAGE,
32    ATOM_MANAGER,
33    ATOM_STRING,
34    ATOM_UTF8_STRING,
35    ATOM_WM_S0,
36    kNumAtoms,
37  };
38
39  struct Message {
40   public:
41    Message() {
42      Init(WM_IPC_MESSAGE_UNKNOWN);
43    }
44    // WmIpcMessageType is defined in chromeos_wm_ipc_enums.h.
45    explicit Message(WmIpcMessageType type) {
46      Init(type);
47    }
48
49    WmIpcMessageType type() const { return type_; }
50    void set_type(WmIpcMessageType type) { type_ = type; }
51
52    inline int max_params() const {
53      return arraysize(params_);
54    }
55    long param(int index) const {
56      DCHECK_GE(index, 0);
57      DCHECK_LT(index, max_params());
58      return params_[index];
59    }
60    void set_param(int index, long value) {
61      DCHECK_GE(index, 0);
62      DCHECK_LT(index, max_params());
63      params_[index] = value;
64    }
65
66   private:
67    // Common initialization code shared between constructors.
68    void Init(WmIpcMessageType type) {
69      set_type(type);
70      for (int i = 0; i < max_params(); ++i) {
71        set_param(i, 0);
72      }
73    }
74
75    // Type of message that was sent.
76    WmIpcMessageType type_;
77
78    // Type-specific data.  This is bounded by the number of 32-bit values
79    // that we can pack into a ClientMessageEvent -- it holds five, but we
80    // use the first one to store the message type.
81    long params_[4];
82  };
83
84  // Returns the single instance of WmIpc.
85  static WmIpc* instance();
86
87  // Gets or sets a property describing a window's type.
88  // WmIpcMessageType is defined in chromeos_wm_ipc_enums.h.  Type-specific
89  // parameters may also be supplied.  The caller is responsible for trapping
90  // errors from the X server.
91  bool SetWindowType(GtkWidget* widget,
92                     WmIpcWindowType type,
93                     const std::vector<int>* params);
94
95  // Gets the type of the window, and any associated parameters. The
96  // caller is responsible for trapping errors from the X server.  If
97  // the parameters are not interesting to the caller, NULL may be
98  // passed for |params|.
99  WmIpcWindowType GetWindowType(GtkWidget* widget, std::vector<int>* params);
100
101  // Sends a message to the WM.
102  void SendMessage(const Message& msg);
103
104  // If |event| is a valid Message it is decoded into |msg| and true is
105  // returned. If false is returned, |event| is not a valid Message.
106  bool DecodeMessage(const GdkEventClient& event, Message* msg);
107
108  // Handles ClientMessage events that weren't decodable using DecodeMessage().
109  // Specifically, this catches messages about the WM_S0 selection that get sent
110  // when a window manager process starts (so that we can re-run InitWmInfo()).
111  // See ICCCM 2.8 for more info about MANAGER selections.
112  void HandleNonChromeClientMessageEvent(const GdkEventClient& event);
113
114  // Sets a _CHROME_LOGGED_IN property on the root window describing whether
115  // the user is currently logged in or not.
116  void SetLoggedInProperty(bool logged_in);
117
118  // Sends a message to the window manager notifying it that we're signing out.
119  void NotifyAboutSignout();
120
121 private:
122  friend struct base::DefaultLazyInstanceTraits<WmIpc>;
123
124  WmIpc();
125
126  // Initialize 'wm_' and send the window manager a message telling it the
127  // version of the IPC protocol that we support.  This is called in our
128  // constructor, but needs to be re-run if the window manager gets restarted.
129  void InitWmInfo();
130
131  // Maps from our Atom enum to the X server's atom IDs and from the
132  // server's IDs to atoms' string names.  These maps aren't necessarily in
133  // sync; 'atom_to_xatom_' is constant after the constructor finishes but
134  // GetName() caches additional string mappings in 'xatom_to_string_'.
135  std::map<AtomType, Atom> type_to_atom_;
136  std::map<Atom, std::string> atom_to_string_;
137
138  // Cached value of type_to_atom_[ATOM_CHROME_WM_MESSAGE].
139  Atom wm_message_atom_;
140
141  // Handle to the wm. Used for sending messages.
142  XID wm_;
143
144  DISALLOW_COPY_AND_ASSIGN(WmIpc);
145};
146
147}  // namespace chromeos
148
149#endif  // CHROME_BROWSER_CHROMEOS_WM_IPC_H_
150