diff --git a/wpigui/src/dev/native/cpp/main.cpp b/wpigui/src/dev/native/cpp/main.cpp
new file mode 100644
index 0000000..abd58a1
--- /dev/null
+++ b/wpigui/src/dev/native/cpp/main.cpp
@@ -0,0 +1,14 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "wpigui.h"
+
+int main() {
+  wpi::gui::CreateContext();
+  wpi::gui::Initialize("Hello World", 1024, 768);
+  wpi::gui::Main();
+}
diff --git a/wpigui/src/main/native/cpp/portable-file-dialogs.cpp b/wpigui/src/main/native/cpp/portable-file-dialogs.cpp
new file mode 100644
index 0000000..09f5d37
--- /dev/null
+++ b/wpigui/src/main/native/cpp/portable-file-dialogs.cpp
@@ -0,0 +1,1366 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+//
+//  Portable File Dialogs
+//
+//  Copyright © 2018—2020 Sam Hocevar <sam@hocevar.net>
+//
+//  This library is free software. It comes without any warranty, to
+//  the extent permitted by applicable law. You can redistribute it
+//  and/or modify it under the terms of the Do What the **** You Want
+//  to Public License, Version 2, as published by the WTFPL Task Force.
+//  See http://www.wtfpl.net/ for more details.
+//
+
+#include "portable-file-dialogs.h"
+
+#if _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#   define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <Windows.h>
+#include <commdlg.h>
+#include <ShlObj.h>
+#include <ShObjIdl.h> // IFileDialog
+#include <shellapi.h>
+#include <strsafe.h>
+#include <future>     // std::async
+
+#elif __EMSCRIPTEN__
+#include <emscripten.h>
+
+#else
+#ifndef _POSIX_C_SOURCE
+#   define _POSIX_C_SOURCE 2 // for popen()
+#endif
+#include <cstdio>     // popen()
+#include <cstdlib>    // std::getenv()
+#include <fcntl.h>    // fcntl()
+#include <unistd.h>   // read(), pipe(), dup2()
+#include <csignal>    // ::kill, std::signal
+#include <sys/wait.h> // waitpid()
+#endif
+
+#ifdef _WIN32
+#include <set>
+#endif
+#include <iostream>
+#include <regex>
+#include <thread>
+#include <chrono>
+
+//
+// Below this are all the method implementations.
+//
+
+namespace pfd
+{
+
+namespace internal
+{
+
+class platform
+{
+public:
+#if _WIN32
+    // Helper class around LoadLibraryA() and GetProcAddress() with some safety
+    class dll
+    {
+    public:
+        explicit dll(std::string const &name);
+        ~dll();
+
+        template<typename T> class proc
+        {
+        public:
+            proc(dll const &lib, std::string const &sym)
+              : m_proc(reinterpret_cast<T *>(::GetProcAddress(lib.handle, sym.c_str())))
+            {}
+
+            operator bool() const { return m_proc != nullptr; }
+            operator T *() const { return m_proc; }
+
+        private:
+            T *m_proc;
+        };
+
+    private:
+        HMODULE handle;
+    };
+
+    // Helper class around CreateActCtx() and ActivateActCtx()
+    class new_style_context
+    {
+    public:
+        new_style_context();
+        ~new_style_context();
+
+    private:
+        HANDLE create();
+        ULONG_PTR m_cookie = 0;
+    };
+#endif
+};
+
+class executor
+{
+    friend class dialog;
+
+public:
+    // High level function to get the result of a command
+    std::string result(int *exit_code = nullptr);
+
+    // High level function to abort
+    bool kill();
+
+#if _WIN32
+    void start_func(std::function<std::string(int *)> const &fun);
+    static BOOL CALLBACK enum_windows_callback(HWND hwnd, LPARAM lParam);
+#elif __EMSCRIPTEN__
+    void start(int exit_code);
+#else
+    void start_process(std::vector<std::string> const &command);
+#endif
+
+    ~executor();
+
+protected:
+    bool ready(int timeout = default_wait_timeout);
+    void stop();
+
+private:
+    bool m_running = false;
+    std::string m_stdout;
+    int m_exit_code = -1;
+#if _WIN32
+    std::future<std::string> m_future;
+    std::set<HWND> m_windows;
+    std::condition_variable m_cond;
+    std::mutex m_mutex;
+    DWORD m_tid;
+#elif __EMSCRIPTEN__ || __NX__
+    // FIXME: do something
+#else
+    pid_t m_pid = 0;
+    int m_fd = -1;
+#endif
+};
+
+// internal free functions implementations
+
+#if _WIN32
+static inline std::wstring str2wstr(std::string const &str)
+{
+    int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), nullptr, 0);
+    std::wstring ret(len, '\0');
+    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), (LPWSTR)ret.data(), (int)ret.size());
+    return ret;
+}
+
+static inline std::string wstr2str(std::wstring const &str)
+{
+    int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.size(), nullptr, 0, nullptr, nullptr);
+    std::string ret(len, '\0');
+    WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.size(), (LPSTR)ret.data(), (int)ret.size(), nullptr, nullptr);
+    return ret;
+}
+
+static inline bool is_vista()
+{
+    OSVERSIONINFOEXW osvi;
+    memset(&osvi, 0, sizeof(osvi));
+    DWORDLONG const mask = VerSetConditionMask(
+            VerSetConditionMask(
+                    VerSetConditionMask(
+                            0, VER_MAJORVERSION, VER_GREATER_EQUAL),
+                    VER_MINORVERSION, VER_GREATER_EQUAL),
+            VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+    osvi.dwOSVersionInfoSize = sizeof(osvi);
+    osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_VISTA);
+    osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_VISTA);
+    osvi.wServicePackMajor = 0;
+
+    return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, mask) != FALSE;
+}
+#endif
+
+// This is necessary until C++20 which will have std::string::ends_with() etc.
+
+static inline bool ends_with(std::string const &str, std::string const &suffix)
+{
+    return suffix.size() <= str.size() &&
+        str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+static inline bool starts_with(std::string const &str, std::string const &prefix)
+{
+    return prefix.size() <= str.size() &&
+        str.compare(0, prefix.size(), prefix) == 0;
+}
+
+} // namespace internal
+
+// settings implementation
+
+settings::settings(bool resync)
+{
+    flags(flag::is_scanned) &= !resync;
+
+    if (flags(flag::is_scanned))
+        return;
+
+#if _WIN32
+    flags(flag::is_vista) = internal::is_vista();
+#elif !__APPLE__
+    flags(flag::has_zenity) = check_program("zenity");
+    flags(flag::has_matedialog) = check_program("matedialog");
+    flags(flag::has_qarma) = check_program("qarma");
+    flags(flag::has_kdialog) = check_program("kdialog");
+
+    // If multiple helpers are available, try to default to the best one
+    if (flags(flag::has_zenity) && flags(flag::has_kdialog))
+    {
+        auto desktop_name = std::getenv("XDG_SESSION_DESKTOP");
+        if (desktop_name && desktop_name == std::string("gnome"))
+            flags(flag::has_kdialog) = false;
+        else if (desktop_name && desktop_name == std::string("KDE"))
+            flags(flag::has_zenity) = false;
+    }
+#endif
+
+    flags(flag::is_scanned) = true;
+}
+
+bool settings::available()
+{
+#if _WIN32
+    return true;
+#elif __APPLE__
+    return true;
+#else
+    settings tmp;
+    return tmp.flags(flag::has_zenity) ||
+           tmp.flags(flag::has_matedialog) ||
+           tmp.flags(flag::has_qarma) ||
+           tmp.flags(flag::has_kdialog);
+#endif
+}
+
+void settings::verbose(bool value)
+{
+    settings().flags(flag::is_verbose) = value;
+}
+
+void settings::rescan()
+{
+    settings(/* resync = */ true);
+}
+
+// Check whether a program is present using “which”.
+bool settings::check_program(std::string const &program)
+{
+#if _WIN32
+    (void)program;
+    return false;
+#elif __EMSCRIPTEN__
+    (void)program;
+    return false;
+#else
+    int exit_code = -1;
+    internal::executor async;
+    async.start_process({"/bin/sh", "-c", "which " + program});
+    async.result(&exit_code);
+    return exit_code == 0;
+#endif
+}
+
+bool const &settings::flags(flag in_flag) const
+{
+    static bool flags[size_t(flag::max_flag)];
+    return flags[size_t(in_flag)];
+}
+
+bool &settings::flags(flag in_flag)
+{
+    return const_cast<bool &>(static_cast<settings const *>(this)->flags(in_flag));
+}
+
+// executor implementation
+
+std::string internal::executor::result(int *exit_code /* = nullptr */)
+{
+    stop();
+    if (exit_code)
+        *exit_code = m_exit_code;
+    return m_stdout;
+}
+
+bool internal::executor::kill()
+{
+#if _WIN32
+    if (m_future.valid())
+    {
+        // Close all windows that weren’t open when we started the future
+        auto previous_windows = m_windows;
+        EnumWindows(&enum_windows_callback, (LPARAM)this);
+        for (auto hwnd : m_windows)
+            if (previous_windows.find(hwnd) == previous_windows.end())
+                SendMessage(hwnd, WM_CLOSE, 0, 0);
+    }
+#elif __EMSCRIPTEN__ || __NX__
+    // FIXME: do something
+    (void)timeout;
+    return false; // cannot kill
+#else
+    ::kill(m_pid, SIGKILL);
+#endif
+    stop();
+    return true;
+}
+
+#if _WIN32
+BOOL CALLBACK internal::executor::enum_windows_callback(HWND hwnd, LPARAM lParam)
+{
+    auto that = (executor *)lParam;
+
+    DWORD pid;
+    auto tid = GetWindowThreadProcessId(hwnd, &pid);
+    if (tid == that->m_tid)
+        that->m_windows.insert(hwnd);
+    return TRUE;
+}
+#endif
+
+#if _WIN32
+void internal::executor::start_func(std::function<std::string(int *)> const &fun)
+{
+    stop();
+
+    auto trampoline = [fun, this]()
+    {
+        // Save our thread id so that the caller can cancel us
+        m_tid = GetCurrentThreadId();
+        EnumWindows(&enum_windows_callback, (LPARAM)this);
+        m_cond.notify_all();
+        return fun(&m_exit_code);
+    };
+
+    std::unique_lock<std::mutex> lock(m_mutex);
+    m_future = std::async(std::launch::async, trampoline);
+    m_cond.wait(lock);
+    m_running = true;
+}
+
+#elif __EMSCRIPTEN__
+void internal::executor::start(int exit_code)
+{
+    m_exit_code = exit_code;
+}
+
+#else
+void internal::executor::start_process(std::vector<std::string> const &command)
+{
+    stop();
+    m_stdout.clear();
+    m_exit_code = -1;
+
+    int in[2], out[2];
+    if (pipe(in) != 0 || pipe(out) != 0)
+        return;
+
+    m_pid = fork();
+    if (m_pid < 0)
+        return;
+
+    close(in[m_pid ? 0 : 1]);
+    close(out[m_pid ? 1 : 0]);
+
+    if (m_pid == 0)
+    {
+        dup2(in[0], STDIN_FILENO);
+        dup2(out[1], STDOUT_FILENO);
+
+        // Ignore stderr so that it doesn’t pollute the console (e.g. GTK+ errors from zenity)
+        int fd = open("/dev/null", O_WRONLY);
+        dup2(fd, STDERR_FILENO);
+        close(fd);
+
+        std::vector<char *> args;
+        std::transform(command.cbegin(), command.cend(), std::back_inserter(args),
+                       [](std::string const &s) { return const_cast<char *>(s.c_str()); });
+        args.push_back(nullptr); // null-terminate argv[]
+
+        execvp(args[0], args.data());
+        exit(1);
+    }
+
+    close(in[1]);
+    m_fd = out[0];
+    auto flags = fcntl(m_fd, F_GETFL);
+    fcntl(m_fd, F_SETFL, flags | O_NONBLOCK);
+
+    m_running = true;
+}
+#endif
+
+internal::executor::~executor()
+{
+    stop();
+}
+
+bool internal::executor::ready(int timeout /* = default_wait_timeout */)
+{
+    if (!m_running)
+        return true;
+
+#if _WIN32
+    if (m_future.valid())
+    {
+        auto status = m_future.wait_for(std::chrono::milliseconds(timeout));
+        if (status != std::future_status::ready)
+        {
+            // On Windows, we need to run the message pump. If the async
+            // thread uses a Windows API dialog, it may be attached to the
+            // main thread and waiting for messages that only we can dispatch.
+            MSG msg;
+            while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
+            {
+                TranslateMessage(&msg);
+                DispatchMessage(&msg);
+            }
+            return false;
+        }
+
+        m_stdout = m_future.get();
+    }
+#elif __EMSCRIPTEN__ || __NX__
+    // FIXME: do something
+    (void)timeout;
+#else
+    char buf[BUFSIZ];
+    ssize_t received = read(m_fd, buf, BUFSIZ); // Flawfinder: ignore
+    if (received > 0)
+    {
+        m_stdout += std::string(buf, received);
+        return false;
+    }
+
+    // Reap child process if it is dead. It is possible that the system has already reaped it
+    // (this happens when the calling application handles or ignores SIG_CHLD) and results in
+    // waitpid() failing with ECHILD. Otherwise we assume the child is running and we sleep for
+    // a little while.
+    int status;
+    pid_t child = waitpid(m_pid, &status, WNOHANG);
+    if (child != m_pid && (child >= 0 || errno != ECHILD))
+    {
+        // FIXME: this happens almost always at first iteration
+        std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
+        return false;
+    }
+
+    close(m_fd);
+    m_exit_code = WEXITSTATUS(status);
+#endif
+
+    m_running = false;
+    return true;
+}
+
+void internal::executor::stop()
+{
+    // Loop until the user closes the dialog
+    while (!ready())
+    {}
+}
+
+// dll implementation
+
+#if _WIN32
+internal::platform::dll::dll(std::string const &name)
+  : handle(::LoadLibraryA(name.c_str()))
+{}
+
+internal::platform::dll::~dll()
+{
+    if (handle)
+        ::FreeLibrary(handle);
+}
+#endif // _WIN32
+
+// new_style_context implementation
+
+#if _WIN32
+internal::platform::new_style_context::new_style_context()
+{
+    // Only create one activation context for the whole app lifetime.
+    static HANDLE hctx = create();
+
+    if (hctx != INVALID_HANDLE_VALUE)
+        ActivateActCtx(hctx, &m_cookie);
+}
+
+internal::platform::new_style_context::~new_style_context()
+{
+    DeactivateActCtx(0, m_cookie);
+}
+
+HANDLE internal::platform::new_style_context::create()
+{
+    // This “hack” seems to be necessary for this code to work on windows XP.
+    // Without it, dialogs do not show and close immediately. GetError()
+    // returns 0 so I don’t know what causes this. I was not able to reproduce
+    // this behavior on Windows 7 and 10 but just in case, let it be here for
+    // those versions too.
+    // This hack is not required if other dialogs are used (they load comdlg32
+    // automatically), only if message boxes are used.
+    internal::platform::dll comdlg32("comdlg32.dll");
+
+    // Using approach as shown here: https://stackoverflow.com/a/10444161
+    UINT len = ::GetSystemDirectoryA(nullptr, 0);
+    std::string sys_dir(len, '\0');
+    ::GetSystemDirectoryA(&sys_dir[0], len);
+
+    ACTCTXA act_ctx =
+    {
+        // Do not set flag ACTCTX_FLAG_SET_PROCESS_DEFAULT, since it causes a
+        // crash with error “default context is already set”.
+        sizeof(act_ctx),
+        ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID,
+        "shell32.dll", 0, 0, sys_dir.c_str(), (LPCSTR)124,
+    };
+
+    return ::CreateActCtxA(&act_ctx);
+}
+#endif // _WIN32
+
+// dialog implementation
+
+bool internal::dialog::ready(int timeout /* = default_wait_timeout */) const
+{
+    return m_async->ready(timeout);
+}
+
+bool internal::dialog::kill() const
+{
+    return m_async->kill();
+}
+
+internal::dialog::dialog()
+  : m_async(std::make_shared<executor>())
+{
+}
+
+std::vector<std::string> internal::dialog::desktop_helper() const
+{
+#if __APPLE__
+    return { "osascript" };
+#else
+    return { flags(flag::has_zenity) ? "zenity"
+           : flags(flag::has_matedialog) ? "matedialog"
+           : flags(flag::has_qarma) ? "qarma"
+           : flags(flag::has_kdialog) ? "kdialog"
+           : "echo" };
+#endif
+}
+
+std::string internal::dialog::buttons_to_name(choice _choice)
+{
+    switch (_choice)
+    {
+        case choice::ok_cancel: return "okcancel";
+        case choice::yes_no: return "yesno";
+        case choice::yes_no_cancel: return "yesnocancel";
+        case choice::retry_cancel: return "retrycancel";
+        case choice::abort_retry_ignore: return "abortretryignore";
+        /* case choice::ok: */ default: return "ok";
+    }
+}
+
+std::string internal::dialog::get_icon_name(icon _icon)
+{
+    switch (_icon)
+    {
+        case icon::warning: return "warning";
+        case icon::error: return "error";
+        case icon::question: return "question";
+        // Zenity wants "information" but WinForms wants "info"
+        /* case icon::info: */ default:
+#if _WIN32
+            return "info";
+#else
+            return "information";
+#endif
+    }
+}
+
+// THis is only used for debugging purposes
+std::ostream& operator <<(std::ostream &s, std::vector<std::string> const &v)
+{
+    int not_first = 0;
+    for (auto &e : v)
+        s << (not_first++ ? " " : "") << e;
+    return s;
+}
+
+// Properly quote a string for Powershell: replace ' or " with '' or ""
+// FIXME: we should probably get rid of newlines!
+// FIXME: the \" sequence seems unsafe, too!
+// XXX: this is no longer used but I would like to keep it around just in case
+std::string internal::dialog::powershell_quote(std::string const &str) const
+{
+    return "'" + std::regex_replace(str, std::regex("['\"]"), "$&$&") + "'";
+}
+
+// Properly quote a string for osascript: replace \ or " with \\ or \"
+// XXX: this also used to replace ' with \' when popen was used, but it would be
+// smarter to do shell_quote(osascript_quote(...)) if this is needed again.
+std::string internal::dialog::osascript_quote(std::string const &str) const
+{
+    return "\"" + std::regex_replace(str, std::regex("[\\\\\"]"), "\\$&") + "\"";
+}
+
+// Properly quote a string for the shell: just replace ' with '\''
+// XXX: this is no longer used but I would like to keep it around just in case
+std::string internal::dialog::shell_quote(std::string const &str) const
+{
+    return "'" + std::regex_replace(str, std::regex("'"), "'\\''") + "'";
+}
+
+// file_dialog implementation
+
+class internal::file_dialog::Impl {
+ public:
+#if _WIN32
+    static int CALLBACK bffcallback(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData);
+    std::string select_folder_vista(IFileDialog *ifd, bool force_path);
+
+    std::wstring m_wtitle;
+    std::wstring m_wdefault_path;
+
+    std::vector<std::string> m_vector_result;
+#endif
+};
+
+internal::file_dialog::file_dialog(type in_type,
+            std::string const &title,
+            std::string const &default_path /* = "" */,
+            std::vector<std::string> const &filters /* = {} */,
+            opt options /* = opt::none */)
+  : m_impl(std::make_shared<Impl>())
+{
+#if _WIN32
+    std::string filter_list;
+    std::regex whitespace("  *");
+    for (size_t i = 0; i + 1 < filters.size(); i += 2)
+    {
+        filter_list += filters[i] + '\0';
+        filter_list += std::regex_replace(filters[i + 1], whitespace, ";") + '\0';
+    }
+    filter_list += '\0';
+
+    m_async->start_func([this, in_type, title, default_path, filter_list,
+                         options](int *exit_code) -> std::string
+    {
+        (void)exit_code;
+        m_impl->m_wtitle = internal::str2wstr(title);
+        m_impl->m_wdefault_path = internal::str2wstr(default_path);
+        auto wfilter_list = internal::str2wstr(filter_list);
+
+        // Folder selection uses a different method
+        if (in_type == type::folder)
+        {
+            internal::platform::dll ole32("ole32.dll");
+
+            auto status = internal::platform::dll::proc<HRESULT WINAPI (LPVOID, DWORD)>(ole32, "CoInitializeEx")
+                              (nullptr, COINIT_APARTMENTTHREADED);
+            if (flags(flag::is_vista))
+            {
+                // On Vista and higher we should be able to use IFileDialog for folder selection
+                IFileDialog *ifd;
+                HRESULT hr = internal::platform::dll::proc<HRESULT WINAPI (REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID *)>(ole32, "CoCreateInstance")
+                                 (CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ifd));
+
+                // In case CoCreateInstance fails (which it should not), try legacy approach
+                if (SUCCEEDED(hr))
+                    return m_impl->select_folder_vista(ifd, options & opt::force_path);
+            }
+
+            BROWSEINFOW bi;
+            memset(&bi, 0, sizeof(bi));
+
+            bi.lpfn = &Impl::bffcallback;
+            bi.lParam = (LPARAM)m_impl.get();
+
+            if (flags(flag::is_vista))
+            {
+                // This hangs on Windows XP, as reported here:
+                // https://github.com/samhocevar/portable-file-dialogs/pull/21
+                if (status == S_OK)
+                    bi.ulFlags |= BIF_NEWDIALOGSTYLE;
+                bi.ulFlags |= BIF_EDITBOX;
+                bi.ulFlags |= BIF_STATUSTEXT;
+            }
+
+            auto *list = SHBrowseForFolderW(&bi);
+            std::string ret;
+            if (list)
+            {
+                auto buffer = new wchar_t[MAX_PATH];
+                SHGetPathFromIDListW(list, buffer);
+                internal::platform::dll::proc<void WINAPI (LPVOID)>(ole32, "CoTaskMemFree")(list);
+                ret = internal::wstr2str(buffer);
+                delete[] buffer;
+            }
+            if (status == S_OK)
+                internal::platform::dll::proc<void WINAPI ()>(ole32, "CoUninitialize")();
+            return ret;
+        }
+
+        OPENFILENAMEW ofn;
+        memset(&ofn, 0, sizeof(ofn));
+        ofn.lStructSize = sizeof(OPENFILENAMEW);
+        ofn.hwndOwner = GetActiveWindow();
+
+        ofn.lpstrFilter = wfilter_list.c_str();
+
+        auto woutput = std::wstring(MAX_PATH * 256, L'\0');
+        ofn.lpstrFile = (LPWSTR)woutput.data();
+        ofn.nMaxFile = (DWORD)woutput.size();
+        if (!m_impl->m_wdefault_path.empty())
+        {
+            // If a directory was provided, use it as the initial directory. If
+            // a valid path was provided, use it as the initial file. Otherwise,
+            // let the Windows API decide.
+            auto path_attr = GetFileAttributesW(m_impl->m_wdefault_path.c_str());
+            if (path_attr != INVALID_FILE_ATTRIBUTES && (path_attr & FILE_ATTRIBUTE_DIRECTORY))
+                ofn.lpstrInitialDir = m_impl->m_wdefault_path.c_str();
+            else if (m_impl->m_wdefault_path.size() <= woutput.size())
+                //second argument is size of buffer, not length of string
+                StringCchCopyW(ofn.lpstrFile, MAX_PATH*256+1, m_impl->m_wdefault_path.c_str());
+            else
+            {
+                ofn.lpstrFileTitle = (LPWSTR)m_impl->m_wdefault_path.data();
+                ofn.nMaxFileTitle = (DWORD)m_impl->m_wdefault_path.size();
+            }
+        }
+        ofn.lpstrTitle = m_impl->m_wtitle.c_str();
+        ofn.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER;
+
+        internal::platform::dll comdlg32("comdlg32.dll");
+
+        if (in_type == type::save)
+        {
+            if (!(options & opt::force_overwrite))
+                ofn.Flags |= OFN_OVERWRITEPROMPT;
+
+            // using set context to apply new visual style (required for windows XP)
+            internal::platform::new_style_context ctx;
+
+            internal::platform::dll::proc<BOOL WINAPI (LPOPENFILENAMEW)> get_save_file_name(comdlg32, "GetSaveFileNameW");
+            if (get_save_file_name(&ofn) == 0)
+                return "";
+            return internal::wstr2str(woutput.c_str());
+        }
+
+        if (options & opt::multiselect)
+            ofn.Flags |= OFN_ALLOWMULTISELECT;
+        ofn.Flags |= OFN_PATHMUSTEXIST;
+
+        // using set context to apply new visual style (required for windows XP)
+        internal::platform::new_style_context ctx;
+
+        internal::platform::dll::proc<BOOL WINAPI (LPOPENFILENAMEW)> get_open_file_name(comdlg32, "GetOpenFileNameW");
+        if (get_open_file_name(&ofn) == 0)
+            return "";
+
+        std::string prefix;
+        for (wchar_t const *p = woutput.c_str(); *p; )
+        {
+            auto filename = internal::wstr2str(p);
+            p += filename.size();
+            // In multiselect mode, we advance p one step more and
+            // check for another filename. If there is one and the
+            // prefix is empty, it means we just read the prefix.
+            if ((options & opt::multiselect) && *++p && prefix.empty())
+            {
+                prefix = filename + "/";
+                continue;
+            }
+
+            m_impl->m_vector_result.push_back(prefix + filename);
+        }
+
+        return "";
+    });
+#else
+    auto command = desktop_helper();
+
+    if (is_osascript())
+    {
+        std::string script = "set ret to choose";
+        switch (in_type)
+        {
+            case type::save:
+                script += " file name";
+                break;
+            case type::open: default:
+                script += " file";
+                if (options & opt::multiselect)
+                    script += " with multiple selections allowed";
+                break;
+            case type::folder:
+                script += " folder";
+                break;
+        }
+
+        if (default_path.size())
+            script += " default location " + osascript_quote(default_path);
+        script += " with prompt " + osascript_quote(title);
+
+        if (in_type == type::open)
+        {
+            // Concatenate all user-provided filter patterns
+            std::string patterns;
+            for (size_t i = 0; i < filters.size() / 2; ++i)
+                patterns += " " + filters[2 * i + 1];
+
+            // Split the pattern list to check whether "*" is in there; if it
+            // is, we have to disable filters because there is no mechanism in
+            // OS X for the user to override the filter.
+            std::regex sep("\\s+");
+            std::string filter_list;
+            bool has_filter = true;
+            std::sregex_token_iterator iter(patterns.begin(), patterns.end(), sep, -1);
+            std::sregex_token_iterator end;
+            for ( ; iter != end; ++iter)
+            {
+                auto pat = iter->str();
+                if (pat == "*" || pat == "*.*")
+                    has_filter = false;
+                else if (internal::starts_with(pat, "*."))
+                    filter_list += (filter_list.size() == 0 ? "" : ",") +
+                                   osascript_quote(pat.substr(2, pat.size() - 2));
+            }
+            if (has_filter && filter_list.size() > 0)
+                script += " of type {" + filter_list + "}";
+        }
+
+        if (in_type == type::open && (options & opt::multiselect))
+        {
+            script += "\nset s to \"\"";
+            script += "\nrepeat with i in ret";
+            script += "\n  set s to s & (POSIX path of i) & \"\\n\"";
+            script += "\nend repeat";
+            script += "\ncopy s to stdout";
+        }
+        else
+        {
+            script += "\nPOSIX path of ret";
+        }
+
+        command.push_back("-e");
+        command.push_back(script);
+    }
+    else if (is_zenity())
+    {
+        command.push_back("--file-selection");
+        command.push_back("--filename=" + default_path);
+        command.push_back("--title");
+        command.push_back(title);
+        command.push_back("--separator=\n");
+
+        for (size_t i = 0; i < filters.size() / 2; ++i)
+        {
+            command.push_back("--file-filter");
+            command.push_back(filters[2 * i] + "|" + filters[2 * i + 1]);
+        }
+
+        if (in_type == type::save)
+            command.push_back("--save");
+        if (in_type == type::folder)
+            command.push_back("--directory");
+        if (!(options & opt::force_overwrite))
+            command.push_back("--confirm-overwrite");
+        if (options & opt::multiselect)
+            command.push_back("--multiple");
+    }
+    else if (is_kdialog())
+    {
+        switch (in_type)
+        {
+            case type::save: command.push_back("--getsavefilename"); break;
+            case type::open: command.push_back("--getopenfilename"); break;
+            case type::folder: command.push_back("--getexistingdirectory"); break;
+        }
+        if (options & opt::multiselect)
+            command.push_back(" --multiple");
+
+        command.push_back(default_path);
+
+        std::string filter;
+        for (size_t i = 0; i < filters.size() / 2; ++i)
+            filter += (i == 0 ? "" : " | ") + filters[2 * i] + "(" + filters[2 * i + 1] + ")";
+        command.push_back(filter);
+
+        command.push_back("--title");
+        command.push_back(title);
+    }
+
+    if (flags(flag::is_verbose))
+        std::cerr << "pfd: " << command << std::endl;
+
+    m_async->start_process(command);
+#endif
+}
+
+std::string internal::file_dialog::string_result()
+{
+#if _WIN32
+    return m_async->result();
+#else
+    auto ret = m_async->result();
+    // Strip potential trailing newline (zenity). Also strip trailing slash
+    // added by osascript for consistency with other backends.
+    while (ret.back() == '\n' || ret.back() == '/')
+        ret = ret.substr(0, ret.size() - 1);
+    return ret;
+#endif
+}
+
+std::vector<std::string> internal::file_dialog::vector_result()
+{
+#if _WIN32
+    m_async->result();
+    return m_impl->m_vector_result;
+#else
+    std::vector<std::string> ret;
+    auto result = m_async->result();
+    for (;;)
+    {
+        // Split result along newline characters
+        auto i = result.find('\n');
+        if (i == 0 || i == std::string::npos)
+            break;
+        ret.push_back(result.substr(0, i));
+        result = result.substr(i + 1, result.size());
+    }
+    return ret;
+#endif
+}
+
+#if _WIN32
+// Use a static function to pass as BFFCALLBACK for legacy folder select
+int CALLBACK internal::file_dialog::Impl::bffcallback(HWND hwnd, UINT uMsg,
+                                                       LPARAM, LPARAM pData)
+{
+    auto inst = (file_dialog::Impl *)pData;
+    switch (uMsg)
+    {
+        case BFFM_INITIALIZED:
+            SendMessage(hwnd, BFFM_SETSELECTIONW, TRUE, (LPARAM)inst->m_wdefault_path.c_str());
+            break;
+    }
+    return 0;
+}
+
+std::string internal::file_dialog::Impl::select_folder_vista(IFileDialog *ifd, bool force_path)
+{
+    std::string result;
+
+    IShellItem *folder;
+
+    // Load library at runtime so app doesn't link it at load time (which will fail on windows XP)
+    internal::platform::dll shell32("shell32.dll");
+    internal::platform::dll::proc<HRESULT WINAPI (PCWSTR, IBindCtx*, REFIID, void**)>
+        create_item(shell32, "SHCreateItemFromParsingName");
+
+    if (!create_item)
+        return "";
+
+    auto hr = create_item(m_wdefault_path.c_str(),
+                          nullptr,
+                          IID_PPV_ARGS(&folder));
+
+    // Set default folder if found. This only sets the default folder. If
+    // Windows has any info about the most recently selected folder, it
+    // will display it instead. Generally, calling SetFolder() to set the
+    // current directory “is not a good or expected user experience and
+    // should therefore be avoided”:
+    // https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setfolder
+    if (SUCCEEDED(hr))
+    {
+        if (force_path)
+            ifd->SetFolder(folder);
+        else
+            ifd->SetDefaultFolder(folder);
+        folder->Release();
+    }
+
+    // Set the dialog title and option to select folders
+    ifd->SetOptions(FOS_PICKFOLDERS);
+    ifd->SetTitle(m_wtitle.c_str());
+
+    hr = ifd->Show(GetActiveWindow());
+    if (SUCCEEDED(hr))
+    {
+        IShellItem* item;
+        hr = ifd->GetResult(&item);
+        if (SUCCEEDED(hr))
+        {
+            wchar_t* wselected = nullptr;
+            item->GetDisplayName(SIGDN_FILESYSPATH, &wselected);
+            item->Release();
+
+            if (wselected)
+            {
+                result = internal::wstr2str(std::wstring(wselected));
+                internal::platform::dll ole32("ole32.dll");
+                internal::platform::dll::proc<void WINAPI (LPVOID)>(ole32, "CoTaskMemFree")(wselected);
+            }
+        }
+    }
+
+    ifd->Release();
+
+    return result;
+}
+#endif
+
+// notify implementation
+
+notify::notify(std::string const &title,
+                      std::string const &message,
+                      icon _icon /* = icon::info */)
+{
+    if (_icon == icon::question) // Not supported by notifications
+        _icon = icon::info;
+
+#if _WIN32
+    // Use a static shared pointer for notify_icon so that we can delete
+    // it whenever we need to display a new one, and we can also wait
+    // until the program has finished running.
+    struct notify_icon_data : public NOTIFYICONDATAW
+    {
+        ~notify_icon_data() { Shell_NotifyIconW(NIM_DELETE, this); }
+    };
+
+    static std::shared_ptr<notify_icon_data> nid;
+
+    // Release the previous notification icon, if any, and allocate a new
+    // one. Note that std::make_shared() does value initialization, so there
+    // is no need to memset the structure.
+    nid = nullptr;
+    nid = std::make_shared<notify_icon_data>();
+
+    // For XP support
+    nid->cbSize = NOTIFYICONDATAW_V2_SIZE;
+    nid->hWnd = nullptr;
+    nid->uID = 0;
+
+    // Flag Description:
+    // - NIF_ICON    The hIcon member is valid.
+    // - NIF_MESSAGE The uCallbackMessage member is valid.
+    // - NIF_TIP     The szTip member is valid.
+    // - NIF_STATE   The dwState and dwStateMask members are valid.
+    // - NIF_INFO    Use a balloon ToolTip instead of a standard ToolTip. The szInfo, uTimeout, szInfoTitle, and dwInfoFlags members are valid.
+    // - NIF_GUID    Reserved.
+    nid->uFlags = NIF_MESSAGE | NIF_ICON | NIF_INFO;
+
+    // Flag Description
+    // - NIIF_ERROR     An error icon.
+    // - NIIF_INFO      An information icon.
+    // - NIIF_NONE      No icon.
+    // - NIIF_WARNING   A warning icon.
+    // - NIIF_ICON_MASK Version 6.0. Reserved.
+    // - NIIF_NOSOUND   Version 6.0. Do not play the associated sound. Applies only to balloon ToolTips
+    switch (_icon)
+    {
+        case icon::warning: nid->dwInfoFlags = NIIF_WARNING; break;
+        case icon::error: nid->dwInfoFlags = NIIF_ERROR; break;
+        /* case icon::info: */ default: nid->dwInfoFlags = NIIF_INFO; break;
+    }
+
+    ENUMRESNAMEPROC icon_enum_callback = [](HMODULE, LPCTSTR, LPTSTR lpName, LONG_PTR lParam) -> BOOL
+    {
+        ((NOTIFYICONDATAW *)lParam)->hIcon = ::LoadIcon(GetModuleHandle(nullptr), lpName);
+        return false;
+    };
+
+    nid->hIcon = ::LoadIcon(nullptr, IDI_APPLICATION);
+    ::EnumResourceNames(nullptr, RT_GROUP_ICON, icon_enum_callback, (LONG_PTR)nid.get());
+
+    nid->uTimeout = 5000;
+
+    StringCchCopyW(nid->szInfoTitle, ARRAYSIZE(nid->szInfoTitle), internal::str2wstr(title).c_str());
+    StringCchCopyW(nid->szInfo, ARRAYSIZE(nid->szInfo), internal::str2wstr(message).c_str());
+
+    // Display the new icon
+    Shell_NotifyIconW(NIM_ADD, nid.get());
+#else
+    auto command = desktop_helper();
+
+    if (is_osascript())
+    {
+        command.push_back("-e");
+        command.push_back("display notification " + osascript_quote(message) +
+                          " with title " + osascript_quote(title));
+    }
+    else if (is_zenity())
+    {
+        command.push_back("--notification");
+        command.push_back("--window-icon");
+        command.push_back(get_icon_name(_icon));
+        command.push_back("--text");
+        command.push_back(title + "\n" + message);
+    }
+    else if (is_kdialog())
+    {
+        command.push_back("--icon");
+        command.push_back(get_icon_name(_icon));
+        command.push_back("--title");
+        command.push_back(title);
+        command.push_back("--passivepopup");
+        command.push_back(message);
+        command.push_back("5");
+    }
+
+    if (flags(flag::is_verbose))
+        std::cerr << "pfd: " << command << std::endl;
+
+    m_async->start_process(command);
+#endif
+}
+
+// message implementation
+
+message::message(std::string const &title,
+                        std::string const &text,
+                        choice _choice /* = choice::ok_cancel */,
+                        icon _icon /* = icon::info */)
+{
+#if _WIN32
+    UINT style = MB_TOPMOST;
+    switch (_icon)
+    {
+        case icon::warning: style |= MB_ICONWARNING; break;
+        case icon::error: style |= MB_ICONERROR; break;
+        case icon::question: style |= MB_ICONQUESTION; break;
+        /* case icon::info: */ default: style |= MB_ICONINFORMATION; break;
+    }
+
+    switch (_choice)
+    {
+        case choice::ok_cancel: style |= MB_OKCANCEL; break;
+        case choice::yes_no: style |= MB_YESNO; break;
+        case choice::yes_no_cancel: style |= MB_YESNOCANCEL; break;
+        case choice::retry_cancel: style |= MB_RETRYCANCEL; break;
+        case choice::abort_retry_ignore: style |= MB_ABORTRETRYIGNORE; break;
+        /* case choice::ok: */ default: style |= MB_OK; break;
+    }
+
+    m_mappings[IDCANCEL] = button::cancel;
+    m_mappings[IDOK] = button::ok;
+    m_mappings[IDYES] = button::yes;
+    m_mappings[IDNO] = button::no;
+    m_mappings[IDABORT] = button::abort;
+    m_mappings[IDRETRY] = button::retry;
+    m_mappings[IDIGNORE] = button::ignore;
+
+    m_async->start_func([this, text, title, style](int* exit_code) -> std::string
+    {
+        auto wtext = internal::str2wstr(text);
+        auto wtitle = internal::str2wstr(title);
+        // using set context to apply new visual style (required for all windows versions)
+        internal::platform::new_style_context ctx;
+        *exit_code = MessageBoxW(GetActiveWindow(), wtext.c_str(), wtitle.c_str(), style);
+        return "";
+    });
+
+#elif __EMSCRIPTEN__
+    std::string full_message;
+    switch (_icon)
+    {
+        case icon::warning: full_message = "⚠️"; break;
+        case icon::error: full_message = "⛔"; break;
+        case icon::question: full_message = "❓"; break;
+        /* case icon::info: */ default: full_message = "ℹ"; break;
+    }
+
+    full_message += ' ' + title + "\n\n" + text;
+
+    // This does not really start an async task; it just passes the
+    // EM_ASM_INT return value to a fake start() function.
+    m_async->start(EM_ASM_INT(
+    {
+        if ($1)
+            return window.confirm(UTF8ToString($0)) ? 0 : -1;
+        alert(UTF8ToString($0));
+        return 0;
+    }, full_message.c_str(), _choice == choice::ok_cancel));
+#else
+    auto command = desktop_helper();
+
+    if (is_osascript())
+    {
+        std::string script = "display dialog " + osascript_quote(text) +
+                             " with title " + osascript_quote(title);
+        switch (_choice)
+        {
+            case choice::ok_cancel:
+                script += "buttons {\"OK\", \"Cancel\"}"
+                          " default button \"OK\""
+                          " cancel button \"Cancel\"";
+                m_mappings[256] = button::cancel;
+                break;
+            case choice::yes_no:
+                script += "buttons {\"Yes\", \"No\"}"
+                          " default button \"Yes\""
+                          " cancel button \"No\"";
+                m_mappings[256] = button::no;
+                break;
+            case choice::yes_no_cancel:
+                script += "buttons {\"Yes\", \"No\", \"Cancel\"}"
+                          " default button \"Yes\""
+                          " cancel button \"Cancel\"";
+                m_mappings[256] = button::cancel;
+                break;
+            case choice::retry_cancel:
+                script += "buttons {\"Retry\", \"Cancel\"}"
+                          " default button \"Retry\""
+                          " cancel button \"Cancel\"";
+                m_mappings[256] = button::cancel;
+                break;
+            case choice::abort_retry_ignore:
+                script += "buttons {\"Abort\", \"Retry\", \"Ignore\"}"
+                          " default button \"Retry\""
+                          " cancel button \"Retry\"";
+                m_mappings[256] = button::cancel;
+                break;
+            case choice::ok: default:
+                script += "buttons {\"OK\"}"
+                          " default button \"OK\""
+                          " cancel button \"OK\"";
+                m_mappings[256] = button::ok;
+                break;
+        }
+        script += " with icon ";
+        switch (_icon)
+        {
+            #define PFD_OSX_ICON(n) "alias ((path to library folder from system domain) as text " \
+                "& \"CoreServices:CoreTypes.bundle:Contents:Resources:" n ".icns\")"
+            case icon::info: default: script += PFD_OSX_ICON("ToolBarInfo"); break;
+            case icon::warning: script += "caution"; break;
+            case icon::error: script += "stop"; break;
+            case icon::question: script += PFD_OSX_ICON("GenericQuestionMarkIcon"); break;
+            #undef PFD_OSX_ICON
+        }
+
+        command.push_back("-e");
+        command.push_back(script);
+    }
+    else if (is_zenity())
+    {
+        switch (_choice)
+        {
+            case choice::ok_cancel:
+                command.insert(command.end(), { "--question", "--cancel-label=Cancel", "--ok-label=OK" }); break;
+            case choice::yes_no:
+                // Do not use standard --question because it causes “No” to return -1,
+                // which is inconsistent with the “Yes/No/Cancel” mode below.
+                command.insert(command.end(), { "--question", "--switch", "--extra-button=No", "--extra-button=Yes" }); break;
+            case choice::yes_no_cancel:
+                command.insert(command.end(), { "--question", "--switch", "--extra-button=Cancel", "--extra-button=No", "--extra-button=Yes" }); break;
+            case choice::retry_cancel:
+                command.insert(command.end(), { "--question", "--switch", "--extra-button=Cancel", "--extra-button=Retry" }); break;
+            case choice::abort_retry_ignore:
+                command.insert(command.end(), { "--question", "--switch", "--extra-button=Ignore", "--extra-button=Abort", "--extra-button=Retry" }); break;
+            case choice::ok:
+            default:
+                switch (_icon)
+                {
+                    case icon::error: command.push_back("--error"); break;
+                    case icon::warning: command.push_back("--warning"); break;
+                    default: command.push_back("--info"); break;
+                }
+        }
+
+        command.insert(command.end(), { "--title", title,
+                                        "--width=300", "--height=0", // sensible defaults
+                                        "--text", text,
+                                        "--icon-name=dialog-" + get_icon_name(_icon) });
+    }
+    else if (is_kdialog())
+    {
+        if (_choice == choice::ok)
+        {
+            switch (_icon)
+            {
+                case icon::error: command.push_back("--error"); break;
+                case icon::warning: command.push_back("--sorry"); break;
+                default: command.push_back("--msgbox"); break;
+            }
+        }
+        else
+        {
+            std::string flag = "--";
+            if (_icon == icon::warning || _icon == icon::error)
+                flag += "warning";
+            flag += "yesno";
+            if (_choice == choice::yes_no_cancel)
+                flag += "cancel";
+            command.push_back(flag);
+            if (_choice == choice::yes_no || _choice == choice::yes_no_cancel)
+            {
+                m_mappings[0] = button::yes;
+                m_mappings[256] = button::no;
+            }
+        }
+
+        command.push_back(text);
+        command.push_back("--title");
+        command.push_back(title);
+
+        // Must be after the above part
+        if (_choice == choice::ok_cancel)
+            command.insert(command.end(), { "--yes-label", "OK", "--no-label", "Cancel" });
+    }
+
+    if (flags(flag::is_verbose))
+        std::cerr << "pfd: " << command << std::endl;
+
+    m_async->start_process(command);
+#endif
+}
+
+button message::result()
+{
+    int exit_code;
+    auto ret = m_async->result(&exit_code);
+    // osascript will say "button returned:Cancel\n"
+    // and others will just say "Cancel\n"
+    if (exit_code < 0 || // this means cancel
+        internal::ends_with(ret, "Cancel\n"))
+        return button::cancel;
+    if (internal::ends_with(ret, "OK\n"))
+        return button::ok;
+    if (internal::ends_with(ret, "Yes\n"))
+        return button::yes;
+    if (internal::ends_with(ret, "No\n"))
+        return button::no;
+    if (internal::ends_with(ret, "Abort\n"))
+        return button::abort;
+    if (internal::ends_with(ret, "Retry\n"))
+        return button::retry;
+    if (internal::ends_with(ret, "Ignore\n"))
+        return button::ignore;
+    if (m_mappings.count(exit_code) != 0)
+        return m_mappings[exit_code];
+    return exit_code == 0 ? button::ok : button::cancel;
+}
+
+} // namespace pfd
diff --git a/wpigui/src/main/native/cpp/wpigui.cpp b/wpigui/src/main/native/cpp/wpigui.cpp
new file mode 100644
index 0000000..955b3f5
--- /dev/null
+++ b/wpigui/src/main/native/cpp/wpigui.cpp
@@ -0,0 +1,437 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2019-2020 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "wpigui.h"
+
+#include <algorithm>
+#include <cstdio>
+#include <cstring>
+
+#include <GLFW/glfw3.h>
+#include <imgui.h>
+#include <imgui_ProggyDotted.h>
+#include <imgui_impl_glfw.h>
+#include <imgui_internal.h>
+#include <implot.h>
+#include <stb_image.h>
+
+#include "wpigui_internal.h"
+
+using namespace wpi::gui;
+
+namespace wpi {
+
+Context* gui::gContext;
+
+static void ErrorCallback(int error, const char* description) {
+  std::fprintf(stderr, "GLFW Error %d: %s\n", error, description);
+}
+
+static void WindowSizeCallback(GLFWwindow* window, int width, int height) {
+  if (!gContext->maximized) {
+    gContext->width = width;
+    gContext->height = height;
+  }
+  PlatformRenderFrame();
+}
+
+static void FramebufferSizeCallback(GLFWwindow* window, int width, int height) {
+  PlatformFramebufferSizeChanged(width, height);
+}
+
+static void WindowMaximizeCallback(GLFWwindow* window, int maximized) {
+  gContext->maximized = maximized;
+}
+
+static void WindowPosCallback(GLFWwindow* window, int xpos, int ypos) {
+  if (!gContext->maximized) {
+    gContext->xPos = xpos;
+    gContext->yPos = ypos;
+  }
+}
+
+static void* IniReadOpen(ImGuiContext* ctx, ImGuiSettingsHandler* handler,
+                         const char* name) {
+  if (std::strcmp(name, "GLOBAL") != 0) return nullptr;
+  return static_cast<SavedSettings*>(gContext);
+}
+
+static void IniReadLine(ImGuiContext* ctx, ImGuiSettingsHandler* handler,
+                        void* entry, const char* lineStr) {
+  auto impl = static_cast<SavedSettings*>(entry);
+  const char* value = std::strchr(lineStr, '=');
+  if (!value) return;
+  ++value;
+  int num = std::atoi(value);
+  if (std::strncmp(lineStr, "width=", 6) == 0) {
+    impl->width = num;
+    impl->loadedWidthHeight = true;
+  } else if (std::strncmp(lineStr, "height=", 7) == 0) {
+    impl->height = num;
+    impl->loadedWidthHeight = true;
+  } else if (std::strncmp(lineStr, "maximized=", 10) == 0) {
+    impl->maximized = num;
+  } else if (std::strncmp(lineStr, "xpos=", 5) == 0) {
+    impl->xPos = num;
+  } else if (std::strncmp(lineStr, "ypos=", 5) == 0) {
+    impl->yPos = num;
+  } else if (std::strncmp(lineStr, "userScale=", 10) == 0) {
+    impl->userScale = num;
+  } else if (std::strncmp(lineStr, "style=", 6) == 0) {
+    impl->style = num;
+  }
+}
+
+static void IniWriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler,
+                        ImGuiTextBuffer* out_buf) {
+  if (!gContext) return;
+  out_buf->appendf(
+      "[MainWindow][GLOBAL]\nwidth=%d\nheight=%d\nmaximized=%d\n"
+      "xpos=%d\nypos=%d\nuserScale=%d\nstyle=%d\n\n",
+      gContext->width, gContext->height, gContext->maximized, gContext->xPos,
+      gContext->yPos, gContext->userScale, gContext->style);
+}
+
+void gui::CreateContext() {
+  gContext = new Context;
+  AddFont("ProggyDotted", [](ImGuiIO& io, float size, const ImFontConfig* cfg) {
+    return ImGui::AddFontProggyDotted(io, size, cfg);
+  });
+  PlatformCreateContext();
+}
+
+void gui::DestroyContext() {
+  PlatformDestroyContext();
+  delete gContext;
+  gContext = nullptr;
+}
+
+bool gui::Initialize(const char* title, int width, int height) {
+  gContext->title = title;
+  gContext->width = width;
+  gContext->height = height;
+  gContext->defaultWidth = width;
+  gContext->defaultHeight = height;
+
+  // Setup window
+  glfwSetErrorCallback(ErrorCallback);
+  glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE);
+  PlatformGlfwInitHints();
+  if (!glfwInit()) return false;
+
+  PlatformGlfwWindowHints();
+
+  // Setup Dear ImGui context
+  IMGUI_CHECKVERSION();
+  ImGui::CreateContext();
+  ImPlot::CreateContext();
+  ImGuiIO& io = ImGui::GetIO();
+
+  // Hook ini handler to save settings
+  ImGuiSettingsHandler iniHandler;
+  iniHandler.TypeName = "MainWindow";
+  iniHandler.TypeHash = ImHashStr(iniHandler.TypeName);
+  iniHandler.ReadOpenFn = IniReadOpen;
+  iniHandler.ReadLineFn = IniReadLine;
+  iniHandler.WriteAllFn = IniWriteAll;
+  ImGui::GetCurrentContext()->SettingsHandlers.push_back(iniHandler);
+
+  for (auto&& initialize : gContext->initializers) {
+    if (initialize) initialize();
+  }
+
+  // Load INI file
+  ImGui::LoadIniSettingsFromDisk(io.IniFilename);
+
+  // Set initial window settings
+  glfwWindowHint(GLFW_MAXIMIZED, gContext->maximized ? GLFW_TRUE : GLFW_FALSE);
+
+  if (gContext->width == 0 || gContext->height == 0) {
+    gContext->width = gContext->defaultWidth;
+    gContext->height = gContext->defaultHeight;
+    gContext->loadedWidthHeight = false;
+  }
+
+  float windowScale = 1.0;
+  if (!gContext->loadedWidthHeight) {
+    glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
+    // get the primary monitor work area to see if we have a reasonable initial
+    // window size; if not, maximize, and default scaling to smaller
+    if (GLFWmonitor* primary = glfwGetPrimaryMonitor()) {
+      int monWidth, monHeight;
+      glfwGetMonitorWorkarea(primary, nullptr, nullptr, &monWidth, &monHeight);
+      if (monWidth < gContext->width || monHeight < gContext->height) {
+        glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
+        windowScale = (std::min)(monWidth * 1.0 / gContext->width,
+                                 monHeight * 1.0 / gContext->height);
+      }
+    }
+  }
+  if (gContext->xPos != -1 && gContext->yPos != -1)
+    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
+
+  // Create window with graphics context
+  gContext->window =
+      glfwCreateWindow(gContext->width, gContext->height,
+                       gContext->title.c_str(), nullptr, nullptr);
+  if (!gContext->window) return false;
+
+  if (!gContext->loadedWidthHeight) {
+    if (windowScale == 1.0)
+      glfwGetWindowContentScale(gContext->window, &windowScale, nullptr);
+    // force user scale if window scale is smaller
+    if (windowScale <= 0.5)
+      gContext->userScale = 0;
+    else if (windowScale <= 0.75)
+      gContext->userScale = 1;
+    if (windowScale != 1.0) {
+      for (auto&& func : gContext->windowScalers) func(windowScale);
+    }
+  }
+
+  // Update window settings
+  if (gContext->xPos != -1 && gContext->yPos != -1) {
+    glfwSetWindowPos(gContext->window, gContext->xPos, gContext->yPos);
+    glfwShowWindow(gContext->window);
+  }
+
+  // Set window callbacks
+  glfwGetWindowSize(gContext->window, &gContext->width, &gContext->height);
+  glfwSetWindowSizeCallback(gContext->window, WindowSizeCallback);
+  glfwSetFramebufferSizeCallback(gContext->window, FramebufferSizeCallback);
+  glfwSetWindowMaximizeCallback(gContext->window, WindowMaximizeCallback);
+  glfwSetWindowPosCallback(gContext->window, WindowPosCallback);
+
+  // Setup Dear ImGui style
+  SetStyle(static_cast<Style>(gContext->style));
+
+  // Load Fonts
+  // this range is based on 13px being the "nominal" 100% size and going from
+  // ~0.5x (7px) to ~2.0x (25px)
+  for (auto&& makeFont : gContext->makeFonts) {
+    if (makeFont.second) {
+      auto& font = gContext->fonts.emplace_back();
+      for (int i = 0; i < Font::kScaledLevels; ++i) {
+        float size = 7.0f + i * 3.0f;
+        ImFontConfig cfg;
+        std::snprintf(cfg.Name, sizeof(cfg.Name), "%s-%d", makeFont.first,
+                      static_cast<int>(size));
+        font.scaled[i] = makeFont.second(io, size, &cfg);
+      }
+    }
+  }
+
+  if (!PlatformInitRenderer()) return false;
+
+  return true;
+}
+
+void gui::Main() {
+  // Main loop
+  while (!glfwWindowShouldClose(gContext->window) && !gContext->exit) {
+    // Poll and handle events (inputs, window resize, etc.)
+    glfwPollEvents();
+    PlatformRenderFrame();
+  }
+
+  // Cleanup
+  PlatformShutdown();
+  ImGui_ImplGlfw_Shutdown();
+  ImPlot::DestroyContext();
+  ImGui::DestroyContext();
+
+  glfwDestroyWindow(gContext->window);
+  glfwTerminate();
+}
+
+void gui::CommonRenderFrame() {
+  ImGui_ImplGlfw_NewFrame();
+
+  // Start the Dear ImGui frame
+  ImGui::NewFrame();
+
+  // Scale based on OS window content scaling
+  float windowScale = 1.0;
+  glfwGetWindowContentScale(gContext->window, &windowScale, nullptr);
+  // map to closest font size: 0 = 0.5x, 1 = 0.75x, 2 = 1.0x, 3 = 1.25x,
+  // 4 = 1.5x, 5 = 1.75x, 6 = 2x
+  gContext->fontScale = std::clamp(
+      gContext->userScale + static_cast<int>((windowScale - 1.0) * 4), 0,
+      Font::kScaledLevels - 1);
+  ImGui::GetIO().FontDefault = gContext->fonts[0].scaled[gContext->fontScale];
+
+  for (size_t i = 0; i < gContext->earlyExecutors.size(); ++i) {
+    auto& execute = gContext->earlyExecutors[i];
+    if (execute) execute();
+  }
+
+  for (size_t i = 0; i < gContext->lateExecutors.size(); ++i) {
+    auto& execute = gContext->lateExecutors[i];
+    if (execute) execute();
+  }
+
+  // Rendering
+  ImGui::Render();
+}
+
+void gui::Exit() {
+  if (!gContext) return;
+  gContext->exit = true;
+}
+
+void gui::AddInit(std::function<void()> initialize) {
+  if (initialize) gContext->initializers.emplace_back(std::move(initialize));
+}
+
+void gui::AddWindowScaler(std::function<void(float scale)> windowScaler) {
+  if (windowScaler)
+    gContext->windowScalers.emplace_back(std::move(windowScaler));
+}
+
+void gui::AddEarlyExecute(std::function<void()> execute) {
+  if (execute) gContext->earlyExecutors.emplace_back(std::move(execute));
+}
+
+void gui::AddLateExecute(std::function<void()> execute) {
+  if (execute) gContext->lateExecutors.emplace_back(std::move(execute));
+}
+
+GLFWwindow* gui::GetSystemWindow() { return gContext->window; }
+
+int gui::AddFont(
+    const char* name,
+    std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
+        makeFont) {
+  if (makeFont) gContext->makeFonts.emplace_back(name, std::move(makeFont));
+  return gContext->makeFonts.size() - 1;
+}
+
+ImFont* gui::GetFont(int font) {
+  return gContext->fonts[font].scaled[gContext->fontScale];
+}
+
+void gui::SetStyle(Style style) {
+  gContext->style = static_cast<int>(style);
+  switch (style) {
+    case kStyleClassic:
+      ImGui::StyleColorsClassic();
+      break;
+    case kStyleDark:
+      ImGui::StyleColorsDark();
+      break;
+    case kStyleLight:
+      ImGui::StyleColorsLight();
+      break;
+  }
+}
+
+void gui::SetClearColor(ImVec4 color) { gContext->clearColor = color; }
+
+void gui::EmitViewMenu() {
+  if (ImGui::BeginMenu("View")) {
+    if (ImGui::BeginMenu("Style")) {
+      bool selected;
+      selected = gContext->style == kStyleClassic;
+      if (ImGui::MenuItem("Classic", nullptr, &selected, true))
+        SetStyle(kStyleClassic);
+      selected = gContext->style == kStyleDark;
+      if (ImGui::MenuItem("Dark", nullptr, &selected, true))
+        SetStyle(kStyleDark);
+      selected = gContext->style == kStyleLight;
+      if (ImGui::MenuItem("Light", nullptr, &selected, true))
+        SetStyle(kStyleLight);
+      ImGui::EndMenu();
+    }
+
+    if (ImGui::BeginMenu("Zoom")) {
+      for (int i = 0; i < Font::kScaledLevels && (25 * (i + 2)) <= 200; ++i) {
+        char label[20];
+        std::snprintf(label, sizeof(label), "%d%%", 25 * (i + 2));
+        bool selected = gContext->userScale == i;
+        bool enabled = (gContext->fontScale - gContext->userScale + i) >= 0 &&
+                       (gContext->fontScale - gContext->userScale + i) <
+                           Font::kScaledLevels;
+        if (ImGui::MenuItem(label, nullptr, &selected, enabled))
+          gContext->userScale = i;
+      }
+      ImGui::EndMenu();
+    }
+    ImGui::EndMenu();
+  }
+}
+
+bool gui::UpdateTextureFromImage(ImTextureID* texture, int width, int height,
+                                 const unsigned char* data, int len) {
+  // Load from memory
+  int width2 = 0;
+  int height2 = 0;
+  unsigned char* imgData =
+      stbi_load_from_memory(data, len, &width2, &height2, nullptr, 4);
+  if (!data) return false;
+
+  if (width2 == width && height2 == height)
+    UpdateTexture(texture, kPixelRGBA, width2, height2, imgData);
+  else
+    *texture = CreateTexture(kPixelRGBA, width2, height2, imgData);
+
+  stbi_image_free(imgData);
+
+  return true;
+}
+
+bool gui::CreateTextureFromFile(const char* filename, ImTextureID* out_texture,
+                                int* out_width, int* out_height) {
+  // Load from file
+  int width = 0;
+  int height = 0;
+  unsigned char* data = stbi_load(filename, &width, &height, nullptr, 4);
+  if (!data) return false;
+
+  *out_texture = CreateTexture(kPixelRGBA, width, height, data);
+  if (out_width) *out_width = width;
+  if (out_height) *out_height = height;
+
+  stbi_image_free(data);
+
+  return true;
+}
+
+bool gui::CreateTextureFromImage(const unsigned char* data, int len,
+                                 ImTextureID* out_texture, int* out_width,
+                                 int* out_height) {
+  // Load from memory
+  int width = 0;
+  int height = 0;
+  unsigned char* imgData =
+      stbi_load_from_memory(data, len, &width, &height, nullptr, 4);
+  if (!imgData) return false;
+
+  *out_texture = CreateTexture(kPixelRGBA, width, height, imgData);
+  if (out_width) *out_width = width;
+  if (out_height) *out_height = height;
+
+  stbi_image_free(imgData);
+
+  return true;
+}
+
+void gui::MaxFit(ImVec2* min, ImVec2* max, float width, float height) {
+  float destWidth = max->x - min->x;
+  float destHeight = max->y - min->y;
+  if (width == 0 || height == 0) return;
+  if (destWidth * height > destHeight * width) {
+    float outputWidth = width * destHeight / height;
+    min->x += (destWidth - outputWidth) / 2;
+    max->x -= (destWidth - outputWidth) / 2;
+  } else {
+    float outputHeight = height * destWidth / width;
+    min->y += (destHeight - outputHeight) / 2;
+    max->y -= (destHeight - outputHeight) / 2;
+  }
+}
+
+}  // namespace wpi
diff --git a/wpigui/src/main/native/directx11/wpigui_directx11.cpp b/wpigui/src/main/native/directx11/wpigui_directx11.cpp
new file mode 100644
index 0000000..6ecf155
--- /dev/null
+++ b/wpigui/src/main/native/directx11/wpigui_directx11.cpp
@@ -0,0 +1,242 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2019-2020 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <d3d11.h>
+
+#define GLFW_INCLUDE_NONE
+#define GLFW_EXPOSE_NATIVE_WIN32
+#include <GLFW/glfw3.h>
+#include <GLFW/glfw3native.h>
+
+#include <imgui.h>
+#include <imgui_impl_glfw.h>
+#include <imgui_impl_dx11.h>
+
+#include "wpigui.h"
+#include "wpigui_internal.h"
+
+using namespace wpi::gui;
+
+namespace {
+struct PlatformContext {
+  ID3D11Device* pd3dDevice = nullptr;
+  ID3D11DeviceContext* pd3dDeviceContext = nullptr;
+  IDXGISwapChain* pSwapChain = nullptr;
+  ID3D11RenderTargetView* mainRenderTargetView = nullptr;
+};
+}  // namespace
+
+static PlatformContext* gPlatformContext;
+static bool gPlatformValid = false;
+
+static void CreateRenderTarget() {
+  ID3D11Texture2D* pBackBuffer;
+  gPlatformContext->pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
+  gPlatformContext->pd3dDevice->CreateRenderTargetView(
+      pBackBuffer, nullptr, &gPlatformContext->mainRenderTargetView);
+  pBackBuffer->Release();
+}
+
+static bool CreateDeviceD3D(HWND hWnd) {
+  // Setup swap chain
+  DXGI_SWAP_CHAIN_DESC sd;
+  ZeroMemory(&sd, sizeof(sd));
+  sd.BufferCount = 2;
+  sd.BufferDesc.Width = 0;
+  sd.BufferDesc.Height = 0;
+  sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+  sd.BufferDesc.RefreshRate.Numerator = 60;
+  sd.BufferDesc.RefreshRate.Denominator = 1;
+  sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+  sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+  sd.OutputWindow = hWnd;
+  sd.SampleDesc.Count = 1;
+  sd.SampleDesc.Quality = 0;
+  sd.Windowed = TRUE;
+  sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+
+  UINT createDeviceFlags = 0;
+  // createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
+  D3D_FEATURE_LEVEL featureLevel;
+  const D3D_FEATURE_LEVEL featureLevelArray[2] = {
+      D3D_FEATURE_LEVEL_11_0,
+      D3D_FEATURE_LEVEL_10_0,
+  };
+  if (D3D11CreateDeviceAndSwapChain(
+          nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags,
+          featureLevelArray, 2, D3D11_SDK_VERSION, &sd,
+          &gPlatformContext->pSwapChain, &gPlatformContext->pd3dDevice,
+          &featureLevel, &gPlatformContext->pd3dDeviceContext) != S_OK)
+    return false;
+
+  CreateRenderTarget();
+  return true;
+}
+
+static void CleanupRenderTarget() {
+  if (gPlatformContext->mainRenderTargetView) {
+    gPlatformContext->mainRenderTargetView->Release();
+    gPlatformContext->mainRenderTargetView = nullptr;
+  }
+}
+
+static void CleanupDeviceD3D() {
+  CleanupRenderTarget();
+  if (gPlatformContext->pSwapChain) {
+    gPlatformContext->pSwapChain->Release();
+    gPlatformContext->pSwapChain = nullptr;
+  }
+  if (gPlatformContext->pd3dDeviceContext) {
+    gPlatformContext->pd3dDeviceContext->Release();
+    gPlatformContext->pd3dDeviceContext = nullptr;
+  }
+  if (gPlatformContext->pd3dDevice) {
+    gPlatformContext->pd3dDevice->Release();
+    gPlatformContext->pd3dDevice = nullptr;
+  }
+}
+
+namespace wpi {
+
+void gui::PlatformCreateContext() { gPlatformContext = new PlatformContext; }
+
+void gui::PlatformDestroyContext() {
+  CleanupDeviceD3D();
+  delete gPlatformContext;
+  gPlatformContext = nullptr;
+}
+
+void gui::PlatformGlfwInitHints() {}
+
+void gui::PlatformGlfwWindowHints() {
+  glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+}
+
+bool gui::PlatformInitRenderer() {
+  // Initialize Direct3D
+  if (!CreateDeviceD3D(glfwGetWin32Window(gContext->window))) {
+    CleanupDeviceD3D();
+    return false;
+  }
+
+  ImGui_ImplGlfw_InitForOpenGL(gContext->window, true);
+  ImGui_ImplDX11_Init(gPlatformContext->pd3dDevice,
+                      gPlatformContext->pd3dDeviceContext);
+
+  gPlatformValid = true;
+  return true;
+}
+
+void gui::PlatformRenderFrame() {
+  ImGui_ImplDX11_NewFrame();
+
+  CommonRenderFrame();
+
+  gPlatformContext->pd3dDeviceContext->OMSetRenderTargets(
+      1, &gPlatformContext->mainRenderTargetView, nullptr);
+  gPlatformContext->pd3dDeviceContext->ClearRenderTargetView(
+      gPlatformContext->mainRenderTargetView,
+      reinterpret_cast<float*>(&gContext->clearColor));
+  ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
+
+  gPlatformContext->pSwapChain->Present(1, 0);  // Present with vsync
+  // gPlatformContext->pSwapChain->Present(0, 0);  // Present without vsync
+}
+
+void gui::PlatformShutdown() {
+  gPlatformValid = false;
+  ImGui_ImplDX11_Shutdown();
+}
+
+void gui::PlatformFramebufferSizeChanged(int width, int height) {
+  if (gPlatformContext && gPlatformContext->pd3dDevice) {
+    CleanupRenderTarget();
+    gPlatformContext->pSwapChain->ResizeBuffers(0, width, height,
+                                                DXGI_FORMAT_UNKNOWN, 0);
+    CreateRenderTarget();
+  }
+}
+
+static inline DXGI_FORMAT DXPixelFormat(PixelFormat format) {
+  switch (format) {
+    case kPixelRGBA:
+      return DXGI_FORMAT_R8G8B8A8_UNORM;
+    case kPixelBGRA:
+      return DXGI_FORMAT_B8G8R8A8_UNORM;
+    default:
+      return DXGI_FORMAT_R8G8B8A8_UNORM;
+  }
+}
+
+ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
+                               const unsigned char* data) {
+  if (!gPlatformValid) return nullptr;
+
+  // Create texture
+  D3D11_TEXTURE2D_DESC desc;
+  ZeroMemory(&desc, sizeof(desc));
+  desc.Width = width;
+  desc.Height = height;
+  desc.MipLevels = 1;
+  desc.ArraySize = 1;
+  desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+  desc.SampleDesc.Count = 1;
+  desc.Usage = D3D11_USAGE_DEFAULT;
+  desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+  desc.CPUAccessFlags = 0;
+
+  ID3D11Texture2D* pTexture = nullptr;
+  D3D11_SUBRESOURCE_DATA subResource;
+  subResource.pSysMem = data;
+  subResource.SysMemPitch = desc.Width * 4;
+  subResource.SysMemSlicePitch = 0;
+  gPlatformContext->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
+
+  // Create texture view
+  D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+  ZeroMemory(&srvDesc, sizeof(srvDesc));
+  srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+  srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+  srvDesc.Texture2D.MipLevels = desc.MipLevels;
+  srvDesc.Texture2D.MostDetailedMip = 0;
+  ID3D11ShaderResourceView* srv;
+  gPlatformContext->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc,
+                                                         &srv);
+  pTexture->Release();
+
+  return srv;
+}
+
+void gui::UpdateTexture(ImTextureID texture, PixelFormat, int width, int height,
+                        const unsigned char* data) {
+  if (!texture) return;
+
+  D3D11_BOX box;
+  box.front = 0;
+  box.back = 1;
+  box.left = 0;
+  box.right = width;
+  box.top = 0;
+  box.bottom = height;
+
+  ID3D11Resource* resource = nullptr;
+  static_cast<ID3D11ShaderResourceView*>(texture)->GetResource(&resource);
+
+  if (resource) {
+    gPlatformContext->pd3dDeviceContext->UpdateSubresource(
+        resource, 0, &box, data, width * 4, width * height * 4);
+
+    resource->Release();
+  }
+}
+
+void gui::DeleteTexture(ImTextureID texture) {
+  if (!gPlatformValid) return;
+  if (texture) static_cast<ID3D11ShaderResourceView*>(texture)->Release();
+}
+
+}  // namespace wpi
diff --git a/wpigui/src/main/native/include/portable-file-dialogs.h b/wpigui/src/main/native/include/portable-file-dialogs.h
new file mode 100644
index 0000000..dffa71e
--- /dev/null
+++ b/wpigui/src/main/native/include/portable-file-dialogs.h
@@ -0,0 +1,249 @@
+//
+//  Portable File Dialogs
+//
+//  Copyright © 2018—2020 Sam Hocevar <sam@hocevar.net>
+//
+//  This library is free software. It comes without any warranty, to
+//  the extent permitted by applicable law. You can redistribute it
+//  and/or modify it under the terms of the Do What the **** You Want
+//  to Public License, Version 2, as published by the WTFPL Task Force.
+//  See http://www.wtfpl.net/ for more details.
+//
+
+#pragma once
+
+#include <string>   // std::string
+#include <memory>   // std::shared_ptr
+#include <map>      // std::map
+#include <vector>
+
+namespace pfd
+{
+
+enum class button
+{
+    cancel = -1,
+    ok,
+    yes,
+    no,
+    abort,
+    retry,
+    ignore,
+};
+
+enum class choice
+{
+    ok = 0,
+    ok_cancel,
+    yes_no,
+    yes_no_cancel,
+    retry_cancel,
+    abort_retry_ignore,
+};
+
+enum class icon
+{
+    info = 0,
+    warning,
+    error,
+    question,
+};
+
+// Additional option flags for various dialog constructors
+enum class opt : uint8_t
+{
+    none = 0,
+    // For file open, allow multiselect.
+    multiselect     = 0x1,
+    // For file save, force overwrite and disable the confirmation dialog.
+    force_overwrite = 0x2,
+    // For folder select, force path to be the provided argument instead
+    // of the last opened directory, which is the Microsoft-recommended,
+    // user-friendly behaviour.
+    force_path      = 0x4,
+};
+
+inline opt operator |(opt a, opt b) { return opt(uint8_t(a) | uint8_t(b)); }
+inline bool operator &(opt a, opt b) { return bool(uint8_t(a) & uint8_t(b)); }
+
+// The settings class, only exposing to the user a way to set verbose mode
+// and to force a rescan of installed desktop helpers (zenity, kdialog…).
+class settings
+{
+public:
+    static bool available();
+
+    static void verbose(bool value);
+    static void rescan();
+
+protected:
+    explicit settings(bool resync = false);
+
+    bool check_program(std::string const &program);
+
+    constexpr bool is_osascript() const {
+#if __APPLE__
+        return true;
+#else
+        return false;
+#endif
+    }
+    bool is_zenity() const {
+        return flags(flag::has_zenity) ||
+               flags(flag::has_matedialog) ||
+               flags(flag::has_qarma);
+    }
+    bool is_kdialog() const { return flags(flag::has_kdialog); }
+
+    enum class flag
+    {
+        is_scanned = 0,
+        is_verbose,
+
+        has_zenity,
+        has_matedialog,
+        has_qarma,
+        has_kdialog,
+        is_vista,
+
+        max_flag,
+    };
+
+    // Static array of flags for internal state
+    bool const &flags(flag in_flag) const;
+
+    // Non-const getter for the static array of flags
+    bool &flags(flag in_flag);
+};
+
+// Internal classes, not to be used by client applications
+namespace internal
+{
+
+// Process wait timeout, in milliseconds
+constexpr int default_wait_timeout = 20;
+
+class executor;
+
+class dialog : protected settings
+{
+public:
+    bool ready(int timeout = default_wait_timeout) const;
+    bool kill() const;
+
+protected:
+    explicit dialog();
+
+    std::vector<std::string> desktop_helper() const;
+    static std::string buttons_to_name(choice _choice);
+    static std::string get_icon_name(icon _icon);
+
+    std::string powershell_quote(std::string const &str) const;
+    std::string osascript_quote(std::string const &str) const;
+    std::string shell_quote(std::string const &str) const;
+
+    // Keep handle to executing command
+    std::shared_ptr<executor> m_async;
+};
+
+class file_dialog : public dialog
+{
+protected:
+    enum type
+    {
+        open,
+        save,
+        folder,
+    };
+
+    file_dialog(type in_type,
+                std::string const &title,
+                std::string const &default_path = "",
+                std::vector<std::string> const &filters = {},
+                opt options = opt::none);
+
+protected:
+    std::string string_result();
+    std::vector<std::string> vector_result();
+
+    class Impl;
+    std::shared_ptr<Impl> m_impl;
+};
+
+} // namespace internal
+
+//
+// The notify widget
+//
+
+class notify : public internal::dialog
+{
+public:
+    notify(std::string const &title,
+           std::string const &message,
+           icon _icon = icon::info);
+};
+
+//
+// The message widget
+//
+
+class message : public internal::dialog
+{
+public:
+    message(std::string const &title,
+            std::string const &text,
+            choice _choice = choice::ok_cancel,
+            icon _icon = icon::info);
+
+    button result();
+
+private:
+    // Some extra logic to map the exit code to button number
+    std::map<int, button> m_mappings;
+};
+
+//
+// The open_file, save_file, and open_folder widgets
+//
+
+class open_file : public internal::file_dialog
+{
+public:
+    open_file(std::string const &title,
+              std::string const &default_path = "",
+              std::vector<std::string> const &filters = { "All Files", "*" },
+              opt options = opt::none)
+      : file_dialog(type::open, title, default_path, filters, options)
+    {}
+
+    std::vector<std::string> result() { return vector_result(); }
+};
+
+class save_file : public internal::file_dialog
+{
+public:
+    save_file(std::string const &title,
+              std::string const &default_path = "",
+              std::vector<std::string> const &filters = { "All Files", "*" },
+              opt options = opt::none)
+      : file_dialog(type::save, title, default_path, filters, options)
+    {}
+
+    std::string result() { return string_result(); }
+};
+
+class select_folder : public internal::file_dialog
+{
+public:
+    select_folder(std::string const &title,
+                  std::string const &default_path = "",
+                  opt options = opt::none)
+      : file_dialog(type::folder, title, default_path, {}, options)
+    {}
+
+    std::string result() { return string_result(); }
+};
+
+} // namespace pfd
+
diff --git a/wpigui/src/main/native/include/wpigui.h b/wpigui/src/main/native/include/wpigui.h
new file mode 100644
index 0000000..c1dbc15
--- /dev/null
+++ b/wpigui/src/main/native/include/wpigui.h
@@ -0,0 +1,379 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2019-2020 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <functional>
+
+#include <imgui.h>
+
+extern "C" struct GLFWwindow;
+
+namespace wpi::gui {
+
+/**
+ * Creates GUI context.  Must be called prior to calling any other functions.
+ */
+void CreateContext();
+
+/**
+ * Destroys GUI context.
+ */
+void DestroyContext();
+
+/**
+ * Initializes the GUI.
+ *
+ * @param title main application window title
+ * @param width main application window width
+ * @param height main application window height
+ */
+bool Initialize(const char* title, int width, int height);
+
+/**
+ * Runs main GUI loop.  On some OS'es this must be called from the main thread.
+ * Does not return until Exit() is called.
+ */
+void Main();
+
+/**
+ * Exits main GUI loop when current loop iteration finishes.
+ * Safe to call from any thread, including from within main GUI loop.
+ */
+void Exit();
+
+/**
+ * Adds initializer to GUI.  The passed function is called once, immediately
+ * after the GUI (both GLFW and Dear ImGui) are initialized in Initialize().
+ * To have any effect, must be called prior to Initialize().
+ *
+ * @param initialize initialization function
+ */
+void AddInit(std::function<void()> initialize);
+
+/**
+ * Adds window scaler function.  The passed function is called once during
+ * Initialize() if the window scale is not 1.0.  To have any effect, must
+ * be called prior to Initialize().
+ *
+ * @param windowScaler window scaler function
+ */
+void AddWindowScaler(std::function<void(float scale)> windowScaler);
+
+/**
+ * Adds per-frame executor to GUI.  The passed function is called on each
+ * Dear ImGui frame prior to any of the late execute functions.
+ *
+ * @param execute frame execution function
+ */
+void AddEarlyExecute(std::function<void()> execute);
+
+/**
+ * Adds per-frame executor to GUI.  The passed function is called on each
+ * Dear ImGui frame after all of the early execute functions.
+ *
+ * @param execute frame execution function
+ */
+void AddLateExecute(std::function<void()> execute);
+
+/**
+ * Gets GLFW window handle.
+ */
+GLFWwindow* GetSystemWindow();
+
+/**
+ * Adds a font to the GUI.  The passed function is called during
+ * initialization as many times as necessary to create a range of sizes.
+ *
+ * @param name font name
+ * @param makeFont font creation / loader function
+ * @return Font index for later use with GetFont()
+ */
+int AddFont(
+    const char* name,
+    std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
+        makeFont);
+
+/**
+ * Gets a font added with AddFont() with the appropriate font size for
+ * the current scaling of the GUI.
+ *
+ * @param font font index returned by AddFont()
+ * @return Font pointer
+ */
+ImFont* GetFont(int font);
+
+enum Style { kStyleClassic = 0, kStyleDark, kStyleLight };
+
+/**
+ * Sets the ImGui style.  Using this function makes this setting persistent.
+ *
+ * @param style Style
+ */
+void SetStyle(Style style);
+
+/**
+ * Sets the clear (background) color.
+ *
+ * @param color Color
+ */
+void SetClearColor(ImVec4 color);
+
+/**
+ * Emits a View menu (e.g. for a main menu bar) that allows setting of
+ * style and zoom.  Internally starts with ImGui::BeginMenu("View").
+ */
+void EmitViewMenu();
+
+/**
+ * Pixel formats for texture pixel data.
+ */
+enum PixelFormat { kPixelRGBA, kPixelBGRA };
+
+/**
+ * Creates a texture from pixel data.
+ *
+ * @param format pixel format
+ * @param width image width
+ * @param height image height
+ * @param data pixel data
+ * @return Texture
+ */
+ImTextureID CreateTexture(PixelFormat format, int width, int height,
+                          const unsigned char* data);
+
+/**
+ * Updates a texture from pixel data.
+ * The passed-in width and height must match the width and height of the
+ * texture.
+ *
+ * @param texture texture
+ * @param format pixel format
+ * @param width texture width
+ * @param height texture height
+ * @param data pixel data
+ */
+void UpdateTexture(ImTextureID texture, PixelFormat format, int width,
+                   int height, const unsigned char* data);
+
+/**
+ * Updates a texture from image data.
+ * The pixel format of the texture must be RGBA.  The passed-in width and
+ * height must match the width and height of the texture.  If the width and
+ * height of the image differ from the passed-in width and height, a new
+ * texture is created (note this may be inefficient).
+ *
+ * @param texture texture (pointer, may be updated)
+ * @param width texture width
+ * @param height texture height
+ * @param data image data
+ * @param len image data length
+ *
+ * @return True on success, false on failure.
+ */
+bool UpdateTextureFromImage(ImTextureID* texture, int width, int height,
+                            const unsigned char* data, int len);
+
+/**
+ * Creates a texture from an image file.
+ *
+ * @param filename filename
+ * @param out_texture texture (output)
+ * @param out_width image width (output)
+ * @param out_height image height (output)
+ * @return True on success, false on failure.
+ */
+bool CreateTextureFromFile(const char* filename, ImTextureID* out_texture,
+                           int* out_width, int* out_height);
+
+/**
+ * Creates a texture from image data.
+ *
+ * @param data image data
+ * @param len image data length
+ * @param out_texture texture (output)
+ * @param out_width image width (output)
+ * @param out_height image height (output)
+ * @return True on success, false on failure.
+ */
+bool CreateTextureFromImage(const unsigned char* data, int len,
+                            ImTextureID* out_texture, int* out_width,
+                            int* out_height);
+
+/**
+ * Deletes a texture.
+ *
+ * @param texture texture
+ */
+void DeleteTexture(ImTextureID texture);
+
+/**
+ * RAII wrapper around ImTextureID.  Also keeps track of width, height, and
+ * pixel format.
+ */
+class Texture {
+ public:
+  Texture() = default;
+
+  /**
+   * Constructs a texture from pixel data.
+   *
+   * @param format pixel format
+   * @param width image width
+   * @param height image height
+   * @param data pixel data
+   */
+  Texture(PixelFormat format, int width, int height, const unsigned char* data)
+      : m_format{format}, m_width{width}, m_height{height} {
+    m_texture = CreateTexture(format, width, height, data);
+  }
+
+  Texture(const Texture&) = delete;
+  Texture(Texture&& oth)
+      : m_texture{oth.m_texture},
+        m_format{oth.m_format},
+        m_width{oth.m_width},
+        m_height{oth.m_height} {
+    oth.m_texture = 0;
+  }
+
+  Texture& operator=(const Texture&) = delete;
+  Texture& operator=(Texture&& oth) {
+    if (m_texture) DeleteTexture(m_texture);
+    m_texture = oth.m_texture;
+    oth.m_texture = 0;
+    m_format = oth.m_format;
+    m_width = oth.m_width;
+    m_height = oth.m_height;
+    return *this;
+  }
+
+  ~Texture() {
+    if (m_texture) DeleteTexture(m_texture);
+  }
+
+  /**
+   * Evaluates to true if the texture is valid.
+   */
+  explicit operator bool() const { return m_texture; }
+
+  /**
+   * Implicit conversion to ImTextureID.
+   */
+  operator ImTextureID() const { return m_texture; }
+
+  /**
+   * Gets the texture pixel format.
+   *
+   * @return pixel format
+   */
+  PixelFormat GetFormat() const { return m_format; }
+
+  /**
+   * Gets the texture width.
+   *
+   * @return width
+   */
+  int GetWidth() const { return m_width; }
+
+  /**
+   * Gets the texture height.
+   *
+   * @return height
+   */
+  int GetHeight() const { return m_height; }
+
+  /**
+   * Updates the texture from pixel data.
+   * The image data size and format is assumed to match that of the texture.
+   *
+   * @param format pixel format
+   * @param data pixel data
+   */
+  void Update(const unsigned char* data) {
+    UpdateTexture(m_texture, m_format, m_width, m_height, data);
+  }
+
+  /**
+   * Updates the texture from image data.
+   * The pixel format of the texture must be RGBA.  If the width and height of
+   * the image differ from the texture width and height, a new texture is
+   * created (note this may be inefficient).
+   *
+   * @param data image data
+   * @param len image data length
+   *
+   * @return True on success, false on failure.
+   */
+  bool UpdateFromImage(const unsigned char* data, int len) {
+    return UpdateTextureFromImage(&m_texture, m_width, m_height, data, len);
+  }
+
+  /**
+   * Creates a texture by loading an image file.
+   *
+   * @param filename filename
+   *
+   * @return Texture, or invalid (empty) texture on failure.
+   */
+  static Texture CreateFromFile(const char* filename) {
+    Texture texture;
+    if (!CreateTextureFromFile(filename, &texture.m_texture, &texture.m_width,
+                               &texture.m_height))
+      return {};
+    return texture;
+  }
+
+  /**
+   * Creates a texture from image data.
+   *
+   * @param data image data
+   * @param len image data length
+   *
+   * @return Texture, or invalid (empty) texture on failure.
+   */
+  static Texture CreateFromImage(const unsigned char* data, int len) {
+    Texture texture;
+    if (!CreateTextureFromImage(data, len, &texture.m_texture, &texture.m_width,
+                                &texture.m_height))
+      return {};
+    return texture;
+  }
+
+ private:
+  ImTextureID m_texture = nullptr;
+  PixelFormat m_format = kPixelRGBA;
+  int m_width = 0;
+  int m_height = 0;
+};
+
+/**
+ * Get square of distance between two ImVec2's.
+ *
+ * @param a first ImVec
+ * @param b second ImVec
+ *
+ * @return Distance^2 between a and b.
+ */
+inline float GetDistSquared(const ImVec2& a, const ImVec2& b) {
+  float deltaX = b.x - a.x;
+  float deltaY = b.y - a.y;
+  return deltaX * deltaX + deltaY * deltaY;
+}
+
+/**
+ * Maximize fit in "window" while preserving aspect ratio.  Min and max
+ * passed-in values are modified such that the object maximally fits.
+ *
+ * @param min upper left corner of window (modified to fit)
+ * @param max lower right corner of window (modified to fit)
+ * @param width width of object to fit
+ * @param height height of object to fit
+ */
+void MaxFit(ImVec2* min, ImVec2* max, float width, float height);
+
+}  // namespace wpi::gui
diff --git a/wpigui/src/main/native/include/wpigui_internal.h b/wpigui/src/main/native/include/wpigui_internal.h
new file mode 100644
index 0000000..9a2c70f
--- /dev/null
+++ b/wpigui/src/main/native/include/wpigui_internal.h
@@ -0,0 +1,74 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2019-2020 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <atomic>
+#include <functional>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <GLFW/glfw3.h>
+#include <imgui.h>
+
+namespace wpi::gui {
+
+struct SavedSettings {
+  bool loadedWidthHeight = false;
+  int width;
+  int height;
+  int maximized = 0;
+  int xPos = -1;
+  int yPos = -1;
+  int userScale = 2;
+  int style = 0;
+};
+
+struct Font {
+  static constexpr int kScaledLevels = 9;
+  ImFont* scaled[kScaledLevels];
+};
+
+struct Context : public SavedSettings {
+  std::atomic_bool exit{false};
+
+  std::string title;
+  int defaultWidth;
+  int defaultHeight;
+
+  GLFWwindow* window = nullptr;
+
+  std::vector<std::function<void()>> initializers;
+  std::vector<std::function<void(float scale)>> windowScalers;
+  std::vector<std::pair<
+      const char*,
+      std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>>>
+      makeFonts;
+
+  ImVec4 clearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
+  std::vector<std::function<void()>> earlyExecutors;
+  std::vector<std::function<void()>> lateExecutors;
+
+  int fontScale = 2;  // updated by main loop
+  std::vector<Font> fonts;
+};
+
+extern Context* gContext;
+
+void PlatformCreateContext();
+void PlatformDestroyContext();
+void PlatformGlfwInitHints();
+void PlatformGlfwWindowHints();
+bool PlatformInitRenderer();
+void PlatformRenderFrame();
+void PlatformShutdown();
+void PlatformFramebufferSizeChanged(int width, int height);
+
+void CommonRenderFrame();
+
+}  // namespace wpi::gui
diff --git a/wpigui/src/main/native/metal/wpigui_metal.mm b/wpigui/src/main/native/metal/wpigui_metal.mm
new file mode 100644
index 0000000..cf46247
--- /dev/null
+++ b/wpigui/src/main/native/metal/wpigui_metal.mm
@@ -0,0 +1,154 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2019-2020 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#define GLFW_INCLUDE_NONE
+#define GLFW_EXPOSE_NATIVE_COCOA
+#include <GLFW/glfw3.h>
+#include <GLFW/glfw3native.h>
+
+#import <Metal/Metal.h>
+#import <QuartzCore/QuartzCore.h>
+
+#include <imgui.h>
+#include <imgui_impl_glfw.h>
+#include <imgui_impl_metal.h>
+
+#include "wpigui.h"
+#include "wpigui_internal.h"
+
+using namespace wpi::gui;
+
+namespace {
+struct PlatformContext {
+  CAMetalLayer* layer;
+  MTLRenderPassDescriptor *renderPassDescriptor;
+  id <MTLCommandQueue> commandQueue;
+};
+}  // namespace
+
+static PlatformContext* gPlatformContext;
+static bool gPlatformValid = false;
+
+namespace wpi {
+
+void gui::PlatformCreateContext() {
+  gPlatformContext = new PlatformContext;
+}
+
+void gui::PlatformDestroyContext() {
+  delete gPlatformContext;
+  gPlatformContext = nullptr;
+}
+
+void gui::PlatformGlfwInitHints() {}
+
+void gui::PlatformGlfwWindowHints() {
+  glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
+}
+
+bool gui::PlatformInitRenderer() {
+  id <MTLDevice> device = MTLCreateSystemDefaultDevice();
+  gPlatformContext->commandQueue = [device newCommandQueue];
+
+  ImGui_ImplGlfw_InitForOpenGL(gContext->window, true);
+  ImGui_ImplMetal_Init(device);
+
+  NSWindow *nswin = glfwGetCocoaWindow(gContext->window);
+  gPlatformContext->layer = [CAMetalLayer layer];
+  gPlatformContext->layer.device = device;
+  gPlatformContext->layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
+  nswin.contentView.layer = gPlatformContext->layer;
+  nswin.contentView.wantsLayer = YES;
+
+  gPlatformContext->renderPassDescriptor = [MTLRenderPassDescriptor new];
+
+  gPlatformValid = true;
+  return true;
+}
+
+void gui::PlatformRenderFrame() {
+  @autoreleasepool
+  {
+    int width, height;
+    glfwGetFramebufferSize(gContext->window, &width, &height);
+    gPlatformContext->layer.drawableSize = CGSizeMake(width, height);
+    id<CAMetalDrawable> drawable = [gPlatformContext->layer nextDrawable];
+
+    id<MTLCommandBuffer> commandBuffer = [gPlatformContext->commandQueue commandBuffer];
+    auto renderPassDescriptor = gPlatformContext->renderPassDescriptor;
+    renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(gContext->clearColor.x, gContext->clearColor.y, gContext->clearColor.z, gContext->clearColor.w);
+    renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
+    renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
+    renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
+    id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
+    [renderEncoder pushDebugGroup:@"WPI GUI"];
+
+    // Start the Dear ImGui frame
+    ImGui_ImplMetal_NewFrame(renderPassDescriptor);
+
+    CommonRenderFrame();
+
+    ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
+
+    [renderEncoder popDebugGroup];
+    [renderEncoder endEncoding];
+
+    [commandBuffer presentDrawable:drawable];
+    [commandBuffer commit];
+  }
+}
+
+void gui::PlatformShutdown() {
+  ImGui_ImplMetal_Shutdown();
+  gPlatformValid = false;
+}
+
+void gui::PlatformFramebufferSizeChanged(int, int) {}
+
+static inline MTLPixelFormat MetalPixelFormat(PixelFormat format) {
+  switch (format) {
+    case kPixelRGBA:
+      return MTLPixelFormatRGBA8Unorm;
+    case kPixelBGRA:
+      return MTLPixelFormatBGRA8Unorm;
+    default:
+      return MTLPixelFormatRGBA8Unorm;
+  }
+}
+
+ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
+                               const unsigned char* data) {
+  if (!gPlatformValid) return nullptr;
+
+  MTLPixelFormat fmt = MetalPixelFormat(format);
+  MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:fmt width:width height:height mipmapped:NO];
+  textureDescriptor.usage = MTLTextureUsageShaderRead;
+#if TARGET_OS_OSX
+  textureDescriptor.storageMode = MTLStorageModeManaged;
+#else
+  textureDescriptor.storageMode = MTLStorageModeShared;
+#endif
+  id <MTLTexture> texture = [gPlatformContext->layer.device newTextureWithDescriptor:textureDescriptor];
+  [texture replaceRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 withBytes:data bytesPerRow:width * 4];
+
+  return (__bridge_retained void *)texture;
+}
+
+void gui::UpdateTexture(ImTextureID texture, PixelFormat, int width,
+                        int height, const unsigned char* data) {
+  if (!texture) return;
+  id <MTLTexture> mtlTexture = (__bridge id <MTLTexture>)texture;
+  [mtlTexture replaceRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 withBytes:data bytesPerRow:width * 4];
+}
+
+void gui::DeleteTexture(ImTextureID texture) {
+  if (!gPlatformValid || !texture) return;
+  id <MTLTexture> mtlTexture = (__bridge_transfer id <MTLTexture>)texture;
+  (void)mtlTexture;
+}
+
+}  // namespace wpi
diff --git a/wpigui/src/main/native/opengl3/wpigui_opengl3.cpp b/wpigui/src/main/native/opengl3/wpigui_opengl3.cpp
new file mode 100644
index 0000000..bf14700
--- /dev/null
+++ b/wpigui/src/main/native/opengl3/wpigui_opengl3.cpp
@@ -0,0 +1,151 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2019-2020 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <cstdio>
+
+#include <GL/gl3w.h>
+#include <GLFW/glfw3.h>
+#include <imgui.h>
+#include <imgui_impl_glfw.h>
+#include <imgui_impl_opengl3.h>
+
+#include "wpigui.h"
+#include "wpigui_internal.h"
+
+using namespace wpi::gui;
+
+static bool gPlatformValid = false;
+
+namespace wpi {
+
+void gui::PlatformCreateContext() {}
+
+void gui::PlatformDestroyContext() {}
+
+void gui::PlatformGlfwInitHints() {}
+
+void gui::PlatformGlfwWindowHints() {
+  // Decide GL versions
+#if __APPLE__
+  // GL 3.2 + GLSL 150
+  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
+  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  // 3.2+ only
+  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);  // Required on Mac
+  glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, GLFW_TRUE);
+#else
+  // GL 3.0 + GLSL 130
+  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
+  // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  // 3.2+
+  // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+
+#endif
+
+  // enable 4xMSAA
+  glfwWindowHint(GLFW_SAMPLES, 4);
+}
+
+bool gui::PlatformInitRenderer() {
+  glfwMakeContextCurrent(gContext->window);
+
+  glfwSwapInterval(1);  // Enable vsync
+
+  // Initialize OpenGL loader
+  if (gl3wInit() != 0) {
+    std::fprintf(stderr, "Failed to initialize OpenGL loader!\n");
+    return false;
+  }
+
+  // Turn on multisampling
+  glEnable(GL_MULTISAMPLE);
+
+  // Setup Platform/Renderer bindings
+  ImGui_ImplGlfw_InitForOpenGL(gContext->window, true);
+
+  // Decide GLSL versions
+#if __APPLE__
+  const char* glsl_version = "#version 150";
+#else
+  const char* glsl_version = "#version 130";
+#endif
+  ImGui_ImplOpenGL3_Init(glsl_version);
+
+  gPlatformValid = true;
+  return true;
+}
+
+void gui::PlatformRenderFrame() {
+  ImGui_ImplOpenGL3_NewFrame();
+
+  CommonRenderFrame();
+
+  int display_w, display_h;
+  glfwGetFramebufferSize(gContext->window, &display_w, &display_h);
+  glViewport(0, 0, display_w, display_h);
+  glClearColor(gContext->clearColor.x, gContext->clearColor.y,
+               gContext->clearColor.z, gContext->clearColor.w);
+  glClear(GL_COLOR_BUFFER_BIT);
+  ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
+
+  glfwSwapBuffers(gContext->window);
+}
+
+void gui::PlatformShutdown() {
+  gPlatformValid = false;
+  ImGui_ImplOpenGL3_Shutdown();
+}
+
+void gui::PlatformFramebufferSizeChanged(int width, int height) {}
+
+static inline GLenum GLPixelFormat(PixelFormat format) {
+  switch (format) {
+    case kPixelRGBA:
+      return GL_RGBA;
+    case kPixelBGRA:
+      return GL_BGRA;
+    default:
+      return GL_RGBA;
+  }
+}
+
+ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
+                               const unsigned char* data) {
+  if (!gPlatformValid) return nullptr;
+
+  // Create a OpenGL texture identifier
+  GLuint texture;
+  glGenTextures(1, &texture);
+  glBindTexture(GL_TEXTURE_2D, texture);
+
+  // Setup filtering parameters for display
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+  // Upload pixels into texture
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
+               GLPixelFormat(format), GL_UNSIGNED_BYTE, data);
+
+  return reinterpret_cast<ImTextureID>(static_cast<uintptr_t>(texture));
+}
+
+void gui::UpdateTexture(ImTextureID texture, PixelFormat format, int width,
+                        int height, const unsigned char* data) {
+  GLuint glTexture = static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture));
+  if (glTexture == 0) return;
+  glBindTexture(GL_TEXTURE_2D, glTexture);
+  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GLPixelFormat(format),
+                  GL_UNSIGNED_BYTE, data);
+}
+
+void gui::DeleteTexture(ImTextureID texture) {
+  if (!gPlatformValid) return;
+  GLuint glTexture = static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture));
+  if (glTexture != 0) glDeleteTextures(1, &glTexture);
+}
+
+}  // namespace wpi
