/[dtapublic]/projs/trunk/shared_source/tk_base/tkwinclipboard.c
ViewVC logotype

Contents of /projs/trunk/shared_source/tk_base/tkwinclipboard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (show annotations) (download)
Fri Oct 14 01:50:00 2016 UTC (7 years, 8 months ago) by dashley
File MIME type: text/plain
File size: 11506 byte(s)
Move shared source code to commonize.
1 /* $Header: /cvsroot/esrg/sfesrg/esrgpcpj/shared/tk_base/tkwinclipboard.c,v 1.1.1.1 2001/06/13 05:11:58 dtashley Exp $ */
2
3 /*
4 * tkWinClipboard.c --
5 *
6 * This file contains functions for managing the clipboard.
7 *
8 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
9 * Copyright (c) 1998-2000 by Scriptics Corporation.
10 *
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 *
14 * RCS: @(#) $Id: tkwinclipboard.c,v 1.1.1.1 2001/06/13 05:11:58 dtashley Exp $
15 */
16
17 #include "tkWinInt.h"
18 #include "tkSelect.h"
19
20 static void UpdateClipboard _ANSI_ARGS_((HWND hwnd));
21
22 /*
23 *----------------------------------------------------------------------
24 *
25 * TkSelGetSelection --
26 *
27 * Retrieve the specified selection from another process. For
28 * now, only fetching XA_STRING from CLIPBOARD is supported.
29 * Eventually other types should be allowed.
30 *
31 * Results:
32 * The return value is a standard Tcl return value.
33 * If an error occurs (such as no selection exists)
34 * then an error message is left in the interp's result.
35 *
36 * Side effects:
37 * None.
38 *
39 *----------------------------------------------------------------------
40 */
41
42 int
43 TkSelGetSelection(interp, tkwin, selection, target, proc, clientData)
44 Tcl_Interp *interp; /* Interpreter to use for reporting
45 * errors. */
46 Tk_Window tkwin; /* Window on whose behalf to retrieve
47 * the selection (determines display
48 * from which to retrieve). */
49 Atom selection; /* Selection to retrieve. */
50 Atom target; /* Desired form in which selection
51 * is to be returned. */
52 Tk_GetSelProc *proc; /* Procedure to call to process the
53 * selection, once it has been retrieved. */
54 ClientData clientData; /* Arbitrary value to pass to proc. */
55 {
56 char *data, *destPtr;
57 Tcl_DString ds;
58 HGLOBAL handle;
59 Tcl_Encoding encoding;
60 int result, locale;
61
62 if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD"))
63 || (target != XA_STRING)
64 || !OpenClipboard(NULL)) {
65 goto error;
66 }
67
68 /*
69 * Attempt to get the data in Unicode form if available as this is
70 * less work that CF_TEXT.
71 */
72
73 result = TCL_ERROR;
74 if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
75 handle = GetClipboardData(CF_UNICODETEXT);
76 if (!handle) {
77 CloseClipboard();
78 goto error;
79 }
80 data = GlobalLock(handle);
81 Tcl_DStringInit(&ds);
82 Tcl_UniCharToUtfDString((Tcl_UniChar *)data,
83 Tcl_UniCharLen((Tcl_UniChar *)data), &ds);
84 GlobalUnlock(handle);
85 } else if (IsClipboardFormatAvailable(CF_TEXT)) {
86 /*
87 * Determine the encoding to use to convert this text.
88 */
89
90 if (IsClipboardFormatAvailable(CF_LOCALE)) {
91 handle = GetClipboardData(CF_LOCALE);
92 if (!handle) {
93 CloseClipboard();
94 goto error;
95 }
96
97 /*
98 * Get the locale identifier, determine the proper code page
99 * to use, and find the corresponding encoding.
100 */
101
102 Tcl_DStringInit(&ds);
103 Tcl_DStringAppend(&ds, "cp######", -1);
104 data = GlobalLock(handle);
105
106
107 /*
108 * Even though the documentation claims that GetLocaleInfo
109 * expects an LCID, on Windows 9x it really seems to expect
110 * a LanguageID.
111 */
112
113 locale = LANGIDFROMLCID(*((int*)data));
114 GetLocaleInfo(locale, LOCALE_IDEFAULTANSICODEPAGE,
115 Tcl_DStringValue(&ds)+2, Tcl_DStringLength(&ds)-2);
116 GlobalUnlock(handle);
117
118 encoding = Tcl_GetEncoding(NULL, Tcl_DStringValue(&ds));
119 Tcl_DStringFree(&ds);
120 } else {
121 encoding = NULL;
122 }
123
124 /*
125 * Fetch the text and convert it to UTF.
126 */
127
128 handle = GetClipboardData(CF_TEXT);
129 if (!handle) {
130 if (encoding) {
131 Tcl_FreeEncoding(encoding);
132 }
133 CloseClipboard();
134 goto error;
135 }
136 data = GlobalLock(handle);
137 Tcl_ExternalToUtfDString(encoding, data, -1, &ds);
138 GlobalUnlock(handle);
139 if (encoding) {
140 Tcl_FreeEncoding(encoding);
141 }
142
143 } else {
144 CloseClipboard();
145 goto error;
146 }
147
148 /*
149 * Translate CR/LF to LF.
150 */
151
152 data = destPtr = Tcl_DStringValue(&ds);
153 while (*data) {
154 if (data[0] == '\r' && data[1] == '\n') {
155 data++;
156 } else {
157 *destPtr++ = *data++;
158 }
159 }
160 *destPtr = '\0';
161
162 /*
163 * Pass the data off to the selection procedure.
164 */
165
166 result = (*proc)(clientData, interp, Tcl_DStringValue(&ds));
167 Tcl_DStringFree(&ds);
168 CloseClipboard();
169 return result;
170
171 error:
172 Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
173 " selection doesn't exist or form \"",
174 Tk_GetAtomName(tkwin, target),
175 "\" not defined", (char *) NULL);
176 return TCL_ERROR;
177 }
178
179 /*
180 *----------------------------------------------------------------------
181 *
182 * TkSetSelectionOwner --
183 *
184 * This function claims ownership of the specified selection.
185 * If the selection is CLIPBOARD, then we empty the system
186 * clipboard.
187 *
188 * Results:
189 * None.
190 *
191 * Side effects:
192 * Empties the system clipboard, and claims ownership.
193 *
194 *----------------------------------------------------------------------
195 */
196
197 void
198 XSetSelectionOwner(display, selection, owner, time)
199 Display* display;
200 Atom selection;
201 Window owner;
202 Time time;
203 {
204 HWND hwnd = owner ? TkWinGetHWND(owner) : NULL;
205 Tk_Window tkwin;
206
207 /*
208 * This is a gross hack because the Tk_InternAtom interface is broken.
209 * It expects a Tk_Window, even though it only needs a Tk_Display.
210 */
211
212 tkwin = (Tk_Window) TkGetMainInfoList()->winPtr;
213
214 if (selection == Tk_InternAtom(tkwin, "CLIPBOARD")) {
215
216 /*
217 * Only claim and empty the clipboard if we aren't already the
218 * owner of the clipboard.
219 */
220
221 if (GetClipboardOwner() != hwnd) {
222 UpdateClipboard(hwnd);
223 }
224 }
225 }
226
227 /*
228 *----------------------------------------------------------------------
229 *
230 * TkWinClipboardRender --
231 *
232 * This function supplies the contents of the clipboard in
233 * response to a WM_RENDERFORMAT message.
234 *
235 * Results:
236 * None.
237 *
238 * Side effects:
239 * Sets the contents of the clipboard.
240 *
241 *----------------------------------------------------------------------
242 */
243
244 void
245 TkWinClipboardRender(dispPtr, format)
246 TkDisplay *dispPtr;
247 UINT format;
248 {
249 TkClipboardTarget *targetPtr;
250 TkClipboardBuffer *cbPtr;
251 HGLOBAL handle;
252 char *buffer, *p, *rawText, *endPtr;
253 int length;
254 Tcl_DString ds;
255
256 for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
257 targetPtr = targetPtr->nextPtr) {
258 if (targetPtr->type == XA_STRING)
259 break;
260 }
261
262 /*
263 * Count the number of newlines so we can add space for them in
264 * the resulting string.
265 */
266
267 length = 0;
268 if (targetPtr != NULL) {
269 for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
270 cbPtr = cbPtr->nextPtr) {
271 length += cbPtr->length;
272 for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
273 p < endPtr; p++) {
274 if (*p == '\n') {
275 length++;
276 }
277 }
278 }
279 }
280
281 /*
282 * Copy the data and change EOL characters.
283 */
284
285 buffer = rawText = ckalloc(length + 1);
286 if (targetPtr != NULL) {
287 for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
288 cbPtr = cbPtr->nextPtr) {
289 for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
290 p < endPtr; p++) {
291 if (*p == '\n') {
292 *buffer++ = '\r';
293 }
294 *buffer++ = *p;
295 }
296 }
297 }
298 *buffer = '\0';
299
300 /*
301 * Depending on the platform, turn the data into Unicode or the
302 * system encoding before placing it on the clipboard.
303 */
304
305 if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
306 Tcl_DStringInit(&ds);
307 Tcl_UtfToUniCharDString(rawText, -1, &ds);
308 ckfree(rawText);
309 handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
310 Tcl_DStringLength(&ds)+2);
311 if (!handle) {
312 Tcl_DStringFree(&ds);
313 return;
314 }
315 buffer = GlobalLock(handle);
316 memcpy(buffer, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds) + 2);
317 GlobalUnlock(handle);
318 Tcl_DStringFree(&ds);
319 SetClipboardData(CF_UNICODETEXT, handle);
320 } else {
321 Tcl_UtfToExternalDString(NULL, rawText, -1, &ds);
322 ckfree(rawText);
323 handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
324 Tcl_DStringLength(&ds)+1);
325 if (!handle) {
326 Tcl_DStringFree(&ds);
327 return;
328 }
329 buffer = GlobalLock(handle);
330 memcpy(buffer, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds) + 1);
331 GlobalUnlock(handle);
332 Tcl_DStringFree(&ds);
333 SetClipboardData(CF_TEXT, handle);
334 }
335
336 return;
337 }
338
339 /*
340 *----------------------------------------------------------------------
341 *
342 * TkSelUpdateClipboard --
343 *
344 * This function is called to force the clipboard to be updated
345 * after new data is added.
346 *
347 * Results:
348 * None.
349 *
350 * Side effects:
351 * Clears the current contents of the clipboard.
352 *
353 *----------------------------------------------------------------------
354 */
355
356 void
357 TkSelUpdateClipboard(winPtr, targetPtr)
358 TkWindow *winPtr;
359 TkClipboardTarget *targetPtr;
360 {
361 HWND hwnd = TkWinGetHWND(winPtr->window);
362 UpdateClipboard(hwnd);
363 }
364
365 /*
366 *----------------------------------------------------------------------
367 *
368 * UpdateClipboard --
369 *
370 * Take ownership of the clipboard, clear it, and indicate to the
371 * system the supported formats.
372 *
373 * Results:
374 * None.
375 *
376 * Side effects:
377 * None.
378 *
379 *----------------------------------------------------------------------
380 */
381
382 static void
383 UpdateClipboard(hwnd)
384 HWND hwnd;
385 {
386 TkWinUpdatingClipboard(TRUE);
387 OpenClipboard(hwnd);
388 EmptyClipboard();
389
390 /*
391 * CF_UNICODETEXT is only supported on NT, but it it is prefered
392 * when possible.
393 */
394
395 if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
396 SetClipboardData(CF_UNICODETEXT, NULL);
397 } else {
398 SetClipboardData(CF_TEXT, NULL);
399 }
400 CloseClipboard();
401 TkWinUpdatingClipboard(FALSE);
402 }
403
404 /*
405 *--------------------------------------------------------------
406 *
407 * TkSelEventProc --
408 *
409 * This procedure is invoked whenever a selection-related
410 * event occurs.
411 *
412 * Results:
413 * None.
414 *
415 * Side effects:
416 * Lots: depends on the type of event.
417 *
418 *--------------------------------------------------------------
419 */
420
421 void
422 TkSelEventProc(tkwin, eventPtr)
423 Tk_Window tkwin; /* Window for which event was
424 * targeted. */
425 register XEvent *eventPtr; /* X event: either SelectionClear,
426 * SelectionRequest, or
427 * SelectionNotify. */
428 {
429 if (eventPtr->type == SelectionClear) {
430 TkSelClearSelection(tkwin, eventPtr);
431 }
432 }
433
434 /*
435 *----------------------------------------------------------------------
436 *
437 * TkSelPropProc --
438 *
439 * This procedure is invoked when property-change events
440 * occur on windows not known to the toolkit. This is a stub
441 * function under Windows.
442 *
443 * Results:
444 * None.
445 *
446 * Side effects:
447 * None.
448 *
449 *----------------------------------------------------------------------
450 */
451
452 void
453 TkSelPropProc(eventPtr)
454 register XEvent *eventPtr; /* X PropertyChange event. */
455 {
456 }
457
458
459 /* $History: tkWinClipboard.c $
460 *
461 * ***************** Version 1 *****************
462 * User: Dtashley Date: 1/02/01 Time: 3:10a
463 * Created in $/IjuScripter, IjuConsole/Source/Tk Base
464 * Initial check-in.
465 */
466
467 /* End of TKWINCLIPBOARD.C */

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25