Leaked source code of windows server 2003
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.

514 lines
14 KiB

  1. /****************************************************************************
  2. *
  3. * DRAWPROC.C
  4. *
  5. * Standard AVI drawing handler.
  6. *
  7. * InstallAVIDrawHandler()
  8. *
  9. * Copyright (c) 1992 Microsoft Corporation. All Rights Reserved.
  10. *
  11. * You have a royalty-free right to use, modify, reproduce and
  12. * distribute the Sample Files (and/or any modified version) in
  13. * any way you find useful, provided that you agree that
  14. * Microsoft has no warranty obligations or liability for any
  15. * Sample Application Files which are modified.
  16. *
  17. ***************************************************************************/
  18. #include <win32.h>
  19. #include <vfw.h>
  20. #include "common.h"
  21. #include "mciavi.h"
  22. #define FOURCC_VIDS mmioFOURCC('v','i','d','s')
  23. #define FOURCC_AVIDraw mmioFOURCC('D','R','A','W')
  24. #define VERSION_AVIDraw 0x00010000 // 1.00
  25. #ifdef DEBUG
  26. HDRAWDIB ghdd;
  27. #endif
  28. #ifndef HUGE
  29. #define HUGE _huge
  30. #endif
  31. /***************************************************************************
  32. ***************************************************************************/
  33. typedef struct {
  34. HDRAWDIB hdd;
  35. HDC hdc; // HDC to draw to
  36. int xDst; // destination rectangle
  37. int yDst;
  38. int dxDst;
  39. int dyDst;
  40. int xSrc; // source rectangle
  41. int ySrc;
  42. int dxSrc;
  43. int dySrc;
  44. BOOL fBackground;
  45. BOOL fRle;
  46. DWORD biSizeImage;
  47. BOOL fNeedUpdate;
  48. LONG rate; // playback rate (uSec / frame)
  49. } INSTINFO, *PINSTINFO;
  50. // static stuff in this file.
  51. LONG FAR PASCAL _loadds ICAVIDrawProc(DWORD id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2);
  52. static LONG AVIDrawOpen(ICOPEN FAR * icopen);
  53. static LONG AVIDrawClose(PINSTINFO pi);
  54. static LONG AVIDrawGetInfo(ICINFO FAR *icinfo, LONG lSize);
  55. static LONG AVIDrawQuery(PINSTINFO pi, LPBITMAPINFOHEADER lpbiIn);
  56. static LONG AVIDrawSuggestFormat(PINSTINFO pi, ICDRAWSUGGEST FAR *lpicd, LONG cbicd);
  57. static LONG AVIDrawBegin(PINSTINFO pi, ICDRAWBEGIN FAR *lpicd, LONG cbicd);
  58. static LONG AVIDraw(PINSTINFO pi, ICDRAW FAR *lpicd, LONG cbicd);
  59. static LONG AVIDrawEnd(PINSTINFO pi);
  60. static LONG AVIDrawChangePalette(PINSTINFO pi, LPBITMAPINFOHEADER lpbi);
  61. /***************************************************************************
  62. ***************************************************************************/
  63. LONG FAR PASCAL _loadds ICAVIDrawProc(DWORD id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2)
  64. {
  65. INSTINFO *pi = (INSTINFO *)(UINT)id;
  66. switch (uiMessage)
  67. {
  68. case DRV_LOAD:
  69. case DRV_FREE:
  70. return 1;
  71. /*********************************************************************
  72. open
  73. *********************************************************************/
  74. case DRV_OPEN:
  75. if (lParam2 == 0L)
  76. return 1;
  77. return AVIDrawOpen((ICOPEN FAR *)lParam2);
  78. case DRV_CLOSE:
  79. return AVIDrawClose(pi);
  80. /*********************************************************************
  81. Configure/Info messages
  82. *********************************************************************/
  83. case DRV_QUERYCONFIGURE: // configuration from drivers applet
  84. return 0;
  85. case DRV_CONFIGURE:
  86. return 1;
  87. case ICM_CONFIGURE:
  88. case ICM_ABOUT:
  89. return ICERR_UNSUPPORTED;
  90. /*********************************************************************
  91. state messages
  92. *********************************************************************/
  93. case ICM_GETSTATE:
  94. case ICM_SETSTATE:
  95. return 0L;
  96. // case ICM_GETINFO:
  97. // return AVIDrawGetInfo((ICINFO FAR *)lParam1, lParam2);
  98. /*********************************************************************
  99. decompress messages
  100. *********************************************************************/
  101. case ICM_DRAW_QUERY:
  102. return AVIDrawQuery(pi, (LPBITMAPINFOHEADER)lParam1);
  103. case ICM_DRAW_SUGGESTFORMAT:
  104. return AVIDrawSuggestFormat(pi, (ICDRAWSUGGEST FAR *) lParam1, lParam2);
  105. case ICM_DRAW_BEGIN:
  106. return AVIDrawBegin(pi, (ICDRAWBEGIN FAR *) lParam1, lParam2);
  107. case ICM_DRAW_REALIZE:
  108. pi->hdc = (HDC) lParam1;
  109. if (!pi->hdc || !pi->hdd)
  110. break;
  111. pi->fBackground = (BOOL) lParam2;
  112. return DrawDibRealize(pi->hdd, pi->hdc, pi->fBackground);
  113. case ICM_DRAW_GET_PALETTE:
  114. if (!pi->hdd)
  115. break;
  116. return (LONG) DrawDibGetPalette(pi->hdd);
  117. case ICM_DRAW:
  118. return AVIDraw(pi, (ICDRAW FAR *)lParam1, lParam2);
  119. case ICM_DRAW_CHANGEPALETTE:
  120. return AVIDrawChangePalette(pi, (LPBITMAPINFOHEADER) lParam1);
  121. case ICM_DRAW_END:
  122. return AVIDrawEnd(pi);
  123. case ICM_DRAW_START:
  124. return DrawDibStart(pi->hdd, pi->rate);
  125. case ICM_DRAW_STOP:
  126. return DrawDibStop(pi->hdd);
  127. /*********************************************************************
  128. standard driver messages
  129. *********************************************************************/
  130. case DRV_DISABLE:
  131. case DRV_ENABLE:
  132. return 1;
  133. case DRV_INSTALL:
  134. case DRV_REMOVE:
  135. return 1;
  136. }
  137. return ICERR_UNSUPPORTED;
  138. }
  139. /*****************************************************************************
  140. *
  141. * AVIDrawOpen() is called from the DRV_OPEN message
  142. *
  143. ****************************************************************************/
  144. static LONG AVIDrawOpen(ICOPEN FAR * icopen)
  145. {
  146. INSTINFO * pinst;
  147. if (icopen->dwFlags & ICMODE_COMPRESS)
  148. return 0;
  149. if (icopen->dwFlags & ICMODE_DECOMPRESS)
  150. return 0;
  151. pinst = (INSTINFO *)LocalAlloc(LPTR, sizeof(INSTINFO));
  152. if (!pinst)
  153. {
  154. icopen->dwError = ICERR_MEMORY;
  155. return 0;
  156. }
  157. DPF2(("*** AVIDrawOpen()\n"));
  158. //
  159. // init structure
  160. //
  161. pinst->hdd = DrawDibOpen();
  162. #ifdef DEBUG
  163. ghdd = pinst->hdd;
  164. #endif
  165. //
  166. // return success.
  167. //
  168. icopen->dwError = ICERR_OK;
  169. return (LONG) (UINT) pinst;
  170. }
  171. /*****************************************************************************
  172. *
  173. * Close() is called on the DRV_CLOSE message.
  174. *
  175. ****************************************************************************/
  176. static LONG AVIDrawClose(PINSTINFO pi)
  177. {
  178. DPF2(("*** AVIDrawClose()\n"));
  179. if (pi->hdd) {
  180. DrawDibClose(pi->hdd);
  181. }
  182. LocalFree((HLOCAL) pi);
  183. return 1;
  184. }
  185. #if 0
  186. /*****************************************************************************
  187. *
  188. * AVIDrawGetInfo() implements the ICM_GETINFO message
  189. *
  190. ****************************************************************************/
  191. static LONG AVIDrawGetInfo(ICINFO FAR *icinfo, LONG lSize)
  192. {
  193. if (icinfo == NULL)
  194. return sizeof(ICINFO);
  195. if (lSize < sizeof(ICINFO))
  196. return 0;
  197. icinfo->dwSize = sizeof(ICINFO);
  198. icinfo->fccType = FOURCC_VIDS;
  199. icinfo->fccHandler = FOURCC_AVIDraw;
  200. icinfo->dwFlags = VIDCF_DRAW; // supports inter-frame
  201. icinfo->dwVersion = VERSION_AVIDraw;
  202. icinfo->dwVersionICM = ICVERSION;
  203. icinfo->szName[0] = 0;
  204. icinfo->szDescription[0]= 0;
  205. return sizeof(ICINFO);
  206. }
  207. #endif
  208. /*****************************************************************************
  209. *
  210. * AVIDrawQuery() implements ICM_DRAW_QUERY
  211. *
  212. ****************************************************************************/
  213. static LONG AVIDrawQuery(PINSTINFO pi,
  214. LPBITMAPINFOHEADER lpbiIn)
  215. {
  216. //
  217. // determine if the input DIB data is in a format we like.
  218. //
  219. if (lpbiIn == NULL)
  220. return ICERR_BADFORMAT;
  221. //
  222. // determine if the input DIB data is in a format we like.
  223. //
  224. // !!! Do we need a DrawDibQuery or something here to let this handle
  225. // any compressed format?
  226. #ifdef DRAWDIBNODECOMPRESS
  227. if (lpbiIn->biCompression != BI_RGB &&
  228. #if 0
  229. !(lpbiIn->biBitCount == 8 && lpbiIn->biCompression == BI_RLE8))
  230. #else
  231. 1)
  232. #endif
  233. return ICERR_BADFORMAT;
  234. #endif
  235. return ICERR_OK;
  236. }
  237. static LONG AVIDrawSuggestFormat(PINSTINFO pi, ICDRAWSUGGEST FAR *lpicd, LONG cbicd)
  238. {
  239. HIC hic;
  240. if (lpicd->lpbiSuggest == NULL)
  241. return sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
  242. hic = ICGetDisplayFormat(NULL, lpicd->lpbiIn, lpicd->lpbiSuggest,
  243. 0, lpicd->dxDst, lpicd->dyDst);
  244. if (hic)
  245. ICClose(hic);
  246. return sizeof(BITMAPINFOHEADER) + lpicd->lpbiSuggest->biClrUsed * sizeof(RGBQUAD);
  247. }
  248. /*****************************************************************************
  249. *
  250. * AVIDrawBegin() implements ICM_DRAW_BEGIN
  251. *
  252. ****************************************************************************/
  253. static LONG AVIDrawBegin(PINSTINFO pi, ICDRAWBEGIN FAR *lpicd, LONG cbicd)
  254. {
  255. LONG l;
  256. UINT wFlags;
  257. if (lpicd->dwFlags & ICDRAW_FULLSCREEN)
  258. return ICERR_UNSUPPORTED;
  259. l = AVIDrawQuery(pi, lpicd->lpbi);
  260. if ((l != 0) || (lpicd->dwFlags & ICDRAW_QUERY))
  261. return l;
  262. // Copy over whatever we want to remember
  263. pi->hdc = lpicd->hdc;
  264. pi->xDst = lpicd->xDst;
  265. pi->yDst = lpicd->yDst;
  266. pi->dxDst = lpicd->dxDst;
  267. pi->dyDst = lpicd->dyDst;
  268. pi->xSrc = lpicd->xSrc;
  269. pi->ySrc = lpicd->ySrc;
  270. pi->dxSrc = lpicd->dxSrc;
  271. pi->dySrc = lpicd->dySrc;
  272. pi->rate = muldiv32(lpicd->dwScale,1000000,lpicd->dwRate);
  273. // !!! Should this be done somewhere else? drawdib mabey!
  274. if (pi->hdc)
  275. SetStretchBltMode(pi->hdc, COLORONCOLOR);
  276. wFlags = 0;
  277. // !!! We need some way to have a "stupid" mode here....
  278. if (lpicd->dwFlags & ICDRAW_BUFFER)
  279. wFlags |= DDF_BUFFER;
  280. // Don't animate if we're realizing in the background
  281. if (lpicd->dwFlags & ICDRAW_ANIMATE && !(pi->fBackground))
  282. wFlags |= DDF_ANIMATE;
  283. //
  284. // remember if this is RLE because we may need to hack it later.
  285. //
  286. pi->fRle = lpicd->lpbi->biCompression == BI_RLE8;
  287. pi->biSizeImage = (DWORD)(((UINT)lpicd->lpbi->biWidth+3)&~3)*(DWORD)(UINT)lpicd->lpbi->biHeight;
  288. DPF2(("*** AVIDrawBegin()\n"));
  289. if (lpicd->hpal == (HPALETTE)MCI_AVI_SETVIDEO_PALETTE_HALFTONE) {
  290. DrawDibSetPalette(pi->hdd, NULL);
  291. wFlags |= DDF_HALFTONE;
  292. }
  293. else
  294. DrawDibSetPalette(pi->hdd, lpicd->hpal);
  295. if (!DrawDibBegin(pi->hdd, pi->hdc,
  296. pi->dxDst, pi->dyDst,
  297. lpicd->lpbi,
  298. pi->dxSrc, pi->dySrc,
  299. wFlags))
  300. return ICERR_UNSUPPORTED;
  301. if (pi->hdc)
  302. DrawDibRealize(pi->hdd, pi->hdc, pi->fBackground);
  303. return ICERR_OK;
  304. }
  305. /*****************************************************************************
  306. *
  307. * AVIDraw() implements ICM_DRAW
  308. *
  309. ****************************************************************************/
  310. static LONG AVIDraw(PINSTINFO pi, ICDRAW FAR *lpicd, LONG cbicd)
  311. {
  312. UINT wFlags;
  313. BOOL f;
  314. wFlags = DDF_SAME_DRAW|DDF_SAME_HDC; // !!! Right flags?
  315. if ((lpicd->lpData == NULL) || (lpicd->cbData == 0)) {
  316. if ((lpicd->dwFlags & ICDRAW_UPDATE) || pi->fNeedUpdate) {
  317. DrawDibRealize(pi->hdd, pi->hdc, pi->fBackground);
  318. wFlags |= DDF_UPDATE;
  319. pi->fNeedUpdate = FALSE;
  320. }
  321. else
  322. return ICERR_OK; // no data to draw.
  323. }
  324. else {
  325. if (lpicd->dwFlags & ICDRAW_PREROLL) {
  326. wFlags |= DDF_DONTDRAW;
  327. pi->fNeedUpdate = TRUE;
  328. } else if (lpicd->dwFlags & ICDRAW_HURRYUP) {
  329. wFlags |= DDF_HURRYUP;
  330. pi->fNeedUpdate = TRUE;
  331. } else
  332. pi->fNeedUpdate = FALSE;
  333. if (lpicd->dwFlags & ICDRAW_NOTKEYFRAME)
  334. wFlags |= DDF_NOTKEYFRAME;
  335. //
  336. // if we get a update while playing and we are drawing RLE delta's
  337. // make sure we update.
  338. //
  339. if (pi->fRle && (lpicd->dwFlags & ICDRAW_UPDATE)) {
  340. DrawDibDraw(pi->hdd, pi->hdc, pi->xDst, pi->yDst,
  341. 0,0,NULL,NULL,0,0,0,0,DDF_UPDATE|DDF_SAME_HDC|DDF_SAME_DRAW);
  342. }
  343. }
  344. //
  345. // We need a hack here for the RLE case, to make sure that
  346. // DIBs are marked correctly as BI_RLE8 or BI_RGB....
  347. //
  348. if (pi->fRle) {
  349. if (lpicd->cbData == pi->biSizeImage)
  350. ((LPBITMAPINFOHEADER)lpicd->lpFormat)->biCompression = BI_RGB;
  351. else
  352. ((LPBITMAPINFOHEADER)lpicd->lpFormat)->biCompression = BI_RLE8;
  353. }
  354. f = DrawDibDraw(pi->hdd, pi->hdc,
  355. pi->xDst, pi->yDst,
  356. pi->dxDst, pi->dyDst,
  357. lpicd->lpFormat,
  358. lpicd->lpData,
  359. pi->xSrc, pi->ySrc,
  360. pi->dxSrc, pi->dySrc,
  361. wFlags);
  362. if (pi->fRle)
  363. ((LPBITMAPINFOHEADER)lpicd->lpFormat)->biCompression = BI_RLE8;
  364. if (!f) {
  365. if (wFlags & DDF_UPDATE)
  366. DPF(("DrawDibUpdate failed\n"));
  367. else
  368. DPF(("DrawDibDraw failed\n"));
  369. if (wFlags & DDF_UPDATE)
  370. return ICERR_CANTUPDATE;
  371. else
  372. return ICERR_ERROR;
  373. }
  374. return ICERR_OK;
  375. }
  376. static LONG AVIDrawChangePalette(PINSTINFO pi, LPBITMAPINFOHEADER lpbi)
  377. {
  378. PALETTEENTRY ape[256];
  379. LPRGBQUAD lprgb;
  380. int i;
  381. lprgb = (LPRGBQUAD) ((LPBYTE) lpbi + lpbi->biSize);
  382. for (i = 0; i < (int) lpbi->biClrUsed; i++) {
  383. ape[i].peRed = lprgb[i].rgbRed;
  384. ape[i].peGreen = lprgb[i].rgbGreen;
  385. ape[i].peBlue = lprgb[i].rgbBlue;
  386. ape[i].peFlags = 0;
  387. }
  388. DrawDibChangePalette(pi->hdd, 0, (int) lpbi->biClrUsed,
  389. (LPPALETTEENTRY)ape);
  390. return ICERR_OK;
  391. }
  392. /*****************************************************************************
  393. *
  394. * AVIDrawEnd() implements ICM_DRAW_END
  395. *
  396. ****************************************************************************/
  397. static LONG AVIDrawEnd(PINSTINFO pi)
  398. {
  399. return ICERR_OK;
  400. }