Index: src/Fl_Copy_Surface.cxx
===================================================================
--- src/Fl_Copy_Surface.cxx	(revision 0)
+++ src/Fl_Copy_Surface.cxx	(revision 0)
@@ -0,0 +1,267 @@
+#include <FL/Fl_Copy_Surface.H>
+#include <FL/Fl.H>
+
+#if defined(__APPLE__) && defined(__ppc__)
+#include <QuickTime/QuickTimeComponents.h>
+#endif
+
+const char *Fl_Copy_Surface::class_id = "Fl_Copy_Surface";
+
+/** Constructor. 
+ \param w and \param h are the width and height of the clipboard surface
+ in points where drawing will occur.
+ */
+Fl_Copy_Surface::Fl_Copy_Surface(int w, int h) : 
+#if defined(__APPLE__) || defined(WIN32)
+  Fl_System_Printer()
+#else
+  Fl_Paged_Device()
+#endif
+{
+  width = w;
+  height = h;
+  scale_x = 1;
+  scale_y = 1;
+#ifdef __APPLE__
+  prepare_copy_pdf_and_tiff(w, h);
+  oldgc = fl_gc;
+#elif defined(WIN32)
+  oldgc = fl_gc;
+  // exact computation of factor from screen units to EnhMetaFile units (0.01 mm)
+  HDC hdc = GetDC(NULL);
+  int hmm = GetDeviceCaps(hdc, HORZSIZE);
+  int hdots = GetDeviceCaps(hdc, HORZRES);
+  int vmm = GetDeviceCaps(hdc, VERTSIZE);
+  int vdots = GetDeviceCaps(hdc, VERTRES);
+  ReleaseDC(NULL, hdc);
+  float factorw =  (100. * hmm) / hdots;
+  float factorh =  (100. * vmm) / vdots + 0.5;
+  
+  RECT rect; rect.left = 0; rect.top = 0; rect.right = w * factorw; rect.bottom = h * factorh;
+  gc = CreateEnhMetaFile (NULL, NULL, &rect, NULL);
+  if (gc != NULL) {
+    SetGraphicsMode(gc, GM_ADVANCED); // needed for ModifyWorldTransform()
+    SetTextAlign(gc, TA_BASELINE|TA_LEFT);
+    SetBkMode(gc, TRANSPARENT);
+  } 
+  Fl_Graphics_Driver* d = driver();
+  delete d;
+  driver(new Fl_GDI_Graphics_Driver); // don't use the printer driver
+#else // Xlib
+  oldwindow = fl_window;
+  xid = fl_create_offscreen(w,h);
+  driver(new Fl_Xlib_Graphics_Driver);
+  start_job(1,NULL,NULL);
+  start_page();
+  int AW,AH;
+  int res=printable_rect(&AW,&AH);
+  origin(0,0);
+#endif
+}
+
+/** Destructor.
+ */
+Fl_Copy_Surface::~Fl_Copy_Surface()
+{
+#ifdef __APPLE__
+  complete_copy_pdf_and_tiff();
+  fl_gc = oldgc;
+#elif defined(WIN32)
+  if(oldgc == fl_gc) oldgc = NULL;
+  HENHMETAFILE hmf = CloseEnhMetaFile (gc);
+  if ( hmf != NULL ) {
+    if ( OpenClipboard (NULL) ){
+      EmptyClipboard ();
+      SetClipboardData (CF_ENHMETAFILE, hmf);
+      CloseClipboard ();
+    }
+    DeleteEnhMetaFile(hmf);
+  }
+  DeleteDC(gc);
+  fl_gc = oldgc;
+#else // Xlib
+  fl_window = xid;
+  unsigned char *data=fl_read_image(NULL,0,0,width,height,0);
+  Fl::copy_image(data,width,height,1);
+  delete[] data;
+  end_page();
+  end_job();
+  fl_delete_offscreen(xid);
+  fl_window = oldwindow;
+#endif
+}
+
+void Fl_Copy_Surface::set_current()
+{
+#if defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN)
+  fl_gc = gc;
+  fl_window = (Window)1;
+  Fl_Surface_Device::set_current();
+#else
+  fl_window = xid;
+  Fl_Surface_Device::set_current();
+  fl_draw_box(FL_UP_BOX,0,0,300,300,FL_RED);
+#endif
+}
+
+
+int Fl_Copy_Surface::printable_rect(int *w, int *h)
+{
+  *w = width * scale_x;
+  *h = height * scale_y;
+  return 0;
+}
+
+
+void Fl_Copy_Surface::margins(int *left, int *top, int *right, int *bottom)
+{
+  *left = *top = *right = *bottom = 0;
+}
+
+#ifdef WIN32
+void Fl_Copy_Surface::scale (float scalex, float scaley)
+{
+  if (scaley == 0.) scaley = scalex;
+  scale_x = scalex;
+  scale_y = scaley;
+  XFORM mat;
+  mat.eM11 = scalex;
+  mat.eM12 = 0;
+  mat.eM21 = 0;
+  mat.eM22 = scaley;
+  mat.eDx = mat.eDy = 0;
+  SetWorldTransform(gc, &mat);
+}
+#endif
+
+#ifdef __APPLE__
+
+size_t Fl_Copy_Surface::MyPutBytes(void* info, const void* buffer, size_t count)
+  {
+  CFDataAppendBytes ((CFMutableDataRef) info, (const UInt8 *)buffer, count);
+  return count;
+}
+
+void Fl_Copy_Surface::init_PDF_context(int w, int h)
+{
+  CGRect bounds = CGRectMake(0, 0, w, h );	
+  pdfdata = CFDataCreateMutable(NULL, 0);
+  CGDataConsumerRef myconsumer;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+  if(CGDataConsumerCreateWithCFData != NULL) {
+    myconsumer = CGDataConsumerCreateWithCFData(pdfdata); // 10.4
+  }
+  else 
+#endif
+  {
+    static CGDataConsumerCallbacks callbacks = { Fl_Copy_Surface::MyPutBytes, NULL };
+    myconsumer = CGDataConsumerCreate ((void*) pdfdata, &callbacks);
+  }
+  gc = CGPDFContextCreate (myconsumer, &bounds, NULL);
+  CGDataConsumerRelease (myconsumer);
+}
+
+void Fl_Copy_Surface::prepare_copy_pdf_and_tiff(int w, int h)
+{
+  init_PDF_context(w, h);
+  if (gc == NULL) return;
+  CGRect bounds = CGRectMake(0, 0, w, h );	
+  CGContextBeginPage (gc, &bounds);
+  CGContextTranslateCTM(gc, 0, h);
+  CGContextScaleCTM(gc, 1.0f, -1.0f);
+  CGContextSaveGState(gc);
+}
+
+static void bitmap_to_tiff_clipboard(CGContextRef c, PasteboardRef clipboard)
+{
+  if (fl_mac_os_version >= 100400) {
+    CFStringRef tiff = CFSTR("public.tiff");
+    CFMutableDataRef data = CFDataCreateMutable(NULL, 0);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+    CGImageRef image = CGBitmapContextCreateImage(c); // 10.4
+    CGImageDestinationRef dest = CGImageDestinationCreateWithData(data,tiff, 1, NULL); // 10.4
+    CGImageDestinationAddImage(dest, image, NULL); // 10.4
+    CGImageDestinationFinalize(dest); // 10.4
+    CGImageRelease(image);
+    CFRelease(dest);
+#endif
+    PasteboardPutItemFlavor(clipboard, (PasteboardItemID)1, tiff, data, kPasteboardFlavorNoFlags );
+    CFRelease(data);
+    }
+  else {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 && defined(__ppc__)
+#warning Compilation with -mmacosx-version-min=10.3 requires -framework QuickTime at link time
+	GraphicsExportComponent exporter;
+   	OSErr err = OpenADefaultComponent(GraphicsExporterComponentType, /*kQTFileTypePicture*/ 'PICT', &exporter);
+   	ComponentResult cerr = GraphicsExportSetInputCGBitmapContext(exporter, c); // 10.3 -framework QuickTime
+   	Handle dataHandle = NewHandle(0);
+   	cerr = GraphicsExportSetOutputHandle(exporter, dataHandle); // -framework QuickTime
+  	unsigned long size;
+   	cerr = GraphicsExportDoExport(exporter, &size); // -framework QuickTime
+   	err = CloseComponent(exporter);
+   	if (GetHandleSize(dataHandle) > 512) {
+     	HLock(dataHandle);
+     	// The clipboard REQUIRES only the image data, not the header.
+     	CFDataRef pictdata = CFDataCreate(NULL, (const UInt8 *)*dataHandle + 512, GetHandleSize(dataHandle) - 512);
+     	HUnlock(dataHandle);
+     	PasteboardPutItemFlavor(clipboard, (PasteboardItemID)1,
+					 	CFSTR("com.apple.pict"),
+					 	pictdata,
+					 	kPasteboardFlavorNoFlags );
+     	CFRelease(pictdata);
+     	}
+   	DisposeHandle(dataHandle);
+#endif
+  }
+}
+
+
+void Fl_Copy_Surface::complete_copy_pdf_and_tiff()
+{
+  int w, h;
+  CGContextRestoreGState(gc);
+  CGContextEndPage(gc);
+  CGContextRelease(gc);
+  PasteboardRef clipboard = NULL;
+  PasteboardCreate(kPasteboardClipboard, &clipboard);
+  PasteboardClear(clipboard); //	first, copy PDF to clipboard 
+  PasteboardPutItemFlavor (clipboard, (PasteboardItemID)1, 
+			   CFSTR("com.adobe.pdf"), // kUTTypePDF
+			   pdfdata, kPasteboardFlavorNoFlags);
+  //second, transform this PDF to a bitmap image and put it as tiff in clipboard
+  CGDataProviderRef prov;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+  if(fl_mac_os_version >= 100400)
+    prov = CGDataProviderCreateWithCFData(pdfdata); // 10.4
+  else 
+#endif
+    prov = CGDataProviderCreateWithData(NULL, CFDataGetBytePtr(pdfdata), CFDataGetLength(pdfdata), NULL);
+  CGPDFDocumentRef pdfdoc = CGPDFDocumentCreateWithProvider(prov);
+  CGPDFPageRef pdfpage = CGPDFDocumentGetPage(pdfdoc, 1);
+  w = width;
+  h = height;
+  CGDataProviderRelease(prov);
+  CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
+  const int scale = 2;
+  w *= scale; h *= scale;
+  void *mem = ( fl_mac_os_version >= 100600 ? NULL : malloc(w * h * 4) );
+  gc = CGBitmapContextCreate(mem, w, h, 8, w * 4, space, kCGImageAlphaNoneSkipLast);
+  CFRelease(space);
+  if (gc == NULL) { if (mem) free(mem); return; }
+  CGRect rect = CGRectMake(0, 0, w, h);
+  CGContextSetRGBFillColor(gc,  1,1,1,1);//need to clear background
+  CGContextFillRect(gc, rect);
+  CGContextConcatCTM(gc, CGAffineTransformMakeScale(scale, scale));
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+  CGContextDrawPDFPage(gc, pdfpage);  // requires 10.3
+#endif
+  CGPDFDocumentRelease(pdfdoc);
+  CFRelease(pdfdata);
+  bitmap_to_tiff_clipboard(gc, clipboard);
+  CFRelease(clipboard);    
+  CGContextRelease(gc);
+  if (mem) free(mem);
+}
+#endif //__APPLE__
+
+
Index: src/Fl_x.cxx
===================================================================
--- src/Fl_x.cxx	(revision 10113)
+++ src/Fl_x.cxx	(working copy)
@@ -335,6 +335,7 @@
 Atom fl_XaCompoundText;
 Atom fl_XaUtf8String;
 Atom fl_XaTextUriList;
