// 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.

#include "ui/gtk/gtk_ui.h"

#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <pango/pango.h>

#include <cmath>
#include <memory>
#include <set>
#include <utility>

#include "base/command_line.h"
#include "base/containers/flat_map.h"
#include "base/debug/leak_annotations.h"
#include "base/environment.h"
#include "base/logging.h"
#include "base/nix/mime_util_xdg.h"
#include "base/nix/xdg_util.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/themes/theme_properties.h"  // nogncheck
#include "printing/buildflags/buildflags.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkShader.h"
#include "ui/base/cursor/cursor_theme_manager_observer.h"
#include "ui/base/ime/linux/fake_input_method_context.h"
#include "ui/base/ime/linux/linux_input_method_context.h"
#include "ui/base/ime/linux/linux_input_method_context_factory.h"
#include "ui/display/display.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_keyboard_layout_manager.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font_render_params.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/skbitmap_operations.h"
#include "ui/gfx/skia_util.h"
#include "ui/gtk/gtk_key_bindings_handler.h"
#include "ui/gtk/gtk_ui_delegate.h"
#include "ui/gtk/gtk_util.h"
#include "ui/gtk/input_method_context_impl_gtk.h"
#include "ui/gtk/native_theme_gtk.h"
#include "ui/gtk/nav_button_provider_gtk.h"
#include "ui/gtk/printing/print_dialog_gtk.h"
#include "ui/gtk/printing/printing_gtk_util.h"
#include "ui/gtk/select_file_dialog_impl.h"
#include "ui/gtk/settings_provider_gtk.h"
#include "ui/native_theme/native_theme.h"
#include "ui/shell_dialogs/select_file_policy.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/button/label_button_border.h"
#include "ui/views/linux_ui/device_scale_factor_observer.h"
#include "ui/views/linux_ui/nav_button_provider.h"
#include "ui/views/linux_ui/window_button_order_observer.h"

#if defined(USE_GIO)
#include "ui/gtk/settings_provider_gsettings.h"
#endif

#if defined(USE_OZONE)
#include "ui/base/ime/input_method.h"
#include "ui/base/ui_base_features.h"
#include "ui/ozone/public/ozone_platform.h"
#endif

#if BUILDFLAG(ENABLE_PRINTING)
#include "printing/printing_context_linux.h"
#endif

namespace gtk {

namespace {

// Stores the GtkUi singleton instance
const GtkUi* g_gtk_ui = nullptr;

const double kDefaultDPI = 96;

class GtkButtonImageSource : public gfx::ImageSkiaSource {
 public:
  GtkButtonImageSource(bool focus,
                       views::Button::ButtonState button_state,
                       gfx::Size size)
      : focus_(focus), width_(size.width()), height_(size.height()) {
    switch (button_state) {
      case views::Button::ButtonState::STATE_NORMAL:
        state_ = ui::NativeTheme::kNormal;
        break;
      case views::Button::ButtonState::STATE_HOVERED:
        state_ = ui::NativeTheme::kHovered;
        break;
      case views::Button::ButtonState::STATE_PRESSED:
        state_ = ui::NativeTheme::kPressed;
        break;
      case views::Button::ButtonState::STATE_DISABLED:
        state_ = ui::NativeTheme::kDisabled;
        break;
      case views::Button::ButtonState::STATE_COUNT:
        NOTREACHED();
        state_ = ui::NativeTheme::kNormal;
        break;
    }
  }

  ~GtkButtonImageSource() override = default;

  gfx::ImageSkiaRep GetImageForScale(float scale) override {
    int width = width_ * scale;
    int height = height_ * scale;

    SkBitmap border;
    border.allocN32Pixels(width, height);
    border.eraseColor(0);

    cairo_surface_t* surface = cairo_image_surface_create_for_data(
        static_cast<unsigned char*>(border.getAddr(0, 0)), CAIRO_FORMAT_ARGB32,
        width, height, width * 4);
    cairo_t* cr = cairo_create(surface);

    ScopedStyleContext context = GetStyleContextFromCss("GtkButton#button");
    GtkStateFlags state_flags = StateToStateFlags(state_);
    if (focus_) {
      state_flags =
          static_cast<GtkStateFlags>(state_flags | GTK_STATE_FLAG_FOCUSED);
    }
    gtk_style_context_set_state(context, state_flags);
    gtk_render_background(context, cr, 0, 0, width, height);
    gtk_render_frame(context, cr, 0, 0, width, height);
    if (focus_) {
      gfx::Rect focus_rect(width, height);

#if !GTK_CHECK_VERSION(3, 90, 0)
      if (!GtkCheckVersion(3, 14)) {
        gint focus_pad;
        gtk_style_context_get_style(context, "focus-padding", &focus_pad,
                                    nullptr);
        focus_rect.Inset(focus_pad, focus_pad);

        if (state_ == ui::NativeTheme::kPressed) {
          gint child_displacement_x, child_displacement_y;
          gboolean displace_focus;
          gtk_style_context_get_style(
              context, "child-displacement-x", &child_displacement_x,
              "child-displacement-y", &child_displacement_y, "displace-focus",
              &displace_focus, nullptr);
          if (displace_focus)
            focus_rect.Offset(child_displacement_x, child_displacement_y);
        }
      }
#endif

      if (!GtkCheckVersion(3, 20)) {
        GtkBorder border;
#if GTK_CHECK_VERSION(3, 90, 0)
        gtk_style_context_get_border(context, &border);
#else
        gtk_style_context_get_border(context, state_flags, &border);
#endif
        focus_rect.Inset(border.left, border.top, border.right, border.bottom);
      }

      gtk_render_focus(context, cr, focus_rect.x(), focus_rect.y(),
                       focus_rect.width(), focus_rect.height());
    }

    cairo_destroy(cr);
    cairo_surface_destroy(surface);

    return gfx::ImageSkiaRep(border, scale);
  }

