FLTK logo

[master] c96a4f3 - macOS platform: rename Fl_Cocoa_Gl_Window_Driver.cxx to .mm

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] c96a4f3 - macOS platform: rename Fl_Cocoa_Gl_Window_Driver.cxx to .mm "ManoloFLTK" Sep 29, 2022  
 
commit c96a4f3141259d412b249144086492ec4c400355
Author:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Thu Sep 29 16:25:14 2022 +0200
Commit:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
CommitDate: Thu Sep 29 16:25:14 2022 +0200

    macOS platform: rename Fl_Cocoa_Gl_Window_Driver.cxx to .mm

 src/CMakeLists.txt                              |   2 +-
 src/Fl_cocoa.mm                                 | 181 ---------
 src/Makefile                                    |   4 +-
 src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H   |   1 -
 src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx | 380 -----------------
 src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm  | 518 ++++++++++++++++++++++++
 src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H      |  15 -
 7 files changed, 521 insertions(+), 580 deletions(-)

diff --git src/CMakeLists.txt src/CMakeLists.txt
index 91d4f5f..ab5188e 100644
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
@@ -440,7 +440,7 @@ elseif (FLTK_USE_X11)
   set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/X11/Fl_X11_Gl_Window_Driver.cxx drivers/X11/fl_X11_gl_platform_init.cxx)
   set (GL_DRIVER_HEADER_FILES drivers/X11/Fl_X11_Gl_Window_Driver.H)
 elseif (APPLE)
-  set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx drivers/Cocoa/fl_macOS_gl_platform_init.cxx)
+  set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm drivers/Cocoa/fl_macOS_gl_platform_init.cxx)
   set (GL_DRIVER_HEADER_FILES drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H)
 elseif (WIN32)
   set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx drivers/WinAPI/fl_WinAPI_gl_platform_init.cxx)
diff --git src/Fl_cocoa.mm src/Fl_cocoa.mm
index ccb4ebe..694e54a 100644
--- src/Fl_cocoa.mm
+++ src/Fl_cocoa.mm
@@ -2831,184 +2831,6 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
 @end
 
 