+Atom fl_XaImageBmp;
 Atom fl_NET_WM_NAME;			// utf8 aware window label
 Atom fl_NET_WM_ICON_NAME;		// utf8 aware window icon name
 Atom fl_NET_SUPPORTING_WM_CHECK;
@@ -641,6 +642,7 @@
   fl_XaCompoundText     = XInternAtom(d, "COMPOUND_TEXT",       0);
   fl_XaUtf8String       = XInternAtom(d, "UTF8_STRING",         0);
   fl_XaTextUriList      = XInternAtom(d, "text/uri-list",       0);
+  fl_XaImageBmp         = XInternAtom(d, "image/bmp",           0);
   fl_NET_WM_NAME        = XInternAtom(d, "_NET_WM_NAME",        0);
   fl_NET_WM_ICON_NAME   = XInternAtom(d, "_NET_WM_ICON_NAME",   0);
   fl_NET_SUPPORTING_WM_CHECK = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", 0);
@@ -773,6 +775,9 @@
 Fl_Widget *fl_selection_requestor;
 char *fl_selection_buffer[2];
 int fl_selection_length[2];
+#define FL_SELECTION_TEXT 0
+#define FL_SELECTION_IMAGE 1
+int fl_selection_type[2];
 int fl_selection_buffer_length[2];
 char fl_i_own_selection[2] = {0,0};
 
