// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/x11/application_x11.h"

#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#define XK_3270  // for XK_3270_BackTab
#include <X11/XF86keysym.h>
#include <X11/XKBlib.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>

#include <algorithm>
#include <iomanip>

#include "starboard/common/log.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/event.h"
#include "starboard/input.h"
#include "starboard/key.h"
#include "starboard/memory.h"
#include "starboard/player.h"
#include "starboard/shared/linux/system_network_status.h"
#include "starboard/shared/posix/time_internal.h"
#include "starboard/shared/starboard/audio_sink/audio_sink_internal.h"
#include "starboard/shared/starboard/player/filter/cpu_video_frame.h"
#include "starboard/shared/x11/window_internal.h"
#include "starboard/time.h"

namespace {
const char kTouchscreenPointerSwitch[] = "touchscreen_pointer";
}

namespace starboard {
namespace shared {
namespace x11 {

using ::starboard::shared::dev_input::DevInput;

namespace {

enum {
  kNoneDeviceId,
  kKeyboardDeviceId,
  kMouseDeviceId,
};

// Key translation taken from cobalt/system_window/linux/keycode_conversion.cc
// Eventually, that code should be removed in favor of this code.

uint32_t HardwareKeycodeToDefaultXKeysym(uint32_t hardware_code) {
  static const uint32_t kHardwareKeycodeMap[] = {
      0,                // 0x00:
      0,                // 0x01:
      0,                // 0x02:
      0,                // 0x03:
      0,                // 0x04:
      0,                // 0x05:
      0,                // 0x06:
      0,                // 0x07:
      0,                // 0x08:
      XK_Escape,        // 0x09: XK_Escape
      XK_1,             // 0x0A: XK_1
      XK_2,             // 0x0B: XK_2
      XK_3,             // 0x0C: XK_3
      XK_4,             // 0x0D: XK_4
      XK_5,             // 0x0E: XK_5
      XK_6,             // 0x0F: XK_6
      XK_7,             // 0x10: XK_7
      XK_8,             // 0x11: XK_8
      XK_9,             // 0x12: XK_9
      XK_0,             // 0x13: XK_0
      XK_minus,         // 0x14: XK_minus
      XK_equal,         // 0x15: XK_equal
      XK_BackSpace,     // 0x16: XK_BackSpace
      XK_Tab,           // 0x17: XK_Tab
      XK_q,             // 0x18: XK_q
      XK_w,             // 0x19: XK_w
      XK_e,             // 0x1A: XK_e
      XK_r,             // 0x1B: XK_r
      XK_t,             // 0x1C: XK_t
      XK_y,             // 0x1D: XK_y
      XK_u,             // 0x1E: XK_u
      XK_i,             // 0x1F: XK_i
      XK_o,             // 0x20: XK_o
      XK_p,             // 0x21: XK_p
      XK_bracketleft,   // 0x22: XK_bracketleft
      XK_bracketright,  // 0x23: XK_bracketright
      XK_Return,        // 0x24: XK_Return
      XK_Control_L,     // 0x25: XK_Control_L
      XK_a,             // 0x26: XK_a
      XK_s,             // 0x27: XK_s
      XK_d,             // 0x28: XK_d
      XK_f,             // 0x29: XK_f
      XK_g,             // 0x2A: XK_g
      XK_h,             // 0x2B: XK_h
      XK_j,             // 0x2C: XK_j
      XK_k,             // 0x2D: XK_k
      XK_l,             // 0x2E: XK_l
      XK_semicolon,     // 0x2F: XK_semicolon
      XK_apostrophe,    // 0x30: XK_apostrophe
      XK_grave,         // 0x31: XK_grave
      XK_Shift_L,       // 0x32: XK_Shift_L
      XK_backslash,     // 0x33: XK_backslash
      XK_z,             // 0x34: XK_z
      XK_x,             // 0x35: XK_x
      XK_c,             // 0x36: XK_c
      XK_v,             // 0x37: XK_v
      XK_b,             // 0x38: XK_b
      XK_n,             // 0x39: XK_n
      XK_m,             // 0x3A: XK_m
      XK_comma,         // 0x3B: XK_comma
      XK_period,        // 0x3C: XK_period
      XK_slash,         // 0x3D: XK_slash
      XK_Shift_R,       // 0x3E: XK_Shift_R
      0,                // 0x3F: XK_KP_Multiply
      XK_Alt_L,         // 0x40: XK_Alt_L
      XK_space,         // 0x41: XK_space
      XK_Caps_Lock,     // 0x42: XK_Caps_Lock
      XK_F1,            // 0x43: XK_F1
      XK_F2,            // 0x44: XK_F2
      XK_F3,            // 0x45: XK_F3
      XK_F4,            // 0x46: XK_F4
      XK_F5,            // 0x47: XK_F5
      XK_F6,            // 0x48: XK_F6
      XK_F7,            // 0x49: XK_F7
      XK_F8,            // 0x4A: XK_F8
      XK_F9,            // 0x4B: XK_F9
      XK_F10,           // 0x4C: XK_F10
      XK_Num_Lock,      // 0x4D: XK_Num_Lock
      XK_Scroll_Lock,   // 0x4E: XK_Scroll_Lock
  };

  return hardware_code < SB_ARRAY_SIZE(kHardwareKeycodeMap)
             ? kHardwareKeycodeMap[hardware_code]
             : 0;
}

SbKey KeysymToSbKey(KeySym keysym) {
  switch (keysym) {
    case XK_BackSpace:
      return kSbKeyBack;
    case XK_Delete:
    case XK_KP_Delete:
      return kSbKeyDelete;
    case XK_Tab:
    case XK_KP_Tab:
    case XK_ISO_Left_Tab:
    case XK_3270_BackTab:
      return kSbKeyTab;
    case XK_Linefeed:
    case XK_Return:
    case XK_KP_Enter:
    case XK_ISO_Enter:
      return kSbKeyReturn;
    case XK_Clear:
    case XK_KP_Begin:  // NumPad 5 without Num Lock, for crosbug.com/29169.
      return kSbKeyClear;
    case XK_KP_Space:
    case XK_space:
      return kSbKeySpace;
    case XK_Home:
    case XK_KP_Home:
      return kSbKeyHome;
    case XK_End:
    case XK_KP_End:
      return kSbKeyEnd;
    case XK_Page_Up:
    case XK_KP_Page_Up:  // aka XK_KP_Prior
      return kSbKeyPrior;
    case XK_Page_Down:
    case XK_KP_Page_Down:  // aka XK_KP_Next
      return kSbKeyNext;
    case XK_Left:
    case XK_KP_Left:
      return kSbKeyLeft;
    case XK_Right:
    case XK_KP_Right:
      return kSbKeyRight;
    case XK_Down:
    case XK_KP_Down:
      return kSbKeyDown;
    case XK_Up:
    case XK_KP_Up:
      return kSbKeyUp;
    case XK_Escape:
      return kSbKeyEscape;
    case XK_Kana_Lock:
    case XK_Kana_Shift:
      return kSbKeyKana;
    case XK_Hangul:
      return kSbKeyHangul;
    case XK_Hangul_Hanja:
      return kSbKeyHanja;
    case XK_Kanji:
      return kSbKeyKanji;
    case XK_Henkan:
      return kSbKeyConvert;
    case XK_Muhenkan:
      return kSbKeyNonconvert;
    case XK_Zenkaku_Hankaku:
      return kSbKeyDbeDbcschar;
    case XK_A:
    case XK_a:
      return kSbKeyA;
    case XK_B:
    case XK_b:
      return kSbKeyB;
    case XK_C:
    case XK_c:
      return kSbKeyC;
    case XK_D:
    case XK_d:
      return kSbKeyD;
    case XK_E:
    case XK_e:
      return kSbKeyE;
    case XK_F:
    case XK_f:
      return kSbKeyF;
    case XK_G:
    case XK_g:
      return kSbKeyG;
    case XK_H:
    case XK_h:
      return kSbKeyH;
    case XK_I:
    case XK_i:
      return kSbKeyI;
    case XK_J:
    case XK_j:
      return kSbKeyJ;
    case XK_K:
    case XK_k:
      return kSbKeyK;
    case XK_L:
    case XK_l:
      return kSbKeyL;
    case XK_M:
    case XK_m:
      return kSbKeyM;
    case XK_N:
    case XK_n:
      return kSbKeyN;
    case XK_O:
    case XK_o:
      return kSbKeyO;
    case XK_P:
    case XK_p:
      return kSbKeyP;
    case XK_Q:
    case XK_q:
      return kSbKeyQ;
    case XK_R:
    case XK_r:
      return kSbKeyR;
    case XK_S:
    case XK_s:
      return kSbKeyS;
    case XK_T:
    case XK_t:
      return kSbKeyT;
    case XK_U:
    case XK_u:
      return kSbKeyU;
    case XK_V:
    case XK_v:
      return kSbKeyV;
    case XK_W:
    case XK_w:
      return kSbKeyW;
    case XK_X:
    case XK_x:
      return kSbKeyX;
    case XK_Y:
    case XK_y:
      return kSbKeyY;
    case XK_Z:
    case XK_z:
      return kSbKeyZ;

    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<SbKey>(kSbKey0 + (keysym - XK_0));

    case XK_parenright:
      return kSbKey0;
    case XK_exclam:
      return kSbKey1;
    case XK_at:
      return kSbKey2;
    case XK_numbersign:
      return kSbKey3;
    case XK_dollar:
      return kSbKey4;
    case XK_percent:
      return kSbKey5;
    case XK_asciicircum:
      return kSbKey6;
    case XK_ampersand:
      return kSbKey7;
    case XK_asterisk:
      return kSbKey8;
    case XK_parenleft:
      return kSbKey9;

    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<SbKey>(kSbKeyNumpad0 + (keysym - XK_KP_0));

    case XK_multiply:
    case XK_KP_Multiply:
      return kSbKeyMultiply;
    case XK_KP_Add:
      return kSbKeyAdd;
    case XK_KP_Separator:
      return kSbKeySeparator;
    case XK_KP_Subtract:
      return kSbKeySubtract;
    case XK_KP_Decimal:
      return kSbKeyDecimal;
    case XK_KP_Divide:
      return kSbKeyDivide;
    case XK_KP_Equal:
    case XK_equal:
    case XK_plus:
      return kSbKeyOemPlus;
    case XK_comma:
    case XK_less:
      return kSbKeyOemComma;
    case XK_minus:
    case XK_underscore:
      return kSbKeyOemMinus;
    case XK_greater:
    case XK_period:
      return kSbKeyOemPeriod;
    case XK_colon:
    case XK_semicolon:
      return kSbKeyOem1;
    case XK_question:
    case XK_slash:
      return kSbKeyOem2;
    case XK_asciitilde:
    case XK_quoteleft:
      return kSbKeyOem3;
    case XK_bracketleft:
    case XK_braceleft:
      return kSbKeyOem4;
    case XK_backslash:
    case XK_bar:
      return kSbKeyOem5;
    case XK_bracketright:
    case XK_braceright:
      return kSbKeyOem6;
    case XK_quoteright:
    case XK_quotedbl:
      return kSbKeyOem7;
    case XK_Shift_L:
    case XK_Shift_R:
      return kSbKeyShift;
    case XK_Control_L:
    case XK_Control_R:
      return kSbKeyControl;
    case XK_Meta_L:
    case XK_Meta_R:
    case XK_Alt_L:
    case XK_Alt_R:
      return kSbKeyMenu;
    case XK_Pause:
      return kSbKeyPause;
    case XK_Caps_Lock:
      return kSbKeyCapital;
    case XK_Num_Lock:
      return kSbKeyNumlock;
    case XK_Scroll_Lock:
      return kSbKeyScroll;
    case XK_Select:
      return kSbKeySelect;
    case XK_Print:
      return kSbKeyPrint;
    case XK_Execute:
      return kSbKeyExecute;
    case XK_Insert:
    case XK_KP_Insert:
      return kSbKeyInsert;
    case XK_Help:
      return kSbKeyHelp;
    case XK_Super_L:
      return kSbKeyLwin;
    case XK_Super_R:
      return kSbKeyRwin;
    case XK_Menu:
      return kSbKeyApps;
    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<SbKey>(kSbKeyF1 + (keysym - XK_F1));
    case XK_KP_F1:
    case XK_KP_F2:
    case XK_KP_F3:
    case XK_KP_F4:
      return static_cast<SbKey>(kSbKeyF1 + (keysym - XK_KP_F1));

    // 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 kSbKeyF13;
    case XF86XK_Launch5:
      return kSbKeyF14;
    case XF86XK_Launch6:
      return kSbKeyF15;
    case XF86XK_Launch7:
      return kSbKeyF16;
    case XF86XK_Launch8:
      return kSbKeyF17;
    case XF86XK_Launch9:
      return kSbKeyF18;

    // For supporting multimedia buttons on a USB keyboard.
    case XF86XK_Back:
      return kSbKeyBrowserBack;
    case XF86XK_Forward:
      return kSbKeyBrowserForward;
    case XF86XK_Reload:
      return kSbKeyBrowserRefresh;
    case XF86XK_Stop:
      return kSbKeyBrowserStop;
    case XF86XK_Search:
      return kSbKeyBrowserSearch;
    case XF86XK_Favorites:
      return kSbKeyBrowserFavorites;
    case XF86XK_HomePage:
      return kSbKeyBrowserHome;
    case XF86XK_AudioMute:
      return kSbKeyVolumeMute;
    case XF86XK_AudioLowerVolume:
      return kSbKeyVolumeDown;
    case XF86XK_AudioRaiseVolume:
      return kSbKeyVolumeUp;
    case XF86XK_AudioNext:
      return kSbKeyMediaNextTrack;
    case XF86XK_AudioPrev:
      return kSbKeyMediaPrevTrack;
    case XF86XK_AudioStop:
      return kSbKeyMediaStop;
    case XF86XK_AudioPlay:
      return kSbKeyMediaPlayPause;
    case XF86XK_Mail:
      return kSbKeyMediaLaunchMail;
    case XF86XK_LaunchA:  // F3 on an Apple keyboard.
      return kSbKeyMediaLaunchApp1;
    case XF86XK_LaunchB:  // F4 on an Apple keyboard.
    case XF86XK_Calculator:
      return kSbKeyMediaLaunchApp2;
    case XF86XK_WLAN:
      return kSbKeyWlan;
    case XF86XK_PowerOff:
      return kSbKeyPower;
    case XF86XK_MonBrightnessDown:
      return kSbKeyBrightnessDown;
    case XF86XK_MonBrightnessUp:
      return kSbKeyBrightnessUp;
    case XF86XK_KbdBrightnessDown:
      return kSbKeyKbdBrightnessDown;
    case XF86XK_KbdBrightnessUp:
      return kSbKeyKbdBrightnessUp;
  }
  SB_DLOG(WARNING) << "Unknown keysym: 0x" << std::hex << keysym;
  return kSbKeyUnknown;
}  // NOLINT(readability/fn_size)

// Get a SbKey from an XKeyEvent.
SbKey XKeyEventToSbKey(XKeyEvent* event) {
  // XLookupKeysym does not take into consideration the state of the lock/shift
  // etc. keys. So it is necessary to use XLookupString instead.
  KeySym keysym = XK_VoidSymbol;
  XLookupString(event, NULL, 0, &keysym, NULL);
  SbKey key = KeysymToSbKey(keysym);
  if (key == kSbKeyUnknown) {
    keysym = HardwareKeycodeToDefaultXKeysym(event->keycode);
    key = KeysymToSbKey(keysym);
  }

  return key;
}

bool XButtonEventIsWheelEvent(XButtonEvent* event) {
  // Buttons 4, 5, 6, and 7 are wheel events.
  return event->button >= 4 && event->button <= 7;
}

enum {
  kWheelUpButton = 4,
  kWheelDownButton = 5,
  kWheelLeftButton = 6,
  kWheelRightButton = 7,
  kPointerBackButton = 8,
  kPointerForwardButton = 9,
};

SbKey XButtonEventToSbKey(XButtonEvent* event) {
  SbKey key;
  switch (event->button) {
    case Button1:
      return kSbKeyMouse1;
    case Button2:
      return kSbKeyMouse2;
    case Button3:
      return kSbKeyMouse3;
    case kWheelUpButton:
      return kSbKeyUp;
    case kWheelDownButton:
      return kSbKeyDown;
    case kWheelLeftButton:
      return kSbKeyLeft;
    case kWheelRightButton:
      return kSbKeyRight;
    case kPointerBackButton:
      return kSbKeyBrowserBack;
    case kPointerForwardButton:
      return kSbKeyBrowserForward;
    default:
      return kSbKeyUnknown;
  }
  return key;
}

// Get a SbKeyLocation from an XKeyEvent.
SbKeyLocation XKeyEventToSbKeyLocation(XKeyEvent* event) {
  KeySym keysym = XK_VoidSymbol;
  XLookupString(event, NULL, 0, &keysym, NULL);
  switch (keysym) {
    case XK_Shift_L:
    case XK_Control_L:
    case XK_Meta_L:
    case XK_Alt_L:
      return kSbKeyLocationLeft;
    case XK_Shift_R:
    case XK_Control_R:
    case XK_Meta_R:
    case XK_Alt_R:
      return kSbKeyLocationRight;
  }

  return kSbKeyLocationUnspecified;
}

// Get an SbKeyModifiers from an XKeyEvent.
unsigned int XEventStateToSbKeyModifiers(unsigned int state) {
  unsigned int key_modifiers = kSbKeyModifiersNone;
  if (state & Mod1Mask) {
    key_modifiers |= kSbKeyModifiersAlt;
  }
  if (state & ControlMask) {
    key_modifiers |= kSbKeyModifiersCtrl;
  }
  if (state & Mod4Mask) {
    key_modifiers |= kSbKeyModifiersMeta;
  }
  if (state & ShiftMask) {
    key_modifiers |= kSbKeyModifiersShift;
  }
  if (state & Button1Mask) {
    key_modifiers |= kSbKeyModifiersPointerButtonLeft;
  }
  if (state & Button2Mask) {
    key_modifiers |= kSbKeyModifiersPointerButtonMiddle;
  }
  if (state & Button3Mask) {
    key_modifiers |= kSbKeyModifiersPointerButtonRight;
  }
  // Note: Button 4 and button 5 represent vertical wheel motion. As a result,
  // Button4Mask and Button5Mask do not represent a useful mouse button state
  // since the wheel up and wheel down do not have 'buttons' that can be held
  // down. The state of the Back and Forward mouse buttons is not reported to
  // X11 clients. This is not a hardware limitation, but a result of historical
  // Xorg X11 mouse driver button mapping choices.
  return key_modifiers;
}

SbInputVector XButtonEventToSbInputVectorDelta(XButtonEvent* event) {
  SbInputVector delta = {0, 0};
  switch (event->button) {
    case kWheelUpButton:
      delta.y = -1;
      break;
    case kWheelDownButton:
      delta.y = 1;
      break;
    case kWheelLeftButton:
      delta.x = -1;
      break;
    case kWheelRightButton:
      delta.x = 1;
      break;
  }
  return delta;
}

void XSendAtom(Window window, Atom atom) {
  // XLib is not thread-safe. Since we may be coming from another thread, we
  // have to open another connection to the display to inject the wake-up event.
  Display* display = XOpenDisplay(NULL);
  SB_DCHECK(display);
  XClientMessageEvent event = {0};
  event.type = ClientMessage;
  event.message_type = atom;
  event.window = window;
  event.format = 32;
  XSendEvent(display, event.window, 0, 0, reinterpret_cast<XEvent*>(&event));
  XFlush(display);
  XCloseDisplay(display);
}

// Remain compatible with the older glibc found on previous Ubuntu distros.
__asm__(".symver quick_exit,quick_exit@GLIBC_2.10");

// X IO error handler. Called if we lose our connection to the X server.
int IOErrorHandler(Display* display) {
  // Not much we can do here except immediately exit.
  SB_DSTACK(ERROR);
  quick_exit(0);
  return 0;
}

int ErrorHandler(Display* display, XErrorEvent* event) {
  char error_text[256] = {0};
  XGetErrorText(event->display, event->error_code, error_text,
                SB_ARRAY_SIZE_INT(error_text));
  SB_DLOG(ERROR) << "X11 Error: " << error_text;
  SB_DLOG(ERROR) << "display=" << XDisplayString(event->display);
  SB_DLOG(ERROR) << "serial=" << event->serial;
  SB_DLOG(ERROR) << "request=" << static_cast<int>(event->request_code);
  SB_DLOG(ERROR) << "minor=" << static_cast<int>(event->minor_code);
  SB_DLOG(ERROR) << "resourceid=" << event->resourceid;
  SbSystemBreakIntoDebugger();
  return 0;
}

}  // namespace

using shared::starboard::player::filter::CpuVideoFrame;

#if SB_MODULAR_BUILD
ApplicationX11::ApplicationX11(SbEventHandleCallback sb_event_handle_callback)
#else
ApplicationX11::ApplicationX11()
#endif  // SB_MODULAR_BUILD
    : wake_up_atom_(None),
      wm_delete_atom_(None),
#if SB_API_VERSION >= 13
      wm_change_state_atom_(None),
#endif  // SB_API_VERSION >= 13
#if SB_MODULAR_BUILD
      QueueApplication(sb_event_handle_callback),
#endif  // SB_MODULAR_BUILD
      composite_event_id_(kSbEventIdInvalid),
      display_(NULL),
      paste_buffer_key_release_pending_(false) {
  SbAudioSinkPrivate::Initialize();
#if SB_API_VERSION >= 13
  NetworkNotifier::GetOrCreateInstance();
#endif
}

ApplicationX11::~ApplicationX11() {
  SbAudioSinkPrivate::TearDown();
}

SbWindow ApplicationX11::CreateWindow(const SbWindowOptions* options) {
  if (!EnsureX()) {
    return kSbWindowInvalid;
  }

  SbWindow window = new SbWindowPrivate(display_, options);
  windows_.push_back(window);
  if (!dev_input_) {
    // evdev input will be sent to the first created window only.
    dev_input_.reset(DevInput::Create(window, ConnectionNumber(display_)));
  }
  touchscreen_pointer_ = GetCommandLine()->HasSwitch(kTouchscreenPointerSwitch);
  return window;
}

bool ApplicationX11::DestroyWindow(SbWindow window) {
  if (!SbWindowIsValid(window)) {
    return false;
  }

  SB_DCHECK(display_);
  SbWindowVector::iterator iterator =
      std::find(windows_.begin(), windows_.end(), window);
  SB_DCHECK(iterator != windows_.end());
  windows_.erase(iterator);

  if (windows_.empty()) {
    SB_DCHECK(dev_input_);
    dev_input_.reset();
  }

  delete window;
  if (windows_.empty()) {
    StopX();
  }
  return true;
}

SbWindow ApplicationX11::GetFirstWindow() {
  if (windows_.empty()) {
    return kSbWindowInvalid;
  }

  return windows_.front();
}

namespace {
void CompositeCallback(void* context) {
  ApplicationX11* application = reinterpret_cast<ApplicationX11*>(context);
  application->Composite();
}
}  // namespace

void ApplicationX11::Composite() {
  if (!windows_.empty()) {
    SbWindow window = windows_[0];
    if (SbWindowIsValid(window)) {
      ScopedLock lock(frame_mutex_);

      window->BeginComposite();
      for (auto& frame_info : current_video_bounds_) {
        // Get the cached video frame.
        SbPlayer player = frame_info.player;
        scoped_refptr<CpuVideoFrame> cpu_video_frame =
            static_cast<CpuVideoFrame*>(current_video_frames_[player].get());
        if (!cpu_video_frame) {
          // Need to generate a new video frame.
          cpu_video_frame =
              static_cast<CpuVideoFrame*>(next_video_frames_[player].get());
          if (!cpu_video_frame) {
            // The player was already destroyed, so nothing to render.
            continue;
          }
          if (cpu_video_frame->format() != CpuVideoFrame::kBGRA32) {
            cpu_video_frame =
                cpu_video_frame->ConvertTo(CpuVideoFrame::kBGRA32);
          }
          current_video_frames_[player] = cpu_video_frame;
        }
        window->CompositeVideoFrame(frame_info.x, frame_info.y,
                                    frame_info.width, frame_info.height,
                                    cpu_video_frame);
      }
      window->EndComposite();
    }
  }
  composite_event_id_ =
      SbEventSchedule(&CompositeCallback, this, kSbTimeSecond / 60);
}

void ApplicationX11::AcceptFrame(SbPlayer player,
                                 const scoped_refptr<VideoFrame>& frame,
                                 int z_index,
                                 int x,
                                 int y,
                                 int width,
                                 int height) {
  ScopedLock lock(frame_mutex_);

  if (frame->is_end_of_stream()) {
    // Remove all references the the player and its resources.
    next_video_frames_.erase(player);
    next_video_bounds_.erase(player);
  } else {
    next_video_frames_[player] = frame;
  }

  // Invalidate the cache of this player's current frame.
  current_video_frames_.erase(player);
}

void ApplicationX11::SwapBuffersBegin() {
  // Prevent compositing while the GL layer is changing.
  frame_mutex_.Acquire();
}

void ApplicationX11::SwapBuffersEnd() {
  // Determine the video bounds that should be used with the new GL layer.

  // Sort the video bounds according to their z_index.
  current_video_bounds_.clear();
  for (auto& iter : next_video_bounds_) {
    const FrameInfo& bounds = iter.second;
    auto position = current_video_bounds_.begin();
    while (position != current_video_bounds_.end()) {
      if (bounds.z_index < position->z_index) {
        break;
      }
      ++position;
    }
    current_video_bounds_.insert(position, bounds);
  }

  frame_mutex_.Release();
}

void ApplicationX11::PlayerSetBounds(SbPlayer player,
                                     int z_index,
                                     int x,
                                     int y,
                                     int width,
                                     int height) {
  ScopedLock lock(frame_mutex_);

  bool player_exists =
      next_video_bounds_.find(player) != next_video_bounds_.end();

  FrameInfo& frame_info = next_video_bounds_[player];
  frame_info.player = player;
  frame_info.z_index = z_index;
  frame_info.x = x;
  frame_info.y = y;
  frame_info.width = width;
  frame_info.height = height;

  if (player_exists) {
    return;
  }

  // The bounds should only take effect once the UI frame is submitted.  But we
  // apply the bounds immediately if it is the first time the bounds for this
  // player are set.
  auto position = current_video_bounds_.begin();
  while (position != current_video_bounds_.end()) {
    if (frame_info.z_index < position->z_index) {
      break;
    }
    ++position;
  }
  current_video_bounds_.insert(position, frame_info);
}

void ApplicationX11::Initialize() {
  // Mesa is installed on Ubuntu machines and will be selected as the default
  // EGL implementation.  This Mesa environment variable ensures that Mesa
  // internally uses its Gallium drivers for its EGL implementation.
  if (getenv("EGL_DRIVER") == NULL) {
    // putenv takes a non-const char *, and holds onto it indefinitely, so we
    // first create global writable memory and then copy the literal into it.
    static char to_put[] = "EGL_DRIVER=egl_gallium";
    SB_CHECK(!putenv(to_put));
  }
}

void ApplicationX11::Teardown() {
  StopX();
}

bool ApplicationX11::MayHaveSystemEvents() {
  return display_ && !windows_.empty();
}

shared::starboard::Application::Event*
ApplicationX11::WaitForSystemEventWithTimeout(SbTime time) {
  SB_DCHECK(display_);

  shared::starboard::Application::Event* pending_event = GetPendingEvent();
  if (pending_event) {
    return pending_event;
  }

  SB_DCHECK(dev_input_);
  shared::starboard::Application::Event* evdev_event =
      dev_input_->WaitForSystemEventWithTimeout(time);

  if (!evdev_event && XPending(display_) != 0) {
    XEvent x_event;
    XNextEvent(display_, &x_event);
    return XEventToEvent(&x_event);
  }

  return evdev_event;
}

void ApplicationX11::WakeSystemEventWait() {
  SB_DCHECK(!windows_.empty());
  XSendAtom((*windows_.begin())->window, wake_up_atom_);
  SB_DCHECK(dev_input_);
  dev_input_->WakeSystemEventWait();
}

bool ApplicationX11::EnsureX() {
  // TODO: Consider thread-safety.
  if (display_) {
    return true;
  }

  XInitThreads();
  XSetIOErrorHandler(IOErrorHandler);
  XSetErrorHandler(ErrorHandler);
  display_ = XOpenDisplay(NULL);
  if (!display_) {
    const char* display_environment = getenv("DISPLAY");
    if (display_environment == NULL) {
      SB_LOG(ERROR) << "Unable to open display, DISPLAY not set.";
    } else {
      SB_LOG(ERROR) << "Unable to open display " << display_environment << ".";
    }
    return false;
  }

  // Disable keyup events on auto-repeat to match Windows.
  // Otherwise when holding down a key, we get a keyup event before
  // each keydown event.
  int supported = false;
  XkbSetDetectableAutoRepeat(display_, True, &supported);
  SB_DCHECK(supported);

  wake_up_atom_ = XInternAtom(display_, "WakeUpAtom", 0);
  wm_delete_atom_ = XInternAtom(display_, "WM_DELETE_WINDOW", True);
#if SB_API_VERSION >= 13
  wm_change_state_atom_ = XInternAtom(display_, "WM_CHANGE_STATE", True);
#endif  // SB_API_VERSION >= 13

  Composite();

  return true;
}

void ApplicationX11::StopX() {
  if (!display_) {
    return;
  }

  SbEventCancel(composite_event_id_);
  composite_event_id_ = kSbEventIdInvalid;

  XCloseDisplay(display_);
  display_ = NULL;
  wake_up_atom_ = None;
  wm_delete_atom_ = None;
#if SB_API_VERSION >= 13
  wm_change_state_atom_ = None;
#endif  // SB_API_VERSION >= 13
}

shared::starboard::Application::Event* ApplicationX11::GetPendingEvent() {
  typedef struct {
    SbKey key;
    unsigned int modifiers;
  } KeyModifierData;

  static const KeyModifierData ASCIIKeyModifierMap[] = {
      // 0x00 ... 0x0F
      /* .0 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .1 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .2 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .3 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .4 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .5 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .6 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .7 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .8 */ {kSbKeyBackspace, kSbKeyModifiersNone},
      /* .9 */ {kSbKeyTab, kSbKeyModifiersNone},
      /* .A */ {kSbKeyBacktab, kSbKeyModifiersNone},
      /* .B */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .C */ {kSbKeyClear, kSbKeyModifiersNone},
      /* .D */ {kSbKeyReturn, kSbKeyModifiersNone},
      /* .E */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .F */ {kSbKeyUnknown, kSbKeyModifiersNone},

      // 0x10 ... 0x1F
      /* .0 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .1 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .2 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .3 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .4 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .5 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .6 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .7 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .8 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .9 */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .A */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .B */ {kSbKeyEscape, kSbKeyModifiersNone},
      /* .C */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .D */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .E */ {kSbKeyUnknown, kSbKeyModifiersNone},
      /* .F */ {kSbKeyUnknown, kSbKeyModifiersNone},

      // 0x20 ... 0x2F
      /* .0 */ {kSbKeySpace, kSbKeyModifiersNone},
      /* .1 */ {kSbKey1, kSbKeyModifiersShift},
      /* .2 */ {kSbKeyOem7, kSbKeyModifiersShift},
      /* .3 */ {kSbKey3, kSbKeyModifiersShift},
      /* .4 */ {kSbKey4, kSbKeyModifiersShift},
      /* .5 */ {kSbKey5, kSbKeyModifiersShift},
      /* .6 */ {kSbKey7, kSbKeyModifiersShift},
      /* .7 */ {kSbKeyOem7, kSbKeyModifiersNone},
      /* .8 */ {kSbKey9, kSbKeyModifiersShift},
      /* .9 */ {kSbKey0, kSbKeyModifiersShift},
      /* .A */ {kSbKey8, kSbKeyModifiersShift},
      /* .B */ {kSbKeyOemPlus, kSbKeyModifiersShift},
      /* .C */ {kSbKeyOemComma, kSbKeyModifiersNone},
      /* .D */ {kSbKeyOemMinus, kSbKeyModifiersNone},
      /* .E */ {kSbKeyOemPeriod, kSbKeyModifiersNone},
      /* .F */ {kSbKeyOem2, kSbKeyModifiersNone},

      // 0x30 ... 0x3F
      /* .0 */ {kSbKey0, kSbKeyModifiersNone},
      /* .1 */ {kSbKey1, kSbKeyModifiersNone},
      /* .2 */ {kSbKey2, kSbKeyModifiersNone},
      /* .3 */ {kSbKey3, kSbKeyModifiersNone},
      /* .4 */ {kSbKey4, kSbKeyModifiersNone},
      /* .5 */ {kSbKey5, kSbKeyModifiersNone},
      /* .6 */ {kSbKey6, kSbKeyModifiersNone},
      /* .7 */ {kSbKey7, kSbKeyModifiersNone},
      /* .8 */ {kSbKey8, kSbKeyModifiersNone},
      /* .9 */ {kSbKey9, kSbKeyModifiersNone},
      /* .A */ {kSbKeyOem1, kSbKeyModifiersShift},
      /* .B */ {kSbKeyOem1, kSbKeyModifiersNone},
      /* .C */ {kSbKeyOemComma, kSbKeyModifiersShift},
      /* .D */ {kSbKeyOemPlus, kSbKeyModifiersNone},
      /* .E */ {kSbKeyOemPeriod, kSbKeyModifiersShift},
      /* .F */ {kSbKeyOem2, kSbKeyModifiersShift},

      // 0x40 ... 0x4F
      /* .0 */ {kSbKey2, kSbKeyModifiersShift},
      /* .1 */ {kSbKeyA, kSbKeyModifiersShift},
      /* .2 */ {kSbKeyB, kSbKeyModifiersShift},
      /* .3 */ {kSbKeyC, kSbKeyModifiersShift},
      /* .4 */ {kSbKeyD, kSbKeyModifiersShift},
      /* .5 */ {kSbKeyE, kSbKeyModifiersShift},
      /* .6 */ {kSbKeyF, kSbKeyModifiersShift},
      /* .7 */ {kSbKeyG, kSbKeyModifiersShift},
      /* .8 */ {kSbKeyH, kSbKeyModifiersShift},
      /* .9 */ {kSbKeyI, kSbKeyModifiersShift},
      /* .A */ {kSbKeyJ, kSbKeyModifiersShift},
      /* .B */ {kSbKeyK, kSbKeyModifiersShift},
      /* .C */ {kSbKeyL, kSbKeyModifiersShift},
      /* .D */ {kSbKeyM, kSbKeyModifiersShift},
      /* .E */ {kSbKeyN, kSbKeyModifiersShift},
      /* .F */ {kSbKeyO, kSbKeyModifiersShift},

      // 0x50 ... 0x5F
      /* .0 */ {kSbKeyP, kSbKeyModifiersShift},
      /* .1 */ {kSbKeyQ, kSbKeyModifiersShift},
      /* .2 */ {kSbKeyR, kSbKeyModifiersShift},
      /* .3 */ {kSbKeyS, kSbKeyModifiersShift},
      /* .4 */ {kSbKeyT, kSbKeyModifiersShift},
      /* .5 */ {kSbKeyU, kSbKeyModifiersShift},
      /* .6 */ {kSbKeyV, kSbKeyModifiersShift},
      /* .7 */ {kSbKeyW, kSbKeyModifiersShift},
      /* .8 */ {kSbKeyX, kSbKeyModifiersShift},
      /* .9 */ {kSbKeyY, kSbKeyModifiersShift},
      /* .A */ {kSbKeyZ, kSbKeyModifiersShift},
      /* .B */ {kSbKeyOem4, kSbKeyModifiersNone},
      /* .C */ {kSbKeyOem5, kSbKeyModifiersNone},
      /* .D */ {kSbKeyOem6, kSbKeyModifiersNone},
      /* .E */ {kSbKey6, kSbKeyModifiersShift},
      /* .F */ {kSbKeyOemMinus, kSbKeyModifiersShift},

      // 0x60 ... 0x6F
      /* .0 */ {kSbKeyOem3, kSbKeyModifiersNone},
      /* .1 */ {kSbKeyA, kSbKeyModifiersNone},
      /* .2 */ {kSbKeyB, kSbKeyModifiersNone},
      /* .3 */ {kSbKeyC, kSbKeyModifiersNone},
      /* .4 */ {kSbKeyD, kSbKeyModifiersNone},
      /* .5 */ {kSbKeyE, kSbKeyModifiersNone},
      /* .6 */ {kSbKeyF, kSbKeyModifiersNone},
      /* .7 */ {kSbKeyG, kSbKeyModifiersNone},
      /* .8 */ {kSbKeyH, kSbKeyModifiersNone},
      /* .9 */ {kSbKeyI, kSbKeyModifiersNone},
      /* .A */ {kSbKeyJ, kSbKeyModifiersNone},
      /* .B */ {kSbKeyK, kSbKeyModifiersNone},
      /* .C */ {kSbKeyL, kSbKeyModifiersNone},
      /* .D */ {kSbKeyM, kSbKeyModifiersNone},
      /* .E */ {kSbKeyN, kSbKeyModifiersNone},
      /* .F */ {kSbKeyO, kSbKeyModifiersNone},

      // 0x70 ... 0x7F
      /* .0 */ {kSbKeyP, kSbKeyModifiersNone},
      /* .1 */ {kSbKeyQ, kSbKeyModifiersNone},
      /* .2 */ {kSbKeyR, kSbKeyModifiersNone},
      /* .3 */ {kSbKeyS, kSbKeyModifiersNone},
      /* .4 */ {kSbKeyT, kSbKeyModifiersNone},
      /* .5 */ {kSbKeyU, kSbKeyModifiersNone},
      /* .6 */ {kSbKeyV, kSbKeyModifiersNone},
      /* .7 */ {kSbKeyW, kSbKeyModifiersNone},
      /* .8 */ {kSbKeyX, kSbKeyModifiersNone},
      /* .9 */ {kSbKeyY, kSbKeyModifiersNone},
      /* .A */ {kSbKeyZ, kSbKeyModifiersNone},
      /* .B */ {kSbKeyOem4, kSbKeyModifiersShift},
      /* .C */ {kSbKeyOem5, kSbKeyModifiersShift},
      /* .D */ {kSbKeyOem6, kSbKeyModifiersShift},
      /* .E */ {kSbKeyOem3, kSbKeyModifiersShift},
      /* .F */ {kSbKeyUnknown, kSbKeyModifiersNone},
  };

  KeyModifierData key_modifiers;
  unsigned char character;
  while (!paste_buffer_pending_characters_.empty()) {
    character = paste_buffer_pending_characters_.front();
    if (character < SB_ARRAY_SIZE(ASCIIKeyModifierMap)) {
      key_modifiers = ASCIIKeyModifierMap[character];
      if (key_modifiers.key != kSbKeyUnknown) {
        break;
      }
    }
    paste_buffer_pending_characters_.pop();
  }

  if (paste_buffer_pending_characters_.empty()) {
    return NULL;
  }

  if (paste_buffer_key_release_pending_) {
    paste_buffer_pending_characters_.pop();
  }

  scoped_ptr<SbInputData> data(new SbInputData());
  memset(data.get(), 0, sizeof(*data));
#if SB_API_VERSION < 13
  data->timestamp = SbTimeGetMonotonicNow();
#endif  // SB_API_VERSION < 13
  data->window = windows_[0];
  SB_DCHECK(SbWindowIsValid(data->window));
  data->type = paste_buffer_key_release_pending_ ? kSbInputEventTypeUnpress
                                                 : kSbInputEventTypePress;
  data->device_type = kSbInputDeviceTypeKeyboard;
  data->device_id = kKeyboardDeviceId;
  data->key = key_modifiers.key;
  data->key_location = kSbKeyLocationUnspecified;
  data->key_modifiers = key_modifiers.modifiers;
  data->position.x = 0;
  data->position.y = 0;

  paste_buffer_key_release_pending_ = !paste_buffer_key_release_pending_;
  return new Event(kSbEventTypeInput, data.release(),
                   &DeleteDestructor<SbInputData>);
}

shared::starboard::Application::Event* ApplicationX11::XEventToEvent(
    XEvent* x_event) {
  switch (x_event->type) {
    case ClientMessage: {
      const XClientMessageEvent* client_message =
          reinterpret_cast<const XClientMessageEvent*>(x_event);
      if (client_message->message_type == wake_up_atom_) {
        // We've woken up, so our job is done.
        return NULL;
      }

      if (x_event->xclient.data.l[0] == wm_delete_atom_) {
        SB_DLOG(INFO) << "Received WM_DELETE_WINDOW message.";
        // TODO: Expose this as an event to clients.
        Stop(0);
        return NULL;
      }

#if SB_API_VERSION >= 13
      if (client_message->message_type == wm_change_state_atom_) {
        SB_DLOG(INFO) << "Received WM_CHANGE_STATE message.";
        if (x_event->xclient.data.l[0] == IconicState) {
          Reveal(NULL, NULL);
          return NULL;
        } else if (x_event->xclient.data.l[0] == NormalState) {
          Conceal(NULL, NULL);
          return NULL;
        }
      }
#endif  // SB_API_VERSION >= 13

      // Unknown event, ignore.
      return NULL;
    }
    case KeyPress:
    case KeyRelease: {
      // User pressed key.
      XKeyEvent* x_key_event = reinterpret_cast<XKeyEvent*>(x_event);

      SbKey key = XKeyEventToSbKey(x_key_event);
      unsigned int key_modifiers =
          XEventStateToSbKeyModifiers(x_key_event->state);

      bool is_press_event = KeyPress == x_event->type;
      bool is_paste_keypress = is_press_event &&
                               (key_modifiers & kSbKeyModifiersCtrl) &&
                               key == kSbKeyV;
      is_paste_keypress |= is_press_event &&
                           (key_modifiers & kSbKeyModifiersShift) &&
                           key == kSbKeyInsert;
      if (is_paste_keypress) {
        // Handle Ctrl-V or Shift-Insert as paste.
        const Atom xtarget = XInternAtom(x_key_event->display, "TEXT", 0);
        // Request the paste buffer, which will be sent as a separate
        // SelectionNotify XEvent.
        XConvertSelection(x_key_event->display, XA_PRIMARY, xtarget, XA_PRIMARY,
                          x_key_event->window, CurrentTime);
        return NULL;
      }

      scoped_ptr<SbInputData> data(new SbInputData());
      memset(data.get(), 0, sizeof(*data));
#if SB_API_VERSION < 13
      data->timestamp = SbTimeGetMonotonicNow();
#endif  // SB_API_VERSION < 13
      data->window = FindWindow(x_key_event->window);
      SB_DCHECK(SbWindowIsValid(data->window));
      data->type = x_event->type == KeyPress ? kSbInputEventTypePress
                                             : kSbInputEventTypeUnpress;
      data->device_type = kSbInputDeviceTypeKeyboard;
      data->device_id = kKeyboardDeviceId;
      data->key = key;
      data->key_modifiers = key_modifiers;
      data->key_location = XKeyEventToSbKeyLocation(x_key_event);
      data->position.x = x_key_event->x;
      data->position.y = x_key_event->y;
      return new Event(kSbEventTypeInput, data.release(),
                       &DeleteDestructor<SbInputData>);
    }
    case ButtonPress:
    case ButtonRelease: {
      XButtonEvent* x_button_event = reinterpret_cast<XButtonEvent*>(x_event);
      bool is_press_event = ButtonPress == x_event->type;
      bool is_wheel_event = XButtonEventIsWheelEvent(x_button_event);
      if (is_wheel_event && !is_press_event) {
        // unpress events from the wheel are discarded.
        return NULL;
      }
      scoped_ptr<SbInputData> data(new SbInputData());
      memset(data.get(), 0, sizeof(*data));
#if SB_API_VERSION < 13
      data->timestamp = SbTimeGetMonotonicNow();
#endif  // SB_API_VERSION < 13
      data->window = FindWindow(x_button_event->window);
      SB_DCHECK(SbWindowIsValid(data->window));
      data->key = XButtonEventToSbKey(x_button_event);
      data->type =
          is_press_event ? kSbInputEventTypePress : kSbInputEventTypeUnpress;
      data->device_type = touchscreen_pointer_ ? kSbInputDeviceTypeTouchScreen
                                               : kSbInputDeviceTypeMouse;
      if (is_wheel_event) {
        data->pressure = NAN;
        data->size = {NAN, NAN};
        data->tilt = {NAN, NAN};
        data->type = kSbInputEventTypeWheel;
        data->delta = XButtonEventToSbInputVectorDelta(x_button_event);
      }
      data->device_id = kMouseDeviceId;
      data->key_modifiers = XEventStateToSbKeyModifiers(x_button_event->state);
      data->position.x = x_button_event->x;
      data->position.y = x_button_event->y;
      return new Event(kSbEventTypeInput, data.release(),
                       &DeleteDestructor<SbInputData>);
    }
    case MotionNotify: {
      XMotionEvent* x_motion_event = reinterpret_cast<XMotionEvent*>(x_event);
      scoped_ptr<SbInputData> data(new SbInputData());
      memset(data.get(), 0, sizeof(*data));
#if SB_API_VERSION < 13
      data->timestamp = SbTimeGetMonotonicNow();
#endif  // SB_API_VERSION < 13
      data->window = FindWindow(x_motion_event->window);
      SB_DCHECK(SbWindowIsValid(data->window));
      data->pressure = NAN;
      data->size = {NAN, NAN};
      data->tilt = {NAN, NAN};
      data->type = kSbInputEventTypeMove;
      data->device_type = touchscreen_pointer_ ? kSbInputDeviceTypeTouchScreen
                                               : kSbInputDeviceTypeMouse;
      data->device_id = kMouseDeviceId;
      data->key_modifiers = XEventStateToSbKeyModifiers(x_motion_event->state);
      data->position.x = x_motion_event->x;
      data->position.y = x_motion_event->y;
      if (touchscreen_pointer_ && !data->key_modifiers) {
        // For touch screens, only report motion events when a button is
        // pressed.
        return NULL;
      }
      return new Event(kSbEventTypeInput, data.release(),
                       &DeleteDestructor<SbInputData>);
    }
#if SB_API_VERSION >= 13
    case FocusIn: {
      Focus(NULL, NULL);
      return NULL;
    }
    case FocusOut: {
      Blur(NULL, NULL);
      return NULL;
    }
#else
    case FocusIn: {
      Unpause(NULL, NULL);
      return NULL;
    }
    case FocusOut: {
      Pause(NULL, NULL);
      return NULL;
    }
#endif  // SB_API_VERSION >= 13
    case ConfigureNotify: {
      XConfigureEvent* x_configure_event =
          reinterpret_cast<XConfigureEvent*>(x_event);
      scoped_ptr<SbEventWindowSizeChangedData> data(
          new SbEventWindowSizeChangedData());
      data->window = FindWindow(x_configure_event->window);
      bool unhandled_resize = data->window->unhandled_resize;
      data->window->BeginComposite();
      unhandled_resize |= data->window->unhandled_resize;
      if (!unhandled_resize) {
        // Ignore move events.
        return NULL;
      }
      // Get the current window size.
      SbWindowSize window_size;
      SbWindowGetSize(data->window, &window_size);
      data->size = window_size;
      data->window->unhandled_resize = false;
      return new Event(kSbEventTypeWindowSizeChanged, data.release(),
                       &DeleteDestructor<SbInputData>);
    }
    case SelectionNotify: {
      XSelectionEvent* x_selection_event =
          reinterpret_cast<XSelectionEvent*>(x_event);

      unsigned long nitems = 0;       // NOLINT(runtime/int)
      unsigned long bytes_after = 0;  // NOLINT(runtime/int)
      int format = 0;
      unsigned char* property = NULL;
      Atom type = XA_PRIMARY;

      if (XGetWindowProperty(x_selection_event->display,
                             x_selection_event->requestor, XA_PRIMARY, 0, 4096,
                             False, AnyPropertyType, &type, &format, &nitems,
                             &bytes_after, &property)) {
        return NULL;
      }

      if (property && nitems) {
        for (unsigned char* ptr = property; *ptr; ++ptr) {
          paste_buffer_pending_characters_.push(*ptr);
        }
      }
      XFree(property);
      break;
    }
    default: {
      SB_DLOG(INFO) << "Unrecognized event type = " << x_event->type;
      break;
    }
  }

  return NULL;
}

SbWindow ApplicationX11::FindWindow(Window window) {
  for (SbWindowVector::iterator i = windows_.begin(); i != windows_.end();
       ++i) {
    if ((*i)->window == window) {
      return *i;
    }
  }
  return kSbWindowInvalid;
}

}  // namespace x11
}  // namespace shared
}  // namespace starboard
