winclipboardxevents.c revision 706f2543
1/* 2 *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. 3 *Copyright (C) Colin Harrison 2005-2008 4 * 5 *Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 *"Software"), to deal in the Software without restriction, including 8 *without limitation the rights to use, copy, modify, merge, publish, 9 *distribute, sublicense, and/or sell copies of the Software, and to 10 *permit persons to whom the Software is furnished to do so, subject to 11 *the following conditions: 12 * 13 *The above copyright notice and this permission notice shall be 14 *included in all copies or substantial portions of the Software. 15 * 16 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR 20 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 21 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 *Except as contained in this notice, the name of the copyright holder(s) 25 *and author(s) shall not be used in advertising or otherwise to promote 26 *the sale, use or other dealings in this Software without prior written 27 *authorization from the copyright holder(s) and author(s). 28 * 29 * Authors: Harold L Hunt II 30 * Colin Harrison 31 */ 32 33#ifdef HAVE_XWIN_CONFIG_H 34#include <xwin-config.h> 35#endif 36#include "winclipboard.h" 37#include "misc.h" 38 39 40/* 41 * References to external symbols 42 */ 43 44extern Bool g_fUnicodeSupport; 45 46 47/* 48 * Process any pending X events 49 */ 50 51int 52winClipboardFlushXEvents (HWND hwnd, 53 int iWindow, 54 Display *pDisplay, 55 Bool fUseUnicode) 56{ 57 static Atom atomLocalProperty; 58 static Atom atomCompoundText; 59 static Atom atomUTF8String; 60 static Atom atomTargets; 61 static int generation; 62 63 if (generation != serverGeneration) 64 { 65 generation = serverGeneration; 66 atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False); 67 atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); 68 atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); 69 atomTargets = XInternAtom (pDisplay, "TARGETS", False); 70 } 71 72 /* Process all pending events */ 73 while (XPending (pDisplay)) 74 { 75 XTextProperty xtpText = {0}; 76 XEvent event; 77 XSelectionEvent eventSelection; 78 unsigned long ulReturnBytesLeft; 79 char *pszReturnData = NULL; 80 char *pszGlobalData = NULL; 81 int iReturn; 82 HGLOBAL hGlobal = NULL; 83 XICCEncodingStyle xiccesStyle; 84 int iConvertDataLen = 0; 85 char *pszConvertData = NULL; 86 char *pszTextList[2] = {NULL}; 87 int iCount; 88 char **ppszTextList = NULL; 89 wchar_t *pwszUnicodeStr = NULL; 90 int iUnicodeLen = 0; 91 int iReturnDataLen = 0; 92 int i; 93 Bool fAbort = FALSE; 94 Bool fCloseClipboard = FALSE; 95 Bool fSetClipboardData = TRUE; 96 97 /* Get the next event - will not block because one is ready */ 98 XNextEvent (pDisplay, &event); 99 100 /* Branch on the event type */ 101 switch (event.type) 102 { 103 /* 104 * SelectionRequest 105 */ 106 107 case SelectionRequest: 108 { 109 char *pszAtomName = NULL; 110 winDebug("SelectionRequest - target %d\n", 111 event.xselectionrequest.target); 112 113 pszAtomName = XGetAtomName (pDisplay, 114 event.xselectionrequest.target); 115 winDebug("SelectionRequest - Target atom name %s\n", pszAtomName); 116 XFree (pszAtomName); 117 pszAtomName = NULL; 118 } 119 120 /* Abort if invalid target type */ 121 if (event.xselectionrequest.target != XA_STRING 122 && event.xselectionrequest.target != atomUTF8String 123 && event.xselectionrequest.target != atomCompoundText 124 && event.xselectionrequest.target != atomTargets) 125 { 126 /* Abort */ 127 fAbort = TRUE; 128 goto winClipboardFlushXEvents_SelectionRequest_Done; 129 } 130 131 /* Handle targets type of request */ 132 if (event.xselectionrequest.target == atomTargets) 133 { 134 Atom atomTargetArr[] = {atomTargets, 135 atomCompoundText, 136 atomUTF8String, 137 XA_STRING}; 138 139 /* Try to change the property */ 140 iReturn = XChangeProperty (pDisplay, 141 event.xselectionrequest.requestor, 142 event.xselectionrequest.property, 143 XA_ATOM, 144 32, 145 PropModeReplace, 146 (unsigned char *) atomTargetArr, 147 (sizeof (atomTargetArr) 148 / sizeof (atomTargetArr[0]))); 149 if (iReturn == BadAlloc 150 || iReturn == BadAtom 151 || iReturn == BadMatch 152 || iReturn == BadValue 153 || iReturn == BadWindow) 154 { 155 ErrorF ("winClipboardFlushXEvents - SelectionRequest - " 156 "XChangeProperty failed: %d\n", 157 iReturn); 158 } 159 160 /* Setup selection notify xevent */ 161 eventSelection.type = SelectionNotify; 162 eventSelection.send_event = True; 163 eventSelection.display = pDisplay; 164 eventSelection.requestor = event.xselectionrequest.requestor; 165 eventSelection.selection = event.xselectionrequest.selection; 166 eventSelection.target = event.xselectionrequest.target; 167 eventSelection.property = event.xselectionrequest.property; 168 eventSelection.time = event.xselectionrequest.time; 169 170 /* 171 * Notify the requesting window that 172 * the operation has completed 173 */ 174 iReturn = XSendEvent (pDisplay, 175 eventSelection.requestor, 176 False, 177 0L, 178 (XEvent *) &eventSelection); 179 if (iReturn == BadValue || iReturn == BadWindow) 180 { 181 ErrorF ("winClipboardFlushXEvents - SelectionRequest - " 182 "XSendEvent () failed\n"); 183 } 184 break; 185 } 186 187 /* Check that clipboard format is available */ 188 if (fUseUnicode 189 && !IsClipboardFormatAvailable (CF_UNICODETEXT)) 190 { 191 static int count; /* Hack to stop acroread spamming the log */ 192 static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */ 193 if (hwnd != lasthwnd) count = 0; 194 count++; 195 if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not " 196 "available from Win32 clipboard. Aborting %d.\n", count); 197 lasthwnd = hwnd; 198 199 /* Abort */ 200 fAbort = TRUE; 201 goto winClipboardFlushXEvents_SelectionRequest_Done; 202 } 203 else if (!fUseUnicode 204 && !IsClipboardFormatAvailable (CF_TEXT)) 205 { 206 ErrorF ("winClipboardFlushXEvents - CF_TEXT is not " 207 "available from Win32 clipboard. Aborting.\n"); 208 209 /* Abort */ 210 fAbort = TRUE; 211 goto winClipboardFlushXEvents_SelectionRequest_Done; 212 } 213 214 /* Close clipboard if we have it open already */ 215 if (GetOpenClipboardWindow () == hwnd) 216 { 217 CloseClipboard (); 218 } 219 220 /* Access the clipboard */ 221 if (!OpenClipboard (hwnd)) 222 { 223 ErrorF ("winClipboardFlushXEvents - SelectionRequest - " 224 "OpenClipboard () failed: %08lx\n", 225 GetLastError ()); 226 227 /* Abort */ 228 fAbort = TRUE; 229 goto winClipboardFlushXEvents_SelectionRequest_Done; 230 } 231 232 /* Indicate that clipboard was opened */ 233 fCloseClipboard = TRUE; 234 235 /* Setup the string style */ 236 if (event.xselectionrequest.target == XA_STRING) 237 xiccesStyle = XStringStyle; 238#ifdef X_HAVE_UTF8_STRING 239 else if (event.xselectionrequest.target == atomUTF8String) 240 xiccesStyle = XUTF8StringStyle; 241#endif 242 else if (event.xselectionrequest.target == atomCompoundText) 243 xiccesStyle = XCompoundTextStyle; 244 else 245 xiccesStyle = XStringStyle; 246 247 /* 248 * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me 249 */ 250 251 /* Get a pointer to the clipboard text, in desired format */ 252 if (fUseUnicode) 253 { 254 /* Retrieve clipboard data */ 255 hGlobal = GetClipboardData (CF_UNICODETEXT); 256 } 257 else 258 { 259 /* Retrieve clipboard data */ 260 hGlobal = GetClipboardData (CF_TEXT); 261 } 262 if (!hGlobal) 263 { 264 ErrorF ("winClipboardFlushXEvents - SelectionRequest - " 265 "GetClipboardData () failed: %08lx\n", 266 GetLastError ()); 267 268 /* Abort */ 269 fAbort = TRUE; 270 goto winClipboardFlushXEvents_SelectionRequest_Done; 271 } 272 pszGlobalData = (char *) GlobalLock (hGlobal); 273 274 /* Convert the Unicode string to UTF8 (MBCS) */ 275 if (fUseUnicode) 276 { 277 iConvertDataLen = WideCharToMultiByte (CP_UTF8, 278 0, 279 (LPCWSTR)pszGlobalData, 280 -1, 281 NULL, 282 0, 283 NULL, 284 NULL); 285 /* NOTE: iConvertDataLen includes space for null terminator */ 286 pszConvertData = (char *) malloc (iConvertDataLen); 287 WideCharToMultiByte (CP_UTF8, 288 0, 289 (LPCWSTR)pszGlobalData, 290 -1, 291 pszConvertData, 292 iConvertDataLen, 293 NULL, 294 NULL); 295 } 296 else 297 { 298 pszConvertData = strdup (pszGlobalData); 299 iConvertDataLen = strlen (pszConvertData) + 1; 300 } 301 302 /* Convert DOS string to UNIX string */ 303 winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData)); 304 305 /* Setup our text list */ 306 pszTextList[0] = pszConvertData; 307 pszTextList[1] = NULL; 308 309 /* Initialize the text property */ 310 xtpText.value = NULL; 311 xtpText.nitems = 0; 312 313 /* Create the text property from the text list */ 314 if (fUseUnicode) 315 { 316#ifdef X_HAVE_UTF8_STRING 317 iReturn = Xutf8TextListToTextProperty (pDisplay, 318 pszTextList, 319 1, 320 xiccesStyle, 321 &xtpText); 322#endif 323 } 324 else 325 { 326 iReturn = XmbTextListToTextProperty (pDisplay, 327 pszTextList, 328 1, 329 xiccesStyle, 330 &xtpText); 331 } 332 if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) 333 { 334 ErrorF ("winClipboardFlushXEvents - SelectionRequest - " 335 "X*TextListToTextProperty failed: %d\n", 336 iReturn); 337 338 /* Abort */ 339 fAbort = TRUE; 340 goto winClipboardFlushXEvents_SelectionRequest_Done; 341 } 342 343 /* Free the converted string */ 344 free (pszConvertData); 345 pszConvertData = NULL; 346 347 /* Copy the clipboard text to the requesting window */ 348 iReturn = XChangeProperty (pDisplay, 349 event.xselectionrequest.requestor, 350 event.xselectionrequest.property, 351 event.xselectionrequest.target, 352 8, 353 PropModeReplace, 354 xtpText.value, 355 xtpText.nitems); 356 if (iReturn == BadAlloc || iReturn == BadAtom 357 || iReturn == BadMatch || iReturn == BadValue 358 || iReturn == BadWindow) 359 { 360 ErrorF ("winClipboardFlushXEvents - SelectionRequest - " 361 "XChangeProperty failed: %d\n", 362 iReturn); 363 364 /* Abort */ 365 fAbort = TRUE; 366 goto winClipboardFlushXEvents_SelectionRequest_Done; 367 } 368 369 /* Release the clipboard data */ 370 GlobalUnlock (hGlobal); 371 pszGlobalData = NULL; 372 fCloseClipboard = FALSE; 373 CloseClipboard (); 374 375 /* Clean up */ 376 XFree (xtpText.value); 377 xtpText.value = NULL; 378 xtpText.nitems = 0; 379 380 /* Setup selection notify event */ 381 eventSelection.type = SelectionNotify; 382 eventSelection.send_event = True; 383 eventSelection.display = pDisplay; 384 eventSelection.requestor = event.xselectionrequest.requestor; 385 eventSelection.selection = event.xselectionrequest.selection; 386 eventSelection.target = event.xselectionrequest.target; 387 eventSelection.property = event.xselectionrequest.property; 388 eventSelection.time = event.xselectionrequest.time; 389 390 /* Notify the requesting window that the operation has completed */ 391 iReturn = XSendEvent (pDisplay, 392 eventSelection.requestor, 393 False, 394 0L, 395 (XEvent *) &eventSelection); 396 if (iReturn == BadValue || iReturn == BadWindow) 397 { 398 ErrorF ("winClipboardFlushXEvents - SelectionRequest - " 399 "XSendEvent () failed\n"); 400 401 /* Abort */ 402 fAbort = TRUE; 403 goto winClipboardFlushXEvents_SelectionRequest_Done; 404 } 405 406 winClipboardFlushXEvents_SelectionRequest_Done: 407 /* Free allocated resources */ 408 if (xtpText.value) 409 { 410 XFree (xtpText.value); 411 xtpText.value = NULL; 412 xtpText.nitems = 0; 413 } 414 free(pszConvertData); 415 if (hGlobal && pszGlobalData) 416 GlobalUnlock (hGlobal); 417 418 /* 419 * Send a SelectionNotify event to the requesting 420 * client when we abort. 421 */ 422 if (fAbort) 423 { 424 /* Setup selection notify event */ 425 eventSelection.type = SelectionNotify; 426 eventSelection.send_event = True; 427 eventSelection.display = pDisplay; 428 eventSelection.requestor = event.xselectionrequest.requestor; 429 eventSelection.selection = event.xselectionrequest.selection; 430 eventSelection.target = event.xselectionrequest.target; 431 eventSelection.property = None; 432 eventSelection.time = event.xselectionrequest.time; 433 434 /* Notify the requesting window that the operation is complete */ 435 iReturn = XSendEvent (pDisplay, 436 eventSelection.requestor, 437 False, 438 0L, 439 (XEvent *) &eventSelection); 440 if (iReturn == BadValue || iReturn == BadWindow) 441 { 442 /* 443 * Should not be a problem if XSendEvent fails because 444 * the client may simply have exited. 445 */ 446 ErrorF ("winClipboardFlushXEvents - SelectionRequest - " 447 "XSendEvent () failed for abort event.\n"); 448 } 449 } 450 451 /* Close clipboard if it was opened */ 452 if (fCloseClipboard) 453 { 454 fCloseClipboard = FALSE; 455 CloseClipboard (); 456 } 457 break; 458 459 460 /* 461 * SelectionNotify 462 */ 463 464 case SelectionNotify: 465 466 winDebug ("winClipboardFlushXEvents - SelectionNotify\n"); 467 { 468 char *pszAtomName; 469 pszAtomName = XGetAtomName (pDisplay, 470 event.xselection.selection); 471 472 winDebug("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", 473 pszAtomName); 474 XFree (pszAtomName); 475 } 476 477 /* 478 * Request conversion of UTF8 and CompoundText targets. 479 */ 480 if (event.xselection.property == None) 481 { 482 if (event.xselection.target == XA_STRING) 483 { 484 winDebug ("winClipboardFlushXEvents - SelectionNotify - " 485 "XA_STRING\n"); 486 487 return WIN_XEVENTS_CONVERT; 488 } 489 else if (event.xselection.target == atomUTF8String) 490 { 491 winDebug("winClipboardFlushXEvents - SelectionNotify - " 492 "Requesting conversion of UTF8 target.\n"); 493 494 XConvertSelection (pDisplay, 495 event.xselection.selection, 496 XA_STRING, 497 atomLocalProperty, 498 iWindow, 499 CurrentTime); 500 501 /* Process the ConvertSelection event */ 502 XFlush (pDisplay); 503 return WIN_XEVENTS_CONVERT; 504 } 505#ifdef X_HAVE_UTF8_STRING 506 else if (event.xselection.target == atomCompoundText) 507 { 508 winDebug("winClipboardFlushXEvents - SelectionNotify - " 509 "Requesting conversion of CompoundText target.\n"); 510 511 XConvertSelection (pDisplay, 512 event.xselection.selection, 513 atomUTF8String, 514 atomLocalProperty, 515 iWindow, 516 CurrentTime); 517 518 /* Process the ConvertSelection event */ 519 XFlush (pDisplay); 520 return WIN_XEVENTS_CONVERT; 521 } 522#endif 523 else 524 { 525 ErrorF ("winClipboardFlushXEvents - SelectionNotify - " 526 "Unknown format. Cannot request conversion, " 527 "aborting.\n"); 528 break; 529 } 530 } 531 532 /* Retrieve the size of the stored data */ 533 iReturn = XGetWindowProperty (pDisplay, 534 iWindow, 535 atomLocalProperty, 536 0, 537 0, /* Don't get data, just size */ 538 False, 539 AnyPropertyType, 540 &xtpText.encoding, 541 &xtpText.format, 542 &xtpText.nitems, 543 &ulReturnBytesLeft, 544 &xtpText.value); 545 if (iReturn != Success) 546 { 547 ErrorF ("winClipboardFlushXEvents - SelectionNotify - " 548 "XGetWindowProperty () failed, aborting: %d\n", 549 iReturn); 550 break; 551 } 552 553 winDebug("SelectionNotify - returned data %d left %d\n", 554 xtpText.nitems, ulReturnBytesLeft); 555 556 /* Request the selection data */ 557 iReturn = XGetWindowProperty (pDisplay, 558 iWindow, 559 atomLocalProperty, 560 0, 561 ulReturnBytesLeft, 562 False, 563 AnyPropertyType, 564 &xtpText.encoding, 565 &xtpText.format, 566 &xtpText.nitems, 567 &ulReturnBytesLeft, 568 &xtpText.value); 569 if (iReturn != Success) 570 { 571 ErrorF ("winClipboardFlushXEvents - SelectionNotify - " 572 "XGetWindowProperty () failed, aborting: %d\n", 573 iReturn); 574 break; 575 } 576 577 { 578 char *pszAtomName = NULL; 579 580 winDebug("SelectionNotify - returned data %d left %d\n", 581 xtpText.nitems, ulReturnBytesLeft); 582 pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); 583 winDebug("Notify atom name %s\n", pszAtomName); 584 XFree (pszAtomName); 585 pszAtomName = NULL; 586 } 587 588 if (fUseUnicode) 589 { 590#ifdef X_HAVE_UTF8_STRING 591 /* Convert the text property to a text list */ 592 iReturn = Xutf8TextPropertyToTextList (pDisplay, 593 &xtpText, 594 &ppszTextList, 595 &iCount); 596#endif 597 } 598 else 599 { 600 iReturn = XmbTextPropertyToTextList (pDisplay, 601 &xtpText, 602 &ppszTextList, 603 &iCount); 604 } 605 if (iReturn == Success || iReturn > 0) 606 { 607 /* Conversion succeeded or some unconvertible characters */ 608 if (ppszTextList != NULL) 609 { 610 iReturnDataLen = 0; 611 for (i = 0; i < iCount; i++) 612 { 613 iReturnDataLen += strlen(ppszTextList[i]); 614 } 615 pszReturnData = malloc (iReturnDataLen + 1); 616 pszReturnData[0] = '\0'; 617 for (i = 0; i < iCount; i++) 618 { 619 strcat (pszReturnData, ppszTextList[i]); 620 } 621 } 622 else 623 { 624 ErrorF ("winClipboardFlushXEvents - SelectionNotify - " 625 "X*TextPropertyToTextList list_return is NULL.\n"); 626 pszReturnData = malloc (1); 627 pszReturnData[0] = '\0'; 628 } 629 } 630 else 631 { 632 ErrorF ("winClipboardFlushXEvents - SelectionNotify - " 633 "X*TextPropertyToTextList returned: "); 634 switch (iReturn) 635 { 636 case XNoMemory: 637 ErrorF ("XNoMemory\n"); 638 break; 639 case XConverterNotFound: 640 ErrorF ("XConverterNotFound\n"); 641 break; 642 default: 643 ErrorF ("%d", iReturn); 644 break; 645 } 646 pszReturnData = malloc (1); 647 pszReturnData[0] = '\0'; 648 } 649 650 /* Free the data returned from XGetWindowProperty */ 651 if (ppszTextList) 652 XFreeStringList (ppszTextList); 653 ppszTextList = NULL; 654 XFree (xtpText.value); 655 xtpText.value = NULL; 656 xtpText.nitems = 0; 657 658 /* Convert the X clipboard string to DOS format */ 659 winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); 660 661 if (fUseUnicode) 662 { 663 /* Find out how much space needed to convert MBCS to Unicode */ 664 iUnicodeLen = MultiByteToWideChar (CP_UTF8, 665 0, 666 pszReturnData, 667 -1, 668 NULL, 669 0); 670 671 /* Allocate memory for the Unicode string */ 672 pwszUnicodeStr 673 = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1)); 674 if (!pwszUnicodeStr) 675 { 676 ErrorF ("winClipboardFlushXEvents - SelectionNotify " 677 "malloc failed for pwszUnicodeStr, aborting.\n"); 678 679 /* Abort */ 680 fAbort = TRUE; 681 goto winClipboardFlushXEvents_SelectionNotify_Done; 682 } 683 684 /* Do the actual conversion */ 685 MultiByteToWideChar (CP_UTF8, 686 0, 687 pszReturnData, 688 -1, 689 pwszUnicodeStr, 690 iUnicodeLen); 691 692 /* Allocate global memory for the X clipboard data */ 693 hGlobal = GlobalAlloc (GMEM_MOVEABLE, 694 sizeof (wchar_t) * (iUnicodeLen + 1)); 695 } 696 else 697 { 698 pszConvertData = strdup (pszReturnData); 699 iConvertDataLen = strlen (pszConvertData) + 1; 700 701 /* Allocate global memory for the X clipboard data */ 702 hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen); 703 } 704 705 free (pszReturnData); 706 707 /* Check that global memory was allocated */ 708 if (!hGlobal) 709 { 710 ErrorF ("winClipboardFlushXEvents - SelectionNotify " 711 "GlobalAlloc failed, aborting: %ld\n", 712 GetLastError ()); 713 714 /* Abort */ 715 fAbort = TRUE; 716 goto winClipboardFlushXEvents_SelectionNotify_Done; 717 } 718 719 /* Obtain a pointer to the global memory */ 720 pszGlobalData = GlobalLock (hGlobal); 721 if (pszGlobalData == NULL) 722 { 723 ErrorF ("winClipboardFlushXEvents - Could not lock global " 724 "memory for clipboard transfer\n"); 725 726 /* Abort */ 727 fAbort = TRUE; 728 goto winClipboardFlushXEvents_SelectionNotify_Done; 729 } 730 731 /* Copy the returned string into the global memory */ 732 if (fUseUnicode) 733 { 734 memcpy (pszGlobalData, 735 pwszUnicodeStr, 736 sizeof (wchar_t) * (iUnicodeLen + 1)); 737 free (pwszUnicodeStr); 738 pwszUnicodeStr = NULL; 739 } 740 else 741 { 742 strcpy (pszGlobalData, pszConvertData); 743 free (pszConvertData); 744 pszConvertData = NULL; 745 } 746 747 /* Release the pointer to the global memory */ 748 GlobalUnlock (hGlobal); 749 pszGlobalData = NULL; 750 751 /* Push the selection data to the Windows clipboard */ 752 if (fUseUnicode) 753 SetClipboardData (CF_UNICODETEXT, hGlobal); 754 else 755 SetClipboardData (CF_TEXT, hGlobal); 756 757 /* Flag that SetClipboardData has been called */ 758 fSetClipboardData = FALSE; 759 760 /* 761 * NOTE: Do not try to free pszGlobalData, it is owned by 762 * Windows after the call to SetClipboardData (). 763 */ 764 765 winClipboardFlushXEvents_SelectionNotify_Done: 766 /* Free allocated resources */ 767 if (ppszTextList) 768 XFreeStringList (ppszTextList); 769 if (xtpText.value) 770 { 771 XFree (xtpText.value); 772 xtpText.value = NULL; 773 xtpText.nitems = 0; 774 } 775 free(pszConvertData); 776 free(pwszUnicodeStr); 777 if (hGlobal && pszGlobalData) 778 GlobalUnlock (hGlobal); 779 if (fSetClipboardData && g_fUnicodeSupport) 780 SetClipboardData (CF_UNICODETEXT, NULL); 781 if (fSetClipboardData) 782 SetClipboardData (CF_TEXT, NULL); 783 return WIN_XEVENTS_NOTIFY; 784 785 case SelectionClear: 786 winDebug("SelectionClear - doing nothing\n"); 787 break; 788 789 case PropertyNotify: 790 break; 791 792 case MappingNotify: 793 break; 794 795 default: 796 ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type); 797 break; 798 } 799 } 800 801 return WIN_XEVENTS_SUCCESS; 802} 803