Skip to content

Instantly share code, notes, and snippets.

@ghishadow
Forked from chinmaygarde/FlutterEmbedderGLFW.cc
Created March 27, 2025 01:57
Show Gist options
  • Save ghishadow/38de6c543093a46947a4a82944001d95 to your computer and use it in GitHub Desktop.
Save ghishadow/38de6c543093a46947a4a82944001d95 to your computer and use it in GitHub Desktop.

Revisions

  1. @chinmaygarde chinmaygarde revised this gist Jun 23, 2019. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions FlutterEmbedderGLFW.cc
    Original file line number Diff line number Diff line change
    @@ -90,8 +90,6 @@ bool RunFlutter(GLFWwindow *window) {
    FlutterProjectArgs args = {
    .struct_size = sizeof(FlutterProjectArgs),
    .assets_path = MY_PROJECT "/build/fluttter_assets", // This directory is generated by `flutter build bundle`
    .main_path = "", // Used only for Dart 1.
    .packages_path = "", // Used only for Dart 1.
    .icu_data_path = "path_to/icudtl.dat", // Find this in your bin/cache directory.
    };
    FlutterEngine engine = nullptr;
  2. @chinmaygarde chinmaygarde revised this gist Aug 31, 2018. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions FlutterEmbedderGLFW.cc
    Original file line number Diff line number Diff line change
    @@ -89,9 +89,10 @@ bool RunFlutter(GLFWwindow *window) {
    #define MY_PROJECT "/Volumes/Mojo/flutter/examples/flutter_gallery"
    FlutterProjectArgs args = {
    .struct_size = sizeof(FlutterProjectArgs),
    .assets_path = MY_PROJECT "/build/app.flx",
    .main_path = MY_PROJECT "/lib/main.dart",
    .packages_path = MY_PROJECT "/.packages",
    .assets_path = MY_PROJECT "/build/fluttter_assets", // This directory is generated by `flutter build bundle`
    .main_path = "", // Used only for Dart 1.
    .packages_path = "", // Used only for Dart 1.
    .icu_data_path = "path_to/icudtl.dat", // Find this in your bin/cache directory.
    };
    FlutterEngine engine = nullptr;
    auto result = FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, // renderer
  3. @chinmaygarde chinmaygarde revised this gist Aug 23, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions FlutterEmbedderGLFW.cc
    Original file line number Diff line number Diff line change
    @@ -23,8 +23,8 @@ void GLFWcursorPositionCallbackAtPhase(GLFWwindow *window,
    std::chrono::high_resolution_clock::now().time_since_epoch())
    .count();
    FlutterEngineSendPointerEvent(
    reinterpret_cast<FlutterEngine>(glfwGetWindowUserPointer(window)),
    &event);
    reinterpret_cast<FlutterEngine>(glfwGetWindowUserPointer(window)), &event,
    1);
    }

    void GLFWcursorPositionCallback(GLFWwindow *window, double x, double y) {
  4. @chinmaygarde chinmaygarde revised this gist Aug 22, 2017. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions FlutterEmbedderGLFW.cc
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,8 @@
    #include <glfw3.h>
    #include <iostream>

    static_assert(FLUTTER_ENGINE_VERSION == 1, "");

    static const size_t kInitialWindowWidth = 800;
    static const size_t kInitialWindowHeight = 600;

  5. @chinmaygarde chinmaygarde revised this gist Aug 21, 2017. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion FlutterEmbedderGLFW.cc
    Original file line number Diff line number Diff line change
    @@ -12,6 +12,7 @@ void GLFWcursorPositionCallbackAtPhase(GLFWwindow *window,
    FlutterPointerPhase phase, double x,
    double y) {
    FlutterPointerEvent event = {};
    event.struct_size = sizeof(event);
    event.phase = phase;
    event.x = x;
    event.y = y;
    @@ -53,7 +54,8 @@ static void GLFWKeyCallback(GLFWwindow *window, int key, int scancode,
    }

    void GLFWwindowSizeCallback(GLFWwindow *window, int width, int height) {
    FlutterWindowMetricsEvent event;
    FlutterWindowMetricsEvent event = {};
    event.struct_size = sizeof(event);
    event.width = width;
    event.height = height;
    event.pixel_ratio = 1.0;
    @@ -65,6 +67,7 @@ void GLFWwindowSizeCallback(GLFWwindow *window, int width, int height) {
    bool RunFlutter(GLFWwindow *window) {
    FlutterRendererConfig config = {};
    config.type = kOpenGL;
    config.open_gl.struct_size = sizeof(config.open_gl);
    config.open_gl.make_current = [](void *userdata) -> bool {
    glfwMakeContextCurrent((GLFWwindow *)userdata);
    return true;
    @@ -83,6 +86,7 @@ bool RunFlutter(GLFWwindow *window) {

    #define MY_PROJECT "/Volumes/Mojo/flutter/examples/flutter_gallery"
    FlutterProjectArgs args = {
    .struct_size = sizeof(FlutterProjectArgs),
    .assets_path = MY_PROJECT "/build/app.flx",
    .main_path = MY_PROJECT "/lib/main.dart",
    .packages_path = MY_PROJECT "/.packages",
  6. @chinmaygarde chinmaygarde revised this gist Aug 18, 2017. 1 changed file with 15 additions and 12 deletions.
    27 changes: 15 additions & 12 deletions FlutterEmbedderGLFW.cc
    Original file line number Diff line number Diff line change
    @@ -11,16 +11,17 @@ static const size_t kInitialWindowHeight = 600;
    void GLFWcursorPositionCallbackAtPhase(GLFWwindow *window,
    FlutterPointerPhase phase, double x,
    double y) {
    FlutterEvent event = {};
    event.type = kPointer;
    event.pointer.phase = phase;
    event.pointer.x = x;
    event.pointer.y = y;
    event.pointer.timestamp = // holy fuck
    FlutterPointerEvent event = {};
    event.phase = phase;
    event.x = x;
    event.y = y;
    event.timestamp =
    std::chrono::duration_cast<std::chrono::microseconds>(
    std::chrono::high_resolution_clock::now().time_since_epoch())
    .count();
    FlutterEngineSendEvent(glfwGetWindowUserPointer(window), &event);
    FlutterEngineSendPointerEvent(
    reinterpret_cast<FlutterEngine>(glfwGetWindowUserPointer(window)),
    &event);
    }

    void GLFWcursorPositionCallback(GLFWwindow *window, double x, double y) {
    @@ -52,11 +53,13 @@ static void GLFWKeyCallback(GLFWwindow *window, int key, int scancode,
    }

    void GLFWwindowSizeCallback(GLFWwindow *window, int width, int height) {
    FlutterEvent event = {};
    event.type = kWindowMetrics;
    event.window_metrics.width = width;
    event.window_metrics.height = height;
    FlutterEngineSendEvent(glfwGetWindowUserPointer(window), &event);
    FlutterWindowMetricsEvent event;
    event.width = width;
    event.height = height;
    event.pixel_ratio = 1.0;
    FlutterEngineSendWindowMetricsEvent(
    reinterpret_cast<FlutterEngine>(glfwGetWindowUserPointer(window)),
    &event);
    }

    bool RunFlutter(GLFWwindow *window) {
  7. @chinmaygarde chinmaygarde created this gist Aug 17, 2017.
    126 changes: 126 additions & 0 deletions FlutterEmbedderGLFW.cc
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,126 @@

    #include <assert.h>
    #include <chrono>
    #include <embedder.h>
    #include <glfw3.h>
    #include <iostream>

    static const size_t kInitialWindowWidth = 800;
    static const size_t kInitialWindowHeight = 600;

    void GLFWcursorPositionCallbackAtPhase(GLFWwindow *window,
    FlutterPointerPhase phase, double x,
    double y) {
    FlutterEvent event = {};
    event.type = kPointer;
    event.pointer.phase = phase;
    event.pointer.x = x;
    event.pointer.y = y;
    event.pointer.timestamp = // holy fuck
    std::chrono::duration_cast<std::chrono::microseconds>(
    std::chrono::high_resolution_clock::now().time_since_epoch())
    .count();
    FlutterEngineSendEvent(glfwGetWindowUserPointer(window), &event);
    }

    void GLFWcursorPositionCallback(GLFWwindow *window, double x, double y) {
    GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kMove, x, y);
    }

    void GLFWmouseButtonCallback(GLFWwindow *window, int key, int action,
    int mods) {
    if (key == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS) {
    double x, y;
    glfwGetCursorPos(window, &x, &y);
    GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kDown, x, y);
    glfwSetCursorPosCallback(window, GLFWcursorPositionCallback);
    }

    if (key == GLFW_MOUSE_BUTTON_1 && action == GLFW_RELEASE) {
    double x, y;
    glfwGetCursorPos(window, &x, &y);
    GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kUp, x, y);
    glfwSetCursorPosCallback(window, nullptr);
    }
    }

    static void GLFWKeyCallback(GLFWwindow *window, int key, int scancode,
    int action, int mods) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
    glfwSetWindowShouldClose(window, GLFW_TRUE);
    }
    }

    void GLFWwindowSizeCallback(GLFWwindow *window, int width, int height) {
    FlutterEvent event = {};
    event.type = kWindowMetrics;
    event.window_metrics.width = width;
    event.window_metrics.height = height;
    FlutterEngineSendEvent(glfwGetWindowUserPointer(window), &event);
    }

    bool RunFlutter(GLFWwindow *window) {
    FlutterRendererConfig config = {};
    config.type = kOpenGL;
    config.open_gl.make_current = [](void *userdata) -> bool {
    glfwMakeContextCurrent((GLFWwindow *)userdata);
    return true;
    };
    config.open_gl.clear_current = [](void *) -> bool {
    glfwMakeContextCurrent(nullptr); // is this even a thing?
    return true;
    };
    config.open_gl.present = [](void *userdata) -> bool {
    glfwSwapBuffers((GLFWwindow *)userdata);
    return true;
    };
    config.open_gl.fbo_callback = [](void *) -> uint32_t {
    return 0; // FBO0
    };

    #define MY_PROJECT "/Volumes/Mojo/flutter/examples/flutter_gallery"
    FlutterProjectArgs args = {
    .assets_path = MY_PROJECT "/build/app.flx",
    .main_path = MY_PROJECT "/lib/main.dart",
    .packages_path = MY_PROJECT "/.packages",
    };
    FlutterEngine engine = nullptr;
    auto result = FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, // renderer
    &args, window, &engine);
    assert(result == kSuccess && engine != nullptr);

    glfwSetWindowUserPointer(window, engine);

    GLFWwindowSizeCallback(window, kInitialWindowWidth, kInitialWindowHeight);

    return true;
    }

    int main(int argc, const char *argv[]) {

    auto result = glfwInit();
    assert(result == GLFW_TRUE);

    auto window = glfwCreateWindow(kInitialWindowWidth, kInitialWindowHeight,
    "Flutter", NULL, NULL);
    assert(window != nullptr);

    bool runResult = RunFlutter(window);
    assert(runResult);

    glfwSetKeyCallback(window, GLFWKeyCallback);

    glfwSetWindowSizeCallback(window, GLFWwindowSizeCallback);

    glfwSetMouseButtonCallback(window, GLFWmouseButtonCallback);

    while (!glfwWindowShouldClose(window)) {
    std::cout << "Looping..." << std::endl;
    glfwWaitEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();

    return EXIT_SUCCESS;
    }