@@ -782,6 +787,8 @@
     // We already have it, do it quickly without window server.
     // Notice that the text is clobbered if set_selection is
     // called in response to FL_PASTE!
+    // However, for now, we only paste text in this function
+    if (fl_selection_type[clipboard] != FL_SELECTION_TEXT) return;
     Fl::e_text = fl_selection_buffer[clipboard];
     Fl::e_length = fl_selection_length[clipboard];
     if (!Fl::e_text) Fl::e_text = (char *)"";
@@ -870,10 +877,81 @@
   fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
   fl_selection_length[clipboard] = len;
   fl_i_own_selection[clipboard] = 1;
+  fl_selection_type[clipboard] = FL_SELECTION_TEXT;
   Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
   XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time);
 }
 
+static void write_short(unsigned char **cp,short i){
+  unsigned char *c=*cp;
+  *c++=i&0xFF;i>>=8;
+  *c++=i&0xFF;i>>=8;
+  *cp=c;
+}
+
+static void write_int(unsigned char **cp,int i){
+  unsigned char *c=*cp;
+  *c++=i&0xFF;i>>=8;
+  *c++=i&0xFF;i>>=8;
+  *c++=i&0xFF;i>>=8;
+  *c++=i&0xFF;i>>=8;
+  *cp=c;
+}
+
+static unsigned char *create_bmp(const unsigned char *data, int W, int H, int *return_size){
+  int R=(3*W+3)/4 * 4; // the number of bytes per row, rounded up to multiple of 4
+  int s=H*R;
+  int fs=14+40+s;
+  unsigned char *b=new unsigned char[fs];
+  unsigned char *c=b;
+  // BMP header
+  *c++='B';
+  *c++='M';
+  write_int(&c,fs);
+  write_int(&c,0);
+  write_int(&c,14+40);
+  // DIB header:
+  write_int(&c,40);
+  write_int(&c,W);
+  write_int(&c,H);
+  write_short(&c,1);
+  write_short(&c,24);//bits ber pixel
+  write_int(&c,0);//RGB
+  write_int(&c,s);
+  write_int(&c,0);// horizontal resolution
+  write_int(&c,0);// vertical resolution
+  write_int(&c,0);//number of colors. 0 -> 1<<bits_per_pixel
+  write_int(&c,0);
+  // Pixel data
+  data+=3*W*H;
+  for (int y=0;y<H;++y){
+    data-=3*W;
+    const unsigned char *s=data;
+    unsigned char *p=c;
+    for (int x=0;x<W;++x){
+      *p++=s[0];
+      *p++=s[1];
+      *p++=s[2];
+      s+=3;
+    }
+    c+=R;
+  }
+  *return_size = fs;
+  return b;
+}
+
+void Fl::copy_image(const unsigned char *data, int W, int H, int clipboard){
+  if(!data || W<=0 || H<=0) return;
+  delete[] fl_selection_buffer[clipboard];
+  fl_selection_buffer[clipboard] = (char *) create_bmp(data,W,H,&fl_selection_length[clipboard]);
+  fl_selection_buffer_length[clipboard] = fl_selection_length[clipboard];
+  fl_i_own_selection[clipboard] = 1;
+  fl_selection_type[clipboard] = FL_SELECTION_IMAGE;
+
+  Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
+  XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time);
+}
+
 ////////////////////////////////////////////////////////////////
 // Code for tracking clipboard changes:
 
