text: // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef CHROME_BROWSER_CHROMEOS_EVENTS_SYSTEM_KEY_EVENT_LISTENER_H_
  #define CHROME_BROWSER_CHROMEOS_EVENTS_SYSTEM_KEY_EVENT_LISTENER_H_
  
  #include "base/memory/singleton.h"
  #include "base/message_loop/message_loop.h"
  
  typedef union _XEvent XEvent;
  
  namespace chromeos {
  
  class SystemKeyEventListener : public base::MessageLoopForUI::Observer {
   public:
    // Observer for caps lock state changes.
    class CapsLockObserver {
     public:
      virtual void OnCapsLockChange(bool enabled) = 0;
  
     protected:
      CapsLockObserver() {}
      virtual ~CapsLockObserver() {}
  
      DISALLOW_COPY_AND_ASSIGN(CapsLockObserver);
    };
  
    // Observer for modifier keys' state changes.
    class ModifiersObserver {
     public:
      enum {
        SHIFT_PRESSED = 1,
        CTRL_PRESSED = 1 << 1,
        ALT_PRESSED = 1 << 2,
      };
  
      // |pressed_modifiers| is a bitmask of SHIFT_PRESSED, CTRL_PRESSED and
      // ALT_PRESSED.
      virtual void OnModifiersChange(int pressed_modifiers) = 0;
  
     protected:
      ModifiersObserver() {}
      virtual ~ModifiersObserver() {}
  
      DISALLOW_COPY_AND_ASSIGN(ModifiersObserver);
    };
  
    static void Initialize();
    static void Shutdown();
    // GetInstance returns NULL if not initialized or if already shutdown.
    static SystemKeyEventListener* GetInstance();
  
    void Stop();
  
    void AddCapsLockObserver(CapsLockObserver* observer);
    void AddModifiersObserver(ModifiersObserver* observer);
    void RemoveCapsLockObserver(CapsLockObserver* observer);
    void RemoveModifiersObserver(ModifiersObserver* observer);
  
   private:
    // Defines the delete on exit Singleton traits we like.  Best to have this
    // and const/dest private as recommended for Singletons.
    friend struct DefaultSingletonTraits<SystemKeyEventListener>;
    friend class SystemKeyEventListenerTest;
  
    SystemKeyEventListener();
    virtual ~SystemKeyEventListener();
  
    // MessageLoopForUI::Observer overrides.
    virtual base::EventStatus WillProcessEvent(
        const base::NativeEvent& event) OVERRIDE;
    virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
  
    void OnCapsLock(bool enabled);
    void OnModifiers(int state);
  
    // Returns true if the event was processed, false otherwise.
    virtual bool ProcessedXEvent(XEvent* xevent);
  
    bool stopped_;
  
    unsigned int num_lock_mask_;
    bool caps_lock_is_on_;
    int pressed_modifiers_;
    ObserverList<CapsLockObserver> caps_lock_observers_;
    ObserverList<ModifiersObserver> modifiers_observers_;
  
    // Base X ID for events from the XKB extension.
    int xkb_event_base_;
  
    DISALLOW_COPY_AND_ASSIGN(SystemKeyEventListener);
  };
  
  }  // namespace chromeos
  
  #endif  // CHROME_BROWSER_CHROMEOS_EVENTS_SYSTEM_KEY_EVENT_LISTENER_H_
  