// Copyright (c) 2015 The Chromium Embedded Framework 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 "tests/cefclient/browser/browser_window_osr_gtk.h"

#include <GL/gl.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>

#define XK_3270  // for XK_3270_BackTab
#include <X11/XF86keysym.h>
#include <X11/Xcursor/Xcursor.h>
#include <X11/extensions/XInput2.h>
#include <X11/keysym.h>

#include "include/base/cef_logging.h"
#include "include/base/cef_macros.h"
#include "include/wrapper/cef_closure_task.h"
#include "tests/cefclient/browser/util_gtk.h"
#include "tests/shared/browser/geometry_util.h"
#include "tests/shared/browser/main_message_loop.h"

namespace client {

namespace {

// Major opcode of XInputExtension, or -1 if XInput 2.2 is not available.
int g_xinput_extension = -1;

// Static BrowserWindowOsrGtk::EventFilter needs to forward touch events
// to correct browser, so we maintain a vector of all windows.
std::vector<BrowserWindowOsrGtk*> g_browser_windows;

bool IsTouchAvailable() {
  return g_xinput_extension != -1;
}

int GetCefStateModifiers(guint state) {
  int modifiers = 0;
  if (state & GDK_SHIFT_MASK)
    modifiers |= EVENTFLAG_SHIFT_DOWN;
  if (state & GDK_LOCK_MASK)
    modifiers |= EVENTFLAG_CAPS_LOCK_ON;
  if (state & GDK_CONTROL_MASK)
    modifiers |= EVENTFLAG_CONTROL_DOWN;
  if (state & GDK_MOD1_MASK)
    modifiers |= EVENTFLAG_ALT_DOWN;
  if (state & GDK_BUTTON1_MASK)
    modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON;
  if (state & GDK_BUTTON2_MASK)
    modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON;
  if (state & GDK_BUTTON3_MASK)
    modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON;
  return modifiers;
}

int GetCefStateModifiers(XIModifierState mods, XIButtonState buttons) {
  guint state = mods.effective;
  if (buttons.mask_len >= 1) {
    if (XIMaskIsSet(buttons.mask, 1))
      state |= GDK_BUTTON1_MASK;
    if (XIMaskIsSet(buttons.mask, 2))
      state |= GDK_BUTTON2_MASK;
    if (XIMaskIsSet(buttons.mask, 3))
      state |= GDK_BUTTON3_MASK;
  }

  return GetCefStateModifiers(state);
}

// From ui/events/keycodes/keyboard_codes_posix.h.
enum KeyboardCode {
  VKEY_BACK = 0x08,
  VKEY_TAB = 0x09,
  VKEY_BACKTAB = 0x0A,
  VKEY_CLEAR = 0x0C,
  VKEY_RETURN = 0x0D,
  VKEY_SHIFT = 0x10,
  VKEY_CONTROL = 0x11,
  VKEY_MENU = 0x12,
  VKEY_PAUSE = 0x13,
  VKEY_CAPITAL = 0x14,
  VKEY_KANA = 0x15,
  VKEY_HANGUL = 0x15,
  VKEY_JUNJA = 0x17,
  VKEY_FINAL = 0x18,
  VKEY_HANJA = 0x19,
  VKEY_KANJI = 0x19,
  VKEY_ESCAPE = 0x1B,
  VKEY_CONVERT = 0x1C,
  VKEY_NONCONVERT = 0x1D,
  VKEY_ACCEPT = 0x1E,
  VKEY_MODECHANGE = 0x1F,
  VKEY_SPACE = 0x20,
  VKEY_PRIOR = 0x21,
  VKEY_NEXT = 0x22,
  VKEY_END = 0x23,
  VKEY_HOME = 0x24,
  VKEY_LEFT = 0x25,
  VKEY_UP = 0x26,
  VKEY_RIGHT = 0x27,
  VKEY_DOWN = 0x28,
  VKEY_SELECT = 0x29,
  VKEY_PRINT = 0x2A,
  VKEY_EXECUTE = 0x2B,
  VKEY_SNAPSHOT = 0x2C,
  VKEY_INSERT = 0x2D,
  VKEY_DELETE = 0x2E,
  VKEY_HELP = 0x2F,
  VKEY_0 = 0x30,
  VKEY_1 = 0x31,
  VKEY_2 = 0x32,
  VKEY_3 = 0x33,
  VKEY_4 = 0x34,
  VKEY_5 = 0x35,
  VKEY_6 = 0x36,
  VKEY_7 = 0x37,
  VKEY_8 = 0x38,
  VKEY_9 = 0x39,
  VKEY_A = 0x41,
  VKEY_B = 0x42,
  VKEY_C = 0x43,
  VKEY_D = 0x44,
  VKEY_E = 0x45,
  VKEY_F = 0x46,
  VKEY_G = 0x47,
  VKEY_H = 0x48,
  VKEY_I = 0x49,
  VKEY_J = 0x4A,
  VKEY_K = 0x4B,
  VKEY_L = 0x4C,
  VKEY_M = 0x4D,
  VKEY_N = 0x4E,
  VKEY_O = 0x4F,
  VKEY_P = 0x50,
  VKEY_Q = 0x51,
  VKEY_R = 0x52,
  VKEY_S = 0x53,
  VKEY_T = 0x54,
  VKEY_U = 0x55,
  VKEY_V = 0x56,
  VKEY_W = 0x57,
  VKEY_X = 0x58,
  VKEY_Y = 0x59,
  VKEY_Z = 0x5A,
  VKEY_LWIN = 0x5B,
  VKEY_COMMAND = VKEY_LWIN,  // Provide the Mac name for convenience.
  VKEY_RWIN = 0x5C,
  VKEY_APPS = 0x5D,
  VKEY_SLEEP = 0x5F,
  VKEY_NUMPAD0 = 0x60,
  VKEY_NUMPAD1 = 0x61,
  VKEY_NUMPAD2 = 0x62,
  VKEY_NUMPAD3 = 0x63,
  VKEY_NUMPAD4 = 0x64,
  VKEY_NUMPAD5 = 0x65,
  VKEY_NUMPAD6 = 0x66,
  VKEY_NUMPAD7 = 0x67,
  VKEY_NUMPAD8 = 0x68,
  VKEY_NUMPAD9 = 0x69,
  VKEY_MULTIPLY = 0x6A,
  VKEY_ADD = 0x6B,
  VKEY_SEPARATOR = 0x6C,
  VKEY_SUBTRACT = 0x6D,
  VKEY_DECIMAL = 0x6E,
  VKEY_DIVIDE = 0x6F,
  VKEY_F1 = 0x70,
  VKEY_F2 = 0x71,
  VKEY_F3 = 0x72,
  VKEY_F4 = 0x73,
  VKEY_F5 = 0x74,
  VKEY_F6 = 0x75,
  VKEY_F7 = 0x76,
  VKEY_F8 = 0x77,
  VKEY_F9 = 0x78,
  VKEY_F10 = 0x79,
  VKEY_F11 = 0x7A,
  VKEY_F12 = 0x7B,
  VKEY_F13 = 0x7C,
  VKEY_F14 = 0x7D,
  VKEY_F15 = 0x7E,
  VKEY_F16 = 0x7F,
  VKEY_F17 = 0x80,
  VKEY_F18 = 0x81,
  VKEY_F19 = 0x82,
  VKEY_F20 = 0x83,
  VKEY_F21 = 0x84,
  VKEY_F22 = 0x85,
  VKEY_F23 = 0x86,
  VKEY_F24 = 0x87,
  VKEY_NUMLOCK = 0x90,
  VKEY_SCROLL = 0x91,
  VKEY_LSHIFT = 0xA0,
  VKEY_RSHIFT = 0xA1,
  VKEY_LCONTROL = 0xA2,
  VKEY_RCONTROL = 0xA3,
  VKEY_LMENU = 0xA4,
  VKEY_RMENU = 0xA5,
  VKEY_BROWSER_BACK = 0xA6,
  VKEY_BROWSER_FORWARD = 0xA7,
  VKEY_BROWSER_REFRESH = 0xA8,
  VKEY_BROWSER_STOP = 0xA9,
  VKEY_BROWSER_SEARCH = 0xAA,
  VKEY_BROWSER_FAVORITES = 0xAB,
  VKEY_BROWSER_HOME = 0xAC,
  VKEY_VOLUME_MUTE = 0xAD,
  VKEY_VOLUME_DOWN = 0xAE,
  VKEY_VOLUME_UP = 0xAF,
  VKEY_MEDIA_NEXT_TRACK = 0xB0,
  VKEY_MEDIA_PREV_TRACK = 0xB1,
  VKEY_MEDIA_STOP = 0xB2,
  VKEY_MEDIA_PLAY_PAUSE = 0xB3,
  VKEY_MEDIA_LAUNCH_MAIL = 0xB4,
  VKEY_MEDIA_LAUNCH_MEDIA_SELECT = 0xB5,
  VKEY_MEDIA_LAUNCH_APP1 = 0xB6,
  VKEY_MEDIA_LAUNCH_APP2 = 0xB7,
  VKEY_OEM_1 = 0xBA,
  VKEY_OEM_PLUS = 0xBB,
  VKEY_OEM_COMMA = 0xBC,
  VKEY_OEM_MINUS = 0xBD,
  VKEY_OEM_PERIOD = 0xBE,
  VKEY_OEM_2 = 0xBF,
  VKEY_OEM_3 = 0xC0,
  VKEY_OEM_4 = 0xDB,
  VKEY_OEM_5 = 0xDC,
  VKEY_OEM_6 = 0xDD,
  VKEY_OEM_7 = 0xDE,
  VKEY_OEM_8 = 0xDF,
  VKEY_OEM_102 = 0xE2,
  VKEY_OEM_103 = 0xE3,  // GTV KEYCODE_MEDIA_REWIND
  VKEY_OEM_104 = 0xE4,  // GTV KEYCODE_MEDIA_FAST_FORWARD
  VKEY_PROCESSKEY = 0xE5,
  VKEY_PACKET = 0xE7,
  VKEY_DBE_SBCSCHAR = 0xF3,
  VKEY_DBE_DBCSCHAR = 0xF4,
  VKEY_ATTN = 0xF6,
  VKEY_CRSEL = 0xF7,
  VKEY_EXSEL = 0xF8,
  VKEY_EREOF = 0xF9,
  VKEY_PLAY = 0xFA,
  VKEY_ZOOM = 0xFB,
  VKEY_NONAME = 0xFC,
  VKEY_PA1 = 0xFD,
  VKEY_OEM_CLEAR = 0xFE,
  VKEY_UNKNOWN = 0,

