Source code of Windows XP (NT5)
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.

305 lines
7.6 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: palette.cpp
  6. * Content: new DirectDraw object support
  7. * History:
  8. * Date By Reason
  9. * ==== == ======
  10. * 22-apr-97 jeffort initial implementation
  11. * 30-apr-97 jeffort critical section shared from ddrawex object
  12. * 27-may-97 jeffort keep ref count on internal object eual to outer object
  13. * 18-jun-97 jeffort linked list fix, we were using m_pNext instead of m_pNextPalette
  14. * 20-jun-97 jeffort added debug code to invaliudate objects when freed
  15. * 08-jul-97 jeffort switched order of releasing real palette interface BEFORE ddrawex release
  16. * due to the fact if ddraw is released before hand we will GP fault
  17. ***************************************************************************/
  18. #include "ddfactry.h"
  19. #define m_pDDPalette (m_DDPInt.m_pRealInterface)
  20. CDDPalette::CDDPalette( IDirectDrawPalette * pDDPalette,
  21. IUnknown *pUnkOuter,
  22. CDirectDrawEx *pDirectDrawEx) :
  23. m_cRef(1),
  24. m_pUnkOuter(pUnkOuter != 0 ? pUnkOuter : CAST_TO_IUNKNOWN(this)),
  25. m_pDirectDrawEx(pDirectDrawEx)
  26. {
  27. m_DDPInt.m_pSimplePalette = this;
  28. m_pDDPalette = pDDPalette;
  29. m_pFirstSurface = NULL;
  30. InitDirectDrawPaletteInterfaces( pDDPalette, &m_DDPInt);
  31. pDirectDrawEx->AddRef();
  32. pDirectDrawEx->AddPaletteToList(this);
  33. DllAddRef();
  34. }
  35. CDDPalette::~CDDPalette()
  36. {
  37. /*
  38. * clean up...
  39. */
  40. //we must mark any surfaces in our list as having no palette
  41. //we are running this list, must bracket by critical section
  42. CDDSurface *pSurface = m_pFirstSurface;
  43. ENTER_DDEX();
  44. while (pSurface != NULL)
  45. {
  46. pSurface->m_pCurrentPalette = NULL;
  47. pSurface = pSurface->m_pNextPalette;
  48. }
  49. //if this is the primary surface, go down the primary list and mark the current palette as null
  50. if (m_bIsPrimary)
  51. {
  52. CDDSurface *pSurface = m_pDirectDrawEx->m_pPrimaryPaletteList;
  53. while (pSurface != NULL)
  54. {
  55. pSurface->m_pCurrentPalette = NULL;
  56. pSurface = pSurface->m_pNextPalette;
  57. }
  58. }
  59. LEAVE_DDEX();
  60. m_pDirectDrawEx->RemovePaletteFromList(this);
  61. m_pDDPalette->Release();
  62. m_pDirectDrawEx->Release();
  63. DllRelease();
  64. #ifdef DEBUG
  65. DWORD * ptr;
  66. ptr = (DWORD *)this;
  67. for (int i = 0; i < sizeof(CDDPalette) / sizeof(DWORD);i++)
  68. *ptr++ = 0xDEADBEEF;
  69. #endif
  70. } /* CDDSurface::~CDDSurface */
  71. /*
  72. * CDirectDrawEx::AddSurfaceToList
  73. *
  74. * Adds a surface to our doubly-linked list of surfaces conatining this palette
  75. */
  76. void CDDPalette::AddSurfaceToList(CDDSurface *pSurface)
  77. {
  78. ENTER_DDEX();
  79. if( m_pFirstSurface )
  80. {
  81. m_pFirstSurface->m_pPrevPalette = pSurface;
  82. }
  83. pSurface->m_pPrevPalette = NULL;
  84. pSurface->m_pNextPalette = m_pFirstSurface;
  85. m_pFirstSurface = pSurface;
  86. LEAVE_DDEX();
  87. }
  88. /*
  89. * CDirectDrawEx::RemoveSurfaceFromList
  90. *
  91. * Removes a surface from our doubly-linked surface list
  92. */
  93. void CDDPalette::RemoveSurfaceFromList(CDDSurface *pSurface)
  94. {
  95. ENTER_DDEX();
  96. if( pSurface->m_pPrevPalette )
  97. {
  98. pSurface->m_pPrevPalette->m_pNextPalette = pSurface->m_pNextPalette;
  99. }
  100. else
  101. {
  102. m_pFirstSurface = pSurface->m_pNextPalette;
  103. }
  104. if( pSurface->m_pNextPalette )
  105. {
  106. pSurface->m_pNextPalette->m_pPrevPalette = pSurface->m_pPrevPalette;
  107. }
  108. LEAVE_DDEX();
  109. }
  110. HRESULT CDDPalette::CreateSimplePalette(LPPALETTEENTRY pEntries,
  111. IDirectDrawPalette *pDDPalette,
  112. LPDIRECTDRAWPALETTE FAR * ppPal,
  113. IUnknown FAR * pUnkOuter,
  114. CDirectDrawEx *pDirectDrawEx)
  115. {
  116. HRESULT hr = DD_OK;
  117. CDDPalette *pPalette = new CDDPalette(pDDPalette,
  118. pUnkOuter,
  119. pDirectDrawEx);
  120. if( !pPalette)
  121. {
  122. return E_OUTOFMEMORY;
  123. }
  124. else
  125. {
  126. pPalette->NonDelegatingQueryInterface(pUnkOuter ? IID_IUnknown : IID_IDirectDrawPalette, (void **)ppPal);
  127. pPalette->NonDelegatingRelease();
  128. }
  129. return hr;
  130. }
  131. HRESULT CDDPalette::SetColorTable (CDDSurface * pSurface, LPPALETTEENTRY pEntries, DWORD dwNumEntries, DWORD dwBase)
  132. {
  133. //cal SetDIBColorTable here
  134. RGBQUAD rgbq[256];
  135. HDC hdc;
  136. HRESULT hr;
  137. hr = DD_OK;
  138. if (pSurface->m_bOwnDC)
  139. {
  140. if( pSurface->m_hDCDib )
  141. {
  142. hdc = pSurface->m_hDCDib;
  143. }
  144. else if( pSurface->m_bOwnDC )
  145. {
  146. hdc = pSurface->m_HDC;
  147. }
  148. else
  149. {
  150. return DD_OK;
  151. }
  152. // we need to copy the entries here for
  153. // a logical palette
  154. // we need to ues the struct as a LogPal struct
  155. for( int i=0;i<(int) dwNumEntries;i++ )
  156. {
  157. rgbq[i].rgbBlue = pEntries[i].peBlue;
  158. rgbq[i].rgbGreen = pEntries[i].peGreen;
  159. rgbq[i].rgbRed = pEntries[i].peRed;
  160. rgbq[i].rgbReserved = 0;
  161. }
  162. SetDIBColorTable(hdc, dwBase, dwNumEntries, rgbq);
  163. }
  164. return hr;
  165. }
  166. STDMETHODIMP CDDPalette::InternalSetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpe)
  167. {
  168. HRESULT hr;
  169. CDDSurface *pSurfaceList;
  170. hr = m_pDDPalette->SetEntries(dwFlags, dwBase, dwNumEntries, lpe);
  171. //now we need to traverse the list of Surfaces and if OWNDC is set, set the DibSection ColorTable
  172. if (m_bIsPrimary)
  173. pSurfaceList = m_pDirectDrawEx->m_pPrimaryPaletteList;
  174. else
  175. pSurfaceList = m_pFirstSurface;
  176. while (pSurfaceList != NULL)
  177. {
  178. SetColorTable(pSurfaceList, lpe, dwNumEntries, dwBase);
  179. pSurfaceList = pSurfaceList->m_pNextPalette;
  180. }
  181. return hr;
  182. }
  183. STDMETHODIMP CDDPalette::QueryInterface(REFIID riid, void ** ppv)
  184. {
  185. return m_pUnkOuter->QueryInterface(riid, ppv);
  186. } /* CDirectDrawEx::QueryInterface */
  187. STDMETHODIMP_(ULONG) CDDPalette::AddRef(void)
  188. {
  189. return m_pUnkOuter->AddRef();
  190. } /* CDirectDrawEx::AddRef */
  191. STDMETHODIMP_(ULONG) CDDPalette::Release(void)
  192. {
  193. return m_pUnkOuter->Release();
  194. } /* CDirectDrawEx::Release */
  195. /*
  196. * NonDelegating IUnknown for simple surface follows...
  197. */
  198. STDMETHODIMP CDDPalette::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
  199. {
  200. // HRESULT hr;
  201. *ppv=NULL;
  202. if( IID_IUnknown==riid )
  203. {
  204. *ppv=(INonDelegatingUnknown *)this;
  205. }
  206. else if( IID_IDirectDrawPalette==riid )
  207. {
  208. *ppv=&m_DDPInt;
  209. }
  210. else
  211. {
  212. return E_NOINTERFACE;
  213. }
  214. ((LPUNKNOWN)*ppv)->AddRef();
  215. return NOERROR;
  216. }
  217. STDMETHODIMP_(ULONG) CDDPalette::NonDelegatingAddRef()
  218. {
  219. //addref the internal palette interface
  220. m_pDDPalette->AddRef();
  221. return InterlockedIncrement(&m_cRef);
  222. }
  223. STDMETHODIMP_(ULONG) CDDPalette::NonDelegatingRelease()
  224. {
  225. LONG lRefCount = InterlockedDecrement(&m_cRef);
  226. if (lRefCount) {
  227. //we need to release the internal interface as well
  228. m_pDDPalette->Release();
  229. return lRefCount;
  230. }
  231. delete this;
  232. return 0;
  233. }
  234. /*
  235. * Quick inline fns to get at our internal data...
  236. */
  237. _inline CDDPalette * PALETTEOF(IDirectDrawPalette * pDDP)
  238. {
  239. return ((INTSTRUC_IDirectDrawPalette *)pDDP)->m_pSimplePalette;
  240. }
  241. STDMETHODIMP_(ULONG) IDirectDrawPaletteAggAddRef(IDirectDrawPalette *pDDP)
  242. {
  243. return PALETTEOF(pDDP)->m_pUnkOuter->AddRef();
  244. }
  245. STDMETHODIMP_(ULONG) IDirectDrawPaletteAggRelease(IDirectDrawPalette *pDDP)
  246. {
  247. return PALETTEOF(pDDP)->m_pUnkOuter->Release();
  248. }
  249. STDMETHODIMP IDirectDrawPaletteAggSetEntries(IDirectDrawPalette *pDDP, DWORD dw1, DWORD dw2, DWORD dw3, LPPALETTEENTRY lpe)
  250. {
  251. return PALETTEOF(pDDP)->InternalSetEntries(dw1, dw2, dw3, lpe);
  252. }