home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tk42r2s.zip / tk4.2 / os2 / tkOS2Clipboard.c < prev    next >
C/C++ Source or Header  |  1999-07-26  |  9KB  |  329 lines

  1. /* 
  2.  * tkOS2Clipboard.c --
  3.  *
  4.  *    This file contains functions for managing the clipboard.
  5.  *
  6.  * Copyright (c) 1996-1998 Illya Vaes
  7.  * Copyright (c) 1995 Sun Microsystems, Inc.
  8.  *
  9.  * See the file "license.terms" for information on usage and redistribution
  10.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  */
  12.  
  13. #include "tkOS2Int.h"
  14. #include "tkSelect.h"
  15.  
  16. /* Needed for signal-catching after we've become clipboard-owner */
  17. #include <signal.h>
  18. void sighandler(int sig);
  19.  
  20.  
  21. /*
  22.  *----------------------------------------------------------------------
  23.  *
  24.  * TkSelGetSelection --
  25.  *
  26.  *    Retrieve the specified selection from another process.  For
  27.  *    now, only fetching XA_STRING from CLIPBOARD is supported.
  28.  *    Eventually other types should be allowed.
  29.  * 
  30.  * Results:
  31.  *    The return value is a standard Tcl return value.
  32.  *    If an error occurs (such as no selection exists)
  33.  *    then an error message is left in interp->result.
  34.  *
  35.  * Side effects:
  36.  *    None.
  37.  *
  38.  *----------------------------------------------------------------------
  39.  */
  40.  
  41. int
  42. TkSelGetSelection(interp, tkwin, selection, target, proc, clientData)
  43.     Tcl_Interp *interp;        /* Interpreter to use for reporting
  44.                  * errors. */
  45.     Tk_Window tkwin;        /* Window on whose behalf to retrieve
  46.                  * the selection (determines display
  47.                  * from which to retrieve). */
  48.     Atom selection;        /* Selection to retrieve. */
  49.     Atom target;        /* Desired form in which selection
  50.                  * is to be returned. */
  51.     Tk_GetSelProc *proc;    /* Procedure to call to process the
  52.                  * selection, once it has been retrieved. */
  53.     ClientData clientData;    /* Arbitrary value to pass to proc. */
  54. {
  55.     char *data, *buffer, *destPtr;
  56.     int result, length;
  57.  
  58.     if ((selection == Tk_InternAtom(tkwin, "CLIPBOARD"))
  59.         && (target == XA_STRING)) {
  60.     if (WinOpenClipbrd(hab)) {
  61.         if ((data= (char *)WinQueryClipbrdData(hab, CF_TEXT))) {
  62.         length = strlen(data);
  63.         buffer = ckalloc(length+1);
  64.         destPtr = buffer;
  65.         while (*data != '\0') {
  66.             if (*data != '\r') {
  67.             *destPtr = *data;
  68.             destPtr++;
  69.             }
  70.             data++;
  71.         }
  72.         *destPtr = '\0';
  73.         WinCloseClipbrd(hab);
  74.         result = (*proc)(clientData, interp, buffer);
  75.         ckfree(buffer);
  76.         return result;
  77.         }
  78.         WinCloseClipbrd(hab);
  79.     }
  80.     }
  81.  
  82.     Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
  83.     " selection doesn't exist or form \"", Tk_GetAtomName(tkwin, target),
  84.     "\" not defined", (char *) NULL);
  85.     return TCL_ERROR;
  86. }
  87.  
  88. /*
  89.  *----------------------------------------------------------------------
  90.  *
  91.  * XSetSelectionOwner --
  92.  *
  93.  *    This function claims ownership of the specified selection.
  94.  *    If the selection is CLIPBOARD, then we empty the system
  95.  *    clipboard.
  96.  *
  97.  * Results:
  98.  *    None.
  99.  *
  100.  * Side effects:
  101.  *    Empties the system clipboard, and claims ownership.
  102.  *
  103.  *----------------------------------------------------------------------
  104.  */
  105.  
  106. void
  107. XSetSelectionOwner(display, selection, owner, time)
  108.     Display* display;
  109.     Atom selection;
  110.     Window owner;
  111.     Time time;
  112. {
  113.     HWND hwnd = owner ? TkOS2GetHWND(owner) : NULLHANDLE;
  114.     Tk_Window tkwin;
  115.  
  116.     /*
  117.      * This is a gross hack because the Tk_InternAtom interface is broken.
  118.      * It expects a Tk_Window, even though it only needs a Tk_Display.
  119.      */
  120.  
  121.     tkwin = (Tk_Window)tkMainWindowList->winPtr;
  122.  
  123.     if (selection == Tk_InternAtom(tkwin, "CLIPBOARD")) {
  124.  
  125.     /*
  126.      * Only claim and empty the clipboard if we aren't already the
  127.      * owner of the clipboard.
  128.      */
  129.  
  130.     if (WinQueryClipbrdOwner(hab) != hwnd) {
  131.             rc = WinOpenClipbrd(hab);
  132.             rc = WinEmptyClipbrd(hab);
  133.             rc = WinSetClipbrdData(hab, NULLHANDLE, CF_TEXT, CFI_POINTER);
  134.             rc = WinCloseClipbrd(hab);
  135.             /*
  136.              * If we've become owner of the clipboard but are terminated by
  137.              * a signal, the whole system will be hanging waiting for it.
  138.              */
  139.             signal(SIGFPE, sighandler);
  140.             signal(SIGTERM, sighandler);
  141.             signal(SIGSEGV, sighandler);
  142.             rc = WinSetClipbrdOwner(hab, hwnd);
  143.     }
  144.     }
  145. }
  146.  
  147. /*
  148.  *----------------------------------------------------------------------
  149.  *
  150.  * sighandler --
  151.  *
  152.  *    This function is invoked upon a terminating signal, so we can
  153.  *    release the clipboard to the system (no owner).
  154.  *
  155.  * Results:
  156.  *    None.
  157.  *
  158.  * Side effects:
  159.  *    Relinquishises ownership of the clipboard and exits.
  160.  *
  161.  *----------------------------------------------------------------------
  162.  */
  163.  
  164. void sighandler(int sig)
  165. {
  166.     rc = WinSetClipbrdOwner(hab, NULLHANDLE);
  167.     exit(1);
  168. }
  169.  
  170. /*
  171.  *----------------------------------------------------------------------
  172.  *
  173.  * TkOS2ClipboardRender --
  174.  *
  175.  *    This function supplies the contents of the clipboard in
  176.  *    response to a WM_RENDERFMT message.
  177.  *
  178.  * Results:
  179.  *    None.
  180.  *
  181.  * Side effects:
  182.  *    Sets the contents of the clipboard.
  183.  *
  184.  *----------------------------------------------------------------------
  185.  */
  186.  
  187. void
  188. TkOS2ClipboardRender(winPtr, format)
  189.     TkWindow *winPtr;
  190.     ULONG format;
  191. {
  192.     TkClipboardTarget *targetPtr;
  193.     TkClipboardBuffer *cbPtr;
  194.     TkDisplay *dispPtr = winPtr->dispPtr;
  195.     PVOID mem;
  196.     char *buffer, *p, *endPtr;
  197.     int length;
  198.  
  199.     if (format != CF_TEXT) {
  200.         return;
  201.     }
  202.  
  203.     for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
  204.         targetPtr = targetPtr->nextPtr) {
  205.     if (targetPtr->type == XA_STRING) {
  206.         break;
  207.         }
  208.     }
  209.     length = 0;
  210.     if (targetPtr != NULL) {
  211.     for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
  212.         cbPtr = cbPtr->nextPtr) {
  213.         length += cbPtr->length;
  214.             for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
  215.                     p < endPtr; p++) {
  216.                 if (*p == '\n') {
  217.                     length++;
  218.                 }
  219.             }
  220.     }
  221.     }
  222.     if ( (rc = DosAllocSharedMem(&mem, NULL, length+1,
  223.               OBJ_GIVEABLE | PAG_COMMIT | PAG_READ | PAG_WRITE)) != 0) {
  224.     return;
  225.     }
  226.     buffer= (char *)mem;
  227.     if (targetPtr != NULL) {
  228.     for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
  229.         cbPtr = cbPtr->nextPtr) {
  230.             for (p = cbPtr->buffer, endPtr = p + cbPtr->length;
  231.                     p < endPtr; p++) {
  232.                 if (*p == '\n') {
  233.                     *buffer++ = '\r';
  234.                 }
  235.                 *buffer++ = *p;
  236.             }
  237.     }
  238.     }
  239.     *buffer = '\0';
  240.     rc = WinSetClipbrdData(hab, (ULONG)mem, CF_TEXT, CFI_POINTER);
  241.     return;
  242. }
  243.  
  244. /*
  245.  *----------------------------------------------------------------------
  246.  *
  247.  * TkSelUpdateClipboard --
  248.  *
  249.  *    This function is called to force the clipboard to be updated
  250.  *    after new data is added.
  251.  *
  252.  * Results:
  253.  *    None.
  254.  *
  255.  * Side effects:
  256.  *    Clears the current contents of the clipboard.
  257.  *
  258.  *----------------------------------------------------------------------
  259.  */
  260.  
  261. void
  262. TkSelUpdateClipboard(winPtr, targetPtr)
  263.     TkWindow *winPtr;
  264.     TkClipboardTarget *targetPtr;
  265. {
  266.     /*
  267.     HWND hwnd = TkOS2GetHWND(winPtr->window);
  268.     */
  269.  
  270.     rc = WinOpenClipbrd(hab);
  271.     rc = WinEmptyClipbrd(hab);
  272.     rc = WinSetClipbrdData(hab, NULLHANDLE, CF_TEXT, CFI_POINTER);
  273.     rc = WinCloseClipbrd(hab);
  274. }
  275.  
  276. /*
  277.  *--------------------------------------------------------------
  278.  *
  279.  * TkSelEventProc --
  280.  *
  281.  *    This procedure is invoked whenever a selection-related
  282.  *    event occurs. 
  283.  *
  284.  * Results:
  285.  *    None.
  286.  *
  287.  * Side effects:
  288.  *    Lots:  depends on the type of event.
  289.  *
  290.  *--------------------------------------------------------------
  291.  */
  292.  
  293. void
  294. TkSelEventProc(tkwin, eventPtr)
  295.     Tk_Window tkwin;        /* Window for which event was
  296.                  * targeted. */
  297.     register XEvent *eventPtr;    /* X event:  either SelectionClear,
  298.                  * SelectionRequest, or
  299.                  * SelectionNotify. */
  300. {
  301.     if (eventPtr->type == SelectionClear) {
  302.     TkSelClearSelection(tkwin, eventPtr);
  303.     }
  304. }
  305.  
  306. /*
  307.  *----------------------------------------------------------------------
  308.  *
  309.  * TkSelPropProc --
  310.  *
  311.  *    This procedure is invoked when property-change events
  312.  *    occur on windows not known to the toolkit.  This is a stub
  313.  *    function under OS/2 Presentation Manager.
  314.  *
  315.  * Results:
  316.  *    None.
  317.  *
  318.  * Side effects:
  319.  *    None.
  320.  *
  321.  *----------------------------------------------------------------------
  322.  */
  323.  
  324. void
  325. TkSelPropProc(eventPtr)
  326.     register XEvent *eventPtr;        /* X PropertyChange event. */
  327. {
  328. }
  329.