 private:
  bool focus_;
  ui::NativeTheme::State state_;
  int width_;
  int height_;

  DISALLOW_COPY_AND_ASSIGN(GtkButtonImageSource);
};

class GtkButtonPainter : public views::Painter {
 public:
  GtkButtonPainter(bool focus, views::Button::ButtonState button_state)
      : focus_(focus), button_state_(button_state) {}
  ~GtkButtonPainter() override = default;

  gfx::Size GetMinimumSize() const override { return gfx::Size(); }
  void Paint(gfx::Canvas* canvas, const gfx::Size& size) override {
    gfx::ImageSkia image(
        std::make_unique<GtkButtonImageSource>(focus_, button_state_, size), 1);
    canvas->DrawImageInt(image, 0, 0);
  }

 private:
  const bool focus_;
  const views::Button::ButtonState button_state_;

  DISALLOW_COPY_AND_ASSIGN(GtkButtonPainter);
};

struct GObjectDeleter {
  void operator()(void* ptr) { g_object_unref(ptr); }
};
struct GtkIconInfoDeleter {
  void operator()(GtkIconInfo* ptr) {
#if GTK_CHECK_VERSION(3, 90, 0)
    g_object_unref(ptr);
#else
    G_GNUC_BEGIN_IGNORE_DEPRECATIONS
    gtk_icon_info_free(ptr);
    G_GNUC_END_IGNORE_DEPRECATIONS
#endif
  }
};
typedef std::unique_ptr<GIcon, GObjectDeleter> ScopedGIcon;
typedef std::unique_ptr<GtkIconInfo, GtkIconInfoDeleter> ScopedGtkIconInfo;
typedef std::unique_ptr<GdkPixbuf, GObjectDeleter> ScopedGdkPixbuf;

// Number of app indicators used (used as part of app-indicator id).
int indicators_count;

// The unknown content type.
const char kUnknownContentType[] = "application/octet-stream";

std::unique_ptr<SettingsProvider> CreateSettingsProvider(GtkUi* gtk_ui) {
  if (GtkCheckVersion(3, 14))
    return std::make_unique<SettingsProviderGtk>(gtk_ui);
#if defined(USE_GIO)
  return std::make_unique<SettingsProviderGSettings>(gtk_ui);
#else
  return nullptr;
#endif
}

// Returns a gfx::FontRenderParams corresponding to GTK's configuration.
gfx::FontRenderParams GetGtkFontRenderParams() {
  GtkSettings* gtk_settings = gtk_settings_get_default();
  CHECK(gtk_settings);
  gint antialias = 0;
  gint hinting = 0;
  gchar* hint_style = nullptr;
  gchar* rgba = nullptr;
  g_object_get(gtk_settings, "gtk-xft-antialias", &antialias, "gtk-xft-hinting",
               &hinting, "gtk-xft-hintstyle", &hint_style, "gtk-xft-rgba",
               &rgba, nullptr);

  gfx::FontRenderParams params;
  params.antialiasing = antialias != 0;

  if (hinting == 0 || !hint_style || strcmp(hint_style, "hintnone") == 0) {
    params.hinting = gfx::FontRenderParams::HINTING_NONE;
  } else if (strcmp(hint_style, "hintslight") == 0) {
    params.hinting = gfx::FontRenderParams::HINTING_SLIGHT;
  } else if (strcmp(hint_style, "hintmedium") == 0) {
    params.hinting = gfx::FontRenderParams::HINTING_MEDIUM;
  } else if (strcmp(hint_style, "hintfull") == 0) {
    params.hinting = gfx::FontRenderParams::HINTING_FULL;
  } else {
    LOG(WARNING) << "Unexpected gtk-xft-hintstyle \"" << hint_style << "\"";
    params.hinting = gfx::FontRenderParams::HINTING_NONE;
  }

  if (!rgba || strcmp(rgba, "none") == 0) {
    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE;
  } else if (strcmp(rgba, "rgb") == 0) {
    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_RGB;
  } else if (strcmp(rgba, "bgr") == 0) {
    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_BGR;
  } else if (strcmp(rgba, "vrgb") == 0) {
    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_VRGB;
  } else if (strcmp(rgba, "vbgr") == 0) {
    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_VBGR;
  } else {
    LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\"";
    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE;
  }

  g_free(hint_style);
  g_free(rgba);

  return params;
}

views::LinuxUI::WindowFrameAction GetDefaultMiddleClickAction() {
  if (GtkCheckVersion(3, 14))
    return views::LinuxUI::WindowFrameAction::kNone;
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  switch (base::nix::GetDesktopEnvironment(env.get())) {
    case base::nix::DESKTOP_ENVIRONMENT_KDE4:
    case base::nix::DESKTOP_ENVIRONMENT_KDE5:
      // Starting with KDE 4.4, windows' titlebars can be dragged with the
      // middle mouse button to create tab groups. We don't support that in
      // Chrome, but at least avoid lowering windows in response to middle
      // clicks to avoid surprising users who expect the KDE behavior.
      return views::LinuxUI::WindowFrameAction::kNone;
    default:
      return views::LinuxUI::WindowFrameAction::kLower;
  }
}

const SkBitmap GdkPixbufToSkBitmap(GdkPixbuf* pixbuf) {
  // TODO(erg): What do we do in the case where the pixbuf fails these dchecks?
  // I would prefer to use our gtk based canvas, but that would require
  // recompiling half of our skia extensions with gtk support, which we can't
  // do in this build.
  DCHECK_EQ(GDK_COLORSPACE_RGB, gdk_pixbuf_get_colorspace(pixbuf));

  int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
  int w = gdk_pixbuf_get_width(pixbuf);
  int h = gdk_pixbuf_get_height(pixbuf);

  SkBitmap ret;
  ret.allocN32Pixels(w, h);
  ret.eraseColor(0);

  uint32_t* skia_data = static_cast<uint32_t*>(ret.getAddr(0, 0));

  if (n_channels == 4) {
    int total_length = w * h;
    guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf);

    // Now here's the trick: we need to convert the gdk data (which is RGBA and
    // isn't premultiplied) to skia (which can be anything and premultiplied).
    for (int i = 0; i < total_length; ++i, gdk_pixels += 4) {
      const unsigned char& red = gdk_pixels[0];
      const unsigned char& green = gdk_pixels[1];
      const unsigned char& blue = gdk_pixels[2];
      const unsigned char& alpha = gdk_pixels[3];

      skia_data[i] = SkPreMultiplyARGB(alpha, red, green, blue);
    }
  } else if (n_channels == 3) {
    // Because GDK makes rowstrides word aligned, we need to do something a bit
    // more complex when a pixel isn't perfectly a word of memory.
    int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
    guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf);
    for (int y = 0; y < h; ++y) {
      int row = y * rowstride;

      for (int x = 0; x < w; ++x) {
        guchar* pixel = gdk_pixels + row + (x * 3);
        const unsigned char& red = pixel[0];
        const unsigned char& green = pixel[1];
        const unsigned char& blue = pixel[2];

        skia_data[y * w + x] = SkPreMultiplyARGB(255, red, green, blue);
      }
    }
  } else {
    NOTREACHED();
  }