@@ -1242,32 +1320,54 @@
     e.target = fl_xevent->xselectionrequest.target;
     e.time = fl_xevent->xselectionrequest.time;
     e.property = fl_xevent->xselectionrequest.property;
-    if (e.target == TARGETS) {
-      Atom a[3] = {fl_XaUtf8String, XA_STRING, fl_XaText};
-      XChangeProperty(fl_display, e.requestor, e.property,
-                      XA_ATOM, atom_bits, 0, (unsigned char*)a, 3);
-    } else if (/*e.target == XA_STRING &&*/ fl_selection_length[clipboard]) {
-    if (e.target == fl_XaUtf8String ||
-	     e.target == XA_STRING ||
-	     e.target == fl_XaCompoundText ||
-	     e.target == fl_XaText ||
-	     e.target == fl_Xatextplain ||
-	     e.target == fl_Xatextplainutf ||
-	     e.target == fl_Xatextplainutf2) {
-	// clobber the target type, this seems to make some applications
-	// behave that insist on asking for XA_TEXT instead of UTF8_STRING
-	// Does not change XA_STRING as that breaks xclipboard.
-	if (e.target != XA_STRING) e.target = fl_XaUtf8String;
+    if (fl_selection_type[clipboard] == FL_SELECTION_TEXT){
+      if (e.target == TARGETS) {
+	Atom a[3] = {fl_XaUtf8String, XA_STRING, fl_XaText};
 	XChangeProperty(fl_display, e.requestor, e.property,
-			 e.target, 8, 0,
-			 (unsigned char *)fl_selection_buffer[clipboard],
-			 fl_selection_length[clipboard]);
+	                XA_ATOM, atom_bits, 0, (unsigned char*)a, 3);
+      } else {
+	if (/*e.target == XA_STRING &&*/ fl_selection_length[clipboard]) {
+	  if (e.target == fl_XaUtf8String ||
+	      e.target == XA_STRING ||
+	      e.target == fl_XaCompoundText ||
+	      e.target == fl_XaText ||
+	      e.target == fl_Xatextplain ||
+	      e.target == fl_Xatextplainutf ||
+	      e.target == fl_Xatextplainutf2) {
+	    // clobber the target type, this seems to make some applications
+	    // behave that insist on asking for XA_TEXT instead of UTF8_STRING
+	    // Does not change XA_STRING as that breaks xclipboard.
+	    if (e.target != XA_STRING) e.target = fl_XaUtf8String;
+	    XChangeProperty(fl_display, e.requestor, e.property,
+		            e.target, 8, 0,
+		            (unsigned char *)fl_selection_buffer[clipboard],
+		            fl_selection_length[clipboard]);
+	  }
+	} else {
+	  //    char* x = XGetAtomName(fl_display,e.target);
+	  //    fprintf(stderr,"selection request of %s\n",x);
+	  //    XFree(x);
+	  e.property = 0;
+	}
       }
-    } else {
-//    char* x = XGetAtomName(fl_display,e.target);
-//    fprintf(stderr,"selection request of %s\n",x);
-//    XFree(x);
-      e.property = 0;
+    } else { // image in clipboard
+      if (e.target == TARGETS) {
+	Atom a[1] = {fl_XaImageBmp};
+	XChangeProperty(fl_display, e.requestor, e.property,
+	                XA_ATOM, atom_bits, 0, (unsigned char*)a, 1);
+      } else {
+	if (e.target == fl_XaImageBmp && fl_selection_length[clipboard]) {
+	    XChangeProperty(fl_display, e.requestor, e.property,
+		            e.target, 8, 0,
+		            (unsigned char *)fl_selection_buffer[clipboard],
+		            fl_selection_length[clipboard]);
+	} else {
+	  //    char* x = XGetAtomName(fl_display,e.target);
+	  //    fprintf(stderr,"selection request of %s\n",x);
+	  //    XFree(x);
+	  e.property = 0;
+	}
+      }
     }
     XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);}
     return 1;
