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.

1115 lines
30 KiB

  1. /*
  2. ** Copyright 1995-2095, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. */
  17. #include "glslib.h"
  18. #include <ctype.h>
  19. #include <errno.h>
  20. #include <stdlib.h>
  21. /******************************************************************************
  22. POSIX threads
  23. ******************************************************************************/
  24. #if __GLS_POSIX_THREADS
  25. #if !__GLS_FAKE_MUTEX
  26. static pthread_mutex_t __gls_lock;
  27. static const pthread_mutexattr_t __gls_lockInit = {
  28. MUTEX_TYPE_FAST,
  29. MUTEX_FLAGS_INITED,
  30. };
  31. void __glsBeginCriticalSection(void) {
  32. if (pthread_mutex_lock(&__gls_lock)) {
  33. fprintf(stderr, "GLS fatal: pthread_mutex_lock failed\n");
  34. exit(EXIT_FAILURE);
  35. }
  36. }
  37. void __glsEndCriticalSection(void) {
  38. if (pthread_mutex_unlock(&__gls_lock)) {
  39. fprintf(stderr, "GLS fatal: pthread_mutex_unlock failed\n");
  40. exit(EXIT_FAILURE);
  41. }
  42. }
  43. #endif /* !__GLS_FAKE_MUTEX */
  44. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  45. pthread_key_t __gls_contextTLS;
  46. pthread_key_t __gls_errorTLS;
  47. __GLScontext* __glsGetContext(void) {
  48. return (__GLScontext *)pthread_getspecific(__gls_contextTLS);
  49. }
  50. GLSenum __glsGetError(void) {
  51. return (GLSenum)pthread_getspecific(__gls_errorTLS);
  52. }
  53. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  54. static void __glsFinalPthreads(void) {
  55. #if !__GLS_FAKE_MUTEX
  56. pthread_mutex_destroy(&__gls_lock);
  57. #endif /* !__GLS_FAKE_MUTEX */
  58. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  59. pthread_key_delete(__gls_contextTLS);
  60. pthread_key_delete(__gls_errorTLS);
  61. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  62. }
  63. static void __glsInitPthreads(void) {
  64. #if !__GLS_FAKE_MUTEX
  65. if (pthread_mutex_init(&__gls_lock, &__gls_lockInit)) {
  66. fprintf(stderr, "GLS fatal: pthread_mutex_init failed\n");
  67. exit(EXIT_FAILURE);
  68. }
  69. #endif /* !__GLS_FAKE_MUTEX */
  70. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  71. if (
  72. pthread_key_create(&__gls_contextTLS, GLS_NONE) ||
  73. pthread_key_create(&__gls_errorTLS, GLS_NONE)
  74. ) {
  75. fprintf(stderr, "GLS fatal: pthread_key_create failed\n");
  76. exit(EXIT_FAILURE);
  77. }
  78. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  79. }
  80. #endif /* __GLS_POSIX_THREADS */
  81. /******************************************************************************
  82. These routines must be called during library loading/unloading
  83. ******************************************************************************/
  84. static GLboolean __glsInitContextDict(void) {
  85. __glsContextDict = __glsIntDict_create(1);
  86. return (GLboolean)(__glsContextDict != GLS_NONE);
  87. }
  88. static void __glsFinalContextDict(void) {
  89. __GLScontext *ctx;
  90. __GLS_LIST_ITER(__GLScontext) iter;
  91. __GLS_LIST_FIRST(&__glsContextList, &iter);
  92. while (ctx = iter.elem) {
  93. __GLS_LIST_NEXT(&__glsContextList, &iter);
  94. __glsContext_destroy(ctx);
  95. }
  96. __glsIntDict_destroy(__glsContextDict);
  97. }
  98. /******************************************************************************
  99. Fake lltostr
  100. ******************************************************************************/
  101. #if __GLS_FAKE_LLTOSTR
  102. char *ulltostr(GLulong inVal, char *outBuf) {
  103. char buf[24];
  104. char *p1 = buf;
  105. char *p2 = outBuf;
  106. do {
  107. *p1++ = '0' + (char)(inVal % 10);
  108. inVal /= 10;
  109. } while (inVal);
  110. while (--p1 >= buf) *p2++ = *p1;
  111. *p2 = 0;
  112. return outBuf;
  113. }
  114. char *lltostr(GLlong inVal, char *outBuf) {
  115. char *p = outBuf;
  116. if (inVal < 0) {
  117. *p++ = '-';
  118. inVal = -inVal;
  119. }
  120. ulltostr(inVal, p);
  121. return outBuf;
  122. }
  123. #endif /* __GLS_FAKE_LLTOSTR */
  124. /******************************************************************************
  125. Fake mutex
  126. ******************************************************************************/
  127. #if __GLS_FAKE_MUTEX
  128. void __glsBeginCriticalSection(void) {
  129. }
  130. void __glsEndCriticalSection(void) {
  131. }
  132. #endif /* __GLS_FAKE_MUTEX */
  133. /******************************************************************************
  134. Fake strtoll
  135. ******************************************************************************/
  136. #if __GLS_FAKE_STRTOLL
  137. #define __GLS_DIGIT(c) ( \
  138. isdigit(c) ? c - '0' : islower(c) ? c - 'a' + 10 : c - 'A' + 10 \
  139. )
  140. #define __GLS_LL_MIN (-9223372036854775807LL-1LL)
  141. #define __GLS_LL_MAX 9223372036854775807LL
  142. #define __GLS_ULL_MAX 18446744073709551615LLU
  143. static GLboolean __gls_strtoull(
  144. const char *inStr, char **outPtr, GLboolean *outNeg, GLulong *outVal
  145. ) {
  146. GLint base, c, d;
  147. GLulong multMax, val;
  148. const char **ptr = (const char **)outPtr;
  149. if (ptr) *ptr = inStr;
  150. *outNeg = GL_FALSE;
  151. if (!isalnum(c = *inStr)) {
  152. while (isspace(c)) c = *++inStr;
  153. switch (c) {
  154. case '-':
  155. *outNeg = GL_TRUE;
  156. c = *++inStr;
  157. break;
  158. case '+':
  159. c = *++inStr;
  160. break;
  161. }
  162. }
  163. if (c != '0') {
  164. base = 10;
  165. } else if (inStr[1] == 'x' || inStr[1] == 'X') {
  166. base = 16;
  167. } else {
  168. base = 8;
  169. }
  170. if (!isalnum(c) || __GLS_DIGIT(c) >= base) {
  171. *outVal = 0;
  172. return GL_TRUE;
  173. }
  174. if (base == 16 && isxdigit(inStr[2])) c = *(inStr += 2);
  175. multMax = __GLS_ULL_MAX / base;
  176. val = __GLS_DIGIT(c);
  177. for (c = *++inStr; isalnum(c) && (d = __GLS_DIGIT(c)) < base; ) {
  178. if (val > multMax) goto overflow;
  179. val *= base;
  180. if (__GLS_ULL_MAX - val < d) goto overflow;
  181. val += d;
  182. c = *++inStr;
  183. }
  184. if (ptr) *ptr = inStr;
  185. *outVal = val;
  186. return GL_TRUE;
  187. overflow:
  188. for (c = *++inStr; isalnum(c) && __GLS_DIGIT(c) < base; c = *++inStr);
  189. if (ptr) *ptr = inStr;
  190. return GL_FALSE;
  191. }
  192. extern GLlong strtoll(const char *inStr, char **outPtr, int inBase) {
  193. GLboolean neg;
  194. GLulong outVal;
  195. if (
  196. !__gls_strtoull(inStr, outPtr, &neg, &outVal) ||
  197. outVal > (GLulong)__GLS_LL_MAX + (GLulong)neg
  198. ) {
  199. __GLS_PUT_ERRNO(ERANGE);
  200. return neg ? __GLS_LL_MIN : __GLS_LL_MAX;
  201. } else {
  202. return neg ? -outVal : outVal;
  203. }
  204. }
  205. extern GLulong strtoull(const char *inStr, char **outPtr, int inBase) {
  206. GLboolean neg;
  207. GLulong outVal;
  208. if (!__gls_strtoull(inStr, outPtr, &neg, &outVal)) {
  209. __GLS_PUT_ERRNO(ERANGE);
  210. return __GLS_ULL_MAX;
  211. } else {
  212. return neg ? -outVal : outVal;
  213. }
  214. }
  215. #endif /* __GLS_FAKE_STRTOLL */
  216. /******************************************************************************
  217. Fake thread-local storage
  218. ******************************************************************************/
  219. #if __GLS_FAKE_THREAD_LOCAL_STORAGE
  220. __GLScontext *__gls_context;
  221. GLSenum __gls_error;
  222. #endif /* __GLS_FAKE_THREAD_LOCAL_STORAGE */
  223. /******************************************************************************
  224. 2-level GL dispatch with GLS library defining all GL entry points
  225. ******************************************************************************/
  226. #if __GLS_GL_DISPATCH
  227. #if __GLS_PLATFORM_WIN32
  228. #include <gldrv.h>
  229. #include <exttable.h>
  230. // Version 1.1 table mapping
  231. static GLSopcode opGl11Procs[] =
  232. {
  233. GLS_OP_glArrayElement,
  234. GLS_OP_glBindTexture,
  235. GLS_OP_glColorPointer,
  236. GLS_OP_glDisableClientState,
  237. GLS_OP_glDrawArrays,
  238. GLS_OP_glDrawElements,
  239. GLS_OP_glEdgeFlagPointer,
  240. GLS_OP_glEnableClientState,
  241. GLS_OP_glIndexPointer,
  242. GLS_OP_glIndexub,
  243. GLS_OP_glIndexubv,
  244. GLS_OP_glInterleavedArrays,
  245. GLS_OP_glNormalPointer,
  246. GLS_OP_glPolygonOffset,
  247. GLS_OP_glTexCoordPointer,
  248. GLS_OP_glVertexPointer,
  249. GLS_OP_glAreTexturesResident,
  250. GLS_OP_glCopyTexImage1D,
  251. GLS_OP_glCopyTexImage2D,
  252. GLS_OP_glCopyTexSubImage1D,
  253. GLS_OP_glCopyTexSubImage2D,
  254. GLS_OP_glDeleteTextures,
  255. GLS_OP_glGenTextures,
  256. GLS_OP_glGetPointerv,
  257. GLS_OP_glIsTexture,
  258. GLS_OP_glPrioritizeTextures,
  259. GLS_OP_glTexSubImage1D,
  260. GLS_OP_glTexSubImage2D,
  261. GLS_OP_glPopClientAttrib,
  262. GLS_OP_glPushClientAttrib,
  263. };
  264. #define GL11_PROCS (sizeof(opGl11Procs)/sizeof(opGl11Procs[0]))
  265. // Extension function mapping
  266. static GLSopcode opExtProcs[] =
  267. {
  268. GLS_OP_glDrawRangeElementsWIN,
  269. GLS_OP_glColorTableEXT,
  270. GLS_OP_glColorSubTableEXT,
  271. GLS_OP_glGetColorTableEXT,
  272. GLS_OP_glGetColorTableParameterivEXT,
  273. GLS_OP_glGetColorTableParameterfvEXT
  274. };
  275. #define EXT_PROCS (sizeof(opExtProcs)/sizeof(opExtProcs[0]))
  276. // DrewB
  277. void glsUpdateCaptureExecTable(GLCLTPROCTABLE *pgcpt, GLEXTPROCTABLE *pgept)
  278. {
  279. GLint i;
  280. GLSopcode op;
  281. __GLScontext *ctx = __GLS_CONTEXT;
  282. GLSfunc *pgfn;
  283. if (ctx == NULL)
  284. {
  285. #if DBG
  286. OutputDebugString(TEXT("glsUpdateCaptureExecTable call ignored\n"));
  287. #endif
  288. return;
  289. }
  290. ctx->captureExecOverride = GL_TRUE;
  291. // Copy over standard 1.0 entries
  292. // The ordering is the same between OpenGL and GLS so straight copy works
  293. memcpy(&ctx->captureExec[GLS_OP_glNewList], &pgcpt->glDispatchTable,
  294. OPENGL_VERSION_100_ENTRIES*sizeof(GLSfunc));
  295. // If the dispatch table contains 1.1 entries, map them in
  296. pgfn = (GLSfunc *)&pgcpt->glDispatchTable.glArrayElement;
  297. if (pgcpt->cEntries == OPENGL_VERSION_110_ENTRIES)
  298. {
  299. for (i = 0; i < GL11_PROCS; i++)
  300. {
  301. op = __glsMapOpcode(opGl11Procs[i]);
  302. ctx->captureExec[op] = *pgfn++;
  303. }
  304. }
  305. #if DBG
  306. else if (pgcpt->cEntries != OPENGL_VERSION_100_ENTRIES)
  307. {
  308. OutputDebugString("glsUpdateCaptureExecTable clt table size wrong\n");
  309. }
  310. #endif
  311. // Map in extension functions
  312. #if DBG
  313. if (pgept->cEntries != EXT_PROCS)
  314. {
  315. OutputDebugString("glsUpdateCaptureExecTable ext table size wrong\n");
  316. }
  317. #endif
  318. pgfn = (GLSfunc *)&pgept->glDispatchTable;
  319. for (i = 0; i < EXT_PROCS; i++)
  320. {
  321. op = __glsMapOpcode(opExtProcs[i]);
  322. ctx->captureExec[op] = *pgfn++;
  323. }
  324. }
  325. void __glsMapGlsTableToGl(const GLSfunc *pgfnGlsTable,
  326. GLCLTPROCTABLE *pgcpt, GLEXTPROCTABLE *pgept)
  327. {
  328. GLint i;
  329. GLSopcode op;
  330. GLSfunc *pgfn;
  331. #if DBG
  332. if (sizeof(GLDISPATCHTABLE)/sizeof(PROC) < OPENGL_VERSION_110_ENTRIES)
  333. {
  334. OutputDebugString("__glsMapGlsTableToGl GLDISPATCHTABLE too small\n");
  335. }
  336. #endif
  337. // GLS supports all 1.1 functions so set a 1.1 entry count
  338. pgcpt->cEntries = OPENGL_VERSION_110_ENTRIES;
  339. pgept->cEntries = EXT_PROCS;
  340. // Copy over standard 1.0 entries
  341. // The ordering is the same between OpenGL and GLS so straight copy works
  342. memcpy(&pgcpt->glDispatchTable, &pgfnGlsTable[GLS_OP_glNewList],
  343. OPENGL_VERSION_100_ENTRIES*sizeof(GLSfunc));
  344. // Map in 1.1 entries
  345. pgfn = (GLSfunc *)&pgcpt->glDispatchTable.glArrayElement;
  346. for (i = 0; i < GL11_PROCS; i++)
  347. {
  348. op = __glsMapOpcode(opGl11Procs[i]);
  349. *pgfn++ = pgfnGlsTable[op];
  350. }
  351. // Map in extension functions
  352. pgfn = (GLSfunc *)&pgept->glDispatchTable;
  353. for (i = 0; i < EXT_PROCS; i++)
  354. {
  355. op = __glsMapOpcode(opExtProcs[i]);
  356. *pgfn++ = pgfnGlsTable[op];
  357. }
  358. }
  359. void glsGetCaptureExecTable(GLCLTPROCTABLE *pgcpt, GLEXTPROCTABLE *pgept)
  360. {
  361. __GLScontext *ctx = __GLS_CONTEXT;
  362. if (ctx == NULL ||
  363. !ctx->captureExecOverride)
  364. {
  365. #if DBG
  366. OutputDebugString(TEXT("glsGetCaptureExecTable call ignored\n"));
  367. #endif
  368. return;
  369. }
  370. __glsMapGlsTableToGl(ctx->captureExec, pgcpt, pgept);
  371. }
  372. void glsGetCaptureDispatchTable(GLCLTPROCTABLE *pgcpt, GLEXTPROCTABLE *pgept)
  373. {
  374. __glsMapGlsTableToGl(__glsDispatchCapture, pgcpt, pgept);
  375. }
  376. void __glsBeginCaptureExec(__GLScontext *ctx, GLSopcode inOpcode) {
  377. if (!ctx->captureNesting) return;
  378. inOpcode = __glsMapOpcode(inOpcode);
  379. if (ctx->captureExecOverride)
  380. {
  381. ctx->dispatchAPI[inOpcode] = ctx->captureExec[inOpcode];
  382. }
  383. else
  384. {
  385. ctx->dispatchAPI[inOpcode] = __glsDispatchExec[inOpcode];
  386. }
  387. }
  388. void __glsEndCaptureExec(__GLScontext *ctx, GLSopcode inOpcode) {
  389. if (!ctx->captureNesting) return;
  390. inOpcode = __glsMapOpcode(inOpcode);
  391. ctx->dispatchAPI[inOpcode] = (
  392. (GLSfunc)__glsDispatchCapture[inOpcode]
  393. );
  394. }
  395. #else
  396. void __glsBeginCaptureExec(GLSopcode inOpcode) {
  397. if (!__GLS_CONTEXT->captureNesting) return;
  398. inOpcode = __glsMapOpcode(inOpcode);
  399. __GLS_CONTEXT->dispatchAPI[inOpcode] = __glsDispatchExec[inOpcode];
  400. }
  401. void __glsEndCaptureExec(GLSopcode inOpcode) {
  402. if (!__GLS_CONTEXT->captureNesting) return;
  403. inOpcode = __glsMapOpcode(inOpcode);
  404. __GLS_CONTEXT->dispatchAPI[inOpcode] = (
  405. (GLSfunc)__glsDispatchCapture[inOpcode]
  406. );
  407. }
  408. #endif
  409. void __glsUpdateDispatchTables(void) {
  410. }
  411. #include "g_glapi.c"
  412. #endif /* __GLS_GL_DISPATCH */
  413. /******************************************************************************
  414. If using DSOs for the 2-level dispatch, use this DSO init function as well
  415. ******************************************************************************/
  416. #if __GLS_GL_DISPATCH_DSO
  417. #include <dlfcn.h>
  418. static void __glsInitGLDispatch_DSO(void) {
  419. GLvoid *const dso = dlopen(__GL_LIB_NAME, RTLD_LAZY);
  420. GLint i;
  421. GLSopcode op;
  422. if (!dso) {
  423. fprintf(stderr, "GLS fatal: dlopen failed on %s\n", __GL_LIB_NAME);
  424. exit(EXIT_FAILURE);
  425. }
  426. for (i = 0 ; op = __glsMapOpcode(__glsOpcodesGL[i]) ; ++i) {
  427. const GLSfunc func = (
  428. (GLSfunc) dlsym(dso, (const char *)__glsOpcodeString[op])
  429. );
  430. __glsDispatchExec[op] = func ? func : __glsNop;
  431. }
  432. }
  433. #endif /* __GLS_GL_DISPATCH_DSO */
  434. /******************************************************************************
  435. Null command func
  436. ******************************************************************************/
  437. #if __GLS_SINGLE_NULL_COMMAND_FUNC
  438. GLSfunc glsNullCommandFunc(GLSopcode inOpcode) {
  439. if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
  440. return (GLSfunc)__glsNop;
  441. }
  442. #endif /* __GLS_SINGLE_NULL_COMMAND_FUNC */
  443. /******************************************************************************
  444. AIX
  445. ******************************************************************************/
  446. #if __GLS_PLATFORM_AIX
  447. #include <a.out.h>
  448. #include <ldfcn.h>
  449. #include <string.h>
  450. #include <sys/ldr.h>
  451. static void __glsInitSA(void) {
  452. GLint i;
  453. LDFILE *ldFile = GLS_NONE;
  454. LDHDR *ldHdr;
  455. struct ld_info *ldInfo;
  456. GLvoid *ldInfoBuf = GLS_NONE;
  457. GLint ldInfoBufSize = 4096;
  458. LDSYM *ldSym;
  459. GLSopcode op;
  460. GLubyte *scnBuf;
  461. SCNHDR scnHdr;
  462. if (0) __gls_glRef();
  463. for (;;) {
  464. ldInfoBuf = realloc(ldInfoBuf, ldInfoBufSize);
  465. if (!ldInfoBuf) {
  466. fprintf(stderr, "GLS fatal: realloc for loadquery failed\n");
  467. exit(EXIT_FAILURE);
  468. }
  469. if (loadquery(L_GETINFO, ldInfoBuf, ldInfoBufSize) != -1) break;
  470. if (__GLS_ERRNO != ENOMEM) {
  471. fprintf(stderr, "GLS fatal: loadquery failed\n");
  472. exit(EXIT_FAILURE);
  473. }
  474. ldInfoBufSize <<= 1;
  475. }
  476. ldInfo = (struct ld_info *)ldInfoBuf;
  477. for (;;) {
  478. if (strstr(ldInfo->ldinfo_filename, __GL_LIB_NAME)) break;
  479. if (!ldInfo->ldinfo_next) {
  480. fprintf(stderr, "GLS fatal: %s not loaded\n", __GL_LIB_NAME);
  481. exit(EXIT_FAILURE);
  482. }
  483. ldInfo = (struct ld_info *)((GLubyte *)ldInfo + ldInfo->ldinfo_next);
  484. }
  485. ldFile = ldopen(ldInfo->ldinfo_filename, ldFile);
  486. if (!ldFile) {
  487. fprintf(
  488. stderr,
  489. "GLS fatal: ldopen failed on %s\n",
  490. ldInfo->ldinfo_filename
  491. );
  492. exit(EXIT_FAILURE);
  493. }
  494. if (ldnshread(ldFile, _LOADER, &scnHdr) != SUCCESS) {
  495. fprintf(stderr, "GLS fatal: ldnshread failed on %s\n", __GL_LIB_NAME);
  496. exit(EXIT_FAILURE);
  497. }
  498. scnBuf = (GLubyte *)malloc(scnHdr.s_size);
  499. if (!scnBuf) {
  500. fprintf(stderr, "GLS fatal: malloc for scnBuf failed\n");
  501. exit(EXIT_FAILURE);
  502. }
  503. if (FSEEK(ldFile, scnHdr.s_scnptr, BEGINNING) != OKFSEEK) {
  504. fprintf(stderr, "GLS fatal: FSEEK failed on %s\n", __GL_LIB_NAME);
  505. exit(EXIT_FAILURE);
  506. }
  507. if (FREAD((char *)scnBuf, scnHdr.s_size, 1, ldFile) != 1) {
  508. fprintf(stderr, "GLS fatal: FREAD failed on %s\n", __GL_LIB_NAME);
  509. exit(EXIT_FAILURE);
  510. }
  511. for (i = 0 ; op = __glsMapOpcode(__glsOpcodesGL[i]) ; ++i) {
  512. __glsDispatchExec[op] = __glsNop;
  513. }
  514. __glsParser = __glsParser_create();
  515. ldHdr = (LDHDR *)scnBuf;
  516. ldSym = (LDSYM *)(scnBuf + LDHDRSZ);
  517. for (i = 0 ; i < ldHdr->l_nsyms ; ++i, ++ldSym) {
  518. GLubyte *sym;
  519. if (!LDR_EXPORT(*ldSym)) continue;
  520. if (ldSym->l_zeroes) {
  521. sym = (GLubyte *)ldSym->l_name;
  522. } else {
  523. sym = scnBuf + ldHdr->l_stoff + ldSym->l_offset;
  524. }
  525. if (__glsStr2IntDict_find(__glsParser->glsOpDict, sym, (GLint*)&op)) {
  526. __glsDispatchExec[__glsMapOpcode(op)] = (GLSfunc)(
  527. (GLubyte *)ldInfo->ldinfo_dataorg + ldSym->l_value
  528. );
  529. }
  530. }
  531. free(ldInfoBuf);
  532. free(scnBuf);
  533. while(ldclose(ldFile) == FAILURE);
  534. if (!__glsInitContextDict()) {
  535. fprintf(stderr, "GLS fatal: couldn't create __glsContextDict\n");
  536. exit(EXIT_FAILURE);
  537. }
  538. }
  539. static GLboolean __glsInitDone;
  540. void __glsBeginCriticalSection(void) {
  541. if (!__glsInitDone) {
  542. __glsInitSA();
  543. __glsInitDone = GL_TRUE;
  544. }
  545. }
  546. void __glsEndCriticalSection(void) {
  547. }
  548. #endif /* __GLS_PLATFORM_AIX */
  549. /******************************************************************************
  550. DECUNIX
  551. ******************************************************************************/
  552. #if __GLS_PLATFORM_DECUNIX
  553. #if !__GLS_FAKE_MUTEX
  554. static pthread_mutex_t __gls_lock;
  555. void __glsBeginCriticalSection(void) {
  556. if (pthread_mutex_lock(&__gls_lock)) {
  557. fprintf(stderr, "GLS fatal: pthread_mutex_lock failed\n");
  558. exit(EXIT_FAILURE);
  559. }
  560. }
  561. void __glsEndCriticalSection(void) {
  562. if (pthread_mutex_unlock(&__gls_lock)) {
  563. fprintf(stderr, "GLS fatal: pthread_mutex_unlock failed\n");
  564. exit(EXIT_FAILURE);
  565. }
  566. }
  567. #endif /* !__GLS_FAKE_MUTEX */
  568. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  569. pthread_key_t __gls_contextTLS;
  570. pthread_key_t __gls_errorTLS;
  571. __GLScontext* __glsGetContext(void) {
  572. __GLScontext *outContext;
  573. pthread_getspecific(__gls_contextTLS, (pthread_addr_t *)&outContext);
  574. return outContext;
  575. }
  576. GLSenum __glsGetError(void) {
  577. GLvoid *outError;
  578. pthread_getspecific(__gls_errorTLS, (pthread_addr_t *)&outError);
  579. return (GLSenum)outError;
  580. }
  581. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  582. void __glsFinalDSO(void) {
  583. __glsFinalContextDict();
  584. __glsParser_destroy(__glsParser);
  585. #if !__GLS_FAKE_MUTEX
  586. pthread_mutex_destroy(&__gls_lock);
  587. #endif /* !__GLS_FAKE_MUTEX */
  588. }
  589. void __glsInitDSO(void) {
  590. #if __GLS_GL_DISPATCH_DSO
  591. __glsInitGLDispatch_DSO();
  592. #endif /* __GLS_GL_DISPATCH_DSO */
  593. #if !__GLS_FAKE_MUTEX
  594. if (pthread_mutex_init(&__gls_lock, pthread_mutexattr_default)) {
  595. fprintf(stderr, "GLS fatal: pthread_mutex_init failed\n");
  596. exit(EXIT_FAILURE);
  597. }
  598. #endif /* !__GLS_FAKE_MUTEX */
  599. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  600. if (
  601. pthread_keycreate(&__gls_contextTLS, GLS_NONE) ||
  602. pthread_keycreate(&__gls_errorTLS, GLS_NONE)
  603. ) {
  604. fprintf(stderr, "GLS fatal: pthread_keycreate failed\n");
  605. exit(EXIT_FAILURE);
  606. }
  607. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  608. if (!__glsInitContextDict()) {
  609. fprintf(stderr, "GLS fatal: couldn't create __glsContextDict\n");
  610. exit(EXIT_FAILURE);
  611. }
  612. }
  613. #endif /* __GLS_PLATFORM_DECUNIX */
  614. /******************************************************************************
  615. HPUX
  616. ******************************************************************************/
  617. #if __GLS_PLATFORM_HPUX
  618. #include <dl.h>
  619. void __glsInitSL(void) {
  620. GLint i;
  621. GLSopcode op;
  622. shl_t sl = shl_load(__GL_LIB_NAME, BIND_DEFERRED | DYNAMIC_PATH, 0);
  623. if (!sl) {
  624. fprintf(stderr, "GLS fatal: shl_load failed on %s\n", __GL_LIB_NAME);
  625. exit(EXIT_FAILURE);
  626. }
  627. for (i = 0 ; op = __glsMapOpcode(__glsOpcodesGL[i]) ; ++i) {
  628. GLSfunc func;
  629. if (
  630. !shl_findsym(
  631. &sl,
  632. (const char *)__glsOpcodeString[op],
  633. TYPE_PROCEDURE,
  634. &func
  635. )
  636. ) {
  637. __glsDispatchExec[op] = func;
  638. } else {
  639. __glsDispatchExec[op] = __glsNop;
  640. }
  641. }
  642. if (!__glsInitContextDict()) {
  643. fprintf(stderr, "GLS fatal: couldn't create __glsContextDict\n");
  644. exit(EXIT_FAILURE);
  645. }
  646. }
  647. #endif /* __GLS_PLATFORM_HPUX */
  648. /******************************************************************************
  649. IRIX
  650. ******************************************************************************/
  651. #if __GLS_PLATFORM_IRIX
  652. #if !__GLS_FAKE_MUTEX
  653. #include <abi_mutex.h>
  654. static abilock_t __gls_lock;
  655. void __glsBeginCriticalSection(void) {
  656. spin_lock(&__gls_lock);
  657. }
  658. void __glsEndCriticalSection(void) {
  659. if (release_lock(&__gls_lock)) {
  660. fprintf(stderr, "GLS fatal: release_lock failed\n");
  661. exit(EXIT_FAILURE);
  662. }
  663. }
  664. #endif /* !__GLS_FAKE_MUTEX */
  665. void __glsFinalDSO(void) {
  666. __glsFinalContextDict();
  667. __glsParser_destroy(__glsParser);
  668. }
  669. void __glsInitDSO(void) {
  670. #if __GLS_GL_DISPATCH_DSO
  671. __glsInitGLDispatch_DSO();
  672. #endif /* __GLS_GL_DISPATCH_DSO */
  673. #if !__GLS_FAKE_MUTEX
  674. if (init_lock(&__gls_lock)) {
  675. fprintf(stderr, "GLS fatal: init_lock failed\n");
  676. exit(EXIT_FAILURE);
  677. }
  678. #endif /* !__GLS_FAKE_MUTEX */
  679. if (!__glsInitContextDict()) {
  680. fprintf(stderr, "GLS fatal: couldn't create __glsContextDict\n");
  681. exit(EXIT_FAILURE);
  682. }
  683. }
  684. #if !__GLS_GL_DISPATCH
  685. #include "glxclient.h"
  686. extern __GLdispatchState __glDispatchCapture;
  687. void __glsBeginCaptureExec(GLSopcode inOpcode) {
  688. if (!__gl_dispatchOverride) return;
  689. __gl_dispatch = *__glXDispatchExec();
  690. }
  691. void __glsEndCaptureExec(GLSopcode inOpcode) {
  692. if (!__gl_dispatchOverride) return;
  693. __gl_dispatch = __glDispatchCapture;
  694. }
  695. void __glsUpdateDispatchTables(void) {
  696. if (__GLS_CONTEXT && __GLS_CONTEXT->captureNesting) {
  697. __glXBeginDispatchOverride(&__glDispatchCapture);
  698. } else if (!__GLS_CONTEXT || !__GLS_CONTEXT->captureNesting) {
  699. __glXEndDispatchOverride();
  700. }
  701. }
  702. #include "g_irix.c"
  703. #endif /* !__GLS_GL_DISPATCH */
  704. #endif /* __GLS_PLATFORM_IRIX */
  705. /******************************************************************************
  706. LINUX
  707. ******************************************************************************/
  708. #if __GLS_PLATFORM_LINUX
  709. void __glsFinalDSO(void) __attribute__ ((destructor));
  710. void __glsInitDSO(void) __attribute__ ((constructor));
  711. void __glsFinalDSO(void) {
  712. __glsFinalContextDict();
  713. __glsParser_destroy(__glsParser);
  714. #if __GLS_POSIX_THREADS
  715. __glsFinalPthreads();
  716. #endif /* __GLS_POSIX_THREADS */
  717. }
  718. void __glsInitDSO(void) {
  719. #if __GLS_GL_DISPATCH_DSO
  720. __glsInitGLDispatch_DSO();
  721. #endif /* __GLS_GL_DISPATCH_DSO */
  722. #if __GLS_POSIX_THREADS
  723. __glsInitPthreads();
  724. #endif /* __GLS_POSIX_THREADS */
  725. if (!__glsInitContextDict()) {
  726. fprintf(stderr, "GLS fatal: couldn't create __glsContextDict\n");
  727. exit(EXIT_FAILURE);
  728. }
  729. }
  730. #endif /* __GLS_PLATFORM_LINUX */
  731. /******************************************************************************
  732. SOLARIS
  733. ******************************************************************************/
  734. #if __GLS_PLATFORM_SOLARIS
  735. #if !__GLS_FAKE_MUTEX
  736. #include <synch.h>
  737. static mutex_t __gls_lock;
  738. void __glsBeginCriticalSection(void) {
  739. if (mutex_lock(&__gls_lock)) {
  740. fprintf(stderr, "GLS fatal: mutex_lock failed\n");
  741. exit(EXIT_FAILURE);
  742. }
  743. }
  744. void __glsEndCriticalSection(void) {
  745. if (mutex_unlock(&__gls_lock)) {
  746. fprintf(stderr, "GLS fatal: mutex_unlock failed\n");
  747. exit(EXIT_FAILURE);
  748. }
  749. }
  750. #endif /* !__GLS_FAKE_MUTEX */
  751. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  752. #include <thread.h>
  753. thread_key_t __gls_contextTLS;
  754. thread_key_t __gls_errorTLS;
  755. __GLScontext* __glsGetContext(void) {
  756. __GLScontext *outContext;
  757. thr_getspecific(__gls_contextTLS, (GLvoid **)&outContext);
  758. return outContext;
  759. }
  760. GLSenum __glsGetError(void) {
  761. GLvoid *outError;
  762. thr_getspecific(__gls_errorTLS, &outError);
  763. return (GLSenum)outError;
  764. }
  765. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  766. #pragma fini(__glsFinalDSO)
  767. #pragma init(__glsInitDSO)
  768. void __glsFinalDSO(void) {
  769. __glsFinalContextDict();
  770. __glsParser_destroy(__glsParser);
  771. #if !__GLS_FAKE_MUTEX
  772. mutex_destroy(&__gls_lock);
  773. #endif /* !__GLS_FAKE_MUTEX */
  774. }
  775. void __glsInitDSO(void) {
  776. #if __GLS_GL_DISPATCH_DSO
  777. __glsInitGLDispatch_DSO();
  778. #endif /* __GLS_GL_DISPATCH_DSO */
  779. #if !__GLS_FAKE_MUTEX
  780. if (mutex_init(&__gls_lock, USYNC_THREAD, GLS_NONE)) {
  781. fprintf(stderr, "GLS fatal: mutex_init failed\n");
  782. exit(EXIT_FAILURE);
  783. }
  784. #endif /* !__GLS_FAKE_MUTEX */
  785. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  786. if (
  787. thr_keycreate(&__gls_contextTLS, GLS_NONE) ||
  788. thr_keycreate(&__gls_errorTLS, GLS_NONE)
  789. ) {
  790. fprintf(stderr, "GLS fatal: thr_keycreate failed\n");
  791. exit(EXIT_FAILURE);
  792. }
  793. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  794. if (!__glsInitContextDict()) {
  795. fprintf(stderr, "GLS fatal: couldn't create __glsContextDict\n");
  796. exit(EXIT_FAILURE);
  797. }
  798. }
  799. #endif /* __GLS_PLATFORM_SOLARIS */
  800. /******************************************************************************
  801. WIN32
  802. ******************************************************************************/
  803. #if __GLS_PLATFORM_WIN32
  804. #include <string.h>
  805. #include "g_win32.c"
  806. #if !__GLS_FAKE_MUTEX
  807. static CRITICAL_SECTION __gls_lock;
  808. void __glsBeginCriticalSection(void) {
  809. EnterCriticalSection(&__gls_lock);
  810. }
  811. void __glsEndCriticalSection(void) {
  812. LeaveCriticalSection(&__gls_lock);
  813. }
  814. #endif /* !__GLS_FAKE_MUTEX */
  815. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  816. GLint __gls_contextTLS;
  817. GLint __gls_errorTLS;
  818. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  819. // DrewB
  820. typedef PROC (APIENTRY *wglGetDefaultProcAddressFunc)(LPCSTR);
  821. BOOL __glsDLLProcessAttach(void) {
  822. GLvoid *const dll = LoadLibrary(__GL_LIB_NAME);
  823. GLint i;
  824. GLSopcode op;
  825. // DrewB
  826. wglGetDefaultProcAddressFunc pfnGetDefaultProcAddress;
  827. if (!dll) {
  828. fprintf(
  829. stderr, "GLS fatal: LoadLibrary failed on %s\n", __GL_LIB_NAME
  830. );
  831. return GL_FALSE;
  832. }
  833. // DrewB
  834. pfnGetDefaultProcAddress = (wglGetDefaultProcAddressFunc)
  835. GetProcAddress(dll, "wglGetDefaultProcAddress");
  836. for (i = 0 ; op = __glsMapOpcode(__glsOpcodesGL[i]) ; ++i) {
  837. GLSfunc func;
  838. func = (GLSfunc) GetProcAddress(dll, __glsOpcodeString[op]);
  839. if (func == NULL)
  840. {
  841. func = (GLSfunc) pfnGetDefaultProcAddress(__glsOpcodeString[op]);
  842. }
  843. __glsDispatchExec[op] = func ? func : __glsNullCommandFuncs[op];
  844. }
  845. for (i = 0 ; i < __GLS_OPCODE_COUNT ; ++i) {
  846. if (__glsOpcodeAttrib[i] & __GLS_COMMAND_0_PARAMS_BIT) {
  847. __glsDispatchDecode_bin_default[i] =
  848. __glsDispatchDecode_bin_swap[i];
  849. }
  850. }
  851. #if !__GLS_FAKE_MUTEX
  852. __try
  853. {
  854. InitializeCriticalSection(&__gls_lock);
  855. }
  856. __except(EXCEPTION_EXECUTE_HANDLER)
  857. {
  858. return GL_FALSE;
  859. }
  860. #endif /* !__GLS_FAKE_MUTEX */
  861. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  862. __gls_contextTLS = TlsAlloc();
  863. __gls_errorTLS = TlsAlloc();
  864. if (__gls_contextTLS == -1 || __gls_errorTLS == -1) {
  865. fprintf(stderr, "GLS fatal: TlsAlloc failed\n");
  866. return GL_FALSE;
  867. }
  868. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  869. if (!__glsInitContextDict()) {
  870. fprintf(stderr, "GLS fatal: couldn't create __glsContextDict\n");
  871. return GL_FALSE;
  872. }
  873. return GL_TRUE;
  874. }
  875. BOOL __glsDLLProcessDetach(void) {
  876. __glsFinalContextDict();
  877. __glsParser_destroy(__glsParser);
  878. #if !__GLS_FAKE_MUTEX
  879. DeleteCriticalSection(&__gls_lock);
  880. #endif /* !__GLS_FAKE_MUTEX */
  881. #if !__GLS_FAKE_THREAD_LOCAL_STORAGE
  882. TlsFree(__gls_contextTLS);
  883. TlsFree(__gls_errorTLS);
  884. #endif /* !__GLS_FAKE_THREAD_LOCAL_STORAGE */
  885. return GL_TRUE;
  886. }
  887. BOOL DllMain(HINSTANCE hModule, DWORD inReason, LPVOID inReserved) {
  888. inReserved;
  889. switch (inReason) {
  890. case DLL_PROCESS_ATTACH:
  891. return __glsDLLProcessAttach();
  892. case DLL_PROCESS_DETACH:
  893. return __glsDLLProcessDetach();
  894. }
  895. return GL_TRUE;
  896. }
  897. GLlong __gls_strtoi64(const char *inStr, char **outPtr, int inBase) {
  898. GLlong outVal;
  899. inBase;
  900. if (sscanf(inStr, "%I64i", &outVal) == 1) {
  901. if (outPtr) *outPtr = (char *)inStr + strlen(inStr);
  902. return outVal;
  903. } else {
  904. if (outPtr) *outPtr = (char *)inStr;
  905. return 0;
  906. }
  907. }
  908. GLulong __gls_strtoui64(const char *inStr, char **outPtr, int inBase) {
  909. GLulong outVal;
  910. inBase;
  911. if (sscanf(inStr, "%I64i", &outVal) ==1) {
  912. if (outPtr) *outPtr = (char *)inStr + strlen(inStr);
  913. return outVal;
  914. } else {
  915. if (outPtr) *outPtr = (char *)inStr;
  916. return 0;
  917. }
  918. }
  919. GLSfunc glsNullCommandFunc(GLSopcode inOpcode) {
  920. if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
  921. return __glsNullCommandFuncs[__glsMapOpcode(inOpcode)];
  922. }
  923. #endif /* __GLS_PLATFORM_WIN32 */
  924. /*****************************************************************************/