summaryrefslogtreecommitdiff
path: root/src/drivers/Cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/Cocoa')
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H60
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm527
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm439
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm455
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H114
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx434
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H168
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx294
-rw-r--r--src/drivers/Cocoa/Fl_MacOS_Sys_Menu_Bar_Driver.H51
9 files changed, 0 insertions, 2542 deletions
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H
deleted file mode 100644
index d5ba9c21c..000000000
--- a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H
+++ /dev/null
@@ -1,60 +0,0 @@
-//
-// Class Fl_Cocoa_Gl_Window_Driver for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2021 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_Window_Driver.H"
-
-class Fl_Gl_Choice;
-#ifdef __OBJC__
- @class NSOpenGLContext;
-#else
- class NSOpenGLContext;
-#endif
-
-class Fl_Cocoa_Gl_Window_Driver : public Fl_Gl_Window_Driver {
- NSOpenGLContext *gl1ctxt; // GL1 context in addition to GL3 context
- friend Fl_Gl_Window_Driver* Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *);
- Fl_Cocoa_Gl_Window_Driver(Fl_Gl_Window *win);
- float pixels_per_unit() FL_OVERRIDE;
- void before_show(int& need_after) FL_OVERRIDE;
- void after_show() FL_OVERRIDE;
- int mode_(int m, const int *a) FL_OVERRIDE;
- void make_current_before() FL_OVERRIDE;
- void swap_buffers() FL_OVERRIDE;
- void resize(int is_a_resize, int w, int h) FL_OVERRIDE;
- char swap_type() FL_OVERRIDE;
- void swap_interval(int) FL_OVERRIDE;
- int swap_interval() const FL_OVERRIDE;
- Fl_Gl_Choice *find(int m, const int *alistp) FL_OVERRIDE;
- GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g) FL_OVERRIDE;
- void set_gl_context(Fl_Window* w, GLContext context) FL_OVERRIDE;
- void delete_gl_context(GLContext) FL_OVERRIDE;
- void make_overlay_current() FL_OVERRIDE;
- void redraw_overlay() FL_OVERRIDE;
- void gl_start() FL_OVERRIDE;
- char *alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs) FL_OVERRIDE;
- Fl_RGB_Image* capture_gl_rectangle(int x, int y, int w, int h) FL_OVERRIDE;
- bool need_scissor() FL_OVERRIDE { return true; }
- void* GetProcAddress(const char *procName) FL_OVERRIDE;
- void apply_scissor();
- void switch_to_GL1() FL_OVERRIDE;
- void switch_back() FL_OVERRIDE;
-};
-
-
-#endif // HAVE_GL
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm
deleted file mode 100644
index 561aa2ce5..000000000
--- a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm
+++ /dev/null
@@ -1,527 +0,0 @@
-//
-// Class Fl_Cocoa_Gl_Window_Driver for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2021-2026 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>
-
-/* 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
- (gl1ctxt) 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/GL1 context.
- */
-
-// 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_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
-{
- return new Fl_Cocoa_Gl_Window_Driver(w);
-}
-
-
-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_DEPTH32) {
- //list[n++] = AGL_DEPTH_SIZE; list[n++] = 32;
- attribs[n++] = NSOpenGLPFADepthSize;
- attribs[n++] = (NSOpenGLPixelFormatAttribute)32;
- } else 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++] = 6/*NSOpenGLPFAStereo*/;
- }
- if (m & FL_MULTISAMPLE) {
- attribs[n++] = NSOpenGLPFAMultisample; // 10.4
- attribs[n++] = NSOpenGLPFASampleBuffers; attribs[n++] = (NSOpenGLPixelFormatAttribute)1;
- attribs[n++] = NSOpenGLPFASamples; attribs[n++] = (NSOpenGLPixelFormatAttribute)4;
- }
- attribs[n++] = NSOpenGLPFAOpenGLProfile;
- attribs[n++] = (m & FL_OPENGL3) ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy;
- } else {
- while (alistp[n] && n < 30) {
- 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_X_VERSION_10_12
-# 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];
- [view 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) {
- 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) {
- NSOpenGLContext *current_context = [NSOpenGLContext currentContext];
- if (context != current_context || w != cached_window) {
- cached_window = w;
- [(NSOpenGLContext*)context makeCurrentContext];
- }
-}
-
-void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) {
- NSOpenGLContext *current_context = [NSOpenGLContext currentContext];
- if (current_context == context) {
- cached_window = 0;
- [current_context clearDrawable];
- }
- [(NSOpenGLContext*)context release];
- del_context(context);
- if (gl1ctxt) {
- [[gl1ctxt view] release];
- [gl1ctxt release];
- gl1ctxt = 0;
- }
-}
-
-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.
- if (pWindow->shown()) 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();
- if ((mode() & FL_OPENGL3) && !gl1ctxt) {
- // Create transparent GL1 scene above the GL3 scene to hold child widgets and/or text
- NSView *view = [fl_mac_xid(pWindow) contentView];
- NSView *gl1view = [[NSView alloc] initWithFrame:[view frame]];
- [gl1view setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
- static NSOpenGLContext *shared_gl1_ctxt = nil;
- static NSOpenGLPixelFormat *gl1pixelformat = mode_to_NSOpenGLPixelFormat(
- FL_RGB8 | FL_ALPHA | FL_SINGLE, NULL);
- gl1ctxt = [[NSOpenGLContext alloc] initWithFormat:gl1pixelformat shareContext:shared_gl1_ctxt];
- if (!shared_gl1_ctxt) {
- shared_gl1_ctxt = gl1ctxt;
- [shared_gl1_ctxt retain];
- }
- [view addSubview:gl1view];
- if (Fl::use_high_res_GL()) {
- [gl1view setWantsBestResolutionOpenGLSurface:YES];
- }
- [gl1ctxt setView:gl1view];
- remove_gl_context_opacity(gl1ctxt);
- }
-}
-
-float Fl_Cocoa_Gl_Window_Driver::pixels_per_unit()
-{
- int retina = (Fl::use_high_res_GL() && Fl_X::flx(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;}
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
-# define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
-#endif
-
-void Fl_Cocoa_Gl_Window_Driver::swap_interval(int n) {
- GLint interval = (GLint)n;
- NSOpenGLContext* ctx = (NSOpenGLContext*)pWindow->context();
- if (ctx)
- [ctx setValues:&interval forParameter:NSOpenGLContextParameterSwapInterval];
-}
-
-int Fl_Cocoa_Gl_Window_Driver::swap_interval() const {
- GLint interval = (GLint)-1;
- NSOpenGLContext* ctx = (NSOpenGLContext*)pWindow->context();
- if (ctx)
- [ctx getValues:&interval forParameter:NSOpenGLContextParameterSwapInterval];
- return interval;
-}
-
-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 update];
- }
-}
-
-void Fl_Cocoa_Gl_Window_Driver::apply_scissor() {
- if (glIsEnabled(GL_SCISSOR_TEST)) glDisable(GL_SCISSOR_TEST);
- CGRect *extents = Fl_Cocoa_Window_Driver::driver(pWindow)->subRect();
- if (extents) {
- remove_gl_context_opacity((NSOpenGLContext*)pWindow->context());
- 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;
-}
-
-
-static Fl_RGB_Image *cgimage_to_rgb4(CGImageRef img) {
- int w = (int)CGImageGetWidth(img);
- int h = (int)CGImageGetHeight(img);
- CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
- uchar *rgba = new uchar[4 * w * h];
- CGContextRef auxgc = CGBitmapContextCreate(rgba, w, h, 8, 4 * w, cspace,
- kCGImageAlphaPremultipliedLast);
- CGColorSpaceRelease(cspace);
- CGContextDrawImage(auxgc, CGRectMake(0, 0, w, h), img);
- CGContextRelease(auxgc);
- Fl_RGB_Image *rgb = new Fl_RGB_Image(rgba, w, h, 4);
- rgb->alloc_array = 1;
- return rgb;
-}
-
-
-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;
- }
- NSWindow *nswin = (NSWindow*)fl_mac_xid(pWindow);
- CGImageRef img_full = Fl_Cocoa_Window_Driver::capture_decorated_window_10_5(nswin);
- int bt = [nswin frame].size.height - [[nswin contentView] frame].size.height;
- bt *= (factor / Fl_Graphics_Driver::default_driver().scale());
- CGRect cgr = CGRectMake(x, y + bt, w, h); // add vertical offset to bypass titlebar
- CGImageRef cgimg = CGImageCreateWithImageInRect(img_full, cgr); // 10.4
- CGImageRelease(img_full);
- Fl_RGB_Image *rgb = cgimage_to_rgb4(cgimg);
- CGImageRelease(cgimg);
- return rgb;
- [(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;
-}
-
-
-void Fl_Cocoa_Gl_Window_Driver::switch_to_GL1() {
- [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];
-}
-
-
-class Fl_Gl_Cocoa_Plugin : public Fl_Cocoa_Plugin {
-public:
- Fl_Gl_Cocoa_Plugin() : Fl_Cocoa_Plugin(name()) { }
- const char *name() FL_OVERRIDE { return "gl.cocoa.fltk.org"; }
- void resize(Fl_Gl_Window *glw, int x, int y, int w, int h) FL_OVERRIDE {
- glw->Fl_Gl_Window::resize(x, y, w, h);
- }
-};
-
-static Fl_Gl_Cocoa_Plugin Gl_Cocoa_Plugin;
-
-#endif // HAVE_GL
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm b/src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm
deleted file mode 100644
index 9c75c7ff2..000000000
--- a/src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm
+++ /dev/null
@@ -1,439 +0,0 @@
-//
-// Definition of macOS Cocoa Pen/Tablet event driver.
-//
-// Copyright 2025-2026 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 "src/drivers/Base/Fl_Base_Pen_Events.H"
-
-#include <FL/platform.H>
-#include <FL/Fl.H>
-#include <FL/Fl_Window.H>
-#include "../../Fl_Screen_Driver.H"
-
-#import <Cocoa/Cocoa.h>
-
-
-extern Fl_Window *fl_xmousewin;
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
-
-typedef short NSEventSubtype;
-#define NSPointingDeviceTypePen NSPenPointingDevice
-#define NSEventTypeMouseEntered NSMouseEntered
-#define NSEventTypeMouseExited NSMouseExited
-#define NSEventTypeTabletProximity NSTabletProximity
-#define NSEventTypeTabletPoint NSTabletPoint
-#define NSEventSubtypeTabletProximity NSTabletProximityEventSubtype
-#define NSEventSubtypeTabletPoint NSTabletPointEventSubtype
-#define NSEventSubtypeMouseEvent NSMouseEventSubtype
-#define NSEventTypeLeftMouseDown NSLeftMouseDown
-#define NSEventTypeLeftMouseUp NSLeftMouseUp
-#define NSEventTypeLeftMouseDragged NSLeftMouseDragged
-#define NSEventTypeMouseMoved NSMouseMoved
-#define NSEventTypeRightMouseDown NSRightMouseDown
-#define NSEventTypeRightMouseUp NSRightMouseUp
-#define NSEventTypeRightMouseDragged NSRightMouseDragged
-#define NSEventTypeOtherMouseUp NSOtherMouseUp
-#define NSEventTypeOtherMouseDown NSOtherMouseDown
-#define NSEventTypeOtherMouseDragged NSOtherMouseDragged
-#define NSPointingDeviceTypeEraser NSEraserPointingDevice
-
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
-
-static NSPointingDeviceType device_type_ { NSPointingDeviceTypePen };
-
-// The trait list keeps track of traits for every pen ID that appears while
-// handling events.
-// AppKit does not tell us what traits are available per pen or tablet, so
-// we use the first 5 motion events to discover event values that are not
-// the default value, and enter that knowledge into the traits database.
-typedef std::map<int, Fl::Pen::Trait> TraitList;
-static TraitList trait_list_;
-static int trait_countdown_ { 5 };
-static int current_pen_id_ { -1 };
-static Fl::Pen::Trait current_pen_trait_ { Fl::Pen::Trait::DRIVER_AVAILABLE };
-static Fl::Pen::Trait driver_traits_ {
- Fl::Pen::Trait::DRIVER_AVAILABLE | Fl::Pen::Trait::PEN_ID |
- Fl::Pen::Trait::ERASER | Fl::Pen::Trait::PRESSURE |
- Fl::Pen::Trait::BARREL_PRESSURE | Fl::Pen::Trait::TILT_X |
- Fl::Pen::Trait::TILT_Y | Fl::Pen::Trait::TWIST
- // Notably missing: PROXIMITY
-};
-
-// Temporary storage of event data for the driver;
-static Fl::Pen::EventData ev;
-
-
-namespace Fl {
-
-namespace Private {
-
-// Global mouse position at mouse down event
-extern int e_x_down;
-extern int e_y_down;
-
-}; // namespace Private
-
-namespace Pen {
-
-class Cocoa_Driver : public Driver {
-public:
- Cocoa_Driver() = default;
- //virtual void subscribe(Fl_Widget* widget) override;
- //virtual void unsubscribe(Fl_Widget* widget) override;
- //virtual void release() override;
- virtual Trait traits() override { return driver_traits_; }
- virtual Trait pen_traits(int pen_id) override {
- auto it = trait_list_.find(pen_id);
- if (pen_id == 0)
- return current_pen_trait_;
- if (it == trait_list_.end()) {
- return Trait::DRIVER_AVAILABLE;
- } else {
- return it->second;
- }
- }
-};
-
-Cocoa_Driver cocoa_driver;
-Driver& driver = cocoa_driver;
-
-} // namespace Pen
-
-} // namespace Fl
-
-
-using namespace Fl::Pen;
-
-
-/*
- Copy the event state.
- */
-static void copy_state() {
- Fl::Pen::State tr = (Fl::Pen::State)((uint32_t)Fl::Pen::e.state ^ (uint32_t)ev.state);
- Fl::Pen::e = ev;
- Fl::Pen::e.trigger = tr;
- Fl::e_x = (int)ev.x;
- Fl::e_y = (int)ev.y;
- Fl::e_x_root = (int)ev.rx;
- Fl::e_y_root = (int)ev.ry;
-}
-
-/*
- Offset coordinates for subwindows and subsubwindows.
- */
-static void offset_subwindow_event(Fl_Widget *w, double &x, double &y) {
- Fl_Widget *p = w, *q;
- while (p) {
- q = p->parent();
- if (p->as_window() && q) {
- x -= p->x();
- y -= p->y();
- }
- p = q;
- };
-}
-
-/*
- Check if coordinates are within the widget box.
- Coordinates are in top_window space. We iterate up the hierarchy to ensure
- that we handle subwindows correctly.
- */
-static bool event_inside(Fl_Widget *w, double x, double y) {
- offset_subwindow_event(w, x, y);
- if (w->as_window()) {
- return ((x >= 0) && (y >= 0) && (x < w->w()) && (y < w->h()));
- } else {
- return ((x >= w->x()) && (y >= w->y()) && (x < w->x() + w->w()) && (y < w->y() + w->h()));
- }
-}
-
-/*
- Find the widget under the pen event.
- Search the subscriber list for widgets that are inside the same top window,
- are visible, and are within the give coordinates. Subwindow aware.
- */
-static Fl_Widget *find_below_pen(Fl_Window *win, double x, double y) {
- for (auto &sub: subscriber_list_) {
- Fl_Widget *candidate = sub.second->widget();
- if (candidate && (candidate->top_window() == win)) {
- if (candidate->visible() && event_inside(candidate, x, y)) {
- return candidate;
- }
- }
- }
- return nullptr;
-}
-
-/*
- Send the current event and event data to a widget.
- Note: we will get the wrong coordinates if the widget is not a child of
- the current event window (LEAVE events between windows).
- */
-static int pen_send(Fl_Widget *w, int event, State trigger, bool &copied) {
- // Copy most event data only once
- if (!copied) {
- copy_state();
- copied = true;
- }
- // Copy the top_window coordinates again as they may change when w changes
- e.x = ev.x;
- e.y = ev.y;
- offset_subwindow_event(w, e.x, e.y);
- Fl::e_x = e.x;
- Fl::e_y = e.y;
- // Send the event.
- e.trigger = trigger;
- return w->handle(event);
-}
-
-/*
- Send an event to all subscribers.
- */
-static int pen_send_all(int event, State trigger) {
- bool copied = false;
- // use local value because handler may still change ev values
- for (auto &it: subscriber_list_) {
- auto w = it.second->widget();
- if (w)
- pen_send(w, event, trigger, copied);
- }
- return 1;
-}
-
-/*
- Convert the NSEvent button number to Fl::Pen::State,
- */
-static State button_to_trigger(NSInteger button, bool down) {
- switch (button) {
- case 0:
- if ( (ev.state & (State::ERASER_DOWN | State::ERASER_HOVERS)) != State::NONE ) {
- return down ? State::ERASER_DOWN : State::ERASER_HOVERS;
- } else {
- return down ? State::TIP_DOWN : State::TIP_HOVERS;
- }
- case 1: return State::BUTTON0;
- case 2: return State::BUTTON1;
- case 3: return State::BUTTON2;
- case 4: return State::BUTTON3;
- default: return State::NONE;
- }
-}
-
-/*
- Handle events coming from Cocoa.
- `capabilityMask` is useless, because it is vendor defined
- If a modal window is open, AppKit will send window specific events only there.
- */
-bool fl_cocoa_tablet_handler(NSEvent *event, Fl_Window *eventWindow) {
- // Quick access to the main type.
- auto type = [event type];
-
- // There seems nothing useful here. Ignore for now.
- if ((type == NSEventTypeMouseEntered) || (type == NSEventTypeMouseExited)) {
- return false;
- }
-
- // Sort out tablet-only events and mouse plus tablet events.
- bool is_mouse = ((type != NSEventTypeTabletPoint) && (type != NSEventTypeTabletProximity));
-
- // Set the subtype if one is available. Only NSEventSubtypeTabletPoint and
- // NSEventSubtypeTabletProximity matter in this context
- NSEventSubtype subtype = is_mouse ? [event subtype] : NSEventSubtypeMouseEvent;
-
- // Is this a change in proximity event?
- bool is_proximity = ((type == NSEventTypeTabletProximity) || (subtype == NSEventSubtypeTabletProximity));
-
- // Is this a pen pointer event?
- bool is_point = ((type == NSEventTypeTabletPoint) || (subtype == NSEventSubtypeTabletPoint));
-
- // Check if any of the pen down, move, drag, or up events was triggered.
- bool is_down = ((type == NSEventTypeLeftMouseDown) || (type == NSEventTypeRightMouseDown) || (type == NSEventTypeOtherMouseDown));
- bool is_up = ((type == NSEventTypeLeftMouseUp) || (type == NSEventTypeRightMouseUp) || (type == NSEventTypeOtherMouseUp));
- bool is_drag = ((type == NSEventTypeLeftMouseDragged) || (type == NSEventTypeRightMouseDragged) || (type == NSEventTypeOtherMouseDragged));
- bool is_motion = is_drag || (type == NSEventTypeMouseMoved);
-
- // Find out if we can get the pen position
- bool has_position = (eventWindow != nullptr) && (is_up || is_down || is_motion || is_proximity || is_point);
-
- // Event has extended pen data set:
- if (has_position) {
- // Get the position data.
- auto pt = [event locationInWindow];
- double s = Fl::screen_driver()->scale(0);
- ev.x = pt.x/s;
- ev.y = eventWindow->h() - pt.y/s;
- ev.rx = ev.x + eventWindow->x();
- ev.ry = ev.y + eventWindow->y();
- if (!is_proximity) {
- // Get the pressure data.
- ev.pressure = [event pressure];
- ev.barrel_pressure = [event tangentialPressure];
- // Get the tilt
- auto tilt = [event tilt];
- ev.tilt_x = -tilt.x;
- ev.tilt_y = tilt.y;
- // Other stuff
- ev.twist = [event rotation]; // TODO: untested
- // ev.proximity = [event proximity]; // not supported in AppKit
- }
- if (device_type_ == NSPointingDeviceTypeEraser) {
- if ([event buttonMask] & 1)
- ev.state = State::ERASER_DOWN;
- else
- ev.state = State::ERASER_HOVERS;
- } else {
- if ([event buttonMask] & 1)
- ev.state = State::TIP_DOWN;
- else
- ev.state = State::TIP_HOVERS;
- }
- if ([event buttonMask] & 0x0002) ev.state |= State::BUTTON0;
- if ([event buttonMask] & 0x0004) ev.state |= State::BUTTON1;
- if ([event buttonMask] & 0x0008) ev.state |= State::BUTTON2;
- if ([event buttonMask] & 0x0010) ev.state |= State::BUTTON3;
- // printf("0x%08x\n", [event buttonMask]);
- }
- if (is_proximity) {
- ev.pen_id = (int)[event vendorID];
- device_type_ = [event pointingDeviceType];
- }
- if (type == NSEventTypeTabletProximity) {
- if ([event isEnteringProximity]) {
- // Check if this is the first time we see this pen, or if the pen changed
- if (current_pen_id_ != ev.pen_id) {
- current_pen_id_ = ev.pen_id;
- auto it = trait_list_.find(current_pen_id_);
- if (it == trait_list_.end()) { // not found, create a new entry
- trait_list_[current_pen_id_] = Trait::DRIVER_AVAILABLE;
- trait_countdown_ = 5;
- pen_send_all(Fl::Pen::DETECTED, State::NONE);
- // printf("IN RANGE, NEW PEN\n");
- } else {
- pen_send_all(Fl::Pen::CHANGED, State::NONE);
- // printf("IN RANGE, CHANGED PEN\n");
- }
- trait_list_[0] = trait_list_[current_pen_id_]; // set current pen traits
- } else {
- pen_send_all(Fl::Pen::IN_RANGE, State::NONE);
- // printf("IN RANGE\n");
- }
- } else {
- pen_send_all(Fl::Pen::OUT_OF_RANGE, State::NONE);
- // printf("OUT OF RANGE\n");
- }
- }
-
- Fl_Widget *receiver = nullptr;
- bool pushed = false;
- bool event_data_copied = false;
-
- if (has_position) {
- if (trait_countdown_) {
- trait_countdown_--;
- if (ev.tilt_x != 0.0) current_pen_trait_ |= Trait::TILT_X;
- if (ev.tilt_y != 0.0) current_pen_trait_ |= Trait::TILT_Y;
- if (ev.pressure != 1.0) current_pen_trait_ |= Trait::PRESSURE;
- if (ev.barrel_pressure != 0.0) current_pen_trait_ |= Trait::BARREL_PRESSURE;
- if (ev.pen_id != 0) current_pen_trait_ |= Trait::PEN_ID;
- if (ev.twist != 0.0) current_pen_trait_ |= Trait::TWIST;
- //if (ev.proximity != 0) current_pen_trait_ |= Trait::PROXIMITY;
- trait_list_[current_pen_id_] = current_pen_trait_;
- }
- fl_xmousewin = eventWindow;
- if (pushed_ && pushed_->widget() && (Fl::pushed() == pushed_->widget())) {
- receiver = pushed_->widget();
- if (Fl::grab() && (Fl::grab() != receiver->top_window()))
- return 0;
- if (Fl::modal() && (Fl::modal() != receiver->top_window()))
- return 0;
- pushed = true;
- } else {
- if (Fl::grab() && (Fl::grab() != eventWindow))
- return 0;
- if (Fl::modal() && (Fl::modal() != eventWindow))
- return 0;
- auto bpen = below_pen_ ? below_pen_->widget() : nullptr;
- auto bmouse = Fl::belowmouse();
- auto bpen_old = bmouse && (bmouse == bpen) ? bpen : nullptr;
- auto bpen_now = find_below_pen(eventWindow, ev.x, ev.y);
-
- if (bpen_now != bpen_old) {
- if (bpen_old) {
- pen_send(bpen_old, Fl::Pen::LEAVE, State::NONE, event_data_copied);
- }
- below_pen_ = nullptr;
- if (bpen_now) {
- State state = (device_type_ == NSPointingDeviceTypeEraser) ? State::ERASER_HOVERS : State::TIP_HOVERS;
- if (pen_send(bpen_now, Fl::Pen::ENTER, state, event_data_copied)) {
- below_pen_ = subscriber_list_[bpen_now];
- Fl::belowmouse(bpen_now);
- }
- }
- }
-
- receiver = below_pen_ ? below_pen_->widget() : nullptr;
- if (!receiver)
- return 0;
- }
- } else {
- // Proximity events were handled earlier.
- }
-
- if (!receiver)
- return 0;
-
- if (is_down) {
- if (!pushed) {
- pushed_ = subscriber_list_[receiver];
- Fl::pushed(receiver);
- }
- State trigger = button_to_trigger([event buttonNumber], true);
- if ([event buttonNumber] == 0) {
- Fl::e_is_click = 1;
- Fl::Private::e_x_down = (int)ev.x;
- Fl::Private::e_y_down = (int)ev.y;
- if ([event clickCount] > 1)
- Fl::e_clicks++;
- else
- Fl::e_clicks = 0;
- pen_send(receiver, Fl::Pen::TOUCH, trigger, event_data_copied);
- } else {
- pen_send(receiver, Fl::Pen::BUTTON_PUSH, trigger, event_data_copied);
- }
- } else if (is_up) {
- if ( (ev.state & State::ANY_DOWN) == State::NONE ) {
- Fl::pushed(nullptr);
- pushed_ = nullptr;
- }
- State trigger = button_to_trigger([event buttonNumber], true);
- if ([event buttonNumber] == 0)
- pen_send(receiver, Fl::Pen::LIFT, trigger, event_data_copied);
- else
- pen_send(receiver, Fl::Pen::BUTTON_RELEASE, trigger, event_data_copied);
- } else if (is_motion) {
- if ( Fl::e_is_click &&
- ( (fabs((int)ev.x - Fl::Private::e_x_down) > 5) ||
- (fabs((int)ev.y - Fl::Private::e_y_down) > 5) ) )
- Fl::e_is_click = 0;
- if (pushed) {
- pen_send(receiver, Fl::Pen::DRAW, State::NONE, event_data_copied);
- } else {
- pen_send(receiver, Fl::Pen::HOVER, State::NONE, event_data_copied);
- }
- }
- // Always return 1 because at this point, we capture pen events and don't
- // want mouse events anymore!
- return 1;
-}
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm b/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm
deleted file mode 100644
index a40f1feb4..000000000
--- a/src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm
+++ /dev/null
@@ -1,455 +0,0 @@
-//
-// Mac OS X-specific printing support (objective-c++) for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2010-2026 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 <FL/Fl_Paged_Device.H>
-#include <FL/Fl_Printer.H>
-#include "../../Fl_Window_Driver.H"
-#include "../../Fl_Screen_Driver.H"
-#include "../Quartz/Fl_Quartz_Graphics_Driver.H"
-#include "../Darwin/Fl_Darwin_System_Driver.H"
-#include <FL/Fl_PDF_File_Surface.H>
-#include "Fl_Cocoa_Window_Driver.H"
-
-#include <FL/Fl.H>
-#include <FL/platform.H>
-#include <FL/fl_ask.H>
-#include <FL/fl_draw.H>
-#include <FL/fl_string_functions.h>
-#import <Cocoa/Cocoa.h>
-
-typedef OSStatus (*PMSessionSetDocumentFormatGeneration_type)(
- PMPrintSession printSession,
- CFStringRef docFormat,
- CFArrayRef graphicsContextTypes,
- CFTypeRef options);
-typedef OSStatus (*PMSessionBeginDocumentNoDialog_type)(
- PMPrintSession printSession,
- PMPrintSettings printSettings,
- PMPageFormat pageFormat);
-typedef OSStatus
-(*PMSessionGetGraphicsContext_type)(
- PMPrintSession printSession,
- CFStringRef graphicsContextType,
- void ** graphicsContext);
-
-
-/** Support for printing on the Apple OS X platform */
-class Fl_Cocoa_Printer_Driver : public Fl_Paged_Device {
- friend class Fl_Printer;
-protected:
- float scale_x;
- float scale_y;
- float angle; // rotation angle in radians
- PMPrintSession printSession;
- PMPageFormat pageFormat;
- PMPrintSettings printSettings;
- Fl_Cocoa_Printer_Driver(void);
- int begin_job(int pagecount = 0, int *frompage = NULL, int *topage = NULL, char **perr_message = NULL) FL_OVERRIDE;
- int begin_page (void) FL_OVERRIDE;
- int printable_rect(int *w, int *h) FL_OVERRIDE;
- void margins(int *left, int *top, int *right, int *bottom) FL_OVERRIDE;
- void origin(int *x, int *y) FL_OVERRIDE;
- void origin(int x, int y) FL_OVERRIDE;
- void scale (float scale_x, float scale_y = 0.) FL_OVERRIDE;
- void rotate(float angle) FL_OVERRIDE;
- void translate(int x, int y) FL_OVERRIDE;
- void untranslate(void) FL_OVERRIDE;
- int end_page (void) FL_OVERRIDE;
- void end_job (void) FL_OVERRIDE;
- ~Fl_Cocoa_Printer_Driver(void);
-};
-
-
-Fl_Cocoa_Printer_Driver::Fl_Cocoa_Printer_Driver(void)
-{
- x_offset = 0;
- y_offset = 0;
- scale_x = scale_y = 1.;
- driver(new Fl_Quartz_Printer_Graphics_Driver);
-}
-
-Fl_Paged_Device* Fl_Printer::newPrinterDriver(void)
-{
- return new Fl_Cocoa_Printer_Driver();
-}
-
-Fl_Cocoa_Printer_Driver::~Fl_Cocoa_Printer_Driver(void) {
- delete driver();
-}
-
-@interface print_panel_delegate : NSObject
-- (void)printPanelDidEnd:(NSPrintPanel *)printPanel returnCode:(NSInteger)returnCode contextInfo:(NSInteger *)contextInfo;
-@end
-@implementation print_panel_delegate
-- (void)printPanelDidEnd:(NSPrintPanel *)printPanel returnCode:(NSInteger)returnCode contextInfo:(NSInteger *)contextInfo
-{
- *contextInfo = returnCode;
-}
-@end
-
-int Fl_Cocoa_Printer_Driver::begin_job (int pagecount, int *frompage, int *topage, char **perr_message)
-//printing using a Quartz graphics context
-//returns 0 iff OK
-{
- OSStatus status = 0;
- fl_open_display();
- Fl_Cocoa_Window_Driver::q_release_context();
- NSPrintInfo *info = [NSPrintInfo sharedPrintInfo];
- NSPrintPanel *panel = [NSPrintPanel printPanel];
- //from 10.5
- [panel setOptions:NSPrintPanelShowsCopies | NSPrintPanelShowsPageRange |
- NSPrintPanelShowsPageSetupAccessory | NSPrintPanelShowsOrientation | NSPrintPanelShowsPaperSize];
- NSInteger retval = -1;
- Fl_Window *top = Fl::first_window();
- NSWindow *main = (top ? (NSWindow*)fl_xid(top->top_window()) : nil);
- if (main) {
- [panel beginSheetWithPrintInfo:info
- modalForWindow:main
- delegate:[[[print_panel_delegate alloc] init] autorelease]
- didEndSelector:@selector(printPanelDidEnd:returnCode:contextInfo:)
- contextInfo:&retval];
- while (retval < 0) Fl::wait(100);
- [main makeKeyAndOrderFront:nil];
- } else {
- retval = [panel runModalWithPrintInfo:info]; //from 10.5
- }
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9
- const NSInteger NSModalResponseOK = NSOKButton;
-#endif
- if (retval != NSModalResponseOK) return 1;
- printSession = (PMPrintSession)[info PMPrintSession]; //from 10.5
- pageFormat = (PMPageFormat)[info PMPageFormat]; //from 10.5
- printSettings = (PMPrintSettings)[info PMPrintSettings];//from 10.5
- UInt32 from32, to32;
- PMGetFirstPage(printSettings, &from32);
- if (frompage) *frompage = (int)from32;
- PMGetLastPage(printSettings, &to32);
- if (topage) {
- *topage = (int)to32;
- if (*topage > pagecount && pagecount > 0) *topage = pagecount;
- }
- status = PMSessionBeginCGDocumentNoDialog(printSession, printSettings, pageFormat);//from 10.4
-
- if (status != noErr) {
- if (perr_message) {
- NSError *nserr = [NSError errorWithDomain:NSCocoaErrorDomain code:status userInfo:nil];
- NSString *s = [nserr localizedDescription];
- if (s) *perr_message = fl_strdup([s UTF8String]);
- }
- return 2;
- }
- y_offset = x_offset = 0;
- return 0;
-}
-
-void Fl_Cocoa_Printer_Driver::margins(int *left, int *top, int *right, int *bottom)
-{
- PMPaper paper;
- PMGetPageFormatPaper(pageFormat, &paper);
- PMOrientation orientation;
- PMGetOrientation(pageFormat, &orientation);
- PMPaperMargins margins;
- PMPaperGetMargins(paper, &margins);
- if(orientation == kPMPortrait) {
- if (left) *left = (int)(margins.left / scale_x + 0.5);
- if (top) *top = (int)(margins.top / scale_y + 0.5);
- if (right) *right = (int)(margins.right / scale_x + 0.5);
- if (bottom) *bottom = (int)(margins.bottom / scale_y + 0.5);
- } else {
- if (left) *left = (int)(margins.top / scale_x + 0.5);
- if (top) *top = (int)(margins.left / scale_y + 0.5);
- if (right) *right = (int)(margins.bottom / scale_x + 0.5);
- if (bottom) *bottom = (int)(margins.right / scale_y + 0.5);
- }
-}
-
-int Fl_Cocoa_Printer_Driver::printable_rect(int *w, int *h)
-//returns 0 iff OK
-{
- OSStatus status;
- PMRect pmRect;
- int x, y;
-
- status = PMGetAdjustedPageRect(pageFormat, &pmRect);
- if (status != noErr) return 1;
-
- x = (int)pmRect.left;
- y = (int)pmRect.top;
- *w = int((int)(pmRect.right - x) / scale_x + 1);
- *h = int((int)(pmRect.bottom - y) / scale_y + 1);
- return 0;
-}
-
-void Fl_Cocoa_Printer_Driver::origin(int x, int y)
-{
- x_offset = x;
- y_offset = y;
- CGContextRef gc = (CGContextRef)driver()->gc();
- CGContextRestoreGState(gc);
- CGContextRestoreGState(gc);
- CGContextSaveGState(gc);
- CGContextScaleCTM(gc, scale_x, scale_y);
- CGContextTranslateCTM(gc, x, y);
- CGContextRotateCTM(gc, angle);
- CGContextSaveGState(gc);
-}
-
-void Fl_Cocoa_Printer_Driver::scale (float s_x, float s_y)
-{
- if (s_y == 0.) s_y = s_x;
- scale_x = s_x;
- scale_y = s_y;
- CGContextRef gc = (CGContextRef)driver()->gc();
- CGContextRestoreGState(gc);
- CGContextRestoreGState(gc);
- CGContextSaveGState(gc);
- CGContextScaleCTM(gc, scale_x, scale_y);
- CGContextRotateCTM(gc, angle);
- x_offset = y_offset = 0;
- CGContextSaveGState(gc);
-}
-
-void Fl_Cocoa_Printer_Driver::rotate (float rot_angle)
-{
- angle = - rot_angle * M_PI / 180.;
- CGContextRef gc = (CGContextRef)driver()->gc();
- CGContextRestoreGState(gc);
- CGContextRestoreGState(gc);
- CGContextSaveGState(gc);
- CGContextScaleCTM(gc, scale_x, scale_y);
- CGContextTranslateCTM(gc, x_offset, y_offset);
- CGContextRotateCTM(gc, angle);
- CGContextSaveGState(gc);
-}
-
-void Fl_Cocoa_Printer_Driver::translate(int x, int y)
-{
- CGContextRef gc = (CGContextRef)driver()->gc();
- CGContextSaveGState(gc);
- CGContextTranslateCTM(gc, x, y );
- CGContextSaveGState(gc);
-}
-
-void Fl_Cocoa_Printer_Driver::untranslate(void)
-{
- CGContextRef gc = (CGContextRef)driver()->gc();
- CGContextRestoreGState(gc);
- CGContextRestoreGState(gc);
-}
-
-int Fl_Cocoa_Printer_Driver::begin_page (void)
-{
- OSStatus status = PMSessionBeginPageNoDialog(printSession, pageFormat, NULL);
- CGContextRef gc;
- status = PMSessionGetCGGraphicsContext(printSession, &gc); // 10.4
- driver()->gc(gc);
- Fl_Surface_Device::push_current(this);
- PMRect pmRect;
- float win_scale_x, win_scale_y;
-
- PMPaper paper;
- PMGetPageFormatPaper(pageFormat, &paper);
- PMPaperMargins margins;
- PMPaperGetMargins(paper, &margins);
- PMOrientation orientation;
- PMGetOrientation(pageFormat, &orientation);
-
- status = PMGetAdjustedPageRect(pageFormat, &pmRect);
- double h = pmRect.bottom - pmRect.top;
- x_offset = 0;
- y_offset = 0;
- angle = 0;
- scale_x = scale_y = 1;
- win_scale_x = win_scale_y = 1;
- if(orientation == kPMPortrait)
- CGContextTranslateCTM(gc, margins.left, margins.bottom + h);
- else
- CGContextTranslateCTM(gc, margins.top, margins.right + h);
- CGContextScaleCTM(gc, win_scale_x, - win_scale_y);
- ((Fl_Quartz_Graphics_Driver*)driver())->quartz_restore_line_style();
- CGContextSetShouldAntialias(gc, false);
- CGContextSaveGState(gc);
- CGContextSaveGState(gc);
- fl_line_style(FL_SOLID);
- fl_window = (FLWindow*)1; // TODO: something better
- fl_clip_region(0);
- return status != noErr;
-}
-
-int Fl_Cocoa_Printer_Driver::end_page (void)
-{
- CGContextRef gc = (CGContextRef)driver()->gc();
- CGContextFlush(gc);
- CGContextRestoreGState(gc);
- CGContextRestoreGState(gc);
- OSStatus status = PMSessionEndPageNoDialog(printSession);
- gc = NULL;
- Fl_Surface_Device::pop_current();
- return status != noErr;
-}
-
-void Fl_Cocoa_Printer_Driver::end_job (void)
-{
- OSStatus status;
-
- status = PMSessionError(printSession);
- if (status != noErr) {
- fl_alert ("PM Session error %d", (int)status);
- }
- PMSessionEndDocumentNoDialog(printSession);
- Fl_Window *w = Fl::first_window();
- if (w) w->show();
-}
-
-void Fl_Cocoa_Printer_Driver::origin(int *x, int *y)
-{
- Fl_Paged_Device::origin(x, y);
-}
-
-
-class Fl_PDF_Cocoa_File_Surface : public Fl_Cocoa_Printer_Driver
-{
-public:
- char *doc_fname;
- Fl_PDF_Cocoa_File_Surface();
- ~Fl_PDF_Cocoa_File_Surface() { if (doc_fname) free(doc_fname); }
- int begin_job(const char *defaultname,
- char **perr_message = NULL);
- int begin_job(int, int*, int *, char **) FL_OVERRIDE {return 1;} // don't use
- int begin_document(const char* outname,
- enum Fl_Paged_Device::Page_Format format,
- enum Fl_Paged_Device::Page_Layout layout,
- char **perr_message);
-};
-
-
-Fl_PDF_Cocoa_File_Surface::Fl_PDF_Cocoa_File_Surface() {
- driver(new Fl_Quartz_Graphics_Driver());
- doc_fname = NULL;
-}
-
-
-int Fl_PDF_Cocoa_File_Surface::begin_job(const char* defaultfilename,
- char **perr_message) {
- OSStatus status = 0;
- if (fl_mac_os_version < 100900) return 1;
- Fl_Window *top = Fl::first_window();
- NSWindow *main = (top ? (NSWindow*)fl_xid(top->top_window()) : nil);
- if (!main) return 1;
- Fl_Cocoa_Window_Driver::q_release_context();
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 && defined(__BLOCKS__)
- NSPDFInfo *pdf_info = [[NSPDFInfo alloc] init]; // 10.9
- NSPDFPanel *pdf_panel = [NSPDFPanel panel]; // 10.9
- char buf[FL_PATH_MAX];
- strcpy(buf, defaultfilename);
- fl_filename_setext(buf, sizeof(buf), NULL);
- [pdf_panel setDefaultFileName:[NSString stringWithUTF8String:buf]];
- [pdf_panel setOptions: NSPrintPanelShowsOrientation | NSPrintPanelShowsPaperSize];
- NSInteger retval = -1;
- __block NSInteger complete = -1;
- [pdf_panel beginSheetWithPDFInfo:pdf_info
- modalForWindow:main
- completionHandler:^(NSInteger returnCode) {
- // this block runs after OK or Cancel was triggered in file dialog
- complete = returnCode;
- }
- ];
- while (complete == -1) Fl::wait(100); // loop until end of file dialog
- retval = complete;
- [main makeKeyAndOrderFront:nil];
- if (retval != NSModalResponseOK) return 1;
- NSURL *url = [pdf_info URL];
- doc_fname = fl_strdup([url fileSystemRepresentation]);
- NSPrintInfo *pr_info = [NSPrintInfo sharedPrintInfo];
- [pr_info takeSettingsFromPDFInfo:pdf_info];
- [pdf_info release];
- printSession = (PMPrintSession)[pr_info PMPrintSession];
- printSettings = (PMPrintSettings)[pr_info PMPrintSettings];
- pageFormat = (PMPageFormat)[pr_info PMPageFormat];
- status = PMSessionBeginCGDocumentNoDialog(printSession, printSettings, pageFormat);//from 10.4
-#endif
- if (status != noErr) {
- if (perr_message) {
- NSError *nserr = [NSError errorWithDomain:NSCocoaErrorDomain code:status userInfo:nil];
- NSString *s = [nserr localizedDescription];
- if (s) *perr_message = fl_strdup([s UTF8String]);
- }
- free(doc_fname);
- doc_fname = NULL;
- return 2;
- }
- y_offset = x_offset = 0;
- return 0;
-}
-
-
-int Fl_PDF_Cocoa_File_Surface::begin_document(const char* outfname,
- enum Fl_Paged_Device::Page_Format format,
- enum Fl_Paged_Device::Page_Layout layout,
- char **perr_message) {
- OSStatus status = 0;
- fl_open_display();
- if (fl_mac_os_version < 100900) return 1;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
- NSPDFInfo *pdf_info = [[NSPDFInfo alloc] init]; // 10.9
- doc_fname = fl_strdup(outfname);
- NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:doc_fname]];
- [pdf_info setURL:url];
- NSSize psize = {(CGFloat)Fl_Paged_Device::page_formats[format].width, (CGFloat)Fl_Paged_Device::page_formats[format].height};
- [pdf_info setPaperSize:psize];
- [pdf_info setOrientation:(layout == PORTRAIT ? NSPaperOrientationPortrait : NSPaperOrientationLandscape)];
- NSPrintInfo *pr_info = [NSPrintInfo sharedPrintInfo];
- [pr_info takeSettingsFromPDFInfo:pdf_info];
- [pdf_info release];
- printSession = (PMPrintSession)[pr_info PMPrintSession];
- printSettings = (PMPrintSettings)[pr_info PMPrintSettings];
- pageFormat = (PMPageFormat)[pr_info PMPageFormat];
- status = PMSessionBeginCGDocumentNoDialog(printSession, printSettings, pageFormat);//from 10.4
-#endif
- if (status != noErr) {
- if (perr_message) {
- NSError *nserr = [NSError errorWithDomain:NSCocoaErrorDomain code:status userInfo:nil];
- NSString *s = [nserr localizedDescription];
- if (s) *perr_message = fl_strdup([s UTF8String]);
- }
- free(doc_fname);
- doc_fname = NULL;
- return 2;
- }
- y_offset = x_offset = 0;
- return 0;
-}
-
-
-Fl_Paged_Device *Fl_PDF_File_Surface::new_platform_pdf_surface_(const char ***pfname) {
- Fl_PDF_Cocoa_File_Surface *surf = new Fl_PDF_Cocoa_File_Surface();
- *pfname = (const char**)&surf->doc_fname;
- return surf;
-}
-
-
-int Fl_PDF_File_Surface::begin_job(const char* defaultfilename,
- char **perr_message) {
- return ((Fl_PDF_Cocoa_File_Surface*)platform_surface_)->begin_job(defaultfilename, perr_message);
-}
-
-
-int Fl_PDF_File_Surface::begin_document(const char* defaultfilename,
- enum Fl_Paged_Device::Page_Format format,
- enum Fl_Paged_Device::Page_Layout layout,
- char **perr_message) {
- return ((Fl_PDF_Cocoa_File_Surface*)platform_surface_)->begin_document(defaultfilename, format, layout, perr_message);
-}
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
deleted file mode 100644
index 9e3d2386a..000000000
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
+++ /dev/null
@@ -1,114 +0,0 @@
-//
-// Definition of Apple Cocoa Screen interface
-// for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2010-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
-//
-
-/**
- \file Fl_Cocoa_Screen_Driver.H
- \brief Definition of Apple Cocoa Screen interface.
- */
-
-#ifndef FL_COCOA_SCREEN_DRIVER_H
-#define FL_COCOA_SCREEN_DRIVER_H
-
-#include "../../Fl_Screen_Driver.H"
-
-/*
- Move everything here that manages the native screen interface.
-
- There is exactly one screen driver in the system.
-
- - screen configuration and sizes
- - multiple screens
- - native dialog boxes
-*/
-
-
-class Fl_Window;
-class Fl_Input;
-class Fl_RGB_Image;
-#ifdef __OBJC__
-@class NSImage;
-#else
-class NSImage;
-#endif
-
-class Fl_Cocoa_Screen_Driver : public Fl_Screen_Driver
-{
-protected:
- struct XRectangle {int x, y, width, height;};
- XRectangle screens[MAX_SCREENS];
- float dpi_h[MAX_SCREENS];
- float dpi_v[MAX_SCREENS];
- static int insertion_point_x;
- static int insertion_point_y;
- static int insertion_point_height;
- static bool insertion_point_location_is_valid;
-public:
- NSImage *default_icon;
- Fl_Cocoa_Screen_Driver();
- static int next_marked_length; // next length of marked text after current marked text will have been replaced
- static void breakMacEventLoop();
- // --- display management
- // --- screen configuration
- void init() FL_OVERRIDE;
- int x() FL_OVERRIDE;
- int y() FL_OVERRIDE;
- int w() FL_OVERRIDE;
- int h() FL_OVERRIDE;
- void screen_xywh(int &X, int &Y, int &W, int &H, int n) FL_OVERRIDE;
- void screen_dpi(float &h, float &v, int n=0) FL_OVERRIDE;
- // implemented in Fl_cocoa.mm because uses Objective-c
- void screen_work_area(int &X, int &Y, int &W, int &H, int n) FL_OVERRIDE;
- // --- audible output
- void beep(int type) FL_OVERRIDE;
- // --- global events
- void grab(Fl_Window* win) FL_OVERRIDE;
- // --- global colors
- void get_system_colors() FL_OVERRIDE;
- int has_marked_text() const FL_OVERRIDE;
- static void reset_marked_text();
- static void insertion_point_location(int x, int y, int height);
- static int insertion_point_location(int *px, int *py, int *pheight);
- int dnd(int use_selection) FL_OVERRIDE;
- int compose(int &del) FL_OVERRIDE;
- int input_widget_handle_key(int key, unsigned mods, unsigned shift, Fl_Input *input) FL_OVERRIDE;
- int get_mouse(int &x, int &y) FL_OVERRIDE;
- void enable_im() FL_OVERRIDE;
- void disable_im() FL_OVERRIDE;
- void open_display_platform() FL_OVERRIDE;
- // --- compute dimensions of an Fl_Offscreen
- void offscreen_size(Fl_Offscreen o, int &width, int &height) FL_OVERRIDE;
-
- APP_SCALING_CAPABILITY rescalable() FL_OVERRIDE { return SYSTEMWIDE_APP_SCALING; }
- float scale(int /*nscreen*/) FL_OVERRIDE {return scale_;}
- void scale(int /*nscreen*/, float f) FL_OVERRIDE { scale_ = f;}
- Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool may_capture_subwins, bool *did_capture_subwins) FL_OVERRIDE;
- void default_icons(const Fl_RGB_Image *icons[], int count) FL_OVERRIDE;
- void copy(const char *stuff, int len, int clipboard, const char *type) FL_OVERRIDE;
- void paste(Fl_Widget &receiver, int clipboard, const char *type) FL_OVERRIDE;
- int clipboard_contains(const char *type) FL_OVERRIDE;
- void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win) FL_OVERRIDE;
- void reset_spot() FL_OVERRIDE;
- int need_menu_handle_part2() FL_OVERRIDE {return 1;}
- // these 2 are in Fl_get_key_mac.cxx
- int event_key(int) FL_OVERRIDE;
- int get_key(int) FL_OVERRIDE;
-private:
- float scale_;
-};
-
-
-#endif // FL_COCOA_SCREEN_DRIVER_H
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
deleted file mode 100644
index 7eb98b291..000000000
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
+++ /dev/null
@@ -1,434 +0,0 @@
-//
-// Definition of Apple Cocoa Screen interface.
-//
-// Copyright 1998-2023 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>
-#include "Fl_Cocoa_Screen_Driver.H"
-#include "Fl_Cocoa_Window_Driver.H"
-#include "../Quartz/Fl_Font.H"
-#include <FL/Fl.H>
-#include <FL/platform.H>
-#include <FL/Fl_Graphics_Driver.H>
-#include <FL/Fl_Input.H>
-#include <FL/fl_ask.H>
-#include <FL/Fl_Image_Surface.H>
-#include <stdio.h>
-
-
-extern "C" void NSBeep(void);
-extern void (*fl_lock_function)();
-extern void (*fl_unlock_function)();
-
-int Fl_Cocoa_Screen_Driver::next_marked_length = 0;
-
-
-// This key table is used for the Darwin system driver. It is defined here
-// "static" and assigned in the constructor to avoid static initialization
-// race conditions. It is used in fl_shortcut.cxx.
-//
-// This table must be in numeric order by fltk (X) keysym number:
-
-Fl_Screen_Driver::Keyname darwin_key_table[] = {
- // v - this column may contain UTF-8 characters
- {' ', "Space"},
- {FL_BackSpace, "⌫"/*"\xe2\x8c\xab"*/}, // U+232B : erase to the left
- {FL_Tab, "⇥"/*"\xe2\x87\xa5"*/}, // U+21E5 rightwards arrow to bar
- {FL_Enter, "↩"/*"\xe2\x86\xa9"*/}, // U+21A9 leftwards arrow with hook
- {FL_Pause, "Pause"},
- {FL_Scroll_Lock, "Scroll_Lock"},
- {FL_Escape, "⎋"/*"\xe2\x8e\x8b"*/}, // U+238B : broken circle with northwest arrow
- {FL_Home, "↖"/*"\xe2\x86\x96"*/}, // U+2196 north west arrow
- {FL_Left, "←"/*"\xe2\x86\x90"*/}, // U+2190 leftwards arrow
- {FL_Up, "↑"/*"\xe2\x86\x91"*/}, // U+2191 upwards arrow
- {FL_Right, "→"/*"\xe2\x86\x92"*/}, // U+2192 rightwards arrow
- {FL_Down, "↓"/*"\xe2\x86\x93"*/}, // U+2193 downwards arrow
- {FL_Page_Up, "⇞"/*"\xe2\x87\x9e"*/}, // U+21DE upwards arrow with double stroke
- {FL_Page_Down, "⇟"/*"\xe2\x87\x9f"*/}, // U+21DF downwards arrow with double stroke
- {FL_End, "↘"/*"\xe2\x86\x98"*/}, // U+2198 south east arrow
- {FL_Print, "Print"},
- {FL_Insert, "Insert"},
- {FL_Menu, "Menu"},
- {FL_Num_Lock, "Num_Lock"},
- {FL_KP_Enter, "⌤"/*"\xe2\x8c\xa4"*/}, // U+2324 up arrow head between two horizontal bars
- {FL_Shift_L, "Shift_L"},
- {FL_Shift_R, "Shift_R"},
- {FL_Control_L, "Control_L"},
- {FL_Control_R, "Control_R"},
- {FL_Caps_Lock, "⇪"/*"\xe2\x87\xaa"*/}, // U+21EA upwards white arrow from bar
- {FL_Meta_L, "Meta_L"},
- {FL_Meta_R, "Meta_R"},
- {FL_Alt_L, "Alt_L"},
- {FL_Alt_R, "Alt_R"},
- {FL_Delete, "⌦"/*"\xe2\x8c\xa6"*/} // U+2326 : erase to the right
-};
-
-
-static Fl_Text_Editor::Key_Binding extra_bindings[] = {
- // Define CMD+key accelerators...
- { 'z', FL_COMMAND, Fl_Text_Editor::kf_undo ,0},
- { 'z', FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_redo ,0},
- { 'x', FL_COMMAND, Fl_Text_Editor::kf_cut ,0},
- { 'c', FL_COMMAND, Fl_Text_Editor::kf_copy ,0},
- { 'v', FL_COMMAND, Fl_Text_Editor::kf_paste ,0},
- { 'a', FL_COMMAND, Fl_Text_Editor::kf_select_all ,0},
- { FL_Left, FL_COMMAND, Fl_Text_Editor::kf_meta_move ,0},
- { FL_Right, FL_COMMAND, Fl_Text_Editor::kf_meta_move ,0},
- { FL_Up, FL_COMMAND, Fl_Text_Editor::kf_meta_move ,0},
- { FL_Down, FL_COMMAND, Fl_Text_Editor::kf_meta_move ,0},
- { FL_Left, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move ,0},
- { FL_Right, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move ,0},
- { FL_Up, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move ,0},
- { FL_Down, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move ,0},
- { 0, 0, 0 ,0}
-};
-
-
-Fl_Cocoa_Screen_Driver::Fl_Cocoa_Screen_Driver() {
- text_editor_extra_key_bindings = extra_bindings;
- scale_ = 1.;
- default_icon = nil;
- // initialize key table
- key_table = darwin_key_table;
- key_table_size = sizeof(darwin_key_table)/sizeof(*darwin_key_table);
-}
-
-
-void Fl_Cocoa_Screen_Driver::init()
-{
- open_display();
- CGDirectDisplayID displays[MAX_SCREENS];
- CGDisplayCount count, i;
- CGRect r;
- CGGetActiveDisplayList(MAX_SCREENS, displays, &count);
- for( i = 0; i < count; i++) {
- r = CGDisplayBounds(displays[i]);
- screens[i].x = int(r.origin.x);
- screens[i].y = int(r.origin.y);
- screens[i].width = int(r.size.width);
- screens[i].height = int(r.size.height);
- //fprintf(stderr,"screen %d %dx%dx%dx%d\n",i,screens[i].x,screens[i].y,screens[i].width,screens[i].height);
- if (&CGDisplayScreenSize != NULL) {
- CGSize s = CGDisplayScreenSize(displays[i]); // from 10.3
- dpi_h[i] = screens[i].width / (s.width/25.4);
- dpi_v[i] = screens[i].height / (s.height/25.4);
- } else {
- dpi_h[i] = dpi_v[i] = 75.;
- }
- }
- num_screens = count;
-}
-
-
-void Fl_Cocoa_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H, int n)
-{
- if (num_screens < 0) init();
-
- if ((n < 0) || (n >= num_screens))
- n = 0;
-
- float s = scale(0);
- X = screens[n].x/s;
- Y = screens[n].y/s;
- W = screens[n].width/s;
- H = screens[n].height/s;
-}
-
-
-void Fl_Cocoa_Screen_Driver::screen_dpi(float &h, float &v, int n)
-{
- if (num_screens < 0) init();
- h = v = 0.0f;
-
- if (n >= 0 && n < num_screens) {
- h = dpi_h[n];
- v = dpi_v[n];
- }
-}
-
-
-// Implements fl_beep(). See documentation in src/fl_ask.cxx.
-void Fl_Cocoa_Screen_Driver::beep(int type) {
- switch (type) {
- case FL_BEEP_DEFAULT :
- case FL_BEEP_ERROR :
- NSBeep();
- break;
- default :
- break;
- }
-}
-
-
-extern void fl_fix_focus(); // in Fl.cxx
-
-extern void *fl_capture;
-
-
-void Fl_Cocoa_Screen_Driver::grab(Fl_Window* win)
-{
- if (win) {
- if (!Fl::grab_) {
- fl_capture = (FLWindow*)(Fl_X::flx(Fl::first_window())->xid);
- Fl_Cocoa_Window_Driver::driver(Fl::first_window())->set_key_window();
- }
- Fl::grab_ = win;
- } else {
- if (Fl::grab_) {
- fl_capture = 0;
- Fl::grab_ = 0;
- fl_fix_focus();
- }
- }
-}
-
-
-static void set_selection_color(uchar r, uchar g, uchar b)
-{
- Fl::set_color(FL_SELECTION_COLOR,r,g,b);
-}
-
-
-// MacOS X currently supports two color schemes - Blue and Graphite.
-// Since we aren't emulating the Aqua interface (even if Apple would
-// let us), we use some defaults that are similar to both. The
-// Fl::scheme("plastic") color/box scheme provides a usable Aqua-like
-// look-n-feel...
-void Fl_Cocoa_Screen_Driver::get_system_colors()
-{
- open_display();
-
- Fl_Screen_Driver::get_system_colors();
-
- if (!bg2_set) Fl::background2(0xff, 0xff, 0xff);
- if (!fg_set) Fl::foreground(0, 0, 0);
- if (!bg_set) Fl::background(0xd8, 0xd8, 0xd8);
-
-#if 0
- // this would be the correct code, but it does not run on all versions
- // of OS X. Also, setting a bright selection color would require
- // some updates in Fl_Adjuster and Fl_Help_Browser
- OSStatus err;
- RGBColor c;
- err = GetThemeBrushAsColor(kThemeBrushPrimaryHighlightColor, 24, true, &c);
- if (err)
- set_selection_color(0x00, 0x00, 0x80);
- else
- set_selection_color(c.red, c.green, c.blue);
-#else
- set_selection_color(0x00, 0x00, 0x80);
-#endif
-}
-
-
-int Fl_Cocoa_Screen_Driver::has_marked_text() const {
- return 1;
-}
-
-
-int Fl_Cocoa_Screen_Driver::insertion_point_x = 0;
-int Fl_Cocoa_Screen_Driver::insertion_point_y = 0;
-int Fl_Cocoa_Screen_Driver::insertion_point_height = 0;
-bool Fl_Cocoa_Screen_Driver::insertion_point_location_is_valid = false;
-
-void Fl_Cocoa_Screen_Driver::reset_marked_text() {
- Fl::compose_state = 0;
- next_marked_length = 0;
- insertion_point_location_is_valid = false;
-}
-
-// computes window coordinates & height of insertion point
-int Fl_Cocoa_Screen_Driver::insertion_point_location(int *px, int *py, int *pheight)
-// return true if the current coordinates of the insertion point are available
-{
- if ( ! insertion_point_location_is_valid ) return false;
- *px = insertion_point_x;
- *py = insertion_point_y;
- *pheight = insertion_point_height;
- return true;
-}
-
-void Fl_Cocoa_Screen_Driver::insertion_point_location(int x, int y, int height) {
- insertion_point_location_is_valid = true;
- insertion_point_x = x;
- insertion_point_y = y;
- insertion_point_height = height;
-}
-
-int Fl_Cocoa_Screen_Driver::compose(int &del) {
- int condition;
- int has_text_key = Fl::compose_state || Fl::e_keysym <= '~' || Fl::e_keysym == FL_Iso_Key ||
- Fl::e_keysym == FL_JIS_Underscore || Fl::e_keysym == FL_Yen ||
- (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last && Fl::e_keysym != FL_KP_Enter);
- condition = Fl::e_state&(FL_META | FL_CTRL) ||
- (Fl::e_keysym >= FL_Shift_L && Fl::e_keysym <= FL_Alt_R) || // called from flagsChanged
- !has_text_key ;
- if (condition) { del = 0; return 0;} // this stuff is to be treated as a function key
- del = Fl::compose_state;
- Fl::compose_state = next_marked_length;
- return 1;
-}
-
-
-int Fl_Cocoa_Screen_Driver::input_widget_handle_key(int key, unsigned mods, unsigned shift, Fl_Input *input)
-{
- switch (key) {
- case FL_Delete: {
- if (mods==0) return input->kf_delete_char_right(); // Delete (OSX-HIG,TE,SA,WOX)
- if (mods==FL_CTRL) return input->kf_delete_char_right(); // Ctrl-Delete (??? TE,!SA,!WOX)
- if (mods==FL_ALT) return input->kf_delete_word_right(); // Alt-Delete (OSX-HIG,TE,SA)
- return 0; // ignore other combos, pass to parent
- }
-
- case FL_Left:
- if (mods==0) return input->kf_move_char_left(); // Left (OSX-HIG)
- if (mods==FL_ALT) return input->kf_move_word_left(); // Alt-Left (OSX-HIG)
- if (mods==FL_META) return input->kf_move_sol(); // Meta-Left (OSX-HIG)
- if (mods==FL_CTRL) return input->kf_move_sol(); // Ctrl-Left (TE/SA)
- return 0; // ignore other combos, pass to parent
-
- case FL_Right:
- if (mods==0) return input->kf_move_char_right(); // Right (OSX-HIG)
- if (mods==FL_ALT) return input->kf_move_word_right(); // Alt-Right (OSX-HIG)
- if (mods==FL_META) return input->kf_move_eol(); // Meta-Right (OSX-HIG)
- if (mods==FL_CTRL) return input->kf_move_eol(); // Ctrl-Right (TE/SA)
- return 0; // ignore other combos, pass to parent
-
- case FL_Up:
- if (mods==0) return input->kf_lines_up(1); // Up (OSX-HIG)
- if (mods==FL_CTRL) return input->kf_page_up(); // Ctrl-Up (TE !HIG)
- if (mods==FL_ALT) return input->kf_move_up_and_sol(); // Alt-Up (OSX-HIG)
- if (mods==FL_META) return input->kf_top(); // Meta-Up (OSX-HIG)
- return 0; // ignore other combos, pass to parent
-
- case FL_Down:
- if (mods==0) return input->kf_lines_down(1); // Dn (OSX-HIG)
- if (mods==FL_CTRL) return input->kf_page_down(); // Ctrl-Dn (TE !HIG)
- if (mods==FL_ALT) return input->kf_move_down_and_eol(); // Alt-Dn (OSX-HIG)
- if (mods==FL_META) return input->kf_bottom(); // Meta-Dn (OSX-HIG)
- return 0; // ignore other combos, pass to parent
-
- case FL_Page_Up:
- // Fl_Input has no scroll control, so instead we move the cursor by one page
- // OSX-HIG recommends Alt increase one semantic unit, Meta next higher..
- if (mods==0) return input->kf_page_up(); // PgUp (OSX-HIG)
- if (mods==FL_ALT) return input->kf_page_up(); // Alt-PageUp (OSX-HIG)
- if (mods==FL_META) return input->kf_top(); // Meta-PageUp (OSX-HIG,!TE)
- return 0; // ignore other combos, pass to parent
-
- case FL_Page_Down:
- // Fl_Input has no scroll control, so instead we move the cursor by one page
- // OSX-HIG recommends Alt increase one semantic unit, Meta next higher..
- if (mods==0) return input->kf_page_down(); // PgDn (OSX-HIG)
- if (mods==FL_ALT) return input->kf_page_down(); // Alt-PageDn (OSX-HIG)
- if (mods==FL_META) return input->kf_bottom(); // Meta-PageDn (OSX-HIG,!TE)
- return 0; // ignore other combos, pass to parent
-
- case FL_Home:
- if (mods==0) return input->kf_top(); // Home (OSX-HIG)
- if (mods==FL_ALT) return input->kf_top(); // Alt-Home (???)
- return 0; // ignore other combos, pass to parent
-
- case FL_End:
- if (mods==0) return input->kf_bottom(); // End (OSX-HIG)
- if (mods==FL_ALT) return input->kf_bottom(); // Alt-End (???)
- return 0; // ignore other combos, pass to parent
-
- case FL_BackSpace:
- if (mods==0) return input->kf_delete_char_left(); // Backspace (OSX-HIG)
- if (mods==FL_CTRL) return input->kf_delete_char_left(); // Ctrl-Backspace (TE/SA)
- if (mods==FL_ALT) return input->kf_delete_word_left(); // Alt-Backspace (OSX-HIG)
- if (mods==FL_META) return input->kf_delete_sol(); // Meta-Backspace (OSX-HIG,!TE)
- return 0; // ignore other combos, pass to parent
- }
- return -1;
-}
-
-void Fl_Cocoa_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &height)
-{
- width = (int)CGBitmapContextGetWidth((CGContextRef)off);
- height = (int)CGBitmapContextGetHeight((CGContextRef)off);
-}
-
-Fl_RGB_Image *Fl_Cocoa_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *window,
- bool may_capture_subwins, bool *did_capture_subwins)
-{
- int bpp, bpr;
- uchar *base, *p;
- if (!window) { // read from offscreen buffer
- float s = 1;
- CGContextRef src = (CGContextRef)Fl_Surface_Device::surface()->driver()->gc(); // get bitmap context
- base = (uchar *)CGBitmapContextGetData(src); // get data
- if(!base) return NULL;
- int sw = (int)CGBitmapContextGetWidth(src);
- int sh = (int)CGBitmapContextGetHeight(src);
- if( (sw - X < w) || (sh - Y < h) ) return NULL;
- bpr = (int)CGBitmapContextGetBytesPerRow(src);
- bpp = (int)CGBitmapContextGetBitsPerPixel(src)/8;
- Fl_Image_Surface *imgs = (Fl_Image_Surface*)Fl_Surface_Device::surface();
- int fltk_w, fltk_h;
- imgs->printable_rect(&fltk_w, &fltk_h);
- s = sw / float(fltk_w);
- X *= s; Y *= s; w *= s; h *= s;
- if (X + w > sw) w = sw - X;
- if (Y + h > sh) h = sh - Y;
- // Copy the image from the off-screen buffer to the memory buffer.
- int idx, idy; // Current X & Y in image
- uchar *pdst, *psrc;
- p = new uchar[w * h * 4];
- for (idy = Y, pdst = p; idy < h + Y; idy ++) {
- for (idx = 0, psrc = base + idy * bpr + X * bpp; idx < w; idx ++, psrc += bpp, pdst += 4) {
- pdst[0] = psrc[0]; // R
- pdst[1] = psrc[1]; // G
- pdst[2] = psrc[2]; // B
- }
- }
- bpr = 0;
- } else { // read from window
- Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(window);
- CGImageRef cgimg = d->CGImage_from_window_rect(X, Y, w, h, may_capture_subwins);
- if (did_capture_subwins) *did_capture_subwins = may_capture_subwins;
- if (!cgimg) {
- return NULL;
- }
- w = (int)CGImageGetWidth(cgimg);
- h = (int)CGImageGetHeight(cgimg);
- Fl_Image_Surface *surf = new Fl_Image_Surface(w, h);
- Fl_Surface_Device::push_current(surf);
- ((Fl_Quartz_Graphics_Driver*)fl_graphics_driver)->draw_CGImage(cgimg, 0, 0, w, h, 0, 0, w, h);
- CGContextRef gc = (CGContextRef)fl_graphics_driver->gc();
- w = (int)CGBitmapContextGetWidth(gc);
- h = (int)CGBitmapContextGetHeight(gc);
- bpr = (int)CGBitmapContextGetBytesPerRow(gc);
- bpp = (int)CGBitmapContextGetBitsPerPixel(gc)/8;
- base = (uchar*)CGBitmapContextGetData(gc);
- p = new uchar[bpr * h];
- memcpy(p, base, bpr * h);
- Fl_Surface_Device::pop_current();
- delete surf;
- CFRelease(cgimg);
- }
- Fl_RGB_Image *rgb = new Fl_RGB_Image(p, w, h, 4, bpr);
- rgb->alloc_array = 1;
- return rgb;
-}
-
-void Fl_Cocoa_Screen_Driver::set_spot(int /*font*/, int size, int X, int Y, int /*W*/, int /*H*/, Fl_Window* /*win*/) {
- Fl_Cocoa_Screen_Driver::insertion_point_location(X, Y, size);
-}
-
-void Fl_Cocoa_Screen_Driver::reset_spot() {
- Fl_Cocoa_Screen_Driver::reset_marked_text();
-}
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
deleted file mode 100644
index 358523dbd..000000000
--- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
+++ /dev/null
@@ -1,168 +0,0 @@
-//
-// Definition of Apple Cocoa window driver
-// for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2010-2025 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
-//
-
-/**
- \file Fl_Cocoa_Window_Driver.H
- \brief Definition of Apple Cocoa window driver.
- */
-
-#ifndef FL_COCOA_WINDOW_DRIVER_H
-#define FL_COCOA_WINDOW_DRIVER_H
-
-#include "../../Fl_Window_Driver.H"
-#include <FL/Fl_Plugin.H>
-#include <ApplicationServices/ApplicationServices.h>
-
-class Fl_Image;
-class Fl_Window;
-#ifdef __OBJC__
-@class CALayer;
-@class NSCursor;
-@class NSImage;
-@class FLWindow;
-@class NSOpenGLContext;
-@class NSOpenGLPixelFormat;
-@class NSView;
-@class NSWindow;
-#else
-class CALayer;
-class NSCursor;
-class NSImage;
-class FLWindow;
-class NSOpenGLContext;
-class NSOpenGLPixelFormat;
-class NSView;
-class NSWindow;
-#endif // __OBJC__
-
-/**
- \cond DriverDev
- \addtogroup DriverDeveloper
- \{
- */
-
-/*
- Move everything here that manages the native window interface.
-
- There is one window driver for each Fl_Window. Window drivers manage window
- actions such as resizing, events, decoration, fullscreen modes, etc. . All
- drawing and rendering is managed by the Surface device and the associated
- graphics driver.
-
- - window specific event handling
- - window types and styles, depth, etc.
- - decorations
-
- ? where do we handle the interface between OpenGL/DirectX and Cocoa/Windows/Glx?
- */
-
-/**
- \}
- \endcond
- */
-
-
-class Fl_Cocoa_Window_Driver : public Fl_Window_Driver
-{
-private:
- struct shape_data_type {
- Fl_Image* shape_; ///< shape image
- CGImageRef mask;
- } *shape_data_;
- void shape_bitmap_(Fl_Image* b);
- void shape_alpha_(Fl_Image* img, int offset) FL_OVERRIDE;
- CGRect* subRect_; // makes sure subwindow remains inside its parent window
- // stores 3 binary flags: whether window is mapped to retina display; whether resolution just changed;
- // whether window's view received the [FLView view_did_resize] message
- unsigned window_flags_;
-public:
- Fl_Cocoa_Window_Driver(Fl_Window*);
- ~Fl_Cocoa_Window_Driver();
- static inline Fl_Cocoa_Window_Driver* driver(const Fl_Window *w) {return (Fl_Cocoa_Window_Driver*)Fl_Window_Driver::driver(w);}
- CGContextRef gc; // graphics context
- NSCursor *cursor;
- static void q_release_context(Fl_Cocoa_Window_Driver *x = 0); // free all resources associated with gc
- static CGImageRef capture_decorated_window_10_5(NSWindow *nswin);
- void set_key_window();
- bool mapped_to_retina(); // is window mapped to retina display?
- void mapped_to_retina(bool); // sets whether window is mapped to retina display
- bool changed_resolution(); // did window just moved to display with another resolution?
- void changed_resolution(bool);// sets whether window just moved to display with another resolution
- bool view_resized(); // did window's view receive [FLView view_did_resize] message?
- void view_resized(bool b); // sets whether window's view received [FLView view_did_resize] message
- bool through_resize(); // did Fl_Window::resize() run already
- void through_resize(bool b); // set whether Fl_Window::resize() run already
- CGRect* subRect() { return subRect_; } // getter
- void subRect(CGRect *r) { subRect_ = r; } // setter
- static void destroy(FLWindow*);
- CGImageRef CGImage_from_window_rect(int x, int y, int w, int h, bool capture_subwins = true);
-
- // --- window data
- int decorated_w() FL_OVERRIDE;
- int decorated_h() FL_OVERRIDE;
- const Fl_Image* shape() FL_OVERRIDE;
-
- // --- window management
- void makeWindow() FL_OVERRIDE;
- void take_focus() FL_OVERRIDE;
- void flush() FL_OVERRIDE;
- void flush_overlay() FL_OVERRIDE;
- void draw_begin() FL_OVERRIDE;
- void draw_end() FL_OVERRIDE;
- void make_current() FL_OVERRIDE;
- void label(const char *name, const char *mininame) FL_OVERRIDE;
- void show() FL_OVERRIDE;
- void resize(int X,int Y,int W,int H) FL_OVERRIDE;
- void hide() FL_OVERRIDE;
- void map() FL_OVERRIDE;
- void unmap() FL_OVERRIDE;
- void fullscreen_on() FL_OVERRIDE;
- void fullscreen_off(int X, int Y, int W, int H) FL_OVERRIDE;
- void fullscreen_screens(bool on_off) FL_OVERRIDE;
- void maximize() FL_OVERRIDE;
- void un_maximize() FL_OVERRIDE;
- void use_border() FL_OVERRIDE;
- void size_range() FL_OVERRIDE;
- void iconize() FL_OVERRIDE;
- void decoration_sizes(int *top, int *left, int *right, int *bottom) FL_OVERRIDE;
- // --- window cursor stuff
- int set_cursor(Fl_Cursor) FL_OVERRIDE;
- int set_cursor(const Fl_RGB_Image*, int, int) FL_OVERRIDE;
-
- void shape(const Fl_Image* img) FL_OVERRIDE;
- // next 4 are in Fl_cocoa.mm because they use Objective-c
- void capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) FL_OVERRIDE;
- void wait_for_expose() FL_OVERRIDE;
- void draw_titlebar_to_context(CGContextRef gc, int w, int h);
- 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) FL_OVERRIDE;
-
- //icons
- void icons(const Fl_RGB_Image *icons[], int count) FL_OVERRIDE;
- NSImage *icon_image;
-
- fl_uintptr_t os_id() FL_OVERRIDE;
-};
-
-class Fl_Cocoa_Plugin : public Fl_Plugin {
-public:
- Fl_Cocoa_Plugin(const char *pluginName) : Fl_Plugin(klass(), pluginName) { }
- virtual const char *klass() { return "fltk:cocoa"; }
- virtual const char *name() = 0;
- virtual void resize(Fl_Gl_Window *glw, int x, int y, int w, int h) = 0;
-};
-
-#endif // FL_COCOA_WINDOW_DRIVER_H
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
deleted file mode 100644
index 55d1bea32..000000000
--- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
+++ /dev/null
@@ -1,294 +0,0 @@
-//
-// Definition of Apple Cocoa window driver.
-//
-// Copyright 1998-2026 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>
-#include "Fl_Cocoa_Window_Driver.H"
-#include "../../Fl_Screen_Driver.H"
-#include "../Quartz/Fl_Quartz_Graphics_Driver.H"
-#include <FL/Fl_Double_Window.H>
-#include <FL/Fl_Overlay_Window.H>
-#include <FL/Fl_Image_Surface.H>
-#include <FL/fl_draw.H>
-#include <FL/Fl.H>
-#include <FL/platform.H>
-#include <math.h>
-
-
-Fl_Cocoa_Window_Driver::Fl_Cocoa_Window_Driver(Fl_Window *win)
-: Fl_Window_Driver(win)
-{
- cursor = nil;
- window_flags_ = 0;
- icon_image = NULL;
- screen_num_ = 0;
- shape_data_ = NULL;
-}
-
-
-void Fl_Cocoa_Window_Driver::take_focus()
-{
- set_key_window();
-}
-
-
-void Fl_Cocoa_Window_Driver::flush_overlay()
-{
- Fl_Overlay_Window *oWindow = pWindow->as_overlay_window();
- int erase_overlay = (pWindow->damage()&FL_DAMAGE_OVERLAY) | (overlay() == oWindow);
- pWindow->clear_damage((uchar)(pWindow->damage()&~FL_DAMAGE_OVERLAY));
-
- if (!oWindow->shown()) return;
- pWindow->make_current(); // make sure fl_gc is non-zero
- if (!other_xid) {
- other_xid = new Fl_Image_Surface(oWindow->w(), oWindow->h(), 1);
- oWindow->clear_damage(FL_DAMAGE_ALL);
- }
- if (oWindow->damage() & ~FL_DAMAGE_EXPOSE) {
- Fl_X *myi = Fl_X::flx(pWindow);
- fl_clip_region(myi->region); myi->region = 0;
- Fl_Surface_Device::push_current(other_xid);
- draw();
- Fl_Surface_Device::pop_current();
- }
- if (erase_overlay) fl_clip_region(0);
- fl_copy_offscreen(0, 0, oWindow->w(), oWindow->h(), other_xid->offscreen(), 0, 0);
- if (overlay() == oWindow) oWindow->draw_overlay();
-}
-
-
-void Fl_Cocoa_Window_Driver::draw_begin()
-{
- if (!Fl_Surface_Device::surface()->driver()->has_feature(Fl_Graphics_Driver::NATIVE)) return;
- CGContextRef my_gc = (CGContextRef)Fl_Surface_Device::surface()->driver()->gc();
- if (shape_data_) {
- if (shape_data_->mask) {
- CGContextClipToMask(my_gc, CGRectMake(0,0,w(),h()), shape_data_->mask); // requires Mac OS 10.4
- }
- CGContextSaveGState(my_gc);
- }
-}
-
-
-void Fl_Cocoa_Window_Driver::draw_end()
-{
- if (Fl_Surface_Device::surface()->driver()->has_feature(Fl_Graphics_Driver::NATIVE)) {
- CGContextRef my_gc = (CGContextRef)Fl_Surface_Device::surface()->driver()->gc();
- if (shape_data_) CGContextRestoreGState(my_gc);
- }
-}
-
-
-
-static void MyProviderReleaseData (void *info, const void *data, size_t size) {
- delete[] (uchar*)data;
-}
-
-// bitwise inversion of all 4-bit quantities
-static const unsigned char swapped[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
-
-static inline uchar swap_byte(const uchar b) {
- // reverse the order of bits of byte b: 1->8 becomes 8->1
- return (swapped[b & 0xF] << 4) | swapped[b >> 4];
-}
-
-
-void Fl_Cocoa_Window_Driver::shape_bitmap_(Fl_Image* b) {
- shape_data_->shape_ = b;
- if (b) {
- // complement mask bits and perform bitwise inversion of all bytes and also reverse top and bottom
- int bytes_per_row = (b->w() + 7)/8;
- uchar *from = new uchar[bytes_per_row * b->h()];
- for (int i = 0; i < b->h(); i++) {
- uchar *p = (uchar*)(*b->data()) + bytes_per_row * i;
- uchar *last = p + bytes_per_row;
- uchar *q = from + (b->h() - 1 - i) * bytes_per_row;
- while (p < last) {
- *q++ = swap_byte(~*p++);
- }
- }
- CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, from, bytes_per_row * b->h(), MyProviderReleaseData);
- shape_data_->mask = CGImageMaskCreate(b->w(), b->h(), 1, 1, bytes_per_row, provider, NULL, false);
- CFRelease(provider);
- }
-}
-
-
-void Fl_Cocoa_Window_Driver::shape_alpha_(Fl_Image* img, int offset) {
- int i, d = img->d(), w = img->w(), h = img->h();
- shape_data_->shape_ = img;
- if (shape_data_->shape_) {
- // reverse top and bottom and convert to gray scale if img->d() == 3 and complement bits
- int bytes_per_row = w * d;
- uchar *from = new uchar[w * h];
- for ( i = 0; i < h; i++) {
- uchar *p = (uchar*)(*img->data()) + bytes_per_row * i + offset;
- uchar *last = p + bytes_per_row;
- uchar *q = from + (h - 1 - i) * w;
- while (p < last) {
- if (d == 3) {
- unsigned u = *p++;
- u += *p++;
- u += *p++;
- *q++ = ~(u/3);
- }
- else {
- *q++ = ~(*p);
- p += d;
- }
- }
- }
- CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, from, w * h, MyProviderReleaseData);
- shape_data_->mask = CGImageMaskCreate(w, h, 8, 8, w, provider, NULL, false);
- CFRelease(provider);
- }
-}
-
-
-void Fl_Cocoa_Window_Driver::shape(const Fl_Image* img) {
- if (shape_data_) {
- if (shape_data_->mask) { CGImageRelease(shape_data_->mask); }
- }
- else {
- shape_data_ = new shape_data_type;
- }
- memset(shape_data_, 0, sizeof(shape_data_type));
- int d = img->d();
- if (d && img->count() >= 2) {
- shape_pixmap_((Fl_Image*)img);
- shape_data_->shape_ = (Fl_Image*)img;
- }
- else if (d == 0) shape_bitmap_((Fl_Image*)img);
- else if (d == 2 || d == 4) shape_alpha_((Fl_Image*)img, d - 1);
- else if ((d == 1 || d == 3) && img->count() == 1) shape_alpha_((Fl_Image*)img, 0);
- pWindow->border(false);
-}
-
-
-void Fl_Cocoa_Window_Driver::hide() {
- Fl_X* ip = Fl_X::flx(pWindow);
- // MacOS X manages a single pointer per application. Make sure that hiding
- // a toplevel window will not leave us with some random pointer shape, or
- // worst case, an invisible pointer
- if (ip && !parent()) pWindow->cursor(FL_CURSOR_DEFAULT);
- if ( hide_common() ) return;
- q_release_context(this);
- if ( ip->xid == (fl_uintptr_t)fl_window )
- fl_window = 0;
- if (ip->region) Fl_Graphics_Driver::default_driver().XDestroyRegion(ip->region);
- destroy((FLWindow*)ip->xid);
- delete subRect();
- delete ip;
-}
-
-
-int Fl_Cocoa_Window_Driver::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)
-{
- if ( (src_x < 0) || (src_y < 0) )
- return 1;
- if ( (src_x+src_w > pWindow->w()) || (src_y+src_h > pWindow->h()) )
- return 1;
- CGImageRef img = CGImage_from_window_rect(src_x, src_y, src_w, src_h);
- if (!img)
- return 1;
- // the current surface is generally the display, but is an Fl_Image_Surface when scrolling an Fl_Overlay_Window
- Fl_Quartz_Graphics_Driver *qgd = (Fl_Quartz_Graphics_Driver*)Fl_Surface_Device::surface()->driver();
- float s = qgd->scale();
- qgd->draw_CGImage(img, dest_x, dest_y, (int)lround(s*src_w), (int)lround(s*src_h), 0, 0, src_w, src_h);
- CFRelease(img);
- return 0;
-}
-
-static const unsigned mapped_mask = 1;
-static const unsigned changed_mask = 2;
-static const unsigned view_resized_mask = 4;
-static const unsigned through_resize_mask = 8;
-
-bool Fl_Cocoa_Window_Driver::mapped_to_retina() {
- return window_flags_ & mapped_mask;
-}
-
-void Fl_Cocoa_Window_Driver::mapped_to_retina(bool b) {
- if (b) window_flags_ |= mapped_mask;
- else window_flags_ &= ~mapped_mask;
-}
-
-bool Fl_Cocoa_Window_Driver::changed_resolution() {
- return window_flags_ & changed_mask;
-}
-
-void Fl_Cocoa_Window_Driver::changed_resolution(bool b) {
- if (b) window_flags_ |= changed_mask;
- else window_flags_ &= ~changed_mask;
-}
-
-bool Fl_Cocoa_Window_Driver::view_resized() {
- return window_flags_ & view_resized_mask;
-}
-
-void Fl_Cocoa_Window_Driver::view_resized(bool b) {
- if (b) window_flags_ |= view_resized_mask;
- else window_flags_ &= ~view_resized_mask;
-}
-
-bool Fl_Cocoa_Window_Driver::through_resize() {
- return window_flags_ & through_resize_mask;
-}
-
-void Fl_Cocoa_Window_Driver::through_resize(bool b) {
- if (b) window_flags_ |= through_resize_mask;
- else window_flags_ &= ~through_resize_mask;
-}
-
-const Fl_Image* Fl_Cocoa_Window_Driver::shape() {
- return shape_data_ ? shape_data_->shape_ : NULL;
-}
-
-/* Returns images of the capture of the window title-bar.
- On the Mac OS platform, left, bottom and right are returned NULL; top is returned with depth 4.
- */
-void Fl_Cocoa_Window_Driver::capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right)
-{
- top = left = bottom = right = NULL;
- int htop, hleft, hright, hbottom;
- Fl_Cocoa_Window_Driver::decoration_sizes(&htop, &hleft, &hright, &hbottom);
- if (htop == 0) return; // when window is fullscreen
- CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
- float s = Fl::screen_driver()->scale(screen_num());
- int scaled_w = int(w() * s);
- const int factor = (mapped_to_retina() ? 2 : 1);
- int data_w = factor * scaled_w, data_h = factor * htop;
- uchar *rgba = new uchar[4 * data_w * data_h];
- CGContextRef auxgc = CGBitmapContextCreate(rgba, data_w, data_h, 8, 4 * data_w, cspace, kCGImageAlphaPremultipliedLast);
- CGColorSpaceRelease(cspace);
- CGContextClearRect(auxgc, CGRectMake(0,0,data_w,data_h));
- CGContextScaleCTM(auxgc, factor, factor);
- draw_titlebar_to_context(auxgc, scaled_w, htop);
- top = new Fl_RGB_Image(rgba, data_w, data_h, 4);
- top->alloc_array = 1;
- top->scale(w(),htop, s <1 ? 0 : 1, 1);
- CGContextRelease(auxgc);
-}
-
-
-FLWindow *fl_mac_xid(const Fl_Window *win) {
- return (FLWindow*)Fl_Window_Driver::xid(win);
-}
-
-
-Fl_Window *fl_mac_find(FLWindow *xid) {
- return Fl_Window_Driver::find((fl_uintptr_t)xid);
-}
diff --git a/src/drivers/Cocoa/Fl_MacOS_Sys_Menu_Bar_Driver.H b/src/drivers/Cocoa/Fl_MacOS_Sys_Menu_Bar_Driver.H
deleted file mode 100644
index 2de8bde64..000000000
--- a/src/drivers/Cocoa/Fl_MacOS_Sys_Menu_Bar_Driver.H
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Definition of class Fl_MacOS_Sys_Menu_Bar_Driver for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2017 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
-//
-
-#ifndef Fl_MacOS_Sys_Menu_Bar_Driver_H
-#define Fl_MacOS_Sys_Menu_Bar_Driver_H
-
-#include "../../Fl_Sys_Menu_Bar_Driver.H"
-
-class Fl_MacOS_Sys_Menu_Bar_Driver : public Fl_Sys_Menu_Bar_Driver {
-public:
- Fl_Menu_Item *window_menu_items;
- int first_window_menu_item;
- Fl_MacOS_Sys_Menu_Bar_Driver();
- virtual ~Fl_MacOS_Sys_Menu_Bar_Driver();
- void update() FL_OVERRIDE;
- void draw() FL_OVERRIDE;
- void about(Fl_Callback *cb, void *data) FL_OVERRIDE;
- int add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) FL_OVERRIDE;
- int add(const char* str) FL_OVERRIDE;
- int insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) FL_OVERRIDE;
- void menu(const Fl_Menu_Item *m) FL_OVERRIDE;
- void shortcut (int i, int s) FL_OVERRIDE;
- void setonly (Fl_Menu_Item *item) FL_OVERRIDE;
- void clear() FL_OVERRIDE;
- int clear_submenu(int index) FL_OVERRIDE;
- void remove(int index) FL_OVERRIDE;
- void replace(int index, const char *name) FL_OVERRIDE;
- void mode(int i, int fl) FL_OVERRIDE;
- void create_window_menu() FL_OVERRIDE;
- void new_window(Fl_Window *win);
- void remove_window(Fl_Window *win);
- void rename_window(Fl_Window *win);
- static Fl_MacOS_Sys_Menu_Bar_Driver* driver();
- void play_menu(const Fl_Menu_Item *) FL_OVERRIDE;
-};
-
-
-#endif /* Fl_MacOS_Sys_Menu_Bar_Driver_H */