Index: FL/Fl.H
===================================================================
--- FL/Fl.H	(revision 10113)
+++ FL/Fl.H	(working copy)
@@ -765,6 +765,9 @@
   clipboard is used for traditional copy/cut/paste operations.
   */
   static void copy(const char* stuff, int len, int destination = 0); // platform dependent
+#if !(defined(__APPLE__) || defined(WIN32))
+  static void copy_image(const unsigned char* data, int W, int H, int destination = 0); // platform dependent
+#endif
   /**
   Pastes the data from the selection buffer (\p source is 0) or the clipboard 
   (\p source is 1) into \p receiver.  
Index: FL/Fl_Copy_Surface.H
===================================================================
--- FL/Fl_Copy_Surface.H	(revision 0)
+++ FL/Fl_Copy_Surface.H	(revision 0)
@@ -0,0 +1,76 @@
+#include <FL/Fl_Paged_Device.H>
+#include <FL/Fl_Printer.H>
+
+#if defined(__APPLE__)
+#include <ApplicationServices/ApplicationServices.h>
+#endif
+
+#if defined(USE_X11)
+#include <FL/x.H>
+#endif
+
+/** A class that supports copying of graphical data to the clipboard (MSWindows and Mac OS only).
+ 
+ This class is implemented only on the MSWindows and Mac OS platforms.
+ <br> After creation of an Fl_Copy_Surface object, call set_current() on it, and all subsequent graphics requests
+ will be recorded in the clipboard. It's possible to draw widgets (using Fl_Copy_Surface::print_widget()
+ or Fl_Copy_Surface::print_window()) or to use any of the \ref fl_drawings or the \ref fl_attributes.
+ Finally, delete the Fl_Copy_Surface object to load the clipboard with the graphical data.
+ <br> Fl_GL_Window's can be copied to the clipboard as well. 
+ <br> Usage example:
+ \code
+ Fl_Widget *g = ...; // a widget you want to copy to the clipboard
+ Fl_Copy_Surface *copy_surf = new Fl_Copy_Surface(g->w(), g->h()); // create an Fl_Copy_Surface object
+ copy_surf->set_current(); // direct graphics requests to the clipboard
+ copy_surf->print_widget(g); // draw the g widget in the clipboard
+ delete copy_surf; // after this, the clipboard is loaded
+ Fl_Display_Device::display_device()->set_current();  // direct graphics requests back to the display
+ \endcode
+ Platform details:
+ \li MSWindows: Transparent RGB images copy without transparency.
+ The graphical data is copied to the clipboard as an 'enhanced metafile'.
+ \li Mac OS: Mac OS X 10.4 or higher is necessary. The graphical data is copied to the 
+ clipboard (a.k.a. pasteboard) in 2 'flavors': 
+ 1) in vectorial form as PDF data; 2) in bitmap form as a TIFF image. Applications to which the 
+ clipboard content is pasted can use the flavor that suits them best.
+*/
+class Fl_Copy_Surface : public
+#if defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN)
+                                Fl_System_Printer {
+#else // Xlib
+                                Fl_Paged_Device {
+#endif
+private:
+  int width;
+  int height;
+  float scale_x;
+  float scale_y;
+#ifdef __APPLE__
+  CFMutableDataRef pdfdata;
+  CGContextRef oldgc;
+  CGContextRef gc;
+  void prepare_copy_pdf_and_tiff(int w, int h);
+  void complete_copy_pdf_and_tiff();
+  void init_PDF_context(int w, int h);
+  static size_t MyPutBytes(void* info, const void* buffer, size_t count);
+#elif defined(WIN32)
+  HDC oldgc;
+  HDC           gc;
+#else // Xlib
+  Fl_Offscreen xid;
+  Window oldwindow;
+#endif
+public:
+  static const char *class_id;
+  const char *class_name() {return class_id;};
+  Fl_Copy_Surface(int w, int h);
+  ~Fl_Copy_Surface();
+  int printable_rect(int *w, int *h);
+  void margins(int *left, int *top, int *right, int *bottom);
+  void set_current();
+#ifdef WIN32
+  void scale (float scale_x, float scale_y = 0.);
+#endif
+};
+
+
Index: test/device.cxx
===================================================================
--- test/device.cxx	(revision 10113)
+++ test/device.cxx	(working copy)
@@ -564,6 +564,17 @@
   delete p;
 }
 
