Skip to content

Commit

Permalink
Implement non-rectangular windows using the Window Driver mechanism.
Browse files Browse the repository at this point in the history
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11336 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
  • Loading branch information
Manolo Gouy authored and Manolo Gouy committed Mar 10, 2016
1 parent 79f79d2 commit d476807
Show file tree
Hide file tree
Showing 19 changed files with 625 additions and 127 deletions.
1 change: 1 addition & 0 deletions FL/Fl_Double_Window.H
Expand Up @@ -41,6 +41,7 @@ class Fl_Overlay_Window;
class FL_EXPORT Fl_Double_Window : public Fl_Window {
protected:
void flush(int eraseoverlay);
Fl_Double_Window(int X, int Y, int W, int H, const char *l, Fl_Window_Driver *driver);
public:
/**
Return non-null if this is an Fl_Overlay_Window object.
Expand Down
47 changes: 8 additions & 39 deletions FL/Fl_Window.H
Expand Up @@ -101,42 +101,6 @@ class FL_EXPORT Fl_Window : public Fl_Group {
// cursor stuff
Fl_Cursor cursor_default;

protected:
/** Data supporting a non-rectangular window shape */
struct shape_data_type {
int lw_; ///< width of shape image
int lh_; ///< height of shape image
Fl_Image* shape_; ///< shape image
#if defined(__APPLE__) // PORTME: Fl_Window_Driver - per-window shape information, move to Fl_X/Fl_Window_Driver
typedef struct CGImage* CGImageRef;
CGImageRef mask;
#elif defined(WIN32)
// not needed
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: define storage for a window mask here if needed"
#else // X11
// not needed
#endif
Fl_Bitmap *todelete_; ///< auxiliary bitmap image
};

shape_data_type *shape_data_; ///< non-null means the window has a non-rectangular shape
private:
void shape_bitmap_(Fl_Image* b);
void shape_alpha_(Fl_Image* img, int offset);
void shape_pixmap_(Fl_Image* pixmap);
public:
void shape(const Fl_Image* img);
/** Set the window's shape with an Fl_Image.
\see void shape(const Fl_Image* img)
*/
inline void shape(const Fl_Image& b) { shape(&b); }
#if defined(WIN32) || defined(__APPLE__) || defined(FL_DOXYGEN) // PORTME: Fl_Window_Driver - per-window shape
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: do you need a combine_mask() function in Fl_Window?"
#else // X11
void combine_mask(void);
#endif
private:

void size_range_();
Expand All @@ -152,7 +116,7 @@ protected:

/** Stores the last window that was made current. See current() const */
static Fl_Window *current_;
virtual void draw();
void draw();
/** Forces the window to be drawn, this window is also made current and calls draw(). */
virtual void flush();

Expand Down Expand Up @@ -180,6 +144,7 @@ protected:

void free_icons();

Fl_Window(int x, int y, int w, int h, const char* title, Fl_Window_Driver *driver);
public:

/**
Expand Down Expand Up @@ -640,9 +605,13 @@ public:
Fl_Window_Driver *driver() { return pWindowDriver; }

/**
Return non-null if this is an Fl_Overlay_Window object.
Return non-null if this is an Fl_Double_Window object.
*/
virtual Fl_Double_Window *as_double_window() {return NULL; }
virtual Fl_Double_Window *as_double_window() {return NULL;}
void shape(const Fl_Image* img);
void shape(const Fl_Image& b) ;
int is_shaped();

};

#endif
Expand Down
9 changes: 8 additions & 1 deletion FL/Fl_Window_Driver.H
Expand Up @@ -28,14 +28,18 @@


class Fl_Window;
class Fl_Image;


/**
\brief A base class for platform specific window handling code.
*/
class FL_EXPORT Fl_Window_Driver {
friend class Fl_Window;
protected:
Fl_Window *pWindow;
struct shape_data_type;
shape_data_type *shape_data_; ///< non-null means the window has a non-rectangular shape
public:
Fl_Window_Driver(Fl_Window *);
virtual ~Fl_Window_Driver();
Expand All @@ -47,7 +51,10 @@ public:
virtual void take_focus() { }
virtual int double_flush(int eraseoverlay);
virtual void destroy_double_buffer();
void draw();
virtual void draw();
void shape_pixmap_(Fl_Image* pixmap);
virtual void shape(const Fl_Image* img) {}
virtual void shape_alpha_(Fl_Image* img, int offset) {}
};


