/[dtapublic]/projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkclipboard.c
ViewVC logotype

Diff of /projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkclipboard.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 69 by dashley, Sat Nov 5 10:54:17 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2    
3  /*  /*
4   * tkClipboard.c --   * tkClipboard.c --
5   *   *
6   *      This file manages the clipboard for the Tk toolkit,   *      This file manages the clipboard for the Tk toolkit,
7   *      maintaining a collection of data buffers that will be   *      maintaining a collection of data buffers that will be
8   *      supplied on demand to requesting applications.   *      supplied on demand to requesting applications.
9   *   *
10   * Copyright (c) 1994 The Regents of the University of California.   * Copyright (c) 1994 The Regents of the University of California.
11   * Copyright (c) 1994-1997 Sun Microsystems, Inc.   * Copyright (c) 1994-1997 Sun Microsystems, Inc.
12   *   *
13   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
14   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15   *   *
16   * RCS: @(#) $Id: tkclipboard.c,v 1.1.1.1 2001/06/13 04:58:07 dtashley Exp $   * RCS: @(#) $Id: tkclipboard.c,v 1.1.1.1 2001/06/13 04:58:07 dtashley Exp $
17   */   */
18    
19  #include "tkInt.h"  #include "tkInt.h"
20  #include "tkPort.h"  #include "tkPort.h"
21  #include "tkSelect.h"  #include "tkSelect.h"
22    
23  /*  /*
24   * Prototypes for procedures used only in this file:   * Prototypes for procedures used only in this file:
25   */   */
26    
27  static int              ClipboardAppHandler _ANSI_ARGS_((ClientData clientData,  static int              ClipboardAppHandler _ANSI_ARGS_((ClientData clientData,
28                              int offset, char *buffer, int maxBytes));                              int offset, char *buffer, int maxBytes));
29  static int              ClipboardHandler _ANSI_ARGS_((ClientData clientData,  static int              ClipboardHandler _ANSI_ARGS_((ClientData clientData,
30                              int offset, char *buffer, int maxBytes));                              int offset, char *buffer, int maxBytes));
31  static int              ClipboardWindowHandler _ANSI_ARGS_((  static int              ClipboardWindowHandler _ANSI_ARGS_((
32                              ClientData clientData, int offset, char *buffer,                              ClientData clientData, int offset, char *buffer,
33                              int maxBytes));                              int maxBytes));
34  static void             ClipboardLostSel _ANSI_ARGS_((ClientData clientData));  static void             ClipboardLostSel _ANSI_ARGS_((ClientData clientData));
35    
36  /*  /*
37   *----------------------------------------------------------------------   *----------------------------------------------------------------------
38   *   *
39   * ClipboardHandler --   * ClipboardHandler --
40   *   *
41   *      This procedure acts as selection handler for the   *      This procedure acts as selection handler for the
42   *      clipboard manager.  It extracts the required chunk of   *      clipboard manager.  It extracts the required chunk of
43   *      data from the buffer chain for a given selection target.   *      data from the buffer chain for a given selection target.
44   *   *
45   * Results:   * Results:
46   *      The return value is a count of the number of bytes   *      The return value is a count of the number of bytes
47   *      actually stored at buffer.   *      actually stored at buffer.
48   *   *
49   * Side effects:   * Side effects:
50   *      None.   *      None.
51   *   *
52   *----------------------------------------------------------------------   *----------------------------------------------------------------------
53   */   */
54    
55  static int  static int
56  ClipboardHandler(clientData, offset, buffer, maxBytes)  ClipboardHandler(clientData, offset, buffer, maxBytes)
57      ClientData clientData;      /* Information about data to fetch. */      ClientData clientData;      /* Information about data to fetch. */
58      int offset;                 /* Return selection bytes starting at this      int offset;                 /* Return selection bytes starting at this
59                                   * offset. */                                   * offset. */
60      char *buffer;               /* Place to store converted selection. */      char *buffer;               /* Place to store converted selection. */
61      int maxBytes;               /* Maximum # of bytes to store at buffer. */      int maxBytes;               /* Maximum # of bytes to store at buffer. */
62  {  {
63      TkClipboardTarget *targetPtr = (TkClipboardTarget*) clientData;      TkClipboardTarget *targetPtr = (TkClipboardTarget*) clientData;
64      TkClipboardBuffer *cbPtr;      TkClipboardBuffer *cbPtr;
65      char *srcPtr, *destPtr;      char *srcPtr, *destPtr;
66      int count = 0;      int count = 0;
67      int scanned = 0;      int scanned = 0;
68      size_t length, freeCount;      size_t length, freeCount;
69    
70      /*      /*
71       * Skip to buffer containing offset byte       * Skip to buffer containing offset byte
72       */       */
73    
74      for (cbPtr = targetPtr->firstBufferPtr; ; cbPtr = cbPtr->nextPtr) {      for (cbPtr = targetPtr->firstBufferPtr; ; cbPtr = cbPtr->nextPtr) {
75          if (cbPtr == NULL) {          if (cbPtr == NULL) {
76              return 0;              return 0;
77          }          }
78          if (scanned + cbPtr->length > offset) {          if (scanned + cbPtr->length > offset) {
79              break;              break;
80          }          }
81          scanned += cbPtr->length;          scanned += cbPtr->length;
82      }      }
83    
84      /*      /*
85       * Copy up to maxBytes or end of list, switching buffers as needed.       * Copy up to maxBytes or end of list, switching buffers as needed.
86       */       */
87    
88      freeCount = maxBytes;      freeCount = maxBytes;
89      srcPtr = cbPtr->buffer + (offset - scanned);      srcPtr = cbPtr->buffer + (offset - scanned);
90      destPtr = buffer;      destPtr = buffer;
91      length = cbPtr->length - (offset - scanned);      length = cbPtr->length - (offset - scanned);
92      while (1) {      while (1) {
93          if (length > freeCount) {          if (length > freeCount) {
94              strncpy(destPtr, srcPtr, freeCount);              strncpy(destPtr, srcPtr, freeCount);
95              return maxBytes;              return maxBytes;
96          } else {          } else {
97              strncpy(destPtr, srcPtr, length);              strncpy(destPtr, srcPtr, length);
98              destPtr += length;              destPtr += length;
99              count += length;              count += length;
100              freeCount -= length;              freeCount -= length;
101          }          }
102          cbPtr = cbPtr->nextPtr;          cbPtr = cbPtr->nextPtr;
103          if (cbPtr == NULL) {          if (cbPtr == NULL) {
104              break;              break;
105          }          }
106          srcPtr = cbPtr->buffer;          srcPtr = cbPtr->buffer;
107          length = cbPtr->length;          length = cbPtr->length;
108      }      }
109      return count;      return count;
110  }  }
111    
112  /*  /*
113   *----------------------------------------------------------------------   *----------------------------------------------------------------------
114   *   *
115   * ClipboardAppHandler --   * ClipboardAppHandler --
116   *   *
117   *      This procedure acts as selection handler for retrievals of type   *      This procedure acts as selection handler for retrievals of type
118   *      TK_APPLICATION.  It returns the name of the application that   *      TK_APPLICATION.  It returns the name of the application that
119   *      owns the clipboard.  Note:  we can't use the default Tk   *      owns the clipboard.  Note:  we can't use the default Tk
120   *      selection handler for this selection type, because the clipboard   *      selection handler for this selection type, because the clipboard
121   *      window isn't a "real" window and doesn't have the necessary   *      window isn't a "real" window and doesn't have the necessary
122   *      information.   *      information.
123   *   *
124   * Results:   * Results:
125   *      The return value is a count of the number of bytes   *      The return value is a count of the number of bytes
126   *      actually stored at buffer.   *      actually stored at buffer.
127   *   *
128   * Side effects:   * Side effects:
129   *      None.   *      None.
130   *   *
131   *----------------------------------------------------------------------   *----------------------------------------------------------------------
132   */   */
133    
134  static int  static int
135  ClipboardAppHandler(clientData, offset, buffer, maxBytes)  ClipboardAppHandler(clientData, offset, buffer, maxBytes)
136      ClientData clientData;      /* Pointer to TkDisplay structure. */      ClientData clientData;      /* Pointer to TkDisplay structure. */
137      int offset;                 /* Return selection bytes starting at this      int offset;                 /* Return selection bytes starting at this
138                                   * offset. */                                   * offset. */
139      char *buffer;               /* Place to store converted selection. */      char *buffer;               /* Place to store converted selection. */
140      int maxBytes;               /* Maximum # of bytes to store at buffer. */      int maxBytes;               /* Maximum # of bytes to store at buffer. */
141  {  {
142      TkDisplay *dispPtr = (TkDisplay *) clientData;      TkDisplay *dispPtr = (TkDisplay *) clientData;
143      size_t length;      size_t length;
144      char *p;      char *p;
145    
146      p = dispPtr->clipboardAppPtr->winPtr->nameUid;      p = dispPtr->clipboardAppPtr->winPtr->nameUid;
147      length = strlen(p);      length = strlen(p);
148      length -= offset;      length -= offset;
149      if (length <= 0) {      if (length <= 0) {
150          return 0;          return 0;
151      }      }
152      if (length > (size_t) maxBytes) {      if (length > (size_t) maxBytes) {
153          length = maxBytes;          length = maxBytes;
154      }      }
155      strncpy(buffer, p, length);      strncpy(buffer, p, length);
156      return length;      return length;
157  }  }
158    
159  /*  /*
160   *----------------------------------------------------------------------   *----------------------------------------------------------------------
161   *   *
162   * ClipboardWindowHandler --   * ClipboardWindowHandler --
163   *   *
164   *      This procedure acts as selection handler for retrievals of   *      This procedure acts as selection handler for retrievals of
165   *      type TK_WINDOW.  Since the clipboard doesn't correspond to   *      type TK_WINDOW.  Since the clipboard doesn't correspond to
166   *      any particular window, we just return ".".  We can't use Tk's   *      any particular window, we just return ".".  We can't use Tk's
167   *      default handler for this selection type, because the clipboard   *      default handler for this selection type, because the clipboard
168   *      window isn't a valid window.   *      window isn't a valid window.
169   *   *
170   * Results:   * Results:
171   *      The return value is 1, the number of non-null bytes stored   *      The return value is 1, the number of non-null bytes stored
172   *      at buffer.   *      at buffer.
173   *   *
174   * Side effects:   * Side effects:
175   *      None.   *      None.
176   *   *
177   *----------------------------------------------------------------------   *----------------------------------------------------------------------
178   */   */
179    
180  static int  static int
181  ClipboardWindowHandler(clientData, offset, buffer, maxBytes)  ClipboardWindowHandler(clientData, offset, buffer, maxBytes)
182      ClientData clientData;      /* Not used. */      ClientData clientData;      /* Not used. */
183      int offset;                 /* Return selection bytes starting at this      int offset;                 /* Return selection bytes starting at this
184                                   * offset. */                                   * offset. */
185      char *buffer;               /* Place to store converted selection. */      char *buffer;               /* Place to store converted selection. */
186      int maxBytes;               /* Maximum # of bytes to store at buffer. */      int maxBytes;               /* Maximum # of bytes to store at buffer. */
187  {  {
188      buffer[0] = '.';      buffer[0] = '.';
189      buffer[1] = 0;      buffer[1] = 0;
190      return 1;      return 1;
191  }  }
192    
193  /*  /*
194   *----------------------------------------------------------------------   *----------------------------------------------------------------------
195   *   *
196   * ClipboardLostSel --   * ClipboardLostSel --
197   *   *
198   *      This procedure is invoked whenever clipboard ownership is   *      This procedure is invoked whenever clipboard ownership is
199   *      claimed by another window.  It just sets a flag so that we   *      claimed by another window.  It just sets a flag so that we
200   *      know the clipboard was taken away.   *      know the clipboard was taken away.
201   *   *
202   * Results:   * Results:
203   *      None.   *      None.
204   *   *
205   * Side effects:   * Side effects:
206   *      The clipboard is marked as inactive.   *      The clipboard is marked as inactive.
207   *   *
208   *----------------------------------------------------------------------   *----------------------------------------------------------------------
209   */   */
210    
211  static void  static void
212  ClipboardLostSel(clientData)  ClipboardLostSel(clientData)
213      ClientData clientData;              /* Pointer to TkDisplay structure. */      ClientData clientData;              /* Pointer to TkDisplay structure. */
214  {  {
215      TkDisplay *dispPtr = (TkDisplay*) clientData;      TkDisplay *dispPtr = (TkDisplay*) clientData;
216    
217      dispPtr->clipboardActive = 0;      dispPtr->clipboardActive = 0;
218  }  }
219    
220  /*  /*
221   *----------------------------------------------------------------------   *----------------------------------------------------------------------
222   *   *
223   * Tk_ClipboardClear --   * Tk_ClipboardClear --
224   *   *
225   *      Take control of the clipboard and clear out the previous   *      Take control of the clipboard and clear out the previous
226   *      contents.  This procedure must be invoked before any   *      contents.  This procedure must be invoked before any
227   *      calls to Tk_ClipboardAppend.   *      calls to Tk_ClipboardAppend.
228   *   *
229   * Results:   * Results:
230   *      A standard Tcl result.  If an error occurs, an error message is   *      A standard Tcl result.  If an error occurs, an error message is
231   *      left in the interp's result.   *      left in the interp's result.
232   *   *
233   * Side effects:   * Side effects:
234   *      From now on, requests for the CLIPBOARD selection will be   *      From now on, requests for the CLIPBOARD selection will be
235   *      directed to the clipboard manager routines associated with   *      directed to the clipboard manager routines associated with
236   *      clipWindow for the display of tkwin.  In order to guarantee   *      clipWindow for the display of tkwin.  In order to guarantee
237   *      atomicity, no event handling should occur between   *      atomicity, no event handling should occur between
238   *      Tk_ClipboardClear and the following Tk_ClipboardAppend   *      Tk_ClipboardClear and the following Tk_ClipboardAppend
239   *      calls.  This procedure may cause a user-defined LostSel command   *      calls.  This procedure may cause a user-defined LostSel command
240   *      to be invoked when the CLIPBOARD is claimed, so any calling   *      to be invoked when the CLIPBOARD is claimed, so any calling
241   *      function should be reentrant at the point Tk_ClipboardClear is   *      function should be reentrant at the point Tk_ClipboardClear is
242   *      invoked.   *      invoked.
243   *   *
244   *----------------------------------------------------------------------   *----------------------------------------------------------------------
245   */   */
246    
247  int  int
248  Tk_ClipboardClear(interp, tkwin)  Tk_ClipboardClear(interp, tkwin)
249      Tcl_Interp *interp;         /* Interpreter to use for error reporting. */      Tcl_Interp *interp;         /* Interpreter to use for error reporting. */
250      Tk_Window tkwin;            /* Window in application that is clearing      Tk_Window tkwin;            /* Window in application that is clearing
251                                   * clipboard;  identifies application and                                   * clipboard;  identifies application and
252                                   * display. */                                   * display. */
253  {  {
254      TkWindow *winPtr = (TkWindow *) tkwin;      TkWindow *winPtr = (TkWindow *) tkwin;
255      TkDisplay *dispPtr = winPtr->dispPtr;      TkDisplay *dispPtr = winPtr->dispPtr;
256      TkClipboardTarget *targetPtr, *nextTargetPtr;      TkClipboardTarget *targetPtr, *nextTargetPtr;
257      TkClipboardBuffer *cbPtr, *nextCbPtr;      TkClipboardBuffer *cbPtr, *nextCbPtr;
258    
259      if (dispPtr->clipWindow == NULL) {      if (dispPtr->clipWindow == NULL) {
260          int result;          int result;
261    
262          result = TkClipInit(interp, dispPtr);          result = TkClipInit(interp, dispPtr);
263          if (result != TCL_OK) {          if (result != TCL_OK) {
264              return result;              return result;
265          }          }
266      }      }
267    
268      /*      /*
269       * Discard any existing clipboard data and delete the selection       * Discard any existing clipboard data and delete the selection
270       * handler(s) associated with that data.       * handler(s) associated with that data.
271       */       */
272    
273      for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;      for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
274              targetPtr = nextTargetPtr) {              targetPtr = nextTargetPtr) {
275          for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;          for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
276                  cbPtr = nextCbPtr) {                  cbPtr = nextCbPtr) {
277              ckfree(cbPtr->buffer);              ckfree(cbPtr->buffer);
278              nextCbPtr = cbPtr->nextPtr;              nextCbPtr = cbPtr->nextPtr;
279              ckfree((char *) cbPtr);              ckfree((char *) cbPtr);
280          }          }
281          nextTargetPtr = targetPtr->nextPtr;          nextTargetPtr = targetPtr->nextPtr;
282          Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,          Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
283                  targetPtr->type);                  targetPtr->type);
284          ckfree((char *) targetPtr);          ckfree((char *) targetPtr);
285      }      }
286      dispPtr->clipTargetPtr = NULL;      dispPtr->clipTargetPtr = NULL;
287    
288      /*      /*
289       * Reclaim the clipboard selection if we lost it.       * Reclaim the clipboard selection if we lost it.
290       */       */
291    
292      if (!dispPtr->clipboardActive) {      if (!dispPtr->clipboardActive) {
293          Tk_OwnSelection(dispPtr->clipWindow, dispPtr->clipboardAtom,          Tk_OwnSelection(dispPtr->clipWindow, dispPtr->clipboardAtom,
294                  ClipboardLostSel, (ClientData) dispPtr);                  ClipboardLostSel, (ClientData) dispPtr);
295          dispPtr->clipboardActive = 1;          dispPtr->clipboardActive = 1;
296      }      }
297      dispPtr->clipboardAppPtr = winPtr->mainPtr;      dispPtr->clipboardAppPtr = winPtr->mainPtr;
298      return TCL_OK;      return TCL_OK;
299  }  }
300    
301  /*  /*
302   *----------------------------------------------------------------------   *----------------------------------------------------------------------
303   *   *
304   * Tk_ClipboardAppend --   * Tk_ClipboardAppend --
305   *   *
306   *      Append a buffer of data to the clipboard.  The first buffer of   *      Append a buffer of data to the clipboard.  The first buffer of
307   *      a given type determines the format for that type.  Any successive   *      a given type determines the format for that type.  Any successive
308   *      appends to that type must have the same format or an error will   *      appends to that type must have the same format or an error will
309   *      be returned.  Tk_ClipboardClear must be called before a sequence   *      be returned.  Tk_ClipboardClear must be called before a sequence
310   *      of Tk_ClipboardAppend calls can be issued.  In order to guarantee   *      of Tk_ClipboardAppend calls can be issued.  In order to guarantee
311   *      atomicity, no event handling should occur between Tk_ClipboardClear   *      atomicity, no event handling should occur between Tk_ClipboardClear
312   *      and the following Tk_ClipboardAppend calls.   *      and the following Tk_ClipboardAppend calls.
313   *   *
314   * Results:   * Results:
315   *      A standard Tcl result.  If an error is returned, an error message   *      A standard Tcl result.  If an error is returned, an error message
316   *      is left in the interp's result.   *      is left in the interp's result.
317   *   *
318   * Side effects:   * Side effects:
319   *      The specified buffer will be copied onto the end of the clipboard.   *      The specified buffer will be copied onto the end of the clipboard.
320   *      The clipboard maintains a list of buffers which will be used to   *      The clipboard maintains a list of buffers which will be used to
321   *      supply the data for a selection get request.  The first time a given   *      supply the data for a selection get request.  The first time a given
322   *      type is appended, Tk_ClipboardAppend will register a selection   *      type is appended, Tk_ClipboardAppend will register a selection
323   *      handler of the appropriate type.   *      handler of the appropriate type.
324   *   *
325   *----------------------------------------------------------------------   *----------------------------------------------------------------------
326   */   */
327    
328  int  int
329  Tk_ClipboardAppend(interp, tkwin, type, format, buffer)  Tk_ClipboardAppend(interp, tkwin, type, format, buffer)
330      Tcl_Interp *interp;         /* Used for error reporting. */      Tcl_Interp *interp;         /* Used for error reporting. */
331      Tk_Window tkwin;            /* Window that selects a display. */      Tk_Window tkwin;            /* Window that selects a display. */
332      Atom type;                  /* The desired conversion type for this      Atom type;                  /* The desired conversion type for this
333                                   * clipboard item, e.g. STRING or LENGTH. */                                   * clipboard item, e.g. STRING or LENGTH. */
334      Atom format;                /* Format in which the selection      Atom format;                /* Format in which the selection
335                                   * information should be returned to                                   * information should be returned to
336                                   * the requestor. */                                   * the requestor. */
337      char* buffer;               /* NULL terminated string containing the data      char* buffer;               /* NULL terminated string containing the data
338                                   * to be added to the clipboard. */                                   * to be added to the clipboard. */
339  {  {
340      TkWindow *winPtr = (TkWindow *) tkwin;      TkWindow *winPtr = (TkWindow *) tkwin;
341      TkDisplay *dispPtr = winPtr->dispPtr;      TkDisplay *dispPtr = winPtr->dispPtr;
342      TkClipboardTarget *targetPtr;      TkClipboardTarget *targetPtr;
343      TkClipboardBuffer *cbPtr;      TkClipboardBuffer *cbPtr;
344    
345      /*      /*
346       * If this application doesn't already own the clipboard, clear       * If this application doesn't already own the clipboard, clear
347       * the clipboard.  If we don't own the clipboard selection, claim it.       * the clipboard.  If we don't own the clipboard selection, claim it.
348       */       */
349    
350      if (dispPtr->clipboardAppPtr != winPtr->mainPtr) {      if (dispPtr->clipboardAppPtr != winPtr->mainPtr) {
351          Tk_ClipboardClear(interp, tkwin);          Tk_ClipboardClear(interp, tkwin);
352      } else if (!dispPtr->clipboardActive) {      } else if (!dispPtr->clipboardActive) {
353          Tk_OwnSelection(dispPtr->clipWindow, dispPtr->clipboardAtom,          Tk_OwnSelection(dispPtr->clipWindow, dispPtr->clipboardAtom,
354                  ClipboardLostSel, (ClientData) dispPtr);                  ClipboardLostSel, (ClientData) dispPtr);
355          dispPtr->clipboardActive = 1;          dispPtr->clipboardActive = 1;
356      }      }
357    
358      /*      /*
359       * Check to see if the specified target is already present on the       * Check to see if the specified target is already present on the
360       * clipboard.  If it isn't, we need to create a new target; otherwise,       * clipboard.  If it isn't, we need to create a new target; otherwise,
361       * we just append the new buffer to the clipboard list.       * we just append the new buffer to the clipboard list.
362       */       */
363    
364      for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;      for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
365              targetPtr = targetPtr->nextPtr) {              targetPtr = targetPtr->nextPtr) {
366          if (targetPtr->type == type)          if (targetPtr->type == type)
367              break;              break;
368      }      }
369      if (targetPtr == NULL) {      if (targetPtr == NULL) {
370          targetPtr = (TkClipboardTarget*) ckalloc(sizeof(TkClipboardTarget));          targetPtr = (TkClipboardTarget*) ckalloc(sizeof(TkClipboardTarget));
371          targetPtr->type = type;          targetPtr->type = type;
372          targetPtr->format = format;          targetPtr->format = format;
373          targetPtr->firstBufferPtr = targetPtr->lastBufferPtr = NULL;          targetPtr->firstBufferPtr = targetPtr->lastBufferPtr = NULL;
374          targetPtr->nextPtr = dispPtr->clipTargetPtr;          targetPtr->nextPtr = dispPtr->clipTargetPtr;
375          dispPtr->clipTargetPtr = targetPtr;          dispPtr->clipTargetPtr = targetPtr;
376          Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,          Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
377                  type, ClipboardHandler, (ClientData) targetPtr, format);                  type, ClipboardHandler, (ClientData) targetPtr, format);
378      } else if (targetPtr->format != format) {      } else if (targetPtr->format != format) {
379          Tcl_AppendResult(interp, "format \"", Tk_GetAtomName(tkwin, format),          Tcl_AppendResult(interp, "format \"", Tk_GetAtomName(tkwin, format),
380                  "\" does not match current format \"",                  "\" does not match current format \"",
381                  Tk_GetAtomName(tkwin, targetPtr->format),"\" for ",                  Tk_GetAtomName(tkwin, targetPtr->format),"\" for ",
382                  Tk_GetAtomName(tkwin, type), (char *) NULL);                  Tk_GetAtomName(tkwin, type), (char *) NULL);
383          return TCL_ERROR;          return TCL_ERROR;
384      }      }
385    
386      /*      /*
387       * Append a new buffer to the buffer chain.       * Append a new buffer to the buffer chain.
388       */       */
389    
390      cbPtr = (TkClipboardBuffer*) ckalloc(sizeof(TkClipboardBuffer));      cbPtr = (TkClipboardBuffer*) ckalloc(sizeof(TkClipboardBuffer));
391      cbPtr->nextPtr = NULL;      cbPtr->nextPtr = NULL;
392      if (targetPtr->lastBufferPtr != NULL) {      if (targetPtr->lastBufferPtr != NULL) {
393          targetPtr->lastBufferPtr->nextPtr = cbPtr;          targetPtr->lastBufferPtr->nextPtr = cbPtr;
394      } else {      } else {
395          targetPtr->firstBufferPtr = cbPtr;          targetPtr->firstBufferPtr = cbPtr;
396      }      }
397      targetPtr->lastBufferPtr = cbPtr;      targetPtr->lastBufferPtr = cbPtr;
398    
399      cbPtr->length = strlen(buffer);      cbPtr->length = strlen(buffer);
400      cbPtr->buffer = (char *) ckalloc((unsigned) (cbPtr->length + 1));      cbPtr->buffer = (char *) ckalloc((unsigned) (cbPtr->length + 1));
401      strcpy(cbPtr->buffer, buffer);      strcpy(cbPtr->buffer, buffer);
402    
403      TkSelUpdateClipboard((TkWindow*)(dispPtr->clipWindow), targetPtr);      TkSelUpdateClipboard((TkWindow*)(dispPtr->clipWindow), targetPtr);
404    
405      return TCL_OK;      return TCL_OK;
406  }  }
407    
408  /*  /*
409   *----------------------------------------------------------------------   *----------------------------------------------------------------------
410   *   *
411   * Tk_ClipboardCmd --   * Tk_ClipboardCmd --
412   *   *
413   *      This procedure is invoked to process the "clipboard" Tcl   *      This procedure is invoked to process the "clipboard" Tcl
414   *      command.  See the user documentation for details on what   *      command.  See the user documentation for details on what
415   *      it does.   *      it does.
416   *   *
417   * Results:   * Results:
418   *      A standard Tcl result.   *      A standard Tcl result.
419   *   *
420   * Side effects:   * Side effects:
421   *      See the user documentation.   *      See the user documentation.
422   *   *
423   *----------------------------------------------------------------------   *----------------------------------------------------------------------
424   */   */
425    
426  int  int
427  Tk_ClipboardCmd(clientData, interp, argc, argv)  Tk_ClipboardCmd(clientData, interp, argc, argv)
428      ClientData clientData;      /* Main window associated with      ClientData clientData;      /* Main window associated with
429                                   * interpreter. */                                   * interpreter. */
430      Tcl_Interp *interp;         /* Current interpreter. */      Tcl_Interp *interp;         /* Current interpreter. */
431      int argc;                   /* Number of arguments. */      int argc;                   /* Number of arguments. */
432      char **argv;                /* Argument strings. */      char **argv;                /* Argument strings. */
433  {  {
434      Tk_Window tkwin = (Tk_Window) clientData;      Tk_Window tkwin = (Tk_Window) clientData;
435      char *path = NULL;      char *path = NULL;
436      size_t length;      size_t length;
437      int count;      int count;
438      char c;      char c;
439      char **args;      char **args;
440    
441      if (argc < 2) {      if (argc < 2) {
442          Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],          Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
443                  " option ?arg arg ...?\"", (char *) NULL);                  " option ?arg arg ...?\"", (char *) NULL);
444          return TCL_ERROR;          return TCL_ERROR;
445      }      }
446      c = argv[1][0];      c = argv[1][0];
447      length = strlen(argv[1]);      length = strlen(argv[1]);
448      if ((c == 'a') && (strncmp(argv[1], "append", length) == 0)) {      if ((c == 'a') && (strncmp(argv[1], "append", length) == 0)) {
449          Atom target, format;          Atom target, format;
450          char *targetName = NULL;          char *targetName = NULL;
451          char *formatName = NULL;          char *formatName = NULL;
452    
453          for (count = argc-2, args = argv+2; count > 1; count -= 2, args += 2) {          for (count = argc-2, args = argv+2; count > 1; count -= 2, args += 2) {
454              if (args[0][0] != '-') {              if (args[0][0] != '-') {
455                  break;                  break;
456              }              }
457              c = args[0][1];              c = args[0][1];
458              length = strlen(args[0]);              length = strlen(args[0]);
459              if ((c == '-') && (length == 2)) {              if ((c == '-') && (length == 2)) {
460                  args++;                  args++;
461                  count--;                  count--;
462                  break;                  break;
463              }              }
464              if ((c == 'd') && (strncmp(args[0], "-displayof", length) == 0)) {              if ((c == 'd') && (strncmp(args[0], "-displayof", length) == 0)) {
465                  path = args[1];                  path = args[1];
466              } else if ((c == 'f')              } else if ((c == 'f')
467                      && (strncmp(args[0], "-format", length) == 0)) {                      && (strncmp(args[0], "-format", length) == 0)) {
468                  formatName = args[1];                  formatName = args[1];
469              } else if ((c == 't')              } else if ((c == 't')
470                      && (strncmp(args[0], "-type", length) == 0)) {                      && (strncmp(args[0], "-type", length) == 0)) {
471                  targetName = args[1];                  targetName = args[1];
472              } else {              } else {
473                  Tcl_AppendResult(interp, "unknown option \"", args[0],                  Tcl_AppendResult(interp, "unknown option \"", args[0],
474                          "\"", (char *) NULL);                          "\"", (char *) NULL);
475                  return TCL_ERROR;                  return TCL_ERROR;
476              }              }
477          }          }
478          if (count != 1) {          if (count != 1) {
479              Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],              Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
480                      " append ?options? data\"", (char *) NULL);                      " append ?options? data\"", (char *) NULL);
481              return TCL_ERROR;              return TCL_ERROR;
482          }          }
483          if (path != NULL) {          if (path != NULL) {
484              tkwin = Tk_NameToWindow(interp, path, tkwin);              tkwin = Tk_NameToWindow(interp, path, tkwin);
485          }          }
486          if (tkwin == NULL) {          if (tkwin == NULL) {
487              return TCL_ERROR;              return TCL_ERROR;
488          }          }
489          if (targetName != NULL) {          if (targetName != NULL) {
490              target = Tk_InternAtom(tkwin, targetName);              target = Tk_InternAtom(tkwin, targetName);
491          } else {          } else {
492              target = XA_STRING;              target = XA_STRING;
493          }          }
494          if (formatName != NULL) {          if (formatName != NULL) {
495              format = Tk_InternAtom(tkwin, formatName);              format = Tk_InternAtom(tkwin, formatName);
496          } else {          } else {
497              format = XA_STRING;              format = XA_STRING;
498          }          }
499          return Tk_ClipboardAppend(interp, tkwin, target, format, args[0]);          return Tk_ClipboardAppend(interp, tkwin, target, format, args[0]);
500      } else if ((c == 'c') && (strncmp(argv[1], "clear", length) == 0)) {      } else if ((c == 'c') && (strncmp(argv[1], "clear", length) == 0)) {
501          for (count = argc-2, args = argv+2; count > 0; count -= 2, args += 2) {          for (count = argc-2, args = argv+2; count > 0; count -= 2, args += 2) {
502              if (args[0][0] != '-') {              if (args[0][0] != '-') {
503                  break;                  break;
504              }              }
505              if (count < 2) {              if (count < 2) {
506                  Tcl_AppendResult(interp, "value for \"", *args,                  Tcl_AppendResult(interp, "value for \"", *args,
507                          "\" missing", (char *) NULL);                          "\" missing", (char *) NULL);
508                  return TCL_ERROR;                  return TCL_ERROR;
509              }              }
510              c = args[0][1];              c = args[0][1];
511              length = strlen(args[0]);              length = strlen(args[0]);
512              if ((c == 'd') && (strncmp(args[0], "-displayof", length) == 0)) {              if ((c == 'd') && (strncmp(args[0], "-displayof", length) == 0)) {
513                  path = args[1];                  path = args[1];
514              } else {              } else {
515                  Tcl_AppendResult(interp, "unknown option \"", args[0],                  Tcl_AppendResult(interp, "unknown option \"", args[0],
516                          "\"", (char *) NULL);                          "\"", (char *) NULL);
517                  return TCL_ERROR;                  return TCL_ERROR;
518              }              }
519          }          }
520          if (count > 0) {          if (count > 0) {
521              Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],              Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
522                      " clear ?options?\"", (char *) NULL);                      " clear ?options?\"", (char *) NULL);
523              return TCL_ERROR;              return TCL_ERROR;
524          }          }
525          if (path != NULL) {          if (path != NULL) {
526              tkwin = Tk_NameToWindow(interp, path, tkwin);              tkwin = Tk_NameToWindow(interp, path, tkwin);
527          }          }
528          if (tkwin == NULL) {          if (tkwin == NULL) {
529              return TCL_ERROR;              return TCL_ERROR;
530          }          }
531          return Tk_ClipboardClear(interp, tkwin);          return Tk_ClipboardClear(interp, tkwin);
532      } else {      } else {
533          char buf[100 + TCL_INTEGER_SPACE];          char buf[100 + TCL_INTEGER_SPACE];
534                    
535          sprintf(buf, "bad option \"%.50s\": must be clear or append", argv[1]);          sprintf(buf, "bad option \"%.50s\": must be clear or append", argv[1]);
536          Tcl_SetResult(interp, buf, TCL_VOLATILE);          Tcl_SetResult(interp, buf, TCL_VOLATILE);
537          return TCL_ERROR;          return TCL_ERROR;
538      }      }
539  }  }
540    
541  /*  /*
542   *----------------------------------------------------------------------   *----------------------------------------------------------------------
543   *   *
544   * TkClipInit --   * TkClipInit --
545   *   *
546   *      This procedure is called to initialize the window for claiming   *      This procedure is called to initialize the window for claiming
547   *      clipboard ownership and for receiving selection get results.  This   *      clipboard ownership and for receiving selection get results.  This
548   *      function is called from tkSelect.c as well as tkClipboard.c.   *      function is called from tkSelect.c as well as tkClipboard.c.
549   *   *
550   * Results:   * Results:
551   *      The result is a standard Tcl return value, which is normally TCL_OK.   *      The result is a standard Tcl return value, which is normally TCL_OK.
552   *      If an error occurs then an error message is left in the interp's   *      If an error occurs then an error message is left in the interp's
553   *      result and TCL_ERROR is returned.   *      result and TCL_ERROR is returned.
554   *   *
555   * Side effects:   * Side effects:
556   *      Sets up the clipWindow and related data structures.   *      Sets up the clipWindow and related data structures.
557   *   *
558   *----------------------------------------------------------------------   *----------------------------------------------------------------------
559   */   */
560    
561  int  int
562  TkClipInit(interp, dispPtr)  TkClipInit(interp, dispPtr)
563      Tcl_Interp *interp;         /* Interpreter to use for error      Tcl_Interp *interp;         /* Interpreter to use for error
564                                   * reporting. */                                   * reporting. */
565      register TkDisplay *dispPtr;/* Display to initialize. */      register TkDisplay *dispPtr;/* Display to initialize. */
566  {  {
567      XSetWindowAttributes atts;      XSetWindowAttributes atts;
568    
569      dispPtr->clipTargetPtr = NULL;      dispPtr->clipTargetPtr = NULL;
570      dispPtr->clipboardActive = 0;      dispPtr->clipboardActive = 0;
571      dispPtr->clipboardAppPtr = NULL;      dispPtr->clipboardAppPtr = NULL;
572            
573      /*      /*
574       * Create the window used for clipboard ownership and selection retrieval,       * Create the window used for clipboard ownership and selection retrieval,
575       * and set up an event handler for it.       * and set up an event handler for it.
576       */       */
577    
578      dispPtr->clipWindow = Tk_CreateWindow(interp, (Tk_Window) NULL,      dispPtr->clipWindow = Tk_CreateWindow(interp, (Tk_Window) NULL,
579              "_clip", DisplayString(dispPtr->display));              "_clip", DisplayString(dispPtr->display));
580      if (dispPtr->clipWindow == NULL) {      if (dispPtr->clipWindow == NULL) {
581          return TCL_ERROR;          return TCL_ERROR;
582      }      }
583      atts.override_redirect = True;      atts.override_redirect = True;
584      Tk_ChangeWindowAttributes(dispPtr->clipWindow, CWOverrideRedirect, &atts);      Tk_ChangeWindowAttributes(dispPtr->clipWindow, CWOverrideRedirect, &atts);
585      Tk_MakeWindowExist(dispPtr->clipWindow);      Tk_MakeWindowExist(dispPtr->clipWindow);
586    
587      if (dispPtr->multipleAtom == None) {      if (dispPtr->multipleAtom == None) {
588          /*          /*
589           * Need to invoke selection initialization to make sure that           * Need to invoke selection initialization to make sure that
590           * atoms we depend on below are defined.           * atoms we depend on below are defined.
591           */           */
592    
593          TkSelInit(dispPtr->clipWindow);          TkSelInit(dispPtr->clipWindow);
594      }      }
595    
596      /*      /*
597       * Create selection handlers for types TK_APPLICATION and TK_WINDOW       * Create selection handlers for types TK_APPLICATION and TK_WINDOW
598       * on this window.  Can't use the default handlers for these types       * on this window.  Can't use the default handlers for these types
599       * because this isn't a full-fledged window.       * because this isn't a full-fledged window.
600       */       */
601    
602      Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,      Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
603              dispPtr->applicationAtom, ClipboardAppHandler,              dispPtr->applicationAtom, ClipboardAppHandler,
604              (ClientData) dispPtr, XA_STRING);              (ClientData) dispPtr, XA_STRING);
605      Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,      Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
606              dispPtr->windowAtom, ClipboardWindowHandler,              dispPtr->windowAtom, ClipboardWindowHandler,
607              (ClientData) dispPtr, XA_STRING);              (ClientData) dispPtr, XA_STRING);
608      return TCL_OK;      return TCL_OK;
609  }  }
610    
611  /* End of tkclipboard.c */  /* End of tkclipboard.c */

Legend:
Removed from v.69  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25