1e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// found in the LICENSE file.
4e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#ifndef CHROME_BROWSER_UI_LIBGTK2UI_GTK2_KEY_BINDINGS_HANDLER_H_
6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#define CHROME_BROWSER_UI_LIBGTK2UI_GTK2_KEY_BINDINGS_HANDLER_H_
7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
8e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <gtk/gtk.h>
9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
10e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <string>
11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <vector>
12e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
13e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/event_types.h"
14e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h"
15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/events/linux/text_edit_command_auralinux.h"
16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace content {
18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochstruct NativeWebKeyboardEvent;
19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace ui {
22e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass Event;
23e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
24e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
25e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace libgtk2ui {
26e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// This class is a convenience class for handling editor key bindings defined
28e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// in gtk keyboard theme.
29e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// In gtk, only GtkEntry and GtkTextView support customizing editor key bindings
30e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// through keyboard theme. And in gtk keyboard theme definition file, each key
31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// binding must be bound to a specific class or object. So existing keyboard
32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// themes only define editor key bindings exactly for GtkEntry and GtkTextView.
33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Then, the only way for us to intercept editor key bindings defined in
34e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// keyboard theme, is to create a GtkEntry or GtkTextView object and call
35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// gtk_bindings_activate_event() against it for the key events. If a key event
36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// matches a predefined key binding, corresponding signal will be emitted.
37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// GtkTextView is used here because it supports more key bindings than GtkEntry,
38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// but in order to minimize the side effect of using a GtkTextView object, a new
39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// class derived from GtkTextView is used, which overrides all signals related
40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// to key bindings, to make sure GtkTextView won't receive them.
41e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch//
42e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// See third_party/WebKit/Source/WebCore/editing/EditorCommand.cpp for detailed
43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// definition of webkit edit commands.
44e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// See webkit/glue/editor_client_impl.cc for key bindings predefined in our
45e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// webkit glue.
46e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass Gtk2KeyBindingsHandler {
47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public:
48e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  Gtk2KeyBindingsHandler();
49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual ~Gtk2KeyBindingsHandler();
50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Matches a key event against predefined gtk key bindings, false will be
52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // returned if the key event doesn't correspond to a predefined key binding.
53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Edit commands matched with |event| will be stored in |edit_commands|, if
54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // non-NULL.
55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  bool MatchEvent(const ui::Event& event,
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                  std::vector<ui::TextEditCommandAuraLinux>* commands);
57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch private:
59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Object structure of Handler class, which is derived from GtkTextView.
60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  struct Handler {
61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    GtkTextView parent_object;
62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    Gtk2KeyBindingsHandler *owner;
63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  };
64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Class structure of Handler class.
66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  struct HandlerClass {
67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    GtkTextViewClass parent_class;
68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  };
69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Creates a new instance of Handler class.
71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  GtkWidget* CreateNewHandler();
72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Adds an edit command to the key event.
74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void EditCommandMatched(ui::TextEditCommandAuraLinux::CommandId id,
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                          const std::string& value,
76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                          bool extend_selection);
77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Builds a fake GdkEventKey from an XEvent.
79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  void BuildGdkEventKeyFromXEvent(const base::NativeEvent& xevent,
80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                  GdkEventKey* gdk_event);
81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Initializes Handler structure.
83e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void HandlerInit(Handler *self);
84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Initializes HandlerClass structure.
86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void HandlerClassInit(HandlerClass *klass);
87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Registeres Handler class to GObject type system and return its type id.
89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static GType HandlerGetType();
90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Gets the Gtk2KeyBindingsHandler object which owns the Handler object.
92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static Gtk2KeyBindingsHandler* GetHandlerOwner(GtkTextView* text_view);
93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "backspace" signal.
95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void BackSpace(GtkTextView* text_view);
96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "copy-clipboard" signal.
98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void CopyClipboard(GtkTextView* text_view);
99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "cut-clipboard" signal.
101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void CutClipboard(GtkTextView* text_view);
102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "delete-from-cursor" signal.
104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void DeleteFromCursor(GtkTextView* text_view, GtkDeleteType type,
105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                               gint count);
106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "insert-at-cursor" signal.
108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void InsertAtCursor(GtkTextView* text_view, const gchar* str);
109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "move-cursor" signal.
111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void MoveCursor(GtkTextView* text_view, GtkMovementStep step,
112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                         gint count, gboolean extend_selection);
113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "move-viewport" signal.
115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void MoveViewport(GtkTextView* text_view, GtkScrollStep step,
116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                           gint count);
117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "paste-clipboard" signal.
119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void PasteClipboard(GtkTextView* text_view);
120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "select-all" signal.
122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void SelectAll(GtkTextView* text_view, gboolean select);
123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "set-anchor" signal.
125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void SetAnchor(GtkTextView* text_view);
126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "toggle-cursor-visible" signal.
128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void ToggleCursorVisible(GtkTextView* text_view);
129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "toggle-overwrite" signal.
131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void ToggleOverwrite(GtkTextView* text_view);
132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "show-help" signal.
134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static gboolean ShowHelp(GtkWidget* widget, GtkWidgetHelpType arg1);
135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Handler of "move-focus" signal.
137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  static void MoveFocus(GtkWidget* widget, GtkDirectionType arg1);
138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  GtkWidget* fake_window_;
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  libgtk2ui::OwnedWidgetGtk handler_;
142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Buffer to store the match results.
144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::vector<ui::TextEditCommandAuraLinux> edit_commands_;
145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Whether the current X server has the XKeyboard extension.
147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  bool has_xkb_;
148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch};
149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}  // namespace libgtk2ui
151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif  // CHROME_BROWSER_UI_LIBGTK2UI_GTK2_KEY_BINDINGS_HANDLER_H_
153