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.

485 lines
13 KiB

  1. /****************************************************************************
  2. *
  3. * DRAWPROC.C
  4. *
  5. * Standard AVI drawing handler.
  6. *
  7. * Copyright (c) 1992 Microsoft Corporation. All Rights Reserved.
  8. *
  9. * You have a royalty-free right to use, modify, reproduce and
  10. * distribute the Sample Files (and/or any modified version) in
  11. * any way you find useful, provided that you agree that
  12. * Microsoft has no warranty obligations or liability for any
  13. * Sample Application Files which are modified.
  14. *
  15. ***************************************************************************/
  16. #include <win32.h>
  17. #include <compman.h>
  18. #include <dispdib.h>
  19. #ifdef WIN32
  20. #include <mmddk.h>
  21. #endif
  22. static SZCODE szDisplayDibLib[] = TEXT("DISPDIB.DLL");
  23. static SZCODEA szDisplayDibEx[] = "DisplayDibEx";
  24. #define FOURCC_VIDS mmioFOURCC('v','i','d','s')
  25. #define FOURCC_AVIFull mmioFOURCC('F','U','L','L')
  26. #define VERSION_AVIFull 0x00010000 // 1.00
  27. #ifndef HUGE
  28. #define HUGE _huge
  29. #endif
  30. extern FAR PASCAL LockCurrentTask(BOOL);
  31. static int siUsage = 0;
  32. HINSTANCE ghDISPDIB = NULL; // handle to DISPDIB.DLL module
  33. UINT (FAR PASCAL *DisplayDibExProc)(LPBITMAPINFOHEADER lpbi, int x, int y, BYTE HUGE * hpBits, UINT wFlags);
  34. /***************************************************************************
  35. ***************************************************************************/
  36. typedef struct {
  37. int xDst; // destination rectangle
  38. int yDst;
  39. int dxDst;
  40. int dyDst;
  41. int xSrc; // source rectangle
  42. int ySrc;
  43. int dxSrc;
  44. int dySrc;
  45. HWND hwnd;
  46. HWND hwndOldFocus;
  47. BOOL fRle;
  48. DWORD biSizeImage;
  49. } INSTINFO, *PINSTINFO;
  50. // static stuff in this file.
  51. LONG FAR PASCAL _loadds ICAVIFullProc(DWORD id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2);
  52. static LONG AVIFullOpen(ICOPEN FAR * icopen);
  53. static LONG AVIFullClose(PINSTINFO pi);
  54. static LONG AVIFullGetInfo(ICINFO FAR *icinfo, LONG lSize);
  55. static LONG AVIFullQuery(PINSTINFO pi, LPBITMAPINFOHEADER lpbiIn);
  56. static LONG AVIFullSuggestFormat(PINSTINFO pi, ICDRAWSUGGEST FAR *lpicd, LONG cbicd);
  57. static LONG AVIFullBegin(PINSTINFO pi, ICDRAWBEGIN FAR *lpicd, LONG cbicd);
  58. static LONG AVIFullDraw(PINSTINFO pi, ICDRAW FAR *lpicd, LONG cbicd);
  59. static LONG AVIFullEnd(PINSTINFO pi);
  60. /***************************************************************************
  61. ***************************************************************************/
  62. LONG FAR PASCAL _loadds ICAVIFullProc(DWORD id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2)
  63. {
  64. INSTINFO *pi = (INSTINFO *)(UINT)id;
  65. switch (uiMessage)
  66. {
  67. case DRV_LOAD:
  68. return 1;
  69. case DRV_FREE:
  70. return 1;
  71. /*********************************************************************
  72. open
  73. *********************************************************************/
  74. case DRV_OPEN:
  75. if (ghDISPDIB == NULL) {
  76. UINT w;
  77. w = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  78. if ((ghDISPDIB = LoadLibrary(szDisplayDibLib)) > HINSTANCE_ERROR) {
  79. (FARPROC)DisplayDibExProc = GetProcAddress(ghDISPDIB, szDisplayDibEx);
  80. }
  81. else
  82. ghDISPDIB = (HINSTANCE)-1;
  83. SetErrorMode(w);
  84. }
  85. if (DisplayDibExProc == NULL)
  86. return 0;
  87. if (lParam2 == 0L)
  88. return 1;
  89. return AVIFullOpen((ICOPEN FAR *)lParam2);
  90. case DRV_CLOSE:
  91. if (id == 1)
  92. return 1;
  93. return AVIFullClose(pi);
  94. /*********************************************************************
  95. Configure/Info messages
  96. *********************************************************************/
  97. case DRV_QUERYCONFIGURE: // configuration from drivers applet
  98. return 0;
  99. case DRV_CONFIGURE:
  100. return 1;
  101. case ICM_CONFIGURE:
  102. case ICM_ABOUT:
  103. return ICERR_UNSUPPORTED;
  104. /*********************************************************************
  105. state messages
  106. *********************************************************************/
  107. case ICM_GETSTATE:
  108. case ICM_SETSTATE:
  109. return 0L;
  110. #if 0
  111. case ICM_GETINFO:
  112. return AVIFullGetInfo((ICINFO FAR *)lParam1, lParam2);
  113. #endif
  114. /*********************************************************************
  115. decompress messages
  116. *********************************************************************/
  117. case ICM_DRAW_QUERY:
  118. return AVIFullQuery(pi, (LPBITMAPINFOHEADER)lParam1);
  119. case ICM_DRAW_SUGGESTFORMAT:
  120. return AVIFullSuggestFormat(pi, (ICDRAWSUGGEST FAR *) lParam1, lParam2);
  121. case ICM_DRAW_BEGIN:
  122. return AVIFullBegin(pi, (ICDRAWBEGIN FAR *) lParam1, lParam2);
  123. case ICM_DRAW:
  124. return AVIFullDraw(pi, (ICDRAW FAR *)lParam1, lParam2);
  125. case ICM_DRAW_CHANGEPALETTE:
  126. DisplayDibExProc((LPBITMAPINFOHEADER) lParam1, 0, 0, NULL,
  127. DISPLAYDIB_NOWAIT | DISPLAYDIB_NOIMAGE);
  128. return ICERR_OK;
  129. case ICM_DRAW_END:
  130. return AVIFullEnd(pi);
  131. /*********************************************************************
  132. standard driver messages
  133. *********************************************************************/
  134. case DRV_DISABLE:
  135. case DRV_ENABLE:
  136. return 1;
  137. case DRV_INSTALL:
  138. case DRV_REMOVE:
  139. return 1;
  140. }
  141. if (uiMessage < DRV_USER)
  142. return DefDriverProc(id,hDriver,uiMessage,lParam1,lParam2);
  143. else
  144. return ICERR_UNSUPPORTED;
  145. }
  146. /*****************************************************************************
  147. *
  148. * AVIFullOpen() is called from the DRV_OPEN message
  149. *
  150. ****************************************************************************/
  151. static LONG AVIFullOpen(ICOPEN FAR * icopen)
  152. {
  153. INSTINFO * pinst;
  154. //
  155. // refuse to open if we are not being opened as a Video compressor
  156. //
  157. if (icopen->dwFlags & ICMODE_COMPRESS)
  158. return 0;
  159. if (icopen->dwFlags & ICMODE_DECOMPRESS)
  160. return 0;
  161. pinst = (INSTINFO *)LocalAlloc(LPTR, sizeof(INSTINFO));
  162. if (!pinst)
  163. {
  164. icopen->dwError = ICERR_MEMORY;
  165. return 0;
  166. }
  167. ++siUsage;
  168. //
  169. // return success.
  170. //
  171. icopen->dwError = ICERR_OK;
  172. return (LONG) (UINT) pinst;
  173. }
  174. /*****************************************************************************
  175. *
  176. * Close() is called on the DRV_CLOSE message.
  177. *
  178. ****************************************************************************/
  179. static LONG AVIFullClose(PINSTINFO pi)
  180. {
  181. LocalFree((HLOCAL) pi);
  182. if (--siUsage == 0) {
  183. /* unload DISPDIB library (if loaded) */
  184. if (ghDISPDIB != NULL && ghDISPDIB != (HINSTANCE) -1)
  185. FreeLibrary(ghDISPDIB), ghDISPDIB = NULL;
  186. }
  187. return 1;
  188. }
  189. #if 0
  190. /*****************************************************************************
  191. *
  192. * AVIFullGetInfo() implements the ICM_GETINFO message
  193. *
  194. ****************************************************************************/
  195. static LONG AVIFullGetInfo(ICINFO FAR *icinfo, LONG lSize)
  196. {
  197. if (icinfo == NULL)
  198. return sizeof(ICINFO);
  199. if (lSize < sizeof(ICINFO))
  200. return 0;
  201. icinfo->dwSize = sizeof(ICINFO);
  202. icinfo->fccType = FOURCC_VIDS;
  203. icinfo->fccHandler = FOURCC_AVIFull;
  204. icinfo->dwFlags = VIDCF_DRAW;
  205. icinfo->dwVersion = VERSION_AVIFull;
  206. icinfo->dwVersionICM = ICVERSION;
  207. lstrcpy(icinfo->szDescription, szDescription);
  208. lstrcpy(icinfo->szName, szName);
  209. return sizeof(ICINFO);
  210. }
  211. #endif
  212. /*****************************************************************************
  213. *
  214. * AVIFullQuery() implements ICM_DRAW_QUERY
  215. *
  216. ****************************************************************************/
  217. static LONG AVIFullQuery(PINSTINFO pi,
  218. LPBITMAPINFOHEADER lpbiIn)
  219. {
  220. //
  221. // determine if the input DIB data is in a format we like.
  222. //
  223. if (lpbiIn == NULL)
  224. return ICERR_BADFORMAT;
  225. if (DisplayDibExProc(lpbiIn, 0, 0, 0,
  226. DISPLAYDIB_MODE_DEFAULT|DISPLAYDIB_NOWAIT|DISPLAYDIB_TEST) != 0)
  227. return ICERR_BADFORMAT;
  228. return ICERR_OK;
  229. }
  230. static LONG AVIFullSuggestFormat(PINSTINFO pi, ICDRAWSUGGEST FAR *lpicd, LONG cbicd)
  231. {
  232. HIC hic;
  233. static int iFull = -1;
  234. int iDepth;
  235. if (iFull < 0) {
  236. BITMAPINFOHEADER bih;
  237. bih.biSize = sizeof(bih);
  238. bih.biBitCount = 16;
  239. bih.biCompression = BI_RGB;
  240. bih.biWidth = 160;
  241. bih.biHeight = 120;
  242. iFull = (AVIFullQuery(pi, &bih) == ICERR_OK) ? 1 : 0;
  243. }
  244. iDepth = lpicd->lpbiIn->biBitCount > 8 && iFull == 1 ? 16 : 8;
  245. if (lpicd->lpbiSuggest == NULL)
  246. return sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
  247. hic = ICGetDisplayFormat(NULL, lpicd->lpbiIn,
  248. lpicd->lpbiSuggest,
  249. iDepth, 0, 0);
  250. if (hic)
  251. ICClose(hic);
  252. return sizeof(BITMAPINFOHEADER) + lpicd->lpbiSuggest->biClrUsed * sizeof(RGBQUAD);
  253. }
  254. /*****************************************************************************
  255. *
  256. * AVIFullBegin() implements ICM_DRAW_BEGIN
  257. *
  258. ****************************************************************************/
  259. static LONG AVIFullBegin(PINSTINFO pi, ICDRAWBEGIN FAR *lpicd, LONG cbicd)
  260. {
  261. UINT w;
  262. LONG lRet;
  263. if (!(lpicd->dwFlags & ICDRAW_FULLSCREEN))
  264. return ICERR_UNSUPPORTED; // !!! Necessary?
  265. lRet = AVIFullQuery(pi, lpicd->lpbi);
  266. if (lRet != 0 || (lpicd->dwFlags & ICDRAW_QUERY))
  267. return lRet;
  268. // Copy over whatever we want to remember
  269. pi->hwnd = lpicd->hwnd;
  270. pi->xDst = lpicd->xDst;
  271. pi->yDst = lpicd->yDst;
  272. pi->dxDst = lpicd->dxDst;
  273. pi->dyDst = lpicd->dyDst;
  274. pi->xSrc = lpicd->xSrc;
  275. pi->ySrc = lpicd->ySrc;
  276. pi->dxSrc = lpicd->dxSrc;
  277. pi->dySrc = lpicd->dySrc;
  278. //
  279. // remember if this is RLE because we may need to hack it later.
  280. //
  281. pi->fRle = lpicd->lpbi->biCompression == BI_RLE8;
  282. pi->biSizeImage = (DWORD)(((UINT)lpicd->lpbi->biWidth+3)&~3)*(DWORD)(UINT)lpicd->lpbi->biHeight;
  283. pi->hwndOldFocus = GetFocus();
  284. SetFocus(NULL);
  285. //
  286. // we dont need to do this, DISPDIB will do it for us
  287. //
  288. #if 0
  289. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  290. LockCurrentTask(TRUE);
  291. #endif
  292. /* Capture the mouse, so other apps don't get called. */
  293. SetCapture(pi->hwnd);
  294. /* We don't explicitly specify a graphics mode; DispDib will
  295. ** choose one for us.
  296. */
  297. w = DisplayDibExProc(lpicd->lpbi, 0, 0, NULL,
  298. DISPLAYDIB_BEGIN | DISPLAYDIB_NOWAIT);
  299. switch (w) {
  300. case DISPLAYDIB_INVALIDFORMAT:
  301. return ICERR_BADFORMAT;
  302. case 0:
  303. return ICERR_OK;
  304. default:
  305. return ICERR_UNSUPPORTED;
  306. }
  307. }
  308. /*****************************************************************************
  309. *
  310. * AVIFullDraw() implements ICM_DRAW
  311. *
  312. ****************************************************************************/
  313. static LONG AVIFullDraw(PINSTINFO pi, ICDRAW FAR *lpicd, LONG cbicd)
  314. {
  315. UINT wFlags;
  316. UINT w;
  317. wFlags = DISPLAYDIB_NOPALETTE | DISPLAYDIB_NOWAIT;
  318. if (pi->dxDst > pi->dxSrc)
  319. wFlags |= DISPLAYDIB_ZOOM2;
  320. if (lpicd->dwFlags & ICDRAW_NULLFRAME) {
  321. return ICERR_OK; // !!!
  322. }
  323. if (lpicd->dwFlags & ICDRAW_PREROLL) {
  324. if (((LPBITMAPINFOHEADER)lpicd->lpFormat)->biCompression == BI_RGB) // !!!
  325. return ICERR_OK;
  326. }
  327. if (lpicd->dwFlags & ICDRAW_HURRYUP)
  328. ; // !!! DONTDRAW?
  329. if (lpicd->lpData == NULL)
  330. return ICERR_UNSUPPORTED;
  331. //
  332. // We need a hack here for the RLE case, to make sure that
  333. // DIBs are marked correctly as BI_RLE8 or BI_RGB....
  334. //
  335. if (pi->fRle) {
  336. if (lpicd->cbData == pi->biSizeImage)
  337. ((LPBITMAPINFOHEADER)lpicd->lpFormat)->biCompression = BI_RGB;
  338. else
  339. ((LPBITMAPINFOHEADER)lpicd->lpFormat)->biCompression = BI_RLE8;
  340. }
  341. w = DisplayDibExProc(lpicd->lpFormat, 0, 0, lpicd->lpData, wFlags);
  342. if (pi->fRle)
  343. ((LPBITMAPINFOHEADER)lpicd->lpFormat)->biCompression = BI_RLE8;
  344. if (w != DISPLAYDIB_NOERROR)
  345. return ICERR_ERROR;
  346. return ICERR_OK;
  347. }
  348. /*****************************************************************************
  349. *
  350. * AVIFullEnd() implements ICM_DRAW_END
  351. *
  352. ****************************************************************************/
  353. static LONG AVIFullEnd(PINSTINFO pi)
  354. {
  355. MSG msg;
  356. DisplayDibExProc(NULL, 0, 0, NULL, DISPLAYDIB_END | DISPLAYDIB_NOWAIT);
  357. //
  358. // we dont need to do this, DISPDIB will do it for us
  359. //
  360. #if 0
  361. LockCurrentTask(FALSE);
  362. /* Can we assume the error mode should be 0? */
  363. SetErrorMode(0);
  364. #endif
  365. ReleaseCapture();
  366. /* Clear out left-over key messages */
  367. while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST,
  368. PM_REMOVE | PM_NOYIELD))
  369. ;
  370. /* Clear out left-over mouse messages */
  371. while (PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST,
  372. PM_REMOVE | PM_NOYIELD))
  373. ;
  374. SetFocus(pi->hwndOldFocus);
  375. return ICERR_OK;
  376. }
  377.