summaryrefslogtreecommitdiff
path: root/src/Fl_cutpaste_win32.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Fl_cutpaste_win32.cxx')
-rw-r--r--src/Fl_cutpaste_win32.cxx106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/Fl_cutpaste_win32.cxx b/src/Fl_cutpaste_win32.cxx
new file mode 100644
index 000000000..de60c8ed2
--- /dev/null
+++ b/src/Fl_cutpaste_win32.cxx
@@ -0,0 +1,106 @@
+// Fl_cutpaste_win32.C
+
+// Implementation of cut and paste.
+
+// This is seperated from Fl.C mostly to test Fl::add_handler().
+// But this will save a small amount of code size in a program that
+// has no text editing fields or other things that call cut or paste.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Widget.H>
+#include <string.h>
+
+static char *selection_buffer;
+static int selection_length;
+static int selection_buffer_length;
+static char beenhere;
+
+extern Fl_Widget *fl_selection_requestor; // widget doing request_paste()
+
+static int selection_xevent_handler(int) {
+
+ switch (fl_msg.message) {
+
+ case WM_DESTROYCLIPBOARD:
+ Fl::selection_owner(0);
+ Fl::flush(); // get the redraw to happen
+ return 1;
+
+ case WM_RENDERALLFORMATS:
+ if (!OpenClipboard(fl_xid(Fl::first_window()))) return 0;
+ EmptyClipboard();
+ // fall through...
+ case WM_RENDERFORMAT: {
+ HANDLE h = GlobalAlloc(GHND, selection_length+1);
+ if (h) {
+ LPSTR p = (LPSTR)GlobalLock(h);
+ memcpy(p, selection_buffer, selection_length);
+ p[selection_length] = 0;
+ GlobalUnlock(h);
+ SetClipboardData(CF_TEXT, h);
+ }
+ if (fl_msg.message == WM_RENDERALLFORMATS)
+ CloseClipboard();
+ return 1;}
+
+ default:
+ return 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+// call this when you create a selection:
+void Fl::selection(Fl_Widget &owner, const char *stuff, int len) {
+ if (!stuff || len<=0) return;
+ if (len+1 > selection_buffer_length) {
+ delete[] selection_buffer;
+ selection_buffer = new char[len+100];
+ selection_buffer_length = len+100;
+ }
+ memcpy(selection_buffer, stuff, len);
+ selection_buffer[len] = 0; // needed for direct paste
+ selection_length = len;
+ if (OpenClipboard(fl_xid(Fl::first_window()))) {
+ EmptyClipboard();
+ SetClipboardData(CF_TEXT, NULL);
+ CloseClipboard();
+ if (!beenhere) {
+ Fl::add_handler(selection_xevent_handler);
+ beenhere = 1;
+ }
+ }
+ selection_owner(&owner);
+}
+
+////////////////////////////////////////////////////////////////
+
+// Call this when a "paste" operation happens:
+void Fl::paste(Fl_Widget &receiver) {
+ if (selection_owner()) {
+ // We already have it, do it quickly without window server.
+ // Notice that the text is clobbered if set_selection is
+ // called in response to FL_PASTE!
+ Fl::e_text = selection_buffer;
+ Fl::e_length = selection_length;
+ receiver.handle(FL_PASTE);
+ } else {
+ if (!OpenClipboard(fl_xid(Fl::first_window()))) return;
+ HANDLE h = GetClipboardData(CF_TEXT);
+ if (h) {
+ Fl::e_text = (LPSTR)GlobalLock(h);
+ LPSTR a,b;
+ a = b = Fl::e_text;
+ while (*a) { // strip the CRLF pairs ($%$#@^)
+ if (*a == '\r' && a[1] == '\n') a++;
+ else *b++ = *a++;
+ }
+ *b = 0;
+ Fl::e_length = b - Fl::e_text;
+ receiver.handle(FL_PASTE);
+ GlobalUnlock(h);
+ }
+ CloseClipboard();
+ }
+}