  return ret;
}

}  // namespace

GtkUi::GtkUi(ui::GtkUiDelegate* delegate) : delegate_(delegate) {
  using Action = views::LinuxUI::WindowFrameAction;
  using ActionSource = views::LinuxUI::WindowFrameActionSource;

  DCHECK(delegate_);
  DCHECK(!g_gtk_ui);
  g_gtk_ui = this;

  window_frame_actions_ = {
      {ActionSource::kDoubleClick, Action::kToggleMaximize},
      {ActionSource::kMiddleClick, GetDefaultMiddleClickAction()},
      {ActionSource::kRightClick, Action::kMenu}};

  // Avoid GTK initializing atk-bridge, and let AuraLinux implementation
  // do it once it is ready.
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  env->SetVar("NO_AT_BRIDGE", "1");
  GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
  native_theme_ = NativeThemeGtk::instance();
  fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_widget_realize(fake_window_);
}

GtkUi::~GtkUi() {
  gtk_widget_destroy(fake_window_);
  g_gtk_ui = nullptr;
}

ui::GtkUiDelegate* GtkUi::GetDelegate() {
  DCHECK(g_gtk_ui) << "GtkUi instance is not set.";
  return g_gtk_ui->delegate_;
}

void GtkUi::Initialize() {
#if defined(USE_OZONE)
  // Linux ozone platforms may want to set LinuxInputMethodContextFactory
  // instance instead of using GtkUi context factory. This step is made upon
  // CreateInputMethod call. If the factory is not set, use the GtkUi context
  // factory.
  if (!features::IsUsingOzonePlatform() ||
      !ui::OzonePlatform::GetInstance()->CreateInputMethod(
          nullptr, gfx::kNullAcceleratedWidget)) {
    if (!ui::LinuxInputMethodContextFactory::instance())
      ui::LinuxInputMethodContextFactory::SetInstance(this);
  }
#endif

  GtkSettings* settings = gtk_settings_get_default();
  g_signal_connect_after(settings, "notify::gtk-theme-name",
                         G_CALLBACK(OnThemeChangedThunk), this);
  g_signal_connect_after(settings, "notify::gtk-icon-theme-name",
                         G_CALLBACK(OnThemeChangedThunk), this);
  g_signal_connect_after(settings, "notify::gtk-application-prefer-dark-theme",
                         G_CALLBACK(OnThemeChangedThunk), this);
  g_signal_connect_after(settings, "notify::gtk-cursor-theme-name",
                         G_CALLBACK(OnCursorThemeNameChangedThunk), this);
  g_signal_connect_after(settings, "notify::gtk-cursor-theme-size",
                         G_CALLBACK(OnCursorThemeSizeChangedThunk), this);

  GdkScreen* screen = gdk_screen_get_default();
  // Listen for DPI changes.
  g_signal_connect_after(screen, "notify::resolution",
                         G_CALLBACK(OnDeviceScaleFactorMaybeChangedThunk),
                         this);
  // Listen for scale factor changes.  We would prefer to listen on
  // |screen|, but there is no scale-factor property, so use an
  // unmapped window instead.
  g_signal_connect(fake_window_, "notify::scale-factor",
                   G_CALLBACK(OnDeviceScaleFactorMaybeChangedThunk), this);

  LoadGtkValues();

#if BUILDFLAG(ENABLE_PRINTING)
  printing::PrintingContextLinux::SetCreatePrintDialogFunction(
      &PrintDialogGtk::CreatePrintDialog);
  printing::PrintingContextLinux::SetPdfPaperSizeFunction(
      &GetPdfPaperSizeDeviceUnitsGtk);
#endif

  // We must build this after GTK gets initialized.
  settings_provider_ = CreateSettingsProvider(this);

  indicators_count = 0;

  GetDelegate()->OnInitialized();
}

