mirror of
https://github.com/fltk/fltk.git
synced 2026-06-06 00:22:42 +08:00
Added copy/paste from/to FLTK applications of graphical data.
Added Fl_Image_Surface class to draw into an Fl_Image object. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10159 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
CHANGES IN FLTK 1.3.3 RELEASED: MMM DD YYYY
|
CHANGES IN FLTK 1.3.3 RELEASED: MMM DD YYYY
|
||||||
|
|
||||||
|
- added class Fl_Copy_Surface allowing to copy graphical data to the clipboard
|
||||||
|
in a cross-platform way.
|
||||||
|
- added support for pasting graphical data from the clipboard to an FLTK widget.
|
||||||
|
- added class Fl_Image_Surface allowing to draw into an Fl_Image object.
|
||||||
- removed constraint that lines are limited to 1024 chars in widget labels and browser lines (STR #2990).
|
- removed constraint that lines are limited to 1024 chars in widget labels and browser lines (STR #2990).
|
||||||
- fix crash if Fl_Window::flush() was called, but window not shown() (STR #3028).
|
- fix crash if Fl_Window::flush() was called, but window not shown() (STR #3028).
|
||||||
- new method Fl::scheme_is(const char *name) returns 1 if current scheme is name.
|
- new method Fl::scheme_is(const char *name) returns 1 if current scheme is name.
|
||||||
|
|||||||
@@ -137,6 +137,8 @@ public: // should be private!
|
|||||||
static int e_keysym;
|
static int e_keysym;
|
||||||
static char* e_text;
|
static char* e_text;
|
||||||
static int e_length;
|
static int e_length;
|
||||||
|
static void *e_clipboard_data;
|
||||||
|
static const char *e_clipboard_type;
|
||||||
static Fl_Event_Dispatch e_dispatch;
|
static Fl_Event_Dispatch e_dispatch;
|
||||||
static Fl_Widget* belowmouse_;
|
static Fl_Widget* belowmouse_;
|
||||||
static Fl_Widget* pushed_;
|
static Fl_Widget* pushed_;
|
||||||
@@ -151,7 +153,9 @@ public: // should be private!
|
|||||||
static void reset_marked_text(); // resets marked text
|
static void reset_marked_text(); // resets marked text
|
||||||
static void insertion_point_location(int x, int y, int height); // sets window coordinates & height of insertion point
|
static void insertion_point_location(int x, int y, int height); // sets window coordinates & height of insertion point
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif // FL_DOXYGEN
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
If true then flush() will do something.
|
If true then flush() will do something.
|
||||||
*/
|
*/
|
||||||
@@ -729,6 +733,16 @@ public:
|
|||||||
you paste a nul character.
|
you paste a nul character.
|
||||||
*/
|
*/
|
||||||
static int event_length() {return e_length;}
|
static int event_length() {return e_length;}
|
||||||
|
|
||||||
|
/** During an FL_PASTE event of non-textual data, returns a pointer to the pasted data.
|
||||||
|
The returned data is an Fl_Image * when the result of Fl::event_clipboard_type() is Fl::clipboard_image.
|
||||||
|
*/
|
||||||
|
static void *event_clipboard() { return e_clipboard_data; }
|
||||||
|
/** Returns the type of the pasted data during an FL_PASTE event.
|
||||||
|
This type can be Fl::clipboard_plain_text or Fl::clipboard_image.
|
||||||
|
*/
|
||||||
|
static const char *event_clipboard_type() {return e_clipboard_type; }
|
||||||
|
|
||||||
|
|
||||||
static int compose(int &del);
|
static int compose(int &del);
|
||||||
static void compose_reset();
|
static void compose_reset();
|
||||||
@@ -763,19 +777,39 @@ public:
|
|||||||
/**
|
/**
|
||||||
Copies the data pointed to by \p stuff to the selection buffer
|
Copies the data pointed to by \p stuff to the selection buffer
|
||||||
(\p destination is 0) or
|
(\p destination is 0) or
|
||||||
the clipboard (\p destination is 1); \p len is the number of relevant
|
the clipboard (\p destination is 1).
|
||||||
bytes in \p stuff.
|
\p len is the number of relevant bytes in \p stuff.
|
||||||
|
\p type is always Fl::clipboard_plain_text.
|
||||||
The selection buffer is used for
|
The selection buffer is used for
|
||||||
middle-mouse pastes and for drag-and-drop selections. The
|
middle-mouse pastes and for drag-and-drop selections. The
|
||||||
clipboard is used for traditional copy/cut/paste operations.
|
clipboard is used for traditional copy/cut/paste operations.
|
||||||
|
|
||||||
|
\note This function is, at present, intended only to copy UTF-8 encoded textual data.
|
||||||
|
To copy graphical data, use the Fl_Copy_Surface class. The \p type argument may allow
|
||||||
|
in the future to copy other kinds of data.
|
||||||
*/
|
*/
|
||||||
static void copy(const char* stuff, int len, int destination = 0); // platform dependent
|
#if FLTK_ABI_VERSION >= 10303 || defined(FL_DOXYGEN)
|
||||||
|
static void copy(const char* stuff, int len, int destination = 0, const char *type = Fl::clipboard_plain_text); // platform dependent
|
||||||
|
#else
|
||||||
|
static void copy(const char* stuff, int len, int destination, const char *type);
|
||||||
|
static void copy(const char* stuff, int len, int destination = 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN))
|
||||||
|
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
|
Pastes the data from the selection buffer (\p source is 0) or the clipboard
|
||||||
(\p source is 1) into \p receiver.
|
(\p source is 1) into \p receiver. If \p source is 1,
|
||||||
Set things up so the receiver widget will be called with an FL_PASTE event some
|
the optional \p type argument indicates what type of data is requested from the clipboard
|
||||||
time in the future with the data from the specified \p source in Fl::event_text()
|
(at present, Fl::clipboard_plain_text - requesting text data - and
|
||||||
and the number of characters in Fl::event_length().
|
Fl::clipboard_image - requesting image data - are possible).
|
||||||
|
Set things up so the handle function of the \p receiver widget will be called with an FL_PASTE event some
|
||||||
|
time in the future if the clipboard does contain data of the requested type. During processing of this event,
|
||||||
|
and if \p type is Fl::clipboard_plain_text, the text data from the specified \p source are in Fl::event_text()
|
||||||
|
with UTF-8 encoding, and the number of characters in Fl::event_length();
|
||||||
|
if \p type is Fl::clipboard_image, Fl::event_clipboard() returns a pointer to the
|
||||||
|
image data, as an Fl_Image *.
|
||||||
The receiver
|
The receiver
|
||||||
should be prepared to be called \e directly by this, or for
|
should be prepared to be called \e directly by this, or for
|
||||||
it to happen \e later, or possibly <i>not at all</i>. This
|
it to happen \e later, or possibly <i>not at all</i>. This
|
||||||
@@ -786,8 +820,21 @@ public:
|
|||||||
The selection buffer is used for middle-mouse pastes and for
|
The selection buffer is used for middle-mouse pastes and for
|
||||||
drag-and-drop selections. The clipboard is used for traditional
|
drag-and-drop selections. The clipboard is used for traditional
|
||||||
copy/cut/paste operations.
|
copy/cut/paste operations.
|
||||||
*/
|
|
||||||
static void paste(Fl_Widget &receiver, int source /*=0*/); // platform dependent
|
\par Platform details for image data:
|
||||||
|
\li Unix/Linux platform: Image data in PNG or BMP formats are recognized. Requires linking with the fltk_images library.
|
||||||
|
\li MSWindows platform: Both bitmap and vectorial (Enhanced metafile) data from clipboard
|
||||||
|
can be pasted as image data.
|
||||||
|
\li Mac OS X platform: Both bitmap (TIFF) and vectorial (PDF) data from clipboard
|
||||||
|
can be pasted as image data.
|
||||||
|
|
||||||
|
*/
|
||||||
|
#if FLTK_ABI_VERSION >= 10303 || defined(FL_DOXYGEN)
|
||||||
|
static void paste(Fl_Widget &receiver, int source, const char *type = Fl::clipboard_plain_text); // platform dependent
|
||||||
|
#else
|
||||||
|
static void paste(Fl_Widget &receiver, int source, const char *type);
|
||||||
|
static void paste(Fl_Widget &receiver, int source /*=0*/);
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
FLTK will call the registered callback whenever there is a change to the
|
FLTK will call the registered callback whenever there is a change to the
|
||||||
selection buffer or the clipboard. The source argument indicates which
|
selection buffer or the clipboard. The source argument indicates which
|
||||||
@@ -815,6 +862,17 @@ public:
|
|||||||
buffer or the clipboard.
|
buffer or the clipboard.
|
||||||
*/
|
*/
|
||||||
static void remove_clipboard_notify(Fl_Clipboard_Notify_Handler h);
|
static void remove_clipboard_notify(Fl_Clipboard_Notify_Handler h);
|
||||||
|
/** Returns non 0 if the clipboard contains data matching \p type.
|
||||||
|
\p type can be Fl::clipboard_plain_text or Fl::clipboard_image.
|
||||||
|
*/
|
||||||
|
static int clipboard_contains(const char *type);
|
||||||
|
/** Denotes plain textual data
|
||||||
|
*/
|
||||||
|
static char const * const clipboard_plain_text;
|
||||||
|
/** Denotes image data
|
||||||
|
*/
|
||||||
|
static char const * const clipboard_image;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initiate a Drag And Drop operation. The selection buffer should be
|
Initiate a Drag And Drop operation. The selection buffer should be
|
||||||
filled with relevant data before calling this method. FLTK will
|
filled with relevant data before calling this method. FLTK will
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
//
|
||||||
|
// "$Id: Fl_Copy_Surface.H 9869 2013-04-09 20:11:28Z greg.ercolano $"
|
||||||
|
//
|
||||||
|
// Copy-to-clipboard code for the Fast Light Tool Kit (FLTK).
|
||||||
|
//
|
||||||
|
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||||
|
//
|
||||||
|
// This library is free software. Distribution and use rights are outlined in
|
||||||
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
|
// file is missing or damaged, see the license at:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/COPYING.php
|
||||||
|
//
|
||||||
|
// Please report all bugs and problems on the following page:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/str.php
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Fl_Copy_Surface_H
|
||||||
|
#define Fl_Copy_Surface_H
|
||||||
|
|
||||||
|
#include <FL/Fl_Paged_Device.H>
|
||||||
|
#include <FL/Fl_Printer.H>
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Supports copying of graphical data to the clipboard.
|
||||||
|
|
||||||
|
<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::draw()
|
||||||
|
) 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
|
||||||
|
fl_color(FL_WHITE); fl_rectf(0, 0, g->w(), g->h()); // draw a white background
|
||||||
|
copy_surf->draw(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: 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 (or PICT for Mac OS 10.3).
|
||||||
|
Applications to which the clipboard content is pasted can use the flavor that suits them best.
|
||||||
|
\li X11: the graphical data is copied to the clipboard as an image in BMP format.
|
||||||
|
*/
|
||||||
|
class Fl_Copy_Surface : public Fl_Surface_Device {
|
||||||
|
private:
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
Fl_Paged_Device *helper;
|
||||||
|
#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;
|
||||||
|
Fl_Surface_Device *_ss;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
static const char *class_id;
|
||||||
|
const char *class_name() {return class_id;};
|
||||||
|
Fl_Copy_Surface(int w, int h);
|
||||||
|
~Fl_Copy_Surface();
|
||||||
|
void set_current();
|
||||||
|
void draw(Fl_Widget* widget, int delta_x = 0, int delta_y = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
|
||||||
|
/* Mac class to reimplement Fl_Paged_Device::printable_rect() */
|
||||||
|
class Fl_Quartz_Surface_ : public Fl_System_Printer {
|
||||||
|
protected:
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
public:
|
||||||
|
static const char *class_id;
|
||||||
|
const char *class_name() {return class_id;};
|
||||||
|
Fl_Quartz_Surface_(int w, int h);
|
||||||
|
virtual int printable_rect(int *w, int *h);
|
||||||
|
virtual ~Fl_Quartz_Surface_() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif defined(WIN32)
|
||||||
|
|
||||||
|
/* Win class to implement translate()/untranslate() */
|
||||||
|
class Fl_GDI_Surface_ : public Fl_Paged_Device {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int depth;
|
||||||
|
POINT origins[10];
|
||||||
|
public:
|
||||||
|
static const char *class_id;
|
||||||
|
const char *class_name() {return class_id;};
|
||||||
|
Fl_GDI_Surface_();
|
||||||
|
virtual void translate(int x, int y);
|
||||||
|
virtual void untranslate();
|
||||||
|
virtual ~Fl_GDI_Surface_();
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif !defined(FL_DOXYGEN)
|
||||||
|
|
||||||
|
/* Xlib class to implement translate()/untranslate() */
|
||||||
|
class Fl_Xlib_Surface_ : public Fl_Paged_Device {
|
||||||
|
public:
|
||||||
|
static const char *class_id;
|
||||||
|
const char *class_name() {return class_id;};
|
||||||
|
Fl_Xlib_Surface_();
|
||||||
|
virtual void translate(int x, int y);
|
||||||
|
virtual void untranslate();
|
||||||
|
virtual ~Fl_Xlib_Surface_();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // Fl_Copy_Surface_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// End of "$Id: $".
|
||||||
|
//
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// "$Id: Fl_Image_Surface.H 9869 2013-04-09 20:11:28Z greg.ercolano $"
|
||||||
|
//
|
||||||
|
// Draw-to-image code for the Fast Light Tool Kit (FLTK).
|
||||||
|
//
|
||||||
|
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||||
|
//
|
||||||
|
// This library is free software. Distribution and use rights are outlined in
|
||||||
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
|
// file is missing or damaged, see the license at:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/COPYING.php
|
||||||
|
//
|
||||||
|
// Please report all bugs and problems on the following page:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/str.php
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Fl_Image_Surface_H
|
||||||
|
#define Fl_Image_Surface_H
|
||||||
|
|
||||||
|
#include <FL/Fl_Copy_Surface.H>
|
||||||
|
#include <FL/Fl_Image.H>
|
||||||
|
|
||||||
|
|
||||||
|
/** Directs all graphics requests to an Fl_Image.
|
||||||
|
|
||||||
|
After creation of an Fl_Image_Surface object, call set_current() on it, and all subsequent graphics requests
|
||||||
|
will be recorded in the image. It's possible to draw widgets (using Fl_Image_Surface::draw())
|
||||||
|
or to use any of the \ref fl_drawings or the \ref fl_attributes.
|
||||||
|
Finally, call image() on the object to obtain a newly allocated Fl_Image object.
|
||||||
|
<br> Fl_GL_Window objects can be drawn in the image as well.
|
||||||
|
|
||||||
|
<br> Usage example:
|
||||||
|
\code
|
||||||
|
Fl_Widget *g = ...; // a widget you want to draw in an image
|
||||||
|
Fl_Image_Surface *img_surf = new Fl_Image_Surface(g->w(), g->h()); // create an Fl_Image_Surface object
|
||||||
|
img_surf->set_current(); // direct graphics requests to the image
|
||||||
|
fl_color(FL_WHITE); fl_rectf(0, 0, g->w(), g->h()); // draw a white background
|
||||||
|
img_surf->draw(g); // draw the g widget in the image
|
||||||
|
Fl_Image* image = img_surf->image(); // get the resulting image
|
||||||
|
delete img_surf; // delete the img_surf object
|
||||||
|
Fl_Display_Device::display_device()->set_current(); // direct graphics requests back to the display
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
class Fl_Image_Surface : public Fl_Surface_Device {
|
||||||
|
private:
|
||||||
|
Fl_Offscreen offscreen;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
Fl_Paged_Device *helper;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#elif defined(WIN32)
|
||||||
|
HDC _sgc;
|
||||||
|
Window _sw;
|
||||||
|
Fl_Surface_Device *_ss;
|
||||||
|
int _savedc;
|
||||||
|
#else
|
||||||
|
Fl_Surface_Device *previous;
|
||||||
|
Window pre_window;
|
||||||
|
GC gc;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
static const char *class_id;
|
||||||
|
const char *class_name() {return class_id;};
|
||||||
|
Fl_Image_Surface(int w, int h);
|
||||||
|
~Fl_Image_Surface();
|
||||||
|
void set_current();
|
||||||
|
void draw(Fl_Widget*, int delta_x = 0, int delta_y = 0);
|
||||||
|
Fl_Image *image();
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
/* Mac class to implement translate()/untranslate() for a flipped bitmap graphics context */
|
||||||
|
class Fl_Quartz_Flipped_Surface_ : public Fl_Quartz_Surface_ {
|
||||||
|
public:
|
||||||
|
static const char *class_id;
|
||||||
|
const char *class_name() {return class_id;};
|
||||||
|
Fl_Quartz_Flipped_Surface_(int w, int h);
|
||||||
|
void translate(int x, int y);
|
||||||
|
void untranslate();
|
||||||
|
virtual ~Fl_Quartz_Flipped_Surface_() {};
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // Fl_Image_Surface_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// End of "$Id: $".
|
||||||
|
//
|
||||||
@@ -145,6 +145,7 @@ public:
|
|||||||
void set_cursor(Fl_Cursor);
|
void set_cursor(Fl_Cursor);
|
||||||
static CGImageRef CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, int h);
|
static CGImageRef CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, int h);
|
||||||
static unsigned char *bitmap_from_window_rect(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel);
|
static unsigned char *bitmap_from_window_rect(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel);
|
||||||
|
static CFDataRef CGBitmapContextToTIFF(CGContextRef c);
|
||||||
static Fl_Region intersect_region_and_rect(Fl_Region current, int x,int y,int w, int h);
|
static Fl_Region intersect_region_and_rect(Fl_Region current, int x,int y,int w, int h);
|
||||||
static CGContextRef watch_cursor_image(void);
|
static CGContextRef watch_cursor_image(void);
|
||||||
static CGContextRef help_cursor_image(void);
|
static CGContextRef help_cursor_image(void);
|
||||||
|
|||||||
+2
-1
@@ -5,7 +5,8 @@ SHELL = /bin/sh
|
|||||||
.SILENT:
|
.SILENT:
|
||||||
|
|
||||||
# Executables
|
# Executables
|
||||||
ALL = howto-add_fd-and-popen$(EXEEXT) \
|
ALL = clipboard$(EXEEXT) \
|
||||||
|
howto-add_fd-and-popen$(EXEEXT) \
|
||||||
howto-browser-with-icons$(EXEEXT) \
|
howto-browser-with-icons$(EXEEXT) \
|
||||||
howto-drag-and-drop$(EXEEXT) \
|
howto-drag-and-drop$(EXEEXT) \
|
||||||
howto-parse-args$(EXEEXT) \
|
howto-parse-args$(EXEEXT) \
|
||||||
|
|||||||
@@ -0,0 +1,168 @@
|
|||||||
|
//
|
||||||
|
// "$Id: clipboard.cxx 9869 2013-04-09 20:11:28Z greg.ercolano $"
|
||||||
|
//
|
||||||
|
// Clipboard display test application for the Fast Light Tool Kit (FLTK).
|
||||||
|
//
|
||||||
|
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||||
|
//
|
||||||
|
// This library is free software. Distribution and use rights are outlined in
|
||||||
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
|
// file is missing or damaged, see the license at:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/COPYING.php
|
||||||
|
//
|
||||||
|
// Please report all bugs and problems on the following page:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/str.php
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <FL/Fl_Window.H>
|
||||||
|
#include <FL/Fl_Box.H>
|
||||||
|
#include <FL/Fl_Image.H>
|
||||||
|
#include <FL/Fl_Text_Buffer.H>
|
||||||
|
#include <FL/Fl_Text_Display.H>
|
||||||
|
#include <FL/Fl_Tabs.H>
|
||||||
|
#include <FL/Fl_Button.H>
|
||||||
|
#include <FL/Fl.H>
|
||||||
|
#include <FL/fl_draw.H>
|
||||||
|
|
||||||
|
/* Displays and follows the content of the clipboard with either image or text data
|
||||||
|
*/
|
||||||
|
|
||||||
|
Fl_Box *image_box;
|
||||||
|
Fl_Box *image_size;
|
||||||
|
Fl_Text_Display *display;
|
||||||
|
|
||||||
|
class chess : public Fl_Box { // a box with a chess-like pattern below its image
|
||||||
|
public:
|
||||||
|
chess(int x, int y, int w, int h) : Fl_Box(FL_FLAT_BOX,x,y,w,h,0) {
|
||||||
|
align(FL_ALIGN_CENTER | FL_ALIGN_CLIP);
|
||||||
|
}
|
||||||
|
void draw() {
|
||||||
|
draw_box();
|
||||||
|
Fl_Image *im = image();
|
||||||
|
if (im) { // draw the chess pattern below the box centered image
|
||||||
|
int X = x() + (w()-im->w())/2, Y = y() + (h()-im->h())/2, W = im->w(), H = im->h();
|
||||||
|
fl_push_clip(X,Y,W,H);
|
||||||
|
fl_push_clip(x(),y(),w(),h());
|
||||||
|
fl_color(FL_WHITE); fl_rectf(X,Y,W,H);
|
||||||
|
fl_color(FL_LIGHT2);
|
||||||
|
const int side = 4, side2 = 2*side;
|
||||||
|
for (int j=Y; j<Y+H; j+=side) {
|
||||||
|
for (int i=X + (j-Y)%side2; i<X+W; i+=side2) {
|
||||||
|
fl_rectf(i,j,side,side);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fl_pop_clip();
|
||||||
|
fl_pop_clip();
|
||||||
|
}
|
||||||
|
draw_label(); // draw the box image
|
||||||
|
}
|
||||||
|
} *chess_obj;
|
||||||
|
|
||||||
|
class clipboard_viewer : public Fl_Tabs { // use tabs to display as appropriate the image or textual content of the clipboard
|
||||||
|
public:
|
||||||
|
clipboard_viewer(int x, int y, int w, int h) : Fl_Tabs(x,y,w,h) {};
|
||||||
|
virtual int handle(int event) {
|
||||||
|
if (event != FL_PASTE) return Fl_Tabs::handle(event);
|
||||||
|
if (strcmp(Fl::event_clipboard_type(), Fl::clipboard_image) == 0) { // an image is being pasted
|
||||||
|
Fl_Image *im = (Fl_Image*)Fl::event_clipboard(); // get it as an Fl_Image object
|
||||||
|
if (!im) return 1;
|
||||||
|
char title[300];
|
||||||
|
sprintf(title, "%dx%d",im->w(), im->h()); // display the image original size
|
||||||
|
#ifdef WIN32
|
||||||
|
OpenClipboard(NULL); // display extra technical info about clipboard content
|
||||||
|
char *p=title + strlen(title);
|
||||||
|
int format = EnumClipboardFormats(0);
|
||||||
|
if (format && format < CF_MAX) { sprintf(p, " %d",format); p += strlen(p); }
|
||||||
|
while (format) {
|
||||||
|
format = EnumClipboardFormats(format);
|
||||||
|
if (format && format < CF_MAX) { sprintf(p, " %d",format); p += strlen(p); }
|
||||||
|
}
|
||||||
|
HANDLE h;
|
||||||
|
if (h = GetClipboardData(CF_DIB)) {
|
||||||
|
LPBITMAPINFO lpBI = (LPBITMAPINFO)GlobalLock(h);
|
||||||
|
sprintf(p, " biBitCount=%d biCompression=%d biClrUsed=%d",
|
||||||
|
lpBI->bmiHeader.biBitCount, lpBI->bmiHeader.biCompression, lpBI->bmiHeader.biClrUsed);
|
||||||
|
}
|
||||||
|
CloseClipboard();
|
||||||
|
#endif
|
||||||
|
float scale_x = (float)im->w() / image_box->w(); // rescale the image if larger than the display box
|
||||||
|
float scale_y = (float)im->h() / image_box->h();
|
||||||
|
float scale = scale_x;
|
||||||
|
if (scale_y > scale) scale = scale_y;
|
||||||
|
if (scale > 1) {
|
||||||
|
Fl_Image *im2 = im->copy(im->w()/scale, im->h()/scale);
|
||||||
|
delete im;
|
||||||
|
im = im2;
|
||||||
|
}
|
||||||
|
Fl_Image *oldim = image_box->image();
|
||||||
|
if (oldim) delete oldim;
|
||||||
|
image_box->image(im); // show the scaled image
|
||||||
|
image_size->copy_label(title);
|
||||||
|
value(image_box->parent());
|
||||||
|
window()->redraw();
|
||||||
|
}
|
||||||
|
else { // text is being pasted
|
||||||
|
display->buffer()->text(Fl::event_text());
|
||||||
|
value(display);
|
||||||
|
display->redraw();
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} *tabs;
|
||||||
|
|
||||||
|
|
||||||
|
void cb(Fl_Widget *wid, clipboard_viewer *tabs)
|
||||||
|
{
|
||||||
|
if (Fl::clipboard_contains(Fl::clipboard_image)) {
|
||||||
|
Fl::paste(*tabs, 1, Fl::clipboard_image); // try to find image in the clipboard
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Fl::clipboard_contains(Fl::clipboard_plain_text)) Fl::paste(*tabs, 1, Fl::clipboard_plain_text); // also try to find text
|
||||||
|
}
|
||||||
|
|
||||||
|
void clip_callback(int source, void *data) { // called after clipboard was changed or at application activation
|
||||||
|
if ( source == 1 ) cb(NULL, (clipboard_viewer *)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#if !(defined(__APPLE__) || defined(WIN32))
|
||||||
|
extern void fl_register_images();
|
||||||
|
fl_register_images(); // required to allow pasting of images
|
||||||
|
#endif
|
||||||
|
Fl_Window* win = new Fl_Window(500, 550, "clipboard viewer");
|
||||||
|
tabs = new clipboard_viewer(0, 0, 500, 500);
|
||||||
|
Fl_Group *g = new Fl_Group( 5, 30, 490, 460, Fl::clipboard_image); // g will display the image form
|
||||||
|
g->box(FL_FLAT_BOX);
|
||||||
|
image_box = new chess(5, 30, 490, 450);
|
||||||
|
image_size = new Fl_Box(FL_NO_BOX, 5, 485, 490, 10, 0);
|
||||||
|
g->end();
|
||||||
|
g->selection_color(FL_INACTIVE_COLOR);
|
||||||
|
|
||||||
|
Fl_Text_Buffer *buffer = new Fl_Text_Buffer();
|
||||||
|
display = new Fl_Text_Display(5,30,490, 460, Fl::clipboard_plain_text); // display will display the text form
|
||||||
|
display->buffer(buffer);
|
||||||
|
display->selection_color(FL_INACTIVE_COLOR);
|
||||||
|
tabs->end();
|
||||||
|
tabs->resizable(display);
|
||||||
|
|
||||||
|
Fl_Group *g2 = new Fl_Group( 10,510,200,25);
|
||||||
|
Fl_Button *refresh = new Fl_Button(10,510,200,25, "Refresh from clipboard");
|
||||||
|
refresh->callback((Fl_Callback*)cb, tabs);
|
||||||
|
g2->end();
|
||||||
|
g2->resizable(NULL);
|
||||||
|
win->end();
|
||||||
|
win->resizable(tabs);
|
||||||
|
win->show();
|
||||||
|
#if defined(__APPLE__) || defined(WIN32)
|
||||||
|
clip_callback(1, tabs); // use clipboard content at start
|
||||||
|
#endif
|
||||||
|
Fl::add_clipboard_notify(clip_callback, tabs); // will update with new clipboard content immediately or at application activation
|
||||||
|
return Fl::run();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// End of "$Id: $".
|
||||||
|
//
|
||||||
@@ -329,6 +329,8 @@
|
|||||||
7F66B1DA12BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */; };
|
7F66B1DA12BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */; };
|
||||||
7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */; };
|
7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */; };
|
||||||
7F74F393190D7F0500C56950 /* fl_gleam.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 299E717718BC503400FF83F2 /* fl_gleam.cxx */; };
|
7F74F393190D7F0500C56950 /* fl_gleam.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 299E717718BC503400FF83F2 /* fl_gleam.cxx */; };
|
||||||
|
7F76E016192FAD420071728B /* Fl_Copy_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7F76E015192FAD420071728B /* Fl_Copy_Surface.cxx */; };
|
||||||
|
7F76E018192FAD590071728B /* Fl_Image_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7F76E017192FAD590071728B /* Fl_Image_Surface.cxx */; };
|
||||||
7FFDE4AD171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7FFDE4AC171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm */; };
|
7FFDE4AD171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7FFDE4AC171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm */; };
|
||||||
812129561A1981D6DEFBCBFB /* Fl_Positioner.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 05BBBFE4BED0452E5D6A81F7 /* Fl_Positioner.cxx */; };
|
812129561A1981D6DEFBCBFB /* Fl_Positioner.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 05BBBFE4BED0452E5D6A81F7 /* Fl_Positioner.cxx */; };
|
||||||
812761E94039F13357F56EE6 /* fltk_png.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98A16A4EC098BA7DB21E13DC /* fltk_png.framework */; };
|
812761E94039F13357F56EE6 /* fltk_png.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98A16A4EC098BA7DB21E13DC /* fltk_png.framework */; };
|
||||||
@@ -4338,6 +4340,10 @@
|
|||||||
7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_cocoa.mm; path = ../../src/Fl_cocoa.mm; sourceTree = SOURCE_ROOT; };
|
7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_cocoa.mm; path = ../../src/Fl_cocoa.mm; sourceTree = SOURCE_ROOT; };
|
||||||
7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Native_File_Chooser_MAC.mm; path = ../../src/Fl_Native_File_Chooser_MAC.mm; sourceTree = SOURCE_ROOT; };
|
7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Native_File_Chooser_MAC.mm; path = ../../src/Fl_Native_File_Chooser_MAC.mm; sourceTree = SOURCE_ROOT; };
|
||||||
7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Quartz_Printer.mm; path = ../../src/Fl_Quartz_Printer.mm; sourceTree = SOURCE_ROOT; };
|
7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Quartz_Printer.mm; path = ../../src/Fl_Quartz_Printer.mm; sourceTree = SOURCE_ROOT; };
|
||||||
|
7F76E015192FAD420071728B /* Fl_Copy_Surface.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Copy_Surface.cxx; path = ../../src/Fl_Copy_Surface.cxx; sourceTree = SOURCE_ROOT; };
|
||||||
|
7F76E017192FAD590071728B /* Fl_Image_Surface.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Image_Surface.cxx; path = ../../src/Fl_Image_Surface.cxx; sourceTree = SOURCE_ROOT; };
|
||||||
|
7F76E019192FAD740071728B /* Fl_Copy_Surface.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Copy_Surface.H; path = ../../FL/Fl_Copy_Surface.H; sourceTree = SOURCE_ROOT; };
|
||||||
|
7F76E01A192FAD840071728B /* Fl_Image_Surface.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Image_Surface.H; path = ../../FL/Fl_Image_Surface.H; sourceTree = SOURCE_ROOT; };
|
||||||
7F784151AF1B748D0F3DB1C0 /* forms.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = forms.cxx; path = ../../test/forms.cxx; sourceTree = SOURCE_ROOT; };
|
7F784151AF1B748D0F3DB1C0 /* forms.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = forms.cxx; path = ../../test/forms.cxx; sourceTree = SOURCE_ROOT; };
|
||||||
7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; };
|
7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; };
|
||||||
7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -5459,6 +5465,7 @@
|
|||||||
4D55C9FE101986BC47029A16 /* Fl_Choice.cxx */,
|
4D55C9FE101986BC47029A16 /* Fl_Choice.cxx */,
|
||||||
F5CAE7DC565B8398F02ED7BA /* Fl_Clock.cxx */,
|
F5CAE7DC565B8398F02ED7BA /* Fl_Clock.cxx */,
|
||||||
058BCBC36ADE724A418F1C43 /* Fl_Color_Chooser.cxx */,
|
058BCBC36ADE724A418F1C43 /* Fl_Color_Chooser.cxx */,
|
||||||
|
7F76E015192FAD420071728B /* Fl_Copy_Surface.cxx */,
|
||||||
E9893274B0B6C5F24730235F /* Fl_Counter.cxx */,
|
E9893274B0B6C5F24730235F /* Fl_Counter.cxx */,
|
||||||
D9A7DCBAFF41CBC3DCB67C6F /* Fl_Device.cxx */,
|
D9A7DCBAFF41CBC3DCB67C6F /* Fl_Device.cxx */,
|
||||||
3AFC31503AB99F6D00BAC647 /* Fl_Dial.cxx */,
|
3AFC31503AB99F6D00BAC647 /* Fl_Dial.cxx */,
|
||||||
@@ -5471,6 +5478,7 @@
|
|||||||
806103D71A8CD0075BF8E1DA /* Fl_Group.cxx */,
|
806103D71A8CD0075BF8E1DA /* Fl_Group.cxx */,
|
||||||
790419B5A0AD64D66F9B19E1 /* Fl_Help_View.cxx */,
|
790419B5A0AD64D66F9B19E1 /* Fl_Help_View.cxx */,
|
||||||
6DCFF326B588B1B27618F28C /* Fl_Image.cxx */,
|
6DCFF326B588B1B27618F28C /* Fl_Image.cxx */,
|
||||||
|
7F76E017192FAD590071728B /* Fl_Image_Surface.cxx */,
|
||||||
63CB19652C470F1E58DCF01E /* Fl_Input.cxx */,
|
63CB19652C470F1E58DCF01E /* Fl_Input.cxx */,
|
||||||
D531F77A15AACC9E297B4490 /* Fl_Input_.cxx */,
|
D531F77A15AACC9E297B4490 /* Fl_Input_.cxx */,
|
||||||
BA7B1E9C7AA7316E98D369C2 /* Fl_Light_Button.cxx */,
|
BA7B1E9C7AA7316E98D369C2 /* Fl_Light_Button.cxx */,
|
||||||
@@ -6219,6 +6227,7 @@
|
|||||||
C8AE10A8DDF53B8B27E3215A /* Fl_Choice.H */,
|
C8AE10A8DDF53B8B27E3215A /* Fl_Choice.H */,
|
||||||
9BCF393F94482AE7C7421397 /* Fl_Clock.H */,
|
9BCF393F94482AE7C7421397 /* Fl_Clock.H */,
|
||||||
2CD1EF8B4BFD0820E9A42641 /* Fl_Color_Chooser.H */,
|
2CD1EF8B4BFD0820E9A42641 /* Fl_Color_Chooser.H */,
|
||||||
|
7F76E019192FAD740071728B /* Fl_Copy_Surface.H */,
|
||||||
CE97D58B5B0F1A2A7DB2A3FF /* Fl_Counter.H */,
|
CE97D58B5B0F1A2A7DB2A3FF /* Fl_Counter.H */,
|
||||||
82863AEFE086C3469C386C22 /* Fl_Device.H */,
|
82863AEFE086C3469C386C22 /* Fl_Device.H */,
|
||||||
02C21BB31E7DDFE9E76F4997 /* Fl_Dial.H */,
|
02C21BB31E7DDFE9E76F4997 /* Fl_Dial.H */,
|
||||||
@@ -6241,6 +6250,7 @@
|
|||||||
AE1717E43F50EBA343960B1E /* Fl_Hor_Slider.H */,
|
AE1717E43F50EBA343960B1E /* Fl_Hor_Slider.H */,
|
||||||
5B8BFBDF9C48A998F0781C9E /* Fl_Hor_Value_Slider.H */,
|
5B8BFBDF9C48A998F0781C9E /* Fl_Hor_Value_Slider.H */,
|
||||||
332598626430923370C48554 /* Fl_Image.H */,
|
332598626430923370C48554 /* Fl_Image.H */,
|
||||||
|
7F76E01A192FAD840071728B /* Fl_Image_Surface.H */,
|
||||||
EFEEE679374D7E4191873447 /* Fl_Input.H */,
|
EFEEE679374D7E4191873447 /* Fl_Input.H */,
|
||||||
A5166C3C9311628F6E450095 /* Fl_Input_.H */,
|
A5166C3C9311628F6E450095 /* Fl_Input_.H */,
|
||||||
648E9C3B61328280244FCCA5 /* Fl_Input_Choice.H */,
|
648E9C3B61328280244FCCA5 /* Fl_Input_Choice.H */,
|
||||||
@@ -9515,6 +9525,8 @@
|
|||||||
299CB8A2848CB844BCEC7829 /* Fl_Paged_Device.cxx in Sources */,
|
299CB8A2848CB844BCEC7829 /* Fl_Paged_Device.cxx in Sources */,
|
||||||
7F74F393190D7F0500C56950 /* fl_gleam.cxx in Sources */,
|
7F74F393190D7F0500C56950 /* fl_gleam.cxx in Sources */,
|
||||||
01C68DB0192C6089000BD75C /* Fl_sleep.cxx in Sources */,
|
01C68DB0192C6089000BD75C /* Fl_sleep.cxx in Sources */,
|
||||||
|
7F76E016192FAD420071728B /* Fl_Copy_Surface.cxx in Sources */,
|
||||||
|
7F76E018192FAD590071728B /* Fl_Image_Surface.cxx in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -328,6 +328,8 @@
|
|||||||
7F66B1D912BB924C00C67B59 /* Fl_cocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */; };
|
7F66B1D912BB924C00C67B59 /* Fl_cocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */; };
|
||||||
7F66B1DA12BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */; };
|
7F66B1DA12BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */; };
|
||||||
7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */; };
|
7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */; };
|
||||||
|
7FA5C2BE192FAEBB00519823 /* Fl_Copy_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FA5C2BD192FAEBB00519823 /* Fl_Copy_Surface.cxx */; };
|
||||||
|
7FA5C2C0192FAECA00519823 /* Fl_Image_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FA5C2BF192FAECA00519823 /* Fl_Image_Surface.cxx */; };
|
||||||
7FDBB8F416B2D1EA00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92032516B1A90A000FC50F /* Localizable.strings */; };
|
7FDBB8F416B2D1EA00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92032516B1A90A000FC50F /* Localizable.strings */; };
|
||||||
7FDBB8F516B2D1EE00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92032216B1A909000FC50F /* Localizable.strings */; };
|
7FDBB8F516B2D1EE00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92032216B1A909000FC50F /* Localizable.strings */; };
|
||||||
7FDBB8F616B2D1FA00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92031F16B1A909000FC50F /* Localizable.strings */; };
|
7FDBB8F616B2D1FA00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92031F16B1A909000FC50F /* Localizable.strings */; };
|
||||||
@@ -4334,6 +4336,10 @@
|
|||||||
7F92032016B1A909000FC50F /* German */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = German; path = Localizable.strings; sourceTree = "<group>"; };
|
7F92032016B1A909000FC50F /* German */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = German; path = Localizable.strings; sourceTree = "<group>"; };
|
||||||
7F92032316B1A90A000FC50F /* Italian */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = Italian; path = Localizable.strings; sourceTree = "<group>"; };
|
7F92032316B1A90A000FC50F /* Italian */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = Italian; path = Localizable.strings; sourceTree = "<group>"; };
|
||||||
7F92032616B1A90A000FC50F /* Spanish */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = Spanish; path = Localizable.strings; sourceTree = "<group>"; };
|
7F92032616B1A90A000FC50F /* Spanish */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = Spanish; path = Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
7FA5C2BD192FAEBB00519823 /* Fl_Copy_Surface.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Copy_Surface.cxx; path = ../../src/Fl_Copy_Surface.cxx; sourceTree = SOURCE_ROOT; };
|
||||||
|
7FA5C2BF192FAECA00519823 /* Fl_Image_Surface.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Image_Surface.cxx; path = ../../src/Fl_Image_Surface.cxx; sourceTree = SOURCE_ROOT; };
|
||||||
|
7FA5C2C1192FAEE300519823 /* Fl_Image_Surface.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Image_Surface.H; path = ../../FL/Fl_Image_Surface.H; sourceTree = SOURCE_ROOT; };
|
||||||
|
7FA5C2C2192FAEF200519823 /* Fl_Copy_Surface.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Copy_Surface.H; path = ../../FL/Fl_Copy_Surface.H; sourceTree = SOURCE_ROOT; };
|
||||||
7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; };
|
7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; };
|
||||||
7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
7FFDE551171D8D0D008753A3 /* Fl_Sys_Menu_Bar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Sys_Menu_Bar.mm; path = ../../src/Fl_Sys_Menu_Bar.mm; sourceTree = SOURCE_ROOT; };
|
7FFDE551171D8D0D008753A3 /* Fl_Sys_Menu_Bar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Sys_Menu_Bar.mm; path = ../../src/Fl_Sys_Menu_Bar.mm; sourceTree = SOURCE_ROOT; };
|
||||||
@@ -5453,6 +5459,7 @@
|
|||||||
4D55C9FE101986BC47029A16 /* Fl_Choice.cxx */,
|
4D55C9FE101986BC47029A16 /* Fl_Choice.cxx */,
|
||||||
F5CAE7DC565B8398F02ED7BA /* Fl_Clock.cxx */,
|
F5CAE7DC565B8398F02ED7BA /* Fl_Clock.cxx */,
|
||||||
058BCBC36ADE724A418F1C43 /* Fl_Color_Chooser.cxx */,
|
058BCBC36ADE724A418F1C43 /* Fl_Color_Chooser.cxx */,
|
||||||
|
7FA5C2BD192FAEBB00519823 /* Fl_Copy_Surface.cxx */,
|
||||||
E9893274B0B6C5F24730235F /* Fl_Counter.cxx */,
|
E9893274B0B6C5F24730235F /* Fl_Counter.cxx */,
|
||||||
D9A7DCBAFF41CBC3DCB67C6F /* Fl_Device.cxx */,
|
D9A7DCBAFF41CBC3DCB67C6F /* Fl_Device.cxx */,
|
||||||
3AFC31503AB99F6D00BAC647 /* Fl_Dial.cxx */,
|
3AFC31503AB99F6D00BAC647 /* Fl_Dial.cxx */,
|
||||||
@@ -5465,6 +5472,7 @@
|
|||||||
806103D71A8CD0075BF8E1DA /* Fl_Group.cxx */,
|
806103D71A8CD0075BF8E1DA /* Fl_Group.cxx */,
|
||||||
790419B5A0AD64D66F9B19E1 /* Fl_Help_View.cxx */,
|
790419B5A0AD64D66F9B19E1 /* Fl_Help_View.cxx */,
|
||||||
6DCFF326B588B1B27618F28C /* Fl_Image.cxx */,
|
6DCFF326B588B1B27618F28C /* Fl_Image.cxx */,
|
||||||
|
7FA5C2BF192FAECA00519823 /* Fl_Image_Surface.cxx */,
|
||||||
63CB19652C470F1E58DCF01E /* Fl_Input.cxx */,
|
63CB19652C470F1E58DCF01E /* Fl_Input.cxx */,
|
||||||
D531F77A15AACC9E297B4490 /* Fl_Input_.cxx */,
|
D531F77A15AACC9E297B4490 /* Fl_Input_.cxx */,
|
||||||
BA7B1E9C7AA7316E98D369C2 /* Fl_Light_Button.cxx */,
|
BA7B1E9C7AA7316E98D369C2 /* Fl_Light_Button.cxx */,
|
||||||
@@ -6258,6 +6266,7 @@
|
|||||||
C8AE10A8DDF53B8B27E3215A /* Fl_Choice.H */,
|
C8AE10A8DDF53B8B27E3215A /* Fl_Choice.H */,
|
||||||
9BCF393F94482AE7C7421397 /* Fl_Clock.H */,
|
9BCF393F94482AE7C7421397 /* Fl_Clock.H */,
|
||||||
2CD1EF8B4BFD0820E9A42641 /* Fl_Color_Chooser.H */,
|
2CD1EF8B4BFD0820E9A42641 /* Fl_Color_Chooser.H */,
|
||||||
|
7FA5C2C2192FAEF200519823 /* Fl_Copy_Surface.H */,
|
||||||
CE97D58B5B0F1A2A7DB2A3FF /* Fl_Counter.H */,
|
CE97D58B5B0F1A2A7DB2A3FF /* Fl_Counter.H */,
|
||||||
82863AEFE086C3469C386C22 /* Fl_Device.H */,
|
82863AEFE086C3469C386C22 /* Fl_Device.H */,
|
||||||
02C21BB31E7DDFE9E76F4997 /* Fl_Dial.H */,
|
02C21BB31E7DDFE9E76F4997 /* Fl_Dial.H */,
|
||||||
@@ -6280,6 +6289,7 @@
|
|||||||
AE1717E43F50EBA343960B1E /* Fl_Hor_Slider.H */,
|
AE1717E43F50EBA343960B1E /* Fl_Hor_Slider.H */,
|
||||||
5B8BFBDF9C48A998F0781C9E /* Fl_Hor_Value_Slider.H */,
|
5B8BFBDF9C48A998F0781C9E /* Fl_Hor_Value_Slider.H */,
|
||||||
332598626430923370C48554 /* Fl_Image.H */,
|
332598626430923370C48554 /* Fl_Image.H */,
|
||||||
|
7FA5C2C1192FAEE300519823 /* Fl_Image_Surface.H */,
|
||||||
EFEEE679374D7E4191873447 /* Fl_Input.H */,
|
EFEEE679374D7E4191873447 /* Fl_Input.H */,
|
||||||
A5166C3C9311628F6E450095 /* Fl_Input_.H */,
|
A5166C3C9311628F6E450095 /* Fl_Input_.H */,
|
||||||
648E9C3B61328280244FCCA5 /* Fl_Input_Choice.H */,
|
648E9C3B61328280244FCCA5 /* Fl_Input_Choice.H */,
|
||||||
@@ -9552,6 +9562,8 @@
|
|||||||
CE14EC6653D4EF4779992758 /* is_right2left.c in Sources */,
|
CE14EC6653D4EF4779992758 /* is_right2left.c in Sources */,
|
||||||
9DD7A2B6D63D30C07781F446 /* is_spacing.c in Sources */,
|
9DD7A2B6D63D30C07781F446 /* is_spacing.c in Sources */,
|
||||||
299CB8A2848CB844BCEC7829 /* Fl_Paged_Device.cxx in Sources */,
|
299CB8A2848CB844BCEC7829 /* Fl_Paged_Device.cxx in Sources */,
|
||||||
|
7FA5C2BE192FAEBB00519823 /* Fl_Copy_Surface.cxx in Sources */,
|
||||||
|
7FA5C2C0192FAECA00519823 /* Fl_Image_Surface.cxx in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
+17
-1
@@ -104,6 +104,8 @@ int Fl::damage_,
|
|||||||
|
|
||||||
char *Fl::e_text = (char *)"";
|
char *Fl::e_text = (char *)"";
|
||||||
int Fl::e_length;
|
int Fl::e_length;
|
||||||
|
const char* Fl::e_clipboard_type = "";
|
||||||
|
void * Fl::e_clipboard_data = NULL;
|
||||||
|
|
||||||
Fl_Event_Dispatch Fl::e_dispatch = 0;
|
Fl_Event_Dispatch Fl::e_dispatch = 0;
|
||||||
|
|
||||||
@@ -118,6 +120,9 @@ Fl_Window *Fl::modal_; // topmost modal() window
|
|||||||
|
|
||||||
#endif // FL_DOXYGEN
|
#endif // FL_DOXYGEN
|
||||||
|
|
||||||
|
char const * const Fl::clipboard_plain_text = "text/plain";
|
||||||
|
char const * const Fl::clipboard_image = "image";
|
||||||
|
|
||||||
//
|
//
|
||||||
// 'Fl::version()' - Return the API version number...
|
// 'Fl::version()' - Return the API version number...
|
||||||
//
|
//
|
||||||
@@ -1635,12 +1640,23 @@ void Fl::selection(Fl_Widget &owner, const char* text, int len) {
|
|||||||
|
|
||||||
/** Backward compatibility only.
|
/** Backward compatibility only.
|
||||||
This calls Fl::paste(receiver, 0);
|
This calls Fl::paste(receiver, 0);
|
||||||
\see Fl::paste(Fl_Widget &receiver, int clipboard)
|
\see Fl::paste(Fl_Widget &receiver, int clipboard, const char* type)
|
||||||
*/
|
*/
|
||||||
void Fl::paste(Fl_Widget &receiver) {
|
void Fl::paste(Fl_Widget &receiver) {
|
||||||
Fl::paste(receiver, 0);
|
Fl::paste(receiver, 0);
|
||||||
}
|
}
|
||||||
|
#if FLTK_ABI_VERSION >= 10303
|
||||||
|
#elif !defined(FL_DOXYGEN)
|
||||||
|
void Fl::paste(Fl_Widget &receiver, int source)
|
||||||
|
{
|
||||||
|
Fl::paste(receiver, source, Fl::clipboard_plain_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl::copy(const char* stuff, int len, int destination) {
|
||||||
|
Fl::copy(stuff, len, destination, Fl::clipboard_plain_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <FL/fl_draw.H>
|
#include <FL/fl_draw.H>
|
||||||
|
|||||||
@@ -0,0 +1,399 @@
|
|||||||
|
//
|
||||||
|
// "$Id: Fl_Copy_Surface.cxx 9869 2013-04-09 20:11:28Z greg.ercolano $"
|
||||||
|
//
|
||||||
|
// Copy-to-clipboard code for the Fast Light Tool Kit (FLTK).
|
||||||
|
//
|
||||||
|
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||||
|
//
|
||||||
|
// This library is free software. Distribution and use rights are outlined in
|
||||||
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
|
// file is missing or damaged, see the license at:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/COPYING.php
|
||||||
|
//
|
||||||
|
// Please report all bugs and problems on the following page:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/str.php
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <FL/Fl_Copy_Surface.H>
|
||||||
|
#include <FL/Fl.H>
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#if defined(__ppc__)
|
||||||
|
#include <QuickTime/QuickTimeComponents.h>
|
||||||
|
#endif // __ppc__
|
||||||
|
|
||||||
|
Fl_Quartz_Surface_::Fl_Quartz_Surface_(int w, int h) : Fl_System_Printer(), width(w), height(h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int Fl_Quartz_Surface_::printable_rect(int *w, int *h) {
|
||||||
|
*w = width;
|
||||||
|
*h = height;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Fl_Quartz_Surface_::class_id = "Fl_Quartz_Surface_";
|
||||||
|
|
||||||
|
#elif defined(WIN32)
|
||||||
|
|
||||||
|
Fl_GDI_Surface_::Fl_GDI_Surface_() : Fl_Paged_Device() {
|
||||||
|
driver(new Fl_GDI_Graphics_Driver);
|
||||||
|
depth = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fl_GDI_Surface_::~Fl_GDI_Surface_() {
|
||||||
|
delete driver();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_GDI_Surface_::translate(int x, int y) {
|
||||||
|
GetWindowOrgEx(fl_gc, origins+depth);
|
||||||
|
SetWindowOrgEx(fl_gc, origins[depth].x - x, origins[depth].y - y, NULL);
|
||||||
|
if (depth < sizeof(origins)/sizeof(POINT)) depth++;
|
||||||
|
else Fl::warning("Fl_GDI_Surface_: translate stack overflow!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_GDI_Surface_::untranslate() {
|
||||||
|
if (depth > 0) depth--;
|
||||||
|
SetWindowOrgEx(fl_gc, origins[depth].x, origins[depth].y, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Fl_GDI_Surface_::class_id = "Fl_GDI_Surface_";
|
||||||
|
|
||||||
|
#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 pixels where drawing will occur.
|
||||||
|
*/
|
||||||
|
Fl_Copy_Surface::Fl_Copy_Surface(int w, int h) : Fl_Surface_Device(NULL)
|
||||||
|
{
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
helper = new Fl_Quartz_Surface_(width, height);
|
||||||
|
driver(helper->driver());
|
||||||
|
prepare_copy_pdf_and_tiff(w, h);
|
||||||
|
oldgc = fl_gc;
|
||||||
|
#elif defined(WIN32)
|
||||||
|
helper = new Fl_GDI_Surface_();
|
||||||
|
driver(helper->driver());
|
||||||
|
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) {
|
||||||
|
SetTextAlign(gc, TA_BASELINE|TA_LEFT);
|
||||||
|
SetBkMode(gc, TRANSPARENT);
|
||||||
|
}
|
||||||
|
#else // Xlib
|
||||||
|
helper = new Fl_Xlib_Surface_();
|
||||||
|
driver(helper->driver());
|
||||||
|
Fl::first_window()->make_current();
|
||||||
|
oldwindow = fl_xid(Fl::first_window());
|
||||||
|
xid = fl_create_offscreen(w,h);
|
||||||
|
Fl_Surface_Device *present_surface = Fl_Surface_Device::surface();
|
||||||
|
set_current();
|
||||||
|
fl_color(FL_WHITE);
|
||||||
|
fl_rectf(0, 0, w, h);
|
||||||
|
present_surface->set_current();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Destructor.
|
||||||
|
*/
|
||||||
|
Fl_Copy_Surface::~Fl_Copy_Surface()
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
complete_copy_pdf_and_tiff();
|
||||||
|
fl_gc = oldgc;
|
||||||
|
delete (Fl_Quartz_Surface_*)helper;
|
||||||
|
#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;
|
||||||
|
delete (Fl_GDI_Surface_*)helper;
|
||||||
|
#else // Xlib
|
||||||
|
fl_pop_clip();
|
||||||
|
unsigned char *data = fl_read_image(NULL,0,0,width,height,0);
|
||||||
|
fl_window = oldwindow;
|
||||||
|
_ss->set_current();
|
||||||
|
Fl::copy_image(data,width,height,1);
|
||||||
|
delete[] data;
|
||||||
|
fl_delete_offscreen(xid);
|
||||||
|
delete (Fl_Xlib_Surface_*)helper;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Copies a widget in the clipboard
|
||||||
|
|
||||||
|
\param widget any FLTK widget (e.g., standard, custom, window, GL view) to copy
|
||||||
|
\param delta_x and \param delta_y give
|
||||||
|
the position in the clipboard of the top-left corner of the widget
|
||||||
|
*/
|
||||||
|
void Fl_Copy_Surface::draw(Fl_Widget* widget, int delta_x, int delta_y)
|
||||||
|
{
|
||||||
|
helper->print_widget(widget, delta_x, delta_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_Copy_Surface::set_current()
|
||||||
|
{
|
||||||
|
#if defined(__APPLE__) || defined(WIN32)
|
||||||
|
fl_gc = gc;
|
||||||
|
fl_window = (Window)1;
|
||||||
|
Fl_Surface_Device::set_current();
|
||||||
|
#else
|
||||||
|
fl_window=xid;
|
||||||
|
_ss = Fl_Surface_Device::surface();
|
||||||
|
Fl_Surface_Device::set_current();
|
||||||
|
fl_push_no_clip();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Fl_Copy_Surface::complete_copy_pdf_and_tiff()
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
CGDataProviderRelease(prov);
|
||||||
|
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
|
||||||
|
void *mem = ( fl_mac_os_version >= 100600 ? NULL : malloc(width * height * 4) );
|
||||||
|
gc = CGBitmapContextCreate(mem, width, height, 8, width * 4, space, kCGImageAlphaNoneSkipLast);
|
||||||
|
CFRelease(space);
|
||||||
|
if (gc == NULL) { if (mem) free(mem); return; }
|
||||||
|
CGRect rect = CGRectMake(0, 0, width, height);
|
||||||
|
CGContextSetRGBFillColor(gc, 1,1,1,1);//need to clear background
|
||||||
|
CGContextFillRect(gc, rect);
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
|
||||||
|
CGContextDrawPDFPage(gc, pdfpage); // requires 10.3
|
||||||
|
#endif
|
||||||
|
CGPDFDocumentRelease(pdfdoc);
|
||||||
|
CFRelease(pdfdata);
|
||||||
|
PasteboardPutItemFlavor(clipboard, (PasteboardItemID)1, CFSTR("public.tiff"),
|
||||||
|
Fl_X::CGBitmapContextToTIFF(gc), kPasteboardFlavorNoFlags);
|
||||||
|
CFRelease(clipboard);
|
||||||
|
CGContextRelease(gc);
|
||||||
|
if (mem) free(mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
#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 {
|
||||||
|
int offset_x, offset_y; // translation between user and graphical coordinates: graphical = user + offset
|
||||||
|
int depth; // depth of translation stack
|
||||||
|
int stack_x[20], stack_y[20]; // translation stack allowing cumulative translations
|
||||||
|
public:
|
||||||
|
static const char *class_id;
|
||||||
|
const char *class_name() {return class_id;};
|
||||||
|
Fl_translated_Xlib_Graphics_Driver_() {
|
||||||
|
offset_x = 0; offset_y = 0;
|
||||||
|
depth = 0;
|
||||||
|
}
|
||||||
|
virtual ~Fl_translated_Xlib_Graphics_Driver_() {};
|
||||||
|
void translate_all(int dx, int dy) { // reversibly adds dx,dy to the offset between user and graphical coordinates
|
||||||
|
stack_x[depth] = offset_x;
|
||||||
|
stack_y[depth] = offset_y;
|
||||||
|
offset_x = stack_x[depth] + dx;
|
||||||
|
offset_y = stack_y[depth] + dy;
|
||||||
|
push_matrix();
|
||||||
|
translate(dx, dy);
|
||||||
|
if (depth < sizeof(stack_x)/sizeof(int)) depth++;
|
||||||
|
else Fl::warning("%s: translate stack overflow!", class_id);
|
||||||
|
}
|
||||||
|
void untranslate_all() { // undoes previous translate_all()
|
||||||
|
if (depth > 0) depth--;
|
||||||
|
offset_x = stack_x[depth];
|
||||||
|
offset_y = stack_y[depth];
|
||||||
|
pop_matrix();
|
||||||
|
}
|
||||||
|
void rect(int x, int y, int w, int h) { Fl_Xlib_Graphics_Driver::rect(x+offset_x, y+offset_y, w, h); }
|
||||||
|
void rectf(int x, int y, int w, int h) { Fl_Xlib_Graphics_Driver::rectf(x+offset_x, y+offset_y, w, h); }
|
||||||
|
void xyline(int x, int y, int x1) { Fl_Xlib_Graphics_Driver::xyline(x+offset_x, y+offset_y, x1+offset_x); }
|
||||||
|
void xyline(int x, int y, int x1, int y2) { Fl_Xlib_Graphics_Driver::xyline(x+offset_x, y+offset_y, x1+offset_x, y2+offset_y); }
|
||||||
|
void xyline(int x, int y, int x1, int y2, int x3) { Fl_Xlib_Graphics_Driver::xyline(x+offset_x, y+offset_y, x1+offset_x, y2+offset_y, x3+offset_x); }
|
||||||
|
void yxline(int x, int y, int y1) { Fl_Xlib_Graphics_Driver::yxline(x+offset_x, y+offset_y, y1+offset_y); }
|
||||||
|
void yxline(int x, int y, int y1, int x2) { Fl_Xlib_Graphics_Driver::yxline(x+offset_x, y+offset_y, y1+offset_y, x2+offset_x); }
|
||||||
|
void yxline(int x, int y, int y1, int x2, int y3) { Fl_Xlib_Graphics_Driver::yxline(x+offset_x, y+offset_y, y1+offset_y, x2+offset_x, y3+offset_y); }
|
||||||
|
void line(int x, int y, int x1, int y1) { Fl_Xlib_Graphics_Driver::line(x+offset_x, y+offset_y, x1+offset_x, y1+offset_y); }
|
||||||
|
void line(int x, int y, int x1, int y1, int x2, int y2) { Fl_Xlib_Graphics_Driver::line(x+offset_x, y+offset_y, x1+offset_x, y1+offset_y, x2+offset_x, y2+offset_y); }
|
||||||
|
void draw(const char* str, int n, int x, int y) {
|
||||||
|
Fl_Xlib_Graphics_Driver::draw(str, n, x+offset_x, y+offset_y);
|
||||||
|
}
|
||||||
|
void draw(int angle, const char *str, int n, int x, int y) {
|
||||||
|
Fl_Xlib_Graphics_Driver::draw(angle, str, n, x+offset_x, y+offset_y);
|
||||||
|
}
|
||||||
|
void rtl_draw(const char* str, int n, int x, int y) {
|
||||||
|
Fl_Xlib_Graphics_Driver::rtl_draw(str, n, x+offset_x, y+offset_y);
|
||||||
|
}
|
||||||
|
void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||||
|
XP += offset_x; YP += offset_y;
|
||||||
|
translate_all(-offset_x, -offset_y);
|
||||||
|
Fl_Xlib_Graphics_Driver::draw(pxm, XP, YP, WP,HP,cx,cy);
|
||||||
|
untranslate_all();
|
||||||
|
}
|
||||||
|
void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||||
|
XP += offset_x; YP += offset_y;
|
||||||
|
translate_all(-offset_x, -offset_y);
|
||||||
|
Fl_Xlib_Graphics_Driver::draw(bm, XP, YP, WP,HP,cx,cy);
|
||||||
|
untranslate_all();
|
||||||
|
}
|
||||||
|
void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||||
|
XP += offset_x; YP += offset_y;
|
||||||
|
translate_all(-offset_x, -offset_y);
|
||||||
|
Fl_Xlib_Graphics_Driver::draw(img, XP, YP, WP,HP,cx,cy);
|
||||||
|
untranslate_all();
|
||||||
|
}
|
||||||
|
void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0) {
|
||||||
|
X += offset_x; Y += offset_y;
|
||||||
|
translate_all(-offset_x, -offset_y);
|
||||||
|
Fl_Xlib_Graphics_Driver::draw_image(buf, X, Y, W,H,D,L);
|
||||||
|
untranslate_all();
|
||||||
|
}
|
||||||
|
void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3) {
|
||||||
|
X += offset_x; Y += offset_y;
|
||||||
|
translate_all(-offset_x, -offset_y);
|
||||||
|
Fl_Xlib_Graphics_Driver::draw_image(cb, data, X, Y, W,H,D);
|
||||||
|
untranslate_all();
|
||||||
|
}
|
||||||
|
void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0) {
|
||||||
|
X += offset_x; Y += offset_y;
|
||||||
|
translate_all(-offset_x, -offset_y);
|
||||||
|
Fl_Xlib_Graphics_Driver::draw_image_mono(buf, X, Y, W,H,D,L);
|
||||||
|
untranslate_all();
|
||||||
|
}
|
||||||
|
void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1) {
|
||||||
|
X += offset_x; Y += offset_y;
|
||||||
|
translate_all(-offset_x, -offset_y);
|
||||||
|
Fl_Xlib_Graphics_Driver::draw_image_mono(cb, data, X, Y, W,H,D);
|
||||||
|
untranslate_all();
|
||||||
|
}
|
||||||
|
void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) {
|
||||||
|
Fl_Xlib_Graphics_Driver::copy_offscreen(x+offset_x, y+offset_y, w, h,pixmap,srcx,srcy);
|
||||||
|
}
|
||||||
|
void push_clip(int x, int y, int w, int h) {
|
||||||
|
Fl_Xlib_Graphics_Driver::push_clip(x+offset_x, y+offset_y, w, h);
|
||||||
|
}
|
||||||
|
int not_clipped(int x, int y, int w, int h) { return Fl_Xlib_Graphics_Driver::not_clipped(x + offset_x, y + offset_y, w, h); };
|
||||||
|
int clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H) {
|
||||||
|
int retval = Fl_Xlib_Graphics_Driver::clip_box(x + offset_x, y + offset_y, w,h,X,Y,W,H);
|
||||||
|
X -= offset_x;
|
||||||
|
Y -= offset_y;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
void pie(int x, int y, int w, int h, double a1, double a2) { Fl_Xlib_Graphics_Driver::pie(x+offset_x,y+offset_y,w,h,a1,a2); }
|
||||||
|
void arc(int x, int y, int w, int h, double a1, double a2) { Fl_Xlib_Graphics_Driver::arc(x+offset_x,y+offset_y,w,h,a1,a2); }
|
||||||
|
void polygon(int x0, int y0, int x1, int y1, int x2, int y2) { Fl_Xlib_Graphics_Driver::polygon(x0+offset_x,y0+offset_y,x1+offset_x,y1+offset_y,x2+offset_x,y2+offset_y);}
|
||||||
|
void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||||
|
Fl_Xlib_Graphics_Driver::polygon(x0+offset_x,y0+offset_y,x1+offset_x,y1+offset_y,x2+offset_x,y2+offset_y,x3+offset_x,y3+offset_y);
|
||||||
|
}
|
||||||
|
void loop(int x0, int y0, int x1, int y1, int x2, int y2) {Fl_Xlib_Graphics_Driver::loop(x0+offset_x,y0+offset_y,x1+offset_x,y1+offset_y,x2+offset_x,y2+offset_y);}
|
||||||
|
void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||||
|
Fl_Xlib_Graphics_Driver::loop(x0+offset_x,y0+offset_y,x1+offset_x,y1+offset_y,x2+offset_x,y2+offset_y,x3+offset_x,y3+offset_y);
|
||||||
|
}
|
||||||
|
void point(int x, int y) { Fl_Xlib_Graphics_Driver::point(x+offset_x, y+offset_y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *Fl_translated_Xlib_Graphics_Driver_::class_id = "Fl_translated_Xlib_Graphics_Driver_";
|
||||||
|
|
||||||
|
void Fl_Xlib_Surface_::translate(int x, int y) {
|
||||||
|
((Fl_translated_Xlib_Graphics_Driver_*)driver())->translate_all(x, y);
|
||||||
|
}
|
||||||
|
void Fl_Xlib_Surface_::untranslate() {
|
||||||
|
((Fl_translated_Xlib_Graphics_Driver_*)driver())->untranslate_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
Fl_Xlib_Surface_::Fl_Xlib_Surface_() : Fl_Paged_Device() {
|
||||||
|
driver(new Fl_translated_Xlib_Graphics_Driver_());
|
||||||
|
}
|
||||||
|
Fl_Xlib_Surface_::~Fl_Xlib_Surface_() {
|
||||||
|
delete driver();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Fl_Xlib_Surface_::class_id = "Fl_Xlib_Surface_";
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// End of "$Id: $".
|
||||||
|
//
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
//
|
||||||
|
// "$Id: Fl_Image_Surface.cxx 9869 2013-04-09 20:11:28Z greg.ercolano $"
|
||||||
|
//
|
||||||
|
// Draw-to-image code for the Fast Light Tool Kit (FLTK).
|
||||||
|
//
|
||||||
|
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||||
|
//
|
||||||
|
// This library is free software. Distribution and use rights are outlined in
|
||||||
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
|
// file is missing or damaged, see the license at:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/COPYING.php
|
||||||
|
//
|
||||||
|
// Please report all bugs and problems on the following page:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/str.php
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <FL/Fl_Image_Surface.H>
|
||||||
|
#include <FL/Fl_Printer.H>
|
||||||
|
#include <FL/Fl.H>
|
||||||
|
|
||||||
|
|
||||||
|
const char *Fl_Image_Surface::class_id = "Fl_Image_Surface";
|
||||||
|
|
||||||
|
/** The constructor.
|
||||||
|
\param w and \param h give the size in pixels of the resulting image.
|
||||||
|
*/
|
||||||
|
Fl_Image_Surface::Fl_Image_Surface(int w, int h) : Fl_Surface_Device(NULL) {
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
#if !(defined(__APPLE__) || defined(WIN32))
|
||||||
|
gc = 0;
|
||||||
|
if (!fl_display) { // allows use of this class before any window is shown
|
||||||
|
fl_open_display();
|
||||||
|
gc = XCreateGC(fl_display, RootWindow(fl_display, fl_screen), 0, 0);
|
||||||
|
fl_gc = gc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
offscreen = fl_create_offscreen(w, h);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
helper = new Fl_Quartz_Flipped_Surface_(width, height);
|
||||||
|
driver(helper->driver());
|
||||||
|
#elif defined(WIN32)
|
||||||
|
helper = new Fl_GDI_Surface_();
|
||||||
|
driver(helper->driver());
|
||||||
|
#else
|
||||||
|
helper = new Fl_Xlib_Surface_();
|
||||||
|
driver(helper->driver());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The destructor.
|
||||||
|
*/
|
||||||
|
Fl_Image_Surface::~Fl_Image_Surface() {
|
||||||
|
fl_delete_offscreen(offscreen);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
delete (Fl_Quartz_Flipped_Surface_*)helper;
|
||||||
|
#elif defined(WIN32)
|
||||||
|
delete (Fl_GDI_Surface_*)helper;
|
||||||
|
#else
|
||||||
|
if (gc) { XFreeGC(fl_display, gc); fl_gc = 0; }
|
||||||
|
delete (Fl_Xlib_Surface_*)helper;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the image made of all drawings sent to the Fl_Image_Surface object.
|
||||||
|
The returned object can be safely cast to Fl_RGB_Image* and contains its own copy
|
||||||
|
of the RGB data.
|
||||||
|
*/
|
||||||
|
Fl_Image* Fl_Image_Surface::image()
|
||||||
|
{
|
||||||
|
unsigned char *data;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
CGContextFlush(offscreen);
|
||||||
|
data = fl_read_image(NULL, 0, 0, width, height, 0);
|
||||||
|
fl_end_offscreen();
|
||||||
|
#elif defined(WIN32)
|
||||||
|
fl_pop_clip();
|
||||||
|
data = fl_read_image(NULL, 0, 0, width, height, 0);
|
||||||
|
RestoreDC(fl_gc, _savedc);
|
||||||
|
DeleteDC(fl_gc);
|
||||||
|
_ss->set_current();
|
||||||
|
fl_window=_sw;
|
||||||
|
fl_gc = _sgc;
|
||||||
|
#else
|
||||||
|
fl_pop_clip();
|
||||||
|
data = fl_read_image(NULL, 0, 0, width, height, 0);
|
||||||
|
fl_window = pre_window;
|
||||||
|
previous->set_current();
|
||||||
|
#endif
|
||||||
|
Fl_RGB_Image *image = new Fl_RGB_Image(data, width, height);
|
||||||
|
image->alloc_array = 1;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draws a widget in the image surface
|
||||||
|
|
||||||
|
\param widget any FLTK widget (e.g., standard, custom, window, GL view) to draw in the image
|
||||||
|
\param delta_x and \param delta_y give
|
||||||
|
the position in the image of the top-left corner of the widget
|
||||||
|
*/
|
||||||
|
void Fl_Image_Surface::draw(Fl_Widget *widget, int delta_x, int delta_y)
|
||||||
|
{
|
||||||
|
helper->print_widget(widget, delta_x, delta_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Fl_Image_Surface::set_current()
|
||||||
|
{
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
fl_begin_offscreen(offscreen);
|
||||||
|
fl_pop_clip();
|
||||||
|
Fl_Surface_Device::set_current();
|
||||||
|
fl_push_no_clip();
|
||||||
|
#elif defined(WIN32)
|
||||||
|
_sgc=fl_gc;
|
||||||
|
_sw=fl_window;
|
||||||
|
_ss = Fl_Surface_Device::surface();
|
||||||
|
Fl_Surface_Device::set_current();
|
||||||
|
fl_gc = fl_makeDC(offscreen);
|
||||||
|
_savedc = SaveDC(fl_gc);
|
||||||
|
fl_window=(HWND)offscreen;
|
||||||
|
fl_push_no_clip();
|
||||||
|
#else
|
||||||
|
pre_window = fl_window;
|
||||||
|
fl_window = offscreen;
|
||||||
|
previous = Fl_Surface_Device::surface();
|
||||||
|
Fl_Surface_Device::set_current();
|
||||||
|
fl_push_no_clip();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
|
||||||
|
Fl_Quartz_Flipped_Surface_::Fl_Quartz_Flipped_Surface_(int w, int h) : Fl_Quartz_Surface_(w, h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_Quartz_Flipped_Surface_::translate(int x, int y) {
|
||||||
|
CGContextRestoreGState(fl_gc);
|
||||||
|
CGContextSaveGState(fl_gc);
|
||||||
|
CGContextTranslateCTM(fl_gc, x, -y);
|
||||||
|
CGContextSaveGState(fl_gc);
|
||||||
|
CGContextTranslateCTM(fl_gc, 0, height);
|
||||||
|
CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_Quartz_Flipped_Surface_::untranslate() {
|
||||||
|
CGContextRestoreGState(fl_gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Fl_Quartz_Flipped_Surface_::class_id = "Fl_Quartz_Flipped_Surface_";
|
||||||
|
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
//
|
||||||
|
// End of "$Id: $".
|
||||||
|
//
|
||||||
+180
-45
@@ -2803,8 +2803,9 @@ static void clipboard_check(void)
|
|||||||
* create a selection
|
* create a selection
|
||||||
* stuff: pointer to selected data
|
* stuff: pointer to selected data
|
||||||
* len: size of selected data
|
* len: size of selected data
|
||||||
|
* type: always "plain/text" for now
|
||||||
*/
|
*/
|
||||||
void Fl::copy(const char *stuff, int len, int clipboard) {
|
void Fl::copy(const char *stuff, int len, int clipboard, const char *type) {
|
||||||
if (!stuff || len<0) return;
|
if (!stuff || len<0) return;
|
||||||
if (len+1 > fl_selection_buffer_length[clipboard]) {
|
if (len+1 > fl_selection_buffer_length[clipboard]) {
|
||||||
delete[] fl_selection_buffer[clipboard];
|
delete[] fl_selection_buffer[clipboard];
|
||||||
@@ -2824,56 +2825,171 @@ void Fl::copy(const char *stuff, int len, int clipboard) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_plain_text_from_clipboard(char **buffer, int previous_length)
|
||||||
|
{
|
||||||
|
NSInteger length = 0;
|
||||||
|
NSPasteboard *clip = [NSPasteboard generalPasteboard];
|
||||||
|
NSString *found = [clip availableTypeFromArray:[NSArray arrayWithObjects:utf8_format, @"public.utf16-plain-text", @"com.apple.traditional-mac-plain-text", nil]];
|
||||||
|
if (found) {
|
||||||
|
NSData *data = [clip dataForType:found];
|
||||||
|
if (data) {
|
||||||
|
NSInteger len;
|
||||||
|
char *aux_c = NULL;
|
||||||
|
if (![found isEqualToString:utf8_format]) {
|
||||||
|
NSString *auxstring;
|
||||||
|
auxstring = (NSString *)CFStringCreateWithBytes(NULL,
|
||||||
|
(const UInt8*)[data bytes],
|
||||||
|
[data length],
|
||||||
|
[found isEqualToString:@"public.utf16-plain-text"] ? kCFStringEncodingUnicode : kCFStringEncodingMacRoman,
|
||||||
|
false);
|
||||||
|
aux_c = strdup([auxstring UTF8String]);
|
||||||
|
[auxstring release];
|
||||||
|
len = strlen(aux_c) + 1;
|
||||||
|
}
|
||||||
|
else len = [data length] + 1;
|
||||||
|
if ( len >= previous_length ) {
|
||||||
|
length = len;
|
||||||
|
delete[] *buffer;
|
||||||
|
*buffer = new char[len];
|
||||||
|
}
|
||||||
|
if (![found isEqualToString:utf8_format]) {
|
||||||
|
strcpy(*buffer, aux_c);
|
||||||
|
free(aux_c);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[data getBytes:*buffer];
|
||||||
|
}
|
||||||
|
(*buffer)[len - 1] = 0;
|
||||||
|
length = len - 1;
|
||||||
|
convert_crlf(*buffer, len - 1); // turn all \r characters into \n:
|
||||||
|
Fl::e_clipboard_type = Fl::clipboard_plain_text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Fl_Image* get_image_from_clipboard()
|
||||||
|
{
|
||||||
|
Fl_RGB_Image *image = NULL;
|
||||||
|
uchar *imagedata;
|
||||||
|
NSBitmapImageRep *bitmap;
|
||||||
|
NSPasteboard *clip = [NSPasteboard generalPasteboard];
|
||||||
|
NSArray *present = [clip types]; // types in pasteboard in order of decreasing preference
|
||||||
|
NSArray *possible = [NSArray arrayWithObjects:@"com.adobe.pdf", @"public.tiff", @"com.apple.pict", nil];
|
||||||
|
NSString *found = nil;
|
||||||
|
NSUInteger rank;
|
||||||
|
for (rank = 0; rank < [present count]; rank++) { // find first of possible types present in pasteboard
|
||||||
|
for (NSUInteger i = 0; i < [possible count]; i++) {
|
||||||
|
if ([[present objectAtIndex:rank] isEqualToString:[possible objectAtIndex:i]]) {
|
||||||
|
found = [present objectAtIndex:rank];
|
||||||
|
goto after_loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
after_loop:
|
||||||
|
if (found) {
|
||||||
|
NSData *data = [clip dataForType:found];
|
||||||
|
if (data) {
|
||||||
|
if ([found isEqualToString:@"public.tiff"]) {
|
||||||
|
bitmap = [NSBitmapImageRep imageRepWithData:data];
|
||||||
|
int bpp = [bitmap bytesPerPlane];
|
||||||
|
int bpr = [bitmap bytesPerRow];
|
||||||
|
int depth = [bitmap samplesPerPixel], w = bpr/depth, h = bpp/bpr;
|
||||||
|
imagedata = new uchar[w * h * depth];
|
||||||
|
memcpy(imagedata, [bitmap bitmapData], w * h * depth);
|
||||||
|
image = new Fl_RGB_Image(imagedata, w, h, depth);
|
||||||
|
image->alloc_array = 1;
|
||||||
|
}
|
||||||
|
else if ([found isEqualToString:@"com.adobe.pdf"] || [found isEqualToString:@"com.apple.pict"]) {
|
||||||
|
NSRect rect;
|
||||||
|
NSImageRep *vectorial;
|
||||||
|
NSAffineTransform *dilate = [NSAffineTransform transform];
|
||||||
|
if ([found isEqualToString:@"com.adobe.pdf"] ) {
|
||||||
|
vectorial = [NSPDFImageRep imageRepWithData:data];
|
||||||
|
rect = [(NSPDFImageRep*)vectorial bounds]; // in points = 1/72 inch
|
||||||
|
Fl_Window *win = Fl::first_window();
|
||||||
|
int screen_num = win ? Fl::screen_num(win->x(), win->y(), win->w(), win->h()) : 0;
|
||||||
|
float hr, vr;
|
||||||
|
Fl::screen_dpi(hr, vr, screen_num); // 1 inch = hr pixels = 72 points -> hr/72 pixel/point
|
||||||
|
CGFloat scale = hr/72;
|
||||||
|
[dilate scaleBy:scale];
|
||||||
|
rect.size.width *= scale;
|
||||||
|
rect.size.height *= scale;
|
||||||
|
rect = NSIntegralRect(rect);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vectorial = [NSPICTImageRep imageRepWithData:data];
|
||||||
|
rect = [(NSPICTImageRep*)vectorial boundingBox]; // in pixel, no scaling required
|
||||||
|
}
|
||||||
|
imagedata = new uchar[(int)(rect.size.width * rect.size.height) * 4];
|
||||||
|
memset(imagedata, -1, (int)(rect.size.width * rect.size.height) * 4);
|
||||||
|
bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&imagedata
|
||||||
|
pixelsWide:rect.size.width
|
||||||
|
pixelsHigh:rect.size.height
|
||||||
|
bitsPerSample:8
|
||||||
|
samplesPerPixel:3
|
||||||
|
hasAlpha:NO
|
||||||
|
isPlanar:NO
|
||||||
|
colorSpaceName:NSDeviceRGBColorSpace
|
||||||
|
bytesPerRow:rect.size.width*4
|
||||||
|
bitsPerPixel:32];
|
||||||
|
NSDictionary *dict = [NSDictionary dictionaryWithObject:bitmap
|
||||||
|
forKey:NSGraphicsContextDestinationAttributeName];
|
||||||
|
NSGraphicsContext *oldgc = [NSGraphicsContext currentContext];
|
||||||
|
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithAttributes:dict]];
|
||||||
|
[dilate concat];
|
||||||
|
[vectorial draw];
|
||||||
|
[NSGraphicsContext setCurrentContext:oldgc];
|
||||||
|
[bitmap release];
|
||||||
|
image = new Fl_RGB_Image(imagedata, rect.size.width, rect.size.height, 4);
|
||||||
|
image->alloc_array = 1;
|
||||||
|
}
|
||||||
|
Fl::e_clipboard_type = Fl::clipboard_image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
// Call this when a "paste" operation happens:
|
// Call this when a "paste" operation happens:
|
||||||
void Fl::paste(Fl_Widget &receiver, int clipboard) {
|
void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) {
|
||||||
|
if (type[0] == 0) type = Fl::clipboard_plain_text;
|
||||||
if (clipboard) {
|
if (clipboard) {
|
||||||
// see if we own the selection, if not go get it:
|
Fl::e_clipboard_type = "";
|
||||||
fl_selection_length[1] = 0;
|
if (strcmp(type, Fl::clipboard_plain_text) == 0) {
|
||||||
|
fl_selection_length[1] = get_plain_text_from_clipboard( &fl_selection_buffer[1], fl_selection_length[1]);
|
||||||
NSPasteboard *clip = [NSPasteboard generalPasteboard];
|
|
||||||
NSString *found = [clip availableTypeFromArray:[NSArray arrayWithObjects:utf8_format, @"public.utf16-plain-text", @"com.apple.traditional-mac-plain-text", nil]];
|
|
||||||
if (found) {
|
|
||||||
NSData *data = [clip dataForType:found];
|
|
||||||
if (data) {
|
|
||||||
NSInteger len;
|
|
||||||
char *aux_c = NULL;
|
|
||||||
if (![found isEqualToString:utf8_format]) {
|
|
||||||
NSString *auxstring;
|
|
||||||
auxstring = (NSString *)CFStringCreateWithBytes(NULL,
|
|
||||||
(const UInt8*)[data bytes],
|
|
||||||
[data length],
|
|
||||||
[found isEqualToString:@"public.utf16-plain-text"] ? kCFStringEncodingUnicode : kCFStringEncodingMacRoman,
|
|
||||||
false);
|
|
||||||
aux_c = strdup([auxstring UTF8String]);
|
|
||||||
[auxstring release];
|
|
||||||
len = strlen(aux_c) + 1;
|
|
||||||
}
|
|
||||||
else len = [data length] + 1;
|
|
||||||
if ( len >= fl_selection_buffer_length[1] ) {
|
|
||||||
fl_selection_buffer_length[1] = len;
|
|
||||||
delete[] fl_selection_buffer[1];
|
|
||||||
fl_selection_buffer[1] = new char[len];
|
|
||||||
}
|
|
||||||
if (![found isEqualToString:utf8_format]) {
|
|
||||||
strcpy(fl_selection_buffer[1], aux_c);
|
|
||||||
free(aux_c);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[data getBytes:fl_selection_buffer[1]];
|
|
||||||
}
|
|
||||||
fl_selection_buffer[1][len - 1] = 0;
|
|
||||||
fl_selection_length[1] = len - 1;
|
|
||||||
convert_crlf(fl_selection_buffer[1], len - 1); // turn all \r characters into \n:
|
|
||||||
}
|
}
|
||||||
}
|
else if (strcmp(type, Fl::clipboard_image) == 0) {
|
||||||
|
Fl::e_clipboard_data = get_image_from_clipboard( );
|
||||||
|
if (Fl::e_clipboard_data) {
|
||||||
|
int done = receiver.handle(FL_PASTE);
|
||||||
|
Fl::e_clipboard_type = "";
|
||||||
|
if (done == 0) {
|
||||||
|
delete (Fl_Image*)Fl::e_clipboard_data;
|
||||||
|
Fl::e_clipboard_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fl_selection_length[1] = 0;
|
||||||
}
|
}
|
||||||
Fl::e_text = fl_selection_buffer[clipboard];
|
Fl::e_text = fl_selection_buffer[clipboard];
|
||||||
Fl::e_length = fl_selection_length[clipboard];
|
Fl::e_length = fl_selection_length[clipboard];
|
||||||
if (!Fl::e_text) Fl::e_text = (char *)"";
|
if (!Fl::e_length) Fl::e_text = (char *)"";
|
||||||
receiver.handle(FL_PASTE);
|
receiver.handle(FL_PASTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Fl::clipboard_contains(const char *type) {
|
||||||
|
NSString *found = nil;
|
||||||
|
if (strcmp(type, Fl::clipboard_plain_text) == 0) {
|
||||||
|
found = [[NSPasteboard generalPasteboard] availableTypeFromArray:[NSArray arrayWithObjects:utf8_format, @"public.utf16-plain-text", @"com.apple.traditional-mac-plain-text", nil]];
|
||||||
|
}
|
||||||
|
else if (strcmp(type, Fl::clipboard_image) == 0) {
|
||||||
|
found = [[NSPasteboard generalPasteboard] availableTypeFromArray:[NSArray arrayWithObjects:@"public.tiff", @"com.adobe.pdf", @"com.apple.pict", nil]];
|
||||||
|
}
|
||||||
|
return found != nil;
|
||||||
|
}
|
||||||
|
|
||||||
int Fl_X::unlink(Fl_X *start) {
|
int Fl_X::unlink(Fl_X *start) {
|
||||||
if (start) {
|
if (start) {
|
||||||
Fl_X *pc = start;
|
Fl_X *pc = start;
|
||||||
@@ -3045,6 +3161,25 @@ static NSImage *CGBitmapContextToNSImage(CGContextRef c)
|
|||||||
return [image autorelease];
|
return [image autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CFDataRef Fl_X::CGBitmapContextToTIFF(CGContextRef c)
|
||||||
|
{ // the returned value is autoreleased
|
||||||
|
unsigned char *pdata = (unsigned char *)CGBitmapContextGetData(c);
|
||||||
|
NSBitmapImageRep *imagerep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&pdata
|
||||||
|
pixelsWide:CGBitmapContextGetWidth(c)
|
||||||
|
pixelsHigh:CGBitmapContextGetHeight(c)
|
||||||
|
bitsPerSample:8
|
||||||
|
samplesPerPixel:3
|
||||||
|
hasAlpha:NO
|
||||||
|
isPlanar:NO
|
||||||
|
colorSpaceName:NSDeviceRGBColorSpace
|
||||||
|
bytesPerRow:CGBitmapContextGetBytesPerRow(c)
|
||||||
|
bitsPerPixel:CGBitmapContextGetBitsPerPixel(c)];
|
||||||
|
NSData* tiff = [imagerep TIFFRepresentation];
|
||||||
|
[imagerep release];
|
||||||
|
return (CFDataRef)tiff;
|
||||||
|
}
|
||||||
|
|
||||||
static NSCursor *PrepareCursor(NSCursor *cursor, CGContextRef (*f)() )
|
static NSCursor *PrepareCursor(NSCursor *cursor, CGContextRef (*f)() )
|
||||||
{
|
{
|
||||||
if (cursor == nil) {
|
if (cursor == nil) {
|
||||||
@@ -3531,10 +3666,10 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
|
|||||||
[title_s drawWithRect:r options:(NSStringDrawingOptions)0 attributes:attr]; // 10.4
|
[title_s drawWithRect:r options:(NSStringDrawingOptions)0 attributes:attr]; // 10.4
|
||||||
[[NSGraphicsContext currentContext] setShouldAntialias:NO];
|
[[NSGraphicsContext currentContext] setShouldAntialias:NO];
|
||||||
[NSGraphicsContext setCurrentContext:current];
|
[NSGraphicsContext setCurrentContext:current];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
fl_font(FL_HELVETICA, 14); // the exact font is LucidaGrande 13 pts
|
fl_font(FL_HELVETICA, 14); // the exact font is LucidaGrande 13 pts
|
||||||
fl_color(FL_BLACK);
|
fl_color(FL_BLACK);
|
||||||
int x = x_offset + win->w()/2 - fl_width(title)/2;
|
int x = x_offset + win->w()/2 - fl_width(title)/2;
|
||||||
@@ -3542,7 +3677,7 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
|
|||||||
fl_push_clip(x_offset, y_offset, win->w(), bt);
|
fl_push_clip(x_offset, y_offset, win->w(), bt);
|
||||||
fl_draw(title, x, y_offset+bt/2+4);
|
fl_draw(title, x, y_offset+bt/2+4);
|
||||||
fl_pop_clip();
|
fl_pop_clip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->print_widget(win, x_offset, y_offset + bt); // print the window inner part
|
this->print_widget(win, x_offset, y_offset + bt); // print the window inner part
|
||||||
}
|
}
|
||||||
|
|||||||
+122
-26
@@ -567,7 +567,7 @@ void fl_update_clipboard(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// call this when you create a selection:
|
// call this when you create a selection:
|
||||||
void Fl::copy(const char *stuff, int len, int clipboard) {
|
void Fl::copy(const char *stuff, int len, int clipboard, const char *type) {
|
||||||
if (!stuff || len<0) return;
|
if (!stuff || len<0) return;
|
||||||
|
|
||||||
// Convert \n -> \r\n (for old apps like Notepad, DOS)
|
// Convert \n -> \r\n (for old apps like Notepad, DOS)
|
||||||
@@ -589,13 +589,11 @@ void Fl::copy(const char *stuff, int len, int clipboard) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call this when a "paste" operation happens:
|
// Call this when a "paste" operation happens:
|
||||||
void Fl::paste(Fl_Widget &receiver, int clipboard) {
|
void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) {
|
||||||
if (!clipboard || fl_i_own_selection[clipboard]) {
|
if (!clipboard || (fl_i_own_selection[clipboard] && strcmp(type, Fl::clipboard_plain_text) == 0)) {
|
||||||
// We already have it, do it quickly without window server.
|
// We already have it, do it quickly without window server.
|
||||||
// Notice that the text is clobbered if set_selection is
|
// Notice that the text is clobbered if set_selection is
|
||||||
// called in response to FL_PASTE!
|
// called in response to FL_PASTE!
|
||||||
|
|
||||||
// Convert \r\n -> \n
|
|
||||||
char *i = fl_selection_buffer[clipboard];
|
char *i = fl_selection_buffer[clipboard];
|
||||||
if (i==0L) {
|
if (i==0L) {
|
||||||
Fl::e_text = 0;
|
Fl::e_text = 0;
|
||||||
@@ -603,39 +601,137 @@ void Fl::paste(Fl_Widget &receiver, int clipboard) {
|
|||||||
}
|
}
|
||||||
Fl::e_text = new char[fl_selection_length[clipboard]+1];
|
Fl::e_text = new char[fl_selection_length[clipboard]+1];
|
||||||
char *o = Fl::e_text;
|
char *o = Fl::e_text;
|
||||||
while (*i) {
|
while (*i) { // Convert \r\n -> \n
|
||||||
if ( *i == '\r' && *(i+1) == '\n') i++;
|
if ( *i == '\r' && *(i+1) == '\n') i++;
|
||||||
else *o++ = *i++;
|
else *o++ = *i++;
|
||||||
}
|
}
|
||||||
*o = 0;
|
*o = 0;
|
||||||
Fl::e_length = (int) (o - Fl::e_text);
|
Fl::e_length = (int) (o - Fl::e_text);
|
||||||
|
Fl::e_clipboard_type = Fl::clipboard_plain_text;
|
||||||
receiver.handle(FL_PASTE);
|
receiver.handle(FL_PASTE);
|
||||||
delete [] Fl::e_text;
|
delete [] Fl::e_text;
|
||||||
Fl::e_text = 0;
|
Fl::e_text = 0;
|
||||||
} else {
|
} else if (clipboard) {
|
||||||
|
HANDLE h;
|
||||||
if (!OpenClipboard(NULL)) return;
|
if (!OpenClipboard(NULL)) return;
|
||||||
HANDLE h = GetClipboardData(CF_UNICODETEXT);
|
if (strcmp(type, Fl::clipboard_plain_text) == 0) { // we want plain text from clipboard
|
||||||
if (h) {
|
if ((h = GetClipboardData(CF_UNICODETEXT))) { // there's text in the clipboard
|
||||||
wchar_t *memLock = (wchar_t*) GlobalLock(h);
|
wchar_t *memLock = (wchar_t*) GlobalLock(h);
|
||||||
size_t utf16_len = wcslen(memLock);
|
size_t utf16_len = wcslen(memLock);
|
||||||
Fl::e_text = (char*) malloc (utf16_len * 4 + 1);
|
Fl::e_text = new char[utf16_len * 4 + 1];
|
||||||
unsigned utf8_len = fl_utf8fromwc(Fl::e_text, (unsigned) (utf16_len * 4), memLock, (unsigned) utf16_len);
|
unsigned utf8_len = fl_utf8fromwc(Fl::e_text, (unsigned) (utf16_len * 4), memLock, (unsigned) utf16_len);
|
||||||
*(Fl::e_text + utf8_len) = 0;
|
*(Fl::e_text + utf8_len) = 0;
|
||||||
LPSTR a,b;
|
GlobalUnlock(h);
|
||||||
a = b = Fl::e_text;
|
LPSTR a,b;
|
||||||
while (*a) { // strip the CRLF pairs ($%$#@^)
|
a = b = Fl::e_text;
|
||||||
if (*a == '\r' && a[1] == '\n') a++;
|
while (*a) { // strip the CRLF pairs ($%$#@^)
|
||||||
else *b++ = *a++;
|
if (*a == '\r' && a[1] == '\n') a++;
|
||||||
|
else *b++ = *a++;
|
||||||
|
}
|
||||||
|
*b = 0;
|
||||||
|
Fl::e_length = (int) (b - Fl::e_text);
|
||||||
|
Fl::e_clipboard_type = Fl::clipboard_plain_text; // indicates that the paste event is for plain UTF8 text
|
||||||
|
receiver.handle(FL_PASTE); // send the FL_PASTE event to the widget
|
||||||
|
delete[] Fl::e_text;
|
||||||
|
Fl::e_text = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*b = 0;
|
else if (strcmp(type, Fl::clipboard_image) == 0) { // we want an image from clipboard
|
||||||
Fl::e_length = (int) (b - Fl::e_text);
|
uchar *rgb = NULL;
|
||||||
receiver.handle(FL_PASTE);
|
int width, height, depth;
|
||||||
GlobalUnlock(h);
|
if ( (h = GetClipboardData(CF_DIB)) ) { // if there's a DIB in clipboard
|
||||||
free(Fl::e_text);
|
LPBITMAPINFO lpBI = (LPBITMAPINFO)GlobalLock(h) ;
|
||||||
Fl::e_text = 0;
|
width = lpBI->bmiHeader.biWidth; // bitmap width & height
|
||||||
|
height = lpBI->bmiHeader.biHeight;
|
||||||
|
if ( (lpBI->bmiHeader.biBitCount == 24 || lpBI->bmiHeader.biBitCount == 32) &&
|
||||||
|
lpBI->bmiHeader.biCompression == BI_RGB &&
|
||||||
|
lpBI->bmiHeader.biClrUsed == 0) { // direct use of the DIB data if it's RGB or RGBA
|
||||||
|
int linewidth; // row length
|
||||||
|
depth = lpBI->bmiHeader.biBitCount/8; // 3 or 4
|
||||||
|
if (depth == 3) linewidth = 4 * ((3*width + 3)/4); // row length: series of groups of 3 bytes, rounded to multiple of 4 bytes
|
||||||
|
else linewidth = 4*width;
|
||||||
|
rgb = new uchar[width * height * depth]; // will hold the image data
|
||||||
|
uchar *p = rgb, *r, rr, gg, bb;
|
||||||
|
for (int i=height-1; i>=0; i--) { // for each row, from last to first
|
||||||
|
r = (uchar*)(lpBI->bmiColors) + i*linewidth; // beginning of pixel data for the ith row
|
||||||
|
for (int j=0; j<width; j++) { // for each pixel in a row
|
||||||
|
bb = *r++; // BGR is in DIB
|
||||||
|
gg = *r++;
|
||||||
|
rr = *r++;
|
||||||
|
*p++ = rr; // we want RGB
|
||||||
|
*p++ = gg;
|
||||||
|
*p++ = bb;
|
||||||
|
if (depth == 4) *p++ = *r++; // copy alpha if present
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // the system will decode a complex DIB
|
||||||
|
void *pDIBBits = (void*)(lpBI->bmiColors);
|
||||||
|
if (lpBI->bmiHeader.biCompression == BI_BITFIELDS) pDIBBits = (void*)(lpBI->bmiColors + 3);
|
||||||
|
else if (lpBI->bmiHeader.biClrUsed > 0) pDIBBits = (void*)(lpBI->bmiColors + lpBI->bmiHeader.biClrUsed);
|
||||||
|
Fl_Offscreen off = fl_create_offscreen(width, height);
|
||||||
|
fl_begin_offscreen(off);
|
||||||
|
SetDIBitsToDevice(fl_gc, 0, 0, width, height, 0, 0, 0, height, pDIBBits, lpBI, DIB_RGB_COLORS);
|
||||||
|
rgb = fl_read_image(NULL, 0, 0, width, height);
|
||||||
|
depth = 3;
|
||||||
|
fl_end_offscreen();
|
||||||
|
fl_delete_offscreen(off);
|
||||||
|
}
|
||||||
|
GlobalUnlock(h);
|
||||||
|
}
|
||||||
|
else if ((h = GetClipboardData(CF_ENHMETAFILE))) { // if there's an enhanced metafile in clipboard
|
||||||
|
ENHMETAHEADER header;
|
||||||
|
GetEnhMetaFileHeader((HENHMETAFILE)h, sizeof(header), &header); // get structure containing metafile dimensions
|
||||||
|
width = (header.rclFrame.right - header.rclFrame.left + 1); // in .01 mm units
|
||||||
|
height = (header.rclFrame.bottom - header.rclFrame.top + 1);
|
||||||
|
HDC hdc = GetDC(NULL); // get unit correspondance between .01 mm and screen pixels
|
||||||
|
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;
|
||||||
|
width /= factorw; height /= factorh; // convert to screen pixel unit
|
||||||
|
RECT rect = {0, 0, width, height};
|
||||||
|
Fl_Offscreen off = fl_create_offscreen(width, height);
|
||||||
|
fl_begin_offscreen(off);
|
||||||
|
fl_color(FL_WHITE); fl_rectf(0,0,width, height); // draw white background
|
||||||
|
PlayEnhMetaFile(fl_gc, (HENHMETAFILE)h, &rect); // draw metafile to offscreen buffer
|
||||||
|
rgb = fl_read_image(NULL, 0, 0, width, height); // read pixels from offscreen buffer
|
||||||
|
depth = 3;
|
||||||
|
fl_end_offscreen();
|
||||||
|
fl_delete_offscreen(off);
|
||||||
|
}
|
||||||
|
if (rgb) {
|
||||||
|
Fl_RGB_Image *image = new Fl_RGB_Image(rgb, width, height, depth); // create new image from pixel data
|
||||||
|
image->alloc_array = 1;
|
||||||
|
Fl::e_clipboard_data = image;
|
||||||
|
Fl::e_clipboard_type = Fl::clipboard_image; // indicates that the paste event is for image data
|
||||||
|
int done = receiver.handle(FL_PASTE); // send FL_PASTE event to widget
|
||||||
|
Fl::e_clipboard_type = "";
|
||||||
|
if (done == 0) { // if widget did not handle the event, delete the image
|
||||||
|
Fl::e_clipboard_data = NULL;
|
||||||
|
delete image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseClipboard();
|
||||||
}
|
}
|
||||||
CloseClipboard();
|
}
|
||||||
|
|
||||||
|
int Fl::clipboard_contains(const char *type)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
if (!OpenClipboard(NULL)) return 0;
|
||||||
|
if (strcmp(type, Fl::clipboard_plain_text) == 0 || type[0] == 0) {
|
||||||
|
retval = IsClipboardFormatAvailable(CF_UNICODETEXT);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(type, Fl::clipboard_image) == 0) {
|
||||||
|
retval = IsClipboardFormatAvailable(CF_DIB) || IsClipboardFormatAvailable(CF_ENHMETAFILE);
|
||||||
|
}
|
||||||
|
CloseClipboard();
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HWND clipboard_wnd = 0;
|
static HWND clipboard_wnd = 0;
|
||||||
|
|||||||
+300
-39
@@ -34,6 +34,7 @@
|
|||||||
# include <FL/Fl_Tooltip.H>
|
# include <FL/Fl_Tooltip.H>
|
||||||
# include <FL/fl_draw.H>
|
# include <FL/fl_draw.H>
|
||||||
# include <FL/Fl_Paged_Device.H>
|
# include <FL/Fl_Paged_Device.H>
|
||||||
|
# include <FL/Fl_Shared_Image.H>
|
||||||
# include <FL/fl_ask.H>
|
# include <FL/fl_ask.H>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
@@ -335,6 +336,9 @@ static Atom fl_XaText;
|
|||||||
Atom fl_XaCompoundText;
|
Atom fl_XaCompoundText;
|
||||||
Atom fl_XaUtf8String;
|
Atom fl_XaUtf8String;
|
||||||
Atom fl_XaTextUriList;
|
Atom fl_XaTextUriList;
|
||||||
|
Atom fl_XaImageBmp;
|
||||||
|
Atom fl_XaImagePNG;
|
||||||
|
Atom fl_INCR;
|
||||||
Atom fl_NET_WM_NAME; // utf8 aware window label
|
Atom fl_NET_WM_NAME; // utf8 aware window label
|
||||||
Atom fl_NET_WM_ICON_NAME; // utf8 aware window icon name
|
Atom fl_NET_WM_ICON_NAME; // utf8 aware window icon name
|
||||||
Atom fl_NET_SUPPORTING_WM_CHECK;
|
Atom fl_NET_SUPPORTING_WM_CHECK;
|
||||||
@@ -641,6 +645,9 @@ void fl_open_display(Display* d) {
|
|||||||
fl_XaCompoundText = XInternAtom(d, "COMPOUND_TEXT", 0);
|
fl_XaCompoundText = XInternAtom(d, "COMPOUND_TEXT", 0);
|
||||||
fl_XaUtf8String = XInternAtom(d, "UTF8_STRING", 0);
|
fl_XaUtf8String = XInternAtom(d, "UTF8_STRING", 0);
|
||||||
fl_XaTextUriList = XInternAtom(d, "text/uri-list", 0);
|
fl_XaTextUriList = XInternAtom(d, "text/uri-list", 0);
|
||||||
|
fl_XaImageBmp = XInternAtom(d, "image/bmp", 0);
|
||||||
|
fl_XaImagePNG = XInternAtom(d, "image/png", 0);
|
||||||
|
fl_INCR = XInternAtom(d, "INCR", 0);
|
||||||
fl_NET_WM_NAME = XInternAtom(d, "_NET_WM_NAME", 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_WM_ICON_NAME = XInternAtom(d, "_NET_WM_ICON_NAME", 0);
|
||||||
fl_NET_SUPPORTING_WM_CHECK = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", 0);
|
fl_NET_SUPPORTING_WM_CHECK = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", 0);
|
||||||
@@ -773,15 +780,18 @@ void Fl::get_mouse(int &xx, int &yy) {
|
|||||||
Fl_Widget *fl_selection_requestor;
|
Fl_Widget *fl_selection_requestor;
|
||||||
char *fl_selection_buffer[2];
|
char *fl_selection_buffer[2];
|
||||||
int fl_selection_length[2];
|
int fl_selection_length[2];
|
||||||
|
const char * fl_selection_type[2];
|
||||||
int fl_selection_buffer_length[2];
|
int fl_selection_buffer_length[2];
|
||||||
char fl_i_own_selection[2] = {0,0};
|
char fl_i_own_selection[2] = {0,0};
|
||||||
|
|
||||||
// Call this when a "paste" operation happens:
|
// Call this when a "paste" operation happens:
|
||||||
void Fl::paste(Fl_Widget &receiver, int clipboard) {
|
void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) {
|
||||||
if (fl_i_own_selection[clipboard]) {
|
if (fl_i_own_selection[clipboard]) {
|
||||||
// We already have it, do it quickly without window server.
|
// We already have it, do it quickly without window server.
|
||||||
// Notice that the text is clobbered if set_selection is
|
// Notice that the text is clobbered if set_selection is
|
||||||
// called in response to FL_PASTE!
|
// called in response to FL_PASTE!
|
||||||
|
// However, for now, we only paste text in this function
|
||||||
|
if (fl_selection_type[clipboard] != Fl::clipboard_plain_text) return; //TODO: allow copy/paste of image within same app
|
||||||
Fl::e_text = fl_selection_buffer[clipboard];
|
Fl::e_text = fl_selection_buffer[clipboard];
|
||||||
Fl::e_length = fl_selection_length[clipboard];
|
Fl::e_length = fl_selection_length[clipboard];
|
||||||
if (!Fl::e_text) Fl::e_text = (char *)"";
|
if (!Fl::e_text) Fl::e_text = (char *)"";
|
||||||
@@ -791,10 +801,57 @@ void Fl::paste(Fl_Widget &receiver, int clipboard) {
|
|||||||
// otherwise get the window server to return it:
|
// otherwise get the window server to return it:
|
||||||
fl_selection_requestor = &receiver;
|
fl_selection_requestor = &receiver;
|
||||||
Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
|
Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
|
||||||
|
Fl::e_clipboard_type = type;
|
||||||
XConvertSelection(fl_display, property, TARGETS, property,
|
XConvertSelection(fl_display, property, TARGETS, property,
|
||||||
fl_xid(Fl::first_window()), fl_event_time);
|
fl_xid(Fl::first_window()), fl_event_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Fl::clipboard_contains(const char *type)
|
||||||
|
{
|
||||||
|
XEvent event;
|
||||||
|
Atom actual; int format; unsigned long count, remaining, i = 0;
|
||||||
|
unsigned char* portion = NULL;
|
||||||
|
Fl_Window *win = Fl::first_window();
|
||||||
|
if (!win || !fl_xid(win)) return 0;
|
||||||
|
XConvertSelection(fl_display, CLIPBOARD, TARGETS, CLIPBOARD,
|
||||||
|
fl_xid(win), fl_event_time);
|
||||||
|
XFlush(fl_display);
|
||||||
|
do { XNextEvent(fl_display, &event); i++; }
|
||||||
|
while (i < 10 && (event.type != SelectionNotify || event.xselection.property == None));
|
||||||
|
if (i >= 10) return 0;
|
||||||
|
XGetWindowProperty(fl_display,
|
||||||
|
event.xselection.requestor,
|
||||||
|
event.xselection.property,
|
||||||
|
0, 4000, 0, 0,
|
||||||
|
&actual, &format, &count, &remaining, &portion);
|
||||||
|
if (actual != XA_ATOM) return 0;
|
||||||
|
Atom t;
|
||||||
|
int retval = 0;
|
||||||
|
if (strcmp(type, Fl::clipboard_plain_text) == 0) {
|
||||||
|
for (i = 0; i<count; i++) { // searching for text data
|
||||||
|
t = ((Atom*)portion)[i];
|
||||||
|
if (t == fl_Xatextplainutf ||
|
||||||
|
t == fl_Xatextplainutf2 ||
|
||||||
|
t == fl_Xatextplain ||
|
||||||
|
t == fl_XaUtf8String) {
|
||||||
|
retval = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(type, Fl::clipboard_image) == 0) {
|
||||||
|
for (i = 0; i<count; i++) { // searching for image data
|
||||||
|
t = ((Atom*)portion)[i];
|
||||||
|
if (t == fl_XaImageBmp || t == fl_XaImagePNG) {
|
||||||
|
retval = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree(portion);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
Window fl_dnd_source_window;
|
Window fl_dnd_source_window;
|
||||||
Atom *fl_dnd_source_types; // null-terminated list of data types being supplied
|
Atom *fl_dnd_source_types; // null-terminated list of data types being supplied
|
||||||
Atom fl_dnd_type;
|
Atom fl_dnd_type;
|
||||||
@@ -859,7 +916,7 @@ static int get_xwinprop(Window wnd, Atom prop, long max_length,
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Code for copying to clipboard and DnD out of the program:
|
// Code for copying to clipboard and DnD out of the program:
|
||||||
|
|
||||||
void Fl::copy(const char *stuff, int len, int clipboard) {
|
void Fl::copy(const char *stuff, int len, int clipboard, const char *type) {
|
||||||
if (!stuff || len<0) return;
|
if (!stuff || len<0) return;
|
||||||
if (len+1 > fl_selection_buffer_length[clipboard]) {
|
if (len+1 > fl_selection_buffer_length[clipboard]) {
|
||||||
delete[] fl_selection_buffer[clipboard];
|
delete[] fl_selection_buffer[clipboard];
|
||||||
@@ -870,6 +927,77 @@ void Fl::copy(const char *stuff, int len, int clipboard) {
|
|||||||
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
|
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
|
||||||
fl_selection_length[clipboard] = len;
|
fl_selection_length[clipboard] = len;
|
||||||
fl_i_own_selection[clipboard] = 1;
|
fl_i_own_selection[clipboard] = 1;
|
||||||
|
fl_selection_type[clipboard] = Fl::clipboard_plain_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[2];
|
||||||
|
*p++=s[1];
|
||||||
|
*p++=s[0];
|
||||||
|
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::clipboard_image;
|
||||||
|
|
||||||
Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
|
Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
|
||||||
XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time);
|
XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time);
|
||||||
}
|
}
|
||||||
@@ -1047,6 +1175,62 @@ static int wasXExceptionRaised() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool getNextEvent(XEvent *event_return)
|
||||||
|
{
|
||||||
|
time_t t = time(NULL);
|
||||||
|
while(!XPending(fl_display))
|
||||||
|
{
|
||||||
|
if(time(NULL) - t > 10.0)
|
||||||
|
{
|
||||||
|
//fprintf(stderr,"Error: The XNextEvent never came...\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XNextEvent(fl_display, event_return);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long getIncrData(uchar* &data, const XSelectionEvent& selevent, long lower_bound)
|
||||||
|
{
|
||||||
|
//fprintf(stderr,"Incremental transfer starting due to INCR property\n");
|
||||||
|
size_t total = 0;
|
||||||
|
XEvent event;
|
||||||
|
XDeleteProperty(fl_display, selevent.requestor, selevent.property);
|
||||||
|
data = (uchar*)realloc(data, lower_bound);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (!getNextEvent(&event)) break;
|
||||||
|
if (event.type == PropertyNotify)
|
||||||
|
{
|
||||||
|
if (event.xproperty.state != PropertyNewValue) continue;
|
||||||
|
Atom actual_type;
|
||||||
|
int actual_format;
|
||||||
|
unsigned long nitems;
|
||||||
|
unsigned long bytes_after;
|
||||||
|
unsigned char* prop = 0;
|
||||||
|
long offset = 0;
|
||||||
|
size_t num_bytes;
|
||||||
|
//size_t slice_size = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
XGetWindowProperty(fl_display, selevent.requestor, selevent.property, offset, 70000, True,
|
||||||
|
AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop);
|
||||||
|
num_bytes = nitems * (actual_format / 8);
|
||||||
|
offset += num_bytes/4;
|
||||||
|
//slice_size += num_bytes;
|
||||||
|
if (total + num_bytes > lower_bound) data = (uchar*)realloc(data, total + num_bytes);
|
||||||
|
memcpy(data + total, prop, num_bytes); total += num_bytes;
|
||||||
|
if (prop) XFree(prop);
|
||||||
|
} while (bytes_after != 0);
|
||||||
|
//fprintf(stderr,"INCR data size:%ld\n", slice_size);
|
||||||
|
if (num_bytes == 0) break;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
XDeleteProperty(fl_display, selevent.requestor, selevent.property);
|
||||||
|
return (long)total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int fl_handle(const XEvent& thisevent)
|
int fl_handle(const XEvent& thisevent)
|
||||||
{
|
{
|
||||||
@@ -1139,6 +1323,7 @@ int fl_handle(const XEvent& thisevent)
|
|||||||
|
|
||||||
case SelectionNotify: {
|
case SelectionNotify: {
|
||||||
static unsigned char* sn_buffer = 0;
|
static unsigned char* sn_buffer = 0;
|
||||||
|
//static const char *buffer_format = 0;
|
||||||
if (sn_buffer) {XFree(sn_buffer); sn_buffer = 0;}
|
if (sn_buffer) {XFree(sn_buffer); sn_buffer = 0;}
|
||||||
long bytesread = 0;
|
long bytesread = 0;
|
||||||
if (fl_xevent->xselection.property) for (;;) {
|
if (fl_xevent->xselection.property) for (;;) {
|
||||||
@@ -1150,7 +1335,7 @@ int fl_handle(const XEvent& thisevent)
|
|||||||
if (XGetWindowProperty(fl_display,
|
if (XGetWindowProperty(fl_display,
|
||||||
fl_xevent->xselection.requestor,
|
fl_xevent->xselection.requestor,
|
||||||
fl_xevent->xselection.property,
|
fl_xevent->xselection.property,
|
||||||
bytesread/4, 65536, 1, 0,
|
bytesread/4, 65536, 0/*1*/, AnyPropertyType,
|
||||||
&actual, &format, &count, &remaining,
|
&actual, &format, &count, &remaining,
|
||||||
&portion)) break; // quit on error
|
&portion)) break; // quit on error
|
||||||
|
|
||||||
@@ -1168,9 +1353,24 @@ int fl_handle(const XEvent& thisevent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (actual == TARGETS || actual == XA_ATOM) {
|
if (actual == TARGETS || actual == XA_ATOM) {
|
||||||
Atom type = XA_STRING;
|
/*for (unsigned i = 0; i<count; i++) {
|
||||||
for (unsigned i = 0; i<count; i++) {
|
fprintf(stderr," %s", XGetAtomName(fl_display, ((Atom*)portion)[i]) );
|
||||||
Atom t = ((Atom*)portion)[i];
|
}
|
||||||
|
fprintf(stderr,"\n");*/
|
||||||
|
Atom t, type = XA_STRING;
|
||||||
|
if (Fl::e_clipboard_type == Fl::clipboard_image) { // searching for image data
|
||||||
|
for (unsigned i = 0; i<count; i++) {
|
||||||
|
t = ((Atom*)portion)[i];
|
||||||
|
if (t == fl_XaImageBmp || t == fl_XaImagePNG) {
|
||||||
|
type = t;
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFree(portion);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i<count; i++) { // searching for text data
|
||||||
|
t = ((Atom*)portion)[i];
|
||||||
if (t == fl_Xatextplainutf ||
|
if (t == fl_Xatextplainutf ||
|
||||||
t == fl_Xatextplainutf2 ||
|
t == fl_Xatextplainutf2 ||
|
||||||
t == fl_Xatextplain ||
|
t == fl_Xatextplain ||
|
||||||
@@ -1183,14 +1383,33 @@ int fl_handle(const XEvent& thisevent)
|
|||||||
t == fl_XaTextUriList ||
|
t == fl_XaTextUriList ||
|
||||||
t == fl_XaCompoundText) type = t;
|
t == fl_XaCompoundText) type = t;
|
||||||
}
|
}
|
||||||
|
found:
|
||||||
XFree(portion); portion = 0;
|
XFree(portion); portion = 0;
|
||||||
Atom property = xevent.xselection.property;
|
Atom property = xevent.xselection.property;
|
||||||
XConvertSelection(fl_display, property, type, property,
|
XConvertSelection(fl_display, property, type, property,
|
||||||
fl_xid(Fl::first_window()),
|
fl_xid(Fl::first_window()),
|
||||||
fl_event_time);
|
fl_event_time);
|
||||||
|
if (type == fl_XaImageBmp) {
|
||||||
|
Fl::e_clipboard_type = Fl::clipboard_image;
|
||||||
|
//buffer_format = "image/bmp";
|
||||||
|
}
|
||||||
|
else if (type == fl_XaImagePNG) {
|
||||||
|
Fl::e_clipboard_type = Fl::clipboard_image;
|
||||||
|
//buffer_format = "image/png";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Fl::e_clipboard_type = Fl::clipboard_plain_text;
|
||||||
|
//buffer_format = Fl::clipboard_plain_text;
|
||||||
|
}
|
||||||
|
//fprintf(stderr,"used format=%s\n", buffer_format);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Make sure we got something sane...
|
if (actual == fl_INCR) {
|
||||||
|
bytesread = getIncrData(sn_buffer, xevent.xselection, *(long*)portion);
|
||||||
|
XFree(portion);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Make sure we got something sane...
|
||||||
if ((portion == NULL) || (format != 8) || (count == 0)) {
|
if ((portion == NULL) || (format != 8) || (count == 0)) {
|
||||||
if (portion) { XFree(portion); portion = 0; }
|
if (portion) { XFree(portion); portion = 0; }
|
||||||
return true;
|
return true;
|
||||||
@@ -1203,22 +1422,45 @@ int fl_handle(const XEvent& thisevent)
|
|||||||
sn_buffer[bytesread] = '\0';
|
sn_buffer[bytesread] = '\0';
|
||||||
if (!remaining) break;
|
if (!remaining) break;
|
||||||
}
|
}
|
||||||
if (sn_buffer) {
|
if (sn_buffer && Fl::e_clipboard_type == Fl::clipboard_plain_text) {
|
||||||
sn_buffer[bytesread] = 0;
|
sn_buffer[bytesread] = 0;
|
||||||
convert_crlf(sn_buffer, bytesread);
|
convert_crlf(sn_buffer, bytesread);
|
||||||
}
|
}
|
||||||
|
if (Fl::e_clipboard_type == Fl::clipboard_image) {
|
||||||
|
if (bytesread == 0) return 0;
|
||||||
|
Fl_Image *image = 0;
|
||||||
|
static char tmp_fname[21];
|
||||||
|
static Fl_Shared_Image *shared = 0;
|
||||||
|
strcpy(tmp_fname, "/tmp/clipboardXXXXXX");
|
||||||
|
int fd = mkstemp(tmp_fname);
|
||||||
|
if (fd == -1) return 0;
|
||||||
|
uchar *p = sn_buffer; ssize_t towrite = bytesread, written;
|
||||||
|
while (towrite) {
|
||||||
|
written = write(fd, p, towrite);
|
||||||
|
p += written; towrite -= written;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
free(sn_buffer); sn_buffer = 0;
|
||||||
|
shared = Fl_Shared_Image::get(tmp_fname);
|
||||||
|
unlink(tmp_fname);
|
||||||
|
if (!shared) return 0;
|
||||||
|
image = shared->copy();
|
||||||
|
shared->release();
|
||||||
|
Fl::e_clipboard_data = (void*)image;
|
||||||
|
}
|
||||||
if (!fl_selection_requestor) return 0;
|
if (!fl_selection_requestor) return 0;
|
||||||
|
|
||||||
Fl::e_text = sn_buffer ? (char*)sn_buffer : (char *)"";
|
if (Fl::e_clipboard_type == Fl::clipboard_plain_text) {
|
||||||
Fl::e_length = bytesread;
|
Fl::e_text = sn_buffer ? (char*)sn_buffer : (char *)"";
|
||||||
|
Fl::e_length = bytesread;
|
||||||
|
}
|
||||||
int old_event = Fl::e_number;
|
int old_event = Fl::e_number;
|
||||||
fl_selection_requestor->handle(Fl::e_number = FL_PASTE);
|
fl_selection_requestor->handle(Fl::e_number = FL_PASTE);
|
||||||
Fl::e_number = old_event;
|
Fl::e_number = old_event;
|
||||||
// Detect if this paste is due to Xdnd by the property name (I use
|
// Detect if this paste is due to Xdnd by the property name (I use
|
||||||
// XA_SECONDARY for that) and send an XdndFinished message. It is not
|
// XA_SECONDARY for that) and send an XdndFinished message. It is not
|
||||||
// clear if this has to be delayed until now or if it can be done
|
// clear if this has to be delayed until now or if it can be done
|
||||||
// immediatly after calling XConvertSelection.
|
// immediately after calling XConvertSelection.
|
||||||
if (fl_xevent->xselection.property == XA_SECONDARY &&
|
if (fl_xevent->xselection.property == XA_SECONDARY &&
|
||||||
fl_dnd_source_window) {
|
fl_dnd_source_window) {
|
||||||
fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished,
|
fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished,
|
||||||
@@ -1242,32 +1484,51 @@ int fl_handle(const XEvent& thisevent)
|
|||||||
e.target = fl_xevent->xselectionrequest.target;
|
e.target = fl_xevent->xselectionrequest.target;
|
||||||
e.time = fl_xevent->xselectionrequest.time;
|
e.time = fl_xevent->xselectionrequest.time;
|
||||||
e.property = fl_xevent->xselectionrequest.property;
|
e.property = fl_xevent->xselectionrequest.property;
|
||||||
if (e.target == TARGETS) {
|
if (fl_selection_type[clipboard] == Fl::clipboard_plain_text) {
|
||||||
Atom a[3] = {fl_XaUtf8String, XA_STRING, fl_XaText};
|
if (e.target == TARGETS) {
|
||||||
XChangeProperty(fl_display, e.requestor, e.property,
|
Atom a[3] = {fl_XaUtf8String, XA_STRING, fl_XaText};
|
||||||
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,
|
XChangeProperty(fl_display, e.requestor, e.property,
|
||||||
e.target, 8, 0,
|
XA_ATOM, atom_bits, 0, (unsigned char*)a, 3);
|
||||||
(unsigned char *)fl_selection_buffer[clipboard],
|
} else {
|
||||||
fl_selection_length[clipboard]);
|
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 { // 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 {
|
||||||
|
e.property = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} 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);}
|
XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1517,13 +1778,13 @@ int fl_handle(const XEvent& thisevent)
|
|||||||
// Display * display ;
|
// Display * display ;
|
||||||
// Bool detectable ;
|
// Bool detectable ;
|
||||||
// Bool * supported_rtrn ;
|
// Bool * supported_rtrn ;
|
||||||
// ...would be the easy way to corrct this isuue. Unfortunatly, this call is also
|
// ...would be the easy way to correct this issue. Unfortunately, this call is also
|
||||||
// broken on many Unix distros including Ubuntu and Solaris (as of Dec 2009)
|
// broken on many Unix distros including Ubuntu and Solaris (as of Dec 2009)
|
||||||
|
|
||||||
// Bogus KeyUp events are generated by repeated KeyDown events. One
|
// Bogus KeyUp events are generated by repeated KeyDown events. One
|
||||||
// neccessary condition is an identical key event pending right after
|
// necessary condition is an identical key event pending right after
|
||||||
// the bogus KeyUp.
|
// the bogus KeyUp.
|
||||||
// The new code introduced Dec 2009 differs in that it only check the very
|
// The new code introduced Dec 2009 differs in that it only checks the very
|
||||||
// next event in the queue, not the entire queue of events.
|
// next event in the queue, not the entire queue of events.
|
||||||
// This function wrongly detects a repeat key if a software keyboard
|
// This function wrongly detects a repeat key if a software keyboard
|
||||||
// sends a burst of events containing two consecutive equal keys. However,
|
// sends a burst of events containing two consecutive equal keys. However,
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ CPPFILES = \
|
|||||||
Fl_Choice.cxx \
|
Fl_Choice.cxx \
|
||||||
Fl_Clock.cxx \
|
Fl_Clock.cxx \
|
||||||
Fl_Color_Chooser.cxx \
|
Fl_Color_Chooser.cxx \
|
||||||
|
Fl_Copy_Surface.cxx \
|
||||||
Fl_Counter.cxx \
|
Fl_Counter.cxx \
|
||||||
Fl_Dial.cxx \
|
Fl_Dial.cxx \
|
||||||
Fl_Device.cxx \
|
Fl_Device.cxx \
|
||||||
@@ -43,6 +44,7 @@ CPPFILES = \
|
|||||||
Fl_Group.cxx \
|
Fl_Group.cxx \
|
||||||
Fl_Help_View.cxx \
|
Fl_Help_View.cxx \
|
||||||
Fl_Image.cxx \
|
Fl_Image.cxx \
|
||||||
|
Fl_Image_Surface.cxx \
|
||||||
Fl_Input.cxx \
|
Fl_Input.cxx \
|
||||||
Fl_Input_.cxx \
|
Fl_Input_.cxx \
|
||||||
Fl_Light_Button.cxx \
|
Fl_Light_Button.cxx \
|
||||||
|
|||||||
+77
-47
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <FL/Fl_Overlay_Window.H>
|
#include <FL/Fl_Overlay_Window.H>
|
||||||
#include <FL/Fl_Light_Button.H>
|
#include <FL/Fl_Light_Button.H>
|
||||||
|
#include <FL/Fl_Radio_Round_Button.H>
|
||||||
#include <FL/fl_draw.H>
|
#include <FL/fl_draw.H>
|
||||||
#include <FL/Fl_Clock.H>
|
#include <FL/Fl_Clock.H>
|
||||||
#include "pixmaps/porsche.xpm"
|
#include "pixmaps/porsche.xpm"
|
||||||
@@ -30,8 +31,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <FL/Fl_Printer.H>
|
#include <FL/Fl_Printer.H>
|
||||||
|
#include <FL/Fl_Copy_Surface.H>
|
||||||
//#include "fl_printer_chooser.H"
|
#include <FL/Fl_Image_Surface.H>
|
||||||
|
|
||||||
#include <FL/Fl_File_Chooser.H>
|
#include <FL/Fl_File_Chooser.H>
|
||||||
#include <FL/fl_draw.H>
|
#include <FL/fl_draw.H>
|
||||||
@@ -448,7 +449,6 @@ class MyWidget5: public Fl_Box{
|
|||||||
protected:
|
protected:
|
||||||
void draw(){
|
void draw(){
|
||||||
Fl_Box::draw();
|
Fl_Box::draw();
|
||||||
//fl_push_clip(x(),y(),w(),h());
|
|
||||||
fl_push_matrix();
|
fl_push_matrix();
|
||||||
|
|
||||||
fl_translate(x(),y());
|
fl_translate(x(),y());
|
||||||
@@ -512,11 +512,6 @@ protected:
|
|||||||
fl_end_complex_polygon();
|
fl_end_complex_polygon();
|
||||||
|
|
||||||
fl_pop_matrix();
|
fl_pop_matrix();
|
||||||
|
|
||||||
// fl_color(FL_BLACK);
|
|
||||||
// fl_line_style(0);
|
|
||||||
//fl_pop_clip();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
MyWidget5(int x, int y):Fl_Box(x,y,230,250, "Complex (double) drawings:\nBlue ellipse may not be\ncorrectly transformed\ndue to non-orthogonal\ntransformation"){
|
MyWidget5(int x, int y):Fl_Box(x,y,230,250, "Complex (double) drawings:\nBlue ellipse may not be\ncorrectly transformed\ndue to non-orthogonal\ntransformation"){
|
||||||
@@ -551,37 +546,53 @@ void make_image() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void print(Fl_Widget *, void *w) {
|
Fl_Widget *target;
|
||||||
Fl_Widget * g = (Fl_Widget *)w;
|
const char *operation;
|
||||||
|
|
||||||
Fl_Printer * p = new Fl_Printer();
|
|
||||||
if (!p->start_job(1)) {
|
|
||||||
p->start_page();
|
|
||||||
p->print_window(g->window());
|
|
||||||
p->end_page();
|
|
||||||
p->end_job();
|
|
||||||
}
|
|
||||||
delete p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*void print2(Fl_Widget *, void *w) {
|
void copy(Fl_Widget *, void *data) {
|
||||||
Fl_Widget * g = (Fl_Widget *)w;
|
if (strcmp(operation, "Fl_Image_Surface") == 0) {
|
||||||
Fl_Printer * p = fl_printer_chooser();
|
Fl_Image_Surface *rgb_surf = new Fl_Image_Surface(target->w()+20, target->h()+10);
|
||||||
if(!p) return;
|
rgb_surf->set_current();
|
||||||
p->page(Fl_Printer::A4);
|
fl_color(FL_BLUE);fl_rectf(0,0,1000,1000);
|
||||||
// fitting inside margins 1 inch wide
|
rgb_surf->draw(target,10,5);
|
||||||
p->place(g, FL_INCH, FL_INCH, p->page_width() - 2 * FL_INCH, p->page_height() - 2 * FL_INCH, FL_ALIGN_CENTER);
|
Fl_Image *img = rgb_surf->image();
|
||||||
Fl_Device * c = p->set_current();
|
delete rgb_surf;
|
||||||
fl_draw(g);
|
Fl_Display_Device::display_device()->set_current();
|
||||||
c->set_current();
|
Fl_Window* g2 = new Fl_Window(img->w(), img->h());
|
||||||
delete p;
|
Fl_Box *b = new Fl_Box(FL_NO_BOX,0,0,img->w(), img->h(),0);
|
||||||
};*/
|
b->image(img);
|
||||||
|
g2->end();
|
||||||
|
g2->show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (strcmp(operation, "Fl_Copy_Surface") == 0) {
|
||||||
|
Fl_Copy_Surface *copy_surf = new Fl_Copy_Surface(target->w()+10, target->h()+20);
|
||||||
|
copy_surf->set_current();
|
||||||
|
fl_color(FL_YELLOW);fl_rectf(0,0,1000,1000);
|
||||||
|
copy_surf->draw(target, 5, 10);
|
||||||
|
delete copy_surf;
|
||||||
|
Fl_Display_Device::display_device()->set_current();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(operation, "Fl_Printer") == 0) {
|
||||||
|
Fl_Printer * p = new Fl_Printer();
|
||||||
|
if (!p->start_job(1)) {
|
||||||
|
p->start_page();
|
||||||
|
if (target->as_window()) p->print_window(target->as_window());
|
||||||
|
else p->print_widget(target);
|
||||||
|
p->end_page();
|
||||||
|
p->end_job();
|
||||||
|
}
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class My_Button:public Fl_Button{
|
class My_Button:public Fl_Button{
|
||||||
protected:
|
protected:
|
||||||
void draw(){
|
void draw(){
|
||||||
// Fl_Button::draw();
|
|
||||||
if (type() == FL_HIDDEN_BUTTON) return;
|
if (type() == FL_HIDDEN_BUTTON) return;
|
||||||
Fl_Color col = value() ? selection_color() : color();
|
Fl_Color col = value() ? selection_color() : color();
|
||||||
draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col);
|
draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col);
|
||||||
@@ -598,15 +609,22 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void target_cb(Fl_Widget* wid, void *data)
|
||||||
|
{
|
||||||
|
target = (Fl_Widget*)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operation_cb(Fl_Widget* wid, void *data)
|
||||||
|
{
|
||||||
|
operation = wid->label();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
|
|
||||||
//Fl::scheme("plastic");
|
//Fl::scheme("plastic");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Fl_Window * w2 = new Fl_Window(500,560,"Graphics test");
|
Fl_Window * w2 = new Fl_Window(500,560,"Graphics test");
|
||||||
|
|
||||||
|
|
||||||
Fl_Group *c2 =new Fl_Group(3, 43, 494, 514 );
|
Fl_Group *c2 =new Fl_Group(3, 43, 494, 514 );
|
||||||
|
|
||||||
new MyWidget(10,140);
|
new MyWidget(10,140);
|
||||||
@@ -643,14 +661,12 @@ int main(int argc, char ** argv) {
|
|||||||
but5.labelfont(FL_BOLD|FL_ITALIC);
|
but5.labelfont(FL_BOLD|FL_ITALIC);
|
||||||
but5.labeltype(FL_SHADOW_LABEL);
|
but5.labeltype(FL_SHADOW_LABEL);
|
||||||
but5.box(FL_ROUND_UP_BOX);
|
but5.box(FL_ROUND_UP_BOX);
|
||||||
// but5.selection_color(FL_WHITE);
|
|
||||||
|
|
||||||
Fl_Button but6(360, 460, 120, 30, "Plastic");
|
Fl_Button but6(360, 460, 120, 30, "Plastic");
|
||||||
but6.box(FL_PLASTIC_UP_BOX);
|
but6.box(FL_PLASTIC_UP_BOX);
|
||||||
|
|
||||||
//Fl_Button but7(, 480, 120, 30, "Engraved box");
|
Fl_Group *group;
|
||||||
//but7.box(FL_ENGRAVED_BOX);
|
{ Fl_Group* o = new Fl_Group(360, 495, 120, 40); group=o;
|
||||||
{ Fl_Group* o = new Fl_Group(360, 495, 120, 40);
|
|
||||||
o->box(FL_UP_BOX);
|
o->box(FL_UP_BOX);
|
||||||
{ Fl_Group* o = new Fl_Group(365, 500, 110, 30);
|
{ Fl_Group* o = new Fl_Group(365, 500, 110, 30);
|
||||||
o->box(FL_THIN_UP_FRAME);
|
o->box(FL_THIN_UP_FRAME);
|
||||||
@@ -673,16 +689,30 @@ int main(int argc, char ** argv) {
|
|||||||
tx.hide();
|
tx.hide();
|
||||||
|
|
||||||
c2->end();
|
c2->end();
|
||||||
Fl_Button *b4 = new Fl_Button(10,5, 150, 25, "Print");
|
|
||||||
b4->callback(print,c2);
|
Fl_Radio_Round_Button *rb;
|
||||||
/*Fl_Button *b5 = new Fl_Button(165,5, 90, 25, "Print");
|
Fl_Window *w3 = new Fl_Window(2,5,w2->w()-10,55);
|
||||||
b5->tooltip("This is a tooltip");
|
w3->box(FL_DOWN_BOX);
|
||||||
b5->callback(print2,c2);*/
|
Fl_Group *g1 = new Fl_Group(w3->x(),w3->y(),w3->w(),w3->h());
|
||||||
|
rb = new Fl_Radio_Round_Button(5,5,150,12, "Fl_Image_Surface");
|
||||||
|
rb->set(); rb->callback(operation_cb, NULL); operation = rb->label();
|
||||||
|
rb = new Fl_Radio_Round_Button(5,22,150,12, "Fl_Copy_Surface"); rb->callback(operation_cb, NULL);
|
||||||
|
rb = new Fl_Radio_Round_Button(5,39,150,12, "Fl_Printer"); rb->callback(operation_cb, NULL);
|
||||||
|
g1->end();
|
||||||
|
|
||||||
|
Fl_Group *g2 = new Fl_Group(w3->x(),w3->y(),w3->w(),w3->h());
|
||||||
|
rb = new Fl_Radio_Round_Button(170,5,150,12, "Window");
|
||||||
|
rb->set(); rb->callback(target_cb, w2); target = w2;
|
||||||
|
rb = new Fl_Radio_Round_Button(170,22,150,12, "Sub-window"); rb->callback(target_cb, w3);
|
||||||
|
rb = new Fl_Radio_Round_Button(170,39,150,12, "Group"); rb->callback(target_cb, group);
|
||||||
|
g2->end();
|
||||||
|
Fl_Button *b4 = new Fl_Button(330, (w3->h() - 25)/2, 150, 25, "GO");
|
||||||
|
b4->callback((Fl_Callback*)copy,NULL);
|
||||||
|
w3->end();
|
||||||
|
|
||||||
w2->end();
|
w2->end();
|
||||||
w2->show(argc, argv);
|
w2->show(argc, argv);
|
||||||
|
|
||||||
|
|
||||||
Fl::run();
|
Fl::run();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user