-NSOpenGLPixelFormat* Fl_Cocoa_Window_Driver::mode_to_NSOpenGLPixelFormat(int m, const int *alistp)
-{
-  NSOpenGLPixelFormatAttribute attribs[32];
-  int n = 0;
-  // AGL-style code remains commented out for comparison
-  if (!alistp) {
-    if (m & FL_INDEX) {
-      //list[n++] = AGL_BUFFER_SIZE; list[n++] = 8;
-    } else {
-      //list[n++] = AGL_RGBA;
-      //list[n++] = AGL_GREEN_SIZE;
-      //list[n++] = (m & FL_RGB8) ? 8 : 1;
-      attribs[n++] = NSOpenGLPFAColorSize;
-      attribs[n++] = (NSOpenGLPixelFormatAttribute)((m & FL_RGB8) ? 32 : 1);
-      if (m & FL_ALPHA) {
-        //list[n++] = AGL_ALPHA_SIZE;
-        attribs[n++] = NSOpenGLPFAAlphaSize;
-        attribs[n++] = (NSOpenGLPixelFormatAttribute)((m & FL_RGB8) ? 8 : 1);
-      }
-      if (m & FL_ACCUM) {
-        //list[n++] = AGL_ACCUM_GREEN_SIZE; list[n++] = 1;
-        attribs[n++] = NSOpenGLPFAAccumSize;
-        attribs[n++] = (NSOpenGLPixelFormatAttribute)1;
-        if (m & FL_ALPHA) {
-          //list[n++] = AGL_ACCUM_ALPHA_SIZE; list[n++] = 1;
-        }
-      }
-    }
-    if (m & FL_DOUBLE) {
-      //list[n++] = AGL_DOUBLEBUFFER;
-      attribs[n++] = NSOpenGLPFADoubleBuffer;
-    }
-    if (m & FL_DEPTH) {
-      //list[n++] = AGL_DEPTH_SIZE; list[n++] = 24;
-      attribs[n++] = NSOpenGLPFADepthSize;
-      attribs[n++] = (NSOpenGLPixelFormatAttribute)24;
-    }
-    if (m & FL_STENCIL) {
-      //list[n++] = AGL_STENCIL_SIZE; list[n++] = 1;
-      attribs[n++] = NSOpenGLPFAStencilSize;
-      attribs[n++] = (NSOpenGLPixelFormatAttribute)1;
-    }
-    if (m & FL_STEREO) {
-      //list[n++] = AGL_STEREO;
-      attribs[n++] = NSOpenGLPFAStereo;
-    }
-    if ((m & FL_MULTISAMPLE) && fl_mac_os_version >= 100400) {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
-      attribs[n++] = NSOpenGLPFAMultisample, // 10.4
-#endif
-      attribs[n++] = NSOpenGLPFASampleBuffers; attribs[n++] = (NSOpenGLPixelFormatAttribute)1;
-      attribs[n++] = NSOpenGLPFASamples; attribs[n++] = (NSOpenGLPixelFormatAttribute)4;
-    }
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
-#define NSOpenGLPFAOpenGLProfile      (NSOpenGLPixelFormatAttribute)99
-#define kCGLPFAOpenGLProfile          NSOpenGLPFAOpenGLProfile
-#define NSOpenGLProfileVersionLegacy  (NSOpenGLPixelFormatAttribute)0x1000
-#define NSOpenGLProfileVersion3_2Core  (NSOpenGLPixelFormatAttribute)0x3200
-#define kCGLOGLPVersion_Legacy        NSOpenGLProfileVersionLegacy
-#endif
-    if (fl_mac_os_version >= 100700) {
-      attribs[n++] = NSOpenGLPFAOpenGLProfile;
-      attribs[n++] =  (m & FL_OPENGL3) ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy;
-    }
-  } else {
-    while (alistp[n] && n < 30) {
-      if (alistp[n] == kCGLPFAOpenGLProfile) {
-        if (fl_mac_os_version < 100700) {
-          if (alistp[n+1] != kCGLOGLPVersion_Legacy) return nil;
-          n += 2;
-          continue;
-        }
-      }
-      attribs[n] = (NSOpenGLPixelFormatAttribute)alistp[n];
-      n++;
-    }
-  }
-  attribs[n] = (NSOpenGLPixelFormatAttribute)0;
-  NSOpenGLPixelFormat *pixform = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
-  /*GLint color,alpha,accum,depth;
-  [pixform getValues:&color forAttribute:NSOpenGLPFAColorSize forVirtualScreen:0];
-  [pixform getValues:&alpha forAttribute:NSOpenGLPFAAlphaSize forVirtualScreen:0];
-  [pixform getValues:&accum forAttribute:NSOpenGLPFAAccumSize forVirtualScreen:0];
-  [pixform getValues:&depth forAttribute:NSOpenGLPFADepthSize forVirtualScreen:0];
-  NSLog(@"color=%d alpha=%d accum=%d depth=%d",color,alpha,accum,depth);*/
-  return pixform;
-}
-
-NSOpenGLContext* Fl_Cocoa_Window_Driver::create_GLcontext_for_window(NSOpenGLPixelFormat *pixelformat,
-                                              NSOpenGLContext *shared_ctx, Fl_Window *window)
-{
-  NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixelformat shareContext:shared_ctx];
-  if (shared_ctx && !context) context = [[NSOpenGLContext alloc] initWithFormat:pixelformat shareContext:nil];
-  if (context) {
-    FLView *view = (FLView*)[fl_xid(window) contentView];
-    if (fl_mac_os_version >= 100700) {
-      //replaces  [view setWantsBestResolutionOpenGLSurface:YES]  without compiler warning
-      typedef void (*bestResolutionIMP)(id, SEL, BOOL);
-      static bestResolutionIMP addr = (bestResolutionIMP)[NSView instanceMethodForSelector:@selector(setWantsBestResolutionOpenGLSurface:)];
-      addr(view, @selector(setWantsBestResolutionOpenGLSurface:), Fl::use_high_res_GL() != 0);
-    }
-    [context setView:view];
-    if (Fl_Cocoa_Window_Driver::driver(window)->subRect()) {
-      remove_gl_context_opacity(context);
-    }
-  }
-  return context;
-}
-
-
-NSOpenGLContext *Fl_Cocoa_Window_Driver::gl1ctxt_create(NSView **gl1view) {
-  FLView *view = (FLView*)[fl_xid(pWindow) contentView];
-  *gl1view = [[NSView alloc] initWithFrame:[view frame]];
-  NSOpenGLPixelFormat *gl1pixelformat =
-      Fl_Cocoa_Window_Driver::mode_to_NSOpenGLPixelFormat(
-                              FL_RGB8 | FL_ALPHA | FL_SINGLE, NULL);
-  NSOpenGLContext *gl1ctxt = [[NSOpenGLContext alloc]
-                              initWithFormat:gl1pixelformat shareContext:nil];
-  [gl1pixelformat release];
-  return gl1ctxt;
-}
-
-void Fl_Cocoa_Window_Driver::gl1ctxt_add(NSOpenGLContext *gl1ctxt, NSView *gl1view) {
-  FLView *flview = (FLView*)[fl_xid(pWindow) contentView];
-  [flview addSubview:gl1view];
-  [gl1view release];
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_7
-  if (fl_mac_os_version >= 100700 && Fl::use_high_res_GL()) {
-    [gl1view setWantsBestResolutionOpenGLSurface:YES];
-  }
-#endif
-  [gl1ctxt setView:gl1view];
-  remove_gl_context_opacity(gl1ctxt);
-}
-
-
-void Fl_Cocoa_Window_Driver::gl1ctxt_resize(NSOpenGLContext *ctxt) {
-  [[ctxt view] setFrame:[[[ctxt view] superview] frame]];
-}
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_12_0
-#  define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
-#endif
-
-void Fl_Cocoa_Window_Driver::remove_gl_context_opacity(NSOpenGLContext *ctx) {
-  GLint gl_opacity;
-  [ctx getValues:&gl_opacity forParameter:NSOpenGLContextParameterSurfaceOpacity];
-  if (gl_opacity != 0) {
-    gl_opacity = 0;
-    [ctx setValues:&gl_opacity forParameter:NSOpenGLContextParameterSurfaceOpacity];
-  }
-}
-
-void Fl_Cocoa_Window_Driver::GLcontext_update(NSOpenGLContext* ctxt)
-{
-  [ctxt update];
-}
-
-void Fl_Cocoa_Window_Driver::flush_context(NSOpenGLContext* ctxt)
-{
-  [ctxt flushBuffer];
-}
-
-void Fl_Cocoa_Window_Driver::GLcontext_release(NSOpenGLContext* ctxt)
-{
-  [ctxt release];
-}
-
-void Fl_Cocoa_Window_Driver::GL_cleardrawable(void)
-{
-  [[NSOpenGLContext currentContext] clearDrawable];
-}
-
-void Fl_Cocoa_Window_Driver::GLcontext_makecurrent(NSOpenGLContext* ctxt)
-{
-  [ctxt makeCurrentContext];
-}
-
 /*
  * Initialize the given port for redraw and call the window's flush() to actually draw the content
  */
@@ -4561,9 +4383,6 @@ void Fl_Cocoa_Window_Driver::draw_titlebar_to_context(CGContextRef gc, int w, in
   }
 }
 