bool GtkUi::GetTint(int id, color_utils::HSL* tint) const {
  switch (id) {
    // Tints for which the cross-platform default is fine. Before adding new
    // values here, specifically verify they work well on Linux.
    case ThemeProperties::TINT_BACKGROUND_TAB:
    // TODO(estade): Return something useful for TINT_BUTTONS so that chrome://
    // page icons are colored appropriately.
    case ThemeProperties::TINT_BUTTONS:
      break;
    default:
      // Assume any tints not specifically verified on Linux aren't usable.
      // TODO(pkasting): Try to remove values from |colors_| that could just be
      // added to the group above instead.
      NOTREACHED();
  }
  return false;
}

bool GtkUi::GetColor(int id, SkColor* color, bool use_custom_frame) const {
  for (const ColorMap& color_map :
       {colors_,
        use_custom_frame ? custom_frame_colors_ : native_frame_colors_}) {
    auto it = color_map.find(id);
    if (it != color_map.end()) {
      *color = it->second;
      return true;
    }
  }

  return false;
}

bool GtkUi::GetDisplayProperty(int id, int* result) const {
  if (id == ThemeProperties::SHOULD_FILL_BACKGROUND_TAB_COLOR) {
    *result = 0;
    return true;
  }
  return false;
}

SkColor GtkUi::GetFocusRingColor() const {
  return focus_ring_color_;
}

SkColor GtkUi::GetActiveSelectionBgColor() const {
  return active_selection_bg_color_;
}

SkColor GtkUi::GetActiveSelectionFgColor() const {
  return active_selection_fg_color_;
}

SkColor GtkUi::GetInactiveSelectionBgColor() const {
  return inactive_selection_bg_color_;
}

SkColor GtkUi::GetInactiveSelectionFgColor() const {
  return inactive_selection_fg_color_;
}

base::TimeDelta GtkUi::GetCursorBlinkInterval() const {
  // From http://library.gnome.org/devel/gtk/unstable/GtkSettings.html, this is
  // the default value for gtk-cursor-blink-time.
  static const gint kGtkDefaultCursorBlinkTime = 1200;

  // Dividing GTK's cursor blink cycle time (in milliseconds) by this value
  // yields an appropriate value for
  // blink::RendererPreferences::caret_blink_interval.
  static const double kGtkCursorBlinkCycleFactor = 2000.0;

  gint cursor_blink_time = kGtkDefaultCursorBlinkTime;
  gboolean cursor_blink = TRUE;
  g_object_get(gtk_settings_get_default(), "gtk-cursor-blink-time",
               &cursor_blink_time, "gtk-cursor-blink", &cursor_blink, nullptr);
  return cursor_blink ? base::TimeDelta::FromSecondsD(
                            cursor_blink_time / kGtkCursorBlinkCycleFactor)
                      : base::TimeDelta();
}

ui::NativeTheme* GtkUi::GetNativeTheme(aura::Window* window) const {
  return (use_system_theme_callback_.is_null() ||
          use_system_theme_callback_.Run(window))
             ? native_theme_
             : ui::NativeTheme::GetInstanceForNativeUi();
}

void GtkUi::SetUseSystemThemeCallback(UseSystemThemeCallback callback) {
  use_system_theme_callback_ = std::move(callback);
}

bool GtkUi::GetDefaultUsesSystemTheme() const {
  std::unique_ptr<base::Environment> env(base::Environment::Create());

  switch (base::nix::GetDesktopEnvironment(env.get())) {
    case base::nix::DESKTOP_ENVIRONMENT_CINNAMON:
    case base::nix::DESKTOP_ENVIRONMENT_GNOME:
    case base::nix::DESKTOP_ENVIRONMENT_PANTHEON:
    case base::nix::DESKTOP_ENVIRONMENT_UNITY:
    case base::nix::DESKTOP_ENVIRONMENT_XFCE:
      return true;
    case base::nix::DESKTOP_ENVIRONMENT_KDE3:
    case base::nix::DESKTOP_ENVIRONMENT_KDE4:
    case base::nix::DESKTOP_ENVIRONMENT_KDE5:
    case base::nix::DESKTOP_ENVIRONMENT_OTHER:
      return false;
  }
  // Unless GetDesktopEnvironment() badly misbehaves, this should never happen.
  NOTREACHED();
  return false;
}

gfx::Image GtkUi::GetIconForContentType(const std::string& content_type,
                                        int size) const {
  // This call doesn't take a reference.
  GtkIconTheme* theme = gtk_icon_theme_get_default();

  std::string content_types[] = {content_type, kUnknownContentType};

  for (size_t i = 0; i < base::size(content_types); ++i) {
    ScopedGIcon icon(g_content_type_get_icon(content_types[i].c_str()));
    ScopedGtkIconInfo icon_info(gtk_icon_theme_lookup_by_gicon(
        theme, icon.get(), size,
        static_cast<GtkIconLookupFlags>(GTK_ICON_LOOKUP_FORCE_SIZE)));
    if (!icon_info)
      continue;
    ScopedGdkPixbuf pixbuf(gtk_icon_info_load_icon(icon_info.get(), nullptr));
    if (!pixbuf)
      continue;

    SkBitmap bitmap = GdkPixbufToSkBitmap(pixbuf.get());
    DCHECK_EQ(size, bitmap.width());
    DCHECK_EQ(size, bitmap.height());
    gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
    image_skia.MakeThreadSafe();
    return gfx::Image(image_skia);
  }
  return gfx::Image();
}

