comparison src/select-msw.c @ 404:2f8bb876ab1d r21-2-32

Import from CVS: tag r21-2-32
author cvs
date Mon, 13 Aug 2007 11:16:07 +0200
parents a86b2b5e0111
children de805c49cfc1
comparison
equal deleted inserted replaced
403:9f011ab08d48 404:2f8bb876ab1d
32 #include "frame.h" 32 #include "frame.h"
33 #include "select.h" 33 #include "select.h"
34 34
35 #include "console-msw.h" 35 #include "console-msw.h"
36 36
37 DEFUN ("mswindows-set-clipboard", Fmswindows_set_clipboard, 1, 1, 0, /*
38 Copy STRING to the mswindows clipboard.
39 */
40 (string))
41 {
42 int rawsize, size, i;
43 unsigned char *src, *dst, *next;
44 HGLOBAL h = NULL;
45 struct frame *f = NULL;
46
47 CHECK_STRING (string);
48
49 /* Calculate size with LFs converted to CRLFs because
50 * CF_TEXT format uses CRLF delimited ASCIIZ */
51 src = XSTRING_DATA (string);
52 size = rawsize = XSTRING_LENGTH (string) + 1;
53 for (i=0; i<rawsize; i++)
54 if (src[i] == '\n')
55 size++;
56
57 f = selected_frame ();
58 if (!OpenClipboard (FRAME_MSWINDOWS_HANDLE (f)))
59 return Qnil;
60
61 if (!EmptyClipboard () ||
62 (h = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, size)) == NULL ||
63 (dst = (unsigned char *) GlobalLock (h)) == NULL)
64 {
65 if (h != NULL) GlobalFree (h);
66 CloseClipboard ();
67 return Qnil;
68 }
69
70 /* Convert LFs to CRLFs */
71 do
72 {
73 /* copy next line or remaining bytes including '\0' */
74 next = (char*) memccpy (dst, src, '\n', rawsize);
75 if (next)
76 {
77 /* copied one line ending with '\n' */
78 int copied = next - dst;
79 rawsize -= copied;
80 src += copied;
81 /* insert '\r' before '\n' */
82 next[-1] = '\r';
83 next[0] = '\n';
84 dst = next+1;
85 }
86 }
87 while (next);
88
89 GlobalUnlock (h);
90
91 i = (SetClipboardData (CF_TEXT, h) != NULL);
92
93 CloseClipboard ();
94
95 return i ? Qt : Qnil;
96 }
97 37
98 /* Do protocol to assert ourself as a selection owner. Under mswindows 38 /* Do protocol to assert ourself as a selection owner. Under mswindows
99 this is easy, we just set the clipboard. */ 39 this is easy, we just set the clipboard. */
100 static Lisp_Object 40 static Lisp_Object
101 mswindows_own_selection (Lisp_Object selection_name, Lisp_Object selection_value) 41 mswindows_own_selection (Lisp_Object selection_name,
42 Lisp_Object selection_value)
102 { 43 {
103 Lisp_Object converted_value = get_local_selection (selection_name, QSTRING); 44 Lisp_Object converted_value = get_local_selection (selection_name, QSTRING);
45
104 if (!NILP (converted_value) && 46 if (!NILP (converted_value) &&
105 CONSP (converted_value) && 47 CONSP (converted_value) &&
106 EQ (XCAR (converted_value), QSTRING) && 48 EQ (XCAR (converted_value), QSTRING) &&
107 /* pure mswindows behaviour only says we can own the selection 49 /* pure mswindows behaviour only says we can own the selection
108 if it is the clipboard */ 50 if it is the clipboard */
109 EQ (selection_name, QCLIPBOARD)) 51 EQ (selection_name, QCLIPBOARD))
110 Fmswindows_set_clipboard (XCDR (converted_value));
111
112 return Qnil;
113 }
114
115 DEFUN ("mswindows-get-clipboard", Fmswindows_get_clipboard, 0, 0, 0, /*
116 Return the contents of the mswindows clipboard.
117 */
118 ())
119 {
120 HANDLE h;
121 unsigned char *src, *dst, *next;
122 Lisp_Object ret = Qnil;
123
124 if (!OpenClipboard (NULL))
125 return Qnil;
126
127 if ((h = GetClipboardData (CF_TEXT)) != NULL &&
128 (src = (unsigned char *) GlobalLock (h)) != NULL)
129 { 52 {
130 int i; 53 int rawsize, size, i;
131 int size, rawsize; 54 unsigned char *src, *dst, *next;
132 size = rawsize = strlen (src); 55 HGLOBAL h = NULL;
133 56 struct frame *f = NULL;
57 struct gcpro gcpro1, gcpro2;
58 Lisp_Object string = XCDR (converted_value);
59
60 GCPRO2 (converted_value, string);
61
62 CHECK_STRING (string);
63
64 /* Calculate size with LFs converted to CRLFs because
65 * CF_TEXT format uses CRLF delimited ASCIIZ */
66 src = XSTRING_DATA (string);
67 size = rawsize = XSTRING_LENGTH (string) + 1;
134 for (i=0; i<rawsize; i++) 68 for (i=0; i<rawsize; i++)
135 if (src[i] == '\r' && src[i+1] == '\n') 69 if (src[i] == '\n')
136 size--; 70 size++;
137 71
138 /* Convert CRLFs to LFs */ 72 f = selected_frame ();
139 ret = make_uninit_string (size); 73 if (!OpenClipboard (FRAME_MSWINDOWS_HANDLE (f)))
140 dst = XSTRING_DATA (ret); 74 {
75 UNGCPRO;
76 return Qnil;
77 }
78
79 /* This call to EmptyClipboard may post an event back to us if
80 we already own the clipboard (to tell us we lost it) and this
81 event may execute random lisp code. Hence we must protect
82 the string and get its address again after the call. */
83 if (!EmptyClipboard () ||
84 (h = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, size)) == NULL ||
85 (dst = (unsigned char *) GlobalLock (h)) == NULL)
86 {
87 if (h != NULL) GlobalFree (h);
88 CloseClipboard ();
89 UNGCPRO;
90 return Qnil;
91 }
92 src = XSTRING_DATA (string);
93
94 /* Convert LFs to CRLFs */
141 do 95 do
142 { 96 {
143 /* copy next line or remaining bytes excluding '\0' */ 97 /* copy next line or remaining bytes including '\0' */
144 next = (char*) memccpy (dst, src, '\r', rawsize); 98 next = (char*) memccpy (dst, src, '\n', rawsize);
145 if (next) 99 if (next)
146 { 100 {
147 /* copied one line ending with '\r' */ 101 /* copied one line ending with '\n' */
148 int copied = next - dst; 102 int copied = next - dst;
149 rawsize -= copied; 103 rawsize -= copied;
150 src += copied; 104 src += copied;
151 if (*src == '\n') 105 /* insert '\r' before '\n' */
152 dst += copied - 1; /* overwrite '\r' */ 106 next[-1] = '\r';
153 else 107 next[0] = '\n';
154 dst += copied; 108 dst = next+1;
155 } 109 }
156 } 110 }
157 while (next); 111 while (next);
158 112
159 GlobalUnlock (h); 113 GlobalUnlock (h);
114
115 i = (SetClipboardData (CF_TEXT, h) != NULL);
116
117 CloseClipboard ();
118
119 UNGCPRO;
120 /* #### we are supposed to return a time! */
121 /* return i ? Qt : Qnil; */
122 return Qnil;
160 } 123 }
161 124
162 CloseClipboard (); 125 return Qnil;
163
164 return ret;
165 } 126 }
166 127
167 static Lisp_Object 128 static Lisp_Object
168 mswindows_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type) 129 mswindows_get_foreign_selection (Lisp_Object selection_symbol,
130 Lisp_Object target_type)
169 { 131 {
170 if (EQ (selection_symbol, QCLIPBOARD)) 132 if (EQ (selection_symbol, QCLIPBOARD))
171 return Fmswindows_get_clipboard (); 133 {
134 HANDLE h;
135 unsigned char *src, *dst, *next;
136 Lisp_Object ret = Qnil;
137
138 if (!OpenClipboard (NULL))
139 return Qnil;
140
141 if ((h = GetClipboardData (CF_TEXT)) != NULL &&
142 (src = (unsigned char *) GlobalLock (h)) != NULL)
143 {
144 int i;
145 int size, rawsize;
146 size = rawsize = strlen (src);
147
148 for (i=0; i<rawsize; i++)
149 if (src[i] == '\r' && src[i+1] == '\n')
150 size--;
151
152 /* Convert CRLFs to LFs */
153 ret = make_uninit_string (size);
154 dst = XSTRING_DATA (ret);
155 do
156 {
157 /* copy next line or remaining bytes excluding '\0' */
158 next = (unsigned char *) memccpy (dst, src, '\r', rawsize);
159 if (next)
160 {
161 /* copied one line ending with '\r' */
162 int copied = next - dst;
163 rawsize -= copied;
164 src += copied;
165 if (*src == '\n')
166 dst += copied - 1; /* overwrite '\r' */
167 else
168 dst += copied;
169 }
170 }
171 while (next);
172
173 GlobalUnlock (h);
174 }
175
176 CloseClipboard ();
177
178 return ret;
179 }
172 else 180 else
173 return Qnil; 181 return Qnil;
174 } 182 }
175 183
176 DEFUN ("mswindows-selection-exists-p", Fmswindows_selection_exists_p, 0, 0, 0, /*
177 Whether there is an MS-Windows selection.
178 */
179 ())
180 {
181 return IsClipboardFormatAvailable (CF_TEXT) ? Qt : Qnil;
182 }
183
184 DEFUN ("mswindows-delete-selection", Fmswindows_delete_selection, 0, 0, 0, /*
185 Remove the current MS-Windows selection from the clipboard.
186 */
187 ())
188 {
189 BOOL success = OpenClipboard (NULL);
190 if (success)
191 {
192 success = EmptyClipboard ();
193 /* Close it regardless of whether empty worked. */
194 if (!CloseClipboard ())
195 success = FALSE;
196 }
197
198 return success ? Qt : Qnil;
199 }
200
201 static void 184 static void
202 mswindows_disown_selection (Lisp_Object selection, Lisp_Object timeval) 185 mswindows_disown_selection (Lisp_Object selection, Lisp_Object timeval)
203 { 186 {
204 if (EQ (selection, QCLIPBOARD)) 187 if (EQ (selection, QCLIPBOARD))
205 Fmswindows_delete_selection (); 188 {
189 BOOL success = OpenClipboard (NULL);
190 if (success)
191 {
192 success = EmptyClipboard ();
193 /* Close it regardless of whether empty worked. */
194 if (!CloseClipboard ())
195 success = FALSE;
196 }
197
198 /* #### return success ? Qt : Qnil; */
199 }
200 }
201
202 static Lisp_Object
203 mswindows_selection_exists_p (Lisp_Object selection)
204 {
205 if (EQ (selection, QCLIPBOARD))
206 return IsClipboardFormatAvailable (CF_TEXT) ? Qt : Qnil;
207 else
208 return Qnil;
206 } 209 }
207 210
208 211
209 /************************************************************************/ 212 /************************************************************************/
210 /* initialization */ 213 /* initialization */
213 void 216 void
214 console_type_create_select_mswindows (void) 217 console_type_create_select_mswindows (void)
215 { 218 {
216 CONSOLE_HAS_METHOD (mswindows, own_selection); 219 CONSOLE_HAS_METHOD (mswindows, own_selection);
217 CONSOLE_HAS_METHOD (mswindows, disown_selection); 220 CONSOLE_HAS_METHOD (mswindows, disown_selection);
221 CONSOLE_HAS_METHOD (mswindows, selection_exists_p);
218 CONSOLE_HAS_METHOD (mswindows, get_foreign_selection); 222 CONSOLE_HAS_METHOD (mswindows, get_foreign_selection);
219 } 223 }
220 224
221 void 225 void
222 syms_of_select_mswindows (void) 226 syms_of_select_mswindows (void)
223 { 227 {
224 DEFSUBR (Fmswindows_set_clipboard);
225 DEFSUBR (Fmswindows_get_clipboard);
226 DEFSUBR (Fmswindows_selection_exists_p);
227 DEFSUBR (Fmswindows_delete_selection);
228 } 228 }
229 229
230 void 230 void
231 vars_of_select_mswindows (void) 231 vars_of_select_mswindows (void)
232 { 232 {