diff options
Diffstat (limited to 'src/drivers/Cocoa')
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.H | 60 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.mm | 527 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Pen_Events.mm | 439 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Printer_Driver.mm | 455 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H | 114 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx | 434 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H | 168 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx | 294 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_MacOS_Sys_Menu_Bar_Driver.H | 51 |
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 */ |