std::unique_ptr<views::Border> GtkUi::CreateNativeBorder(
    views::LabelButton* owning_button,
    std::unique_ptr<views::LabelButtonBorder> border) {
  if (owning_button->GetNativeTheme() != native_theme_)
    return std::move(border);

  auto gtk_border = std::make_unique<views::LabelButtonAssetBorder>();

  gtk_border->set_insets(border->GetInsets());

  constexpr bool kFocus = true;

  static struct {
    bool focus;
    views::Button::ButtonState state;
  } const paintstate[] = {
      {!kFocus, views::Button::STATE_NORMAL},
      {!kFocus, views::Button::STATE_HOVERED},
      {!kFocus, views::Button::STATE_PRESSED},
      {!kFocus, views::Button::STATE_DISABLED},
      {kFocus, views::Button::STATE_NORMAL},
      {kFocus, views::Button::STATE_HOVERED},
      {kFocus, views::Button::STATE_PRESSED},
      {kFocus, views::Button::STATE_DISABLED},
  };

  for (unsigned i = 0; i < base::size(paintstate); i++) {
    gtk_border->SetPainter(
        paintstate[i].focus, paintstate[i].state,
        border->PaintsButtonState(paintstate[i].focus, paintstate[i].state)
            ? std::make_unique<GtkButtonPainter>(paintstate[i].focus,
                                                 paintstate[i].state)
            : nullptr);
  }

  return std::move(gtk_border);
}

void GtkUi::AddWindowButtonOrderObserver(
    views::WindowButtonOrderObserver* observer) {
  if (nav_buttons_set_)
    observer->OnWindowButtonOrderingChange(leading_buttons_, trailing_buttons_);

  window_button_order_observer_list_.AddObserver(observer);
}

void GtkUi::RemoveWindowButtonOrderObserver(
    views::WindowButtonOrderObserver* observer) {
  window_button_order_observer_list_.RemoveObserver(observer);
}

void GtkUi::SetWindowButtonOrdering(
    const std::vector<views::FrameButton>& leading_buttons,
    const std::vector<views::FrameButton>& trailing_buttons) {
  leading_buttons_ = leading_buttons;
  trailing_buttons_ = trailing_buttons;
  nav_buttons_set_ = true;

  for (views::WindowButtonOrderObserver& observer :
       window_button_order_observer_list_) {
    observer.OnWindowButtonOrderingChange(leading_buttons_, trailing_buttons_);
  }
}

void GtkUi::SetWindowFrameAction(WindowFrameActionSource source,
                                 WindowFrameAction action) {
  window_frame_actions_[source] = action;
}

std::unique_ptr<ui::LinuxInputMethodContext> GtkUi::CreateInputMethodContext(
    ui::LinuxInputMethodContextDelegate* delegate,
    bool is_simple) const {
  return std::make_unique<InputMethodContextImplGtk>(delegate, is_simple);
}

gfx::FontRenderParams GtkUi::GetDefaultFontRenderParams() const {
  static gfx::FontRenderParams params = GetGtkFontRenderParams();
  return params;
}

void GtkUi::GetDefaultFontDescription(std::string* family_out,
                                      int* size_pixels_out,
                                      int* style_out,
                                      gfx::Font::Weight* weight_out,
                                      gfx::FontRenderParams* params_out) const {
  *family_out = default_font_family_;
  *size_pixels_out = default_font_size_pixels_;
  *style_out = default_font_style_;
  *weight_out = default_font_weight_;
  *params_out = default_font_render_params_;
}

ui::SelectFileDialog* GtkUi::CreateSelectFileDialog(
    ui::SelectFileDialog::Listener* listener,
    std::unique_ptr<ui::SelectFilePolicy> policy) const {
  return SelectFileDialogImpl::Create(listener, std::move(policy));
}

views::LinuxUI::WindowFrameAction GtkUi::GetWindowFrameAction(
    WindowFrameActionSource source) {
  return window_frame_actions_[source];
}

void GtkUi::NotifyWindowManagerStartupComplete() {
  // TODO(port) Implement this using _NET_STARTUP_INFO_BEGIN/_NET_STARTUP_INFO
  // from http://standards.freedesktop.org/startup-notification-spec/ instead.
  gdk_notify_startup_complete();
}

void GtkUi::AddDeviceScaleFactorObserver(
    views::DeviceScaleFactorObserver* observer) {
  device_scale_factor_observer_list_.AddObserver(observer);
}

void GtkUi::RemoveDeviceScaleFactorObserver(
    views::DeviceScaleFactorObserver* observer) {
  device_scale_factor_observer_list_.RemoveObserver(observer);
}

bool GtkUi::PreferDarkTheme() const {
  gboolean dark = false;
  g_object_get(gtk_settings_get_default(), "gtk-application-prefer-dark-theme",
               &dark, nullptr);
  return dark;
}

bool GtkUi::AnimationsEnabled() const {
  gboolean animations_enabled = false;
  g_object_get(gtk_settings_get_default(), "gtk-enable-animations",
               &animations_enabled, nullptr);
  return animations_enabled;
}

std::unique_ptr<views::NavButtonProvider> GtkUi::CreateNavButtonProvider() {
  if (GtkCheckVersion(3, 14))
    return std::make_unique<gtk::NavButtonProviderGtk>();
  return nullptr;
}

