--- 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 -#include +#include +#include +#include +#include +#include + +#include #include @@ -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(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(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( + 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(glfwGetWindowUserPointer(glfw_window)); + if (window->m_drop_cb) { + std::vector 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); + } +}