  // POSIX specific VKEYs. Note that as of Windows SDK 7.1, 0x97-9F, 0xD8-DA,
  // and 0xE8 are unassigned.
  VKEY_WLAN = 0x97,
  VKEY_POWER = 0x98,
  VKEY_BRIGHTNESS_DOWN = 0xD8,
  VKEY_BRIGHTNESS_UP = 0xD9,
  VKEY_KBD_BRIGHTNESS_DOWN = 0xDA,
  VKEY_KBD_BRIGHTNESS_UP = 0xE8,

  // Windows does not have a specific key code for AltGr. We use the unused 0xE1
  // (VK_OEM_AX) code to represent AltGr, matching the behaviour of Firefox on
  // Linux.
  VKEY_ALTGR = 0xE1,
  // Windows does not have a specific key code for Compose. We use the unused
  // 0xE6 (VK_ICO_CLEAR) code to represent Compose.
  VKEY_COMPOSE = 0xE6,
};

// From ui/events/keycodes/keyboard_code_conversion_x.cc.
// Gdk key codes (e.g. GDK_BackSpace) and X keysyms (e.g. XK_BackSpace) share
// the same values.
KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) {
  switch (keysym) {
    case XK_BackSpace:
      return VKEY_BACK;
    case XK_Delete:
    case XK_KP_Delete:
      return VKEY_DELETE;
    case XK_Tab:
    case XK_KP_Tab:
    case XK_ISO_Left_Tab:
    case XK_3270_BackTab:
      return VKEY_TAB;
    case XK_Linefeed:
    case XK_Return:
    case XK_KP_Enter:
    case XK_ISO_Enter:
      return VKEY_RETURN;
    case XK_Clear:
    case XK_KP_Begin:  // NumPad 5 without Num Lock, for crosbug.com/29169.
      return VKEY_CLEAR;
    case XK_KP_Space:
    case XK_space:
      return VKEY_SPACE;
    case XK_Home:
    case XK_KP_Home:
      return VKEY_HOME;
    case XK_End:
    case XK_KP_End:
      return VKEY_END;
    case XK_Page_Up:
    case XK_KP_Page_Up:  // aka XK_KP_Prior
      return VKEY_PRIOR;
    case XK_Page_Down:
    case XK_KP_Page_Down:  // aka XK_KP_Next
      return VKEY_NEXT;
    case XK_Left:
    case XK_KP_Left:
      return VKEY_LEFT;
    case XK_Right:
    case XK_KP_Right:
      return VKEY_RIGHT;
    case XK_Down:
    case XK_KP_Down:
      return VKEY_DOWN;
    case XK_Up:
    case XK_KP_Up:
      return VKEY_UP;
    case XK_Escape:
      return VKEY_ESCAPE;
    case XK_Kana_Lock:
    case XK_Kana_Shift:
      return VKEY_KANA;
    case XK_Hangul:
      return VKEY_HANGUL;
    case XK_Hangul_Hanja:
      return VKEY_HANJA;
    case XK_Kanji:
      return VKEY_KANJI;
    case XK_Henkan:
      return VKEY_CONVERT;
    case XK_Muhenkan:
      return VKEY_NONCONVERT;
    case XK_Zenkaku_Hankaku:
      return VKEY_DBE_DBCSCHAR;
    case XK_A:
    case XK_a:
      return VKEY_A;
    case XK_B:
    case XK_b:
      return VKEY_B;
    case XK_C:
    case XK_c:
      return VKEY_C;
    case XK_D:
    case XK_d:
      return VKEY_D;
    case XK_E:
    case XK_e:
      return VKEY_E;
    case XK_F:
    case XK_f:
      return VKEY_F;
    case XK_G:
    case XK_g:
      return VKEY_G;
    case XK_H:
    case XK_h:
      return VKEY_H;
    case XK_I:
    case XK_i:
      return VKEY_I;
    case XK_J:
    case XK_j:
      return VKEY_J;
    case XK_K:
    case XK_k:
      return VKEY_K;
    case XK_L:
    case XK_l:
      return VKEY_L;
    case XK_M:
    case XK_m:
      return VKEY_M;
    case XK_N:
    case XK_n:
      return VKEY_N;
    case XK_O:
    case XK_o:
      return VKEY_O;
    case XK_P:
    case XK_p:
      return VKEY_P;
    case XK_Q:
    case XK_q:
      return VKEY_Q;
    case XK_R:
    case XK_r:
      return VKEY_R;
    case XK_S:
    case XK_s:
      return VKEY_S;
    case XK_T:
    case XK_t:
      return VKEY_T;
    case XK_U:
    case XK_u:
      return VKEY_U;
    case XK_V:
    case XK_v:
      return VKEY_V;
    case XK_W:
    case XK_w:
      return VKEY_W;
    case XK_X:
    case XK_x:
      return VKEY_X;
    case XK_Y:
    case XK_y:
      return VKEY_Y;
    case XK_Z:
    case XK_z:
      return VKEY_Z;

    case XK_0:
    case XK_1:
    case XK_2:
    case XK_3:
    case XK_4:
    case XK_5:
    case XK_6:
    case XK_7:
    case XK_8:
    case XK_9:
      return static_cast<KeyboardCode>(VKEY_0 + (keysym - XK_0));

    case XK_parenright:
      return VKEY_0;
    case XK_exclam:
      return VKEY_1;
    case XK_at:
      return VKEY_2;
    case XK_numbersign:
      return VKEY_3;
    case XK_dollar:
      return VKEY_4;
    case XK_percent:
      return VKEY_5;
    case XK_asciicircum:
      return VKEY_6;
    case XK_ampersand:
      return VKEY_7;
    case XK_asterisk:
      return VKEY_8;
    case XK_parenleft:
      return VKEY_9;

    case XK_KP_0:
    case XK_KP_1:
    case XK_KP_2:
    case XK_KP_3:
    case XK_KP_4:
    case XK_KP_5:
    case XK_KP_6:
    case XK_KP_7:
    case XK_KP_8:
    case XK_KP_9:
      return static_cast<KeyboardCode>(VKEY_NUMPAD0 + (keysym - XK_KP_0));

    case XK_multiply:
    case XK_KP_Multiply:
      return VKEY_MULTIPLY;
    case XK_KP_Add:
      return VKEY_ADD;
    case XK_KP_Separator:
      return VKEY_SEPARATOR;
    case XK_KP_Subtract:
      return VKEY_SUBTRACT;
    case XK_KP_Decimal:
      return VKEY_DECIMAL;
    case XK_KP_Divide:
      return VKEY_DIVIDE;
    case XK_KP_Equal:
    case XK_equal:
    case XK_plus:
      return VKEY_OEM_PLUS;
    case XK_comma:
    case XK_less:
      return VKEY_OEM_COMMA;
    case XK_minus:
    case XK_underscore:
      return VKEY_OEM_MINUS;
    case XK_greater:
    case XK_period:
      return VKEY_OEM_PERIOD;
    case XK_colon:
    case XK_semicolon:
      return VKEY_OEM_1;
    case XK_question:
    case XK_slash:
      return VKEY_OEM_2;
    case XK_asciitilde:
    case XK_quoteleft:
      return VKEY_OEM_3;
    case XK_bracketleft:
    case XK_braceleft:
      return VKEY_OEM_4;
    case XK_backslash:
    case XK_bar:
      return VKEY_OEM_5;
    case XK_bracketright:
    case XK_braceright:
      return VKEY_OEM_6;
    case XK_quoteright:
    case XK_quotedbl:
      return VKEY_OEM_7;
    case XK_ISO_Level5_Shift:
      return VKEY_OEM_8;
    case XK_Shift_L:
    case XK_Shift_R:
      return VKEY_SHIFT;
    case XK_Control_L:
    case XK_Control_R:
      return VKEY_CONTROL;
    case XK_Meta_L:
    case XK_Meta_R:
    case XK_Alt_L:
    case XK_Alt_R:
      return VKEY_MENU;
    case XK_ISO_Level3_Shift:
      return VKEY_ALTGR;
    case XK_Multi_key:
      return VKEY_COMPOSE;
    case XK_Pause:
      return VKEY_PAUSE;
    case XK_Caps_Lock:
      return VKEY_CAPITAL;
    case XK_Num_Lock:
      return VKEY_NUMLOCK;
    case XK_Scroll_Lock:
      return VKEY_SCROLL;
    case XK_Select:
      return VKEY_SELECT;
    case XK_Print:
      return VKEY_PRINT;
    case XK_Execute:
      return VKEY_EXECUTE;
    case XK_Insert:
    case XK_KP_Insert:
      return VKEY_INSERT;
    case XK_Help:
      return VKEY_HELP;
    case XK_Super_L:
      return VKEY_LWIN;
    case XK_Super_R:
      return VKEY_RWIN;
    case XK_Menu:
      return VKEY_APPS;
    case XK_F1:
    case XK_F2:
    case XK_F3:
    case XK_F4:
    case XK_F5:
    case XK_F6:
    case XK_F7:
    case XK_F8:
    case XK_F9:
    case XK_F10:
    case XK_F11:
    case XK_F12:
    case XK_F13:
    case XK_F14:
    case XK_F15:
    case XK_F16:
    case XK_F17:
    case XK_F18:
    case XK_F19:
    case XK_F20:
    case XK_F21:
    case XK_F22:
    case XK_F23:
    case XK_F24:
      return static_cast<KeyboardCode>(VKEY_F1 + (keysym - XK_F1));
    case XK_KP_F1:
    case XK_KP_F2:
    case XK_KP_F3:
    case XK_KP_F4:
      return static_cast<KeyboardCode>(VKEY_F1 + (keysym - XK_KP_F1));

    case XK_guillemotleft:
    case XK_guillemotright:
    case XK_degree:
    // In the case of canadian multilingual keyboard layout, VKEY_OEM_102 is
    // assigned to ugrave key.
    case XK_ugrave:
    case XK_Ugrave:
    case XK_brokenbar:
      return VKEY_OEM_102;  // international backslash key in 102 keyboard.

    // When evdev is in use, /usr/share/X11/xkb/symbols/inet maps F13-18 keys
    // to the special XF86XK symbols to support Microsoft Ergonomic keyboards:
    // https://bugs.freedesktop.org/show_bug.cgi?id=5783
    // In Chrome, we map these X key symbols back to F13-18 since we don't have
    // VKEYs for these XF86XK symbols.
    case XF86XK_Tools:
      return VKEY_F13;
    case XF86XK_Launch5:
      return VKEY_F14;
    case XF86XK_Launch6:
      return VKEY_F15;
    case XF86XK_Launch7:
      return VKEY_F16;
    case XF86XK_Launch8:
      return VKEY_F17;
    case XF86XK_Launch9:
      return VKEY_F18;
    case XF86XK_Refresh:
    case XF86XK_History:
    case XF86XK_OpenURL:
    case XF86XK_AddFavorite:
    case XF86XK_Go:
    case XF86XK_ZoomIn:
    case XF86XK_ZoomOut:
      // ui::AcceleratorGtk tries to convert the XF86XK_ keysyms on Chrome
      // startup. It's safe to return VKEY_UNKNOWN here since ui::AcceleratorGtk
      // also checks a Gdk keysym. http://crbug.com/109843
      return VKEY_UNKNOWN;
    // For supporting multimedia buttons on a USB keyboard.
    case XF86XK_Back:
      return VKEY_BROWSER_BACK;
    case XF86XK_Forward:
      return VKEY_BROWSER_FORWARD;
    case XF86XK_Reload:
      return VKEY_BROWSER_REFRESH;
    case XF86XK_Stop:
      return VKEY_BROWSER_STOP;
    case XF86XK_Search:
      return VKEY_BROWSER_SEARCH;
    case XF86XK_Favorites:
      return VKEY_BROWSER_FAVORITES;
    case XF86XK_HomePage:
      return VKEY_BROWSER_HOME;
    case XF86XK_AudioMute:
      return VKEY_VOLUME_MUTE;
    case XF86XK_AudioLowerVolume:
      return VKEY_VOLUME_DOWN;
    case XF86XK_AudioRaiseVolume:
      return VKEY_VOLUME_UP;
    case XF86XK_AudioNext:
      return VKEY_MEDIA_NEXT_TRACK;
    case XF86XK_AudioPrev:
      return VKEY_MEDIA_PREV_TRACK;
    case XF86XK_AudioStop:
      return VKEY_MEDIA_STOP;
    case XF86XK_AudioPlay:
      return VKEY_MEDIA_PLAY_PAUSE;
    case XF86XK_Mail:
      return VKEY_MEDIA_LAUNCH_MAIL;
    case XF86XK_LaunchA:  // F3 on an Apple keyboard.
      return VKEY_MEDIA_LAUNCH_APP1;
    case XF86XK_LaunchB:  // F4 on an Apple keyboard.
    case XF86XK_Calculator:
      return VKEY_MEDIA_LAUNCH_APP2;
    case XF86XK_WLAN:
      return VKEY_WLAN;
    case XF86XK_PowerOff:
      return VKEY_POWER;
    case XF86XK_MonBrightnessDown:
      return VKEY_BRIGHTNESS_DOWN;
    case XF86XK_MonBrightnessUp:
      return VKEY_BRIGHTNESS_UP;
    case XF86XK_KbdBrightnessDown:
      return VKEY_KBD_BRIGHTNESS_DOWN;
    case XF86XK_KbdBrightnessUp:
      return VKEY_KBD_BRIGHTNESS_UP;

      // TODO(sad): some keycodes are still missing.
  }
  return VKEY_UNKNOWN;
}

// From content/browser/renderer_host/input/web_input_event_util_posix.cc.
KeyboardCode GdkEventToWindowsKeyCode(const GdkEventKey* event) {
  static const unsigned int kHardwareCodeToGDKKeyval[] = {
      0,                 // 0x00:
      0,                 // 0x01:
      0,                 // 0x02:
      0,                 // 0x03:
      0,                 // 0x04:
      0,                 // 0x05:
      0,                 // 0x06:
      0,                 // 0x07:
      0,                 // 0x08:
      0,                 // 0x09: GDK_Escape
      GDK_1,             // 0x0A: GDK_1
      GDK_2,             // 0x0B: GDK_2
      GDK_3,             // 0x0C: GDK_3
      GDK_4,             // 0x0D: GDK_4
      GDK_5,             // 0x0E: GDK_5
      GDK_6,             // 0x0F: GDK_6
      GDK_7,             // 0x10: GDK_7
      GDK_8,             // 0x11: GDK_8
      GDK_9,             // 0x12: GDK_9
      GDK_0,             // 0x13: GDK_0
      GDK_minus,         // 0x14: GDK_minus
      GDK_equal,         // 0x15: GDK_equal
      0,                 // 0x16: GDK_BackSpace
      0,                 // 0x17: GDK_Tab
      GDK_q,             // 0x18: GDK_q
      GDK_w,             // 0x19: GDK_w
      GDK_e,             // 0x1A: GDK_e
      GDK_r,             // 0x1B: GDK_r
      GDK_t,             // 0x1C: GDK_t
      GDK_y,             // 0x1D: GDK_y
      GDK_u,             // 0x1E: GDK_u
      GDK_i,             // 0x1F: GDK_i
      GDK_o,             // 0x20: GDK_o
      GDK_p,             // 0x21: GDK_p
      GDK_bracketleft,   // 0x22: GDK_bracketleft
      GDK_bracketright,  // 0x23: GDK_bracketright
      0,                 // 0x24: GDK_Return
      0,                 // 0x25: GDK_Control_L
      GDK_a,             // 0x26: GDK_a
      GDK_s,             // 0x27: GDK_s
      GDK_d,             // 0x28: GDK_d
      GDK_f,             // 0x29: GDK_f
      GDK_g,             // 0x2A: GDK_g
      GDK_h,             // 0x2B: GDK_h
      GDK_j,             // 0x2C: GDK_j
      GDK_k,             // 0x2D: GDK_k
      GDK_l,             // 0x2E: GDK_l
      GDK_semicolon,     // 0x2F: GDK_semicolon
      GDK_apostrophe,    // 0x30: GDK_apostrophe
      GDK_grave,         // 0x31: GDK_grave
      0,                 // 0x32: GDK_Shift_L
      GDK_backslash,     // 0x33: GDK_backslash
      GDK_z,             // 0x34: GDK_z
      GDK_x,             // 0x35: GDK_x
      GDK_c,             // 0x36: GDK_c
      GDK_v,             // 0x37: GDK_v
      GDK_b,             // 0x38: GDK_b
      GDK_n,             // 0x39: GDK_n
      GDK_m,             // 0x3A: GDK_m
      GDK_comma,         // 0x3B: GDK_comma
      GDK_period,        // 0x3C: GDK_period
      GDK_slash,         // 0x3D: GDK_slash
      0,                 // 0x3E: GDK_Shift_R
      0,                 // 0x3F:
      0,                 // 0x40:
      0,                 // 0x41:
      0,                 // 0x42:
      0,                 // 0x43:
      0,                 // 0x44:
      0,                 // 0x45:
      0,                 // 0x46:
      0,                 // 0x47:
      0,                 // 0x48:
      0,                 // 0x49:
      0,                 // 0x4A:
      0,                 // 0x4B:
      0,                 // 0x4C:
      0,                 // 0x4D:
      0,                 // 0x4E:
      0,                 // 0x4F:
      0,                 // 0x50:
      0,                 // 0x51:
      0,                 // 0x52:
      0,                 // 0x53:
      0,                 // 0x54:
      0,                 // 0x55:
      0,                 // 0x56:
      0,                 // 0x57:
      0,                 // 0x58:
      0,                 // 0x59:
      0,                 // 0x5A:
      0,                 // 0x5B:
      0,                 // 0x5C:
      0,                 // 0x5D:
      0,                 // 0x5E:
      0,                 // 0x5F:
      0,                 // 0x60:
      0,                 // 0x61:
      0,                 // 0x62:
      0,                 // 0x63:
      0,                 // 0x64:
      0,                 // 0x65:
      0,                 // 0x66:
      0,                 // 0x67:
      0,                 // 0x68:
      0,                 // 0x69:
      0,                 // 0x6A:
      0,                 // 0x6B:
      0,                 // 0x6C:
      0,                 // 0x6D:
      0,                 // 0x6E:
      0,                 // 0x6F:
      0,                 // 0x70:
      0,                 // 0x71:
      0,                 // 0x72:
      GDK_Super_L,       // 0x73: GDK_Super_L
      GDK_Super_R,       // 0x74: GDK_Super_R
  };

  // |windows_key_code| has to include a valid virtual-key code even when we
  // use non-US layouts, e.g. even when we type an 'A' key of a US keyboard
  // on the Hebrew layout, |windows_key_code| should be VK_A.
  // On the other hand, |event->keyval| value depends on the current
  // GdkKeymap object, i.e. when we type an 'A' key of a US keyboard on
  // the Hebrew layout, |event->keyval| becomes GDK_hebrew_shin and this
  // KeyboardCodeFromXKeysym() call returns 0.
  // To improve compatibilty with Windows, we use |event->hardware_keycode|
  // for retrieving its Windows key-code for the keys when the
  // WebCore::windows_key_codeForEvent() call returns 0.
  // We shouldn't use |event->hardware_keycode| for keys that GdkKeymap
  // objects cannot change because |event->hardware_keycode| doesn't change
  // even when we change the layout options, e.g. when we swap a control
  // key and a caps-lock key, GTK doesn't swap their
  // |event->hardware_keycode| values but swap their |event->keyval| values.
  KeyboardCode windows_key_code = KeyboardCodeFromXKeysym(event->keyval);
  if (windows_key_code)
    return windows_key_code;

  if (event->hardware_keycode < arraysize(kHardwareCodeToGDKKeyval)) {
    int keyval = kHardwareCodeToGDKKeyval[event->hardware_keycode];
    if (keyval)
      return KeyboardCodeFromXKeysym(keyval);
  }

  // This key is one that keyboard-layout drivers cannot change.
  // Use |event->keyval| to retrieve its |windows_key_code| value.
  return KeyboardCodeFromXKeysym(event->keyval);
}

// From content/browser/renderer_host/input/web_input_event_util_posix.cc.
KeyboardCode GetWindowsKeyCodeWithoutLocation(KeyboardCode key_code) {
  switch (key_code) {
    case VKEY_LCONTROL:
    case VKEY_RCONTROL:
      return VKEY_CONTROL;
    case VKEY_LSHIFT:
    case VKEY_RSHIFT:
      return VKEY_SHIFT;
    case VKEY_LMENU:
    case VKEY_RMENU:
      return VKEY_MENU;
    default:
      return key_code;
  }
}

// From content/browser/renderer_host/input/web_input_event_builders_gtk.cc.
// Gets the corresponding control character of a specified key code. See:
// http://en.wikipedia.org/wiki/Control_characters
// We emulate Windows behavior here.
int GetControlCharacter(KeyboardCode windows_key_code, bool shift) {
  if (windows_key_code >= VKEY_A && windows_key_code <= VKEY_Z) {
    // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A
    return windows_key_code - VKEY_A + 1;
  }
  if (shift) {
    // following graphics chars require shift key to input.
    switch (windows_key_code) {
      // ctrl-@ maps to \x00 (Null byte)
      case VKEY_2:
        return 0;
      // ctrl-^ maps to \x1E (Record separator, Information separator two)
      case VKEY_6:
        return 0x1E;
      // ctrl-_ maps to \x1F (Unit separator, Information separator one)
      case VKEY_OEM_MINUS:
        return 0x1F;
      // Returns 0 for all other keys to avoid inputting unexpected chars.
      default:
        return 0;
    }
  } else {
    switch (windows_key_code) {
      // ctrl-[ maps to \x1B (Escape)
      case VKEY_OEM_4:
        return 0x1B;
      // ctrl-\ maps to \x1C (File separator, Information separator four)
      case VKEY_OEM_5:
        return 0x1C;
      // ctrl-] maps to \x1D (Group separator, Information separator three)
      case VKEY_OEM_6:
        return 0x1D;
      // ctrl-Enter maps to \x0A (Line feed)
      case VKEY_RETURN:
        return 0x0A;
      // Returns 0 for all other keys to avoid inputting unexpected chars.
      default:
        return 0;
    }
  }
}

void GetWidgetRectInScreen(GtkWidget* widget, GdkRectangle* r) {
  gint x, y, w, h;
  GdkRectangle extents;

  GdkWindow* window = gtk_widget_get_parent_window(widget);

  // Get parent's left-top screen coordinates.
  gdk_window_get_root_origin(window, &x, &y);
  // Get parent's width and height.
  gdk_drawable_get_size(window, &w, &h);
  // Get parent's extents including decorations.
  gdk_window_get_frame_extents(window, &extents);

  // X and Y calculations assume that left, right and bottom border sizes are
  // all the same.
  const gint border = (extents.width - w) / 2;
  r->x = x + border + widget->allocation.x;
  r->y = y + (extents.height - h) - border + widget->allocation.y;
  r->width = widget->allocation.width;
  r->height = widget->allocation.height;
}

CefBrowserHost::DragOperationsMask GetDragOperationsMask(
    GdkDragContext* drag_context) {
  int allowed_ops = DRAG_OPERATION_NONE;
  GdkDragAction drag_action = gdk_drag_context_get_actions(drag_context);
  if (drag_action & GDK_ACTION_COPY)
    allowed_ops |= DRAG_OPERATION_COPY;
  if (drag_action & GDK_ACTION_MOVE)
    allowed_ops |= DRAG_OPERATION_MOVE;
  if (drag_action & GDK_ACTION_LINK)
    allowed_ops |= DRAG_OPERATION_LINK;
  if (drag_action & GDK_ACTION_PRIVATE)
    allowed_ops |= DRAG_OPERATION_PRIVATE;
  return static_cast<CefBrowserHost::DragOperationsMask>(allowed_ops);
}

class ScopedGLContext {
 public:
  ScopedGLContext(GtkWidget* widget, bool swap_buffers)
      : swap_buffers_(swap_buffers) {
    GdkGLContext* glcontext = gtk_widget_get_gl_context(widget);
    gldrawable_ = gtk_widget_get_gl_drawable(widget);
    is_valid_ = gdk_gl_drawable_gl_begin(gldrawable_, glcontext);
  }

