platform_view_glfw.cc 6.1 KB
Newer Older
1 2 3 4 5
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/linux/platform_view_glfw.h"
6
#include <GLFW/glfw3.h>
A
Adam Barth 已提交
7
#include "flutter/common/threads.h"
8
#include "flutter/shell/gpu/gpu_rasterizer.h"
9 10 11 12 13 14 15 16 17
#include "flutter/shell/platform/linux/glfw_service_provider.h"

namespace shell {

inline PlatformViewGLFW* ToPlatformView(GLFWwindow* window) {
  return static_cast<PlatformViewGLFW*>(glfwGetWindowUserPointer(window));
}

PlatformViewGLFW::PlatformViewGLFW()
18 19 20 21 22
    : PlatformView(std::make_unique<GPURasterizer>()),
      valid_(false),
      glfw_window_(nullptr),
      buttons_(0),
      weak_factory_(this) {
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
  if (!glfwInit()) {
    return;
  }

  glfw_window_ = glfwCreateWindow(640, 480, "Flutter", NULL, NULL);
  if (glfw_window_ == nullptr) {
    return;
  }

  glfwSetWindowUserPointer(glfw_window_, this);

  glfwSetWindowSizeCallback(
      glfw_window_, [](GLFWwindow* window, int width, int height) {
        ToPlatformView(window)->OnWindowSizeChanged(width, height);
      });

  glfwSetMouseButtonCallback(
      glfw_window_, [](GLFWwindow* window, int button, int action, int mods) {
        ToPlatformView(window)->OnMouseButtonChanged(button, action, mods);
      });

  glfwSetKeyCallback(glfw_window_, [](GLFWwindow* window, int key, int scancode,
                                      int action, int mods) {
    ToPlatformView(window)->OnKeyEvent(key, scancode, action, mods);
  });

  valid_ = true;
}

PlatformViewGLFW::~PlatformViewGLFW() {
  if (glfw_window_ != nullptr) {
    glfwSetWindowUserPointer(glfw_window_, nullptr);
    glfwDestroyWindow(glfw_window_);
    glfw_window_ = nullptr;
  }

  glfwTerminate();
}

void PlatformViewGLFW::ConnectToEngineAndSetupServices() {
  ConnectToEngine(mojo::GetProxy(&engine_));

  mojo::ServiceProviderPtr platform_service_provider;
  new GLFWServiceProvider(mojo::GetProxy(&platform_service_provider));

  sky::ServicesDataPtr services = sky::ServicesData::New();
  services->incoming_services = platform_service_provider.Pass();
  engine_->SetServices(services.Pass());
}

sky::SkyEnginePtr& PlatformViewGLFW::EngineProxy() {
  return engine_;
}

bool PlatformViewGLFW::IsValid() const {
  return valid_;
}

ftl::WeakPtr<PlatformView> PlatformViewGLFW::GetWeakViewPtr() {
  return weak_factory_.GetWeakPtr();
}

85
intptr_t PlatformViewGLFW::GLContextFBO() const {
86 87 88 89
  // The default window bound FBO.
  return 0;
}

90
bool PlatformViewGLFW::GLContextMakeCurrent() {
91 92 93 94
  glfwMakeContextCurrent(glfw_window_);
  return true;
}

95 96 97 98 99
bool PlatformViewGLFW::GLContextClearCurrent() {
  glfwMakeContextCurrent(nullptr);
  return true;
}

100 101 102 103 104
bool PlatformViewGLFW::ResourceContextMakeCurrent() {
  // Resource loading contexts are not supported on this platform.
  return false;
}

105
bool PlatformViewGLFW::GLContextPresent() {
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
  glfwSwapBuffers(glfw_window_);
  return true;
}

void PlatformViewGLFW::RunFromSource(const std::string& main,
                                     const std::string& packages,
                                     const std::string& assets_directory) {}

void PlatformViewGLFW::OnWindowSizeChanged(int width, int height) {
  auto metrics = sky::ViewportMetrics::New();
  metrics->physical_width = width;
  metrics->physical_height = height;
  metrics->device_pixel_ratio = 1.0;
  engine_->OnViewportMetricsChanged(metrics.Pass());
}

void PlatformViewGLFW::OnMouseButtonChanged(int button, int action, int mods) {
A
Adam Barth 已提交
123
  blink::PointerData::Change change = blink::PointerData::Change::kCancel;
124 125
  if (action == GLFW_PRESS) {
    if (!buttons_) {
A
Adam Barth 已提交
126
      change = blink::PointerData::Change::kDown;
127 128 129 130 131
      glfwSetCursorPosCallback(
          glfw_window_, [](GLFWwindow* window, double x, double y) {
            ToPlatformView(window)->OnCursorPosChanged(x, y);
          });
    } else {
A
Adam Barth 已提交
132
      change = blink::PointerData::Change::kMove;
133 134 135 136 137 138 139 140
    }
    // GLFW's button order matches what we want:
    // https://github.com/flutter/engine/blob/master/sky/specs/pointer.md
    // http://www.glfw.org/docs/3.2/group__buttons.html
    buttons_ |= 1 << button;
  } else if (action == GLFW_RELEASE) {
    buttons_ &= ~(1 << button);
    if (!buttons_) {
A
Adam Barth 已提交
141
      change = blink::PointerData::Change::kUp;
142 143
      glfwSetCursorPosCallback(glfw_window_, nullptr);
    } else {
A
Adam Barth 已提交
144
      change = blink::PointerData::Change::kMove;
145 146 147 148 149 150
    }
  } else {
    DLOG(INFO) << "Unknown mouse action: " << action;
    return;
  }

A
Adam Barth 已提交
151 152
  double x = 0.0;
  double y = 0.0;
153 154 155 156
  glfwGetCursorPos(glfw_window_, &x, &y);

  base::TimeDelta time_stamp = base::TimeTicks::Now() - base::TimeTicks();

A
Adam Barth 已提交
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
  blink::PointerData pointer_data;
  pointer_data.Clear();
  pointer_data.time_stamp = time_stamp.InMicroseconds();
  pointer_data.change = change;
  pointer_data.kind = blink::PointerData::DeviceKind::kMouse;
  pointer_data.physical_x = x;
  pointer_data.physical_y = y;
  pointer_data.buttons = buttons_;
  pointer_data.pressure = 1.0;
  pointer_data.pressure_max = 1.0;

  blink::Threads::UI()->PostTask(
      [ engine = engine().GetWeakPtr(), pointer_data ] {
        if (engine.get()) {
          blink::PointerDataPacket packet(1);
          packet.SetPointerData(0, pointer_data);
          engine->DispatchPointerDataPacket(packet);
        }
      });
176 177 178 179 180
}

void PlatformViewGLFW::OnCursorPosChanged(double x, double y) {
  base::TimeDelta time_stamp = base::TimeTicks::Now() - base::TimeTicks();

A
Adam Barth 已提交
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
  blink::PointerData pointer_data;
  pointer_data.Clear();
  pointer_data.time_stamp = time_stamp.InMicroseconds();
  pointer_data.change = blink::PointerData::Change::kMove;
  pointer_data.kind = blink::PointerData::DeviceKind::kMouse;
  pointer_data.physical_x = x;
  pointer_data.physical_y = y;
  pointer_data.buttons = buttons_;
  pointer_data.pressure = 1.0;
  pointer_data.pressure_max = 1.0;

  blink::Threads::UI()->PostTask(
      [ engine = engine().GetWeakPtr(), pointer_data ] {
        if (engine.get()) {
          blink::PointerDataPacket packet(1);
          packet.SetPointerData(0, pointer_data);
          engine->DispatchPointerDataPacket(packet);
        }
      });
200 201 202 203 204 205
}

void PlatformViewGLFW::OnKeyEvent(int key, int scancode, int action, int mods) {
}

}  // namespace shell