Expand Down
3 changes: 1 addition & 2 deletions FL/fl_draw.H
Expand Up @@ -755,8 +755,7 @@ inline void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int
\returns 1 if true alpha blending supported by platform
\returns 0 not supported so FLTK will use screen door transparency
*/
/* note: doxygen comment here to avoid triplication in os-speciic files */
FL_EXPORT char fl_can_do_alpha_blending();
inline char fl_can_do_alpha_blending() {return Fl_Display_Device::display_device()->driver()->can_do_alpha_blending();}

/**
Reads an RGB(A) image from the current window or off-screen buffer.
Expand Down
1 change: 0 additions & 1 deletion src/CMakeLists.txt
Expand Up @@ -84,7 +84,6 @@ set(CPPFILES
Fl_Window_fullscreen.cxx
Fl_Window_hotspot.cxx
Fl_Window_iconize.cxx
Fl_Window_shape.cxx
Fl_Wizard.cxx
Fl_XBM_Image.cxx
Fl_XPM_Image.cxx
Expand Down
72 changes: 10 additions & 62 deletions src/Fl_Double_Window.cxx
Expand Up @@ -21,7 +21,6 @@

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Overlay_Window.H>
#include <FL/Fl_Printer.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
Expand All @@ -33,14 +32,20 @@


Fl_Double_Window::Fl_Double_Window(int W, int H, const char *l)
: Fl_Window(W,H,l)
: Fl_Window(0, 0, W, H, l, Fl_Window_Driver::newWindowDriver(this))
{
type(FL_DOUBLE_WINDOW);
clear_flag(FORCE_POSITION);
}


Fl_Double_Window::Fl_Double_Window(int X, int Y, int W, int H, const char *l)
: Fl_Window(X,Y,W,H,l)
: Fl_Window(X,Y,W,H,l, Fl_Window_Driver::newWindowDriver(this))
{
type(FL_DOUBLE_WINDOW);
}

Fl_Double_Window::Fl_Double_Window(int x, int y, int w, int h, const char* title, Fl_Window_Driver *driver) : Fl_Window(x,y,w,h,title, driver)
{
type(FL_DOUBLE_WINDOW);
}
Expand All @@ -51,19 +56,9 @@ void Fl_Double_Window::show() {
}


/** see fl_copy_offscreen() */
void Fl_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy)
{
fl_begin_offscreen(pixmap);
uchar *img = fl_read_image(NULL, srcx, srcy, w, h, 0);
fl_end_offscreen();
fl_draw_image(img, x, y, w, h, 3, 0);
delete[] img;
}

char fl_can_do_alpha_blending() {
/*char fl_can_do_alpha_blending() {
return Fl_Display_Device::display_device()->driver()->can_do_alpha_blending();
}
}*/

/**
Forces the window to be redrawn.
Expand Down Expand Up @@ -94,29 +89,6 @@ void Fl_Double_Window::flush(int eraseoverlay) {
}
}

int Fl_Window_Driver::double_flush(int eraseoverlay) {
/* This is a working, platform-independent implementation.
Some platforms may re-implement it for their own logic:
- on Mac OS, the system double buffers all windows, so it is
reimplemented to do the same as Fl_Window::flush(), except for
Fl_Overlay_Window's which fall back on this implementation.
- on Xlib, it is reimplemented if the Xdbe extension is available.
*/
Fl_X *i = Fl_X::i(pWindow);

if (!i->other_xid) {
i->other_xid = fl_create_offscreen(pWindow->w(), pWindow->h());
pWindow->clear_damage(FL_DAMAGE_ALL);
}
if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
fl_clip_region(i->region); i->region = 0;
fl_begin_offscreen(i->other_xid);
fl_graphics_driver->clip_region( 0 );
draw();
fl_end_offscreen();
}
return 0;
}

