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

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_gapi.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 TARGET_WINCE
  25. #define WIN32_LEAN_AND_MEAN
  26. #ifndef STRICT
  27. #define STRICT
  28. #endif
  29. #include <windows.h>
  30. typedef struct GXDisplayProperties 
  31. {
  32. int cxWidth;
  33. int cyHeight;
  34. int cbxPitch;
  35. int cbyPitch;
  36. int cBPP;
  37. int ffFormat;
  38. } GXDisplayProperties;
  39. #define SHFS_SHOWTASKBAR            0x0001
  40. #define SHFS_HIDETASKBAR            0x0002
  41. #define SHFS_SHOWSIPBUTTON          0x0004
  42. #define SHFS_HIDESIPBUTTON          0x0008
  43. #define SHFS_SHOWSTARTICON          0x0010
  44. #define SHFS_HIDESTARTICON          0x0020
  45. #define GX_FULLSCREEN 0x01
  46. #define kfLandscape 0x08
  47. #define kfPalette 0x10
  48. #define kfDirect 0x20
  49. #define kfDirect555 0x40
  50. #define kfDirect565 0x80
  51. #define kfDirect888 0x100
  52. #define kfDirect444 0x200
  53. #define kfDirectInverted 0x400
  54. typedef struct gapi
  55. {
  56. overlay Overlay;
  57. bool_t Windows;
  58. bool_t Opened;
  59. bool_t DRAM;
  60. void* Wnd;
  61. int AdjustPtr;
  62. uint8_t* DirectPtr;
  63. uint8_t* Pointer;
  64. HMODULE GX;
  65. HMODULE AygShell;
  66. GXDisplayProperties Info;
  67. int (*GXOpenDisplay)(HWND hWnd, DWORD dwFlags);
  68. int (*GXCloseDisplay)();
  69. void* (*GXBeginDraw)();
  70. int (*GXEndDraw)();
  71. GXDisplayProperties (*GXGetDisplayProperties)();
  72. int (*GXSetViewport)(DWORD dwTop, DWORD dwHeight, DWORD, DWORD);
  73. BOOL (*GXIsDisplayDRAMBuffer)();
  74. BOOL (WINAPI* SHFullScreen)(HWND, DWORD);
  75. } gapi;
  76. static const datatable Params[] = 
  77. {
  78. { GAPI_WIDTH, TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
  79. { GAPI_HEIGHT, TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
  80. { GAPI_PITCHX, TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
  81. { GAPI_PITCHY, TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
  82. { GAPI_BPP, TYPE_INT, DF_SETUP | DF_RDONLY | DF_HIDDEN },
  83. { GAPI_FORMAT, TYPE_INT, DF_SETUP | DF_RDONLY|DF_HEX | DF_HIDDEN },
  84. { GAPI_DRAM, TYPE_BOOL, DF_SETUP | DF_RDONLY | DF_HIDDEN },
  85. { GAPI_POINTER, TYPE_INT, DF_SETUP | DF_RDONLY|DF_HEX | DF_HIDDEN },
  86. DATATABLE_END(GAPI_ID)
  87. };
  88. static int Enum(gapi* p, int* No, datadef* Param)
  89. {
  90. if (OverlayEnum(&p->Overlay,No,Param)==ERR_NONE)
  91. return ERR_NONE;
  92. return NodeEnumTable(No,Param,Params);
  93. }
  94. static int Get(gapi* p,int No,void* Data,int Size)
  95. {
  96. int Result = OverlayGet(&p->Overlay,No,Data,Size);
  97. switch (No)
  98. {
  99. case GAPI_WIDTH: GETVALUE(p->Info.cxWidth,int); break;
  100. case GAPI_HEIGHT: GETVALUE(p->Info.cyHeight,int); break;
  101. case GAPI_PITCHX: GETVALUE(p->Info.cbxPitch,int); break;
  102. case GAPI_PITCHY: GETVALUE(p->Info.cbyPitch,int); break;
  103. case GAPI_BPP: GETVALUE(p->Info.cBPP,int); break;
  104. case GAPI_FORMAT: GETVALUE(p->Info.ffFormat,int); break;
  105. case GAPI_DRAM: GETVALUE(p->DRAM,bool_t); break;
  106. case GAPI_POINTER: GETVALUE((int)p->Pointer,int); break;
  107. }
  108. return Result;
  109. }
  110. static bool_t LoadDriver(gapi* p)
  111. {
  112. HMODULE GX;
  113. tchar_t Path[MAXPATH];
  114. if (p->Windows)
  115. GetSystemPath(Path,TSIZEOF(Path),T("gx.dll"));
  116. else
  117. tcscpy_s(Path,TSIZEOF(Path),T("gx.dll"));
  118. if ((GX = LoadLibrary(Path))==NULL)
  119. {
  120. if (!p->Windows)
  121. {
  122. p->Windows = 1;
  123. return LoadDriver(p);
  124. }
  125. return 0;
  126. }
  127. if (p->GX)
  128. FreeLibrary(p->GX);
  129. p->GX = GX;
  130. GetProc(&p->GX,&p->GXOpenDisplay,T("?GXOpenDisplay@@YAHPAUHWND__@@K@Z"),0);
  131. GetProc(&p->GX,&p->GXCloseDisplay,T("?GXCloseDisplay@@YAHXZ"),0);
  132. GetProc(&p->GX,&p->GXBeginDraw,T("?GXBeginDraw@@YAPAXXZ"),0);
  133. GetProc(&p->GX,&p->GXEndDraw,T("?GXEndDraw@@YAHXZ"),0);
  134. GetProc(&p->GX,&p->GXGetDisplayProperties,T("?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ"),0);
  135. GetProc(&p->GX,&p->GXSetViewport,T("?GXSetViewport@@YAHKKKK@Z"),1);
  136. GetProc(&p->GX,&p->GXIsDisplayDRAMBuffer,T("?GXIsDisplayDRAMBuffer@@YAHXZ"),1);
  137. return p->GX!=NULL;
  138. }
  139. static int Init(gapi* p)
  140. {
  141. GXDisplayProperties Info;
  142. video GDI;
  143. int Caps = QueryPlatform(PLATFORM_CAPS);
  144. if (!p->Opened)
  145. {
  146. ShowError(p->Overlay.Node.Class,GAPI_ID,GAPI_OPEN_ERROR);
  147. return ERR_NOT_SUPPORTED; // don't show device error
  148. }
  149. Info = p->Info;
  150. if (Info.cxWidth == GetSystemMetrics(SM_CXSCREEN) &&
  151. Info.cyHeight < GetSystemMetrics(SM_CYSCREEN))
  152. {
  153. // HPC devices we need the taskbar counted in the height too
  154. RECT WorkArea;
  155. SystemParametersInfo(SPI_GETWORKAREA,0,&WorkArea,0);
  156. if (WorkArea.top == 0 && WorkArea.bottom == Info.cyHeight)
  157. Info.cyHeight = GetSystemMetrics(SM_CYSCREEN);
  158. }
  159. p->Overlay.Output.Format.Video.Direction = 0;
  160. p->Overlay.Output.Format.Video.Aspect = ASPECT_ONE;
  161. if (Info.ffFormat & kfPalette)
  162. {
  163. QueryDesktop(&GDI);
  164. p->Overlay.Output.Format.Video.Pixel.Flags = PF_PALETTE;
  165. p->Overlay.Output.Format.Video.Pixel.BitCount = Info.cBPP;
  166. p->Overlay.Output.Format.Video.Pixel.Palette = GDI.Pixel.Palette;
  167. }
  168. else
  169. if (Info.ffFormat & kfDirect444)
  170. DefaultRGB(&p->Overlay.Output.Format.Video.Pixel,Info.cBPP,4,4,4,0,0,0);
  171. else
  172. if (Info.ffFormat & kfDirect565)
  173. {
  174. if (Caps & CAPS_ONLY12BITRGB)
  175. DefaultRGB(&p->Overlay.Output.Format.Video.Pixel,Info.cBPP,4,4,4,1,2,1);
  176. else
  177. DefaultRGB(&p->Overlay.Output.Format.Video.Pixel,Info.cBPP,5,6,5,0,0,0);
  178. }
  179. else
  180. if (Info.ffFormat & kfDirect555)
  181. DefaultRGB(&p->Overlay.Output.Format.Video.Pixel,Info.cBPP,5,5,5,0,0,0);
  182. else
  183. if (Info.ffFormat & kfDirect888)
  184. DefaultRGB(&p->Overlay.Output.Format.Video.Pixel,Info.cBPP,8,8,8,0,0,0);
  185. if (Info.ffFormat & kfDirectInverted)
  186. p->Overlay.Output.Format.Video.Pixel.Flags |= PF_INVERTED;
  187. // get signed x/y pitches in bits
  188. Info.cbxPitch <<= 3;
  189. Info.cbyPitch <<= 3;
  190. // one pitch is probably zero when BPP<8
  191. if (!Info.cbxPitch) 
  192. if (Info.cbyPitch < 0)
  193. Info.cbxPitch = -Info.cBPP;
  194. else
  195. Info.cbxPitch = Info.cBPP;
  196. else
  197. if (!Info.cbyPitch)
  198. if (Info.cbxPitch < 0)
  199. Info.cbyPitch = Info.cBPP;
  200. else
  201. Info.cbyPitch = -Info.cBPP;
  202. // one of the pitches absolute value must be BPP
  203. if (abs(Info.cbyPitch) < abs(Info.cbxPitch))
  204. {
  205. if (abs(Info.cbxPitch) < Info.cyHeight*Info.cBPP &&
  206. abs(Info.cbxPitch) >= Info.cxWidth*Info.cBPP) //swapped gapi resolution
  207. SwapInt(&Info.cxWidth,&Info.cyHeight);
  208. Info.ffFormat |= kfLandscape;
  209. Info.cbyPitch = Info.cbyPitch<0 ? -Info.cBPP : Info.cBPP;
  210. }
  211. else
  212. {
  213. if (abs(Info.cbyPitch) < Info.cxWidth*Info.cBPP &&
  214. abs(Info.cbyPitch) >= Info.cyHeight*Info.cBPP) //swapped gapi resolution
  215. SwapInt(&Info.cxWidth,&Info.cyHeight);
  216. Info.ffFormat &= ~kfLandscape;
  217. Info.cbxPitch = Info.cbxPitch<0 ? -Info.cBPP : Info.cBPP;
  218. }
  219. p->Overlay.Output.Format.Video.Width = Info.cxWidth;
  220. p->Overlay.Output.Format.Video.Height = Info.cyHeight;
  221. // we need the physical start of the framebuffer
  222. p->AdjustPtr = 0;
  223. if (Info.cbxPitch<0) 
  224. p->AdjustPtr += (Info.cbxPitch * (Info.cxWidth-1)) >> 3;
  225. if (Info.cbyPitch<0) 
  226. p->AdjustPtr += (Info.cbyPitch * (Info.cyHeight-1)) >> 3;
  227. if (Info.ffFormat & kfLandscape)
  228. {
  229. p->Overlay.Output.Format.Video.Direction |= DIR_SWAPXY;
  230. p->Overlay.Output.Format.Video.Pitch = abs(Info.cbxPitch) >> 3;
  231. SwapInt(&p->Overlay.Output.Format.Video.Width,&p->Overlay.Output.Format.Video.Height);
  232. if (Info.cbxPitch<0) 
  233. p->Overlay.Output.Format.Video.Direction |= DIR_MIRRORUPDOWN;
  234. if (Info.cbyPitch<0) 
  235. p->Overlay.Output.Format.Video.Direction |= DIR_MIRRORLEFTRIGHT;
  236. }
  237. else
  238. {
  239. p->Overlay.Output.Format.Video.Pitch = abs(Info.cbyPitch) >> 3;
  240. if (Info.cbxPitch<0) 
  241. p->Overlay.Output.Format.Video.Direction |= DIR_MIRRORLEFTRIGHT;
  242. if (Info.cbyPitch<0) 
  243. p->Overlay.Output.Format.Video.Direction |= DIR_MIRRORUPDOWN;
  244. }
  245. if (!p->DRAM)
  246. {
  247. p->Overlay.SetFX = BLITFX_AVOIDTEARING;
  248. if ((Info.cxWidth > Info.cyHeight) && (Caps & CAPS_PORTRAIT))
  249. p->Overlay.SetFX |= BLITFX_VMEMROTATED;
  250. if ((Info.cyHeight > Info.cxWidth) && (Caps & CAPS_LANDSCAPE))
  251. p->Overlay.SetFX |= BLITFX_VMEMROTATED;
  252. }
  253. else
  254. p->Overlay.ClearFX = BLITFX_ONLYDIFF;
  255. // wm2003se gapi emulation?
  256. if (QueryPlatform(PLATFORM_VER) >= 421)
  257. {
  258. if (p->Overlay.Output.Format.Video.Width == 240 && p->Overlay.Output.Format.Video.Height == 320 && p->Overlay.Output.Format.Video.Pitch == 640)
  259. p->Overlay.Output.Format.Video.Pitch = 480;
  260. }
  261. if (Info.cxWidth == 240 && Info.cyHeight == 320)
  262. AdjustOrientation(&p->Overlay.Output.Format.Video,0);
  263. return ERR_NONE;
  264. }
  265. static void Done(gapi* p)
  266. {
  267. }
  268. static int Reset(gapi* p)
  269. {
  270. Done(p);
  271. Init(p);
  272. return ERR_NONE;
  273. }
  274. static int Lock(gapi* p, planes Planes, bool_t OnlyAligned)
  275. {
  276. if (!p->Opened)
  277. return ERR_INVALID_PARAM;
  278. if (p->DirectPtr)
  279. p->Pointer = p->DirectPtr + p->AdjustPtr;
  280. else
  281. {
  282. if (p->DRAM && p->GXSetViewport)
  283. {
  284. int Top,Height;
  285. if (OnlyAligned)
  286. {
  287. Top = p->Overlay.GUIAlignedRect.y;
  288. Height = p->Overlay.GUIAlignedRect.Height;
  289. }
  290. else
  291. {
  292. Top = p->Overlay.Viewport.y;
  293. Height = p->Overlay.Viewport.Height;
  294. }
  295. if (p->Overlay.Output.Format.Video.Pixel.Flags & PF_PIXELDOUBLE)
  296. {
  297. Top >>= 1;
  298. Height >>= 1;
  299. }
  300. p->GXSetViewport(Top,Height,0,0); // coords in windows space
  301. }
  302. p->Pointer = (uint8_t*)p->GXBeginDraw();
  303. if (!p->Pointer)
  304. return ERR_NOT_SUPPORTED;
  305. p->Pointer += p->AdjustPtr;
  306. }
  307. Planes[0] = p->Pointer;
  308. return ERR_NONE;
  309. }
  310. static int Unlock(gapi* p)
  311. {
  312. if (!p->DirectPtr)
  313. p->GXEndDraw();
  314. return ERR_NONE;
  315. }
  316. static int UpdateWnd(gapi* p)
  317. {
  318. void* Wnd = Context()->Wnd;
  319. if (p->Wnd != Wnd)
  320. {
  321. p->Wnd = Wnd;
  322. if (p->Wnd && !p->Opened)
  323. {
  324. HWND WndTask;
  325. while (!p->GX || !p->GXOpenDisplay(p->Wnd,GX_FULLSCREEN))
  326. {
  327. if (!p->Windows)
  328. {
  329. p->Windows = 1; // try gx.dll in windows directory (HPC with .NET)
  330. if (LoadDriver(p))
  331. continue;
  332. }
  333. return ERR_NOT_SUPPORTED;
  334. }
  335. // just in case GXOpenDisplay hides these things
  336. if (p->SHFullScreen)
  337. {
  338. p->SHFullScreen(p->Wnd,SHFS_SHOWSTARTICON);
  339. p->SHFullScreen(p->Wnd,SHFS_SHOWTASKBAR);
  340. }
  341. WndTask = FindWindow(T("HHTaskbar"),NULL);
  342. if (WndTask)
  343. ShowWindow(WndTask,SW_SHOWNA);
  344. p->Info = p->GXGetDisplayProperties();
  345. if (!p->Info.cxWidth || !p->Info.cyHeight) // this shouldn't happen
  346. {
  347. p->GXCloseDisplay();
  348. return ERR_DEVICE_ERROR;
  349. }
  350. p->DirectPtr = NULL;
  351. p->Opened = 1;
  352. p->DRAM = 0;
  353. if (p->GXIsDisplayDRAMBuffer)
  354. p->DRAM = p->GXIsDisplayDRAMBuffer() != 0;
  355. // detect fake DRAM
  356. if (p->DRAM && !(p->Info.ffFormat & kfLandscape) && QueryPlatform(PLATFORM_MODEL)==MODEL_SPV_C500_ORIGROM)
  357. {
  358. p->GXSetViewport(0,0,0,0);
  359. p->DirectPtr = p->GXBeginDraw();
  360. }
  361. if (QueryPlatform(PLATFORM_VER) >= 421)
  362. IsOrientationChanged(); // force requery of orientation (GXOpenDisplay changes to portrait)
  363. Init(p); // we need the output format
  364. }
  365. else
  366. if (p->Opened && !p->Wnd && !p->DirectPtr)
  367. {
  368. p->GXCloseDisplay();
  369. p->Opened = 0;
  370. }
  371. }
  372. return ERR_NONE;
  373. }
  374. static int Set(gapi* p,int No,const void* Data,int Size)
  375. {
  376. int Result = OverlaySet(&p->Overlay,No,Data,Size);
  377. switch (No)
  378. {
  379. case NODE_SETTINGSCHANGED: 
  380. Result = UpdateWnd(p);
  381. break;
  382. }
  383. return Result;
  384. }
  385. static int Create(gapi* p)
  386. {
  387. if (NodeEnumObject(NULL,RAW_ID))
  388. return ERR_NOT_SUPPORTED;
  389. p->Overlay.Node.Enum = Enum;
  390. p->Overlay.Node.Get = Get;
  391. p->Overlay.Node.Set = Set;
  392. p->Overlay.Lock = Lock;
  393. p->Overlay.Unlock = Unlock;
  394. p->Overlay.Init = Init;
  395. p->Overlay.Done = Done;
  396. p->Overlay.Reset = Reset;
  397. p->Overlay.Node.Get = Get;
  398. p->Overlay.Node.Enum = Enum;
  399. if (!LoadDriver(p))
  400. return ERR_NOT_SUPPORTED;
  401. p->AygShell = LoadLibrary(T("aygshell.dll"));
  402. GetProc(&p->AygShell,&p->SHFullScreen,T("SHFullScreen"),1);
  403. return ERR_NONE;
  404. }
  405. static void Delete(gapi* p)
  406. {
  407. if (p->GX)
  408. FreeLibrary(p->GX);
  409. if (p->AygShell)
  410. FreeLibrary(p->AygShell);
  411. }
  412. static const nodedef GAPI =
  413. {
  414. sizeof(gapi)|CF_GLOBAL,
  415. GAPI_ID,
  416. OVERLAY_CLASS,
  417. PRI_DEFAULT+50,
  418. (nodecreate)Create,
  419. (nodedelete)Delete,
  420. };
  421. void OverlayGAPI_Init() 
  422. NodeRegisterClass(&GAPI);
  423. }
  424. void OverlayGAPI_Done()
  425. {
  426. NodeUnRegisterClass(GAPI_ID);
  427. }
  428. #endif