home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tkisrc04.zip / tk / os2 / tkOS2Clipboard.c < prev    next >
C/C++ Source or Header  |  1998-08-07  |  11KB  |  432 lines

  1. /* 
  2.  * tkOS2Clipboard.c --
  3.  *
  4.  *    This file contains functions for managing the clipboard.
  5.  *
  6.  * Copyright (c) 1996-1997 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. #ifdef DEBUG
  61.         printf("TkSelGetSelection, CLIPBOARD\n");
  62. #endif
  63.     if (WinOpenClipbrd(hab)) {
  64. #ifdef DEBUG
  65.             printf("WinOpenClipbrd OK\n");
  66. #endif
  67.         if ((data= (char *)WinQueryClipbrdData(hab, CF_TEXT))) {
  68.         length = strlen(data);
  69. #ifdef DEBUG
  70.                 printf("WinQueryClipbrdData OK: %s (%d)\n", data, length);
  71. #endif
  72.         buffer = ckalloc(length+1);
  73.         destPtr = buffer;
  74.         while (*data != '\0') {
  75.             if (*data != '\r') {
  76.             *destPtr = *data;
  77.             destPtr++;
  78.             }
  79.             data++;
  80.         }
  81.         *destPtr = '\0';
  82.         WinCloseClipbrd(hab);
  83.         result = (*proc)(clientData, interp, buffer);
  84.         ckfree(buffer);
  85.         return result;
  86.         }
  87. #ifdef DEBUG
  88.             printf("WinQueryClipbrdData ERROR or no such format: %x\n", data);
  89. #endif
  90.         WinCloseClipbrd(hab);
  91.     }
  92. #ifdef DEBUG
  93.           else {
  94.             printf("WinOpenClipbrd ERROR %x\n", WinGetLastError(hab));
  95.         }
  96. #endif
  97.     }
  98. #ifdef DEBUG
  99.       else {
  100.         printf("TkSelGetSelection, != CLIPBOARD, target %x (%s), selection %x (%s)\n",
  101.                target, Tk_GetAtomName(tkwin, target),
  102.                selection, Tk_GetAtomName(tkwin, selection));
  103.     }
  104. #endif
  105.  
  106.     Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection),
  107.     " selection doesn't exist or form \"", Tk_GetAtomName(tkwin, target),
  108.     "\" not defined", (char *) NULL);
  109.     return TCL_ERROR;
  110. }
  111.  
  112. /*
  113.  *----------------------------------------------------------------------
  114.  *
  115.  * XSetSelectionOwner --
  116.  *
  117.  *    This function claims ownership of the specified selection.
  118.  *    If the selection is CLIPBOARD, then we empty the system
  119.  *    clipboard.
  120.  *
  121.  * Results:
  122.  *    None.
  123.  *
  124.  * Side effects:
  125.  *    Empties the system clipboard, and claims ownership.
  126.  *
  127.  *----------------------------------------------------------------------
  128.  */
  129.  
  130. void
  131. XSetSelectionOwner(display, selection, owner, time)
  132.     Display* display;
  133.     Atom selection;
  134.     Window owner;
  135.     Time time;
  136. {
  137.     HWND hwnd = owner ? TkOS2GetHWND(owner) : NULLHANDLE;
  138.     Tk_Window tkwin;
  139.  
  140. #ifdef DEBUG
  141.     printf("XSetSelectionOwner\n");
  142. #endif
  143.  
  144.     /*
  145.      * This is a gross hack because the Tk_InternAtom interface is broken.
  146.      * It expects a Tk_Window, even though it only needs a Tk_Display.
  147.      */
  148.  
  149.     tkwin = (Tk_Window)tkMainWindowList->winPtr;
  150.  
  151.     if (selection == Tk_InternAtom(tkwin, "CLIPBOARD")) {
  152.  
  153. #ifdef DEBUG
  154.         printf("    selection CLIPBOARD\n");
  155. #endif
  156.     /*
  157.      * Only claim and empty the clipboard if we aren't already the
  158.      * owner of the clipboard.
  159.      */
  160.  
  161.     if (WinQueryClipbrdOwner(hab) != hwnd) {
  162.             rc = WinOpenClipbrd(hab);
  163. #ifdef DEBUG
  164.             if (rc==TRUE) printf("WinOpenClipbrd OK\n");
  165.             else printf("WinOpenClipBrd ERROR %x\n", WinGetLastError(hab));
  166. #endif
  167.             rc = WinEmptyClipbrd(hab);
  168. #ifdef DEBUG
  169.             if (rc==TRUE) printf("WinEmptyClipbrd OK\n");
  170.             else printf("WinEmptyClipBrd ERROR %x\n", WinGetLastError(hab));
  171. #endif
  172.             rc = WinSetClipbrdData(hab, NULLHANDLE, CF_TEXT, CFI_POINTER);
  173. #ifdef DEBUG
  174.             if (rc==TRUE) printf("WinSetClipbrdData OK\n");
  175.             else printf("WinSetClipBrdData ERROR %x\n", WinGetLastError(hab));
  176. #endif
  177.             rc = WinCloseClipbrd(hab);
  178. #ifdef DEBUG
  179.             if (rc==TRUE) printf("WinCloseClipbrd OK\n");
  180.             else printf("WinCloseClipBrd ERROR %x\n", WinGetLastError(hab));
  181. #endif
  182.             /*
  183.              * If we've become owner of the clipboard but are terminated by
  184.              * a signal, the whole system will be hanging waiting for it.
  185.              */
  186.             signal(SIGFPE, sighandler);
  187.             signal(SIGTERM, sighandler);
  188.             signal(SIGSEGV, sighandler);
  189.             rc = WinSetClipbrdOwner(hab, hwnd);
  190. #ifdef DEBUG
  191.             if (rc==TRUE) printf("WinSetClipbrdOwner OK\n");
  192.             else printf("WinSetClipBrdOwner ERROR %x\n", WinGetLastError(hab));
  193. #endif
  194.     }
  195.     }
  196. }
  197.  
  198. /*
  199.  *----------------------------------------------------------------------
  200.  *
  201.  * sighandler --
  202.  *
  203.  *    This function is invoked upon a terminating signal, so we can
  204.  *    release the clipboard to the system (no owner).
  205.  *
  206.  * Results:
  207.  *    None.
  208.  *
  209.  * Side effects:
  210.  *    Relinquishises ownership of the clipboard and exits.
  211.  *
  212.  *----------------------------------------------------------------------
  213.  */
  214.  
  215. void sighandler(int sig)
  216. {
  217.     rc = WinSetClipbrdOwner(hab, NULLHANDLE);
  218. #ifdef DEBUG
  219.     if (rc==TRUE) printf("\nSIGNAL %d: WinSetClipbrdOwner OK\n", sig);
  220.     else printf("\nSIGNAL %d: WinSetClipBrdOwner ERROR %x\n", sig,
  221.                 WinGetLastError(hab));
  222. #endif
  223.     exit(1);
  224. }
  225.  
  226. /*
  227.  *----------------------------------------------------------------------
  228.  *
  229.  * TkOS2ClipboardRender --
  230.  *
  231.  *    This function supplies the contents of the clipboard in
  232.  *    response to a WM_RENDERFMT message.
  233.  *
  234.  * Results:
  235.  *    None.
  236.  *
  237.  * Side effects:
  238.  *    Sets the contents of the clipboard.
  239.  *
  240.  *----------------------------------------------------------------------
  241.  */
  242.  
  243. void
  244. TkOS2ClipboardRender(winPtr, format)
  245.     TkWindow *winPtr;
  246.     ULONG format;
  247. {
  248.     TkClipboardTarget *targetPtr;
  249.     TkClipboardBuffer *cbPtr;
  250.     TkDisplay *dispPtr = winPtr->dispPtr;
  251.     PVOID mem;
  252.     char *buffer;
  253.     int length;
  254.  
  255.     if (format != CF_TEXT) {
  256. #ifdef DEBUG
  257.         printf("TkOS2ClipboardRender != CF_TEXT (%x)\n", format);
  258. #endif
  259.         return;
  260.     }
  261. #ifdef DEBUG
  262.     printf("TkOS2ClipboardRender CF_TEXT\n");
  263. #endif
  264.  
  265.     for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL;
  266.         targetPtr = targetPtr->nextPtr) {
  267.     if (targetPtr->type == XA_STRING) {
  268. #ifdef DEBUG
  269.             printf("Found target XA_STRING\n");
  270. #endif
  271.         break;
  272.         }
  273.     }
  274.     length = 0;
  275.     if (targetPtr != NULL) {
  276.     for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
  277.         cbPtr = cbPtr->nextPtr) {
  278.         length += cbPtr->length;
  279.     }
  280.     }
  281.     if ( (rc = DosAllocSharedMem(&mem, NULL, length+1,
  282.               OBJ_GIVEABLE | PAG_COMMIT | PAG_READ | PAG_WRITE)) != 0) {
  283. #ifdef DEBUG
  284.         printf("TkOS2ClipboardRender: DosAllocSharedMem ERROR %x\n", rc);
  285. #endif
  286.     return;
  287.     }
  288. #ifdef DEBUG
  289.     printf("TkOS2ClipboardRender: DosAllocSharedMem %s (%d) OK\n", mem, length+1);
  290. #endif
  291.     buffer= (char *)mem;
  292.     if (targetPtr != NULL) {
  293.     for (cbPtr = targetPtr->firstBufferPtr; cbPtr != NULL;
  294.         cbPtr = cbPtr->nextPtr) {
  295.         strncpy(buffer, cbPtr->buffer, cbPtr->length);
  296.         buffer += cbPtr->length;
  297.     }
  298.     }
  299.     *buffer = '\0';
  300.     rc = WinSetClipbrdData(hab, (ULONG)mem, CF_TEXT, CFI_POINTER);
  301. #ifdef DEBUG
  302.     if (rc==TRUE) {
  303.         printf("WinSetClipbrdData OK\n", mem);
  304.     } else {
  305.         printf("WinSetClipbrdData ERROR %x\n", WinGetLastError(hab));
  306.     }
  307. #endif
  308.     return;
  309. }
  310.  
  311. /*
  312.  *----------------------------------------------------------------------
  313.  *
  314.  * TkSelUpdateClipboard --
  315.  *
  316.  *    This function is called to force the clipboard to be updated
  317.  *    after new data is added.
  318.  *
  319.  * Results:
  320.  *    None.
  321.  *
  322.  * Side effects:
  323.  *    Clears the current contents of the clipboard.
  324.  *
  325.  *----------------------------------------------------------------------
  326.  */
  327.  
  328. void
  329. TkSelUpdateClipboard(winPtr, targetPtr)
  330.     TkWindow *winPtr;
  331.     TkClipboardTarget *targetPtr;
  332. {
  333.     /*
  334.     HWND hwnd = TkOS2GetHWND(winPtr->window);
  335.     */
  336.  
  337. #ifdef DEBUG
  338.     printf("TkSelUpdateClipboard\n");
  339. #endif
  340.  
  341.     rc = WinOpenClipbrd(hab);
  342. #ifdef DEBUG
  343.     if (rc==TRUE) {
  344.         printf("WinOpenClipbrd OK\n");
  345.     } else {
  346.         printf("WinOpenClipBrd ERROR %x\n", WinGetLastError(hab));
  347.     }
  348. #endif
  349.     rc = WinEmptyClipbrd(hab);
  350. #ifdef DEBUG
  351.     if (rc==TRUE) {
  352.         printf("WinEmptyClipbrd OK\n");
  353.     } else {
  354.         printf("WinEmptyClipBrd ERROR %x\n", WinGetLastError(hab));
  355.     }
  356. #endif
  357.     rc = WinSetClipbrdData(hab, NULLHANDLE, CF_TEXT, CFI_POINTER);
  358. #ifdef DEBUG
  359.     if (rc==TRUE) {
  360.         printf("WinSetClipbrdData OK\n");
  361.     } else {
  362.         printf("WinSetClipBrdData ERROR %x\n", WinGetLastError(hab));
  363.     }
  364. #endif
  365.     rc = WinCloseClipbrd(hab);
  366. #ifdef DEBUG
  367.     if (rc==TRUE) {
  368.         printf("WinCloseClipbrd OK\n");
  369.     } else {
  370.         printf("WinCloseClipBrd ERROR %x\n", WinGetLastError(hab));
  371.     }
  372. #endif
  373. }
  374.  
  375. /*
  376.  *--------------------------------------------------------------
  377.  *
  378.  * TkSelEventProc --
  379.  *
  380.  *    This procedure is invoked whenever a selection-related
  381.  *    event occurs. 
  382.  *
  383.  * Results:
  384.  *    None.
  385.  *
  386.  * Side effects:
  387.  *    Lots:  depends on the type of event.
  388.  *
  389.  *--------------------------------------------------------------
  390.  */
  391.  
  392. void
  393. TkSelEventProc(tkwin, eventPtr)
  394.     Tk_Window tkwin;        /* Window for which event was
  395.                  * targeted. */
  396.     register XEvent *eventPtr;    /* X event:  either SelectionClear,
  397.                  * SelectionRequest, or
  398.                  * SelectionNotify. */
  399. {
  400. #ifdef DEBUG
  401. printf("TkSelEventProc\n");
  402. #endif
  403.  
  404.     if (eventPtr->type == SelectionClear) {
  405.     TkSelClearSelection(tkwin, eventPtr);
  406.     }
  407. }
  408.  
  409. /*
  410.  *----------------------------------------------------------------------
  411.  *
  412.  * TkSelPropProc --
  413.  *
  414.  *    This procedure is invoked when property-change events
  415.  *    occur on windows not known to the toolkit.  This is a stub
  416.  *    function under OS/2 Presentation Manager.
  417.  *
  418.  * Results:
  419.  *    None.
  420.  *
  421.  * Side effects:
  422.  *    None.
  423.  *
  424.  *----------------------------------------------------------------------
  425.  */
  426.  
  427. void
  428. TkSelPropProc(eventPtr)
  429.     register XEvent *eventPtr;        /* X PropertyChange event. */
  430. {
  431. }
  432.