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.

466 lines
12 KiB

  1. #include <windows.h>
  2. #undef WINAPI
  3. #define WINAPI FAR PASCAL _loadds
  4. #include "dva.h"
  5. #include "dciman.h"
  6. #include "lockbm.h"
  7. /****************************************************************************
  8. ***************************************************************************/
  9. extern BOOL vga_get_surface(HDC, int, DVASURFACEINFO FAR *);
  10. extern BOOL ati_get_surface(HDC, int, DVASURFACEINFO FAR *);
  11. #ifdef DEBUG
  12. //extern BOOL dib_get_surface(HDC, int, DVASURFACEINFO FAR *);
  13. extern BOOL thun_get_surface(HDC,int, DVASURFACEINFO FAR *);
  14. extern BOOL vlb_get_surface(HDC, int, DVASURFACEINFO FAR *);
  15. #endif
  16. #define GetDS() SELECTOROF((LPVOID)&ScreenSel)
  17. static short ScreenSel;
  18. static BOOL InitSurface(DVASURFACEINFO FAR *pdva);
  19. static BOOL TestSurface(DVASURFACEINFO FAR *pdva);
  20. static void SetSelLimit(UINT sel, DWORD limit);
  21. /****************************************************************************
  22. ***************************************************************************/
  23. static void FAR PASCAL DVAInit()
  24. {
  25. }
  26. /****************************************************************************
  27. ***************************************************************************/
  28. static void FAR PASCAL DVATerm()
  29. {
  30. //
  31. // free screen alias
  32. //
  33. if (ScreenSel)
  34. {
  35. SetSelLimit(ScreenSel, 0);
  36. FreeSelector(ScreenSel);
  37. ScreenSel = 0;
  38. }
  39. }
  40. /****************************************************************************
  41. ***************************************************************************/
  42. BOOL WINAPI DVAGetSurface(HDC hdc, int nSurface, DVASURFACEINFO FAR *pdva)
  43. {
  44. //
  45. // should this be a function table? list?
  46. //
  47. if (!ati_get_surface(hdc, nSurface, pdva) &&
  48. #ifdef DEBUG
  49. // !dib_get_surface(hdc, nSurface, pdva) &&
  50. !vlb_get_surface(hdc, nSurface, pdva) &&
  51. !thun_get_surface(hdc, nSurface, pdva) &&
  52. #endif
  53. !vga_get_surface(hdc, nSurface, pdva))
  54. return FALSE;
  55. return InitSurface(pdva);
  56. }
  57. /****************************************************************************
  58. ***************************************************************************/
  59. BOOL CALLBACK default_open_surface(LPVOID pv)
  60. {
  61. return TRUE;
  62. }
  63. /****************************************************************************
  64. ***************************************************************************/
  65. void CALLBACK default_close_surface(LPVOID pv)
  66. {
  67. }
  68. /****************************************************************************
  69. ***************************************************************************/
  70. BOOL CALLBACK default_begin_access(LPVOID pv, int x, int y, int dx, int dy)
  71. {
  72. return TRUE;
  73. }
  74. /****************************************************************************
  75. ***************************************************************************/
  76. void CALLBACK default_end_access(LPVOID pv)
  77. {
  78. }
  79. /****************************************************************************
  80. ***************************************************************************/
  81. UINT CALLBACK default_show_surface(LPVOID pv, HWND hwnd, LPRECT src, LPRECT dst)
  82. {
  83. return 1;
  84. }
  85. /****************************************************************************
  86. ***************************************************************************/
  87. static BOOL InitSurface(DVASURFACEINFO FAR *pdva)
  88. {
  89. LPBITMAPINFOHEADER lpbi;
  90. if (pdva->Version != 0x0100)
  91. return FALSE;
  92. lpbi = &pdva->BitmapInfo;
  93. if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  94. return FALSE;
  95. if (lpbi->biPlanes != 1)
  96. return FALSE;
  97. //
  98. // make the pointer a 16:16 pointer
  99. //
  100. if (pdva->offSurface >= 0x10000 &&
  101. !(pdva->Flags & DVAF_1632_ACCESS))
  102. {
  103. if (ScreenSel == NULL)
  104. ScreenSel = AllocSelector(GetDS());
  105. if (pdva->selSurface != 0)
  106. pdva->offSurface += GetSelectorBase(pdva->selSurface);
  107. SetSelectorBase(ScreenSel,pdva->offSurface);
  108. SetSelLimit(ScreenSel,lpbi->biSizeImage-1);
  109. pdva->offSurface = 0;
  110. pdva->selSurface = ScreenSel;
  111. }
  112. //
  113. // fill in defaults.
  114. //
  115. if (pdva->OpenSurface == NULL)
  116. pdva->OpenSurface = default_open_surface;
  117. if (pdva->CloseSurface == NULL)
  118. pdva->CloseSurface = default_close_surface;
  119. if (pdva->ShowSurface == NULL)
  120. pdva->ShowSurface = default_show_surface;
  121. if (pdva->BeginAccess == NULL)
  122. {
  123. pdva->BeginAccess = default_begin_access;
  124. pdva->EndAccess = default_end_access;
  125. }
  126. //
  127. // only test RGB surfaces.
  128. //
  129. if (lpbi->biCompression == 0 ||
  130. lpbi->biCompression == BI_BITFIELDS ||
  131. lpbi->biCompression == BI_1632)
  132. {
  133. if (!TestSurface(pdva))
  134. return FALSE;
  135. }
  136. //
  137. // set BI_1632 if needed
  138. //
  139. if (pdva->Flags & DVAF_1632_ACCESS)
  140. {
  141. lpbi->biCompression = BI_1632;
  142. }
  143. return TRUE;
  144. }
  145. /****************************************************************************
  146. ***************************************************************************/
  147. #pragma optimize("", off)
  148. static void SetSelLimit(UINT sel, DWORD limit)
  149. {
  150. if (limit >= 1024*1024l)
  151. limit = ((limit+4096) & ~4095) - 1;
  152. _asm
  153. {
  154. mov ax,0008h ; DPMI set limit
  155. mov bx,sel
  156. mov dx,word ptr limit[0]
  157. mov cx,word ptr limit[2]
  158. int 31h
  159. }
  160. }
  161. #pragma optimize("", on)
  162. /****************************************************************************
  163. ***************************************************************************/
  164. #define ASM66 _asm _emit 0x66 _asm
  165. #define DB _asm _emit
  166. #pragma optimize("", off)
  167. static BYTE ReadByte(PDVA pdva, LPVOID lpBits, DWORD dw)
  168. {
  169. BYTE b=42;
  170. DVABeginAccess(pdva, 0, 0, 1024, 1024);
  171. _asm {
  172. ASM66 xor bx,bx
  173. les bx,lpBits
  174. ASM66 add bx,word ptr dw
  175. mov ax,es
  176. ASM66 lsl ax,ax
  177. ASM66 cmp bx,ax
  178. ja exit
  179. DB 26h ;mov al,es:[ebx]
  180. DB 67h
  181. DB 8Ah
  182. DB 03h
  183. mov b,al
  184. exit:
  185. }
  186. DVAEndAccess(pdva);
  187. return b;
  188. }
  189. #pragma optimize("", on)
  190. /////////////////////////////////////////////////////////////////////////////
  191. //
  192. // SetPixel
  193. //
  194. // some cards cant't seam to do SetPixel right it is amazing they work at all
  195. //
  196. /////////////////////////////////////////////////////////////////////////////
  197. static void SetPixelX(HDC hdc, int x, int y, COLORREF rgb)
  198. {
  199. RECT rc;
  200. rc.left = x;
  201. rc.top = y;
  202. rc.right = x+1;
  203. rc.bottom = y+1;
  204. SetBkColor(hdc, rgb);
  205. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
  206. }
  207. #define SetPixel SetPixelX
  208. /****************************************************************************
  209. ***************************************************************************/
  210. static BOOL TestSurface(DVASURFACEINFO FAR *pdva)
  211. {
  212. HDC hdc;
  213. int x,y,h,w,wb;
  214. COLORREF rgb,rgb0,rgb1,rgb2,rgb3,rgb4;
  215. DWORD dw;
  216. BYTE b0,b1;
  217. UINT uType=0;
  218. LPBITMAPINFOHEADER lpbi;
  219. LPVOID lpBits;
  220. HCURSOR hcur;
  221. if (!pdva->OpenSurface(pdva->lpSurface))
  222. return FALSE;
  223. lpbi = DVAGetSurfaceFmt(pdva);
  224. lpBits = DVAGetSurfacePtr(pdva);
  225. h = abs((int)lpbi->biHeight);
  226. w = (int)lpbi->biWidth;
  227. wb = (w * ((UINT)lpbi->biBitCount/8) + 3) & ~3;
  228. dw = (DWORD)(UINT)(h-1) * (DWORD)(UINT)wb;
  229. if ((int)lpbi->biHeight < 0)
  230. y = 0;
  231. else
  232. y = h-1;
  233. #ifdef XDEBUG
  234. x = (int)lpbi->biWidth - 5;
  235. ((LPBYTE)lpBits) += x * (UINT)lpbi->biBitCount/8;
  236. #else
  237. x = 0;
  238. #endif
  239. hcur = SetCursor(NULL);
  240. hdc = GetDC(NULL);
  241. rgb = GetPixel(hdc, x, h-1-y);
  242. SetPixel(hdc, x, h-1-y, RGB(0,0,0)); GetPixel(hdc, x, h-1-y); b0 = ReadByte(pdva, lpBits, dw);
  243. SetPixel(hdc, x, h-1-y, RGB(255,255,255)); GetPixel(hdc, x, h-1-y); b1 = ReadByte(pdva, lpBits, dw);
  244. SetPixel(hdc, x, h-1-y,rgb);
  245. if (b0 != 0x00 || b1 == 0x00)
  246. goto done;
  247. rgb0 = GetPixel(hdc, x+0, y);
  248. rgb1 = GetPixel(hdc, x+1, y);
  249. rgb2 = GetPixel(hdc, x+2, y);
  250. rgb3 = GetPixel(hdc, x+3, y);
  251. rgb4 = GetPixel(hdc, x+4, y);
  252. TestSurfaceType(hdc, x, y);
  253. DVABeginAccess(pdva, x, y, 5, 1);
  254. uType = GetSurfaceType(lpBits);
  255. DVAEndAccess(pdva);
  256. SetPixel(hdc, x+0, y,rgb0);
  257. SetPixel(hdc, x+1, y,rgb1);
  258. SetPixel(hdc, x+2, y,rgb2);
  259. SetPixel(hdc, x+3, y,rgb3);
  260. SetPixel(hdc, x+4, y,rgb4);
  261. done:
  262. ReleaseDC(NULL, hdc);
  263. SetCursor(hcur);
  264. pdva->CloseSurface(pdva->lpSurface);
  265. switch (uType)
  266. {
  267. case BM_8BIT:
  268. break;
  269. case BM_16555:
  270. ((LPDWORD)(lpbi+1))[0] = 0x007C00;
  271. ((LPDWORD)(lpbi+1))[1] = 0x0003E0;
  272. ((LPDWORD)(lpbi+1))[2] = 0x00001F;
  273. break;
  274. case BM_24BGR:
  275. case BM_32BGR:
  276. ((LPDWORD)(lpbi+1))[0] = 0xFF0000;
  277. ((LPDWORD)(lpbi+1))[1] = 0x00FF00;
  278. ((LPDWORD)(lpbi+1))[2] = 0x0000FF;
  279. break;
  280. case BM_16565:
  281. lpbi->biCompression = BI_BITFIELDS;
  282. ((LPDWORD)(lpbi+1))[0] = 0x00F800;
  283. ((LPDWORD)(lpbi+1))[1] = 0x0007E0;
  284. ((LPDWORD)(lpbi+1))[2] = 0x00001F;
  285. break;
  286. case BM_24RGB:
  287. case BM_32RGB:
  288. lpbi->biCompression = BI_BITFIELDS;
  289. ((LPDWORD)(lpbi+1))[0] = 0x0000FF;
  290. ((LPDWORD)(lpbi+1))[1] = 0x00FF00;
  291. ((LPDWORD)(lpbi+1))[2] = 0xFF0000;
  292. break;
  293. }
  294. return uType != 0;
  295. }
  296. /****************************************************************************
  297. map DCI escapes to old DVA stuff.
  298. ***************************************************************************/
  299. UINT CALLBACK dci_begin_access(DCISURFACEINFO FAR *pdci, RECT FAR *prc)
  300. {
  301. DVASURFACEINFO FAR *pdva = (DVASURFACEINFO FAR *)pdci->dwReserved1;
  302. if (pdva->BeginAccess(pdva->lpSurface,prc->left,prc->top,prc->right-prc->left,prc->bottom-prc->top))
  303. return 0;
  304. else
  305. return (UINT)-1;
  306. }
  307. void CALLBACK dci_end_access(DCISURFACEINFO FAR *pdci)
  308. {
  309. DVASURFACEINFO FAR *pdva = (DVASURFACEINFO FAR *)pdci->dwReserved1;
  310. pdva->EndAccess(pdva->lpSurface);
  311. }
  312. void CALLBACK dci_destroy(DCISURFACEINFO FAR *pdci)
  313. {
  314. DVASURFACEINFO FAR *pdva = (DVASURFACEINFO FAR *)pdci->dwReserved1;
  315. pdva->CloseSurface(pdva->lpSurface);
  316. }
  317. LONG DVAEscape(HDC hdc, UINT function, UINT size, LPVOID lp_in_data, LPVOID lp_out_data)
  318. {
  319. DCICMD FAR *pcmd;
  320. static DVASURFACEINFO dva;
  321. static DCISURFACEINFO dci;
  322. switch (function)
  323. {
  324. case QUERYESCSUPPORT:
  325. switch (*((UINT FAR *)lp_in_data))
  326. {
  327. case QUERYESCSUPPORT:
  328. return TRUE;
  329. case DCICOMMAND:
  330. return TRUE;
  331. default:
  332. return FALSE;
  333. }
  334. case DCICOMMAND:
  335. pcmd = (DCICMD FAR *)lp_in_data;
  336. switch (pcmd->dwCommand)
  337. {
  338. case DCICREATEPRIMARYSURFACE:
  339. if (!DVAGetSurface(hdc, 0, &dva))
  340. return DCI_FAIL_UNSUPPORTED;
  341. dci.dwSize = sizeof(dci);
  342. dci.dwDCICaps = DCI_PRIMARY | DCI_VISIBLE | DCI_1632_ACCESS;
  343. dci.dwCompression = dva.BitmapInfo.biCompression;
  344. dci.dwMask[0] = dva.dwMask[0];
  345. dci.dwMask[1] = dva.dwMask[1];
  346. dci.dwMask[2] = dva.dwMask[2];
  347. dci.dwWidth = dva.BitmapInfo.biWidth;
  348. dci.dwHeight = abs(dva.BitmapInfo.biHeight);
  349. dci.dwBitCount = dva.BitmapInfo.biBitCount;
  350. dci.lStride = dci.dwWidth * dci.dwBitCount / 8;
  351. dci.dwOffSurface = dva.offSurface;
  352. dci.wSelSurface = dva.selSurface;
  353. dci.wReserved = 0;
  354. dci.dwReserved1 = (DWORD)(LPVOID)&dva;
  355. dci.dwReserved2 = 0;
  356. dci.dwReserved3 = 0;
  357. dci.BeginAccess = dci_begin_access;
  358. dci.EndAccess = dci_end_access;
  359. dci.DestroySurface = dci_destroy;
  360. *((DCISURFACEINFO FAR * FAR *)lp_out_data) = &dci;
  361. return DCI_OK;
  362. default:
  363. return DCI_FAIL_UNSUPPORTED;
  364. }
  365. }
  366. return -1;
  367. }