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.

692 lines
18 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 <string.h>
  19. #include <time.h>
  20. static GLuint __glsContextCount = 0;
  21. static GLuint __glsNextContext = 1;
  22. typedef struct {
  23. GLuint mask1;
  24. GLuint val1;
  25. GLuint shift;
  26. GLuint mask4;
  27. GLuint val4;
  28. } __GLSutf8format;
  29. static const __GLSutf8format __glsUTF8formats[] = {
  30. {0x80, 0x00, 0, 0x0000007f, 0x00000000,},
  31. {0xe0, 0xc0, 6, 0x000007ff, 0x00000080,},
  32. {0xf0, 0xe0, 12, 0x0000ffff, 0x00000800,},
  33. {0xf8, 0xf0, 18, 0x001fffff, 0x00010000,},
  34. {0xfc, 0xf8, 24, 0x03ffffff, 0x00200000,},
  35. {0xfe, 0xfc, 30, 0x7fffffff, 0x04000000,},
  36. {0x00, 0x00, 0, 0x00000000, 0x00000000,},
  37. };
  38. GLSenum glsBinary(GLboolean inSwapped) {
  39. return inSwapped ? __GLS_BINARY_SWAP1 : __GLS_BINARY_SWAP0;
  40. }
  41. GLSenum glsCommandAPI(GLSopcode inOpcode) {
  42. const GLSenum outVal = __glsOpcodeAPI(inOpcode);
  43. if (!outVal) __GLS_RAISE_ERROR(GLS_UNSUPPORTED_COMMAND);
  44. return outVal;
  45. }
  46. const GLubyte* glsCommandString(GLSopcode inOpcode) {
  47. if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
  48. return __glsOpcodeString[__glsMapOpcode(inOpcode)];
  49. }
  50. void glsContext(GLuint inContext) {
  51. __GLScontext *ctx = __GLS_CONTEXT;
  52. __GLScontext *newCtx;
  53. if (ctx && (ctx->callNesting || ctx->captureEntryCount)) {
  54. __GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
  55. return;
  56. }
  57. if (inContext) {
  58. __glsBeginCriticalSection();
  59. if (
  60. newCtx = (__GLScontext *)__glsInt2PtrDict_find(
  61. __glsContextDict, (GLint)inContext
  62. )
  63. ) {
  64. if (newCtx == ctx) {
  65. newCtx = GLS_NONE;
  66. } else {
  67. if (newCtx->current) {
  68. __GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
  69. newCtx = GLS_NONE;
  70. } else {
  71. newCtx->current = GL_TRUE;
  72. if (ctx)
  73. {
  74. if (ctx->deleted)
  75. {
  76. __glsContext_destroy(ctx);
  77. }
  78. else
  79. {
  80. ctx->current = GL_FALSE;
  81. }
  82. }
  83. }
  84. }
  85. } else {
  86. __GLS_RAISE_ERROR(GLS_NOT_FOUND);
  87. }
  88. __glsEndCriticalSection();
  89. if (newCtx) {
  90. __GLS_PUT_CONTEXT(newCtx);
  91. __glsUpdateDispatchTables();
  92. }
  93. } else if (ctx) {
  94. __glsBeginCriticalSection();
  95. if (ctx->deleted) {
  96. __glsContext_destroy(ctx);
  97. } else {
  98. ctx->current = GL_FALSE;
  99. }
  100. __glsEndCriticalSection();
  101. __GLS_PUT_CONTEXT(GLS_NONE);
  102. __glsUpdateDispatchTables();
  103. }
  104. }
  105. void glsDeleteContext(GLuint inContext) {
  106. if (inContext) {
  107. __GLScontext *ctx;
  108. __glsBeginCriticalSection();
  109. if (
  110. ctx = (__GLScontext *)__glsInt2PtrDict_find(
  111. __glsContextDict, (GLint)inContext
  112. )
  113. ) {
  114. __glsIntDict_remove(__glsContextDict, (GLint)inContext);
  115. __GLS_LIST_REMOVE(&__glsContextList, ctx);
  116. --__glsContextCount;
  117. if (ctx->current) {
  118. ctx->deleted = GL_TRUE;
  119. } else {
  120. __glsContext_destroy(ctx);
  121. }
  122. } else {
  123. __GLS_RAISE_ERROR(GLS_NOT_FOUND);
  124. }
  125. __glsEndCriticalSection();
  126. } else {
  127. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  128. }
  129. }
  130. const GLubyte* glsEnumString(GLSenum inAPI, GLSenum inEnum) {
  131. GLint offset, page;
  132. switch (inAPI) {
  133. case GLS_API_GLS:
  134. page = __GLS_ENUM_PAGE(inEnum);
  135. offset = __GLS_ENUM_OFFSET(inEnum);
  136. if (
  137. page < __GLS_ENUM_PAGE_COUNT &&
  138. offset < __glsEnumStringCount[page] &&
  139. __glsEnumString[page][offset]
  140. ) {
  141. return __glsEnumString[page][offset];
  142. }
  143. break;
  144. case GLS_API_GL:
  145. page = __GL_ENUM_PAGE(inEnum);
  146. offset = __GL_ENUM_OFFSET(inEnum);
  147. if (
  148. page < __GL_ENUM_PAGE_COUNT &&
  149. offset < __glEnumStringCount[page] &&
  150. __glEnumString[page][offset]
  151. ) {
  152. return __glEnumString[page][offset];
  153. }
  154. break;
  155. }
  156. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  157. return GLS_NONE;
  158. }
  159. GLuint glsGenContext(void) {
  160. GLboolean added = GL_FALSE;
  161. __GLScontext *ctx;
  162. GLuint name;
  163. __glsBeginCriticalSection();
  164. name = __glsNextContext;
  165. if (
  166. (ctx = __glsContext_create(name)) &&
  167. (added = __glsInt2PtrDict_add(__glsContextDict, (GLint)name, ctx))
  168. ) {
  169. ++__glsContextCount;
  170. ++__glsNextContext;
  171. __GLS_LIST_APPEND(&__glsContextList, ctx);
  172. }
  173. __glsEndCriticalSection();
  174. if (added) {
  175. return name;
  176. } else {
  177. __glsContext_destroy(ctx);
  178. return 0;
  179. }
  180. }
  181. GLuint* glsGetAllContexts(void) {
  182. GLuint *buf = GLS_NONE;
  183. GLint i = 0;
  184. __glsBeginCriticalSection();
  185. if (buf = __glsMalloc((__glsContextCount + 1) * sizeof(GLuint))) {
  186. __GLS_LIST_ITER(__GLScontext) iter;
  187. __GLS_LIST_FIRST(&__glsContextList, &iter);
  188. while (iter.elem) {
  189. buf[i++] = iter.elem->name;
  190. __GLS_LIST_NEXT(&__glsContextList, &iter);
  191. }
  192. buf[i] = 0;
  193. }
  194. __glsEndCriticalSection();
  195. return buf;
  196. }
  197. GLScommandAlignment* glsGetCommandAlignment(
  198. GLSopcode inOpcode,
  199. GLSenum inExternStreamType,
  200. GLScommandAlignment *outAlignment
  201. ) {
  202. GLbitfield attrib;
  203. if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
  204. attrib = __glsOpcodeAttrib[__glsMapOpcode(inOpcode)];
  205. switch (inExternStreamType) {
  206. case GLS_BINARY_LSB_FIRST:
  207. case GLS_BINARY_MSB_FIRST:
  208. if (attrib & __GLS_COMMAND_ALIGN_EVEN32_BIT) {
  209. outAlignment->mask = 7;
  210. outAlignment->value = 0;
  211. } else if (attrib & __GLS_COMMAND_ALIGN_ODD32_BIT) {
  212. outAlignment->mask = 7;
  213. outAlignment->value = 4;
  214. } else {
  215. outAlignment->mask = 3;
  216. outAlignment->value = 0;
  217. }
  218. break;
  219. case GLS_TEXT:
  220. outAlignment->mask = 0;
  221. outAlignment->value = 0;
  222. break;
  223. default:
  224. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  225. return GLS_NONE;
  226. }
  227. return outAlignment;
  228. }
  229. GLbitfield glsGetCommandAttrib(GLSopcode inOpcode) {
  230. if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
  231. return (
  232. __glsOpcodeAttrib[__glsMapOpcode(inOpcode)] &
  233. __GLS_COMMAND_ATTRIB_MASK
  234. );
  235. }
  236. GLint glsGetConsti(GLSenum inAttrib) {
  237. switch (inAttrib) {
  238. case GLS_API_COUNT:
  239. return __GLS_API_COUNT;
  240. case GLS_MAX_CALL_NESTING:
  241. return __GLS_MAX_CALL_NESTING;
  242. case GLS_MAX_CAPTURE_NESTING:
  243. return __GLS_MAX_CAPTURE_NESTING;
  244. case GLS_VERSION_MAJOR:
  245. return __GLS_VERSION_MAJOR;
  246. case GLS_VERSION_MINOR:
  247. return __GLS_VERSION_MINOR;
  248. }
  249. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  250. return GLS_NONE;
  251. }
  252. const GLint* glsGetConstiv(GLSenum inAttrib) {
  253. switch (inAttrib) {
  254. case GLS_ALL_APIS:
  255. return (const GLint *)__glsAllAPIs;
  256. }
  257. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  258. return GLS_NONE;
  259. }
  260. const GLubyte* glsGetConstubz(GLSenum inAttrib) {
  261. switch (inAttrib) {
  262. case GLS_EXTENSIONS:
  263. return __glsExtensions;
  264. case GLS_PLATFORM:
  265. return glsCSTR(__GLS_PLATFORM);
  266. case GLS_RELEASE:
  267. return glsCSTR(__GLS_RELEASE);
  268. case GLS_VENDOR:
  269. return glsCSTR(__GLS_VENDOR);
  270. }
  271. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  272. return GLS_NONE;
  273. }
  274. GLuint glsGetCurrentContext(void) {
  275. return __GLS_CONTEXT ? __GLS_CONTEXT->name : 0;
  276. }
  277. GLint* glsGetCurrentTime(GLint *outTime) {
  278. GLint i;
  279. const time_t t = time(GLS_NONE);
  280. struct tm utc, *utcp;
  281. __glsBeginCriticalSection();
  282. if (utcp = gmtime(&t)) utc = *utcp;
  283. __glsEndCriticalSection();
  284. if (t != (time_t)-1 && utcp) {
  285. outTime[0] = 1900 + utc.tm_year;
  286. outTime[1] = 1 + utc.tm_mon;
  287. outTime[2] = utc.tm_mday;
  288. outTime[3] = utc.tm_hour;
  289. outTime[4] = utc.tm_min;
  290. outTime[5] = utc.tm_sec;
  291. return outTime;
  292. }
  293. for (i = 0 ; i < 6 ; ++i) outTime[i] = 0;
  294. return GLS_NONE;
  295. }
  296. GLSenum glsGetError(GLboolean inClear) {
  297. const GLSenum outError = __GLS_ERROR;
  298. if (inClear) __GLS_PUT_ERROR(GLS_NONE);
  299. return outError;
  300. }
  301. GLint glsGetOpcodeCount(GLSenum inAPI) {
  302. switch (inAPI) {
  303. case GLS_API_GLS:
  304. return __glsOpcodesGLSCount;
  305. case GLS_API_GL:
  306. return __glsOpcodesGLCount;
  307. }
  308. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  309. return GLS_NONE;
  310. }
  311. const GLSopcode* glsGetOpcodes(GLSenum inAPI) {
  312. switch (inAPI) {
  313. case GLS_API_GLS:
  314. return __glsOpcodesGLS;
  315. case GLS_API_GL:
  316. return __glsOpcodesGL;
  317. }
  318. __GLS_RAISE_ERROR(GLS_INVALID_ENUM);
  319. return GLS_NONE;
  320. }
  321. GLboolean glsIsContext(GLuint inContext) {
  322. __GLScontext *ctx;
  323. __glsBeginCriticalSection();
  324. ctx = (__GLScontext *)__glsInt2PtrDict_find(
  325. __glsContextDict, (GLint)inContext
  326. );
  327. __glsEndCriticalSection();
  328. return (GLboolean)(ctx != GLS_NONE);
  329. }
  330. static GLboolean __glsFindExtension(
  331. const GLubyte *inExtension, const GLubyte *inList
  332. ) {
  333. const GLubyte *p0 = inList;
  334. while (
  335. p0 =
  336. (const GLubyte *)strstr((const char *)p0, (const char *)inExtension)
  337. ) {
  338. const GLubyte *const p1 = p0 + strlen((const char *)inExtension);
  339. if (!*p1 || *p1 == ' ') return GL_TRUE;
  340. p0 = p1;
  341. }
  342. return GL_FALSE;
  343. }
  344. GLboolean glsIsExtensionSupported(const GLubyte *inExtension) {
  345. if (!__glsValidateString(inExtension)) return GL_FALSE;
  346. if (!__glsFindExtension(inExtension, __glsExtensions)) return GL_FALSE;
  347. if (!strncmp((const char *)inExtension, "GL_", 3)) {
  348. const GLubyte *const p = glGetString(GL_EXTENSIONS);
  349. if (!p || !__glsFindExtension(inExtension, p)) return GL_FALSE;
  350. }
  351. return GL_TRUE;
  352. }
  353. GLboolean glsIsUTF8String(const GLubyte *inString) {
  354. GLuint b;
  355. while (b = *inString) {
  356. if (b & 0x80) goto slowPath;
  357. ++inString;
  358. }
  359. return GL_TRUE;
  360. slowPath:
  361. while (*inString) {
  362. const GLint n = glsUTF8toUCS4(inString, &b);
  363. if (!n) return GL_FALSE;
  364. inString += n;
  365. }
  366. return GL_TRUE;
  367. }
  368. GLlong glsLong(GLint inHigh, GLuint inLow) {
  369. #if __GLS_INT64
  370. return ((GLlong)inHigh) << 32 | inLow;
  371. #elif __GLS_MSB_FIRST
  372. GLlong outVal;
  373. outVal.uint0 = inHigh;
  374. outVal.uint1 = inLow;
  375. return outVal;
  376. #else /* !__GLS_MSB_FIRST */
  377. GLlong outVal;
  378. outVal.uint0 = inLow;
  379. outVal.uint1 = inHigh;
  380. return outVal;
  381. #endif /* __GLS_INT64 */
  382. }
  383. GLint glsLongHigh(GLlong inVal) {
  384. #if __GLS_INT64
  385. return (GLint)(inVal >> 32 & 0xffffffff);
  386. #elif __GLS_MSB_FIRST
  387. return inVal.uint0;
  388. #else /* !__GLS_MSB_FIRST */
  389. return inVal.uint1;
  390. #endif /* __GLS_INT64 */
  391. }
  392. GLuint glsLongLow(GLlong inVal) {
  393. #if __GLS_INT64
  394. return (GLuint)(inVal & 0xffffffff);
  395. #elif __GLS_MSB_FIRST
  396. return inVal.uint1;
  397. #else /* !__GLS_MSB_FIRST */
  398. return inVal.uint0;
  399. #endif /* __GLS_INT64 */
  400. }
  401. void glsPixelSetup(void) {
  402. __glsPixelSetup_pack();
  403. __glsPixelSetup_unpack();
  404. }
  405. GLulong glsULong(GLuint inHigh, GLuint inLow) {
  406. #if __GLS_INT64
  407. return ((GLulong)inHigh) << 32 | inLow;
  408. #elif __GLS_MSB_FIRST
  409. GLulong outVal;
  410. outVal.uint0 = inHigh;
  411. outVal.uint1 = inLow;
  412. return outVal;
  413. #else /* !__GLS_MSB_FIRST */
  414. GLulong outVal;
  415. outVal.uint0 = inLow;
  416. outVal.uint1 = inHigh;
  417. return outVal;
  418. #endif /* __GLS_INT64 */
  419. }
  420. GLuint glsULongHigh(GLulong inVal) {
  421. #if __GLS_INT64
  422. return (GLuint)(inVal >> 32 & 0xffffffff);
  423. #elif __GLS_MSB_FIRST
  424. return inVal.uint0;
  425. #else /* !__GLS_MSB_FIRST */
  426. return inVal.uint1;
  427. #endif /* __GLS_INT64 */
  428. }
  429. GLuint glsULongLow(GLulong inVal) {
  430. #if __GLS_INT64
  431. return (GLuint)(inVal & 0xffffffff);
  432. #elif __GLS_MSB_FIRST
  433. return inVal.uint1;
  434. #else /* !__GLS_MSB_FIRST */
  435. return inVal.uint0;
  436. #endif /* __GLS_INT64 */
  437. }
  438. GLint glsUCS4toUTF8(GLuint inUCS4, GLubyte *outUTF8) {
  439. const __GLSutf8format *format;
  440. GLint outVal = 1;
  441. for (format = __glsUTF8formats ; format->mask1 ; ++format, ++outVal) {
  442. if (inUCS4 <= format->mask4) {
  443. GLuint shift = format->shift;
  444. *outUTF8++ = (GLubyte)(format->val1 | (inUCS4 >> shift));
  445. while (shift) {
  446. shift -= 6;
  447. *outUTF8++ = (GLubyte)(0x80 | ((inUCS4 >> shift) & 0x3f));
  448. }
  449. return outVal;
  450. }
  451. }
  452. return 0;
  453. }
  454. GLubyte* glsUCStoUTF8z(
  455. size_t inUCSbytes,
  456. const GLvoid *inUCSz,
  457. size_t inUTF8max,
  458. GLubyte *outUTF8z
  459. ) {
  460. switch (inUCSbytes) {
  461. case 1:
  462. return glsUCS1toUTF8z(
  463. (const GLubyte *)inUCSz, inUTF8max, outUTF8z
  464. );
  465. case 2:
  466. return glsUCS2toUTF8z(
  467. (const GLushort *)inUCSz, inUTF8max, outUTF8z
  468. );
  469. case 4:
  470. return glsUCS4toUTF8z(
  471. (const GLuint *)inUCSz, inUTF8max, outUTF8z
  472. );
  473. default:
  474. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  475. return GLS_NONE;
  476. }
  477. }
  478. GLubyte* glsUCS1toUTF8z(
  479. const GLubyte *inUCS1z, size_t inUTF8max, GLubyte *outUTF8z
  480. ) {
  481. GLuint b;
  482. GLubyte *const limit = outUTF8z + inUTF8max - 1;
  483. GLubyte *p = outUTF8z;
  484. while (b = *inUCS1z++) {
  485. if (p >= limit) return GLS_NONE;
  486. p += glsUCS4toUTF8(b, p);
  487. }
  488. if (p > limit) return GLS_NONE;
  489. *p = 0;
  490. return outUTF8z;
  491. }
  492. GLubyte* glsUCS2toUTF8z(
  493. const GLushort *inUCS2z, size_t inUTF8max, GLubyte *outUTF8z
  494. ) {
  495. GLuint b;
  496. GLubyte buf[3];
  497. GLubyte *const limit = outUTF8z + inUTF8max - 1;
  498. GLubyte *p = outUTF8z;
  499. while (b = *inUCS2z++) {
  500. GLubyte *bufPtr = buf;
  501. GLubyte *p0 = p;
  502. p += glsUCS4toUTF8(b, bufPtr);
  503. if (p > limit) return GLS_NONE;
  504. while (p0 < p) *p0++ = *bufPtr++;
  505. }
  506. *p = 0;
  507. return outUTF8z;
  508. }
  509. GLubyte* glsUCS4toUTF8z(
  510. const GLuint *inUCS4z, size_t inUTF8max, GLubyte *outUTF8z
  511. ) {
  512. GLuint b;
  513. GLubyte buf[6];
  514. GLubyte *const limit = outUTF8z + inUTF8max - 1;
  515. GLubyte *p = outUTF8z;
  516. while (b = *inUCS4z++) {
  517. GLubyte *bufPtr = buf;
  518. GLubyte *p0 = p;
  519. p += glsUCS4toUTF8(b, bufPtr);
  520. if (p > limit) return GLS_NONE;
  521. while (p0 < p) *p0++ = *bufPtr++;
  522. }
  523. *p = 0;
  524. return outUTF8z;
  525. }
  526. GLint glsUTF8toUCS4(const GLubyte *inUTF8, GLuint *outUCS4) {
  527. GLuint b, b0, ucs4;
  528. const __GLSutf8format *format;
  529. GLint outVal = 1;
  530. ucs4 = b0 = *inUTF8++;
  531. for (format = __glsUTF8formats ; format->mask1 ; ++format, ++outVal) {
  532. if ((b0 & format->mask1) == format->val1) {
  533. ucs4 &= format->mask4;
  534. if (ucs4 < format->val4) return 0;
  535. *outUCS4 = ucs4;
  536. return outVal;
  537. }
  538. b = *inUTF8++ ^ 0x80;
  539. if (b & 0xc0) return 0;
  540. ucs4 = (ucs4 << 6) | b;
  541. }
  542. return 0;
  543. }
  544. GLboolean glsUTF8toUCSz(
  545. size_t inUCSbytes,
  546. const GLubyte *inUTF8z,
  547. size_t inUCSmax,
  548. GLvoid *outUCSz
  549. ) {
  550. switch (inUCSbytes) {
  551. case 1:
  552. return glsUTF8toUCS1z(inUTF8z, inUCSmax, (GLubyte *)outUCSz);
  553. case 2:
  554. return glsUTF8toUCS2z(inUTF8z, inUCSmax, (GLushort *)outUCSz);
  555. case 4:
  556. return glsUTF8toUCS4z(inUTF8z, inUCSmax, (GLuint *)outUCSz);
  557. default:
  558. __GLS_RAISE_ERROR(GLS_INVALID_VALUE);
  559. return GL_FALSE;
  560. }
  561. }
  562. GLboolean glsUTF8toUCS1z(
  563. const GLubyte *inUTF8z, size_t inUCS1max, GLubyte *outUCS1z
  564. ) {
  565. GLuint b;
  566. GLubyte *const limit = outUCS1z + inUCS1max - 1;
  567. while (*inUTF8z) {
  568. const GLint n = glsUTF8toUCS4(inUTF8z, &b);
  569. if (n && b <= 0xff && outUCS1z < limit) {
  570. inUTF8z += n;
  571. *outUCS1z++ = (GLubyte)b;
  572. } else {
  573. return GL_FALSE;
  574. }
  575. }
  576. if (outUCS1z > limit) return GL_FALSE;
  577. *outUCS1z = 0;
  578. return GL_TRUE;
  579. }
  580. GLboolean glsUTF8toUCS2z(
  581. const GLubyte *inUTF8z, size_t inUCS2max, GLushort *outUCS2z
  582. ) {
  583. GLuint b;
  584. GLushort *const limit = outUCS2z + inUCS2max - 1;
  585. while (*inUTF8z) {
  586. const GLint n = glsUTF8toUCS4(inUTF8z, &b);
  587. if (n && b <= 0xffff && outUCS2z < limit) {
  588. inUTF8z += n;
  589. *outUCS2z++ = (GLushort)b;
  590. } else {
  591. return GL_FALSE;
  592. }
  593. }
  594. if (outUCS2z > limit) return GL_FALSE;
  595. *outUCS2z = 0;
  596. return GL_TRUE;
  597. }
  598. GLboolean glsUTF8toUCS4z(
  599. const GLubyte *inUTF8z, size_t inUCS4max, GLuint *outUCS4z
  600. ) {
  601. GLuint b;
  602. GLuint *const limit = outUCS4z + inUCS4max - 1;
  603. while (*inUTF8z) {
  604. const GLint n = glsUTF8toUCS4(inUTF8z, &b);
  605. if (n && outUCS4z < limit) {
  606. inUTF8z += n;
  607. *outUCS4z++ = b;
  608. } else {
  609. return GL_FALSE;
  610. }
  611. }
  612. if (outUCS4z > limit) return GL_FALSE;
  613. *outUCS4z = 0;
  614. return GL_TRUE;
  615. }