  virtual ~ScopedGLContext() {
    if (is_valid_) {
      gdk_gl_drawable_gl_end(gldrawable_);

      if (swap_buffers_) {
        if (gdk_gl_drawable_is_double_buffered(gldrawable_))
          gdk_gl_drawable_swap_buffers(gldrawable_);
        else
          glFlush();
      }
    }
  }

  bool IsValid() const { return is_valid_; }

 private:
  bool swap_buffers_;
  GdkGLDrawable* gldrawable_;
  bool is_valid_;
  ScopedGdkThreadsEnter scoped_gdk_threads_;
};

}  // namespace

BrowserWindowOsrGtk::BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate,
                                         const std::string& startup_url,
                                         const OsrRendererSettings& settings)
    : BrowserWindow(delegate),
      xdisplay_(nullptr),
      renderer_(settings),
      gl_enabled_(false),
      painting_popup_(false),
      hidden_(false),
      glarea_(NULL),
      drag_trigger_event_(nullptr),
      drag_data_(nullptr),
      drag_operation_(DRAG_OPERATION_NONE),
      drag_context_(nullptr),
      drag_targets_(gtk_target_list_new(NULL, 0)),
      drag_leave_(false),
      drag_drop_(false),
      device_scale_factor_(1.0f) {
  client_handler_ = new ClientHandlerOsr(this, this, startup_url);
  g_browser_windows.push_back(this);
}

