home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tcltk805.zip / tcl805s.zip / tk8.0.5 / os2 / tkOS2Clipboard.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  12KB  |  448 lines

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