diff options
| author | Manolo Gouy <Manolo> | 2015-12-02 09:59:37 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2015-12-02 09:59:37 +0000 |
| commit | 22af09dae7a2e17f0b1253030fd3cb7c6ce92799 (patch) | |
| tree | 9e715f50811df7a6d9a6647a61e289b06371a936 | |
| parent | 30e572985b24eb685e3d9eb0112017c4fc318b4d (diff) | |
Mac OS: support for high resolution OpenGL windows.
Methods Fl::event_x_pixel() and Fl::event_y_pixel() committed at r.10941
are removed. Instead method Fl_Gl_Window::pixels_per_unit() is added.
The documentation explains in more detail how to write cross-platform
FLTK code supporting high resolution OpenGL windows on retina displays.
The examples/OpenGL3test.cxx app exercises Fl_Gl_Window::pixels_per_unit().
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10945 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | CHANGES | 4 | ||||
| -rw-r--r-- | FL/Fl.H | 26 | ||||
| -rw-r--r-- | FL/Fl_Gl_Window.H | 21 | ||||
| -rw-r--r-- | FL/mac.H | 1 | ||||
| -rw-r--r-- | documentation/src/osissues.dox | 21 | ||||
| -rw-r--r-- | examples/OpenGL3test.cxx | 2 | ||||
| -rw-r--r-- | src/Fl.cxx | 15 | ||||
| -rw-r--r-- | src/Fl_Gl_Device_Plugin.cxx | 2 | ||||
| -rw-r--r-- | src/Fl_Gl_Window.cxx | 9 | ||||
| -rw-r--r-- | src/Fl_Group.cxx | 7 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 15 | ||||
| -rw-r--r-- | src/gl_draw.cxx | 2 | ||||
| -rw-r--r-- | src/glut_compatability.cxx | 10 |
13 files changed, 38 insertions, 97 deletions
@@ -34,8 +34,8 @@ CHANGES IN FLTK 1.3.4 RELEASED: ??? ?? ???? (Apple GL library) to draw OpenGL data. Instead, it uses standard cocoa APIs. This allows FLTK to support drawing GL scenes at high resolution when an Fl_Gl_Window is mapped to a 'retina' display. - - Added Fl_Gl_Window::pixel_w(), Fl_Gl_Window::pixel_h(), Fl::event_x_pixel(), - and Fl::event_y_pixel() useful for high resolution OpenGL windows. + - Added Fl_Gl_Window::pixel_w(), Fl_Gl_Window::pixel_h(), and + Fl_Gl_Window::pixels_per_unit() useful for high resolution OpenGL windows. - fl_read_image() now captures all pixels within the rectangle described by its arguments, whether they belong to a GL scene or not (STR #3142). It also captures subwindows of GL windows. @@ -135,9 +135,6 @@ public: // should be private! static int e_y; static int e_x_root; static int e_y_root; -#ifdef __APPLE__ - static Fl_Window *e_window_; -#endif static int e_dx; static int e_dy; static int e_state; @@ -604,29 +601,6 @@ public: event_x(),event_y(). */ static int event_y_root() {return e_y_root;} -#ifdef __APPLE__ - static int event_x_pixel(); - static int event_y_pixel(); -#else - /** Horizontal position in pixels of the mouse event relative to the Fl_Window it was passed to. - Generally identical with Fl::event_x(), but for OpenGL windows of macintosh computers - with a 'retina' display, and if Fl::use_high_res_GL(bool) is set to true, - the returned position, measured in pixels, differs from Fl::event_x(), measured in FLTK units. - \version 1.3.4 - */ - static int event_x_pixel() { - return e_x; - } - /** Vertical position in pixels of the mouse event relative to the Fl_Window it was passed to. - Generally identical with Fl::event_y(), but for OpenGL windows of macintosh computers - with a 'retina' display, and if Fl::use_high_res_GL(bool) is set to true, - the returned position, measured in pixels, differs from Fl::event_y(), measured in FLTK units. - \version 1.3.4 - */ - static int event_y_pixel() { - return e_y; - } -#endif /** Returns the current horizontal mouse scrolling associated with the FL_MOUSEWHEEL event. Right is positive. diff --git a/FL/Fl_Gl_Window.H b/FL/Fl_Gl_Window.H index e8bd11aff..543aa41f3 100644 --- a/FL/Fl_Gl_Window.H +++ b/FL/Fl_Gl_Window.H @@ -229,10 +229,20 @@ public: // Note: Doxygen docs in Fl_Widget.H to avoid redundancy. virtual Fl_Gl_Window* as_gl_window() {return this;} -#if defined(__APPLE__) - int pixel_w(); - int pixel_h(); +#ifdef __APPLE__ + int pixels_per_unit(); #else + /** The number of pixels per FLTK unit of length for the window. + Returns 1, except for a window mapped to + an Apple 'retina' display, and if Fl::use_high_res_GL(bool) is set to true, + when it returns 2. This method dynamically adjusts its value when the window + is moved to/from a retina display. This method is useful, e.g., to convert, + in a window's handle() method, the FLTK units returned by Fl::event_x() and + Fl::event_y() to the pixel units used by the OpenGL source code. + \version 1.3.4 + */ + int pixels_per_unit() { return 1; } +#endif /** Gives the window width in OpenGL pixels. Generally identical with the result of the w() function, but for a window mapped to an Apple 'retina' display, and if Fl::use_high_res_GL(bool) is set to true, @@ -240,7 +250,7 @@ public: between low and high resolution displays and automatically adjusts the returned value. \version 1.3.4 */ - int pixel_w() { return w(); } + int pixel_w() { return pixels_per_unit() * w(); } /** Gives the window height in OpenGL pixels. Generally identical with the result of the h() function, but for a window mapped to an Apple 'retina' display, and if Fl::use_high_res_GL(bool) is set to true, @@ -248,8 +258,7 @@ public: between low and high resolution displays and automatically adjusts the returned value. \version 1.3.4 */ - int pixel_h() { return h(); } -#endif + int pixel_h() { return pixels_per_unit() * h(); } ~Fl_Gl_Window(); /** @@ -181,7 +181,6 @@ 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 static NSOpenGLContext* create_GLcontext_for_window(NSOpenGLPixelFormat *pixelformat, NSOpenGLContext *shared_ctx, Fl_Window *window); static void GLcontext_update(NSOpenGLContext*); diff --git a/documentation/src/osissues.dox b/documentation/src/osissues.dox index 80edb3624..829c3d5e7 100644 --- a/documentation/src/osissues.dox +++ b/documentation/src/osissues.dox @@ -839,16 +839,21 @@ by \verbatim glViewport(0, 0, pixel_w(), pixel_h()); \endverbatim -making use of the Fl_Gl_Window::pixel_w() and Fl_Gl_Window::pixel_h() functions that return the width and height of -the GL scene in pixels: if the Fl_Gl_Window is mapped on a retina display, these functions return twice as much as -reported by Fl_Widget::w() and Fl_Widget::h(); if it's mapped on a regular display, they return the same values as w() and h(). -If you don't call Fl::use_high_res_GL(1), your Fl_Gl_Window 's will be drawn with low resolution. -These functions are synonyms of w() and h() on non-Mac OS X platforms, so your source code remains cross-platform. +making use of the Fl_Gl_Window::pixel_w() and Fl_Gl_Window::pixel_h() methods that return the width and height of +the GL scene in pixels: if the Fl_Gl_Window is mapped on a retina display, these methods return twice as much as +reported by Fl_Widget::w() and Fl_Widget::h(); if it's mapped on a regular display, they return the same values +as w() and h(). These methods dynamically change their values if the window is moved into/out from a retina +display. If Fl::use_high_res_GL(1) is not called, all Fl_Gl_Window 's are drawn at low resolution. +These methods are synonyms of w() and h() on non-Mac OS X platforms, so the source code remains cross-platform. -Fl_Double_Window +The Fl_Gl_Window::pixels_per_unit() method is useful when the OpenGL code depends on the pixel dimension +of the GL scene. This occurs, e.g., if a window's handle() method uses Fl::event_x() and Fl::event_y() +whose returned values should be multiplied by Fl_Gl_Window::pixels_per_unit() to obtain the adequate pixel units. +This method may also be useful, for example, to adjust the width of a line in a high resolution GL scene. -OS X double-buffers all windows automatically. On OS X, -Fl_Window and Fl_Double_Window are handled +\subsection double_window Fl_Double_Window + +OS X double-buffers all windows automatically. On OS X, Fl_Window and Fl_Double_Window are handled internally in the same way. \subsection osissues_mac_files Mac File System Specifics diff --git a/examples/OpenGL3test.cxx b/examples/OpenGL3test.cxx index 8c293f81f..5ce620445 100644 --- a/examples/OpenGL3test.cxx +++ b/examples/OpenGL3test.cxx @@ -149,7 +149,7 @@ public: data[0] *= factor; glBufferSubData(GL_ARRAY_BUFFER, 24*sizeof(GLfloat), 4*sizeof(GLfloat), data); redraw(); - add_output("push Fl::event_x_pixel()=%d Fl::event_y_pixel()=%d\n",Fl::event_x_pixel(), Fl::event_y_pixel()); + add_output("push Fl_Gl_Window::pixels_per_unit()=%d\n", pixels_per_unit()); return 1; } return Fl_Gl_Window::handle(event); diff --git a/src/Fl.cxx b/src/Fl.cxx index 4f4b263fe..357fb55f0 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -86,9 +86,6 @@ Fl_Widget *Fl::belowmouse_, *Fl::pushed_, *Fl::focus_, *Fl::selection_owner_; -#ifdef __APPLE__ -Fl_Window *Fl::e_window_; // the window relative to which Fl::e_x and Fl::e_y are measured -#endif int Fl::damage_, Fl::e_number, Fl::e_x, @@ -1093,9 +1090,6 @@ void fl_fix_focus() { // send a FL_MOVE event so the enter/leave state is up to date Fl::e_x = Fl::e_x_root-fl_xmousewin->x(); Fl::e_y = Fl::e_y_root-fl_xmousewin->y(); -#ifdef __APPLE__ - Fl::e_window_ = fl_xmousewin; -#endif int old_event = Fl::e_number; w->handle(Fl::e_number = FL_MOVE); Fl::e_number = old_event; @@ -1186,19 +1180,10 @@ static int send_event(int event, Fl_Widget* to, Fl_Window* window) { if (w->type()>=FL_WINDOW) {dx -= w->x(); dy -= w->y();} int save_x = Fl::e_x; Fl::e_x += dx; int save_y = Fl::e_y; Fl::e_y += dy; -#ifdef __APPLE__ - Fl_Window *save_e_window = Fl::e_window_; - if (dx || dy) { - Fl::e_window_ = (to->as_window() ? to->as_window() : to->window()); - } -#endif int ret = to->handle(Fl::e_number = event); Fl::e_number = old_event; Fl::e_y = save_y; Fl::e_x = save_x; -#ifdef __APPLE__ - Fl::e_window_ = save_e_window; -#endif return ret; } diff --git a/src/Fl_Gl_Device_Plugin.cxx b/src/Fl_Gl_Device_Plugin.cxx index e9b43d1cf..94c355349 100644 --- a/src/Fl_Gl_Device_Plugin.cxx +++ b/src/Fl_Gl_Device_Plugin.cxx @@ -53,7 +53,7 @@ static Fl_RGB_Image* capture_gl_rectangle(Fl_Gl_Window *glw, int x, int y, int w { #if defined(__APPLE__) const int bytesperpixel = 4; - int factor = Fl_X::resolution_scaling_factor(glw); + int factor = glw->pixels_per_unit(); if (factor > 1) { w *= factor; h *= factor; x *= factor; y *= factor; } diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx index 7fa0a4004..46e7ebbb7 100644 --- a/src/Fl_Gl_Window.cxx +++ b/src/Fl_Gl_Window.cxx @@ -96,14 +96,9 @@ void Fl_Gl_Window::show() { #if defined(__APPLE__) -int Fl_Gl_Window::pixel_w() +int Fl_Gl_Window::pixels_per_unit() { - return Fl_X::resolution_scaling_factor(this) * w(); -} - -int Fl_Gl_Window::pixel_h() -{ - return Fl_X::resolution_scaling_factor(this) * h(); + return (fl_mac_os_version >= 100700 && Fl::use_high_res_GL() && Fl_X::i(this) && Fl_X::i(this)->mapped_to_retina()) ? 2 : 1; } #endif // __APPLE__ diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx index 3ac752613..7b10dc9f3 100644 --- a/src/Fl_Group.cxx +++ b/src/Fl_Group.cxx @@ -105,16 +105,9 @@ static int send(Fl_Widget* o, int event) { } int save_x = Fl::e_x; Fl::e_x -= o->x(); int save_y = Fl::e_y; Fl::e_y -= o->y(); -#ifdef __APPLE__ - Fl_Window *save_e_window = Fl::e_window_; - Fl::e_window_ = o->as_window(); -#endif int ret = o->handle(event); Fl::e_y = save_y; Fl::e_x = save_x; -#ifdef __APPLE__ - Fl::e_window_ = save_e_window; -#endif switch ( event ) { case FL_ENTER: /* FALLTHROUGH */ diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index ed9872f91..02b8e7ce1 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -972,7 +972,6 @@ static void update_e_xy_and_e_xy_root(NSWindow *nsw) { NSPoint pt; pt = [nsw mouseLocationOutsideOfEventStream]; - Fl::e_window_ = [(FLWindow*)nsw getFl_Window]; Fl::e_x = int(pt.x); Fl::e_y = int([[nsw contentView] frame].size.height - pt.y); pt = [NSEvent mouseLocation]; @@ -980,13 +979,6 @@ static void update_e_xy_and_e_xy_root(NSWindow *nsw) Fl::e_y_root = int(main_screen_height - pt.y); } -int Fl::event_x_pixel() { - return e_x * Fl_X::resolution_scaling_factor(Fl::e_window_); -} - -int Fl::event_y_pixel() { - return e_y * Fl_X::resolution_scaling_factor(Fl::e_window_); -} /* * Cocoa Mousewheel handler @@ -2740,13 +2732,6 @@ 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) -{ - return (fl_mac_os_version >= 100700 && win && win->as_gl_window() && Fl::use_high_res_GL() && win->i && win->i->mapped_to_retina()) ? 2 : 1; -} - - NSOpenGLPixelFormat* Fl_X::mode_to_NSOpenGLPixelFormat(int m, const int *alistp) { NSOpenGLPixelFormatAttribute attribs[32]; diff --git a/src/gl_draw.cxx b/src/gl_draw.cxx index 6f88d0637..1c31f4174 100644 --- a/src/gl_draw.cxx +++ b/src/gl_draw.cxx @@ -520,7 +520,7 @@ 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()); + gl_scale = Fl_Window::current()->as_gl_window()->pixels_per_unit(); //fprintf(stderr,"gl_scale=%d\n",gl_scale); if (! gl_fifo) gl_fifo = new gl_texture_fifo(); if (!gl_fifo->textures_generated) { diff --git a/src/glut_compatability.cxx b/src/glut_compatability.cxx index 1f1d6a6ff..9b1f9e6dd 100644 --- a/src/glut_compatability.cxx +++ b/src/glut_compatability.cxx @@ -83,13 +83,9 @@ 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 factor = pixels_per_unit(); + ex *= factor; + ey *= factor; int button; switch (event) { |
