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.

1053 lines
33 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: wgl.c
  3. *
  4. * Routines to integrate Windows NT and OpenGL.
  5. *
  6. * Created: 10-26-1993
  7. * Author: Hock San Lee [hockl]
  8. *
  9. * Copyright (c) 1993 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include <wingdip.h>
  14. #include <glscreen.h>
  15. #include <glgenwin.h>
  16. #include "batchinf.h"
  17. #include "glapi.h"
  18. #include "glsbcltu.h"
  19. #include "wgldef.h"
  20. #include "metasup.h"
  21. #include "glclt.h"
  22. #include "gencx.h"
  23. #include "context.h"
  24. #include "global.h"
  25. #include "mcdcx.h"
  26. // Static functions prototypes
  27. static PROC pfnGenGlExtProc(LPCSTR lpszProc);
  28. static PROC pfnSimGlExtProc(LPCSTR lpszProc);
  29. /******************************Public*Routine******************************\
  30. *
  31. * wglObjectType
  32. *
  33. * Returns GetObjectType result with the exception that
  34. * metafile-spooled printer DC's come back as metafile objects
  35. *
  36. * History:
  37. * Fri Jun 16 12:10:07 1995 -by- Drew Bliss [drewb]
  38. * Created
  39. *
  40. \**************************************************************************/
  41. DWORD APIENTRY wglObjectType(HDC hdc)
  42. {
  43. DWORD dwObjectType;
  44. dwObjectType = GetObjectType(hdc);
  45. #ifdef GL_METAFILE
  46. if (dwObjectType == OBJ_DC &&
  47. pfnGdiIsMetaPrintDC != NULL &&
  48. GlGdiIsMetaPrintDC(hdc))
  49. {
  50. dwObjectType = OBJ_ENHMETADC;
  51. }
  52. #endif
  53. // OBJ_DDRAW is reserved as a special identifier. Make sure
  54. // we aren't returning it from here.
  55. ASSERTOPENGL(dwObjectType != OBJ_DDRAW,
  56. "Unexpected object type\n");
  57. return dwObjectType;
  58. }
  59. /******************************Public*Routine******************************\
  60. * wglDeleteContext(HGLRC hrc)
  61. *
  62. * Delete the rendering context
  63. *
  64. * Arguments:
  65. * hrc - Rendering context.
  66. *
  67. * History:
  68. * Tue Oct 26 10:25:26 1993 -by- Hock San Lee [hockl]
  69. * Rewrote it.
  70. \**************************************************************************/
  71. BOOL WINAPI wglDeleteContext(HGLRC hrc)
  72. {
  73. PLHE plheRC;
  74. ULONG irc;
  75. PLRC plrc;
  76. BOOL bRet = FALSE;
  77. DBGENTRY("wglDeleteContext\n");
  78. // Flush OpenGL calls.
  79. GLFLUSH();
  80. // Validate the RC.
  81. if (cLockHandle((ULONG_PTR)hrc) <= 0)
  82. {
  83. DBGLEVEL1(LEVEL_ERROR, "wglDeleteContext: can't lock hrc 0x%lx\n", hrc);
  84. return(bRet);
  85. }
  86. irc = MASKINDEX(hrc);
  87. plheRC = pLocalTable + irc;
  88. plrc = (PLRC) plheRC->pv;
  89. ASSERTOPENGL(plrc->ident == LRC_IDENTIFIER, "wglDeleteContext: Bad plrc\n");
  90. DBGLEVEL2(LEVEL_INFO, "wglDeleteContext: hrc: 0x%lx, plrc: 0x%lx\n", hrc, plrc);
  91. if (plrc->tidCurrent != INVALID_THREAD_ID)
  92. {
  93. // The RC must be current to this thread because makecurrent locks
  94. // down the handle.
  95. ASSERTOPENGL(plrc->tidCurrent == GetCurrentThreadId(),
  96. "wglDeleteCurrent: hrc is current to another thread\n");
  97. // Make the RC inactive first.
  98. if (!bMakeNoCurrent())
  99. {
  100. DBGERROR("wglDeleteCurrent: bMakeNoCurrent failed\n");
  101. }
  102. }
  103. if (plrc->dhrc)
  104. {
  105. // If it is a device format, call the driver to delete its context.
  106. bRet = plrc->pGLDriver->pfnDrvDeleteContext(plrc->dhrc);
  107. plrc->dhrc = (DHGLRC) 0;
  108. }
  109. else
  110. {
  111. #ifdef GL_METAFILE
  112. // If we have metafile state, clean it up
  113. if (plrc->uiGlsCaptureContext != 0 ||
  114. plrc->uiGlsPlaybackContext != 0)
  115. {
  116. DeleteMetaRc(plrc);
  117. }
  118. #endif
  119. // If it is a generic format, call the server to delete its context.
  120. bRet = __wglDeleteContext((HANDLE) plheRC->hgre);
  121. }
  122. // Always clean up local objects.
  123. vFreeLRC(plrc);
  124. vFreeHandle(irc); // it unlocks handle too
  125. if (!bRet)
  126. DBGERROR("wglDeleteContext failed\n");
  127. return(bRet);
  128. }
  129. /******************************Public*Routine******************************\
  130. * wglGetCurrentContext(VOID)
  131. *
  132. * Return the current rendering context
  133. *
  134. * Arguments:
  135. * None
  136. *
  137. * Returns:
  138. * hrc - Rendering context.
  139. *
  140. * History:
  141. * Tue Oct 26 10:25:26 1993 -by- Hock San Lee [hockl]
  142. * Wrote it.
  143. \**************************************************************************/
  144. HGLRC WINAPI wglGetCurrentContext(VOID)
  145. {
  146. DBGENTRY("wglGetCurrentContext\n");
  147. if (GLTEB_CLTCURRENTRC())
  148. return(GLTEB_CLTCURRENTRC()->hrc);
  149. else
  150. return((HGLRC) 0);
  151. }
  152. /******************************Public*Routine******************************\
  153. * wglGetCurrentDC(VOID)
  154. *
  155. * Return the device context that is associated with the current rendering
  156. * context
  157. *
  158. * Arguments:
  159. * None
  160. *
  161. * Returns:
  162. * hdc - device context.
  163. *
  164. * History:
  165. * Mon Jan 31 12:15:12 1994 -by- Hock San Lee [hockl]
  166. * Wrote it.
  167. \**************************************************************************/
  168. HDC WINAPI wglGetCurrentDC(VOID)
  169. {
  170. PLRC plrc;
  171. DBGENTRY("wglGetCurrentDC\n");
  172. plrc = GLTEB_CLTCURRENTRC();
  173. if (plrc != NULL)
  174. {
  175. return plrc->gwidCurrent.hdc;
  176. }
  177. else
  178. {
  179. return((HDC) 0);
  180. }
  181. }
  182. /******************************Public*Routine******************************\
  183. * wglUseFontBitmapsA
  184. * wglUseFontBitmapsW
  185. *
  186. * Stubs that call wglUseFontBitmapsAW with the bUnicode flag set
  187. * appropriately.
  188. *
  189. * History:
  190. * 11-Mar-1994 gilmanw
  191. * Changed to call wglUseFontBitmapsAW.
  192. *
  193. * 17-Dec-1993 -by- Gilman Wong [gilmanw]
  194. * Wrote it.
  195. \**************************************************************************/
  196. BOOL WINAPI wglUseFontBitmapsAW(HDC hdc, DWORD first, DWORD count,
  197. DWORD listBase, BOOL bUnicode);
  198. BOOL WINAPI
  199. wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, DWORD listBase)
  200. {
  201. return wglUseFontBitmapsAW(hdc, first, count, listBase, FALSE);
  202. }
  203. BOOL WINAPI
  204. wglUseFontBitmapsW(HDC hdc, DWORD first, DWORD count, DWORD listBase)
  205. {
  206. return wglUseFontBitmapsAW(hdc, first, count, listBase, TRUE);
  207. }
  208. /******************************Public*Routine******************************\
  209. * wglUseFontBitmapsAW
  210. *
  211. * Uses the current font in the specified DC to generate a series of OpenGL
  212. * display lists, each of which consists of a glyph bitmap.
  213. *
  214. * Each glyph bitmap is generated by calling ExtTextOut to draw the glyph
  215. * into a memory DC. The contents of the memory DC are then copied into
  216. * a buffer by GetDIBits and then put into the OpenGL display list.
  217. *
  218. * ABC spacing is used (if GetCharABCWidth() is supported by the font) to
  219. * determine proper placement of the glyph origin and character advance width.
  220. * Otherwise, A = C = 0 spacing is assumed and GetCharWidth() is used for the
  221. * advance widths.
  222. *
  223. * Returns:
  224. *
  225. * TRUE if successful, FALSE otherwise.
  226. *
  227. * History:
  228. * 17-Dec-1993 -by- Gilman Wong [gilmanw]
  229. * Wrote it.
  230. \**************************************************************************/
  231. BOOL WINAPI
  232. wglUseFontBitmapsAW(
  233. HDC hdc, // use HFONT from this DC
  234. DWORD first, // generate glyphs starting with this Unicode codepoint
  235. DWORD count, // range is this long [first, first+count-1]
  236. DWORD listBase, // starting display list number
  237. BOOL bUnicode // TRUE for if in Unicode mode, FALSE if in Ansi mode
  238. )
  239. {
  240. BOOL bRet = FALSE; // return value
  241. HDC hdcMem; // render glyphs to this memory DC
  242. HBITMAP hbm; // monochrome bitmap for memory DC
  243. LPABC pabc, pabcTmp, pabcEnd; // array of ABC spacing
  244. LPINT piWidth, piTmp, piWidthEnd; // array of char adv. widths
  245. WCHAR wc; // current Unicode char to render
  246. RECT rc; // background rectangle to clear
  247. TEXTMETRICA tm; // metrics of the font
  248. BOOL bTrueType; // TrueType supports ABC spacing
  249. int iMaxWidth = 1; // maximum glyph width
  250. int iBitmapWidth; // DWORD aligned bitmap width
  251. BYTE ajBmi[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
  252. BITMAPINFO *pbmi = (BITMAPINFO *)ajBmi;// bitmap info for GetDIBits
  253. GLint iUnpackRowLength; // save GL_UNPACK_ROW_LENGTH
  254. GLint iUnpackAlign; // save GL_UNPACK_ALIGNMENT
  255. PVOID pv; // pointer to glyph bitmap buffer
  256. // Return error if there is no current RC.
  257. if (!GLTEB_CLTCURRENTRC())
  258. {
  259. WARNING("wglUseFontBitmapsAW: no current RC\n");
  260. SetLastError(ERROR_INVALID_HANDLE);
  261. return bRet;
  262. }
  263. // Get TEXTMETRIC. The only fields used are those that are invariant with
  264. // respect to Unicode vs. ANSI. Therefore, we can call GetTextMetricsA for
  265. // both cases.
  266. if ( !GetTextMetricsA(hdc, &tm) )
  267. {
  268. WARNING("wglUseFontBitmapsAW: GetTextMetricsA failed\n");
  269. return bRet;
  270. }
  271. // If its a TrueType font, we can get ABC spacing.
  272. if ( bTrueType = (tm.tmPitchAndFamily & TMPF_TRUETYPE) )
  273. {
  274. // Allocate memory for array of ABC data.
  275. if ( (pabc = (LPABC) ALLOC(sizeof(ABC) * count)) == (LPABC) NULL )
  276. {
  277. WARNING("wglUseFontBitmapsAW: Alloc of pabc failed\n");
  278. return bRet;
  279. }
  280. // Get ABC metrics.
  281. if ( bUnicode )
  282. {
  283. if ( !GetCharABCWidthsW(hdc, first, first + count - 1, pabc) )
  284. {
  285. WARNING("wglUseFontBitmapsAW: GetCharABCWidthsW failed\n");
  286. FREE(pabc);
  287. return bRet;
  288. }
  289. }
  290. else
  291. {
  292. if ( !GetCharABCWidthsA(hdc, first, first + count - 1, pabc) )
  293. {
  294. WARNING("wglUseFontBitmapsAW: GetCharABCWidthsA failed\n");
  295. FREE(pabc);
  296. return bRet;
  297. }
  298. }
  299. // Find max glyph width.
  300. for (pabcTmp = pabc, pabcEnd = pabc + count;
  301. pabcTmp < pabcEnd;
  302. pabcTmp++)
  303. {
  304. if (iMaxWidth < (int) pabcTmp->abcB)
  305. iMaxWidth = pabcTmp->abcB;
  306. }
  307. }
  308. // Otherwise we will have to use just the advance width and assume
  309. // A = C = 0.
  310. else
  311. {
  312. // Allocate memory for array of ABC data.
  313. if ( (piWidth = (LPINT) ALLOC(sizeof(INT) * count)) == (LPINT) NULL )
  314. {
  315. WARNING("wglUseFontBitmapsAW: Alloc of pabc failed\n");
  316. return bRet;
  317. }
  318. // Get char widths.
  319. if ( bUnicode )
  320. {
  321. if ( !GetCharWidthW(hdc, first, first + count - 1, piWidth) )
  322. {
  323. WARNING("wglUseFontBitmapsAW: GetCharWidthW failed\n");
  324. FREE(piWidth);
  325. return bRet;
  326. }
  327. }
  328. else
  329. {
  330. if ( !GetCharWidthA(hdc, first, first + count - 1, piWidth) )
  331. {
  332. WARNING("wglUseFontBitmapsAW: GetCharWidthA failed\n");
  333. FREE(piWidth);
  334. return bRet;
  335. }
  336. }
  337. // Find max glyph width.
  338. for (piTmp = piWidth, piWidthEnd = piWidth + count;
  339. piTmp < piWidthEnd;
  340. piTmp++)
  341. {
  342. if (iMaxWidth < *piTmp)
  343. iMaxWidth = *piTmp;
  344. }
  345. }
  346. // Compute the dword aligned width. Bitmap scanlines must be aligned.
  347. iBitmapWidth = (iMaxWidth + 31) & -32;
  348. // Allocate memory for the DIB.
  349. if ( (pv = (PVOID)
  350. ALLOC((iBitmapWidth / 8) * tm.tmHeight)) == (PVOID) NULL )
  351. {
  352. WARNING("wglUseFontBitmapsAW: Alloc of pv failed\n");
  353. (bTrueType) ? FREE(pabc) : FREE(piWidth);
  354. return bRet;
  355. }
  356. // Create compatible DC/bitmap big enough to accomodate the biggest glyph
  357. // in the range requested.
  358. hdcMem = CreateCompatibleDC(hdc);
  359. if ( (hbm = CreateBitmap(iBitmapWidth, tm.tmHeight, 1, 1, (VOID *) NULL)) == (HBITMAP) NULL )
  360. {
  361. WARNING("wglUseFontBitmapsAW: CreateBitmap failed\n");
  362. (bTrueType) ? FREE(pabc) : FREE(piWidth);
  363. FREE(pv);
  364. DeleteDC(hdcMem);
  365. return bRet;
  366. }
  367. SelectObject(hdcMem, hbm);
  368. SelectObject(hdcMem, GetCurrentObject(hdc, OBJ_FONT));
  369. SetMapMode(hdcMem, MM_TEXT);
  370. SetTextAlign(hdcMem, TA_TOP | TA_LEFT);
  371. SetBkColor(hdcMem, RGB(0, 0, 0));
  372. SetBkMode(hdcMem, OPAQUE);
  373. SetTextColor(hdcMem, RGB(255, 255, 255));
  374. // Setup bitmap info header to retrieve a DIB from the compatible bitmap.
  375. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  376. pbmi->bmiHeader.biWidth = iBitmapWidth;
  377. pbmi->bmiHeader.biHeight = tm.tmHeight;
  378. pbmi->bmiHeader.biPlanes = 1;
  379. pbmi->bmiHeader.biBitCount = 1;
  380. pbmi->bmiHeader.biCompression = BI_RGB;
  381. pbmi->bmiHeader.biSizeImage = 0;
  382. pbmi->bmiHeader.biXPelsPerMeter = 0;
  383. pbmi->bmiHeader.biYPelsPerMeter = 0;
  384. pbmi->bmiHeader.biClrUsed = 0;
  385. pbmi->bmiHeader.biClrImportant = 0;
  386. pbmi->bmiColors[0].rgbRed = 0;
  387. pbmi->bmiColors[0].rgbGreen = 0;
  388. pbmi->bmiColors[0].rgbBlue = 0;
  389. pbmi->bmiColors[1].rgbRed = 0xff;
  390. pbmi->bmiColors[1].rgbGreen = 0xff;
  391. pbmi->bmiColors[1].rgbBlue = 0xff;
  392. // Setup OpenGL to accept our bitmap format.
  393. glGetIntegerv(GL_UNPACK_ROW_LENGTH, &iUnpackRowLength);
  394. glGetIntegerv(GL_UNPACK_ALIGNMENT, &iUnpackAlign);
  395. if (glGetError() != GL_NO_ERROR)
  396. {
  397. //XXX too noisy on debug builds running stress with mode changes
  398. //WARNING("wglUseFontBitmapsAW: failed to get GL state\n");
  399. goto wglUseFontBitmapsAW_exit;
  400. }
  401. glPixelStorei(GL_UNPACK_ROW_LENGTH, iBitmapWidth);
  402. if (glGetError() != GL_NO_ERROR)
  403. {
  404. //XXX too noisy on debug builds running stress with mode changes
  405. //WARNING("wglUseFontBitmapsAW: failed to set GL state, row length\n");
  406. goto wglUseFontBitmapsAW_restore_state;
  407. }
  408. glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  409. if (glGetError() != GL_NO_ERROR)
  410. {
  411. //XXX too noisy on debug builds running stress with mode changes
  412. //WARNING("wglUseFontBitmapsAW: failed to set GL state, alignment\n");
  413. goto wglUseFontBitmapsAW_restore_state;
  414. }
  415. // Get the glyphs. Each glyph is rendered one at a time into the the
  416. // memory DC with ExtTextOutW (notice that the optional rectangle is
  417. // used to clear the background). Each glyph is then copied out of the
  418. // memory DC's bitmap with GetDIBits into a buffer. This buffer is passed
  419. // to glBitmap as each display list is created.
  420. rc.left = 0;
  421. rc.top = 0;
  422. rc.right = iBitmapWidth;
  423. rc.bottom = tm.tmHeight;
  424. pabcTmp = pabc;
  425. piTmp = piWidth;
  426. for (wc = (WCHAR) first; wc < (WCHAR) (first + count); wc++, listBase++)
  427. {
  428. if ( bUnicode )
  429. {
  430. if ( !ExtTextOutW(hdcMem, bTrueType ? -pabcTmp->abcA : 0, 0, ETO_OPAQUE, &rc, &wc, 1, (INT *) NULL) ||
  431. !GetDIBits(hdcMem, hbm, 0, tm.tmHeight, pv, pbmi, DIB_RGB_COLORS) )
  432. {
  433. WARNING("wglUseFontBitmapsAW: failed to render glyph\n");
  434. goto wglUseFontBitmapsAW_restore_state;
  435. }
  436. }
  437. else
  438. {
  439. if ( !ExtTextOutA(hdcMem, bTrueType ? -pabcTmp->abcA : 0, 0, ETO_OPAQUE, &rc, (LPCSTR) &wc, 1, (INT *) NULL) ||
  440. !GetDIBits(hdcMem, hbm, 0, tm.tmHeight, pv, pbmi, DIB_RGB_COLORS) )
  441. {
  442. WARNING("wglUseFontBitmapsAW: failed to render glyph\n");
  443. goto wglUseFontBitmapsAW_restore_state;
  444. }
  445. }
  446. glNewList(listBase, GL_COMPILE);
  447. glBitmap((GLsizei) iBitmapWidth,
  448. (GLsizei) tm.tmHeight,
  449. (GLfloat) (bTrueType ? -pabcTmp->abcA : 0),
  450. (GLfloat) tm.tmDescent,
  451. (GLfloat) (bTrueType ? (pabcTmp->abcA + pabcTmp->abcB + pabcTmp->abcC) : *piTmp),
  452. (GLfloat) 0.0,
  453. (GLubyte *) pv);
  454. glEndList();
  455. if (bTrueType)
  456. pabcTmp++;
  457. else
  458. piTmp++;
  459. }
  460. // We can finally return success.
  461. bRet = TRUE;
  462. // Free resources.
  463. wglUseFontBitmapsAW_restore_state:
  464. glPixelStorei(GL_UNPACK_ROW_LENGTH, iUnpackRowLength);
  465. glPixelStorei(GL_UNPACK_ALIGNMENT, iUnpackAlign);
  466. wglUseFontBitmapsAW_exit:
  467. (bTrueType) ? FREE(pabc) : FREE(piWidth);
  468. FREE(pv);
  469. DeleteDC(hdcMem);
  470. DeleteObject(hbm);
  471. return bRet;
  472. }
  473. /******************************Public*Routine******************************\
  474. *
  475. * wglShareLists
  476. *
  477. * Allows a rendering context to share the display lists of another RC
  478. *
  479. * Returns:
  480. * TRUE if successful, FALSE otherwise
  481. *
  482. * History:
  483. * Tue Dec 13 14:57:17 1994 -by- Drew Bliss [drewb]
  484. * Created
  485. *
  486. \**************************************************************************/
  487. BOOL WINAPI
  488. wglShareLists(HGLRC hrcSource, HGLRC hrcShare)
  489. {
  490. BOOL fRet;
  491. PLRC plrcSource, plrcShare;
  492. ULONG irc;
  493. PLHE plheRC;
  494. HANDLE hrcSrvSource, hrcSrvShare;
  495. GLFLUSH();
  496. fRet = FALSE;
  497. // Validate the contexts
  498. if (cLockHandle((ULONG_PTR)hrcSource) <= 0)
  499. {
  500. DBGLEVEL1(LEVEL_ERROR, "wglShareLists: can't lock hrcSource 0x%lx\n",
  501. hrcSource);
  502. goto wglShareListsEnd_nolock;
  503. }
  504. irc = MASKINDEX(hrcSource);
  505. plheRC = pLocalTable + irc;
  506. plrcSource = (PLRC)plheRC->pv;
  507. hrcSrvSource = (HANDLE) plheRC->hgre;
  508. ASSERTOPENGL(plrcSource->ident == LRC_IDENTIFIER,
  509. "wglShareLists: Bad plrc\n");
  510. if (cLockHandle((ULONG_PTR)hrcShare) <= 0)
  511. {
  512. DBGLEVEL1(LEVEL_ERROR, "wglShareLists: can't lock hrcShare 0x%lx\n",
  513. hrcShare);
  514. goto wglShareListsEnd_onelock;
  515. }
  516. irc = MASKINDEX(hrcShare);
  517. plheRC = pLocalTable + irc;
  518. plrcShare = (PLRC)plheRC->pv;
  519. hrcSrvShare = (HANDLE) plheRC->hgre;
  520. ASSERTOPENGL(plrcShare->ident == LRC_IDENTIFIER,
  521. "wglShareLists: Bad plrc\n");
  522. #ifdef GL_METAFILE
  523. // Metafile RC's can't share lists to ensure that metafiles are
  524. // completely self-sufficient
  525. if (plrcSource->uiGlsCaptureContext != 0 ||
  526. plrcShare->uiGlsCaptureContext != 0 ||
  527. plrcSource->uiGlsPlaybackContext != 0 ||
  528. plrcShare->uiGlsPlaybackContext != 0)
  529. {
  530. DBGLEVEL(LEVEL_ERROR,
  531. "wglShareLists: Attempt to share metafile RC\n");
  532. SetLastError(ERROR_INVALID_HANDLE);
  533. goto wglShareListsEnd;
  534. }
  535. #endif
  536. // Lists can only be shared between like implementations so make
  537. // sure that both contexts are either driver contexts or generic
  538. // contexts
  539. if ((plrcSource->dhrc != 0) != (plrcShare->dhrc != 0))
  540. {
  541. DBGLEVEL(LEVEL_ERROR, "wglShareLists: mismatched implementations\n");
  542. SetLastError(ERROR_INVALID_FUNCTION);
  543. goto wglShareListsEnd;
  544. }
  545. if (plrcSource->dhrc == 0)
  546. {
  547. PIXELFORMATDESCRIPTOR *ppfdShare, *ppfdSource;
  548. // Fail sharing unless color parameters match for the two contexts
  549. ppfdShare = &((__GLGENcontext *)hrcSrvShare)->gsurf.pfd;
  550. ppfdSource = &((__GLGENcontext *)hrcSrvSource)->gsurf.pfd;
  551. if (ppfdShare->iPixelType != ppfdSource->iPixelType ||
  552. ppfdShare->cColorBits != ppfdSource->cColorBits ||
  553. ppfdShare->cRedBits != ppfdSource->cRedBits ||
  554. ppfdShare->cRedShift != ppfdSource->cRedShift ||
  555. ppfdShare->cGreenBits != ppfdSource->cGreenBits ||
  556. ppfdShare->cGreenShift != ppfdSource->cGreenShift ||
  557. ppfdShare->cBlueBits != ppfdSource->cBlueBits ||
  558. ppfdShare->cBlueShift != ppfdSource->cBlueShift ||
  559. ppfdShare->cAlphaBits != ppfdSource->cAlphaBits ||
  560. ppfdShare->cAlphaShift != ppfdSource->cAlphaShift ||
  561. (ppfdShare->dwFlags & PFD_GENERIC_ACCELERATED) !=
  562. (ppfdSource->dwFlags & PFD_GENERIC_ACCELERATED))
  563. {
  564. SetLastError(ERROR_INVALID_PIXEL_FORMAT);
  565. goto wglShareListsEnd;
  566. }
  567. // For generic contexts, tell the server to share the lists
  568. fRet = __wglShareLists(hrcSrvShare, hrcSrvSource);
  569. if (!fRet)
  570. {
  571. DBGERROR("wglShareLists: server call failed\n");
  572. }
  573. }
  574. else
  575. {
  576. // For device contexts tell the server to share the lists
  577. // Ensure that both implementations are the same
  578. if (plrcSource->pGLDriver != plrcShare->pGLDriver)
  579. {
  580. DBGLEVEL(LEVEL_ERROR, "wglShareLists: mismatched "
  581. "implementations\n");
  582. SetLastError(ERROR_INVALID_FUNCTION);
  583. goto wglShareListsEnd;
  584. }
  585. ASSERTOPENGL(plrcSource->pGLDriver != NULL,
  586. "wglShareLists: No GLDriver\n");
  587. // Older drivers may not support this entry point, so
  588. // fail the call if they don't
  589. if (plrcSource->pGLDriver->pfnDrvShareLists == NULL)
  590. {
  591. WARNING("wglShareLists called on driver context "
  592. "without driver support\n");
  593. SetLastError(ERROR_NOT_SUPPORTED);
  594. }
  595. else
  596. {
  597. fRet = plrcSource->pGLDriver->pfnDrvShareLists(plrcSource->dhrc,
  598. plrcShare->dhrc);
  599. }
  600. }
  601. wglShareListsEnd:
  602. vUnlockHandle((ULONG_PTR)hrcShare);
  603. wglShareListsEnd_onelock:
  604. vUnlockHandle((ULONG_PTR)hrcSource);
  605. wglShareListsEnd_nolock:
  606. return fRet;
  607. }
  608. /******************************Public*Routine******************************\
  609. *
  610. * wglGetDefaultProcAddress
  611. *
  612. * Returns generic extension functions for metafiling
  613. *
  614. * History:
  615. * Tue Nov 28 16:40:35 1995 -by- Drew Bliss [drewb]
  616. * Created
  617. *
  618. \**************************************************************************/
  619. PROC WINAPI wglGetDefaultProcAddress(LPCSTR lpszProc)
  620. {
  621. return pfnGenGlExtProc(lpszProc);
  622. }
  623. /******************************Public*Routine******************************\
  624. * wglGetProcAddress
  625. *
  626. * The wglGetProcAddress function returns the address of an OpenGL extension
  627. * function to be used with the current OpenGL rendering context.
  628. *
  629. * Arguments:
  630. * lpszProc - Points to a null-terminated string containing the function
  631. * name. The function must be an extension supported by the
  632. * implementation.
  633. *
  634. * Returns:
  635. * If the function succeeds, the return value is the address of the extension
  636. * function. If no current context exists or the function fails, the return
  637. * value is NULL. To get extended error information, call GetLastError.
  638. *
  639. * History:
  640. * Thu Dec 01 13:50:22 1994 -by- Hock San Lee [hockl]
  641. * Wrote it.
  642. \**************************************************************************/
  643. PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
  644. {
  645. PLRC plrc = GLTEB_CLTCURRENTRC();
  646. DBGENTRY("wglGetProcAddress\n");
  647. // Flush OpenGL calls.
  648. GLFLUSH();
  649. // Return error if there is no current RC.
  650. if (!plrc)
  651. {
  652. WARNING("wglGetProcAddress: no current RC\n");
  653. SetLastError(ERROR_INVALID_HANDLE);
  654. return((PROC) NULL);
  655. }
  656. // Handle generic RC.
  657. // Return the generic extension function entry point
  658. if (!plrc->dhrc)
  659. return(pfnGenGlExtProc(lpszProc));
  660. // Handle driver RC.
  661. // There are 3 cases:
  662. // 1. New drivers that support DrvGetProcAddress.
  663. // 2. Old drivers that don't support DrvGetProcAddress but export the function
  664. // 3. If we fail to obtain a function address in 1 and 2, it may still be
  665. // simulated by the generic implemenation for the driver
  666. // (e.g. glDrawArraysEXT). Return the simulated entry point if found.
  667. if (plrc->pGLDriver->pfnDrvGetProcAddress)
  668. {
  669. // Case 1
  670. PROC pfn = plrc->pGLDriver->pfnDrvGetProcAddress(lpszProc);
  671. if (pfn)
  672. return(pfn);
  673. }
  674. #ifdef OBSOLETE
  675. else
  676. {
  677. // Case 2
  678. PROC pfn = GetProcAddress(plrc->pGLDriver->hModule, lpszProc);
  679. if (pfn)
  680. return(pfn);
  681. }
  682. #endif
  683. // Case 3
  684. return (pfnSimGlExtProc(lpszProc));
  685. }
  686. /******************************Public*Routine******************************\
  687. * pfnGenGlExtProc
  688. *
  689. * Return the generic implementation extension function address.
  690. *
  691. * Returns NULL if the function is not found.
  692. *
  693. * History:
  694. * Thu Dec 01 13:50:22 1994 -by- Hock San Lee [hockl]
  695. * Wrote it.
  696. \**************************************************************************/
  697. typedef struct _GLEXTPROC {
  698. LPCSTR szProc; // extension function name
  699. PROC Proc; // extension function address
  700. } GLEXTPROC, *PGLEXTPROC;
  701. // Extension functions supported by the generic implementation
  702. // See also genglExtProcsSim for simulations.
  703. // NOTE: remember to update GL_EXTENSIONS in glGetString.
  704. GLEXTPROC genglExtProcs[] =
  705. {
  706. { "glAddSwapHintRectWIN" , (PROC) glAddSwapHintRectWIN },
  707. { "glColorTableEXT" , (PROC) glColorTableEXT },
  708. { "glColorSubTableEXT" , (PROC) glColorSubTableEXT },
  709. { "glGetColorTableEXT" , (PROC) glGetColorTableEXT },
  710. { "glGetColorTableParameterivEXT", (PROC) glGetColorTableParameterivEXT},
  711. { "glGetColorTableParameterfvEXT", (PROC) glGetColorTableParameterfvEXT},
  712. { "glDrawRangeElementsWIN", (PROC) glDrawRangeElementsWIN},
  713. #ifdef GL_EXT_flat_paletted_lighting
  714. { "glColorTableParameterivEXT", (PROC) glColorTableParameterivEXT},
  715. { "glColorTableParameterfvEXT", (PROC) glColorTableParameterfvEXT},
  716. #endif // GL_EXT_flat_paletted_lighting
  717. #ifdef GL_WIN_multiple_textures
  718. { "glCurrentTextureIndexWIN", (PROC) glCurrentTextureIndexWIN },
  719. { "glMultiTexCoord1dWIN", (PROC) glMultiTexCoord1dWIN },
  720. { "glMultiTexCoord1dvWIN", (PROC) glMultiTexCoord1dvWIN },
  721. { "glMultiTexCoord1fWIN", (PROC) glMultiTexCoord1fWIN },
  722. { "glMultiTexCoord1fvWIN", (PROC) glMultiTexCoord1fvWIN },
  723. { "glMultiTexCoord1iWIN", (PROC) glMultiTexCoord1iWIN },
  724. { "glMultiTexCoord1ivWIN", (PROC) glMultiTexCoord1ivWIN },
  725. { "glMultiTexCoord1sWIN", (PROC) glMultiTexCoord1sWIN },
  726. { "glMultiTexCoord1svWIN", (PROC) glMultiTexCoord1svWIN },
  727. { "glMultiTexCoord2dWIN", (PROC) glMultiTexCoord2dWIN },
  728. { "glMultiTexCoord2dvWIN", (PROC) glMultiTexCoord2dvWIN },
  729. { "glMultiTexCoord2fWIN", (PROC) glMultiTexCoord2fWIN },
  730. { "glMultiTexCoord2fvWIN", (PROC) glMultiTexCoord2fvWIN },
  731. { "glMultiTexCoord2iWIN", (PROC) glMultiTexCoord2iWIN },
  732. { "glMultiTexCoord2ivWIN", (PROC) glMultiTexCoord2ivWIN },
  733. { "glMultiTexCoord2sWIN", (PROC) glMultiTexCoord2sWIN },
  734. { "glMultiTexCoord2svWIN", (PROC) glMultiTexCoord2svWIN },
  735. { "glMultiTexCoord3dWIN", (PROC) glMultiTexCoord3dWIN },
  736. { "glMultiTexCoord3dvWIN", (PROC) glMultiTexCoord3dvWIN },
  737. { "glMultiTexCoord3fWIN", (PROC) glMultiTexCoord3fWIN },
  738. { "glMultiTexCoord3fvWIN", (PROC) glMultiTexCoord3fvWIN },
  739. { "glMultiTexCoord3iWIN", (PROC) glMultiTexCoord3iWIN },
  740. { "glMultiTexCoord3ivWIN", (PROC) glMultiTexCoord3ivWIN },
  741. { "glMultiTexCoord3sWIN", (PROC) glMultiTexCoord3sWIN },
  742. { "glMultiTexCoord3svWIN", (PROC) glMultiTexCoord3svWIN },
  743. { "glMultiTexCoord4dWIN", (PROC) glMultiTexCoord4dWIN },
  744. { "glMultiTexCoord4dvWIN", (PROC) glMultiTexCoord4dvWIN },
  745. { "glMultiTexCoord4fWIN", (PROC) glMultiTexCoord4fWIN },
  746. { "glMultiTexCoord4fvWIN", (PROC) glMultiTexCoord4fvWIN },
  747. { "glMultiTexCoord4iWIN", (PROC) glMultiTexCoord4iWIN },
  748. { "glMultiTexCoord4ivWIN", (PROC) glMultiTexCoord4ivWIN },
  749. { "glMultiTexCoord4sWIN", (PROC) glMultiTexCoord4sWIN },
  750. { "glMultiTexCoord4svWIN", (PROC) glMultiTexCoord4svWIN },
  751. { "glBindNthTextureWIN", (PROC) glBindNthTextureWIN },
  752. { "glNthTexCombineFuncWIN", (PROC) glNthTexCombineFuncWIN },
  753. #endif // GL_WIN_multiple_textures
  754. };
  755. static PROC pfnGenGlExtProc(LPCSTR lpszProc)
  756. {
  757. CONST CHAR *pch1, *pch2;
  758. int i;
  759. DBGENTRY("pfnGenGlExtProc\n");
  760. // Return extension function address if it is found.
  761. for (i = 0; i < sizeof(genglExtProcs) / sizeof(genglExtProcs[0]); i++)
  762. {
  763. // Compare names.
  764. for (pch1 = lpszProc, pch2 = genglExtProcs[i].szProc;
  765. *pch1 == *pch2 && *pch1;
  766. pch1++, pch2++)
  767. ;
  768. // If found, return the address.
  769. if (*pch1 == *pch2 && !*pch1)
  770. return genglExtProcs[i].Proc;
  771. }
  772. // Extension is not supported by the generic implementation, return NULL.
  773. SetLastError(ERROR_PROC_NOT_FOUND);
  774. return((PROC) NULL);
  775. }
  776. /******************************Public*Routine******************************\
  777. * pfnSimGlExtProc
  778. *
  779. * Return the extension function address that is the generic implemenation's
  780. * simulation for the client drivers. The simulation is used only if the
  781. * driver does not support an extension that is desirable to apps.
  782. *
  783. * Returns NULL if the function is not found.
  784. *
  785. * History:
  786. * Thu Dec 01 13:50:22 1994 -by- Hock San Lee [hockl]
  787. * Wrote it.
  788. \**************************************************************************/
  789. // Extension functions simulated by the generic implementation for the client
  790. // drivers
  791. // NOTE: remember to update GL_EXTENSIONS in glGetString.
  792. static PROC pfnSimGlExtProc(LPCSTR lpszProc)
  793. {
  794. // Extension is not supported by the generic implementation, return NULL.
  795. SetLastError(ERROR_PROC_NOT_FOUND);
  796. return((PROC) NULL);
  797. }
  798. /******************************Public*Routine******************************\
  799. *
  800. * wglCopyContext
  801. *
  802. * Copies all of one context's state to another one
  803. *
  804. * Returns:
  805. * TRUE if successful, FALSE otherwise
  806. *
  807. * History:
  808. * Fri May 26 14:57:17 1995 -by- Drew Bliss [drewb]
  809. * Created
  810. *
  811. \**************************************************************************/
  812. BOOL WINAPI
  813. wglCopyContext(HGLRC hrcSource, HGLRC hrcDest, UINT fuMask)
  814. {
  815. BOOL fRet;
  816. PLRC plrcSource, plrcDest;
  817. ULONG irc;
  818. PLHE plheRC;
  819. HANDLE hrcSrvSource, hrcSrvDest;
  820. GLFLUSH();
  821. fRet = FALSE;
  822. // Validate the contexts
  823. if (cLockHandle((ULONG_PTR)hrcSource) <= 0)
  824. {
  825. DBGLEVEL1(LEVEL_ERROR, "wglCopyContext: can't lock hrcSource 0x%lx\n",
  826. hrcSource);
  827. goto wglCopyContextEnd_nolock;
  828. }
  829. irc = MASKINDEX(hrcSource);
  830. plheRC = pLocalTable + irc;
  831. plrcSource = (PLRC)plheRC->pv;
  832. hrcSrvSource = (HANDLE) plheRC->hgre;
  833. ASSERTOPENGL(plrcSource->ident == LRC_IDENTIFIER,
  834. "wglCopyContext: Bad plrc\n");
  835. if (cLockHandle((ULONG_PTR)hrcDest) <= 0)
  836. {
  837. DBGLEVEL1(LEVEL_ERROR, "wglCopyContext: can't lock hrcDest 0x%lx\n",
  838. hrcDest);
  839. goto wglCopyContextEnd_onelock;
  840. }
  841. irc = MASKINDEX(hrcDest);
  842. plheRC = pLocalTable + irc;
  843. plrcDest = (PLRC)plheRC->pv;
  844. hrcSrvDest = (HANDLE) plheRC->hgre;
  845. ASSERTOPENGL(plrcDest->ident == LRC_IDENTIFIER,
  846. "wglCopyContext: Bad plrc\n");
  847. // Context can only be copied between like implementations so make
  848. // sure that both contexts are either driver contexts or generic
  849. // contexts
  850. if ((plrcSource->dhrc != 0) != (plrcDest->dhrc != 0))
  851. {
  852. DBGLEVEL(LEVEL_ERROR, "wglCopyContext: mismatched implementations\n");
  853. SetLastError(ERROR_INVALID_FUNCTION);
  854. goto wglCopyContextEnd;
  855. }
  856. // The destination context cannot be current to a thread
  857. if (plrcDest->tidCurrent != INVALID_THREAD_ID)
  858. {
  859. DBGLEVEL(LEVEL_ERROR, "wglCopyContext: destination has tidCurrent\n");
  860. SetLastError(ERROR_INVALID_HANDLE);
  861. goto wglCopyContextEnd;
  862. }
  863. if (plrcSource->dhrc == 0)
  864. {
  865. // For generic contexts, tell the server to share the lists
  866. fRet = __wglCopyContext(hrcSrvSource, hrcSrvDest, fuMask);
  867. if (!fRet)
  868. {
  869. DBGERROR("wglCopyContext: server call failed\n");
  870. }
  871. }
  872. else
  873. {
  874. // For device contexts tell the driver to copy the context
  875. // Ensure that both implementations are the same
  876. if (plrcSource->pGLDriver != plrcDest->pGLDriver)
  877. {
  878. DBGLEVEL(LEVEL_ERROR, "wglCopyContext: mismatched "
  879. "implementations\n");
  880. SetLastError(ERROR_INVALID_FUNCTION);
  881. goto wglCopyContextEnd;
  882. }
  883. ASSERTOPENGL(plrcSource->pGLDriver != NULL,
  884. "wglCopyContext: No GLDriver\n");
  885. // Older drivers may not support this entry point, so
  886. // fail the call if they don't
  887. if (plrcSource->pGLDriver->pfnDrvCopyContext == NULL)
  888. {
  889. WARNING("wglCopyContext called on driver context "
  890. "without driver support\n");
  891. SetLastError(ERROR_NOT_SUPPORTED);
  892. }
  893. else
  894. {
  895. fRet = plrcSource->pGLDriver->pfnDrvCopyContext(plrcSource->dhrc,
  896. plrcDest->dhrc,
  897. fuMask);
  898. }
  899. }
  900. wglCopyContextEnd:
  901. vUnlockHandle((ULONG_PTR)hrcDest);
  902. wglCopyContextEnd_onelock:
  903. vUnlockHandle((ULONG_PTR)hrcSource);
  904. wglCopyContextEnd_nolock:
  905. return fRet;
  906. }