BrowserWindowOsrGtk::~BrowserWindowOsrGtk() {
  g_browser_windows.erase(
      std::find(g_browser_windows.begin(), g_browser_windows.end(), this));
  ScopedGdkThreadsEnter scoped_gdk_threads;

  if (drag_trigger_event_) {
    gdk_event_free(drag_trigger_event_);
  }
  if (drag_context_) {
    g_object_unref(drag_context_);
  }
  gtk_target_list_unref(drag_targets_);
}

void BrowserWindowOsrGtk::set_xdisplay(XDisplay* xdisplay) {
  REQUIRE_MAIN_THREAD();
  DCHECK(!xdisplay_);
  xdisplay_ = xdisplay;
}

void BrowserWindowOsrGtk::CreateBrowser(
    ClientWindowHandle parent_handle,
    const CefRect& rect,
    const CefBrowserSettings& settings,
    CefRefPtr<CefDictionaryValue> extra_info,
    CefRefPtr<CefRequestContext> request_context) {
  REQUIRE_MAIN_THREAD();

  // Create the native window.
  Create(parent_handle);

  ScopedGdkThreadsEnter scoped_gdk_threads;

  // Retrieve the X11 Window ID for the GTK parent window.
  GtkWidget* window =
      gtk_widget_get_ancestor(GTK_WIDGET(parent_handle), GTK_TYPE_WINDOW);
  ::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(window));
  DCHECK(xwindow);

  CefWindowInfo window_info;
  window_info.SetAsWindowless(xwindow);

  // Create the browser asynchronously.
  CefBrowserHost::CreateBrowser(window_info, client_handler_,
                                client_handler_->startup_url(), settings,
                                extra_info, request_context);
}