// Mapping from GDK dead keys to corresponding printable character.
static struct {
  guint gdk_key;
  guint16 unicode;
} kDeadKeyMapping[] = {
    {GDK_KEY_dead_grave, 0x0060},      {GDK_KEY_dead_acute, 0x0027},
    {GDK_KEY_dead_circumflex, 0x005e}, {GDK_KEY_dead_tilde, 0x007e},
    {GDK_KEY_dead_diaeresis, 0x00a8},
};

base::flat_map<std::string, std::string> GtkUi::GetKeyboardLayoutMap() {
  GdkDisplay* display = gdk_display_get_default();
  GdkKeymap* keymap = gdk_keymap_get_for_display(display);
  if (!keymap)
    return {};

  ui::DomKeyboardLayoutManager* layouts = new ui::DomKeyboardLayoutManager();
  auto map = base::flat_map<std::string, std::string>();

  for (unsigned int i_domcode = 0;
       i_domcode < ui::kWritingSystemKeyDomCodeEntries; ++i_domcode) {
    ui::DomCode domcode = ui::writing_system_key_domcodes[i_domcode];
    guint16 keycode = ui::KeycodeConverter::DomCodeToNativeKeycode(domcode);
    GdkKeymapKey* keys = nullptr;
    guint* keyvals = nullptr;
    gint n_entries = 0;

    // The order of the layouts is based on the system default ordering in
    // Keyboard Settings. The currently active layout does not affect this
    // order.
    if (gdk_keymap_get_entries_for_keycode(keymap, keycode, &keys, &keyvals,
                                           &n_entries)) {
      for (gint i = 0; i < n_entries; ++i) {
        // There are 4 entries per layout group, one each for shift level 0..3.
        // We only care about the unshifted values (level = 0).
        if (keys[i].level == 0) {
          uint16_t unicode = gdk_keyval_to_unicode(keyvals[i]);
          if (unicode == 0) {
            for (unsigned int i_dead = 0; i_dead < base::size(kDeadKeyMapping);
                 ++i_dead) {
              if (keyvals[i] == kDeadKeyMapping[i_dead].gdk_key)
                unicode = kDeadKeyMapping[i_dead].unicode;
            }
          }
          if (unicode != 0)
            layouts->GetLayout(keys[i].group)->AddKeyMapping(domcode, unicode);
        }
      }
    }
    g_free(keys);
    keys = nullptr;
    g_free(keyvals);
    keyvals = nullptr;
  }
  return layouts->GetFirstAsciiCapableLayout()->GetMap();
}

std::string GtkUi::GetCursorThemeName() {
  gchar* theme = nullptr;
  g_object_get(gtk_settings_get_default(), "gtk-cursor-theme-name", &theme,
               nullptr);
  std::string theme_string;
  if (theme) {
    theme_string = theme;
    g_free(theme);
  }
  return theme_string;
}

int GtkUi::GetCursorThemeSize() {
  gint size = 0;
  g_object_get(gtk_settings_get_default(), "gtk-cursor-theme-size", &size,
               nullptr);
  return size;
}

bool GtkUi::MatchEvent(const ui::Event& event,
                       std::vector<ui::TextEditCommandAuraLinux>* commands) {
  // TODO(crbug.com/963419): Use delegate's |GetGdkKeymap| here to
  // determine if GtkUi's key binding handling implementation is used or not.
  // Ozone/Wayland was unintentionally using GtkUi for keybinding handling, so
  // early out here, for now, until a proper solution for ozone is implemented.
  if (!GetDelegate()->GetGdkKeymap())
    return false;

  // Ensure that we have a keyboard handler.
  if (!key_bindings_handler_)
    key_bindings_handler_ = std::make_unique<GtkKeyBindingsHandler>();

  return key_bindings_handler_->MatchEvent(event, commands);
}

void GtkUi::OnThemeChanged(GtkSettings* settings, GtkParamSpec* param) {
  colors_.clear();
  custom_frame_colors_.clear();
  native_frame_colors_.clear();
  native_theme_->OnThemeChanged(settings, param);
  LoadGtkValues();
  native_theme_->NotifyObservers();
}

void GtkUi::OnCursorThemeNameChanged(GtkSettings* settings,
                                     GtkParamSpec* param) {
  std::string cursor_theme_name = GetCursorThemeName();
  if (cursor_theme_name.empty())
    return;
  for (auto& observer : cursor_theme_observers())
    observer.OnCursorThemeNameChanged(cursor_theme_name);
}

void GtkUi::OnCursorThemeSizeChanged(GtkSettings* settings,
                                     GtkParamSpec* param) {
  int cursor_theme_size = GetCursorThemeSize();
  if (!cursor_theme_size)
    return;
  for (auto& observer : cursor_theme_observers())
    observer.OnCursorThemeSizeChanged(cursor_theme_size);
}

void GtkUi::OnDeviceScaleFactorMaybeChanged(void*, GParamSpec*) {
  UpdateDeviceScaleFactor();
}

void GtkUi::LoadGtkValues() {
  // TODO(thomasanderson): GtkThemeService had a comment here about having to
  // muck with the raw Prefs object to remove prefs::kCurrentThemeImages or else
  // we'd regress startup time. Figure out how to do that when we can't access
  // the prefs system from here.
  UpdateDeviceScaleFactor();
  UpdateColors();
}

