Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
3.5 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "clipboardmanager.h"
  7. #include "datamodel.h"
  8. #include "tier1/KeyValues.h"
  9. #ifndef POSIX
  10. #define USE_WINDOWS_CLIPBOARD
  11. #endif
  12. #if defined( USE_WINDOWS_CLIPBOARD )
  13. #include <windows.h>
  14. #endif
  15. CClipboardManager::CClipboardManager( ) :
  16. m_pfnCleanup( NULL )
  17. {
  18. }
  19. CClipboardManager::~CClipboardManager()
  20. {
  21. EmptyClipboard( false );
  22. }
  23. void CClipboardManager::EmptyClipboard( bool bClearWindowsClipboard )
  24. {
  25. // Call optional cleanup function if there is one...
  26. if ( m_pfnCleanup )
  27. {
  28. m_pfnCleanup->ReleaseClipboardData( m_Data );
  29. }
  30. int c = m_Data.Count();
  31. for ( int i = 0; i < c; ++i )
  32. {
  33. m_Data[ i ]->deleteThis();
  34. }
  35. m_Data.RemoveAll();
  36. m_pfnCleanup = NULL;
  37. #if defined( USE_WINDOWS_CLIPBOARD )
  38. if ( bClearWindowsClipboard )
  39. {
  40. if ( ::OpenClipboard( ::GetDesktopWindow() ) )
  41. {
  42. ::EmptyClipboard();
  43. ::CloseClipboard();
  44. }
  45. }
  46. #endif
  47. }
  48. void CClipboardManager::SetClipboardData( CUtlVector< KeyValues * >& data, IClipboardCleanup *pfnOptionalCleanuFunction )
  49. {
  50. EmptyClipboard( true );
  51. m_Data = data;
  52. m_pfnCleanup = pfnOptionalCleanuFunction;
  53. #if defined( USE_WINDOWS_CLIPBOARD )
  54. if ( m_Data.Count() > 0 )
  55. {
  56. // Only stick the first item's data into the clipboard
  57. char const *text = m_Data[ 0 ]->GetString( "text", "" );
  58. if ( text && text[ 0 ] )
  59. {
  60. int textLen = Q_strlen( text );
  61. if ( ::OpenClipboard( ::GetDesktopWindow() ) )
  62. {
  63. HANDLE hmem = ::GlobalAlloc(GMEM_MOVEABLE, textLen + 1);
  64. if (hmem)
  65. {
  66. void *ptr = ::GlobalLock( hmem );
  67. if ( ptr )
  68. {
  69. Q_memset( ptr, 0, textLen + 1 );
  70. Q_memcpy( ptr, text, textLen );
  71. ::GlobalUnlock( hmem );
  72. ::SetClipboardData( CF_TEXT, hmem );
  73. }
  74. }
  75. ::CloseClipboard();
  76. }
  77. }
  78. }
  79. #endif
  80. }
  81. void CClipboardManager::AddToClipboardData( KeyValues *add )
  82. {
  83. m_Data.AddToTail( add );
  84. #if defined( USE_WINDOWS_CLIPBOARD )
  85. if ( m_Data.Count() >= 0 )
  86. {
  87. // Only stick the first item's data into the clipboard
  88. char const *text = m_Data[ 0 ]->GetString( "text", "" );
  89. if ( text && text[ 0 ] )
  90. {
  91. int textLen = Q_strlen( text );
  92. if ( ::OpenClipboard( ::GetDesktopWindow() ) )
  93. {
  94. ::EmptyClipboard();
  95. HANDLE hmem = ::GlobalAlloc(GMEM_MOVEABLE, textLen + 1);
  96. if (hmem)
  97. {
  98. void *ptr = ::GlobalLock( hmem );
  99. if ( ptr )
  100. {
  101. Q_memset( ptr, 0, textLen + 1 );
  102. Q_memcpy( ptr, text, textLen );
  103. ::GlobalUnlock( hmem );
  104. ::SetClipboardData( CF_TEXT, hmem );
  105. }
  106. }
  107. ::CloseClipboard();
  108. }
  109. }
  110. }
  111. #endif
  112. }
  113. void CClipboardManager::GetClipboardData( CUtlVector< KeyValues * >& data )
  114. {
  115. data.RemoveAll();
  116. data = m_Data;
  117. #if defined( USE_WINDOWS_CLIPBOARD )
  118. if ( data.Count() == 0 )
  119. {
  120. // See if windows has some text since we didn't have any internally
  121. if ( ::OpenClipboard( ::GetDesktopWindow() ) )
  122. {
  123. HANDLE hmem = ::GetClipboardData( CF_TEXT );
  124. if ( hmem )
  125. {
  126. int len = GlobalSize( hmem );
  127. if ( len > 0 )
  128. {
  129. void *ptr = GlobalLock(hmem);
  130. if ( ptr )
  131. {
  132. char buf[ 8192 ];
  133. len = min( len, 8191 );
  134. Q_memcpy( buf, ( char * )ptr, len );
  135. buf[ 8191 ] = 0;
  136. GlobalUnlock(hmem);
  137. KeyValues *newData = new KeyValues( "ClipBoard", "text", buf );
  138. data.AddToTail( newData );
  139. }
  140. }
  141. }
  142. ::CloseClipboard();
  143. }
  144. }
  145. #endif
  146. }
  147. bool CClipboardManager::HasClipboardData() const
  148. {
  149. return m_Data.Count() > 0 ? true : false;
  150. }