void Fl_Double_Window::resize(int X,int Y,int W,int H) {
int ow = w();
Expand All @@ -135,16 +107,6 @@ void Fl_Double_Window::hide() {
Fl_Window::hide();
}

void Fl_Window_Driver::destroy_double_buffer() {
Fl_X *i = Fl_X::i(pWindow);
/* This is a working, platform-independent implementation.
Some platforms may re-implement it for their own logic:
- on Xlib, it is reimplemented if the Xdbe extension is available.
*/
fl_delete_offscreen(i->other_xid);
i->other_xid = 0;
}


/**
The destructor <I>also deletes all the children</I>. This allows a
Expand All @@ -156,20 +118,6 @@ Fl_Double_Window::~Fl_Double_Window() {
}


Fl_Overlay_Window::Fl_Overlay_Window(int W, int H, const char *l)
: Fl_Double_Window(W,H,l)
{
overlay_ = 0;
image(0);
}


Fl_Overlay_Window::Fl_Overlay_Window(int X, int Y, int W, int H, const char *l)
: Fl_Double_Window(X,Y,W,H,l)
{
overlay_ = 0;
image(0);
}


//
Expand Down
10 changes: 10 additions & 0 deletions src/Fl_Graphics_Driver.cxx
Expand Up @@ -61,6 +61,16 @@ int Fl_Graphics_Driver::draw_scaled(Fl_Image *img, int X, int Y, int W, int H) {
return 0;
}

/** see fl_copy_offscreen() */
void Fl_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy)
{
fl_begin_offscreen(pixmap);
uchar *img = fl_read_image(NULL, srcx, srcy, w, h, 0);
fl_end_offscreen();
fl_draw_image(img, x, y, w, h, 3, 0);
delete[] img;
}


//
// End of "$Id$".
Expand Down
17 changes: 17 additions & 0 deletions src/Fl_Overlay_Window.cxx
Expand Up @@ -26,6 +26,23 @@
#include <FL/Fl_Overlay_Window.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include <FL/Fl_Window_Driver.H>


Fl_Overlay_Window::Fl_Overlay_Window(int W, int H, const char *l)
: Fl_Double_Window(0,0,W,H,l,Fl_Window_Driver::newWindowDriver(this))
{
overlay_ = 0;
image(0);
clear_flag(FORCE_POSITION);
}

Fl_Overlay_Window::Fl_Overlay_Window(int X, int Y, int W, int H, const char *l)
: Fl_Double_Window(X,Y,W,H,l,Fl_Window_Driver::newWindowDriver(this))
{
overlay_ = 0;
image(0);
}

void Fl_Overlay_Window::show() {
Fl_Double_Window::show();
Expand Down
20 changes: 7 additions & 13 deletions src/Fl_Window.cxx
Expand Up @@ -35,6 +35,7 @@
char *Fl_Window::default_xclass_ = 0L;

void Fl_Window::_Fl_Window() {
cursor_default = FL_CURSOR_DEFAULT;
type(FL_WINDOW);
box(FL_FLAT_BOX);
if (Fl::scheme_bg_) {
Expand All @@ -52,7 +53,6 @@ void Fl_Window::_Fl_Window() {
resizable(0);
size_range_set = 0;
minw = maxw = minh = maxh = 0;
shape_data_ = NULL;
no_fullscreen_x = 0;
no_fullscreen_y = 0;
no_fullscreen_w = w();
Expand All @@ -68,19 +68,22 @@ Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l) :
Fl_Group(X, Y, W, H, l),
pWindowDriver(Fl_Window_Driver::newWindowDriver(this))
{
cursor_default = FL_CURSOR_DEFAULT;
_Fl_Window();
set_flag(FORCE_POSITION);
}

Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l, Fl_Window_Driver *driver) : Fl_Group(X, Y, W, H, l), pWindowDriver(driver)
{
_Fl_Window();
set_flag(FORCE_POSITION);
}


Fl_Window::Fl_Window(int W, int H, const char *l) :
// fix common user error of a missing end() with current(0):
Fl_Group((Fl_Group::current(0),0), 0, W, H, l),
pWindowDriver(Fl_Window_Driver::newWindowDriver(this))
{
cursor_default = FL_CURSOR_DEFAULT;

_Fl_Window();
clear_visible();
}
Expand All @@ -92,15 +95,6 @@ Fl_Window::~Fl_Window() {
}
free_icons();
delete icon_;
if (shape_data_) {
if (shape_data_->todelete_) delete shape_data_->todelete_;
#if defined(__APPLE__) // PORTME: Fl_Window_Driver - platform window driver
if (shape_data_->mask) {
CGImageRelease(shape_data_->mask);
}
#endif
delete shape_data_;
}
}


Expand Down

0 comments on commit d476807

Please sign in to comment.