--- src/window.cc.orig	2026-04-27 01:15:10.069762362 +0000
+++ src/window.cc	2026-04-27 01:49:14.276360555 +0000
@@ -2,8 +2,13 @@
 #include "terminal.h"
 #include "keys.h"
 
-#include <gl/GrGLInterface.h>
-#include <gl/GrGLUtil.h>
+#include <include/gpu/ganesh/gl/GrGLInterface.h>
+#include <include/gpu/ganesh/gl/GrGLDirectContext.h>
+#include <include/gpu/ganesh/gl/GrGLBackendSurface.h>
+#include <include/gpu/ganesh/SkSurfaceGanesh.h>
+#include <include/core/SkSurface.h>
+
+#include <epoxy/gl.h>
 
 #include <absl/memory/memory.h>
 
@@ -15,11 +20,12 @@
   m_surface.reset();
   m_target.reset();
   m_context.reset();
-  m_interface.reset();
   m_gl.reset();
 
-  glfwSetCursor(m_window, nullptr);
-  glfwDestroyCursor(m_cursor);
+  if (m_cursor != nullptr) {
+    glfwSetCursor(m_window, nullptr);
+    glfwDestroyCursor(m_cursor);
+  }
   glfwTerminate();
 }
 
@@ -28,6 +34,7 @@
 void Window::set_resize_cb(ResizeCb resize_cb) { m_resize_cb = resize_cb; }
 void Window::set_selection_cb(SelectionCb selection_cb) { m_selection_cb = selection_cb; }
 void Window::set_scroll_cb(ScrollCb scroll_cb) { m_scroll_cb = scroll_cb; }
+void Window::set_drop_cb(DropCb drop_cb) { m_drop_cb = drop_cb; }
 
 bool Window::isopen() {
   assert(m_window);
@@ -37,6 +44,7 @@
 Error Window::Initialize(int width, int height, bool hwaccel, int vsync, const Theme& theme) {
   m_hwaccel = hwaccel;
   m_theme = &theme;
+  m_cursor = nullptr;
 
   glfwSetErrorCallback([](int ec, const char *err) {
     fmt::print("GLFW error: {}\n", err);
@@ -45,23 +53,60 @@
   if (!glfwInit())
     return Error::New("failed to initialize GLFW");
 
-  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, kGLMajor);
-  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, kGLMinor);
-  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-
-  glfwWindowHint(GLFW_RED_BITS, 8);
-  glfwWindowHint(GLFW_GREEN_BITS, 8);
-  glfwWindowHint(GLFW_BLUE_BITS, 8);
-  glfwWindowHint(GLFW_ALPHA_BITS, 8);
-  glfwWindowHint(GLFW_DEPTH_BITS, 0);
-  glfwWindowHint(GLFW_STENCIL_BITS, kStencilBits);
-  glfwWindowHint(GLFW_DOUBLEBUFFER, 1);
-  glfwWindowHint(GLFW_SAMPLES, kPreferredSamples);
-  #ifdef GLFW_TRANSPARENT_FRAMEBUFFER
-  glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1);
-  #endif
+  // Try multiple GL configurations in order of preference
+  struct GLConfig {
+    int major, minor;
+    int profile;  // GLFW_OPENGL_CORE_PROFILE or GLFW_OPENGL_ANY_PROFILE
+    int stencil;
+    bool forward_compat;
+  };
+
+  GLConfig configs[] = {
+#if !defined(__ppc__) && !defined(__ppc64__)
+    // Modern systems: try GL 3.3 Core first
+    {3, 3, GLFW_OPENGL_CORE_PROFILE, 8, true},
+    {3, 2, GLFW_OPENGL_CORE_PROFILE, 8, true},
+#endif
+    // Compatibility/Legacy fallbacks
+    {2, 1, GLFW_OPENGL_ANY_PROFILE, 8, false},
+    {2, 0, GLFW_OPENGL_ANY_PROFILE, 8, false},
+    // Reduced stencil for very old systems
+    {2, 1, GLFW_OPENGL_ANY_PROFILE, 0, false},
+    {2, 0, GLFW_OPENGL_ANY_PROFILE, 0, false},
+  };
+
+  int actual_stencil = kStencilBits;
+
+  for (const auto& cfg : configs) {
+    glfwDefaultWindowHints();
+    
+    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, cfg.major);
+    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, cfg.minor);
+    
+    if (cfg.profile == GLFW_OPENGL_CORE_PROFILE) {
+      glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+      if (cfg.forward_compat) {
+        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
+      }
+    }
+    
+    glfwWindowHint(GLFW_RED_BITS, 8);
+    glfwWindowHint(GLFW_GREEN_BITS, 8);
+    glfwWindowHint(GLFW_BLUE_BITS, 8);
+    glfwWindowHint(GLFW_ALPHA_BITS, 8);
+    glfwWindowHint(GLFW_DEPTH_BITS, 0);
+    glfwWindowHint(GLFW_STENCIL_BITS, cfg.stencil);
+    glfwWindowHint(GLFW_DOUBLEBUFFER, 1);
+    glfwWindowHint(GLFW_SAMPLES, 0);
+    
+    m_window = glfwCreateWindow(width, height, "uterm", nullptr, nullptr);
+    if (m_window != nullptr) {
+      actual_stencil = cfg.stencil;
+      fmt::print("Created GL {}.{} context (stencil={})\n", cfg.major, cfg.minor, cfg.stencil);
+      break;
+    }
+  }
 
