overlay_gdi.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:8k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: overlay_gdi.c 543 2006-01-07 22:06:24Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #ifdef _WIN32
  25. //#define BLITTEST
  26. #define WIN32_LEAN_AND_MEAN
  27. #ifndef STRICT
  28. #define STRICT
  29. #endif
  30. #include <windows.h>
  31. typedef struct gdi
  32. {
  33. overlay p;
  34. int DIBSection;
  35. HBITMAP Bitmap;
  36. HGDIOBJ Bitmap0; //bitmap returned by selectobject
  37. HDC DC2;
  38. video Overlay;
  39. rect OverlayRect;
  40. planes Planes;
  41. #ifdef BLITTEST
  42. void* Soft2;
  43. planes Planes2;
  44. #endif
  45. } gdi;
  46. static int AllocBitmap(gdi* p)
  47. {
  48. #ifndef BLITTEST
  49. int OldFlags = p->Overlay.Pixel.Flags;
  50. #endif
  51. p->p.Dirty = 1;
  52. if (p->DIBSection)
  53. {
  54. int i;
  55. struct 
  56. {
  57. BITMAPINFOHEADER Head;
  58. int BitMask[3];
  59. } Info;
  60. HDC DC = GetDC(NULL);
  61. memset(&Info,0,sizeof(Info));
  62. Info.Head.biSize = sizeof(Info.Head);
  63. Info.Head.biWidth = p->Overlay.Width;
  64. Info.Head.biHeight = -p->Overlay.Height;
  65. Info.Head.biPlanes = 1;
  66. Info.Head.biBitCount = (WORD)p->Overlay.Pixel.BitCount;
  67. Info.Head.biCompression = (p->Overlay.Pixel.BitCount==16 || p->Overlay.Pixel.BitCount==32) ? BI_BITFIELDS:BI_RGB;
  68. Info.Head.biSizeImage = (p->Overlay.Width * p->Overlay.Height * p->Overlay.Pixel.BitCount) >> 3;
  69. for (i=0;i<3;++i)
  70. Info.BitMask[i] = p->Overlay.Pixel.BitMask[i];
  71. p->Bitmap = CreateDIBSection(DC,(BITMAPINFO*)&Info,DIB_RGB_COLORS,&p->Planes[0],NULL,0);
  72. if (p->Bitmap)
  73. p->Bitmap0 = SelectObject(p->DC2,p->Bitmap);
  74. ReleaseDC(NULL,DC);
  75. }
  76. else
  77. p->Planes[0] = Alloc16(p->Overlay.Pitch * p->Overlay.Height);
  78. if (((uintptr_t)p->Planes[0] & 15) || (p->Overlay.Pitch & 15))
  79. p->Overlay.Pixel.Flags &= ~PF_16ALIGNED;
  80. else
  81. p->Overlay.Pixel.Flags |= PF_16ALIGNED;
  82. #ifndef BLITTEST
  83. if (OldFlags != p->Overlay.Pixel.Flags)
  84. {
  85. BlitRelease(p->p.Soft);
  86. p->p.Soft = BlitCreate(&p->Overlay,&p->p.Input.Format.Video,&p->p.FX,&p->p.Caps);
  87. BlitAlign(p->p.Soft, &p->OverlayRect, &p->p.SrcAlignedRect);
  88. }
  89. #endif
  90. return p->Planes[0] != NULL;
  91. }
  92. static void FreeBitmap(gdi* p)
  93. {
  94. if (p->Bitmap) 
  95. SelectObject(p->DC2,p->Bitmap0);
  96. DeleteObject(p->Bitmap); 
  97. p->Bitmap = 0;
  98. }
  99. if (p->Planes[0])
  100. {
  101. if (!p->DIBSection)
  102. Free16(p->Planes[0]);
  103. p->Planes[0] = NULL;
  104. }
  105. }
  106. static void Done(gdi* p)
  107. {
  108. FreeBitmap(p);
  109. if (p->DC2) 
  110. {
  111. DeleteDC(p->DC2); 
  112. p->DC2 = 0;
  113. }
  114. #ifdef BLITTEST
  115. SurfaceFree(p->Planes2);
  116. BlitRelease(p->Soft2);
  117. p->Soft2 = NULL;
  118. #endif
  119. }
  120. static int Init(gdi* p)
  121. {
  122. HDC DC;
  123. QueryDesktop(&p->p.Output.Format.Video);
  124. p->Planes[0] = NULL;
  125. p->Overlay.Width = 0;
  126. p->Overlay.Height = 0;
  127. p->Overlay.Direction = 0;
  128. p->Overlay.Aspect = ASPECT_ONE;
  129. p->Overlay.Pixel = p->p.Output.Format.Video.Pixel;
  130. if (p->Overlay.Pixel.BitCount==24) 
  131. DefaultRGB(&p->Overlay.Pixel,24,8,8,8,0,0,0); //BI_BITFIELDS not supported for 24bpp
  132. p->Overlay.Pixel.Flags |= PF_16ALIGNED; // assume it will be aligned
  133. p->DIBSection = (p->Overlay.Pixel.Flags & PF_RGB) != 0;
  134. p->Bitmap = 0;
  135. p->Bitmap0 = 0;
  136. DC = GetDC(NULL);
  137. p->DC2 = CreateCompatibleDC(DC);
  138. ReleaseDC(NULL,DC);
  139. p->p.ClearFX = BLITFX_ONLYDIFF;
  140. return ERR_NONE;
  141. }
  142. static int Reset(gdi* p)
  143. {
  144. Done(p);
  145. Init(p);
  146. return ERR_NONE;
  147. }
  148. static int Update(gdi* p)
  149. {
  150. rect OldGUI = p->p.GUIAlignedRect;
  151. rect Old = p->p.DstAlignedRect;
  152. int OldWidth = p->Overlay.Width;
  153. int OldHeight = p->Overlay.Height;
  154. VirtToPhy(&p->p.Viewport,&p->p.DstAlignedRect,&p->p.Output.Format.Video);
  155. VirtToPhy(NULL,&p->p.SrcAlignedRect,&p->p.Input.Format.Video);
  156. AnyAlign(&p->p.DstAlignedRect, &p->p.SrcAlignedRect, &p->p.FX, 2, 2, 1, SCALE_ONE*1024 ); 
  157. PhyToVirt(&p->p.DstAlignedRect,&p->p.GUIAlignedRect,&p->p.Output.Format.Video);
  158. p->Overlay.Width = ALIGN16(p->p.GUIAlignedRect.Width); // we need PF_16ALIGNED for pitch
  159. p->Overlay.Height = p->p.GUIAlignedRect.Height;
  160. p->Overlay.Pitch = (p->Overlay.Width * p->Overlay.Pixel.BitCount) >> 3;
  161. p->Overlay.Pitch = (p->Overlay.Pitch+1) & ~1; //word aligned (it doesn't mater anymore, Width is aligned)
  162. p->OverlayRect.x = p->OverlayRect.y = 0;
  163. p->OverlayRect.Width = p->p.GUIAlignedRect.Width;
  164. p->OverlayRect.Height = p->p.GUIAlignedRect.Height;
  165. #ifdef BLITTEST
  166. {
  167. rect TestAlignedRect = p->OverlayRect;
  168. packetformat TestFormat = {0};
  169. TestFormat.Type = PACKET_VIDEO;
  170. TestFormat.Format.Video = p->Overlay;
  171. TestFormat.Format.Video.Pixel.Flags &= (PF_PALETTE|PF_RGB);
  172. //TestFormat.Format.Video.Pixel.Flags |= PF_FOURCC;
  173. //TestFormat.Format.Video.Pixel.FourCC = FOURCC_Y422;
  174. //PacketFormatDefault(&TestFormat);
  175. DefaultRGB(&TestFormat.Format.Video.Pixel,32,8,8,8,0,0,0);
  176. DefaultPitch(&TestFormat.Format.Video);
  177. SurfaceFree(p->Planes2);
  178. SurfaceAlloc(p->Planes2,&TestFormat.Format.Video);
  179. BlitRelease(p->Soft2);
  180. p->Soft2 = BlitCreate(&TestFormat.Format.Video,&p->p.Input.Format.Video,&p->p.FX,&p->p.Caps);
  181. BlitAlign(p->Soft2,&TestAlignedRect, &p->p.SrcAlignedRect);
  182. BlitRelease(p->p.Soft);
  183. p->p.Soft = BlitCreate(&p->Overlay,&TestFormat.Format.Video,NULL,NULL);
  184. BlitAlign(p->p.Soft,&p->OverlayRect, &TestAlignedRect);
  185. }
  186. #else
  187. BlitRelease(p->p.Soft);
  188. p->p.Soft = BlitCreate(&p->Overlay,&p->p.Input.Format.Video,&p->p.FX,&p->p.Caps);
  189. BlitAlign(p->p.Soft, &p->OverlayRect, &p->p.SrcAlignedRect);
  190. #endif
  191. p->p.GUIAlignedRect.x += p->OverlayRect.x;
  192. p->p.GUIAlignedRect.y += p->OverlayRect.y;
  193. p->p.GUIAlignedRect.Width = p->OverlayRect.Width;
  194. p->p.GUIAlignedRect.Height = p->OverlayRect.Height;
  195. VirtToPhy(&p->p.GUIAlignedRect,&p->p.DstAlignedRect,&p->p.Output.Format.Video);
  196. if (OldWidth != p->Overlay.Width || OldHeight != p->Overlay.Height)
  197. FreeBitmap(p);
  198. if (p->p.Show && !EqRect(&Old,&p->p.DstAlignedRect))
  199. {
  200. WinInvalidate(&OldGUI,0);
  201. WinInvalidate(&p->p.Viewport,1);
  202. WinValidate(&p->p.GUIAlignedRect);
  203. }
  204. return ERR_NONE;
  205. }
  206. static int Blit(gdi* p, const constplanes Data, const constplanes DataLast )
  207. {
  208. HDC DC;
  209. if (!p->Planes[0] && !AllocBitmap(p))
  210. return ERR_OUT_OF_MEMORY;
  211. #ifdef BLITTEST
  212. BlitImage(p->Soft2,p->Planes2,Data,DataLast,-1,-1);
  213. BlitImage(p->p.Soft,p->Planes,p->Planes2,NULL,-1,-1);
  214. #else
  215. BlitImage(p->p.Soft,p->Planes,Data,DataLast,-1,-1);
  216. #endif
  217. if (!p->DIBSection)
  218. {
  219. if (p->Bitmap)
  220. {
  221. SelectObject(p->DC2,p->Bitmap0);
  222. DeleteObject(p->Bitmap);
  223. }
  224. p->Bitmap = CreateBitmap( p->Overlay.Width, p->Overlay.Height, 1, 
  225. p->Overlay.Pixel.BitCount, (char*)p->Planes[0]);
  226. if (!p->Bitmap)
  227. return ERR_OUT_OF_MEMORY;
  228. p->Bitmap0 = SelectObject(p->DC2,p->Bitmap);
  229. }
  230. DC = GetDC(NULL);
  231. BitBlt(DC,p->p.GUIAlignedRect.x,p->p.GUIAlignedRect.y,
  232.    p->OverlayRect.Width,p->OverlayRect.Height,p->DC2,p->OverlayRect.x,p->OverlayRect.y,SRCCOPY);
  233. ReleaseDC(NULL,DC);
  234. return ERR_NONE;
  235. }
  236. static int Create(gdi* p)
  237. {
  238. p->p.Init = Init;
  239. p->p.Done = Done;
  240. p->p.Blit = Blit;
  241. p->p.Update = Update;
  242. p->p.Reset = Reset;
  243. return ERR_NONE;
  244. }
  245. static const nodedef GDI = 
  246. {
  247. sizeof(gdi)|CF_GLOBAL,
  248. GDI_ID,
  249. OVERLAY_CLASS,
  250. PRI_DEFAULT,
  251. (nodecreate)Create,
  252. };
  253. void OverlayGDI_Init() 
  254. NodeRegisterClass(&GDI);
  255. }
  256. void OverlayGDI_Done() 
  257. NodeUnRegisterClass(GDI_ID);
  258. }
  259. #endif