void BrowserWindowOsrGtk::GetPopupConfig(CefWindowHandle temp_handle,
                                         CefWindowInfo& windowInfo,
                                         CefRefPtr<CefClient>& client,
                                         CefBrowserSettings& settings) {
  CEF_REQUIRE_UI_THREAD();

  windowInfo.SetAsWindowless(temp_handle);
  client = client_handler_;
}

void BrowserWindowOsrGtk::ShowPopup(ClientWindowHandle parent_handle,
                                    int x,
                                    int y,
                                    size_t width,
                                    size_t height) {
  REQUIRE_MAIN_THREAD();
  DCHECK(browser_.get());

  // Create the native window.
  Create(parent_handle);

  // Send resize notification so the compositor is assigned the correct
  // viewport size and begins rendering.
  browser_->GetHost()->WasResized();

  Show();
}

void BrowserWindowOsrGtk::Show() {
  REQUIRE_MAIN_THREAD();

  if (hidden_) {
    // Set the browser as visible.
    browser_->GetHost()->WasHidden(false);
    hidden_ = false;
  }

  // Give focus to the browser.
  browser_->GetHost()->SendFocusEvent(true);
}

void BrowserWindowOsrGtk::Hide() {
  REQUIRE_MAIN_THREAD();

  if (!browser_)
    return;

  // Remove focus from the browser.
  browser_->GetHost()->SendFocusEvent(false);

  if (!hidden_) {
    // Set the browser as hidden.
    browser_->GetHost()->WasHidden(true);
    hidden_ = true;
  }
}

void BrowserWindowOsrGtk::SetBounds(int x, int y, size_t width, size_t height) {
  REQUIRE_MAIN_THREAD();
  // Nothing to do here. GTK will take care of positioning in the container.
}

void BrowserWindowOsrGtk::SetFocus(bool focus) {
  REQUIRE_MAIN_THREAD();
  ScopedGdkThreadsEnter scoped_gdk_threads;
  if (glarea_ && focus) {
    gtk_widget_grab_focus(glarea_);
  }
}

void BrowserWindowOsrGtk::SetDeviceScaleFactor(float device_scale_factor) {
  REQUIRE_MAIN_THREAD();
  {
    base::AutoLock lock_scope(lock_);
    if (device_scale_factor == device_scale_factor_)
      return;

    // Apply some sanity checks.
    if (device_scale_factor < 1.0f || device_scale_factor > 4.0f)
      return;

    device_scale_factor_ = device_scale_factor;
  }

  if (browser_) {
    browser_->GetHost()->NotifyScreenInfoChanged();
    browser_->GetHost()->WasResized();
  }
}

float BrowserWindowOsrGtk::GetDeviceScaleFactor() const {
  REQUIRE_MAIN_THREAD();
  base::AutoLock lock_scope(lock_);
  return device_scale_factor_;
}

ClientWindowHandle BrowserWindowOsrGtk::GetWindowHandle() const {
  REQUIRE_MAIN_THREAD();
  return glarea_;
}

void BrowserWindowOsrGtk::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UI_THREAD();
}

void BrowserWindowOsrGtk::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UI_THREAD();

  // Detach |this| from the ClientHandlerOsr.
  static_cast<ClientHandlerOsr*>(client_handler_.get())->DetachOsrDelegate();

  ScopedGdkThreadsEnter scoped_gdk_threads;

  UnregisterDragDrop();

  // Disconnect all signal handlers that reference |this|.
  g_signal_handlers_disconnect_matched(glarea_, G_SIGNAL_MATCH_DATA, 0, 0, NULL,
                                       NULL, this);

  DisableGL();
}

bool BrowserWindowOsrGtk::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
                                            CefRect& rect) {
  CEF_REQUIRE_UI_THREAD();
  return false;
}

void BrowserWindowOsrGtk::GetViewRect(CefRefPtr<CefBrowser> browser,
                                      CefRect& rect) {
  CEF_REQUIRE_UI_THREAD();

  rect.x = rect.y = 0;

  if (!glarea_) {
    // Never return an empty rectangle.
    rect.width = rect.height = 1;
    return;
  }

  float device_scale_factor;
  {
    base::AutoLock lock_scope(lock_);
    device_scale_factor = device_scale_factor_;
  }

  // The simulated screen and view rectangle are the same. This is necessary
  // for popup menus to be located and sized inside the view.
  rect.width = DeviceToLogical(glarea_->allocation.width, device_scale_factor);
  if (rect.width == 0)
    rect.width = 1;
  rect.height =
      DeviceToLogical(glarea_->allocation.height, device_scale_factor);
  if (rect.height == 0)
    rect.height = 1;
}

bool BrowserWindowOsrGtk::GetScreenPoint(CefRefPtr<CefBrowser> browser,
                                         int viewX,
                                         int viewY,
                                         int& screenX,
                                         int& screenY) {
  CEF_REQUIRE_UI_THREAD();

  float device_scale_factor;
  {
    base::AutoLock lock_scope(lock_);
    device_scale_factor = device_scale_factor_;
  }

  GdkRectangle screen_rect;
  GetWidgetRectInScreen(glarea_, &screen_rect);
  screenX = screen_rect.x + LogicalToDevice(viewX, device_scale_factor);
  screenY = screen_rect.y + LogicalToDevice(viewY, device_scale_factor);
  return true;
}

bool BrowserWindowOsrGtk::GetScreenInfo(CefRefPtr<CefBrowser> browser,
                                        CefScreenInfo& screen_info) {
  CEF_REQUIRE_UI_THREAD();

  CefRect view_rect;
  GetViewRect(browser, view_rect);

  float device_scale_factor;
  {
    base::AutoLock lock_scope(lock_);
    device_scale_factor = device_scale_factor_;
  }

  screen_info.device_scale_factor = device_scale_factor;

  // The screen info rectangles are used by the renderer to create and position
  // popups. Keep popups inside the view rectangle.
  screen_info.rect = view_rect;
  screen_info.available_rect = view_rect;
  return true;
}

void BrowserWindowOsrGtk::OnPopupShow(CefRefPtr<CefBrowser> browser,
                                      bool show) {
  CEF_REQUIRE_UI_THREAD();

  if (!show) {
    renderer_.ClearPopupRects();
    browser->GetHost()->Invalidate(PET_VIEW);
  }
  renderer_.OnPopupShow(browser, show);
}

void BrowserWindowOsrGtk::OnPopupSize(CefRefPtr<CefBrowser> browser,
                                      const CefRect& rect) {
  CEF_REQUIRE_UI_THREAD();

  float device_scale_factor;
  {
    base::AutoLock lock_scope(lock_);
    device_scale_factor = device_scale_factor_;
  }

  renderer_.OnPopupSize(browser, LogicalToDevice(rect, device_scale_factor));
}

void BrowserWindowOsrGtk::OnPaint(CefRefPtr<CefBrowser> browser,
                                  CefRenderHandler::PaintElementType type,
                                  const CefRenderHandler::RectList& dirtyRects,
                                  const void* buffer,
                                  int width,
                                  int height) {
  CEF_REQUIRE_UI_THREAD();

  if (width <= 2 && height <= 2) {
    // Ignore really small buffer sizes while the widget is starting up.
    return;
  }

  if (painting_popup_) {
    renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
    return;
  }

  if (!gl_enabled_)
    EnableGL();

  ScopedGLContext scoped_gl_context(glarea_, true);
  if (!scoped_gl_context.IsValid())
    return;

  renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
  if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) {
    painting_popup_ = true;
    browser->GetHost()->Invalidate(PET_POPUP);
    painting_popup_ = false;
  }
  renderer_.Render();
}

void BrowserWindowOsrGtk::OnCursorChange(
    CefRefPtr<CefBrowser> browser,
    CefCursorHandle cursor,
    CefRenderHandler::CursorType type,
    const CefCursorInfo& custom_cursor_info) {
  CEF_REQUIRE_UI_THREAD();

  // Retrieve the X11 display shared with Chromium.
  CHECK(xdisplay_ != 0);

  ScopedGdkThreadsEnter scoped_gdk_threads;

  // Retrieve the X11 window handle for the GTK widget.
  ::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(glarea_));

  // Set the cursor.
  XDefineCursor(xdisplay_, xwindow, cursor);
}

