Home | History | Annotate | Download | only in chromeos
      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 
     17 typedef unsigned long Atom;
     18 typedef unsigned long XID;
     19 
     20 namespace base {
     21 template <typename T> struct DefaultLazyInstanceTraits;
     22 }
     23 
     24 namespace chromeos {
     25 
     26 class 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