+#include <FL/Fl_Copy_Surface.H>
+
+void copy(Fl_Widget *, Fl_Widget *w) {
+  Fl_Window* g =  w->window();
+  Fl_Copy_Surface *copy_surf = new Fl_Copy_Surface(g->w(), g->h());
+  copy_surf->set_current();
+  copy_surf->print_widget(g);
+  delete copy_surf;
+  Fl_Display_Device::display_device()->set_current();  
+}
+
 /*void print2(Fl_Widget *, void *w) {
  Fl_Widget * g = (Fl_Widget *)w;
  Fl_Printer * p = fl_printer_chooser();
@@ -675,6 +686,8 @@
   c2->end();
   Fl_Button *b4 = new Fl_Button(10,5, 150, 25, "Print");
   b4->callback(print,c2);
+  Fl_Button *b6 = new Fl_Button(170,5, 150, 25, "Copy");
+  b6->callback((Fl_Callback*)copy,c2);
   /*Fl_Button *b5 = new Fl_Button(165,5, 90, 25, "Print");
    b5->tooltip("This is a tooltip");
    b5->callback(print2,c2);*/
Index: ide/Xcode3/FLTK.xcodeproj/project.pbxproj
===================================================================
--- ide/Xcode3/FLTK.xcodeproj/project.pbxproj	(revision 10113)
+++ ide/Xcode3/FLTK.xcodeproj/project.pbxproj	(working copy)
@@ -8461,7 +8461,6 @@
 			isa = PBXProject;
 			buildConfigurationList = 615453DB5B8EBEE070930DA7 /* Build configuration list for PBXProject "FLTK" */;
 			compatibilityVersion = "Xcode 3.0";
-			developmentRegion = English;
 			hasScannedForEncodings = 0;
 			knownRegions = (
 				English,