-  m_window = glfwCreateWindow(width, height, "uterm", nullptr, nullptr);
   if (m_window == nullptr)
     return Error::New("failed to create window via GLFW");
 
@@ -76,9 +121,14 @@
   glfwSetFramebufferSizeCallback(m_window, StaticFbResizeCallback);
   glfwSetMouseButtonCallback(m_window, StaticMouseCallback);
   glfwSetScrollCallback(m_window, StaticScrollCallback);
+  glfwSetDropCallback(m_window, StaticDropCallback);
 
+#if !defined(__ppc__) && !defined(__ppc64__)
   m_cursor = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
-  glfwSetCursor(m_window, m_cursor);
+  if (m_cursor != nullptr) {
+    glfwSetCursor(m_window, m_cursor);
+  }
+#endif
 
   glfwGetFramebufferSize(m_window, &m_fb_width, &m_fb_height);
 
@@ -88,16 +138,15 @@
     glClearStencil(0);
     glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 
-    m_interface = GrGLMakeNativeInterface();
-    m_context = GrContext::MakeGL(m_interface);
+    m_context = GrDirectContexts::MakeGL();
     if (m_context == nullptr)
-      return Error::New("failed to create GrContext");
+      return Error::New("failed to create GrDirectContext");
 
-    GrGLint buffer;
-    GR_GL_GetIntegerv(m_interface.get(), GR_GL_FRAMEBUFFER_BINDING, &buffer);
+    GLint buffer;
+    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &buffer);
     m_info.fFBOID = static_cast<GrGLuint>(buffer);
-    // XXX
-    m_info.fFormat = GR_GL_RGBA8;
+    m_info.fFormat = GL_RGBA8;
+    m_stencil_bits = actual_stencil;
   } else {
     if (auto err = m_gl->Initialize(m_fb_width, m_fb_height)) {
       return err;
@@ -127,16 +176,16 @@
 void Window::DrawAndPoll(bool significant_redraw) {
   if (significant_redraw && !m_hwaccel) {
     SkPixmap pixmap;
-    canvas()->flush();
     canvas()->peekPixels(&pixmap);
 
     m_gl->UpdateTextureData(pixmap.addr());
   }
 
-  if (m_hwaccel)
-    canvas()->flush();
-  else
+  if (m_hwaccel) {
+    m_context->flushAndSubmit();
+  } else {
     m_gl->Draw();
+  }
   glfwSwapBuffers(m_window);
 
   if (m_hwaccel)
@@ -168,18 +217,19 @@
     m_surface.reset();
 
     int samples = m_context->maxSurfaceSampleCountForColorType(colortype);
-    m_target = absl::make_unique<GrBackendRenderTarget>(m_fb_width, m_fb_height, samples,
-                                                        kStencilBits, m_info);
-
-    SkSurfaceProps props{SkSurfaceProps::kLegacyFontHost_InitType};
-    m_surface = SkSurface::MakeFromBackendRenderTarget(m_context.get(), *m_target,
-                                                       kBottomLeft_GrSurfaceOrigin,
-                                                       kRGBA_8888_SkColorType, nullptr,
-                                                       &props);
+    m_target = absl::make_unique<GrBackendRenderTarget>(
+        GrBackendRenderTargets::MakeGL(m_fb_width, m_fb_height, samples,
+                                       m_stencil_bits, m_info));
+
+    SkSurfaceProps props{};
+    m_surface = SkSurfaces::WrapBackendRenderTarget(m_context.get(), *m_target,
+                                                    kBottomLeft_GrSurfaceOrigin,
+                                                    kRGBA_8888_SkColorType, nullptr,
+                                                    &props);
   } else {
     auto info = SkImageInfo::Make(m_fb_width, m_fb_height, kRGBA_8888_SkColorType,
                                   kPremul_SkAlphaType);
-    m_surface = SkSurface::MakeRaster(info);
+    m_surface = SkSurfaces::Raster(info);
   }
 
   if (m_surface == nullptr) {
@@ -257,3 +307,16 @@
     window->m_scroll_cb(ScrollDirection::kDown, -yoffset);
   }
 }
+
+void Window::StaticDropCallback(GLFWwindow *glfw_window, int count,
+                                const char **paths) {
+  Window *window = static_cast<Window*>(glfwGetWindowUserPointer(glfw_window));
+  if (window->m_drop_cb) {
+    std::vector<string> path_list;
+    path_list.reserve(count);
+    for (int i = 0; i < count; i++) {
+      path_list.emplace_back(paths[i]);
+    }
+    window->m_drop_cb(path_list);
+  }
+}
