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

Annotation of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkwinclipboard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 29 - (hide annotations) (download)
Sat Oct 8 07:08:47 2016 UTC (7 years, 8 months ago) by dashley
Original Path: to_be_filed/sf_code/esrgpcpj/shared/tk_base/tkwinclipboard.c
File MIME type: text/plain
File size: 11506 byte(s)
Directories relocated.
1 dashley 25 /* $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