summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl.H13
-rw-r--r--FL/Fl_Gl_Window.H23
-rw-r--r--FL/mac.H9
-rw-r--r--src/Fl.cxx2
-rw-r--r--src/Fl_Gl_Choice.H16
-rw-r--r--src/Fl_Gl_Choice.cxx114
-rw-r--r--src/Fl_Gl_Device_Plugin.cxx34
-rw-r--r--src/Fl_Gl_Window.cxx112
-rw-r--r--src/Fl_cocoa.mm206
-rw-r--r--src/gl_draw.cxx77
-rw-r--r--src/gl_start.cxx7
-rw-r--r--src/glut_compatability.cxx18
-rw-r--r--test/cube.cxx3
-rw-r--r--test/fractals.cxx1
-rw-r--r--test/fullscreen.cxx3
-rw-r--r--test/gl_overlay.cxx5
-rw-r--r--test/glpuzzle.cxx1
-rw-r--r--test/shape.cxx3
18 files changed, 391 insertions, 256 deletions
diff --git a/FL/Fl.H b/FL/Fl.H
index cc223dba8..259e14371 100644
--- a/FL/Fl.H
+++ b/FL/Fl.H
@@ -125,6 +125,9 @@ typedef void (*Fl_Clipboard_Notify_Handler)(int source, void *data);
class FL_EXPORT Fl {
Fl() {}; // no constructor!
+private:
+ static int use_high_res_GL_;
+
public: // should be private!
#ifndef FL_DOXYGEN
static int e_number;
@@ -1206,6 +1209,16 @@ public:
static void release_widget_pointer(Fl_Widget *&w);
static void clear_widget_pointer(Fl_Widget const *w);
/** @} */
+
+ /** sets whether GL windows should be drawn at high resolution on Apple
+ computers with retina displays
+ */
+ static void use_high_res_GL(int val) { use_high_res_GL_ = val; }
+ /** returns whether GL windows should be drawn at high resolution on Apple
+ computers with retina displays.
+ Default is no.
+ */
+ static int use_high_res_GL() { return use_high_res_GL_; }
#ifdef FLTK_HAVE_CAIRO
/** \defgroup group_cairo Cairo support functions and classes
diff --git a/FL/Fl_Gl_Window.H b/FL/Fl_Gl_Window.H
index 47fe04939..7bec39877 100644
--- a/FL/Fl_Gl_Window.H
+++ b/FL/Fl_Gl_Window.H
@@ -89,7 +89,7 @@ public:
\code
void mywindow::draw() {
if (!valid()) {
- glViewport(0,0,w(),h());
+ glViewport(0,0,pixel_w(),pixel_h());
glFrustum(...);
...other initialization...
}
@@ -168,7 +168,8 @@ public:
int mode(int a) {return mode(a,0);}
/** See Fl_Mode mode() const */
int mode(const int *a) {return mode(0, a);}
- /** void See void context(void* v, int destroy_flag) */
+ /** Returns a pointer to the GLContext that this window is using.
+ \see void context(void* v, int destroy_flag) */
void* context() const {return context_;}
void context(void*, int destroy_flag = 0);
void make_current();
@@ -201,6 +202,24 @@ public:
// Note: Doxygen docs in Fl_Widget.H to avoid redundancy.
virtual Fl_Gl_Window* as_gl_window() {return this;}
+#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ int pixel_w();
+ int pixel_h();
+#else
+ /** Gives the window width in OpenGL pixels.
+ Generally identical with the result of the w() function, but on macintosh computers
+ with a 'retina' display, and if Fl::use_high_res_GL(bool) is set to true,
+ pixel_w() returns 2 * w().
+ */
+ int pixel_w() { return w(); }
+ /** Gives the window height in OpenGL pixels.
+ Generally identical with the result of the h() function, but on macintosh computers
+ with a 'retina' display, and if Fl::use_high_res_GL(bool) is set to true,
+ pixel_h() returns 2 * h().
+ */
+ int pixel_h() { return h(); }
+#endif
+
~Fl_Gl_Window();
/**
Creates a new Fl_Gl_Window widget using the given size, and label string.
diff --git a/FL/mac.H b/FL/mac.H
index 85e40c12b..df234710f 100644
--- a/FL/mac.H
+++ b/FL/mac.H
@@ -74,8 +74,10 @@ typedef CGContextRef Fl_Offscreen;
#ifdef __OBJC__
@class NSCursor;
+@class NSOpenGLPixelFormat;
#else
class NSCursor;
+class NSOpenGLPixelFormat;
#endif // __OBJC__
typedef CGContextRef Fl_Offscreen;
@@ -151,6 +153,8 @@ public:
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
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
#endif
// Quartz additions:
CGContextRef gc; // graphics context (NULL when using QD)
@@ -160,6 +164,8 @@ public:
static void q_begin_image(CGRect&, int x, int y, int w, int h);
static void q_end_image();
// Cocoa additions
+ static int resolution_scaling_factor(Fl_Window*);
+ static NSOpenGLPixelFormat *mode_to_NSOpenGLPixelFormat(int mode, const int*); // computes NSOpenGLPixelFormat from Gl window's mode
void destroy(void);
void map(void);
void unmap(void);
@@ -183,7 +189,8 @@ public:
private:
#if FLTK_ABI_VERSION >= 10304
CGRect* subRect_; // makes sure subwindow remains inside its parent window
- unsigned mapped_to_retina_; // stores whether window is mapped to retina display
+ // stores 2 binary flags: whether window is mapped to retina display; whether resolution just changed
+ unsigned mapped_to_retina_;
#else
bool subwindow; // for ABI compatibility, useless with true subwindows
#endif
diff --git a/src/Fl.cxx b/src/Fl.cxx
index b49033716..6b1d8515b 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -2190,7 +2190,7 @@ Fl_Widget_Tracker::~Fl_Widget_Tracker()
Fl::release_widget_pointer(wp_); // remove pointer from watch list
}
-
+int Fl::use_high_res_GL_ = 0;
//
// End of "$Id$".
//
diff --git a/src/Fl_Gl_Choice.H b/src/Fl_Gl_Choice.H
index caca3ce42..2d5e2fcb9 100644
--- a/src/Fl_Gl_Choice.H
+++ b/src/Fl_Gl_Choice.H
@@ -51,10 +51,16 @@
# include <FL/gl.h>
# define GLContext HGLRC
#elif defined(__APPLE_QUARTZ__)
-// warning: the Quartz version should probably use Core GL (CGL) instead of AGL
# include <OpenGL/gl.h>
-# include <AGL/agl.h>
-# define GLContext AGLContext
+#ifdef __OBJC__
+@class NSOpenGLPixelFormat;
+@class NSOpenGLContext;
+#else
+class NSOpenGLPixelFormat;
+class NSOpenGLContext;
+#endif // __OBJC__
+typedef NSOpenGLContext* FLOpenGLContextPtr;
+# define GLContext FLOpenGLContextPtr
#else
# include <GL/glx.h>
# define GLContext GLXContext
@@ -70,8 +76,7 @@ public:
int pixelformat; // the visual to use
PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing
#elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
- AGLPixelFormat pixelformat;
+ NSOpenGLPixelFormat* pixelformat;
#else
XVisualInfo *vis; // the visual to use
Colormap colormap; // a colormap for that visual
@@ -89,7 +94,6 @@ class Fl_Window;
GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0);
#elif defined(__APPLE_QUARTZ__)
-// warning: the Quartz version should probably use Core GL (CGL) instead of AGL
GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0);
diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx
index 45fbc4bfc..3ed89cee7 100644
--- a/src/Fl_Gl_Choice.cxx
+++ b/src/Fl_Gl_Choice.cxx
@@ -28,8 +28,11 @@
# include <FL/fl_utf8.h>
# ifdef __APPLE__
-# include <ApplicationServices/ApplicationServices.h>
-# include <FL/Fl_Window.H>
+extern NSOpenGLContext* gl_create_context_for_window(NSOpenGLPixelFormat *pixelformat,
+ NSOpenGLContext *shared_ctx, Fl_Window *window);
+extern void gl_context_release(NSOpenGLContext*);
+extern void gl_context_makecurrent(NSOpenGLContext*);
+extern void gl_cleardrawable(void);
# endif
# ifdef WIN32
@@ -108,53 +111,7 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
}
#elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
- const int *blist;
- int list[32];
-
- if (alistp)
- blist = alistp;
- else {
- int n = 0;
- if (m & FL_INDEX) {
- list[n++] = AGL_BUFFER_SIZE;
- list[n++] = 8; // glut tries many sizes, but this should work...
- } else {
- list[n++] = AGL_RGBA;
- list[n++] = AGL_GREEN_SIZE;
- list[n++] = (m & FL_RGB8) ? 8 : 1;
- if (m & FL_ALPHA) {
- list[n++] = AGL_ALPHA_SIZE;
- list[n++] = (m & FL_RGB8) ? 8 : 1;
- }
- if (m & FL_ACCUM) {
- list[n++] = AGL_ACCUM_GREEN_SIZE;
- list[n++] = 1;
- if (m & FL_ALPHA) {
- list[n++] = AGL_ACCUM_ALPHA_SIZE;
- list[n++] = 1;
- }
- }
- }
- if (m & FL_DOUBLE) {
- list[n++] = AGL_DOUBLEBUFFER;
- }
- if (m & FL_DEPTH) {
- list[n++] = AGL_DEPTH_SIZE; list[n++] = 24;
- }
- if (m & FL_STENCIL) {
- list[n++] = AGL_STENCIL_SIZE; list[n++] = 1;
- }
-# ifdef AGL_STEREO
- if (m & FL_STEREO) {
- list[n++] = AGL_STEREO;
- }
-# endif
- list[n] = AGL_NONE;
- blist = list;
- }
- fl_open_display();
- AGLPixelFormat fmt = aglChoosePixelFormat(NULL, 0, (GLint*)blist);
+ NSOpenGLPixelFormat* fmt = Fl_X::mode_to_NSOpenGLPixelFormat(m, alistp);
if (!fmt) return 0;
#elif defined(WIN32)
@@ -216,7 +173,6 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
g->pixelformat = pixelformat;
g->pfd = chosen_pfd;
# elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
g->pixelformat = fmt;
# else
# error unsupported platform
@@ -287,38 +243,13 @@ GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int lay
}
# elif defined(__APPLE_QUARTZ__)
-#if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && __LP64__)
-static CGrafPtr fl_GetWindowPort(WindowRef window)
-{
- typedef CGrafPtr (*wf)(WindowRef);
- static wf f = NULL;
- if ( ! f) f = (wf)Fl_X::get_carbon_function("GetWindowPort");
- return (*f)(window);
-}
-#endif
-// warning: the Quartz version should probably use Core GL (CGL) instead of AGL
GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
GLContext context, shared_ctx = 0;
if (context_list && nContext) shared_ctx = context_list[0];
- context = aglCreateContext( g->pixelformat, shared_ctx);
+ context = gl_create_context_for_window(g->pixelformat, shared_ctx, window);
if (!context) return 0;
add_context((GLContext)context);
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-#if __LP64__
- // 64 bit version
- aglSetWindowRef(context, Fl_X::i(window)->window_ref() );
-#else
- // 32 bit version >= 10.5
- if (aglSetWindowRef != NULL)
- aglSetWindowRef(context, Fl_X::i(window)->window_ref() );
- else
- aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(window)->window_ref() ) );
-#endif
-#else
- // 32 bit version < 10.5
- aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(window)->window_ref() ) );
-#endif
return (context);
}
# else
@@ -337,23 +268,7 @@ void fl_set_gl_context(Fl_Window* w, GLContext context) {
# elif defined(WIN32)
wglMakeCurrent(Fl_X::i(w)->private_dc, context);
# elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-#if __LP64__
- // 64 bit version
- aglSetWindowRef(context, Fl_X::i(w)->window_ref() );
-#else
- // 32 bit version >= 10.5
- if (aglSetWindowRef != NULL)
- aglSetWindowRef(context, Fl_X::i(w)->window_ref() );
- else
- aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(w)->window_ref() ) );
-#endif
-#else
- // 32 bit version < 10.5
- aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(w)->window_ref() ) );
-#endif
- aglSetCurrentContext(context);
+ gl_context_makecurrent(context);
# else
# error unsupported platform
# endif
@@ -368,15 +283,7 @@ void fl_no_gl_context() {
# elif defined(WIN32)
wglMakeCurrent(0, 0);
# elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
- AGLContext ctx = aglGetCurrentContext();
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if (aglSetWindowRef != NULL)
- { if(ctx) aglSetWindowRef(ctx, NULL ); }
- else
-#endif
- if(ctx) aglSetDrawable( ctx, NULL );
- aglSetCurrentContext(0);
+ gl_cleardrawable();
# else
# error unsupported platform
# endif
@@ -389,8 +296,7 @@ void fl_delete_gl_context(GLContext context) {
# elif defined(WIN32)
wglDeleteContext(context);
# elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
- aglDestroyContext( context );
+ gl_context_release(context);
# else
# error unsupported platform
# endif
diff --git a/src/Fl_Gl_Device_Plugin.cxx b/src/Fl_Gl_Device_Plugin.cxx
index ed2889dbe..7475deb60 100644
--- a/src/Fl_Gl_Device_Plugin.cxx
+++ b/src/Fl_Gl_Device_Plugin.cxx
@@ -53,10 +53,13 @@ static Fl_RGB_Image* capture_gl_rectangle(Fl_Gl_Window *glw, int x, int y, int w
{
#if defined(__APPLE__)
const int bytesperpixel = 4;
+ if (Fl_X::resolution_scaling_factor(glw) > 1) {
+ w = 2*w; h = 2*h; x = 2*x; y = 2*y;
+ }
#else
const int bytesperpixel = 3;
#endif
- glw->flush(); // forces a GL redraw necessary for the glpuzzle demo
+ glw->flush(); // forces a GL redraw, necessary for the glpuzzle demo
// Read OpenGL context pixels directly.
// For extra safety, save & restore OpenGL states that are changed
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
@@ -68,7 +71,7 @@ static Fl_RGB_Image* capture_gl_rectangle(Fl_Gl_Window *glw, int x, int y, int w
int mByteWidth = w * bytesperpixel;
mByteWidth = (mByteWidth + 3) & ~3; // Align to 4 bytes
uchar *baseAddress = new uchar[mByteWidth * h];
- glReadPixels(x, glw->h() - (y+h), w, h,
+ glReadPixels(x, glw->pixel_h() - (y+h), w, h,
#if defined(__APPLE__)
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
#else
@@ -85,6 +88,11 @@ static Fl_RGB_Image* capture_gl_rectangle(Fl_Gl_Window *glw, int x, int y, int w
return img;
}
+static void imgProviderReleaseData (void *info, const void *data, size_t size)
+{
+ delete (Fl_RGB_Image *)info;
+}
+
/**
This class will make sure that OpenGL printing/screen capture is available if fltk_gl
was linked to the program
@@ -97,7 +105,27 @@ public:
Fl_Gl_Window *glw = w->as_gl_window();
if (!glw) return 0;
Fl_RGB_Image *img = capture_gl_rectangle(glw, 0, 0, glw->w(), glw->h());
- fl_draw_image(img->array + (glw->h() - 1) * img->ld(), x, y , glw->w(), glw->h(), 3, - img->ld());
+#ifdef __APPLE__
+ if (Fl_Surface_Device::surface()->class_name() == Fl_Printer::class_id) {
+ // convert the image to CGImage, and draw it at full res (useful on retina display)
+ CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB();
+ CGDataProviderRef provider = CGDataProviderCreateWithData(img, img->array, img->ld() * img->h(), imgProviderReleaseData);
+ CGImageRef cgimg = CGImageCreate(img->w(), img->h(), 8, 24, img->ld(), cSpace,
+ (CGBitmapInfo)(kCGImageAlphaNone),
+ provider, NULL, false, kCGRenderingIntentDefault);
+ CGColorSpaceRelease(cSpace);
+ CGDataProviderRelease(provider);
+ CGContextDrawImage(fl_gc, CGRectMake(0, 0, glw->w(), glw->h()), cgimg);
+ CFRelease(cgimg);
+ return 1;
+ } else if (img->w() > glw->w()) {
+ Fl_RGB_Image *img2 = (Fl_RGB_Image*)img->copy(glw->w(), glw->h());
+ delete img;
+ img = img2;
+ }
+#endif
+ int ld = img->ld() ? img->ld() : img->w() * img->d();
+ fl_draw_image(img->array + (img->h() - 1) * ld, x, y , img->w(), img->h(), 3, - ld);
delete img;
return 1;
}
diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx
index f23b8e2ab..d4fdfe5a1 100644
--- a/src/Fl_Gl_Window.cxx
+++ b/src/Fl_Gl_Window.cxx
@@ -26,10 +26,12 @@ extern void gl_texture_reset();
#include <FL/Fl.H>
#include <FL/x.H>
+#include "Fl_Gl_Choice.H"
#ifdef __APPLE__
#include <FL/gl.h>
+extern void gl_context_update(NSOpenGLContext*);
+extern void gl_context_flushbuffer(NSOpenGLContext*);
#endif
-#include "Fl_Gl_Choice.H"
#include <FL/Fl_Gl_Window.H>
#include <stdlib.h>
#include <FL/fl_utf8.h>
@@ -97,6 +99,20 @@ void Fl_Gl_Window::show() {
#endif /* __APPLE__ */
}
+#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+
+int Fl_Gl_Window::pixel_w()
+{
+ return Fl_X::resolution_scaling_factor(this) * w();
+}
+
+int Fl_Gl_Window::pixel_h()
+{
+ return Fl_X::resolution_scaling_factor(this) * h();
+}
+
+#endif
+
/**
The invalidate() method turns off valid() and is
equivalent to calling value(0).
@@ -140,7 +156,6 @@ int Fl_Gl_Window::mode(int m, const int *a) {
show();
}
#elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
redraw();
#else
# error unsupported platform
@@ -163,6 +178,14 @@ int Fl_Gl_Window::mode(int m, const int *a) {
void Fl_Gl_Window::make_current() {
// puts("Fl_Gl_Window::make_current()");
// printf("make_current: context_=%p\n", context_);
+#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ // detect if the window was moved between low and high resolution displays
+ if (Fl_X::i(this)->changed_resolution()){
+ Fl_X::i(this)->changed_resolution(false);
+ invalidate();
+ gl_context_update(context_);
+ }
+#endif
if (!context_) {
mode_ &= ~NON_LOCAL_CONTEXT;
context_ = fl_create_gl_context(this, g);
@@ -170,26 +193,12 @@ void Fl_Gl_Window::make_current() {
context_valid(0);
#ifdef __APPLE__
// resets the pile of string textures used to draw strings
+ // necessary when the context is renewed
gl_texture_reset();
#endif
}
fl_set_gl_context(this, context_);
-#ifdef __APPLE__
- // Set the buffer rectangle here, since in resize() we won't have the
- // correct parent window size to work with...
- GLint xywh[4];
-
- xywh[0] = 0;
- xywh[1] = 0;
- xywh[2] = w();
- xywh[3] = h();
-
- aglSetInteger(context_, AGL_BUFFER_RECT, xywh);
- aglEnable(context_, AGL_BUFFER_RECT);
-// printf("make_current: xywh=[%d %d %d %d]\n", xywh[0], xywh[1], xywh[2], xywh[3]);
-#endif // __APPLE__
-
#if defined(WIN32) && USE_COLORMAP
if (fl_palette) {
fl_GetDC(fl_xid(this));
@@ -219,8 +228,8 @@ void Fl_Gl_Window::ortho() {
GLint v[2];
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, v);
glLoadIdentity();
- glViewport(w()-v[0], h()-v[1], v[0], v[1]);
- glOrtho(w()-v[0], w(), h()-v[1], h(), -1, 1);
+ glViewport(pixel_w()-v[0], pixel_h()-v[1], v[0], v[1]);
+ glOrtho(pixel_w()-v[0], pixel_w(), pixel_h()-v[1], pixel_h(), -1, 1);
#endif
}
@@ -244,7 +253,7 @@ void Fl_Gl_Window::swap_buffers() {
// STR# 2944 [1]
// Save matrixmode/proj/modelview/rasterpos before doing overlay.
//
- int wo=w(), ho=h();
+ int wo=pixel_w(), ho=pixel_h();
GLint matrixmode;
GLfloat pos[4];
glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
@@ -270,8 +279,10 @@ void Fl_Gl_Window::swap_buffers() {
glMatrixMode(matrixmode);
glRasterPos3f(pos[0], pos[1], pos[2]); // restore original glRasterPos
}
- else
+ /* // nothing to do here under Cocoa because [NSOpenGLContext -flushBuffer] done later replaces it
+ else
aglSwapBuffers((AGLContext)context_);
+ */
#else
# error unsupported platform
#endif
@@ -290,19 +301,6 @@ void Fl_Gl_Window::flush() {
uchar save_valid_f = valid_f_;
#endif
-#if defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
- //: clear previous clipping in this shared port
-#if ! __LP64__
-/*GrafPtr port = GetWindowPort( Fl_X::i(this)->window_ref() );
- Rect rect; SetRect( &rect, 0, 0, 0x7fff, 0x7fff );
- GrafPtr old; GetPort( &old );
- SetPort( port );
- ClipRect( &rect );
- SetPort( old );*/
-#endif
-#endif
-
#if HAVE_GL_OVERLAY && defined(WIN32)
// Draw into hardware overlay planes if they are damaged:
@@ -383,22 +381,25 @@ void Fl_Gl_Window::flush() {
glReadBuffer(GL_BACK);
glDrawBuffer(GL_FRONT);
glLoadIdentity();
- glViewport(0, 0, w(), h());
- glOrtho(0, w(), 0, h(), -1, 1);
+ glViewport(0, 0, pixel_w(), pixel_h());
+ glOrtho(0, pixel_w(), 0, pixel_h(), -1, 1);
glRasterPos2i(0,0);
ortho_window = this;
}
- glCopyPixels(0,0,w(),h(),GL_COLOR);
+ glCopyPixels(0,0,pixel_w(),pixel_h(),GL_COLOR);
make_current(); // set current context back to draw overlay
damage1_ = 0;
} else {
- damage1_ = damage();
- clear_damage(0xff); draw();
- swap_buffers();
+ damage1_ = damage();
+ clear_damage(0xff); draw();
+ swap_buffers();
}
}
+#ifdef __APPLE__
+ gl_context_flushbuffer(context_);
+#endif
if (overlay==this && SWAP_TYPE != SWAP) { // fake overlay in front buffer
glDrawBuffer(GL_FRONT);
@@ -423,22 +424,27 @@ void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
// printf("Fl_Gl_Window::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H);
// printf("current: x()=%d, y()=%d, w()=%d, h()=%d\n", x(), y(), w(), h());
- if (W != w() || H != h()) valid(0);
+ int is_a_resize = (W != Fl_Widget::w() || H != Fl_Widget::h());
+ if (is_a_resize) valid(0);
-#ifdef __APPLE__
- if (X != x() || Y != y() || W != w() || H != h()) aglUpdateContext(context_);
-#elif !defined(WIN32)
- if ((W != w() || H != h()) && !resizable() && overlay && overlay != this) {
+#if ! ( defined(__APPLE__) || defined(WIN32) )
+ if (is_a_resize && !resizable() && overlay && overlay != this) {
((Fl_Gl_Window*)overlay)->resize(0,0,W,H);
}
#endif
Fl_Window::resize(X,Y,W,H);
+#ifdef __APPLE__
+ if (is_a_resize) {
+ gl_context_update(context_);
+ redraw();
+ }
+#endif
}
/**
- Returns or sets a pointer to the GLContext that this window is
- using. This is a system-dependent structure, but it is portable to copy
+ Sets a pointer to the GLContext that this window is using.
+ This is a system-dependent structure, but it is portable to copy
the context from one window to another. You can also set it to NULL,
which will force FLTK to recreate the context the next time make_current()
is called, this is useful for getting around bugs in OpenGL implementations.
@@ -540,18 +546,6 @@ void Fl_Gl_Window::draw() {
*/
int Fl_Gl_Window::handle(int event)
{
-#ifdef __APPLE_QUARTZ__
- if (event==FL_HIDE) {
- // if we are not hidden, just the parent was hidden, so we must throw away the context
- if (!visible_r())
- context(0); // remove context without setting the hidden flags
- }
- if (event==FL_SHOW) {
- // if we are not hidden, just the parent was shown, so we must create a new context
- if (visible_r())
- show(); //
- }
-#endif
return Fl_Window::handle(event);
}
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index dbbeda052..2d6fca7a0 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -1107,7 +1107,10 @@ static void position_subwindows(Fl_Window *parent, BOOL is_a_move)
NSRect rchild;
Fl_Window *sub = [child getFl_Window];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- Fl_X::i(sub)->mapped_to_retina( Fl_X::i(parent)->mapped_to_retina() );
+ Fl_X *subx = Fl_X::i(sub);
+ bool previous = subx->mapped_to_retina();
+ subx->mapped_to_retina( Fl_X::i(parent)->mapped_to_retina() );
+ if (previous != subx->mapped_to_retina()) subx->changed_resolution(true);
#endif
rchild.origin = NSMakePoint(pframe.origin.x + sub->x(), pframe.origin.y + parent->h() - (sub->h() + sub->y()));
rchild.size = NSMakeSize(sub->w(), sub->h());
@@ -1143,8 +1146,9 @@ static void compute_mapped_to_retina(Fl_Window *window)
if (fl_mac_os_version >= 100700) { // determine whether window is now mapped to a retina display
Fl_X *flx = Fl_X::i(window);
bool previous = flx->mapped_to_retina();
- NSSize s = [[fl_xid(window) contentView] convertSizeToBacking:NSMakeSize(10, 10)];
+ NSSize s = [[flx->xid contentView] convertSizeToBacking:NSMakeSize(10, 10)];
flx->mapped_to_retina( int(s.width + 0.5) > 10 );
+ if (previous != flx->mapped_to_retina()) flx->changed_resolution(true);
// window needs redrawn when moving from low res to retina
if ((!previous) && flx->mapped_to_retina()) {
window->redraw();
@@ -1152,19 +1156,47 @@ static void compute_mapped_to_retina(Fl_Window *window)
}
}
+#if FLTK_ABI_VERSION >= 10304
+static const unsigned mapped_mask = 1;
+static const unsigned changed_mask = 2;
+#else
+static const unsigned long mapped_mask = 1; // sizeof(unsigned long) = sizeof(Fl_X*)
+static const unsigned long changed_mask = 2;
+#endif
+
bool Fl_X::mapped_to_retina() {
#if FLTK_ABI_VERSION >= 10304
- return (bool)mapped_to_retina_;
+ return mapped_to_retina_ & mapped_mask;
#else
- return xidChildren != NULL;
+ return (unsigned long)xidChildren & mapped_mask;
#endif
}
void Fl_X::mapped_to_retina(bool b) {
#if FLTK_ABI_VERSION >= 10304
- mapped_to_retina_ = b;
+ if (b) mapped_to_retina_ |= mapped;
+ else mapped_to_retina_ &= ~mapped;
+#else
+ if (b) xidChildren = (Fl_X*)((unsigned long)xidChildren | mapped_mask);
+ else xidChildren = (Fl_X*)((unsigned long)xidChildren & ~mapped_mask);
+#endif
+}
+
+bool Fl_X::changed_resolution() {
+#if FLTK_ABI_VERSION >= 10304
+ return mapped_to_retina_ & changed_mask;
#else
- xidChildren = (b ? (Fl_X*)1 : NULL);
+ return (unsigned long)xidChildren & changed_mask;
+#endif
+}
+
+void Fl_X::changed_resolution(bool b) {
+#if FLTK_ABI_VERSION >= 10304
+ if (b) mapped_to_retina_ |= changed_mask;
+ else mapped_to_retina_ &= ~changed_mask;
+#else
+ if (b) xidChildren = (Fl_X*)((unsigned long)xidChildren | changed_mask);
+ else xidChildren = (Fl_X*)((unsigned long)xidChildren & ~changed_mask);
#endif
}
@@ -2162,20 +2194,21 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
cocoaKeyboardHandler(theEvent);
BOOL handled;
NSUInteger mods = [theEvent modifierFlags];
- if ( (mods & NSControlKeyMask) || (mods & NSCommandKeyMask) ) {
+ Fl_Window *w = [(FLWindow*)[theEvent window] getFl_Window];
+ if ( (mods & NSControlKeyMask) || (mods & NSCommandKeyMask) || (w->as_gl_window() && Fl::focus() == w)) {
NSString *s = [theEvent characters];
if ( (mods & NSShiftKeyMask) && (mods & NSCommandKeyMask) ) {
s = [s uppercaseString]; // US keyboards return lowercase letter in s if cmd-shift-key is hit
}
[FLView prepareEtext:s];
Fl::compose_state = 0;
- handled = Fl::handle(FL_KEYBOARD, [(FLWindow*)[theEvent window] getFl_Window]);
+ handled = Fl::handle(FL_KEYBOARD, w);
}
else {
in_key_event = YES;
need_handle = NO;
handled = [self fl_handle_keydown_event:theEvent];
- if (need_handle) handled = Fl::handle(FL_KEYBOARD, [(FLWindow*)[theEvent window] getFl_Window]);
+ if (need_handle) handled = Fl::handle(FL_KEYBOARD, w);
in_key_event = NO;
}
fl_unlock_function();
@@ -2238,8 +2271,13 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
Fl::first_window(window);
cocoaKeyboardHandler(theEvent);
in_key_event = YES;
- need_handle = NO;
- [self fl_handle_keydown_event:theEvent];
+ if (window->as_gl_window() && Fl::focus() == window ) { // ignore text input methods for GL windows
+ need_handle = YES;
+ [FLView prepareEtext:[theEvent characters]];
+ } else {
+ need_handle = NO;
+ [self fl_handle_keydown_event:theEvent];
+ }
if (need_handle) Fl::handle(FL_KEYBOARD, window);
in_key_event = NO;
fl_unlock_function();
@@ -2588,6 +2626,125 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
}
@end
+
+// For Fl_Gl_Window on retina display, returns 2, otherwise 1
+int Fl_X::resolution_scaling_factor(Fl_Window* win)
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ return (win->as_gl_window() && Fl::use_high_res_GL() && win->i->mapped_to_retina()) ? 2 : 1;
+#else
+ return 1;
+#endif
+}
+
+
+NSOpenGLPixelFormat* Fl_X::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++] = (m & FL_RGB8) ? 32 : 1;
+ if (m & FL_ALPHA) {
+ //list[n++] = AGL_ALPHA_SIZE;
+ attribs[n++] = NSOpenGLPFAAlphaSize;
+ attribs[n++] = (m & FL_RGB8) ? 8 : 1;
+ }
+ if (m & FL_ACCUM) {
+ //list[n++] = AGL_ACCUM_GREEN_SIZE; list[n++] = 1;
+ attribs[n++] = NSOpenGLPFAAccumSize;
+ attribs[n++] = 1;
+ if (m & FL_ALPHA) {
+ //list[n++] = AGL_ACCUM_ALPHA_SIZE; list[n++] = 1;
+ }
+ }
+ }
+ if (m & FL_DOUBLE) {
+ //list[n++] = AGL_DOUBLEBUFFER;
+ attribs[n++] = NSOpenGLPFADoubleBuffer;
+ }
+ if (m & FL_DEPTH) {
+ //list[n++] = AGL_DEPTH_SIZE; list[n++] = 24;
+ attribs[n++] = NSOpenGLPFADepthSize;
+ attribs[n++] = 24;
+ }
+ if (m & FL_STENCIL) {
+ //list[n++] = AGL_STENCIL_SIZE; list[n++] = 1;
+ attribs[n++] = NSOpenGLPFAStencilSize;
+ attribs[n++] = 1;
+ }
+ if (m & FL_STEREO) {
+ //list[n++] = AGL_STEREO;
+ attribs[n++] = NSOpenGLPFAStereo;
+ }
+ if (m & FL_MULTISAMPLE) {
+ attribs[n++] = NSOpenGLPFAMultisample,
+ attribs[n++] = NSOpenGLPFASampleBuffers; attribs[n++] = 1;
+ attribs[n++] = NSOpenGLPFASamples; attribs[n++] = 4;
+ }
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (fl_mac_os_version >= 100700) {
+ attribs[n++] = NSOpenGLPFAOpenGLProfile;
+ attribs[n++] = NSOpenGLProfileVersionLegacy;
+ }
+#endif
+ } else {
+ while (alistp[n] && n < 30) {
+ attribs[n] = alistp[n];
+ n++;
+ }
+ }
+ attribs[n] = 0;
+ NSOpenGLPixelFormat *pixform = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
+ /*GLint color,alpha,accum,depth;
+ [pixform getValues:&color forAttribute:NSOpenGLPFAColorSize forVirtualScreen:0];
+ [pixform getValues:&alpha forAttribute:NSOpenGLPFAAlphaSize forVirtualScreen:0];
+ [pixform getValues:&accum forAttribute:NSOpenGLPFAAccumSize forVirtualScreen:0];
+ [pixform getValues:&depth forAttribute:NSOpenGLPFADepthSize forVirtualScreen:0];
+ NSLog(@"color=%d alpha=%d accum=%d depth=%d",color,alpha,accum,depth);*/
+ return pixform;
+}
+
+NSOpenGLContext* gl_create_context_for_window(NSOpenGLPixelFormat *pixelformat,
+ NSOpenGLContext *shared_ctx, Fl_Window *window)
+{
+ NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixelformat shareContext:shared_ctx];
+ if (context) [context setView:[fl_xid(window) contentView]];
+ return context;
+}
+
+void gl_context_update(NSOpenGLContext* ctxt)
+{
+ [ctxt update];
+}
+
+void gl_context_flushbuffer(NSOpenGLContext* ctxt)
+{
+ [ctxt flushBuffer];
+}
+
+void gl_context_release(NSOpenGLContext* ctxt)
+{
+ [ctxt release];
+}
+
+void gl_cleardrawable(void)
+{
+ [[NSOpenGLContext currentContext] clearDrawable];
+}
+
+void gl_context_makecurrent(NSOpenGLContext* ctxt)
+{
+ [ctxt makeCurrentContext];
+}
+
void Fl_Window::fullscreen_x() {
_set_fullscreen();
/* On OS X < 10.6, it is necessary to recreate the window. This is done
@@ -2610,15 +2767,19 @@ void Fl_Window::fullscreen_off_x(int X, int Y, int W, int H) {
*/
void Fl_X::flush()
{
- if (through_drawRect || w->as_gl_window()) {
- make_current_counts = 1;
- w->flush();
- make_current_counts = 0;
- Fl_X::q_release_context();
+ if (through_drawRect) {
+ if (w->as_gl_window()) {
+ w->flush();
+ } else {
+ make_current_counts = 1;
+ w->flush();
+ make_current_counts = 0;
+ Fl_X::q_release_context();
+ }
return;
}
// have Cocoa immediately redraw the window's view
- FLView *view = (FLView*)[fl_xid(w) contentView];
+ FLView *view = (FLView*)[xid contentView];
fl_x_to_redraw = this;
[view setNeedsDisplay:YES];
// will send the drawRect: message to the window's view after having prepared the adequate NSGraphicsContext
@@ -2717,6 +2878,7 @@ void Fl_X::make(Fl_Window* w)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (w->parent()) x->mapped_to_retina( w->top_window()->i->mapped_to_retina() );
else x->mapped_to_retina(false);
+ x->changed_resolution(false);
#endif
NSRect crect;
@@ -2781,6 +2943,11 @@ void Fl_X::make(Fl_Window* w)
Fl_X::first = x;
}
FLView *myview = [[FLView alloc] initWithFrame:crect];
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (w->as_gl_window() && fl_mac_os_version >= 100700 && Fl::use_high_res_GL()) {
+ [myview setWantsBestResolutionOpenGLSurface:YES];
+ }
+#endif
[cw setContentView:myview];
[myview release];
[cw setLevel:winlevel];
@@ -2835,6 +3002,10 @@ void Fl_X::make(Fl_Window* w)
FLWindow *pxid = fl_xid(w->top_window());
[pxid makeFirstResponder:[pxid contentView]];
} else {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ compute_mapped_to_retina(w);
+ x->changed_resolution(false);
+#endif
[cw makeKeyAndOrderFront:nil];
}
@@ -3928,6 +4099,7 @@ static void write_bitmap_inside(NSBitmapImageRep *to, int to_width, NSBitmapImag
static NSBitmapImageRep* GL_rect_to_nsbitmap(Fl_Window *win, int x, int y, int w, int h)
// captures a rectangle from a GL window and returns it as an allocated NSBitmapImageRep
+// the capture has high res on retina
{
Fl_Plugin_Manager pm("fltk:device");
Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org");
diff --git a/src/gl_draw.cxx b/src/gl_draw.cxx
index 0fc339d56..315e11d72 100644
--- a/src/gl_draw.cxx
+++ b/src/gl_draw.cxx
@@ -36,9 +36,9 @@
#include "Xutf8.h"
#endif
-#if USE_XFT
-//extern XFontStruct* fl_xxfont();
-#endif // USE_XFT
+#ifdef __APPLE__
+static int gl_scale = 1; // set to 2 for high resolution Fl_Gl_Window
+#endif
/** Returns the current font's height */
int gl_height() {return fl_height();}
@@ -53,11 +53,8 @@ double gl_width(uchar c) {return fl_width(c);}
static Fl_Font_Descriptor *gl_fontsize;
-#define GL_DRAW_USES_TEXTURES (defined(__APPLE__) && !__ppc__) // 1 only for non-PPC OSX
#ifndef __APPLE__
# define USE_OksiD_style_GL_font_selection 1 // Most hosts except OSX
-#else
-# undef USE_OksiD_style_GL_font_selection // OSX
#endif
#if USE_XFT
@@ -70,7 +67,7 @@ static Fl_Font_Descriptor *gl_fontsize;
void gl_font(int fontid, int size) {
fl_font(fontid, size);
Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor();
-#if !GL_DRAW_USES_TEXTURES
+#ifndef __APPLE__
if (!fl_fontsize->listbase) {
#ifdef USE_OksiD_style_GL_font_selection
@@ -97,28 +94,12 @@ void gl_font(int fontid, int size) {
fl_fontsize->listbase = glGenLists(256);
wglUseFontBitmaps(fl_gc, base, count, fl_fontsize->listbase+base);
SelectObject(fl_gc, oldFid);
-# elif defined(__APPLE_QUARTZ__)
-//AGL is not supported for use in 64-bit applications:
-//http://developer.apple.com/mac/library/documentation/Carbon/Conceptual/Carbon64BitGuide/OtherAPIChanges/OtherAPIChanges.html
- short font, face, size;
- uchar fn[256];
- const char *pname = Fl::get_font_name(fontid, NULL);
- fn[0]=strlen(pname);
- strcpy((char*)(fn+1), pname);
- GetFNum(fn, &font);
- face = 0;
- size = fl_fontsize->size;
- fl_fontsize->listbase = glGenLists(256);
- aglUseFont(aglGetCurrentContext(), font, face,
- size, 0, 256, fl_fontsize->listbase);
-# else
-# error unsupported platform
# endif
#endif // USE_OksiD_style_GL_font_selection
}
glListBase(fl_fontsize->listbase);
-#endif // !GL_DRAW_USES_TEXTURES
+#endif // !__APPLE__
gl_fontsize = fl_fontsize;
}
@@ -143,8 +124,6 @@ static void get_list(int r) {
HFONT oldFid = (HFONT)SelectObject(fl_gc, gl_fontsize->fid);
wglUseFontBitmapsW(fl_gc, ii, ii + 0x03ff, gl_fontsize->listbase+ii);
SelectObject(fl_gc, oldFid);
-#elif defined(__APPLE_QUARTZ__)
-// handled by textures
#else
# error unsupported platform
#endif
@@ -189,7 +168,7 @@ void gl_remove_displaylist_fonts()
#endif
}
-#if GL_DRAW_USES_TEXTURES
+#if __APPLE__
static void gl_draw_textures(const char* str, int n);
#endif
@@ -200,14 +179,8 @@ static void gl_draw_textures(const char* str, int n);
*/
void gl_draw(const char* str, int n) {
#ifdef __APPLE__
-
-#if GL_DRAW_USES_TEXTURES
gl_draw_textures(str, n);
#else
- glCallLists(n, GL_UNSIGNED_BYTE, str);
-#endif
-
-#else
static xchar *buf = NULL;
static int l = 0;
int wn = fl_utf8toUtf16(str, n, (unsigned short*)buf, l);
@@ -284,11 +257,13 @@ void gl_draw(
const char* str, // the (multi-line) string
int x, int y, int w, int h, // bounding box
Fl_Align align) {
- fl_draw(str, x, -y-h, w, h, align, gl_draw_invert);
+ fl_draw(str, x, -y-h, w, h, align, gl_draw_invert, NULL, 0);
}
/** Measure how wide and tall the string will be when drawn by the gl_draw() function */
-void gl_measure(const char* str, int& x, int& y) {fl_measure(str,x,y);}
+void gl_measure(const char* str, int& x, int& y) {
+ fl_measure(str,x,y,0);
+}
/**
Outlines the given rectangle with the current color.
@@ -350,9 +325,9 @@ void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) {
glDrawPixels(w,h,d<4?GL_RGB:GL_RGBA,GL_UNSIGNED_BYTE,(const ulong*)b);
}
-#if GL_DRAW_USES_TEXTURES || defined(FL_DOXYGEN)
+#if __APPLE__ || defined(FL_DOXYGEN)
-#include <FL/glu.h>
+#include <FL/glu.h> // for gluUnProject()
// manages a fifo pile of pre-computed string textures
class gl_texture_fifo {
@@ -364,6 +339,7 @@ private:
Fl_Font_Descriptor *fdesc; // its font
int width; // its width
int height; // its height
+ int scale; // 1 or 2 for low/high resolution
} data;
data *fifo; // array of pile elements
int size_; // pile height
@@ -408,14 +384,14 @@ void gl_texture_fifo::display_texture(int rank)
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glLoadIdentity ();
- float winw = Fl_Window::current()->w();
- float winh = Fl_Window::current()->h();
+ float winw = gl_scale * Fl_Window::current()->w();
+ float winh = gl_scale * Fl_Window::current()->h();
glScalef (2.0f / winw, 2.0f / winh, 1.0f);
glTranslatef (-winw / 2.0f, -winh / 2.0f, 0.0f);
//write the texture on screen
GLfloat pos[4];
glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
- CGRect bounds = CGRectMake (pos[0], pos[1] - fl_descent(), fifo[rank].width, fifo[rank].height);
+ CGRect bounds = CGRectMake (pos[0], pos[1] - gl_scale*fl_descent(), fifo[rank].width, fifo[rank].height);
// GL_COLOR_BUFFER_BIT for glBlendFunc, GL_ENABLE_BIT for glEnable / glDisable
glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
@@ -471,6 +447,9 @@ int gl_texture_fifo::compute_texture(const char* str, int n)
fifo[current].utf8[n] = 0;
fifo[current].width = 0, fifo[current].height = 0;
fl_measure(fifo[current].utf8, fifo[current].width, fifo[current].height, 0);
+ fifo[current].width *= gl_scale;
+ fifo[current].height *= gl_scale;
+ fifo[current].scale = gl_scale;
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
void *base = calloc(4*fifo[current].width, fifo[current].height);
if (base == NULL) return -1;
@@ -481,8 +460,10 @@ int gl_texture_fifo::compute_texture(const char* str, int n)
GLfloat colors[4];
glGetFloatv(GL_CURRENT_COLOR, colors);
fl_color((uchar)(colors[0]*255), (uchar)(colors[1]*255), (uchar)(colors[2]*255));
- fl_draw(str, n, 0, fifo[current].height - fl_descent());
- //put this bitmap in a texture
+ CGContextTranslateCTM(fl_gc, 0, fifo[current].height - gl_scale*fl_descent());
+ CGContextScaleCTM(fl_gc, gl_scale, gl_scale);
+ fl_draw(str, n, 0, 0);
+ //put this bitmap in a texture
glPushAttrib(GL_TEXTURE_BIT);
glBindTexture (GL_TEXTURE_RECTANGLE_EXT, fifo[current].texName);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -502,7 +483,7 @@ int gl_texture_fifo::already_known(const char *str, int n)
int rank;
for ( rank = 0; rank <= last; rank++) {
if ( memcmp(str, fifo[rank].utf8, n) == 0 && fifo[rank].utf8[n] == 0 &&
- fifo[rank].fdesc == gl_fontsize) return rank;
+ fifo[rank].fdesc == gl_fontsize && fifo[rank].scale == gl_scale) return rank;
}
return -1;
}
@@ -512,6 +493,8 @@ static gl_texture_fifo *gl_fifo = NULL; // points to the texture pile class inst
// draws a utf8 string using pre-computed texture if available
static void gl_draw_textures(const char* str, int n)
{
+ gl_scale = Fl_X::resolution_scaling_factor(Fl_Window::current());
+ //fprintf(stderr,"gl_scale=%d\n",gl_scale);
if (! gl_fifo) gl_fifo = new gl_texture_fifo();
if (!gl_fifo->textures_generated) {
for (int i = 0; i < gl_fifo->size_; i++) glGenTextures (1, &(gl_fifo->fifo[i].texName));
@@ -553,17 +536,9 @@ void gl_texture_pile_height(int max)
/** @} */
-#elif defined(__APPLE__)
-// used only if __ppc__
-int gl_texture_pile_height(void) {return 0;}
-void gl_texture_pile_height(int max) {}
-#endif // GL_DRAW_USES_TEXTURES
-#if defined(__APPLE__)
void gl_texture_reset()
{
-#if GL_DRAW_USES_TEXTURES
if (gl_fifo) gl_texture_pile_height(gl_texture_pile_height());
-#endif // GL_DRAW_USES_TEXTURES
}
#endif // __APPLE__
diff --git a/src/gl_start.cxx b/src/gl_start.cxx
index 42ce1ee99..d9e5107b3 100644
--- a/src/gl_start.cxx
+++ b/src/gl_start.cxx
@@ -48,6 +48,7 @@ static Fl_Gl_Choice* gl_choice;
#ifdef __APPLE__
static Fl_Gl_Choice* gl_choice;
+extern void gl_context_update(NSOpenGLContext*);
#endif
Fl_Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx
@@ -61,14 +62,15 @@ void gl_start() {
if (!gl_choice) Fl::gl_visual(0);
context = fl_create_gl_context(Fl_Window::current(), gl_choice);
#elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
context = fl_create_gl_context(Fl_Window::current(), gl_choice);
#else
# error Unsupported platform
#endif
}
fl_set_gl_context(Fl_Window::current(), context);
-#if !defined(WIN32) && !defined(__APPLE__)
+#ifdef __APPLE__
+ gl_context_update(context); // supports window resizing
+#elif !defined(WIN32)
glXWaitX();
#endif
if (pw != Fl_Window::current()->w() || ph != Fl_Window::current()->h()) {
@@ -110,7 +112,6 @@ int Fl::gl_visual(int mode, int *alist) {
#elif defined(WIN32)
gl_choice = c;
#elif defined(__APPLE_QUARTZ__)
- // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
gl_choice = c;
#else
# error Unsupported platform
diff --git a/src/glut_compatability.cxx b/src/glut_compatability.cxx
index eadf43c59..1f1d6a6ff 100644
--- a/src/glut_compatability.cxx
+++ b/src/glut_compatability.cxx
@@ -38,6 +38,9 @@
# include <dlfcn.h>
# endif // HAVE_DLFCN_H
# define MAXWINDOWS 32
+# ifdef __APPLE__
+# include <FL/x.H>
+# endif
static Fl_Glut_Window *windows[MAXWINDOWS+1];
static void (*glut_idle_func)() = 0; // global glut idle function
@@ -59,7 +62,7 @@ static int indraw;
void Fl_Glut_Window::draw() {
glut_window = this;
indraw = 1;
- if (!valid()) {reshape(w(),h()); valid(1);}
+ if (!valid()) {reshape(pixel_w(),pixel_h()); valid(1);}
display();
indraw = 0;
}
@@ -70,7 +73,7 @@ void glutSwapBuffers() {
void Fl_Glut_Window::draw_overlay() {
glut_window = this;
- if (!valid()) {reshape(w(),h()); valid(1);}
+ if (!valid()) {reshape(pixel_w(),pixel_h()); valid(1);}
overlaydisplay();
}
@@ -80,6 +83,13 @@ int Fl_Glut_Window::handle(int event) {
make_current();
int ex = Fl::event_x();
int ey = Fl::event_y();
+#ifdef __APPLE__
+ if (shown()) {
+ int factor = Fl_X::resolution_scaling_factor(this);
+ ex *= factor;
+ ey *= factor;
+ }
+#endif
int button;
switch (event) {
@@ -377,8 +387,8 @@ int glutGet(GLenum type) {
case GLUT_RETURN_ZERO: return 0;
case GLUT_WINDOW_X: return glut_window->x();
case GLUT_WINDOW_Y: return glut_window->y();
- case GLUT_WINDOW_WIDTH: return glut_window->w();
- case GLUT_WINDOW_HEIGHT: return glut_window->h();
+ case GLUT_WINDOW_WIDTH: return glut_window->pixel_w();
+ case GLUT_WINDOW_HEIGHT: return glut_window->pixel_h();
case GLUT_WINDOW_PARENT:
if (glut_window->parent())
return ((Fl_Glut_Window *)(glut_window->parent()))->number;
diff --git a/test/cube.cxx b/test/cube.cxx
index 1fd396e1f..9f4cf0aa6 100644
--- a/test/cube.cxx
+++ b/test/cube.cxx
@@ -94,7 +94,7 @@ void cube_box::draw() {
lasttime = lasttime+speed;
if (!valid()) {
glLoadIdentity();
- glViewport(0,0,w(),h());
+ glViewport(0,0,pixel_w(),pixel_h());
glEnable(GL_DEPTH_TEST);
glFrustum(-1,1,-1,1,2,10000);
glTranslatef(0,0,-10);
@@ -167,6 +167,7 @@ void print_cb(Fl_Widget *w, void *data)
// end of printing demo
int main(int argc, char **argv) {
+ Fl::use_high_res_GL(1);
makeform(argv[0]);
// added to demo printing
form->begin();
diff --git a/test/fractals.cxx b/test/fractals.cxx
index 448edb28b..34d3ef92e 100644
--- a/test/fractals.cxx
+++ b/test/fractals.cxx
@@ -768,6 +768,7 @@ void handlemenu(Fl_Widget*, void *value) {handlemenu(fl_intptr_t(value));}
int main(int argc, char** argv)
{
+ Fl::use_high_res_GL(1);
// glutInit(&argc, argv); // this line removed for FLTK
// create FLTK window:
diff --git a/test/fullscreen.cxx b/test/fullscreen.cxx
index 724ec82f0..0b2ce0e80 100644
--- a/test/fullscreen.cxx
+++ b/test/fullscreen.cxx
@@ -84,7 +84,7 @@ void shape_window::draw() {
valid(1);
// printf("init\n");
glLoadIdentity();
- glViewport(0,0,w(),h());
+ glViewport(0,0,pixel_w(),pixel_h());
}
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(.5,.6,.7);
@@ -267,6 +267,7 @@ int arg(int, char **argv, int &i) {
int main(int argc, char **argv) {
+ Fl::use_high_res_GL(1);
int i=0;
if (Fl::args(argc,argv,i,arg) < argc)
Fl::fatal("Options are:\n -2 = 2 windows\n -f = startup fullscreen\n%s",Fl::help);
diff --git a/test/gl_overlay.cxx b/test/gl_overlay.cxx
index 1c37de625..ab52cc251 100644
--- a/test/gl_overlay.cxx
+++ b/test/gl_overlay.cxx
@@ -57,7 +57,7 @@ void shape_window::draw() {
if (!valid()) {
valid(1);
glLoadIdentity();
- glViewport(0,0,w(),h());
+ glViewport(0,0,pixel_w(),pixel_h());
}
// draw an amazing but slow graphic:
glClear(GL_COLOR_BUFFER_BIT);
@@ -78,7 +78,7 @@ void shape_window::draw_overlay() {
if (!valid()) {
valid(1);
glLoadIdentity();
- glViewport(0,0,w(),h());
+ glViewport(0,0,pixel_w(),pixel_h());
}
// draw an amazing graphic:
gl_color(FL_RED);
@@ -108,6 +108,7 @@ void overlay_sides_cb(Fl_Widget *o, void *p) {
#include <stdio.h>
int main(int argc, char **argv) {
+ Fl::use_high_res_GL(1);
Fl_Window window(300, 370);
shape_window sw(10, 75, window.w()-20, window.h()-90);
diff --git a/test/glpuzzle.cxx b/test/glpuzzle.cxx
index 7fcf9b3c7..e3edfa92b 100644
--- a/test/glpuzzle.cxx
+++ b/test/glpuzzle.cxx
@@ -1416,6 +1416,7 @@ main(int argc, char **argv)
{
long i;
+ Fl::use_high_res_GL(1);
glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
diff --git a/test/shape.cxx b/test/shape.cxx
index 17848e9f9..e45e826b6 100644
--- a/test/shape.cxx
+++ b/test/shape.cxx
@@ -45,7 +45,7 @@ void shape_window::draw() {
if (!valid()) {
valid(1);
glLoadIdentity();
- glViewport(0, 0, w(), h());
+ glViewport(0, 0, pixel_w(), pixel_h());
}
// draw an amazing graphic:
glClear(GL_COLOR_BUFFER_BIT);
@@ -81,6 +81,7 @@ void sides_cb(Fl_Widget *o, void *p) {
int main(int argc, char **argv) {
+ Fl::use_high_res_GL(1);
Fl_Window window(300, 330);
// the shape window could be it's own window, but here we make it