summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Copy_Surface.cxx8
-rw-r--r--src/Fl_cocoa.mm39
-rw-r--r--src/Fl_win32.cxx54
-rw-r--r--src/Fl_x.cxx28
4 files changed, 106 insertions, 23 deletions
diff --git a/src/Fl_Copy_Surface.cxx b/src/Fl_Copy_Surface.cxx
index 69f9fea6c..c14e0ce74 100644
--- a/src/Fl_Copy_Surface.cxx
+++ b/src/Fl_Copy_Surface.cxx
@@ -211,6 +211,14 @@ void Fl_Copy_Surface::prepare_copy_pdf_and_tiff(int w, int h)
#endif // __APPLE__
+#if !defined(__APPLE__)
+/** Copies a window and its borders and title bar to the clipboard. */
+void Fl_Copy_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
+{
+ helper->draw_decorated_window(win, delta_x, delta_y, this);
+}
+#endif
+
#if !(defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN))
/* graphics driver that translates all graphics coordinates before calling Xlib */
class Fl_translated_Xlib_Graphics_Driver_ : public Fl_Xlib_Graphics_Driver {
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index d05d3ad5b..8089f75df 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -3855,6 +3855,45 @@ int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
}
@end
+
+void Fl_Copy_Surface::draw_decorated_window(Fl_Window* win, int delta_x, int delta_y)
+{
+ int bx, by, bt;
+ get_window_frame_sizes(bx, by, bt);
+ draw(win, 0, bt); // draw the window content
+ if (win->border()) {
+ // draw the window title bar
+ CGContextSaveGState(gc);
+ CGContextTranslateCTM(gc, 0, bt);
+ CGContextScaleCTM(gc, 1, -1);
+ Fl_X::clip_to_rounded_corners(gc, win->w(), bt);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ CALayer *layer = fl_mac_os_version >= 101000 ?
+ [[[fl_xid(win) standardWindowButton:NSWindowCloseButton] superview] layer] : nil; // 10.5
+ if (layer) {
+ CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
+ // for unknown reason, rendering the layer to the Fl_Copy_Surface pdf graphics context does not work;
+ // we use an auxiliary bitmap context
+ CGContextRef auxgc = CGBitmapContextCreate(NULL, win->w(), bt, 8, 0, cspace, kCGImageAlphaPremultipliedLast);
+ CGColorSpaceRelease(cspace);
+ CGContextClearRect(auxgc, CGRectMake(0, 0, win->w(), bt));
+ CGContextTranslateCTM(auxgc, 0, bt);
+ CGContextScaleCTM(auxgc, 1, -1);
+ [layer renderInContext:auxgc]; // 10.5
+ fl_draw_image((uchar*)CGBitmapContextGetData(auxgc), 0, 0, win->w(), bt, 4, CGBitmapContextGetBytesPerRow(auxgc));
+ CGContextRelease(auxgc);
+ } else
+#endif
+ {
+ CGImageRef img = Fl_X::CGImage_from_window_rect(win, 0, -bt, win->w(), bt);
+ CGContextDrawImage(gc, CGRectMake(0, 0, win->w(), bt), img);
+ CFRelease(img);
+ }
+ CGContextRestoreGState(gc);
+ }
+}
+
+
static void createAppleMenu(void)
{
static BOOL donethat = NO;
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index c14055336..d1927e7a3 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -2731,10 +2731,14 @@ int Fl_Window::decorated_h()
void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
{
- if (!win->shown() || win->parent() || !win->border() || !win->visible()) {
- this->print_widget(win, x_offset, y_offset);
- return;
- }
+ if (!win->shown() || win->parent() || !win->border() || !win->visible())
+ print_widget(win, x_offset, y_offset);
+ else
+ draw_decorated_window(win, x_offset, y_offset, this);
+}
+
+void Fl_Paged_Device::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset)
+{
int X, Y, bt, bx, by, ww, wh; // compute the window border sizes
Fl_X::fake_X_wm(win, X, Y, bt, bx, by);
ww = win->w() + 2 * bx;
@@ -2757,21 +2761,17 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
Window save_win = fl_window;
fl_window = NULL; // force use of read_win_rectangle() by fl_read_image()
uchar *top_image = fl_read_image(NULL, r.left, r.top, ww, bt + by);
- uchar *left_image = fl_read_image(NULL, r.left, r.top, bx, wh);
- uchar *right_image = fl_read_image(NULL, r.right - bx, r.top, bx, wh);
- uchar *bottom_image = fl_read_image(NULL, r.left, r.bottom-by, ww, by);
+ uchar *left_image = bx ? fl_read_image(NULL, r.left, r.top, bx, wh) : NULL;
+ uchar *right_image = bx ? fl_read_image(NULL, r.right - bx, r.top, bx, wh) : NULL;
+ uchar *bottom_image = by ? fl_read_image(NULL, r.left, r.bottom-by, ww, by) : NULL;
fl_window = save_win;
ReleaseDC(NULL, fl_gc); fl_gc = save_gc;
- this->set_current();
+ toset->set_current();
// print the 4 window sides
- fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3);
- fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3);
- fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3);
- fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3);
- delete[] top_image;
- delete[] left_image;
- delete[] right_image;
- delete[] bottom_image;
+ fl_draw_image(top_image, x_offset, y_offset, ww, bt + by, 3); delete[] top_image;
+ if (left_image) { fl_draw_image(left_image, x_offset, y_offset, bx, wh, 3); delete left_image; }
+ if (right_image) { fl_draw_image(right_image, x_offset + win->w() + bx, y_offset, bx, wh, 3); delete right_image; }
+ if (bottom_image) { fl_draw_image(bottom_image, x_offset, y_offset + win->h() + bt + by, ww, by, 3); delete bottom_image; }
// print the window inner part
this->print_widget(win, x_offset + bx, y_offset + bt + by);
fl_gc = GetDC(fl_xid(win));
@@ -2819,14 +2819,30 @@ void printFront(Fl_Widget *o, void *data)
o->window()->show();
}
+#include <FL/Fl_Copy_Surface.H>
+void copyFront(Fl_Widget *o, void *data)
+{
+ o->window()->hide();
+ Fl_Window *win = Fl::first_window();
+ if (!win) return;
+ Fl_Copy_Surface *surf = new Fl_Copy_Surface(win->decorated_w() + 1, (int)(win->decorated_h() *0.985));
+ surf->set_current();
+ surf->draw_decorated_window(win); // draw the window content
+ delete surf; // put the window on the clipboard
+ Fl_Display_Device::display_device()->set_current();
+ o->window()->show();
+}
+
void preparePrintFront(void)
{
static BOOL first=TRUE;
if(!first) return;
first=FALSE;
- static Fl_Window w(0,0,120,30);
- static Fl_Button b(0,0,w.w(),w.h(), "Print front window");
- b.callback(printFront);
+ static Fl_Window w(0,0,120,60);
+ static Fl_Button bp(0,0,w.w(),30, "Print front window");
+ bp.callback(printFront);
+ static Fl_Button bc(0,30,w.w(),30, "Copy front window");
+ bc.callback(copyFront);
w.end();
w.show();
}
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
index 094f271a5..7bb8761f2 100644
--- a/src/Fl_x.cxx
+++ b/src/Fl_x.cxx
@@ -3024,6 +3024,11 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
this->print_widget(win, x_offset, y_offset);
return;
}
+ draw_decorated_window(win, x_offset, y_offset, this);
+}
+
+void Fl_Paged_Device::draw_decorated_window(Fl_Window *win, int x_offset, int y_offset, Fl_Surface_Device *toset)
+{
Fl_Display_Device::display_device()->set_current();
win->show();
Fl::check();
@@ -3052,7 +3057,7 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
bottom_image = fl_read_image(NULL, 0, bt + win->h(), -(win->w() + 2*bx), bx);
}
fl_window = from;
- this->set_current();
+ toset->set_current();
if (top_image) {
fl_draw_image(top_image, x_offset, y_offset, win->w() + 2 * bx, bt, 3);
delete[] top_image;
@@ -3110,14 +3115,29 @@ void printFront(Fl_Widget *o, void *data)
o->window()->show();
}
+#include <FL/Fl_Copy_Surface.H>
+void copyFront(Fl_Widget *o, void *data)
+{
+ o->window()->hide();
+ Fl_Window *win = Fl::first_window();
+ if (!win) return;
+ Fl_Copy_Surface *surf = new Fl_Copy_Surface(win->decorated_w(), win->decorated_h());
+ surf->set_current();
+ surf->draw_decorated_window(win); // draw the window content
+ delete surf; // put the window on the clipboard
+ o->window()->show();
+}
+
void preparePrintFront(void)
{
static int first=1;
if(!first) return;
first=0;
- static Fl_Window w(0,0,150,30);
- static Fl_Button b(0,0,w.w(),w.h(), "Print front window");
- b.callback(printFront);
+ static Fl_Window w(0,0,140,60);
+ static Fl_Button bp(0,0,w.w(),30, "Print front window");
+ bp.callback(printFront);
+ static Fl_Button bc(0,30,w.w(),30, "Copy front window");
+ bc.callback(copyFront);
w.end();
w.show();
}