void GtkUi::UpdateColors() {
  SkColor location_bar_border = GetBorderColor("GtkEntry#entry");
  if (SkColorGetA(location_bar_border))
    colors_[ThemeProperties::COLOR_LOCATION_BAR_BORDER] = location_bar_border;

  inactive_selection_bg_color_ = GetSelectionBgColor(
      GtkCheckVersion(3, 20) ? "GtkTextView#textview.view:backdrop "
                               "#text:backdrop #selection:backdrop"
                             : "GtkTextView.view:selected:backdrop");
  inactive_selection_fg_color_ =
      GetFgColor(GtkCheckVersion(3, 20) ? "GtkTextView#textview.view:backdrop "
                                          "#text:backdrop #selection:backdrop"
                                        : "GtkTextView.view:selected:backdrop");

  SkColor tab_border = GetBorderColor("GtkButton#button");
  // Separates the toolbar from the bookmark bar or butter bars.
  colors_[ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR] = tab_border;
  // Separates entries in the downloads bar.
  colors_[ThemeProperties::COLOR_TOOLBAR_VERTICAL_SEPARATOR] = tab_border;

  colors_[ThemeProperties::COLOR_NTP_BACKGROUND] =
      native_theme_->GetSystemColor(
          ui::NativeTheme::kColorId_TextfieldDefaultBackground);
  colors_[ThemeProperties::COLOR_NTP_TEXT] = native_theme_->GetSystemColor(
      ui::NativeTheme::kColorId_TextfieldDefaultColor);
  colors_[ThemeProperties::COLOR_NTP_HEADER] =
      GetBorderColor("GtkButton#button");

  SkColor tab_text_color = GetFgColor("GtkLabel");
  colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON] = tab_text_color;
  colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_HOVERED] = tab_text_color;
  colors_[ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON_PRESSED] = tab_text_color;
  colors_[ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE] =
      tab_text_color;
  colors_[ThemeProperties::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE] =
      tab_text_color;
  colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = tab_text_color;

  colors_[ThemeProperties::COLOR_NTP_LINK] = native_theme_->GetSystemColor(
      ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused);

  // Generate the colors that we pass to Blink.
  focus_ring_color_ = native_theme_->GetSystemColor(
      ui::NativeTheme::kColorId_FocusedBorderColor);

  // Some GTK themes only define the text selection colors on the GtkEntry
  // class, so we need to use that for getting selection colors.
  active_selection_bg_color_ = native_theme_->GetSystemColor(
      ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused);
  active_selection_fg_color_ = native_theme_->GetSystemColor(
      ui::NativeTheme::kColorId_TextfieldSelectionColor);

  colors_[ThemeProperties::COLOR_TAB_THROBBER_SPINNING] =
      native_theme_->GetSystemColor(
          ui::NativeTheme::kColorId_ThrobberSpinningColor);
  colors_[ThemeProperties::COLOR_TAB_THROBBER_WAITING] =
      native_theme_->GetSystemColor(
          ui::NativeTheme::kColorId_ThrobberWaitingColor);

  // Generate colors that depend on whether or not a custom window frame is
  // used.  These colors belong in |color_map| below, not |colors_|.
  for (bool custom_frame : {false, true}) {
    ColorMap& color_map =
        custom_frame ? custom_frame_colors_ : native_frame_colors_;
    const std::string header_selector =
        custom_frame ? "#headerbar.header-bar.titlebar" : "GtkMenuBar#menubar";
    const std::string header_selector_inactive = header_selector + ":backdrop";
    const SkColor frame_color =
        SkColorSetA(GetBgColor(header_selector), SK_AlphaOPAQUE);
    const SkColor frame_color_incognito =
        color_utils::HSLShift(frame_color, kDefaultTintFrameIncognito);
    const SkColor frame_color_inactive =
        SkColorSetA(GetBgColor(header_selector_inactive), SK_AlphaOPAQUE);
    const SkColor frame_color_incognito_inactive =
        color_utils::HSLShift(frame_color_inactive, kDefaultTintFrameIncognito);

    color_map[ThemeProperties::COLOR_FRAME_ACTIVE] = frame_color;
    color_map[ThemeProperties::COLOR_FRAME_INACTIVE] = frame_color_inactive;
    color_map[ThemeProperties::COLOR_FRAME_ACTIVE_INCOGNITO] =
        frame_color_incognito;
    color_map[ThemeProperties::COLOR_FRAME_INACTIVE_INCOGNITO] =
        frame_color_incognito_inactive;

    // Compose the window color on the frame color to ensure the resulting tab
    // color is opaque.
    SkColor tab_color =
        color_utils::GetResultingPaintColor(GetBgColor(""), frame_color);

    color_map[ThemeProperties::COLOR_TOOLBAR] = tab_color;
    color_map[ThemeProperties::COLOR_DOWNLOAD_SHELF] = tab_color;
    color_map[ThemeProperties::COLOR_INFOBAR] = tab_color;
    color_map[ThemeProperties::COLOR_STATUS_BUBBLE] = tab_color;
    color_map[ThemeProperties::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_ACTIVE] =
        tab_color;
    color_map[ThemeProperties::COLOR_TAB_BACKGROUND_ACTIVE_FRAME_INACTIVE] =
        tab_color;

    const SkColor background_tab_text_color =
        GetFgColor(header_selector + " GtkLabel.title");
    const SkColor background_tab_text_color_inactive =
        GetFgColor(header_selector_inactive + " GtkLabel.title");

    color_map[ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE] =
        background_tab_text_color;
    color_map[ThemeProperties::
                  COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO] =
        color_utils::BlendForMinContrast(
            color_utils::HSLShift(background_tab_text_color,
                                  kDefaultTintFrameIncognito),
            frame_color_incognito)
            .color;
    color_map[ThemeProperties::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE] =
        background_tab_text_color_inactive;
    color_map[ThemeProperties::
                  COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO] =
        color_utils::BlendForMinContrast(
            color_utils::HSLShift(background_tab_text_color_inactive,
                                  kDefaultTintFrameIncognito),
            frame_color_incognito_inactive)
            .color;

    color_map[ThemeProperties::COLOR_OMNIBOX_TEXT] =
        native_theme_->GetSystemColor(
            ui::NativeTheme::kColorId_TextfieldDefaultColor);
    color_map[ThemeProperties::COLOR_OMNIBOX_BACKGROUND] =
        native_theme_->GetSystemColor(
            ui::NativeTheme::kColorId_TextfieldDefaultBackground);

    // These colors represent the border drawn around tabs and between
    // the tabstrip and toolbar.
    SkColor toolbar_top_separator = GetBorderColor(
        header_selector + " GtkSeparator#separator.vertical.titlebutton");
    SkColor toolbar_top_separator_inactive =
        GetBorderColor(header_selector +
                       ":backdrop GtkSeparator#separator.vertical.titlebutton");

    auto toolbar_top_separator_has_good_contrast = [&]() {
      // This constant is copied from chrome/browser/themes/theme_service.cc.
      const float kMinContrastRatio = 2.f;

      SkColor active = color_utils::GetResultingPaintColor(
          toolbar_top_separator, frame_color);
      SkColor inactive = color_utils::GetResultingPaintColor(
          toolbar_top_separator_inactive, frame_color_inactive);
      return color_utils::GetContrastRatio(frame_color, active) >=
                 kMinContrastRatio &&
             color_utils::GetContrastRatio(frame_color_inactive, inactive) >=
                 kMinContrastRatio;
    };

    if (!toolbar_top_separator_has_good_contrast()) {
      toolbar_top_separator =
          GetBorderColor(header_selector + " GtkButton#button");
      toolbar_top_separator_inactive =
          GetBorderColor(header_selector + ":backdrop GtkButton#button");
    }

    // If we can't get a contrasting stroke from the theme, have ThemeService
    // provide a stroke color for us.
    if (toolbar_top_separator_has_good_contrast()) {
      color_map[ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR] =
          toolbar_top_separator;
      color_map[ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR_INACTIVE] =
          toolbar_top_separator_inactive;
    }
  }
}