-void Fl_Cocoa_Window_Driver::gl_start(NSOpenGLContext *ctxt) {
-  [ctxt update]; // supports window resizing
-}
 
 /* Returns the version of the running Mac OS as an int such as 100802 for 10.8.2,
  and also assigns that value to global fl_mac_os_version.
diff --git src/Makefile src/Makefile
index 0510cbb..1271f7c 100644
--- src/Makefile
+++ src/Makefile
@@ -202,7 +202,7 @@ GLCPPFILES = \
 	drivers/OpenGL/Fl_OpenGL_Graphics_Driver_rect.cxx \
 	drivers/OpenGL/Fl_OpenGL_Graphics_Driver_vertex.cxx
 
-GLCPPFILES_OSX = drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx \
+GLCPPFILES_OSX = drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm \
 		 drivers/Cocoa/fl_macOS_gl_platform_init.cxx
 GLCPPFILES_X11 = drivers/X11/Fl_X11_Gl_Window_Driver.cxx \
 		 drivers/X11/fl_X11_gl_platform_init.cxx
@@ -427,7 +427,7 @@ CXXFLAGS += $(EXTRA_CXXFLAGS_$(BUILD))
 
 OBJECTS =  $(MMFILES:.mm=.o) $(CPPFILES:.cxx=.o) $(CFILES:.c=.o) $(UTF8CFILES:.c=.o)
 OBJECTS += $(EXTRA_OBJECTS_$(BUILD))
-GLOBJECTS = $(GLCPPFILES:.cxx=.o)
+GLOBJECTS = $(GLCPPFILES:.cxx=.o) $(GLCPPFILES:.mm=.o)
 FLOBJECTS = $(FLCPPFILES:.cxx=.o)
 IMGOBJECTS = $(IMGCPPFILES:.cxx=.o)
 
diff --git src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H
index f0456ee..01ab231 100644
--- src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H
+++ src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H
@@ -28,7 +28,6 @@ class Fl_Gl_Choice;
 
 class Fl_Cocoa_Gl_Window_Driver : public Fl_Gl_Window_Driver {
   NSOpenGLContext *gl1ctxt; // GL1 context in addition to GL3 context
-  static void delayed_addgl1ctxt(void *data);
   friend Fl_Gl_Window_Driver* Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *);
   Fl_Cocoa_Gl_Window_Driver(Fl_Gl_Window *win);
   virtual float pixels_per_unit();
diff --git src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx
deleted file mode 100644
index 3ee281b..0000000
--- src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx
+++ /dev/null
@@ -1,380 +0,0 @@
-//
-// Class Fl_Cocoa_Gl_Window_Driver for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2021-2022 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file.  If this
-// file is missing or damaged, see the license at:
-//
-//     https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-//     https://www.fltk.org/bugs.php
-//
-
-#include <config.h>
-#if HAVE_GL
-#include <FL/platform.H>
-#include <FL/gl.h>
-#include "../../Fl_Gl_Choice.H"
-#include "../../Fl_Screen_Driver.H"
-#include "Fl_Cocoa_Window_Driver.H"
-#include "Fl_Cocoa_Gl_Window_Driver.H"
-#include <FL/Fl_Graphics_Driver.H>
-#include <OpenGL/OpenGL.h>
-#include <FL/Fl_Image_Surface.H>
-#include <dlfcn.h>
-
-
-#ifdef __OBJC__
-@class NSOpenGLPixelFormat;
-#else
-class NSOpenGLPixelFormat;
-#endif // __OBJC__
-
-
-// Describes crap needed to create a GLContext.
-class Fl_Cocoa_Gl_Choice : public Fl_Gl_Choice {
-  friend class Fl_Cocoa_Gl_Window_Driver;
-private:
-  NSOpenGLPixelFormat* pixelformat;
-public:
-  Fl_Cocoa_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : Fl_Gl_Choice(m, alistp, n) {
-    pixelformat = NULL;
-  }
-};
-
-
-Fl_Cocoa_Gl_Window_Driver::Fl_Cocoa_Gl_Window_Driver(Fl_Gl_Window *win) :
-                              Fl_Gl_Window_Driver(win) {
-  gl1ctxt = NULL;
-}
-
-Fl_Gl_Choice *Fl_Cocoa_Gl_Window_Driver::find(int m, const int *alistp)
-{
-  Fl::screen_driver()->open_display(); // useful when called through gl_start()
-  Fl_Cocoa_Gl_Choice *g = (Fl_Cocoa_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(m, alistp);
-  if (g) return g;
-  NSOpenGLPixelFormat* fmt = Fl_Cocoa_Window_Driver::mode_to_NSOpenGLPixelFormat(m, alistp);
-  if (!fmt) return 0;
-  g = new Fl_Cocoa_Gl_Choice(m, alistp, first);
-  first = g;
-  g->pixelformat = fmt;
-  return g;
-}
-
-GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
-  GLContext context, shared_ctx = 0;
-  if (context_list && nContext) shared_ctx = context_list[0];
-  // resets the pile of string textures used to draw strings
-  // necessary before the first context is created
-  if (!shared_ctx) gl_texture_reset();
-  context = Fl_Cocoa_Window_Driver::create_GLcontext_for_window(((Fl_Cocoa_Gl_Choice*)g)->pixelformat, (NSOpenGLContext*)shared_ctx, window);
-  if (!context) return 0;
-  add_context(context);
-  Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)context);
-  glClearColor(0., 0., 0., 1.);
-  apply_scissor();
-  return (context);
-}
-
-void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
-  if (context != cached_context || w != cached_window) {
-    cached_context = context;
-    cached_window = w;
-    Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)context);
-  }
-}
-
-void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) {
-  if (cached_context == context) {
-    cached_context = 0;
-    cached_window = 0;
-    Fl_Cocoa_Window_Driver::GL_cleardrawable();
-  }
-  Fl_Cocoa_Window_Driver::GLcontext_release((NSOpenGLContext*)context);
-  del_context(context);
-}
-
-void Fl_Cocoa_Gl_Window_Driver::make_overlay_current() {
-  // this is not very useful, but unfortunately, Apple decided
-  // that front buffer drawing can no longer (OS X 10.4) be supported on their platforms.
-  pWindow->make_current();
-}
-
-void Fl_Cocoa_Gl_Window_Driver::redraw_overlay() {
-  pWindow->redraw();
-}
-
-void Fl_Cocoa_Gl_Window_Driver::before_show(int& need_after) {
-  need_after = 1;
-}
-
-void Fl_Cocoa_Gl_Window_Driver::after_show() {
-  // Makes sure the GL context is created to avoid drawing twice the window when first shown
-  pWindow->make_current();
-}
-
-float Fl_Cocoa_Gl_Window_Driver::pixels_per_unit()
-{
-  int retina = (fl_mac_os_version >= 100700 && Fl::use_high_res_GL() && Fl_X::i(pWindow) &&
-          Fl_Cocoa_Window_Driver::driver(pWindow)->mapped_to_retina()) ? 2 : 1;
-  return retina * Fl_Graphics_Driver::default_driver().scale();
-}
-
-int Fl_Cocoa_Gl_Window_Driver::mode_(int m, const int *a) {
-  if (a) { // when the mode is set using the a array of system-dependent values, and if asking for double buffer,
-    // the FL_DOUBLE flag must be set in the mode_ member variable
-    const int *aa = a;
-    while (*aa) {
-      if (*(aa++) ==
-          kCGLPFADoubleBuffer
-          ) { m |= FL_DOUBLE; break; }
-    }
-  }
-  pWindow->context(0);
-  mode( m); alist(a);
-  if (pWindow->shown()) {
-    g( find(m, a) );
-    pWindow->redraw();
-  } else {
-    g(0);
-  }
-  return 1;
-}
-
-void Fl_Cocoa_Gl_Window_Driver::make_current_before() {
-  // detect if the window was moved between low and high resolution displays
-  Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(pWindow);
-  if (d->changed_resolution()){
-    d->changed_resolution(false);
-    pWindow->invalidate();
-    Fl_Cocoa_Window_Driver::GLcontext_update((NSOpenGLContext*)pWindow->context());
-  }
-}
-
-void Fl_Cocoa_Gl_Window_Driver::swap_buffers() {
-  if (overlay() != NULL) {
-    // STR# 2944 [1]
-    //    Save matrixmode/proj/modelview/rasterpos before doing overlay.
-    //
-    int wo = pWindow->pixel_w(), ho = pWindow->pixel_h();
-    GLint matrixmode;
-    GLfloat pos[4];
-    glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
-    glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);       // save original glRasterPos
-    glMatrixMode(GL_PROJECTION);                        // save proj/model matrices
-    glPushMatrix();
-    glLoadIdentity();
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadIdentity();
-    glScalef(2.0f/wo, 2.0f/ho, 1.0f);
-    glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f);         // set transform so 0,0 is bottom/left of Gl_Window
-    glRasterPos2i(0,0);                             // set glRasterPos to bottom left corner
-    {
-      // Emulate overlay by doing copypixels
-      glReadBuffer(GL_BACK);
-      glDrawBuffer(GL_FRONT);
-      glCopyPixels(0, 0, wo, ho, GL_COLOR);         // copy GL_BACK to GL_FRONT
-    }
-    glPopMatrix(); // GL_MODELVIEW                  // restore model/proj matrices
-    glMatrixMode(GL_PROJECTION);
-    glPopMatrix();
-    glMatrixMode(matrixmode);
-    glRasterPos3f(pos[0], pos[1], pos[2]);              // restore original glRasterPos
-  }
-   else
-     Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)pWindow->context());//aglSwapBuffers((AGLContext)context_);
-}
-
-char Fl_Cocoa_Gl_Window_Driver::swap_type() {return copy;}
-
-static void delayed_redraw(Fl_Gl_Window *win) {
-  win->redraw();
-}
-
-void Fl_Cocoa_Gl_Window_Driver::resize(int is_a_resize, int w, int h) {
-  if (pWindow->shown()) apply_scissor();
-  Fl_Cocoa_Window_Driver::GLcontext_update((NSOpenGLContext*)pWindow->context());
-  if (gl1ctxt) {
-    Fl_Cocoa_Window_Driver::gl1ctxt_resize(gl1ctxt);
-    Fl_Cocoa_Window_Driver::GLcontext_update(gl1ctxt);
-    Fl::add_timeout(0.01, (Fl_Timeout_Handler)delayed_redraw, pWindow);
-  }
-}
-
-void Fl_Cocoa_Gl_Window_Driver::apply_scissor() {
-  CGRect *extents = Fl_Cocoa_Window_Driver::driver(pWindow)->subRect();
-  if (extents) {
-    Fl_Cocoa_Window_Driver::remove_gl_context_opacity((NSOpenGLContext*)pWindow->context());
-    glDisable(GL_SCISSOR_TEST);
-    GLdouble vals[4];
-    glGetDoublev(GL_COLOR_CLEAR_VALUE, vals);
-    glClearColor(0., 0., 0., 0.);
-    glClear(GL_COLOR_BUFFER_BIT);
-    glClearColor(vals[0], vals[1], vals[2], vals[3]);
-    float s = pWindow->pixels_per_unit();
-    glScissor(s*extents->origin.x, s*extents->origin.y, s*extents->size.width, s*extents->size.height);
-//printf("apply_scissor %dx%d %dx%d\n",extents->x, extents->y, extents->width, extents->height);
-    glEnable(GL_SCISSOR_TEST);
-  }
-}
-
-
-/* Some old Apple hardware doesn't implement the GL_EXT_texture_rectangle extension.
- For it, draw_string_legacy_glut() is used to draw text. */
-
-char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs)
-{
-  // write str to a bitmap just big enough
-  Fl_Image_Surface *surf = new Fl_Image_Surface(w, h);
-  Fl_Font f=fl_font();
-  Fl_Surface_Device::push_current(surf);
-  fl_color(FL_WHITE);
-  fl_font(f, fs);
-  fl_draw(str, n, 0, fl_height() - fl_descent());
-  // get the alpha channel only of the bitmap
-  char *alpha_buf = new char[w*h], *r = alpha_buf, *q;
-  q = (char*)CGBitmapContextGetData((CGContextRef)surf->offscreen());
-  for (int i = 0; i < h; i++) {
-    for (int j = 0; j < w; j++) {
-      *r++ = *(q+3);
-      q += 4;
-    }
-  }
-  Fl_Surface_Device::pop_current();
-  delete surf;
-  return alpha_buf;
-}
-
-void Fl_Cocoa_Gl_Window_Driver::gl_start() {
-  Fl_Cocoa_Window_Driver::gl_start((NSOpenGLContext*)gl_start_context);
-}
-
-// convert BGRA to RGB and also exchange top and bottom
-static uchar *convert_BGRA_to_RGB(uchar *baseAddress, int w, int h, int mByteWidth)
-{
-  uchar *newimg = new uchar[3*w*h];
-  uchar *to = newimg;
-  for (int i = h-1; i >= 0; i--) {
-    uchar *from = baseAddress + i * mByteWidth;
-    for (int j = 0; j < w; j++, from += 4) {
-#if defined(__ppc__) && __ppc__
-      memcpy(to, from + 1, 3);
-      to += 3;
-#else
-      *(to++) = *(from+2);
-      *(to++) = *(from+1);
-      *(to++) = *from;
-#endif
-    }
-  }
-  delete[] baseAddress;
-  return newimg;
-}
-
-Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int w, int h)
-{
-  Fl_Gl_Window* glw = pWindow;
-  float factor = glw->pixels_per_unit();
-  if (factor != 1) {
-    w *= factor; h *= factor; x *= factor; y *= factor;
-  }
-  Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)glw->context());
-  Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)glw->context()); // to capture also the overlay and for directGL demo
-  // Read OpenGL context pixels directly.
-  // For extra safety, save & restore OpenGL states that are changed
-  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
-  glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
-  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
-  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
-  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
-  // Read a block of pixels from the frame buffer
-  int mByteWidth = w * 4;
-  mByteWidth = (mByteWidth + 3) & ~3;    // Align to 4 bytes
-  uchar *baseAddress = new uchar[mByteWidth * h];
-  glReadPixels(x, glw->pixel_h() - (y+h), w, h,
-               GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, baseAddress);
-  glPopClientAttrib();
-  baseAddress = convert_BGRA_to_RGB(baseAddress, w, h, mByteWidth);
-  Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, 3 * w);
-  img->alloc_array = 1;
-  Fl_Cocoa_Window_Driver::flush_context((NSOpenGLContext*)glw->context());
-  return img;
-}
-
-
-void* Fl_Cocoa_Gl_Window_Driver::GetProcAddress(const char *procName) {
-  return dlsym(RTLD_DEFAULT, procName);
-}
-
-
-FL_EXPORT NSOpenGLContext *fl_mac_glcontext(GLContext rc) {
-  return (NSOpenGLContext*)rc;
-}
-
-
-/* macOS offers only core contexts when using GL3. This forbids to draw
- FLTK widgets in a GL3-using NSOpenGLContext because these widgets are drawn
- with the GL1-based Fl_OpenGL_Graphics_Driver. The solution implemented here
- is to create an additional NSView and an associated additional NSOpenGLContext
- placed above and sized as the GL3-based window, to set the new NSOpenGLContext
- non opaque and GL1-based, and to draw the FLTK widgets in the new
- view/GL context.
- */
-
-static struct win_view {
-  Fl_Gl_Window *win;
-  NSView *gl1view;
-  NSOpenGLContext *gl1ctxt;
-} win_view_struct;
-
-void Fl_Cocoa_Gl_Window_Driver::delayed_addgl1ctxt(void *d) {
-  struct win_view *data = (struct win_view *)d;
-  Fl_Cocoa_Window_Driver::driver(data->win)->gl1ctxt_add(data->gl1ctxt, data->gl1view);
-  data->win->redraw();
-}
-
-void Fl_Cocoa_Gl_Window_Driver::switch_to_GL1() {
-  if (!gl1ctxt) {
-    gl1ctxt = Fl_Cocoa_Window_Driver::driver(pWindow)->gl1ctxt_create(
-                &win_view_struct.gl1view);
-    win_view_struct.win = pWindow;
-    win_view_struct.gl1ctxt = gl1ctxt;
-    Fl::add_timeout(0.01,
-            Fl_Cocoa_Gl_Window_Driver::delayed_addgl1ctxt,
-            &win_view_struct);
-  }
-  Fl_Cocoa_Window_Driver::GLcontext_makecurrent(gl1ctxt);
-  glClearColor(0., 0., 0., 0.);
-  glClear(GL_COLOR_BUFFER_BIT);
-}
-
-void Fl_Cocoa_Gl_Window_Driver::switch_back() {
-  glFlush();
-  Fl_Cocoa_Window_Driver::GLcontext_makecurrent((NSOpenGLContext*)pWindow->context());
-}
-
-void Fl_Cocoa_Gl_Window_Driver::gl_hide_before(void *&) {
-  if (gl1ctxt) {
-  	Fl_Cocoa_Window_Driver::GLcontext_release(gl1ctxt);
-    gl1ctxt = 0;
-  }
-}
-
-
-class Fl_Gl_Cocoa_Plugin : public Fl_Cocoa_Plugin {
-public:
-  Fl_Gl_Cocoa_Plugin() : Fl_Cocoa_Plugin(name()) { }
-  virtual const char *name() { return "gl.cocoa.fltk.org"; }
-  virtual void resize(Fl_Gl_Window *glw, int x, int y, int w, int h) {
-    glw->Fl_Gl_Window::resize(x, y, w, h);
-  }
-};
-
-static Fl_Gl_Cocoa_Plugin Gl_Cocoa_Plugin;
-
-#endif // HAVE_GL
diff --git src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm
new file mode 100644
index 0000000..741ab33
--- /dev/null
+++ src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm
@@ -0,0 +1,518 @@
+//
+// Class Fl_Cocoa_Gl_Window_Driver for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2021-2022 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file.  If this
+// file is missing or damaged, see the license at:
+//
+//     https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+//     https://www.fltk.org/bugs.php
+//
+
+#include <config.h>
+#if HAVE_GL
+#include <FL/platform.H>
+#include <FL/gl.h>
+#include "../../Fl_Gl_Choice.H"
+#include "../../Fl_Screen_Driver.H"
+#include "Fl_Cocoa_Window_Driver.H"
+#include "Fl_Cocoa_Gl_Window_Driver.H"
+#include <FL/Fl_Graphics_Driver.H>
+#include <OpenGL/OpenGL.h>
+#include <FL/Fl_Image_Surface.H>
+#include <dlfcn.h>
+
+#import <Cocoa/Cocoa.h>
+
+// Describes crap needed to create a GLContext.
+class Fl_Cocoa_Gl_Choice : public Fl_Gl_Choice {
+  friend class Fl_Cocoa_Gl_Window_Driver;
+private:
+  NSOpenGLPixelFormat* pixelformat;
+public:
+  Fl_Cocoa_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : Fl_Gl_Choice(m, alistp, n) {
+    pixelformat = NULL;
+  }
+};
+
+
+Fl_Cocoa_Gl_Window_Driver::Fl_Cocoa_Gl_Window_Driver(Fl_Gl_Window *win) :
+                              Fl_Gl_Window_Driver(win) {
+  gl1ctxt = NULL;
+}
+
+
+static NSOpenGLPixelFormat* mode_to_NSOpenGLPixelFormat(int m, const int *alistp)
+{
+  NSOpenGLPixelFormatAttribute attribs[32];
+  int n = 0;
+  // AGL-style code remains commented out for comparison
+  if (!alistp) {
+    if (m & FL_INDEX) {
+      //list[n++] = AGL_BUFFER_SIZE; list[n++] = 8;
+    } else {
+      //list[n++] = AGL_RGBA;
+      //list[n++] = AGL_GREEN_SIZE;
+      //list[n++] = (m & FL_RGB8) ? 8 : 1;
+      attribs[n++] = NSOpenGLPFAColorSize;
+      attribs[n++] = (NSOpenGLPixelFormatAttribute)((m & FL_RGB8) ? 32 : 1);
+      if (m & FL_ALPHA) {
+        //list[n++] = AGL_ALPHA_SIZE;
+        attribs[n++] = NSOpenGLPFAAlphaSize;
+        attribs[n++] = (NSOpenGLPixelFormatAttribute)((m & FL_RGB8) ? 8 : 1);
+      }
+      if (m & FL_ACCUM) {
+        //list[n++] = AGL_ACCUM_GREEN_SIZE; list[n++] = 1;
+        attribs[n++] = NSOpenGLPFAAccumSize;
+        attribs[n++] = (NSOpenGLPixelFormatAttribute)1;
+        if (m & FL_ALPHA) {
+          //list[n++] = AGL_ACCUM_ALPHA_SIZE; list[n++] = 1;
+        }
+      }
+    }
+    if (m & FL_DOUBLE) {
+      //list[n++] = AGL_DOUBLEBUFFER;
+      attribs[n++] = NSOpenGLPFADoubleBuffer;
+    }
+    if (m & FL_DEPTH) {
+      //list[n++] = AGL_DEPTH_SIZE; list[n++] = 24;
+      attribs[n++] = NSOpenGLPFADepthSize;
+      attribs[n++] = (NSOpenGLPixelFormatAttribute)24;
+    }
+    if (m & FL_STENCIL) {
+      //list[n++] = AGL_STENCIL_SIZE; list[n++] = 1;
+      attribs[n++] = NSOpenGLPFAStencilSize;
+      attribs[n++] = (NSOpenGLPixelFormatAttribute)1;
+    }
+    if (m & FL_STEREO) {
+      //list[n++] = AGL_STEREO;
+      attribs[n++] = NSOpenGLPFAStereo;
+    }
+    if ((m & FL_MULTISAMPLE) && fl_mac_os_version >= 100400) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+      attribs[n++] = NSOpenGLPFAMultisample, // 10.4
+#endif
+      attribs[n++] = NSOpenGLPFASampleBuffers; attribs[n++] = (NSOpenGLPixelFormatAttribute)1;
+      attribs[n++] = NSOpenGLPFASamples; attribs[n++] = (NSOpenGLPixelFormatAttribute)4;
+    }
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
+#define NSOpenGLPFAOpenGLProfile      (NSOpenGLPixelFormatAttribute)99
+#define kCGLPFAOpenGLProfile          NSOpenGLPFAOpenGLProfile
+#define NSOpenGLProfileVersionLegacy  (NSOpenGLPixelFormatAttribute)0x1000
+#define NSOpenGLProfileVersion3_2Core  (NSOpenGLPixelFormatAttribute)0x3200
+#define kCGLOGLPVersion_Legacy        NSOpenGLProfileVersionLegacy
+#endif
+    if (fl_mac_os_version >= 100700) {
+      attribs[n++] = NSOpenGLPFAOpenGLProfile;
+      attribs[n++] =  (m & FL_OPENGL3) ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy;
+    }
+  } else {
+    while (alistp[n] && n < 30) {
+      if (alistp[n] == kCGLPFAOpenGLProfile) {
+        if (fl_mac_os_version < 100700) {
+          if (alistp[n+1] != kCGLOGLPVersion_Legacy) return nil;
+          n += 2;
+          continue;
+        }
+      }
+      attribs[n] = (NSOpenGLPixelFormatAttribute)alistp[n];
+      n++;
+    }
+  }
+  attribs[n] = (NSOpenGLPixelFormatAttribute)0;
+  NSOpenGLPixelFormat *pixform = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
+  /*GLint color,alpha,accum,depth;
+  [pixform getValues:&color forAttribute:NSOpenGLPFAColorSize forVirtualScreen:0];
+  [pixform getValues:&alpha forAttribute:NSOpenGLPFAAlphaSize forVirtualScreen:0];
+  [pixform getValues:&accum forAttribute:NSOpenGLPFAAccumSize forVirtualScreen:0];
+  [pixform getValues:&depth forAttribute:NSOpenGLPFADepthSize forVirtualScreen:0];
+  NSLog(@"color=%d alpha=%d accum=%d depth=%d",color,alpha,accum,depth);*/
+  return pixform;
+}
+
+
+Fl_Gl_Choice *Fl_Cocoa_Gl_Window_Driver::find(int m, const int *alistp)
+{
+  Fl::screen_driver()->open_display(); // useful when called through gl_start()
+  Fl_Cocoa_Gl_Choice *g = (Fl_Cocoa_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(m, alistp);
+  if (g) return g;
+  NSOpenGLPixelFormat* fmt = mode_to_NSOpenGLPixelFormat(m, alistp);
+  if (!fmt) return 0;
+  g = new Fl_Cocoa_Gl_Choice(m, alistp, first);
+  first = g;
+  g->pixelformat = fmt;
+  return g;
+}
+
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_VERSION_12_0
+#  define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
+#endif
+
+static void remove_gl_context_opacity(NSOpenGLContext *ctx) {
+  GLint gl_opacity;
+  [ctx getValues:&gl_opacity forParameter:NSOpenGLContextParameterSurfaceOpacity];
+  if (gl_opacity != 0) {
+    gl_opacity = 0;
+    [ctx setValues:&gl_opacity forParameter:NSOpenGLContextParameterSurfaceOpacity];
+  }
+}
+
+
+static NSOpenGLContext *create_GLcontext_for_window(
+                         NSOpenGLPixelFormat *pixelformat,
+                         NSOpenGLContext *shared_ctx, Fl_Window *window)
+{
+  NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixelformat shareContext:shared_ctx];
+  if (shared_ctx && !context) context = [[NSOpenGLContext alloc] initWithFormat:pixelformat shareContext:nil];
+  if (context) {
+    NSView *view = [fl_xid(window) contentView];
+    if (fl_mac_os_version >= 100700) {
+      //replaces  [view setWantsBestResolutionOpenGLSurface:YES]  without compiler warning
+      typedef void (*bestResolutionIMP)(id, SEL, BOOL);
+      static bestResolutionIMP addr = (bestResolutionIMP)[NSView instanceMethodForSelector:@selector(setWantsBestResolutionOpenGLSurface:)];
+      addr(view, @selector(setWantsBestResolutionOpenGLSurface:), Fl::use_high_res_GL() != 0);
+    }
+    [context setView:view];
+    if (Fl_Cocoa_Window_Driver::driver(window)->subRect()) {
+      remove_gl_context_opacity(context);
+    }
+  }
+  return context;
+}
+
+GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
+  GLContext context, shared_ctx = 0;
+  if (context_list && nContext) shared_ctx = context_list[0];
+  // resets the pile of string textures used to draw strings
+  // necessary before the first context is created
+  if (!shared_ctx) gl_texture_reset();
+  context = create_GLcontext_for_window(((Fl_Cocoa_Gl_Choice*)g)->pixelformat, (NSOpenGLContext*)shared_ctx, window);
+  if (!context) return 0;
+  add_context(context);
+  [(NSOpenGLContext*)context makeCurrentContext];
+  glClearColor(0., 0., 0., 1.);
+  apply_scissor();
+  return (context);
+}
+
+void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
+  if (context != cached_context || w != cached_window) {
+    cached_context = context;
+    cached_window = w;
+    [(NSOpenGLContext*)context makeCurrentContext];
+  }
+}
+
+void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) {
+  if (cached_context == context) {
+    cached_context = 0;
+    cached_window = 0;
+    [[NSOpenGLContext currentContext] clearDrawable];
+  }
+  [(NSOpenGLContext*)context release];
+  del_context(context);
+}
+
+void Fl_Cocoa_Gl_Window_Driver::make_overlay_current() {
+  // this is not very useful, but unfortunately, Apple decided
+  // that front buffer drawing can no longer (OS X 10.4) be supported on their platforms.
+  pWindow->make_current();
+}
+
+void Fl_Cocoa_Gl_Window_Driver::redraw_overlay() {
+  pWindow->redraw();
+}
+
+void Fl_Cocoa_Gl_Window_Driver::before_show(int& need_after) {
+  need_after = 1;
+}
+
+void Fl_Cocoa_Gl_Window_Driver::after_show() {
+  // Makes sure the GL context is created to avoid drawing twice the window when first shown
+  pWindow->make_current();
+}
+
+float Fl_Cocoa_Gl_Window_Driver::pixels_per_unit()
+{
+  int retina = (fl_mac_os_version >= 100700 && Fl::use_high_res_GL() && Fl_X::i(pWindow) &&
+          Fl_Cocoa_Window_Driver::driver(pWindow)->mapped_to_retina()) ? 2 : 1;
+  return retina * Fl_Graphics_Driver::default_driver().scale();
+}
+
+int Fl_Cocoa_Gl_Window_Driver::mode_(int m, const int *a) {
+  if (a) { // when the mode is set using the a array of system-dependent values, and if asking for double buffer,
+    // the FL_DOUBLE flag must be set in the mode_ member variable
+    const int *aa = a;
+    while (*aa) {
+      if (*(aa++) ==
+          kCGLPFADoubleBuffer
+          ) { m |= FL_DOUBLE; break; }
+    }
+  }
+  pWindow->context(0);
+  mode( m); alist(a);
+  if (pWindow->shown()) {
+    g( find(m, a) );
+    pWindow->redraw();
+  } else {
+    g(0);
+  }
+  return 1;
+}
+
+void Fl_Cocoa_Gl_Window_Driver::make_current_before() {
+  // detect if the window was moved between low and high resolution displays
+  Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(pWindow);
+  if (d->changed_resolution()){
+    d->changed_resolution(false);
+    pWindow->invalidate();
+    [(NSOpenGLContext*)pWindow->context() update];
+  }
+}
+
+void Fl_Cocoa_Gl_Window_Driver::swap_buffers() {
+  if (overlay() != NULL) {
+    // STR# 2944 [1]
+    //    Save matrixmode/proj/modelview/rasterpos before doing overlay.
+    //
+    int wo = pWindow->pixel_w(), ho = pWindow->pixel_h();
+    GLint matrixmode;
+    GLfloat pos[4];
+    glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
+    glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);       // save original glRasterPos
+    glMatrixMode(GL_PROJECTION);                        // save proj/model matrices
+    glPushMatrix();
+    glLoadIdentity();
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+    glScalef(2.0f/wo, 2.0f/ho, 1.0f);
+    glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f);         // set transform so 0,0 is bottom/left of Gl_Window
+    glRasterPos2i(0,0);                             // set glRasterPos to bottom left corner
+    {
+      // Emulate overlay by doing copypixels
+      glReadBuffer(GL_BACK);
+      glDrawBuffer(GL_FRONT);
+      glCopyPixels(0, 0, wo, ho, GL_COLOR);         // copy GL_BACK to GL_FRONT
+    }
+    glPopMatrix(); // GL_MODELVIEW                  // restore model/proj matrices
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(matrixmode);
+    glRasterPos3f(pos[0], pos[1], pos[2]);              // restore original glRasterPos
+  } else {
+    [(NSOpenGLContext*)pWindow->context() flushBuffer];
+  }
+}
+
+char Fl_Cocoa_Gl_Window_Driver::swap_type() {return copy;}
+
+static void delayed_redraw(Fl_Gl_Window *win) {
+  win->redraw();
+}
+
+void Fl_Cocoa_Gl_Window_Driver::resize(int is_a_resize, int w, int h) {
+  if (pWindow->shown()) apply_scissor();
+  [(NSOpenGLContext*)pWindow->context() update];
+  if (gl1ctxt) {
+    [[gl1ctxt view] setFrame:[[[gl1ctxt view] superview] frame]];
+    [gl1ctxt update];
+    Fl::add_timeout(0.01, (Fl_Timeout_Handler)delayed_redraw, pWindow);
+  }
+}
+
+void Fl_Cocoa_Gl_Window_Driver::apply_scissor() {
+  CGRect *extents = Fl_Cocoa_Window_Driver::driver(pWindow)->subRect();
+  if (extents) {
+    remove_gl_context_opacity((NSOpenGLContext*)pWindow->context());
+    glDisable(GL_SCISSOR_TEST);
+    GLdouble vals[4];
+    glGetDoublev(GL_COLOR_CLEAR_VALUE, vals);
+    glClearColor(0., 0., 0., 0.);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glClearColor(vals[0], vals[1], vals[2], vals[3]);
+    float s = pWindow->pixels_per_unit();
+    glScissor(s*extents->origin.x, s*extents->origin.y, s*extents->size.width, s*extents->size.height);
+//printf("apply_scissor %dx%d %dx%d\n",extents->x, extents->y, extents->width, extents->height);
+    glEnable(GL_SCISSOR_TEST);
+  }
+}
+
+
+/* Some old Apple hardware doesn't implement the GL_EXT_texture_rectangle extension.
+ For it, draw_string_legacy_glut() is used to draw text. */
+
+char *Fl_Cocoa_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs)
+{
+  // write str to a bitmap just big enough
+  Fl_Image_Surface *surf = new Fl_Image_Surface(w, h);
+  Fl_Font f=fl_font();
+  Fl_Surface_Device::push_current(surf);
+  fl_color(FL_WHITE);
+  fl_font(f, fs);
+  fl_draw(str, n, 0, fl_height() - fl_descent());
+  // get the alpha channel only of the bitmap
+  char *alpha_buf = new char[w*h], *r = alpha_buf, *q;
+  q = (char*)CGBitmapContextGetData((CGContextRef)surf->offscreen());
+  for (int i = 0; i < h; i++) {
+    for (int j = 0; j < w; j++) {
+      *r++ = *(q+3);
+      q += 4;
+    }
+  }
+  Fl_Surface_Device::pop_current();
+  delete surf;
+  return alpha_buf;
+}
+
+void Fl_Cocoa_Gl_Window_Driver::gl_start() {
+  [(NSOpenGLContext*)gl_start_context update];
+}
+
+// convert BGRA to RGB and also exchange top and bottom
+static uchar *convert_BGRA_to_RGB(uchar *baseAddress, int w, int h, int mByteWidth)
+{
+  uchar *newimg = new uchar[3*w*h];
+  uchar *to = newimg;
+  for (int i = h-1; i >= 0; i--) {
+    uchar *from = baseAddress + i * mByteWidth;
+    for (int j = 0; j < w; j++, from += 4) {
+#if defined(__ppc__) && __ppc__
+      memcpy(to, from + 1, 3);
+      to += 3;
+#else
+      *(to++) = *(from+2);
+      *(to++) = *(from+1);
+      *(to++) = *from;
+#endif
+    }
+  }
+  delete[] baseAddress;
+  return newimg;
+}
+
+Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int w, int h)
+{
+  Fl_Gl_Window* glw = pWindow;
+  float factor = glw->pixels_per_unit();
+  if (factor != 1) {
+    w *= factor; h *= factor; x *= factor; y *= factor;
+  }
+  [(NSOpenGLContext*)glw->context() makeCurrentContext];
+// to capture also the overlay and for directGL demo
+  [(NSOpenGLContext*)glw->context() flushBuffer];
+  // Read OpenGL context pixels directly.
+  // For extra safety, save & restore OpenGL states that are changed
+  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+  glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
+  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+  // Read a block of pixels from the frame buffer
+  int mByteWidth = w * 4;
+  mByteWidth = (mByteWidth + 3) & ~3;    // Align to 4 bytes
+  uchar *baseAddress = new uchar[mByteWidth * h];
+  glReadPixels(x, glw->pixel_h() - (y+h), w, h,
+               GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, baseAddress);
+  glPopClientAttrib();
+  baseAddress = convert_BGRA_to_RGB(baseAddress, w, h, mByteWidth);
+  Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, 3 * w);
+  img->alloc_array = 1;
+  [(NSOpenGLContext*)glw->context() flushBuffer];
+  return img;
+}
+
+
+void* Fl_Cocoa_Gl_Window_Driver::GetProcAddress(const char *procName) {
+  return dlsym(RTLD_DEFAULT, procName);
+}
+
+
+FL_EXPORT NSOpenGLContext *fl_mac_glcontext(GLContext rc) {
+  return (NSOpenGLContext*)rc;
+}
+
+
+/* macOS offers only core contexts when using GL3. This forbids to draw
+ FLTK widgets in a GL3-using NSOpenGLContext because these widgets are drawn
+ with the GL1-based Fl_OpenGL_Graphics_Driver. The solution implemented here
+ is to create an additional NSView and an associated additional NSOpenGLContext
+ placed above and sized as the GL3-based window, to set the new NSOpenGLContext
+ non opaque and GL1-based, and to draw the FLTK widgets in the new
+ view/GL context.
+ */
+
+static struct win_view {
+  Fl_Gl_Window *win;
+  NSView *gl1view;
+  NSOpenGLContext *gl1ctxt;
+} win_view_struct;
+
+
+static void delayed_addgl1ctxt(struct win_view *data) {
+  NSView *flview = [fl_mac_xid(data->win) contentView];
+  [flview addSubview:data->gl1view];
+  [data->gl1view release];
+#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_7
+  if (fl_mac_os_version >= 100700 && Fl::use_high_res_GL()) {
+    [data->gl1view setWantsBestResolutionOpenGLSurface:YES];
+  }
+#endif
+  [data->gl1ctxt setView:data->gl1view];
+  remove_gl_context_opacity(data->gl1ctxt);
+  data->win->redraw();
+}
+
+
+void Fl_Cocoa_Gl_Window_Driver::switch_to_GL1() {
+  if (!gl1ctxt) {
+    NSView *view = [fl_xid(pWindow) contentView];
+    win_view_struct.gl1view = [[NSView alloc] initWithFrame:[view frame]];
+    NSOpenGLPixelFormat *gl1pixelformat = mode_to_NSOpenGLPixelFormat(
+                                FL_RGB8 | FL_ALPHA | FL_SINGLE, NULL);
+    gl1ctxt = [[NSOpenGLContext alloc]
+                                initWithFormat:gl1pixelformat shareContext:nil];
+    [gl1pixelformat release];
+    win_view_struct.win = pWindow;
+    win_view_struct.gl1ctxt = gl1ctxt;
+    Fl::add_timeout(0.01, (Fl_Timeout_Handler)delayed_addgl1ctxt,
+                    &win_view_struct);
+  }
+  [gl1ctxt makeCurrentContext];
+  glClearColor(0., 0., 0., 0.);
+  glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+void Fl_Cocoa_Gl_Window_Driver::switch_back() {
+  glFlush();
+  [(NSOpenGLContext*)pWindow->context() makeCurrentContext];
+}
+
+
+void Fl_Cocoa_Gl_Window_Driver::gl_hide_before(void *&) {
+  if (gl1ctxt) {
+    [gl1ctxt release];
+    gl1ctxt = 0;
+  }
+}
+
+
+class Fl_Gl_Cocoa_Plugin : public Fl_Cocoa_Plugin {
+public:
+  Fl_Gl_Cocoa_Plugin() : Fl_Cocoa_Plugin(name()) { }
+  virtual const char *name() { return "gl.cocoa.fltk.org"; }
+  virtual void resize(Fl_Gl_Window *glw, int x, int y, int w, int h) {
+    glw->Fl_Gl_Window::resize(x, y, w, h);
+  }
+};
+
+static Fl_Gl_Cocoa_Plugin Gl_Cocoa_Plugin;
+
+#endif // HAVE_GL
diff --git src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
index 16cea4e..520c4c2 100644
--- src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
+++ src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
@@ -146,21 +146,6 @@ public:
   void draw_titlebar_to_context(CGContextRef gc, int w, int h);
   virtual int scroll(int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, void (*draw_area)(void*, int,int,int,int), void* data);
 
-  // these functions are OpenGL-related and use objective-c
-  // they are put here to avoid libfltk_gl dependency in Fl_cocoa.mm
-  static NSOpenGLContext* create_GLcontext_for_window(NSOpenGLPixelFormat *pixelformat, NSOpenGLContext *shared_ctx, Fl_Window *window);
-  static NSOpenGLPixelFormat *mode_to_NSOpenGLPixelFormat(int mode, const int*); // uses Objective-c
-  static void GLcontext_update(NSOpenGLContext*); // uses Objective-c
-  static void GLcontext_release(NSOpenGLContext*); // uses Objective-c
-  static void flush_context(NSOpenGLContext*); // uses Objective-c
-  static void GLcontext_makecurrent(NSOpenGLContext*); // uses Objective-c
-  static void GL_cleardrawable(void); // uses Objective-c
-  static void gl_start(NSOpenGLContext*); // uses Objective-c
-  static void remove_gl_context_opacity(NSOpenGLContext*); // uses Objective-c
-  NSOpenGLContext *gl1ctxt_create(NSView **); // uses Objective-c
-  void gl1ctxt_add(NSOpenGLContext*, NSView*); // uses Objective-c
-  static void gl1ctxt_resize(NSOpenGLContext*); // uses Objective-c
-
   //icons
   virtual void icons(const Fl_RGB_Image *icons[], int count);
   NSImage *icon_image;
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.