bool BrowserWindowOsrGtk::StartDragging(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefDragData> drag_data,
    CefRenderHandler::DragOperationsMask allowed_ops,
    int x,
    int y) {
  CEF_REQUIRE_UI_THREAD();

  if (!drag_data->HasImage()) {
    LOG(ERROR) << "Drag image representation not available";
    return false;
  }

  DragReset();
  drag_data_ = drag_data;

  ScopedGdkThreadsEnter scoped_gdk_threads;

  // Begin drag.
  if (drag_trigger_event_) {
    LOG(ERROR) << "Dragging started, but last mouse event is missing";
    DragReset();
    return false;
  }
  drag_context_ = gtk_drag_begin(glarea_, drag_targets_, GDK_ACTION_COPY,
                                 1,  // left mouse button
                                 drag_trigger_event_);
  if (!drag_context_) {
    LOG(ERROR) << "GTK drag begin failed";
    DragReset();
    return false;
  }
  g_object_ref(drag_context_);

  // Send drag enter event.
  CefMouseEvent ev;
  ev.x = x;
  ev.y = y;
  ev.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;
  browser->GetHost()->DragTargetDragEnter(drag_data, ev, allowed_ops);

  return true;
}

void BrowserWindowOsrGtk::UpdateDragCursor(
    CefRefPtr<CefBrowser> browser,
    CefRenderHandler::DragOperation operation) {
  CEF_REQUIRE_UI_THREAD();
  drag_operation_ = operation;
}

void BrowserWindowOsrGtk::OnImeCompositionRangeChanged(
    CefRefPtr<CefBrowser> browser,
    const CefRange& selection_range,
    const CefRenderHandler::RectList& character_bounds) {
  CEF_REQUIRE_UI_THREAD();
}

void BrowserWindowOsrGtk::UpdateAccessibilityTree(CefRefPtr<CefValue> value) {
  CEF_REQUIRE_UI_THREAD();
}

void BrowserWindowOsrGtk::UpdateAccessibilityLocation(
    CefRefPtr<CefValue> value) {
  CEF_REQUIRE_UI_THREAD();
}