void GtkUi::UpdateDefaultFont() {
  gfx::SetFontRenderParamsDeviceScaleFactor(device_scale_factor_);

  GtkWidget* fake_label = gtk_label_new(nullptr);
  g_object_ref_sink(fake_label);  // Remove the floating reference.
  PangoContext* pc = gtk_widget_get_pango_context(fake_label);
  const PangoFontDescription* desc = pango_context_get_font_description(pc);

  // Use gfx::FontRenderParams to select a family and determine the rendering
  // settings.
  gfx::FontRenderParamsQuery query;
  query.families =
      base::SplitString(pango_font_description_get_family(desc), ",",
                        base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  if (pango_font_description_get_size_is_absolute(desc)) {
    // If the size is absolute, it's specified in Pango units. There are
    // PANGO_SCALE Pango units in a device unit (pixel).
    const int size_pixels = pango_font_description_get_size(desc) / PANGO_SCALE;
    default_font_size_pixels_ = size_pixels;
    query.pixel_size = size_pixels;
  } else {
    // Non-absolute sizes are in points (again scaled by PANGO_SIZE).
    // Round the value when converting to pixels to match GTK's logic.
    const double size_points = pango_font_description_get_size(desc) /
                               static_cast<double>(PANGO_SCALE);
    default_font_size_pixels_ =
        static_cast<int>(kDefaultDPI / 72.0 * size_points + 0.5);
    query.point_size = static_cast<int>(size_points);
  }

  query.style = gfx::Font::NORMAL;
  query.weight =
      static_cast<gfx::Font::Weight>(pango_font_description_get_weight(desc));
  // TODO(davemoore): What about PANGO_STYLE_OBLIQUE?
  if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC)
    query.style |= gfx::Font::ITALIC;

  default_font_render_params_ =
      gfx::GetFontRenderParams(query, &default_font_family_);
  default_font_style_ = query.style;

  gtk_widget_destroy(fake_label);
  g_object_unref(fake_label);
}

float GtkUi::GetRawDeviceScaleFactor() {
  if (display::Display::HasForceDeviceScaleFactor())
    return display::Display::GetForcedDeviceScaleFactor();

  GdkScreen* screen = gdk_screen_get_default();
  float scale = gtk_widget_get_scale_factor(fake_window_);
  DCHECK_GT(scale, 0.0);

  gdouble resolution = gdk_screen_get_resolution(screen);
  // TODO(https://crbug.com/1033552): Remove this hack once the Trusty bots are
  // fixed to have a resolution of 96, or when the Trusty bots are removed
  // altogether.
  if (std::abs(resolution - 95.8486) < 0.001)
    resolution = 96;
  if (resolution > 0)
    scale *= resolution / kDefaultDPI;

  return scale;
}

void GtkUi::UpdateDeviceScaleFactor() {
  float old_device_scale_factor = device_scale_factor_;
  device_scale_factor_ = GetRawDeviceScaleFactor();
  if (device_scale_factor_ != old_device_scale_factor) {
    for (views::DeviceScaleFactorObserver& observer :
         device_scale_factor_observer_list_) {
      observer.OnDeviceScaleFactorChanged();
    }
  }
  UpdateDefaultFont();
}

float GtkUi::GetDeviceScaleFactor() const {
  return device_scale_factor_;
}

}  // namespace gtk

views::LinuxUI* BuildGtkUi(ui::GtkUiDelegate* delegate) {
  return new gtk::GtkUi(delegate);
}
