Changed OpenGL support for the Mac OS X platform: use cocoa instead of deprecated AGL.

All changes are mac-specific, except a very minor change in file src/gl_draw.cxx
where string drawing wrongly claimed to support @symbol, not possible
because symbols are drawn using non-GL primitives.

Unchanged application code can use the new FLTK code.
In addition, the new code allows mac applications to draw OpenGL scenes
at high resolution on so-called 'retina' displays, but this requires some
support from app code. They must call, before opening GL windows,
Fl::use_high_resolution(1);
and change their glViewport() calls as follows
glViewport(0, 0, pxel_w(), pixel_h());
This uses 2 new member functions of the Fl_Gl_Window class,
pixel_w() and pixel_h() returning the window dimensions in pixel
units, that is, twice the w() and h() when the window is mapped
on a retina display.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10498 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy
2014-12-20 07:19:23 +00:00
parent a7dc3ea9e2
commit f3a84c0ee5
18 changed files with 391 additions and 256 deletions
+13
View File
@@ -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
+21 -2
View File
@@ -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.
+8 -1
View File
@@ -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
+1 -1
View File
@@ -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$".
//
+10 -6
View File
@@ -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);
+10 -104
View File
@@ -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
+31 -3
View File
@@ -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;
}
+53 -59
View File
@@ -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);
}
+189 -17
View File
@@ -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
xidChildren = (b ? (Fl_X*)1 : NULL);
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
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");
+26 -51
View File
@@ -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,13 +179,7 @@ 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;
@@ -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__
+4 -3
View File
@@ -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
+14 -4
View File
@@ -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;
+2 -1
View File
@@ -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();
+1
View File
@@ -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:
+2 -1
View File
@@ -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);
+3 -2
View File
@@ -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);
+1
View File
@@ -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] == '-') {
+2 -1
View File
@@ -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