void BrowserWindowOsrGtk::Create(ClientWindowHandle parent_handle) {
  REQUIRE_MAIN_THREAD();
  DCHECK(!glarea_);

  ScopedGdkThreadsEnter scoped_gdk_threads;

  glarea_ = gtk_drawing_area_new();
  DCHECK(glarea_);

  GdkGLConfig* glconfig =
      gdk_gl_config_new_by_mode(static_cast<GdkGLConfigMode>(
          GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE));
  DCHECK(glconfig);

  gtk_widget_set_gl_capability(glarea_, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);

  gtk_widget_set_can_focus(glarea_, TRUE);

  g_signal_connect(G_OBJECT(glarea_), "size_allocate",
                   G_CALLBACK(&BrowserWindowOsrGtk::SizeAllocation), this);

  gtk_widget_set_events(
      glarea_, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                   GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
                   GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
                   GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
                   GDK_SCROLL_MASK | GDK_FOCUS_CHANGE_MASK);
  g_signal_connect(G_OBJECT(glarea_), "button_press_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::ClickEvent), this);
  g_signal_connect(G_OBJECT(glarea_), "button_release_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::ClickEvent), this);
  g_signal_connect(G_OBJECT(glarea_), "key_press_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::KeyEvent), this);
  g_signal_connect(G_OBJECT(glarea_), "key_release_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::KeyEvent), this);
  g_signal_connect(G_OBJECT(glarea_), "enter_notify_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::MoveEvent), this);
  g_signal_connect(G_OBJECT(glarea_), "leave_notify_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::MoveEvent), this);
  g_signal_connect(G_OBJECT(glarea_), "motion_notify_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::MoveEvent), this);
  g_signal_connect(G_OBJECT(glarea_), "scroll_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::ScrollEvent), this);
  g_signal_connect(G_OBJECT(glarea_), "focus_in_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::FocusEvent), this);
  g_signal_connect(G_OBJECT(glarea_), "focus_out_event",
                   G_CALLBACK(&BrowserWindowOsrGtk::FocusEvent), this);

  RegisterDragDrop();

  gtk_container_add(GTK_CONTAINER(parent_handle), glarea_);

  // Make the GlArea visible in the parent container.
  gtk_widget_show_all(parent_handle);

  InitializeXinput(xdisplay_);

  if (IsTouchAvailable())
    RegisterTouch();
}

// static
gint BrowserWindowOsrGtk::SizeAllocation(GtkWidget* widget,
                                         GtkAllocation* allocation,
                                         BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();
  if (self->browser_.get()) {
    // Results in a call to GetViewRect().
    self->browser_->GetHost()->WasResized();
  }
  return TRUE;
}

// static
gint BrowserWindowOsrGtk::ClickEvent(GtkWidget* widget,
                                     GdkEventButton* event,
                                     BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  if (!self->browser_.get())
    return TRUE;

  CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();

  CefBrowserHost::MouseButtonType button_type = MBT_LEFT;
  switch (event->button) {
    case 1:
      break;
    case 2:
      button_type = MBT_MIDDLE;
      break;
    case 3:
      button_type = MBT_RIGHT;
      break;
    default:
      // Other mouse buttons are not handled here.
      return FALSE;
  }

  float device_scale_factor;
  {
    base::AutoLock lock_scope(self->lock_);
    device_scale_factor = self->device_scale_factor_;
  }

  CefMouseEvent mouse_event;
  mouse_event.x = event->x;
  mouse_event.y = event->y;
  self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
  DeviceToLogical(mouse_event, device_scale_factor);
  mouse_event.modifiers = GetCefStateModifiers(event->state);

  bool mouse_up = (event->type == GDK_BUTTON_RELEASE);
  if (!mouse_up) {
    gtk_widget_grab_focus(widget);
  }

  int click_count = 1;
  switch (event->type) {
    case GDK_2BUTTON_PRESS:
      click_count = 2;
      break;
    case GDK_3BUTTON_PRESS:
      click_count = 3;
      break;
    default:
      break;
  }

  host->SendMouseClickEvent(mouse_event, button_type, mouse_up, click_count);

  // Save mouse event that can be a possible trigger for drag.
  if (!self->drag_context_ && button_type == MBT_LEFT) {
    if (self->drag_trigger_event_) {
      gdk_event_free(self->drag_trigger_event_);
    }
    self->drag_trigger_event_ =
        gdk_event_copy(reinterpret_cast<GdkEvent*>(event));
  }

  return TRUE;
}

// static
gint BrowserWindowOsrGtk::KeyEvent(GtkWidget* widget,
                                   GdkEventKey* event,
                                   BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  if (!self->browser_.get())
    return TRUE;

  CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();

  // Based on WebKeyboardEventBuilder::Build from
  // content/browser/renderer_host/input/web_input_event_builders_gtk.cc.
  CefKeyEvent key_event;
  KeyboardCode windows_key_code = GdkEventToWindowsKeyCode(event);
  key_event.windows_key_code =
      GetWindowsKeyCodeWithoutLocation(windows_key_code);
  key_event.native_key_code = event->hardware_keycode;

  key_event.modifiers = GetCefStateModifiers(event->state);
  if (event->keyval >= GDK_KP_Space && event->keyval <= GDK_KP_9)
    key_event.modifiers |= EVENTFLAG_IS_KEY_PAD;
  if (key_event.modifiers & EVENTFLAG_ALT_DOWN)
    key_event.is_system_key = true;

  if (windows_key_code == VKEY_RETURN) {
    // We need to treat the enter key as a key press of character \r.  This
    // is apparently just how webkit handles it and what it expects.
    key_event.unmodified_character = '\r';
  } else {
    // FIXME: fix for non BMP chars
    key_event.unmodified_character =
        static_cast<int>(gdk_keyval_to_unicode(event->keyval));
  }

  // If ctrl key is pressed down, then control character shall be input.
  if (key_event.modifiers & EVENTFLAG_CONTROL_DOWN) {
    key_event.character = GetControlCharacter(
        windows_key_code, key_event.modifiers & EVENTFLAG_SHIFT_DOWN);
  } else {
    key_event.character = key_event.unmodified_character;
  }

  if (event->type == GDK_KEY_PRESS) {
    key_event.type = KEYEVENT_RAWKEYDOWN;
    host->SendKeyEvent(key_event);
    key_event.type = KEYEVENT_CHAR;
    host->SendKeyEvent(key_event);
  } else {
    key_event.type = KEYEVENT_KEYUP;
    host->SendKeyEvent(key_event);
  }

  return TRUE;
}

// static
gint BrowserWindowOsrGtk::MoveEvent(GtkWidget* widget,
                                    GdkEventMotion* event,
                                    BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  if (!self->browser_.get())
    return TRUE;

  CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();

  gint x, y;
  GdkModifierType state;

  if (event->is_hint) {
    gdk_window_get_pointer(event->window, &x, &y, &state);
  } else {
    x = (gint)event->x;
    y = (gint)event->y;
    state = (GdkModifierType)event->state;
    if (x == 0 && y == 0) {
      // Invalid coordinates of (0,0) appear from time to time in
      // enter-notify-event and leave-notify-event events. Sending them may
      // cause StartDragging to never get called, so just ignore these.
      return TRUE;
    }
  }

  float device_scale_factor;
  {
    base::AutoLock lock_scope(self->lock_);
    device_scale_factor = self->device_scale_factor_;
  }

  CefMouseEvent mouse_event;
  mouse_event.x = x;
  mouse_event.y = y;
  self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
  DeviceToLogical(mouse_event, device_scale_factor);
  mouse_event.modifiers = GetCefStateModifiers(state);

  bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY);
  host->SendMouseMoveEvent(mouse_event, mouse_leave);

  // Save mouse event that can be a possible trigger for drag.
  if (!self->drag_context_ &&
      (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON)) {
    if (self->drag_trigger_event_) {
      gdk_event_free(self->drag_trigger_event_);
    }
    self->drag_trigger_event_ =
        gdk_event_copy(reinterpret_cast<GdkEvent*>(event));
  }

  return TRUE;
}

// static
gint BrowserWindowOsrGtk::ScrollEvent(GtkWidget* widget,
                                      GdkEventScroll* event,
                                      BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  if (!self->browser_.get())
    return TRUE;

  CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();

  float device_scale_factor;
  {
    base::AutoLock lock_scope(self->lock_);
    device_scale_factor = self->device_scale_factor_;
  }

  CefMouseEvent mouse_event;
  mouse_event.x = event->x;
  mouse_event.y = event->y;
  self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
  DeviceToLogical(mouse_event, device_scale_factor);
  mouse_event.modifiers = GetCefStateModifiers(event->state);

  static const int scrollbarPixelsPerGtkTick = 40;
  int deltaX = 0;
  int deltaY = 0;
  switch (event->direction) {
    case GDK_SCROLL_UP:
      deltaY = scrollbarPixelsPerGtkTick;
      break;
    case GDK_SCROLL_DOWN:
      deltaY = -scrollbarPixelsPerGtkTick;
      break;
    case GDK_SCROLL_LEFT:
      deltaX = scrollbarPixelsPerGtkTick;
      break;
    case GDK_SCROLL_RIGHT:
      deltaX = -scrollbarPixelsPerGtkTick;
      break;
  }

  host->SendMouseWheelEvent(mouse_event, deltaX, deltaY);
  return TRUE;
}

// static
gint BrowserWindowOsrGtk::FocusEvent(GtkWidget* widget,
                                     GdkEventFocus* event,
                                     BrowserWindowOsrGtk* self) {
  // May be called on the main thread and the UI thread.
  if (self->browser_.get())
    self->browser_->GetHost()->SendFocusEvent(event->in == TRUE);
  return TRUE;
}

void BrowserWindowOsrGtk::TouchEvent(CefXIDeviceEvent event) {
  if (!browser_.get())
    return;

  XIDeviceEvent* ev = static_cast<XIDeviceEvent*>(event);
  CefTouchEvent cef_event;
  switch (ev->evtype) {
    case XI_TouchBegin:
      cef_event.type = CEF_TET_PRESSED;
      break;
    case XI_TouchUpdate:
      cef_event.type = CEF_TET_MOVED;
      break;
    case XI_TouchEnd:
      cef_event.type = CEF_TET_RELEASED;
      break;
    default:
      return;
  }

  cef_event.id = ev->detail;
  cef_event.x = ev->event_x;
  cef_event.y = ev->event_y;
  cef_event.radius_x = 0;
  cef_event.radius_y = 0;
  cef_event.rotation_angle = 0;
  cef_event.pressure = 0;
  cef_event.modifiers = GetCefStateModifiers(ev->mods, ev->buttons);

  browser_->GetHost()->SendTouchEvent(cef_event);
}

void BrowserWindowOsrGtk::RegisterTouch() {
  GdkWindow* glwindow = gtk_widget_get_window(glarea_);
  ::Window xwindow = GDK_WINDOW_XID(glwindow);
  uint32_t bitMask = XI_TouchBeginMask | XI_TouchUpdateMask | XI_TouchEndMask;

  XIEventMask mask;
  mask.deviceid = XIAllMasterDevices;
  mask.mask = reinterpret_cast<unsigned char*>(&bitMask);
  mask.mask_len = sizeof(bitMask);
  XISelectEvents(xdisplay_, xwindow, &mask, 1);
}

// static
GdkFilterReturn BrowserWindowOsrGtk::EventFilter(GdkXEvent* gdk_xevent,
                                                 GdkEvent* event,
                                                 gpointer data) {
  XEvent* xevent = static_cast<XEvent*>(gdk_xevent);
  if (xevent->type == GenericEvent &&
      xevent->xgeneric.extension == g_xinput_extension) {
    XGetEventData(xevent->xcookie.display, &xevent->xcookie);
    XIDeviceEvent* ev = static_cast<XIDeviceEvent*>(xevent->xcookie.data);

    if (!ev)
      return GDK_FILTER_REMOVE;

    for (BrowserWindowOsrGtk* browser_window : g_browser_windows) {
      GtkWidget* widget = browser_window->GetWindowHandle();
      ::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(widget));
      if (xwindow == ev->event) {
        browser_window->TouchEvent(ev);
        break;
      }
    }

    XFreeEventData(xevent->xcookie.display, &xevent->xcookie);
    // Even if we didn't find a consumer for this event, we will make sure Gdk
    // doesn't attempt to process the event, since it can't parse GenericEvents
    return GDK_FILTER_REMOVE;
  }

  return GDK_FILTER_CONTINUE;
}

// static
void BrowserWindowOsrGtk::InitializeXinput(XDisplay* xdisplay) {
  static bool initialized = false;
  if (initialized)
    return;
  initialized = true;

  int firstEvent, firstError;
  if (XQueryExtension(xdisplay, "XInputExtension", &g_xinput_extension,
                      &firstEvent, &firstError)) {
    int major = 2, minor = 2;
    // X Input Extension 2.2 is needed for multitouch events.
    if (XIQueryVersion(xdisplay, &major, &minor) == Success) {
      // Ideally we would add an event filter for each glarea_ window
      // separately, but unfortunately GDK can't parse X GenericEvents
      // which have the target window stored in different way compared
      // to other X events. That is why we add this global event filter
      // just once, and dispatch the event to correct BrowserWindowOsrGtk
      // manually.
      gdk_window_add_filter(nullptr, &BrowserWindowOsrGtk::EventFilter,
                            nullptr);
    } else {
      g_xinput_extension = -1;
    }
  }
}

bool BrowserWindowOsrGtk::IsOverPopupWidget(int x, int y) const {
  const CefRect& rc = renderer_.popup_rect();
  int popup_right = rc.x + rc.width;
  int popup_bottom = rc.y + rc.height;
  return (x >= rc.x) && (x < popup_right) && (y >= rc.y) && (y < popup_bottom);
}

int BrowserWindowOsrGtk::GetPopupXOffset() const {
  return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
}

int BrowserWindowOsrGtk::GetPopupYOffset() const {
  return renderer_.original_popup_rect().y - renderer_.popup_rect().y;
}

void BrowserWindowOsrGtk::ApplyPopupOffset(int& x, int& y) const {
  if (IsOverPopupWidget(x, y)) {
    x += GetPopupXOffset();
    y += GetPopupYOffset();
  }
}

void BrowserWindowOsrGtk::EnableGL() {
  CEF_REQUIRE_UI_THREAD();

  if (gl_enabled_)
    return;

  ScopedGLContext scoped_gl_context(glarea_, false);
  if (!scoped_gl_context.IsValid())
    return;

  renderer_.Initialize();

  gl_enabled_ = true;
}

void BrowserWindowOsrGtk::DisableGL() {
  CEF_REQUIRE_UI_THREAD();

  if (!gl_enabled_)
    return;

  ScopedGLContext scoped_gl_context(glarea_, false);
  if (!scoped_gl_context.IsValid())
    return;

  renderer_.Cleanup();

  gl_enabled_ = false;
}

void BrowserWindowOsrGtk::RegisterDragDrop() {
  REQUIRE_MAIN_THREAD();

  ScopedGdkThreadsEnter scoped_gdk_threads;

  // Succession of CEF d&d calls:
  // 1. DragTargetDragEnter
  // 2. DragTargetDragOver
  // 3. DragTargetDragLeave - optional
  // 4. DragSourceSystemDragEnded - optional, to cancel dragging
  // 5. DragTargetDrop
  // 6. DragSourceEndedAt
  // 7. DragSourceSystemDragEnded

  // Succession of GTK d&d events:
  // 1. drag-begin-event, drag-data-get
  // 2. drag-motion
  // 3. drag-leave
  // 4. drag-failed
  // 5. drag-drop, drag-data-received
  // 6. 7. drag-end-event

  // Using gtk_drag_begin in StartDragging instead of calling
  // gtk_drag_source_set here. Doing so because when using gtk_drag_source_set
  // then StartDragging is being called very late, about ten DragMotion events
  // after DragBegin, and drag icon can be set only when beginning drag.
  // Default values for drag threshold are set to 8 pixels in both GTK and
  // Chromium, but doesn't work as expected.
  // --OFF--
  // gtk_drag_source_set(glarea_, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);

  // Source widget events.
  g_signal_connect(G_OBJECT(glarea_), "drag_begin",
                   G_CALLBACK(&BrowserWindowOsrGtk::DragBegin), this);
  g_signal_connect(G_OBJECT(glarea_), "drag_data_get",
                   G_CALLBACK(&BrowserWindowOsrGtk::DragDataGet), this);
  g_signal_connect(G_OBJECT(glarea_), "drag_end",
                   G_CALLBACK(&BrowserWindowOsrGtk::DragEnd), this);

  // Destination widget and its events.
  gtk_drag_dest_set(glarea_, (GtkDestDefaults)0, (GtkTargetEntry*)NULL, 0,
                    (GdkDragAction)GDK_ACTION_COPY);
  g_signal_connect(G_OBJECT(glarea_), "drag_motion",
                   G_CALLBACK(&BrowserWindowOsrGtk::DragMotion), this);
  g_signal_connect(G_OBJECT(glarea_), "drag_leave",
                   G_CALLBACK(&BrowserWindowOsrGtk::DragLeave), this);
  g_signal_connect(G_OBJECT(glarea_), "drag_failed",
                   G_CALLBACK(&BrowserWindowOsrGtk::DragFailed), this);
  g_signal_connect(G_OBJECT(glarea_), "drag_drop",
                   G_CALLBACK(&BrowserWindowOsrGtk::DragDrop), this);
  g_signal_connect(G_OBJECT(glarea_), "drag_data_received",
                   G_CALLBACK(&BrowserWindowOsrGtk::DragDataReceived), this);
}

void BrowserWindowOsrGtk::UnregisterDragDrop() {
  CEF_REQUIRE_UI_THREAD();
  ScopedGdkThreadsEnter scoped_gdk_threads;
  gtk_drag_dest_unset(glarea_);
  // Drag events are unregistered in OnBeforeClose by calling
  // g_signal_handlers_disconnect_matched.
}

void BrowserWindowOsrGtk::DragReset() {
  CEF_REQUIRE_UI_THREAD();
  if (drag_trigger_event_) {
    gdk_event_free(drag_trigger_event_);
    drag_trigger_event_ = nullptr;
  }
  drag_data_ = nullptr;
  drag_operation_ = DRAG_OPERATION_NONE;
  if (drag_context_) {
    g_object_unref(drag_context_);
    drag_context_ = nullptr;
  }
  drag_leave_ = false;
  drag_drop_ = false;
}

// static
void BrowserWindowOsrGtk::DragBegin(GtkWidget* widget,
                                    GdkDragContext* drag_context,
                                    BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  // Load drag icon.
  if (!self->drag_data_->HasImage()) {
    LOG(ERROR) << "Failed to set drag icon, drag image not available";
    return;
  }

  float device_scale_factor;
  {
    base::AutoLock lock_scope(self->lock_);
    device_scale_factor = self->device_scale_factor_;
  }

  int pixel_width = 0;
  int pixel_height = 0;
  CefRefPtr<CefBinaryValue> image_binary =
      self->drag_data_->GetImage()->GetAsPNG(device_scale_factor, true,
                                             pixel_width, pixel_height);
  if (!image_binary) {
    LOG(ERROR) << "Failed to set drag icon, drag image error";
    return;
  }

  size_t image_size = image_binary->GetSize();
  guint8* image_buffer = (guint8*)malloc(image_size);  // must free
  image_binary->GetData((void*)image_buffer, image_size, 0);
  GdkPixbufLoader* loader = nullptr;  // must unref
  GError* error = nullptr;            // must free
  GdkPixbuf* pixbuf = nullptr;        // owned by loader
  gboolean success = FALSE;
  loader = gdk_pixbuf_loader_new_with_type("png", &error);
  if (error == nullptr && loader) {
    success = gdk_pixbuf_loader_write(loader, image_buffer, image_size, NULL);
    if (success) {
      success = gdk_pixbuf_loader_close(loader, NULL);
      if (success) {
        pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
        if (pixbuf) {
          CefPoint image_hotspot = self->drag_data_->GetImageHotspot();
          int hotspot_x = image_hotspot.x;
          int hotspot_y = image_hotspot.y;
          gtk_drag_set_icon_pixbuf(drag_context, pixbuf, hotspot_x, hotspot_y);
        } else {
          LOG(ERROR) << "Failed to set drag icon, pixbuf error";
        }
      } else {
        LOG(ERROR) << "Failed to set drag icon, loader close error";
      }
    } else {
      LOG(ERROR) << "Failed to set drag icon, loader write error";
    }
  } else {
    LOG(ERROR) << "Failed to set drag icon, loader creation error";
  }
  if (loader) {
    g_object_unref(loader);  // unref
  }
  if (error) {
    g_error_free(error);  // free
  }
  free(image_buffer);  // free
}

// static
void BrowserWindowOsrGtk::DragDataGet(GtkWidget* widget,
                                      GdkDragContext* drag_context,
                                      GtkSelectionData* data,
                                      guint info,
                                      guint time,
                                      BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();
  // No drag targets are set so this callback is never called.
}

// static
void BrowserWindowOsrGtk::DragEnd(GtkWidget* widget,
                                  GdkDragContext* drag_context,
                                  BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  if (self->browser_) {
    // Sometimes there is DragEnd event generated without prior DragDrop.
    // Maybe related to drag-leave bug described in comments in DragLeave.
    if (!self->drag_drop_) {
      // Real coordinates not available.
      self->browser_->GetHost()->DragSourceEndedAt(-1, -1,
                                                   self->drag_operation_);
    }
    self->browser_->GetHost()->DragSourceSystemDragEnded();
  }

  self->DragReset();
}

// static
gboolean BrowserWindowOsrGtk::DragMotion(GtkWidget* widget,
                                         GdkDragContext* drag_context,
                                         gint x,
                                         gint y,
                                         guint time,
                                         BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  float device_scale_factor;
  {
    base::AutoLock lock_scope(self->lock_);
    device_scale_factor = self->device_scale_factor_;
  }

  // MoveEvent is never called during drag & drop, so must call
  // SendMouseMoveEvent here.
  CefMouseEvent mouse_event;
  mouse_event.x = x;
  mouse_event.y = y;
  mouse_event.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;
  self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
  DeviceToLogical(mouse_event, device_scale_factor);
  if (self->browser_) {
    bool mouse_leave = self->drag_leave_;
    self->browser_->GetHost()->SendMouseMoveEvent(mouse_event, mouse_leave);
  }

  // Mouse event.
  CefMouseEvent ev;
  ev.x = x;
  ev.y = y;
  ev.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;

  CefBrowserHost::DragOperationsMask allowed_ops =
      GetDragOperationsMask(drag_context);

  // Send drag enter event if needed.
  if (self->drag_leave_ && self->browser_) {
    self->browser_->GetHost()->DragTargetDragEnter(self->drag_data_, ev,
                                                   allowed_ops);
  }

  // Send drag over event.
  if (self->browser_) {
    self->browser_->GetHost()->DragTargetDragOver(ev, allowed_ops);
  }

  // Update GTK drag status.
  if (widget == self->glarea_) {
    gdk_drag_status(drag_context, GDK_ACTION_COPY, time);
    if (self->drag_leave_) {
      self->drag_leave_ = false;
    }
    return TRUE;
  } else {
    LOG(WARNING) << "Invalid drag destination widget";
    gdk_drag_status(drag_context, (GdkDragAction)0, time);
    return FALSE;
  }
}

// static
void BrowserWindowOsrGtk::DragLeave(GtkWidget* widget,
                                    GdkDragContext* drag_context,
                                    guint time,
                                    BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  // There is no drag-enter event in GTK. The first drag-motion event
  // after drag-leave will be a drag-enter event.

  // There seems to be a bug during GTK drop, drag-leave event is generated
  // just before drag-drop. A solution is to call DragTargetDragEnter
  // and DragTargetDragOver in DragDrop when drag_leave_ is true.

  // Send drag leave event.
  if (self->browser_) {
    self->browser_->GetHost()->DragTargetDragLeave();
  }

  self->drag_leave_ = true;
}

// static
gboolean BrowserWindowOsrGtk::DragFailed(GtkWidget* widget,
                                         GdkDragContext* drag_context,
                                         GtkDragResult result,
                                         BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  // Send drag end coordinates and system drag ended event.
  if (self->browser_) {
    // Real coordinates not available.
    self->browser_->GetHost()->DragSourceEndedAt(-1, -1, self->drag_operation_);
    self->browser_->GetHost()->DragSourceSystemDragEnded();
  }

  self->DragReset();
  return TRUE;
}

// static
gboolean BrowserWindowOsrGtk::DragDrop(GtkWidget* widget,
                                       GdkDragContext* drag_context,
                                       gint x,
                                       gint y,
                                       guint time,
                                       BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();

  // Finish GTK drag.
  gtk_drag_finish(drag_context, TRUE, FALSE, time);

  // Mouse event.
  CefMouseEvent ev;
  ev.x = x;
  ev.y = y;
  ev.modifiers = EVENTFLAG_LEFT_MOUSE_BUTTON;

  CefBrowserHost::DragOperationsMask allowed_ops =
      GetDragOperationsMask(drag_context);

  // Send drag enter/over events if needed (read comment in DragLeave).
  if (self->drag_leave_ && self->browser_) {
    self->browser_->GetHost()->DragTargetDragEnter(self->drag_data_, ev,
                                                   allowed_ops);
    self->browser_->GetHost()->DragTargetDragOver(ev, allowed_ops);
  }

  // Send drag drop event.
  if (self->browser_) {
    self->browser_->GetHost()->DragTargetDrop(ev);
  }

  // Send drag end coordinates.
  if (self->browser_) {
    self->browser_->GetHost()->DragSourceEndedAt(x, y, self->drag_operation_);
  }

  self->drag_drop_ = true;
  return TRUE;
}

// static
void BrowserWindowOsrGtk::DragDataReceived(GtkWidget* widget,
                                           GdkDragContext* drag_context,
                                           gint x,
                                           gint y,
                                           GtkSelectionData* data,
                                           guint info,
                                           guint time,
                                           BrowserWindowOsrGtk* self) {
  CEF_REQUIRE_UI_THREAD();
  // This callback is never called because DragDrop does not call
  // gtk_drag_get_data, as only dragging inside web view is supported.
}

}  // namespace client
