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.

1154 lines
35 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 <stdlib.h>
  19. #include <string.h>
  20. static GLboolean __glsRequireContext(void) {
  21. if (__GLS_CONTEXT) {
  22. return GL_TRUE;
  23. } else {
  24. __GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
  25. return GL_FALSE;
  26. }
  27. }
  28. #ifndef __GLS_PLATFORM_WIN32
  29. // DrewB
  30. void glsAbortCall(GLSenum inMode) {
  31. if (!__glsRequireContext()) return;
  32. switch (inMode) {
  33. case GLS_NONE:
  34. case GLS_LAST:
  35. case GLS_ALL:
  36. __GLS_CONTEXT->abortMode = inMode;
  37. __glsContext_updateDispatchDecode_bin(__GLS_CONTEXT);
  38. break;
  39. default:
  40. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  41. break;
  42. }
  43. }
  44. #else
  45. void __glsInternalAbortCall(__GLScontext *ctx, GLSenum inMode) {
  46. switch (inMode) {
  47. case GLS_NONE:
  48. case GLS_LAST:
  49. case GLS_ALL:
  50. ctx->abortMode = inMode;
  51. __glsContext_updateDispatchDecode_bin(ctx);
  52. break;
  53. default:
  54. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  55. break;
  56. }
  57. }
  58. void glsAbortCall(GLSenum inMode) {
  59. if (!__glsRequireContext()) return;
  60. __glsInternalAbortCall(__GLS_CONTEXT, inMode);
  61. }
  62. #endif
  63. GLboolean glsBeginCapture(
  64. const GLubyte *inStreamName,
  65. GLSenum inCaptureStreamType,
  66. GLbitfield inWriteFlags
  67. ) {
  68. __GLScontext *const ctx = __GLS_CONTEXT;
  69. __GLSwriter *writer;
  70. if (!__glsRequireContext()) return GL_FALSE;
  71. if (ctx->captureNesting >= __GLS_MAX_CAPTURE_NESTING) {
  72. __GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
  73. return GL_FALSE;
  74. }
  75. if (!__glsValidateString(inStreamName)) return GL_FALSE;
  76. switch (inCaptureStreamType) {
  77. case GLS_CONTEXT:
  78. case GLS_BINARY_LSB_FIRST:
  79. case GLS_BINARY_MSB_FIRST:
  80. case GLS_TEXT:
  81. if (
  82. writer = __glsWriter_create(
  83. inStreamName, inCaptureStreamType, inWriteFlags
  84. )
  85. ) {
  86. if (!ctx->captureNesting++) {
  87. __glsContext_updateDispatchTables(ctx);
  88. }
  89. ctx->writer = ctx->writers[ctx->captureNesting - 1] = writer;
  90. return GL_TRUE;
  91. } else {
  92. return GL_FALSE;
  93. }
  94. default:
  95. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  96. return GL_FALSE;
  97. }
  98. }
  99. #ifndef __GLS_PLATFORM_WIN32
  100. // DrewB
  101. static void __glsCallArray_bin(size_t inCount, const GLubyte *inArray) {
  102. __GLScontext *ctx = __GLS_CONTEXT;
  103. #else
  104. static void __glsCallArray_bin(__GLScontext *ctx,
  105. size_t inCount, const GLubyte *inArray) {
  106. #endif
  107. const GLubyte *const arrayTail = inArray + inCount;
  108. size_t cmdBytes, headBytes;
  109. const __GLSbinCommandHead_large *head;
  110. GLSopcode op;
  111. for (;;) {
  112. headBytes = sizeof(__GLSbinCommandHead_small);
  113. if (inArray + headBytes > arrayTail) return;
  114. head = (const __GLSbinCommandHead_large *)inArray;
  115. if (head->countSmall) {
  116. op = head->opSmall;
  117. cmdBytes = head->countSmall << 2;
  118. } else {
  119. if (ctx->abortMode) return;
  120. headBytes = sizeof(__GLSbinCommandHead_large);
  121. if (inArray + headBytes > arrayTail) return;
  122. op = head->opLarge;
  123. cmdBytes = head->countLarge << 2;
  124. }
  125. if (inArray + cmdBytes > arrayTail) return;
  126. op = __glsMapOpcode(op);
  127. if (!__glsOpcodeString[op]) op = GLS_OP_glsUnsupportedCommand;
  128. #ifndef __GLS_PLATFORM_WIN32
  129. // DrewB
  130. ctx->dispatchDecode_bin[op]((GLubyte *)inArray + headBytes);
  131. #else
  132. ctx->dispatchDecode_bin[op](ctx, (GLubyte *)inArray + headBytes);
  133. #endif
  134. inArray += cmdBytes;
  135. }
  136. }
  137. #ifndef __GLS_PLATFORM_WIN32
  138. // DrewB
  139. static void __glsCallArray_bin_swap(size_t inCount, const GLubyte *inArray) {
  140. __GLScontext *ctx = __GLS_CONTEXT;
  141. #else
  142. static void __glsCallArray_bin_swap(__GLScontext *ctx,
  143. size_t inCount, const GLubyte *inArray) {
  144. #endif
  145. const GLubyte *const arrayTail = inArray + inCount;
  146. GLubyte *buf = GLS_NONE;
  147. size_t bufSize = 0, cmdBytes, headBytes;
  148. const __GLSbinCommandHead_large *head;
  149. GLSopcode mappedOp, op;
  150. for (;;) {
  151. if (ctx->abortMode) goto done;
  152. headBytes = sizeof(__GLSbinCommandHead_small);
  153. if (inArray + headBytes > arrayTail) goto done;
  154. head = (const __GLSbinCommandHead_large *)inArray;
  155. if (head->countSmall) {
  156. op = __glsSwaps((GLshort)head->opSmall);
  157. cmdBytes = __glsSwaps((GLshort)head->countSmall) << 2;
  158. } else {
  159. headBytes = sizeof(__GLSbinCommandHead_large);
  160. if (inArray + headBytes > arrayTail) goto done;
  161. op = __glsSwapi((GLint)head->opLarge);
  162. cmdBytes = __glsSwapi((GLint)head->countLarge) << 2;
  163. }
  164. if (inArray + cmdBytes > arrayTail) goto done;
  165. if (__glsOpcodeString[mappedOp = __glsMapOpcode(op)]) {
  166. GLScommandAlignment align;
  167. glsGetCommandAlignment(op, __GLS_BINARY_SWAP1, &align);
  168. if (bufSize < cmdBytes + align.value) {
  169. GLubyte *const newBuf = (GLubyte *)realloc(
  170. buf, bufSize = cmdBytes + align.value
  171. );
  172. if (!newBuf) {
  173. free(buf);
  174. bufSize = 0;
  175. }
  176. buf = newBuf;
  177. }
  178. if (buf) {
  179. memcpy(buf + align.value, inArray, cmdBytes);
  180. #ifndef __GLS_PLATFORM_WIN32
  181. // DrewB
  182. __glsDispatchDecode_bin_swap[mappedOp](
  183. buf + align.value + headBytes
  184. );
  185. #else
  186. __glsDispatchDecode_bin_swap[mappedOp](
  187. ctx, buf + align.value + headBytes
  188. );
  189. #endif
  190. } else {
  191. __GLS_CALL_ERROR(ctx, op, GLS_OUT_OF_MEMORY);
  192. }
  193. } else {
  194. __GLS_CALL_UNSUPPORTED_COMMAND(ctx);
  195. }
  196. inArray += cmdBytes;
  197. }
  198. done:
  199. free(buf);
  200. }
  201. #ifndef __GLS_PLATFORM_WIN32
  202. // DrewB
  203. static void __glsCallArray_text(size_t inCount, const GLubyte *inArray) {
  204. __GLScontext *ctx = __GLS_CONTEXT;
  205. #else
  206. static void __glsCallArray_text(__GLScontext *ctx,
  207. size_t inCount, const GLubyte *inArray) {
  208. #endif
  209. __GLSstring cmd;
  210. GLSopcode op;
  211. __GLSreader reader;
  212. if (!__glsParser) {
  213. __glsBeginCriticalSection();
  214. if (!__glsParser) __glsParser = __glsParser_create();
  215. __glsEndCriticalSection();
  216. if (!__glsParser) {
  217. __GLS_RAISE_ERROR(GLS_OUT_OF_MEMORY);
  218. return;
  219. }
  220. }
  221. __glsString_init(&cmd);
  222. __glsReader_init_array(&reader, inArray, inCount);
  223. for (;;) {
  224. if (ctx->abortMode || !__glsReader_beginCommand_text(&reader, &cmd)) {
  225. break;
  226. }
  227. if (__glsParser_findCommand(__glsParser, cmd.head, &op)) {
  228. #ifndef __GLS_PLATFORM_WIN32
  229. // DrewB
  230. __glsDispatchDecode_text[__glsMapOpcode(op)](&reader);
  231. #else
  232. __glsDispatchDecode_text[__glsMapOpcode(op)](ctx, &reader);
  233. #endif
  234. __glsReader_endCommand_text(&reader);
  235. if (reader.error) {
  236. __GLS_CALL_ERROR(ctx, op, reader.error);
  237. __glsReader_abortCommand_text(&reader);
  238. }
  239. } else {
  240. __glsReader_abortCommand_text(&reader);
  241. }
  242. }
  243. __glsString_final(&cmd);
  244. __glsReader_final(&reader);
  245. }
  246. #ifndef __GLS_PLATFORM_WIN32
  247. // DrewB
  248. void glsCallArray(
  249. GLSenum inExternStreamType, size_t inCount, const GLubyte *inArray
  250. ) {
  251. GLboolean callSave;
  252. __GLScontext *const ctx = __GLS_CONTEXT;
  253. if (!__glsRequireContext()) return;
  254. if (ctx->abortMode) return;
  255. if (ctx->callNesting >= __GLS_MAX_CALL_NESTING) {
  256. __GLS_RAISE_ERROR(GLS_CALL_OVERFLOW);
  257. glsAbortCall(GLS_ALL);
  258. return;
  259. }
  260. ++ctx->callNesting;
  261. callSave = ctx->contextCall;
  262. ctx->contextCall = GL_TRUE;
  263. switch (inExternStreamType) {
  264. case __GLS_BINARY_SWAP0:
  265. __glsCallArray_bin(inCount, inArray);
  266. break;
  267. case __GLS_BINARY_SWAP1:
  268. __glsCallArray_bin_swap(inCount, inArray);
  269. break;
  270. case GLS_TEXT:
  271. __glsCallArray_text(inCount, inArray);
  272. break;
  273. default:
  274. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  275. break;
  276. }
  277. ctx->contextCall = callSave;
  278. --ctx->callNesting;
  279. switch (ctx->abortMode) {
  280. case GLS_ALL:
  281. if (!ctx->callNesting) glsAbortCall(GLS_NONE);
  282. break;
  283. case GLS_LAST:
  284. glsAbortCall(GLS_NONE);
  285. break;
  286. }
  287. }
  288. #else
  289. void glsCallArrayInContext(
  290. GLuint inCtx,
  291. GLSenum inExternStreamType, size_t inCount, const GLubyte *inArray
  292. ) {
  293. GLboolean callSave;
  294. __GLScontext *ctx;
  295. __glsBeginCriticalSection();
  296. ctx = (__GLScontext *)__glsInt2PtrDict_find(
  297. __glsContextDict, (GLint)inCtx
  298. );
  299. __glsEndCriticalSection();
  300. if (ctx == NULL) return;
  301. if (ctx->abortMode) return;
  302. if (ctx->callNesting >= __GLS_MAX_CALL_NESTING) {
  303. __GLS_RAISE_ERROR(GLS_CALL_OVERFLOW);
  304. __glsInternalAbortCall(ctx, GLS_ALL);
  305. return;
  306. }
  307. ++ctx->callNesting;
  308. callSave = ctx->contextCall;
  309. ctx->contextCall = GL_TRUE;
  310. switch (inExternStreamType) {
  311. case __GLS_BINARY_SWAP0:
  312. __glsCallArray_bin(ctx, inCount, inArray);
  313. break;
  314. case __GLS_BINARY_SWAP1:
  315. __glsCallArray_bin_swap(ctx, inCount, inArray);
  316. break;
  317. case GLS_TEXT:
  318. __glsCallArray_text(ctx, inCount, inArray);
  319. break;
  320. default:
  321. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  322. break;
  323. }
  324. ctx->contextCall = callSave;
  325. --ctx->callNesting;
  326. switch (ctx->abortMode) {
  327. case GLS_ALL:
  328. if (!ctx->callNesting) __glsInternalAbortCall(ctx, GLS_NONE);
  329. break;
  330. case GLS_LAST:
  331. __glsInternalAbortCall(ctx, GLS_NONE);
  332. break;
  333. }
  334. }
  335. void glsCallArray(
  336. GLSenum inExternStreamType, size_t inCount, const GLubyte *inArray
  337. ) {
  338. glsCallArrayInContext(__GLS_CONTEXT->name, inExternStreamType, inCount,
  339. inArray);
  340. }
  341. #endif
  342. void glsCaptureFlags(GLSopcode inOpcode, GLbitfield inFlags) {
  343. if (!__glsRequireContext()) return;
  344. if (!__glsValidateOpcode(inOpcode)) return;
  345. switch (inOpcode) {
  346. case GLS_OP_glsBeginGLS:
  347. case GLS_OP_glsEndGLS:
  348. case GLS_OP_glsPad:
  349. return;
  350. }
  351. inOpcode = __glsMapOpcode(inOpcode);
  352. __GLS_CONTEXT->captureFlags[inOpcode] = (GLubyte)inFlags;
  353. }
  354. void glsCaptureFunc(GLSenum inTarget, GLScaptureFunc inFunc) {
  355. if (!__glsRequireContext()) return;
  356. switch (inTarget) {
  357. case GLS_CAPTURE_ENTRY_FUNC:
  358. __GLS_CONTEXT->captureEntryFunc = inFunc;
  359. break;
  360. case GLS_CAPTURE_EXIT_FUNC:
  361. __GLS_CONTEXT->captureExitFunc = inFunc;
  362. break;
  363. default:
  364. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  365. break;
  366. }
  367. }
  368. void glsChannel(GLSenum inTarget, FILE *inChannel) {
  369. if (!__glsRequireContext()) return;
  370. switch (inTarget) {
  371. case GLS_DEFAULT_READ_CHANNEL:
  372. __GLS_CONTEXT->defaultReadChannel = inChannel;
  373. break;
  374. case GLS_DEFAULT_WRITE_CHANNEL:
  375. __GLS_CONTEXT->defaultWriteChannel = inChannel;
  376. break;
  377. default:
  378. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  379. }
  380. }
  381. void glsCommandFunc(GLSopcode inOpcode, GLSfunc inFunc) {
  382. __GLScontext *const ctx = __GLS_CONTEXT;
  383. if (!__glsRequireContext()) return;
  384. if (!__glsValidateOpcode(inOpcode)) return;
  385. inOpcode = __glsMapOpcode(inOpcode);
  386. ctx->commandFuncs[inOpcode] = inFunc;
  387. ctx->dispatchCall[inOpcode] = inFunc ? inFunc : ctx->dispatchAPI[inOpcode];
  388. if (!ctx->abortMode && !__glsDispatchDecode_bin_default[inOpcode]) {
  389. ctx->dispatchDecode_bin[inOpcode] = (
  390. (__GLSdecodeBinFunc)ctx->dispatchCall[inOpcode]
  391. );
  392. }
  393. }
  394. GLSenum glsCopyStream(
  395. const GLubyte *inSource,
  396. const GLubyte *inDest,
  397. GLSenum inDestType,
  398. GLbitfield inWriteFlags
  399. ) {
  400. __GLScontext *const ctx = __GLS_CONTEXT;
  401. __GLScontextStream *contextStream;
  402. __GLSreadStream *readStream;
  403. GLSenum outType = GLS_NONE;
  404. __GLSversion versionSave;
  405. if (!__glsRequireContext()) return outType;
  406. if (!__glsValidateString(inSource)) return outType;
  407. if (!__glsValidateString(inDest)) return outType;
  408. switch (inDestType) {
  409. case GLS_NONE:
  410. case GLS_CONTEXT:
  411. case GLS_BINARY_LSB_FIRST:
  412. case GLS_BINARY_MSB_FIRST:
  413. case GLS_TEXT:
  414. break;
  415. default:
  416. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  417. return outType;
  418. }
  419. if (ctx->abortMode) return outType;
  420. if (ctx->callNesting >= __GLS_MAX_CALL_NESTING) {
  421. __GLS_RAISE_ERROR(GLS_CALL_OVERFLOW);
  422. glsAbortCall(GLS_ALL);
  423. return outType;
  424. }
  425. ++ctx->callNesting;
  426. versionSave = ctx->streamVersion;
  427. ctx->streamVersion.major = ctx->streamVersion.minor = 0;
  428. if (
  429. contextStream = __glsStr2PtrDict_find(ctx->contextStreamDict, inSource)
  430. ) {
  431. GLint i;
  432. if (inDestType == GLS_NONE) inDestType = GLS_CONTEXT;
  433. for (i = 0 ; i < ctx->captureNesting ; ++i) {
  434. if (ctx->writers[i]->contextStream == contextStream) {
  435. __GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
  436. inDestType = GLS_NONE;
  437. break;
  438. }
  439. }
  440. if (
  441. inDestType == GLS_CONTEXT &&
  442. !strcmp(
  443. (const char *)inDest, (const char *)contextStream->name.head
  444. )
  445. ) {
  446. __GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
  447. inDestType = GLS_NONE;
  448. }
  449. if (inDestType) {
  450. if (glsBeginCapture(inDest, inDestType, inWriteFlags)) {
  451. outType = GLS_CONTEXT;
  452. __glsContextStream_call(contextStream);
  453. glsEndCapture();
  454. }
  455. }
  456. } else if (readStream = __glsReadStream_create(inSource)) {
  457. __GLSreader reader;
  458. if (__glsReader_init_stream(
  459. &reader, readStream, __GLS_READER_BUF_BYTES
  460. )) {
  461. if (inDestType == GLS_NONE) inDestType = reader.type;
  462. if (glsBeginCapture(inDest, inDestType, inWriteFlags)) {
  463. outType = reader.type;
  464. __glsReader_call(&reader);
  465. glsEndCapture();
  466. }
  467. __glsReader_final(&reader);
  468. } else {
  469. __GLS_RAISE_ERROR(GLS_INVALID_STREAM);
  470. }
  471. __glsReadStream_destroy(readStream);
  472. } else {
  473. __GLS_RAISE_ERROR(GLS_NOT_FOUND);
  474. }
  475. --ctx->callNesting;
  476. switch (ctx->abortMode) {
  477. case GLS_ALL:
  478. if (!ctx->callNesting) glsAbortCall(GLS_NONE);
  479. break;
  480. case GLS_LAST:
  481. glsAbortCall(GLS_NONE);
  482. break;
  483. }
  484. ctx->streamVersion = versionSave;
  485. return outType;
  486. }
  487. void glsDataPointer(GLvoid *inPointer) {
  488. if (!__glsRequireContext()) return;
  489. __GLS_CONTEXT->dataPointer = inPointer;
  490. }
  491. void glsDeleteReadPrefix(GLuint inIndex) {
  492. __GLScontext *const ctx = __GLS_CONTEXT;
  493. if (!__glsRequireContext()) return;
  494. if (inIndex >= ctx->readPrefixList.count) {
  495. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  496. return;
  497. }
  498. __GLS_ITERLIST_SEEK(&ctx->readPrefixList, inIndex);
  499. __GLS_ITERLIST_REMOVE_DESTROY(
  500. &ctx->readPrefixList,
  501. ctx->readPrefixList.iterElem,
  502. __glsListString_destroy
  503. );
  504. }
  505. void glsDeleteStream(const GLubyte *inName) {
  506. __GLScontext *const ctx = __GLS_CONTEXT;
  507. __GLScontextStream *contextStream;
  508. __GLSreadStream *readStream;
  509. if (!__glsRequireContext()) return;
  510. if (!__glsValidateString(inName)) return;
  511. if (
  512. contextStream = __glsStr2PtrDict_find(ctx->contextStreamDict, inName)
  513. ) {
  514. __glsStrDict_remove(ctx->contextStreamDict, contextStream->name.head);
  515. __GLS_ITERLIST_REMOVE(&ctx->contextStreamList, contextStream);
  516. if (contextStream->callCount) {
  517. contextStream->deleted = GL_TRUE;
  518. } else {
  519. __glsContextStream_destroy(contextStream);
  520. }
  521. } else if (readStream = __glsReadStream_create(inName)) {
  522. if (remove((const char *)readStream->name.head)) {
  523. __GLS_RAISE_ERROR(GLS_STREAM_DELETE_ERROR);
  524. }
  525. __glsReadStream_destroy(readStream);
  526. } else {
  527. __GLS_RAISE_ERROR(GLS_NOT_FOUND);
  528. }
  529. }
  530. void glsEndCapture(void) {
  531. __GLScontext *const ctx = __GLS_CONTEXT;
  532. if (!__glsRequireContext()) return;
  533. if (ctx->captureNesting > 0) {
  534. const GLint n = --ctx->captureNesting;
  535. __glsWriter_destroy(ctx->writer);
  536. ctx->writer = n ? ctx->writers[n - 1] : GLS_NONE;
  537. if (!n) __glsContext_updateDispatchTables(ctx);
  538. } else {
  539. __GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
  540. }
  541. }
  542. void glsFlush(GLSenum inFlushType) {
  543. __GLScontext *const ctx = __GLS_CONTEXT;
  544. GLint i;
  545. if (!__glsRequireContext()) return;
  546. switch (inFlushType) {
  547. case GLS_ALL:
  548. for (i = 0 ; i < ctx->captureNesting ; ++i) {
  549. __glsWriter_flush(ctx->writers[i]);
  550. }
  551. break;
  552. case GLS_LAST:
  553. if (ctx->writer) __glsWriter_flush(ctx->writer);
  554. break;
  555. default:
  556. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  557. break;
  558. }
  559. }
  560. GLbitfield glsGetCaptureFlags(GLSopcode inOpcode) {
  561. if (!__glsRequireContext()) return GLS_NONE;
  562. if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
  563. return __GLS_CONTEXT->captureFlags[__glsMapOpcode(inOpcode)];
  564. }
  565. GLSfunc glsGetCommandFunc(GLSopcode inOpcode) {
  566. if (!__glsRequireContext()) return GLS_NONE;
  567. if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
  568. return __GLS_CONTEXT->commandFuncs[__glsMapOpcode(inOpcode)];
  569. }
  570. GLSfunc glsGetContextFunc(GLSenum inAttrib) {
  571. __GLScontext *const ctx = __GLS_CONTEXT;
  572. if (!__glsRequireContext()) return GLS_NONE;
  573. switch (inAttrib) {
  574. case GLS_CAPTURE_ENTRY_FUNC:
  575. return (GLSfunc)ctx->captureEntryFunc;
  576. case GLS_CAPTURE_EXIT_FUNC:
  577. return (GLSfunc)ctx->captureExitFunc;
  578. case GLS_READ_FUNC:
  579. return (GLSfunc)ctx->readFunc;
  580. case GLS_UNREAD_FUNC:
  581. return (GLSfunc)ctx->unreadFunc;
  582. case GLS_WRITE_FUNC:
  583. return (GLSfunc)ctx->writeFunc;
  584. default:
  585. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  586. return GLS_NONE;
  587. }
  588. }
  589. GLlong glsGetContextListl(GLSenum inAttrib, GLuint inIndex) {
  590. __GLScontext *const ctx = __GLS_CONTEXT;
  591. if (!__glsRequireContext()) return __glsSizeToLong(0);
  592. switch (inAttrib) {
  593. case GLS_OUT_ARG_LIST:
  594. if (inIndex >= (GLuint)ctx->outArgs.count) {
  595. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  596. return __glsSizeToLong(0);
  597. }
  598. return *(GLlong *)(ctx->outArgs.vals + inIndex);
  599. default:
  600. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  601. return __glsSizeToLong(0);
  602. }
  603. }
  604. const GLubyte* glsGetContextListubz(GLSenum inAttrib, GLuint inIndex) {
  605. __GLScontext *const ctx = __GLS_CONTEXT;
  606. GLubyte *outStr;
  607. if (!__glsRequireContext()) return GLS_NONE;
  608. switch (inAttrib) {
  609. case GLS_CONTEXT_STREAM_LIST:
  610. if (inIndex >= ctx->contextStreamList.count) {
  611. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  612. return 0;
  613. }
  614. __GLS_ITERLIST_SEEK(&ctx->contextStreamList, inIndex);
  615. outStr = ctx->contextStreamList.iterElem->name.head;
  616. break;
  617. case GLS_READ_PREFIX_LIST:
  618. if (inIndex >= ctx->readPrefixList.count) {
  619. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  620. return 0;
  621. }
  622. __GLS_ITERLIST_SEEK(&ctx->readPrefixList, inIndex);
  623. outStr = ctx->readPrefixList.iterElem->val.head;
  624. break;
  625. default:
  626. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  627. return GLS_NONE;
  628. }
  629. return (
  630. __glsString_assign(&ctx->returnString, outStr) ?
  631. ctx->returnString.head :
  632. GLS_NONE
  633. );
  634. }
  635. GLvoid* glsGetContextPointer(GLSenum inAttrib) {
  636. __GLScontext *const ctx = __GLS_CONTEXT;
  637. if (!__glsRequireContext()) return GLS_NONE;
  638. switch (inAttrib) {
  639. case GLS_DEFAULT_READ_CHANNEL:
  640. return ctx->defaultReadChannel;
  641. case GLS_DEFAULT_WRITE_CHANNEL:
  642. return ctx->defaultWriteChannel;
  643. case GLS_DATA_POINTER:
  644. return ctx->dataPointer;
  645. default:
  646. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  647. return GLS_NONE;
  648. }
  649. }
  650. GLint glsGetContexti(GLSenum inAttrib) {
  651. __GLScontext *const ctx = __GLS_CONTEXT;
  652. if (!__glsRequireContext()) return 0;
  653. switch (inAttrib) {
  654. case GLS_ABORT_MODE:
  655. return (GLint)ctx->abortMode;
  656. case GLS_BLOCK_TYPE:
  657. return (GLint)ctx->blockType;
  658. case GLS_CALL_NESTING:
  659. return ctx->callNesting;
  660. case GLS_CAPTURE_NESTING:
  661. return ctx->captureNesting;
  662. case GLS_CONTEXT_STREAM_COUNT:
  663. return (GLint)ctx->contextStreamList.count;
  664. case GLS_CURRENT_GLRC:
  665. return (GLint)ctx->currentGLRC;
  666. case GLS_OUT_ARG_COUNT:
  667. return ctx->outArgs.count;
  668. case GLS_PIXEL_SETUP_GEN:
  669. return ctx->pixelSetupGen;
  670. case GLS_READ_PREFIX_COUNT:
  671. return (GLint)ctx->readPrefixList.count;
  672. case GLS_STREAM_VERSION_MAJOR:
  673. return ctx->streamVersion.major;
  674. case GLS_STREAM_VERSION_MINOR:
  675. return ctx->streamVersion.minor;
  676. default:
  677. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  678. return 0;
  679. }
  680. }
  681. const GLubyte* glsGetContextubz(GLSenum inAttrib) {
  682. __GLScontext *const ctx = __GLS_CONTEXT;
  683. GLubyte *outStr;
  684. if (!__glsRequireContext()) return GLS_NONE;
  685. switch (inAttrib) {
  686. case GLS_WRITE_PREFIX:
  687. outStr = ctx->writePrefix->val.head;
  688. break;
  689. default:
  690. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  691. return GLS_NONE;
  692. }
  693. return (
  694. __glsString_assign(&ctx->returnString, outStr) ?
  695. ctx->returnString.head :
  696. GLS_NONE
  697. );
  698. }
  699. GLint glsGetGLRCi(GLuint inGLRC, GLSenum inAttrib) {
  700. __GLScontext *const ctx = __GLS_CONTEXT;
  701. __GLSglrc *glrc;
  702. if (!__glsRequireContext()) return 0;
  703. if (!inGLRC || inGLRC > (GLuint)ctx->header.glrcCount) {
  704. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  705. return 0;
  706. }
  707. glrc = ctx->header.glrcs + inGLRC - 1;
  708. switch (inAttrib) {
  709. case GLS_LAYER:
  710. return (GLint)glrc->layer;
  711. case GLS_READ_LAYER:
  712. return (GLint)glrc->readLayer;
  713. case GLS_SHARE_GLRC:
  714. return (GLint)glrc->shareGLRC;
  715. default:
  716. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  717. return 0;
  718. }
  719. }
  720. GLfloat glsGetHeaderf(GLSenum inAttrib) {
  721. __GLScontext *const ctx = __GLS_CONTEXT;
  722. if (!__glsRequireContext()) return (GLfloat)0;
  723. switch (inAttrib) {
  724. case GLS_ASPECT:
  725. return ctx->header.aspect;
  726. case GLS_BORDER_WIDTH:
  727. return ctx->header.borderWidth;
  728. case GLS_CONTRAST_RATIO:
  729. return ctx->header.contrastRatio;
  730. case GLS_HEIGHT_MM:
  731. return ctx->header.heightMM;
  732. default:
  733. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  734. return (GLfloat)0;
  735. }
  736. }
  737. GLfloat* glsGetHeaderfv(GLSenum inAttrib, GLfloat *outVec) {
  738. __GLScontext *const ctx = __GLS_CONTEXT;
  739. GLint i;
  740. if (!__glsRequireContext()) return GLS_NONE;
  741. switch (inAttrib) {
  742. case GLS_BORDER_COLOR:
  743. for (i = 0 ; i < 4 ; ++i) outVec[i] = ctx->header.borderColor[i];
  744. return outVec;
  745. case GLS_GAMMA:
  746. for (i = 0 ; i < 4 ; ++i) outVec[i] = ctx->header.gamma[i];
  747. return outVec;
  748. case GLS_ORIGIN:
  749. for (i = 0 ; i < 2 ; ++i) outVec[i] = ctx->header.origin[i];
  750. return outVec;
  751. case GLS_PAGE_COLOR:
  752. for (i = 0 ; i < 4 ; ++i) outVec[i] = ctx->header.pageColor[i];
  753. return outVec;
  754. case GLS_PAGE_SIZE:
  755. for (i = 0 ; i < 2 ; ++i) outVec[i] = ctx->header.pageSize[i];
  756. return outVec;
  757. case GLS_RED_POINT:
  758. for (i = 0 ; i < 2 ; ++i) outVec[i] = ctx->header.redPoint[i];
  759. return outVec;
  760. case GLS_GREEN_POINT:
  761. for (i = 0 ; i < 2 ; ++i) outVec[i] = ctx->header.greenPoint[i];
  762. return outVec;
  763. case GLS_BLUE_POINT:
  764. for (i = 0 ; i < 2 ; ++i) outVec[i] = ctx->header.bluePoint[i];
  765. return outVec;
  766. case GLS_WHITE_POINT:
  767. for (i = 0 ; i < 2 ; ++i) outVec[i] = ctx->header.whitePoint[i];
  768. return outVec;
  769. default:
  770. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  771. return GLS_NONE;
  772. }
  773. }
  774. GLint glsGetHeaderi(GLSenum inAttrib) {
  775. __GLScontext *const ctx = __GLS_CONTEXT;
  776. if (!__glsRequireContext()) return 0;
  777. switch (inAttrib) {
  778. case GLS_FRAME_COUNT:
  779. return ctx->header.frameCount;
  780. case GLS_GLRC_COUNT:
  781. return ctx->header.glrcCount;
  782. case GLS_HEIGHT_PIXELS:
  783. return ctx->header.heightPixels;
  784. case GLS_LAYER_COUNT:
  785. return ctx->header.layerCount;
  786. case GLS_TILEABLE:
  787. return ctx->header.tileable;
  788. default:
  789. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  790. return 0;
  791. }
  792. }
  793. GLint* glsGetHeaderiv(GLSenum inAttrib, GLint *outVec) {
  794. __GLScontext *const ctx = __GLS_CONTEXT;
  795. GLint i;
  796. if (!__glsRequireContext()) return GLS_NONE;
  797. switch (inAttrib) {
  798. case GLS_CREATE_TIME:
  799. for (i = 0 ; i < 6 ; ++i) outVec[i] = ctx->header.createTime[i];
  800. return outVec;
  801. case GLS_MODIFY_TIME:
  802. for (i = 0 ; i < 6 ; ++i) outVec[i] = ctx->header.modifyTime[i];
  803. return outVec;
  804. default:
  805. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  806. return GLS_NONE;
  807. }
  808. }
  809. const GLubyte* glsGetHeaderubz(GLSenum inAttrib) {
  810. __GLScontext *const ctx = __GLS_CONTEXT;
  811. GLubyte *outStr;
  812. if (!__glsRequireContext()) return GLS_NONE;
  813. switch (inAttrib) {
  814. case GLS_EXTENSIONS:
  815. outStr = ctx->header.extensions.head;
  816. break;
  817. case GLS_AUTHOR:
  818. outStr = ctx->header.author.head;
  819. break;
  820. case GLS_DESCRIPTION:
  821. outStr = ctx->header.description.head;
  822. break;
  823. case GLS_NOTES:
  824. outStr = ctx->header.notes.head;
  825. break;
  826. case GLS_TITLE:
  827. outStr = ctx->header.title.head;
  828. break;
  829. case GLS_TOOLS:
  830. outStr = ctx->header.tools.head;
  831. break;
  832. case GLS_VERSION:
  833. outStr = ctx->header.version.head;
  834. break;
  835. default:
  836. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  837. return GLS_NONE;
  838. }
  839. return (
  840. __glsString_assign(&ctx->returnString, outStr) ?
  841. ctx->returnString.head :
  842. GLS_NONE
  843. );
  844. }
  845. GLfloat glsGetLayerf(GLuint inLayer, GLSenum inAttrib) {
  846. __GLScontext *const ctx = __GLS_CONTEXT;
  847. __GLSlayer *layer;
  848. if (!__glsRequireContext()) return (GLfloat)0;
  849. if (!inLayer || inLayer > (GLuint)ctx->header.layerCount) {
  850. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  851. return (GLfloat)0;
  852. }
  853. layer = ctx->header.layers + inLayer - 1;
  854. switch (inAttrib) {
  855. case GLS_INVISIBLE_ASPECT:
  856. return layer->invisibleAspect;
  857. default:
  858. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  859. return (GLfloat)0;
  860. }
  861. }
  862. GLint glsGetLayeri(GLuint inLayer, GLSenum inAttrib) {
  863. __GLScontext *const ctx = __GLS_CONTEXT;
  864. __GLSlayer *layer;
  865. if (!__glsRequireContext()) return 0;
  866. if (!inLayer || inLayer > (GLuint)ctx->header.layerCount) {
  867. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  868. return 0;
  869. }
  870. layer = ctx->header.layers + inLayer - 1;
  871. switch (inAttrib) {
  872. case GLS_DISPLAY_FORMAT:
  873. return (GLint)layer->displayFormat;
  874. case GLS_DOUBLEBUFFER:
  875. return layer->doubleBuffer;
  876. case GLS_INVISIBLE:
  877. return layer->invisible;
  878. case GLS_INVISIBLE_HEIGHT_PIXELS:
  879. return layer->invisibleHeightPixels;
  880. case GLS_LEVEL:
  881. return layer->level;
  882. case GLS_STEREO:
  883. return layer->stereo;
  884. case GLS_TRANSPARENT:
  885. return layer->transparent;
  886. case GLS_INDEX_BITS:
  887. return layer->indexBits;
  888. case GLS_RED_BITS:
  889. return layer->redBits;
  890. case GLS_GREEN_BITS:
  891. return layer->greenBits;
  892. case GLS_BLUE_BITS:
  893. return layer->blueBits;
  894. case GLS_ALPHA_BITS:
  895. return layer->alphaBits;
  896. case GLS_DEPTH_BITS:
  897. return layer->depthBits;
  898. case GLS_STENCIL_BITS:
  899. return layer->stencilBits;
  900. case GLS_ACCUM_RED_BITS:
  901. return layer->accumRedBits;
  902. case GLS_ACCUM_GREEN_BITS:
  903. return layer->accumGreenBits;
  904. case GLS_ACCUM_BLUE_BITS:
  905. return layer->accumBlueBits;
  906. case GLS_ACCUM_ALPHA_BITS:
  907. return layer->accumAlphaBits;
  908. case GLS_AUX_BUFFERS:
  909. return layer->auxBuffers;
  910. #if __GL_SGIS_multisample
  911. case GLS_SAMPLE_BUFFERS_SGIS:
  912. return layer->sampleBuffers;
  913. case GLS_SAMPLES_SGIS:
  914. return layer->samples;
  915. #endif /* __GL_SGIS_multisample */
  916. default:
  917. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  918. return 0;
  919. }
  920. }
  921. GLbitfield glsGetStreamAttrib(const GLubyte *inName) {
  922. if (!__glsRequireContext()) return GL_FALSE;
  923. if (!__glsValidateString(inName)) return GL_FALSE;
  924. if (__glsStr2PtrDict_find(__GLS_CONTEXT->contextStreamDict, inName)) {
  925. return (
  926. GLS_STREAM_CONTEXT_BIT |
  927. GLS_STREAM_NAMED_BIT |
  928. GLS_STREAM_READABLE_BIT |
  929. GLS_STREAM_WRITABLE_BIT |
  930. GLS_STREAM_SEEKABLE_BIT
  931. );
  932. } else {
  933. GLbitfield outVal = GLS_NONE;
  934. __GLSreadStream *const readStream = __glsReadStream_create(inName);
  935. if (readStream) {
  936. outVal = __glsReadStream_getAttrib(readStream);
  937. __glsReadStream_destroy(readStream);
  938. }
  939. return outVal;
  940. }
  941. }
  942. GLuint glsGetStreamCRC32(const GLubyte *inName) {
  943. __GLScontextStream *contextStream;
  944. __GLSreadStream *readStream;
  945. if (!__glsRequireContext()) return 0;
  946. if (!__glsValidateString(inName)) return 0;
  947. glsFlush(GLS_ALL);
  948. if (
  949. contextStream =
  950. __glsStr2PtrDict_find(__GLS_CONTEXT->contextStreamDict, inName)
  951. ) {
  952. return __glsContextStream_getCRC32(contextStream);
  953. } else if (readStream = __glsReadStream_create(inName)) {
  954. const GLuint outVal = __glsReadStream_getCRC32(readStream);
  955. __glsReadStream_destroy(readStream);
  956. return outVal;
  957. } else {
  958. __GLS_RAISE_ERROR(GLS_NOT_FOUND);
  959. return 0;
  960. }
  961. }
  962. const GLubyte* glsGetStreamReadName(const GLubyte *inName) {
  963. __GLScontext *const ctx = __GLS_CONTEXT;
  964. __GLScontextStream *contextStream;
  965. __GLSreadStream *readStream;
  966. GLboolean ok;
  967. if (!__glsRequireContext()) return GLS_NONE;
  968. if (!__glsValidateString(inName)) return GLS_NONE;
  969. if (
  970. contextStream =
  971. __glsStr2PtrDict_find(ctx->contextStreamDict, inName)
  972. ) {
  973. ok = __glsString_assign(&ctx->returnString, contextStream->name.head);
  974. } else if (readStream = __glsReadStream_create(inName)) {
  975. ok = __glsString_assign(&ctx->returnString, readStream->name.head);
  976. __glsReadStream_destroy(readStream);
  977. } else {
  978. __GLS_RAISE_ERROR(GLS_NOT_FOUND);
  979. return GLS_NONE;
  980. }
  981. return ok ? ctx->returnString.head : GLS_NONE;
  982. }
  983. size_t glsGetStreamSize(const GLubyte *inName) {
  984. __GLScontextStream *contextStream;
  985. __GLSreadStream *readStream;
  986. if (!__glsRequireContext()) return 0;
  987. if (!__glsValidateString(inName)) return 0;
  988. glsFlush(GLS_ALL);
  989. if (
  990. contextStream =
  991. __glsStr2PtrDict_find(__GLS_CONTEXT->contextStreamDict, inName)
  992. ) {
  993. return __glsContextStream_getByteCount(contextStream);
  994. } else if (readStream = __glsReadStream_create(inName)) {
  995. const size_t outVal = __glsReadStream_getByteCount(readStream);
  996. __glsReadStream_destroy(readStream);
  997. return outVal;
  998. } else {
  999. __GLS_RAISE_ERROR(GLS_NOT_FOUND);
  1000. return 0;
  1001. }
  1002. }
  1003. GLSenum glsGetStreamType(const GLubyte *inName) {
  1004. __GLSreadStream *readStream;
  1005. if (!__glsRequireContext()) return GLS_NONE;
  1006. if (!__glsValidateString(inName)) return GLS_NONE;
  1007. if (__glsStr2PtrDict_find(__GLS_CONTEXT->contextStreamDict, inName)) {
  1008. return GLS_CONTEXT;
  1009. } else if (readStream = __glsReadStream_create(inName)) {
  1010. const GLSenum outVal = __glsReadStream_getType(readStream);
  1011. __glsReadStream_destroy(readStream);
  1012. return outVal;
  1013. } else {
  1014. __GLS_RAISE_ERROR(GLS_NOT_FOUND);
  1015. return GLS_NONE;
  1016. }
  1017. }
  1018. GLboolean glsIsContextStream(const GLubyte *inName) {
  1019. if (!__glsRequireContext()) return GL_FALSE;
  1020. if (!__glsValidateString(inName)) return GL_FALSE;
  1021. return (GLboolean)(
  1022. __glsStr2PtrDict_find(__GLS_CONTEXT->contextStreamDict, inName) !=
  1023. GLS_NONE
  1024. );
  1025. }
  1026. void glsPixelSetupGen(GLboolean inEnabled) {
  1027. __GLS_CONTEXT->pixelSetupGen = (GLboolean)(inEnabled ? GL_TRUE : GL_FALSE);
  1028. }
  1029. void glsReadFunc(GLSreadFunc inFunc) {
  1030. if (!__glsRequireContext()) return;
  1031. __GLS_CONTEXT->readFunc = inFunc;
  1032. }
  1033. void glsReadPrefix(GLSenum inListOp, const GLubyte *inPrefix) {
  1034. __GLScontext *const ctx = __GLS_CONTEXT;
  1035. __GLSlistString *prefix;
  1036. if (!__glsRequireContext()) return;
  1037. if (!__glsValidateString(inPrefix)) return;
  1038. switch (inListOp) {
  1039. case GLS_APPEND:
  1040. if (prefix = __glsListString_create(inPrefix)) {
  1041. __GLS_ITERLIST_APPEND(&ctx->readPrefixList, prefix);
  1042. }
  1043. break;
  1044. case GLS_PREPEND:
  1045. if (prefix = __glsListString_create(inPrefix)) {
  1046. __GLS_ITERLIST_PREPEND(&ctx->readPrefixList, prefix);
  1047. }
  1048. break;
  1049. default:
  1050. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  1051. break;
  1052. }
  1053. }
  1054. void glsUnreadFunc(GLSwriteFunc inFunc) {
  1055. if (!__glsRequireContext()) return;
  1056. __GLS_CONTEXT->unreadFunc = inFunc;
  1057. }
  1058. void glsWriteFunc(GLSwriteFunc inFunc) {
  1059. if (!__glsRequireContext()) return;
  1060. __GLS_CONTEXT->writeFunc = inFunc;
  1061. }
  1062. void glsWritePrefix(const GLubyte *inPrefix) {
  1063. if (!__glsRequireContext()) return;
  1064. if (!__glsValidateString(inPrefix)) return;
  1065. __glsString_assign(&__GLS_CONTEXT->writePrefix->val, inPrefix);
  1066. }