Windows2003-3790/multimedia/opengl/gls/lib/global.c
2020-09-30 16:53:55 +02:00

693 lines
19 KiB
C

/*
** Copyright 1995-2095, Silicon Graphics, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of Silicon Graphics, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
*/
#include "glslib.h"
#include <string.h>
#include <time.h>
static GLuint __glsContextCount = 0;
static GLuint __glsNextContext = 1;
typedef struct {
GLuint mask1;
GLuint val1;
GLuint shift;
GLuint mask4;
GLuint val4;
} __GLSutf8format;
static const __GLSutf8format __glsUTF8formats[] = {
{0x80, 0x00, 0, 0x0000007f, 0x00000000,},
{0xe0, 0xc0, 6, 0x000007ff, 0x00000080,},
{0xf0, 0xe0, 12, 0x0000ffff, 0x00000800,},
{0xf8, 0xf0, 18, 0x001fffff, 0x00010000,},
{0xfc, 0xf8, 24, 0x03ffffff, 0x00200000,},
{0xfe, 0xfc, 30, 0x7fffffff, 0x04000000,},
{0x00, 0x00, 0, 0x00000000, 0x00000000,},
};
GLSenum glsBinary(GLboolean inSwapped) {
return inSwapped ? __GLS_BINARY_SWAP1 : __GLS_BINARY_SWAP0;
}
GLSenum glsCommandAPI(GLSopcode inOpcode) {
const GLSenum outVal = __glsOpcodeAPI(inOpcode);
if (!outVal) __GLS_RAISE_ERROR(GLS_UNSUPPORTED_COMMAND);
return outVal;
}
const GLubyte* glsCommandString(GLSopcode inOpcode) {
if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
return __glsOpcodeString[__glsMapOpcode(inOpcode)];
}
void glsContext(GLuint inContext) {
__GLScontext *ctx = __GLS_CONTEXT;
__GLScontext *newCtx;
if (ctx && (ctx->callNesting || ctx->captureEntryCount)) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
return;
}
if (inContext) {
__glsBeginCriticalSection();
if (
newCtx = (__GLScontext *)__glsInt2PtrDict_find(
__glsContextDict, (GLint)inContext
)
) {
if (newCtx == ctx) {
newCtx = GLS_NONE;
} else {
if (newCtx->current) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
newCtx = GLS_NONE;
} else {
newCtx->current = GL_TRUE;
if (ctx)
{
if (ctx->deleted)
{
__glsContext_destroy(ctx);
}
else
{
ctx->current = GL_FALSE;
}
}
}
}
} else {
__GLS_RAISE_ERROR(GLS_NOT_FOUND);
}
__glsEndCriticalSection();
if (newCtx) {
__GLS_PUT_CONTEXT(newCtx);
__glsUpdateDispatchTables();
}
} else if (ctx) {
__glsBeginCriticalSection();
if (ctx->deleted) {
__glsContext_destroy(ctx);
} else {
ctx->current = GL_FALSE;
}
__glsEndCriticalSection();
__GLS_PUT_CONTEXT(GLS_NONE);
__glsUpdateDispatchTables();
}
}
void glsDeleteContext(GLuint inContext) {
if (inContext) {
__GLScontext *ctx;
__glsBeginCriticalSection();
if (
ctx = (__GLScontext *)__glsInt2PtrDict_find(
__glsContextDict, (GLint)inContext
)
) {
__glsIntDict_remove(__glsContextDict, (GLint)inContext);
__GLS_LIST_REMOVE(&__glsContextList, ctx);
--__glsContextCount;
if (ctx->current) {
ctx->deleted = GL_TRUE;
} else {
__glsContext_destroy(ctx);
}
} else {
__GLS_RAISE_ERROR(GLS_NOT_FOUND);
}
__glsEndCriticalSection();
} else {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
}
}
const GLubyte* glsEnumString(GLSenum inAPI, GLSenum inEnum) {
GLint offset, page;
switch (inAPI) {
case GLS_API_GLS:
page = __GLS_ENUM_PAGE(inEnum);
offset = __GLS_ENUM_OFFSET(inEnum);
if (
page < __GLS_ENUM_PAGE_COUNT &&
offset < __glsEnumStringCount[page] &&
__glsEnumString[page][offset]
) {
return __glsEnumString[page][offset];
}
break;
case GLS_API_GL:
page = __GL_ENUM_PAGE(inEnum);
offset = __GL_ENUM_OFFSET(inEnum);
if (
page < __GL_ENUM_PAGE_COUNT &&
offset < __glEnumStringCount[page] &&
__glEnumString[page][offset]
) {
return __glEnumString[page][offset];
}
break;
}
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
return GLS_NONE;
}
GLuint glsGenContext(void) {
GLboolean added = GL_FALSE;
__GLScontext *ctx;
GLuint name;
__glsBeginCriticalSection();
name = __glsNextContext;
if (
(ctx = __glsContext_create(name)) &&
(added = __glsInt2PtrDict_add(__glsContextDict, (GLint)name, ctx))
) {
++__glsContextCount;
++__glsNextContext;
__GLS_LIST_APPEND(&__glsContextList, ctx);
}
__glsEndCriticalSection();
if (added) {
return name;
} else {
__glsContext_destroy(ctx);
return 0;
}
}
GLuint* glsGetAllContexts(void) {
GLuint *buf = GLS_NONE;
GLint i = 0;
__glsBeginCriticalSection();
if (buf = __glsMalloc((__glsContextCount + 1) * sizeof(GLuint))) {
__GLS_LIST_ITER(__GLScontext) iter;
__GLS_LIST_FIRST(&__glsContextList, &iter);
while (iter.elem) {
buf[i++] = iter.elem->name;
__GLS_LIST_NEXT(&__glsContextList, &iter);
}
buf[i] = 0;
}
__glsEndCriticalSection();
return buf;
}
GLScommandAlignment* glsGetCommandAlignment(
GLSopcode inOpcode,
GLSenum inExternStreamType,
GLScommandAlignment *outAlignment
) {
GLbitfield attrib;
if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
attrib = __glsOpcodeAttrib[__glsMapOpcode(inOpcode)];
switch (inExternStreamType) {
case GLS_BINARY_LSB_FIRST:
case GLS_BINARY_MSB_FIRST:
if (attrib & __GLS_COMMAND_ALIGN_EVEN32_BIT) {
outAlignment->mask = 7;
outAlignment->value = 0;
} else if (attrib & __GLS_COMMAND_ALIGN_ODD32_BIT) {
outAlignment->mask = 7;
outAlignment->value = 4;
} else {
outAlignment->mask = 3;
outAlignment->value = 0;
}
break;
case GLS_TEXT:
outAlignment->mask = 0;
outAlignment->value = 0;
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
return GLS_NONE;
}
return outAlignment;
}
GLbitfield glsGetCommandAttrib(GLSopcode inOpcode) {
if (!__glsValidateOpcode(inOpcode)) return GLS_NONE;
return (
__glsOpcodeAttrib[__glsMapOpcode(inOpcode)] &
__GLS_COMMAND_ATTRIB_MASK
);
}
GLint glsGetConsti(GLSenum inAttrib) {
switch (inAttrib) {
case GLS_API_COUNT:
return __GLS_API_COUNT;
case GLS_MAX_CALL_NESTING:
return __GLS_MAX_CALL_NESTING;
case GLS_MAX_CAPTURE_NESTING:
return __GLS_MAX_CAPTURE_NESTING;
case GLS_VERSION_MAJOR:
return __GLS_VERSION_MAJOR;
case GLS_VERSION_MINOR:
return __GLS_VERSION_MINOR;
}
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
return GLS_NONE;
}
const GLint* glsGetConstiv(GLSenum inAttrib) {
switch (inAttrib) {
case GLS_ALL_APIS:
return (const GLint *)__glsAllAPIs;
}
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
return GLS_NONE;
}
const GLubyte* glsGetConstubz(GLSenum inAttrib) {
switch (inAttrib) {
case GLS_EXTENSIONS:
return __glsExtensions;
case GLS_PLATFORM:
return glsCSTR(__GLS_PLATFORM);
case GLS_RELEASE:
return glsCSTR(__GLS_RELEASE);
case GLS_VENDOR:
return glsCSTR(__GLS_VENDOR);
}
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
return GLS_NONE;
}
GLuint glsGetCurrentContext(void) {
return __GLS_CONTEXT ? __GLS_CONTEXT->name : 0;
}
GLint* glsGetCurrentTime(GLint *outTime) {
GLint i;
const time_t t = time(GLS_NONE);
struct tm utc, *utcp;
__glsBeginCriticalSection();
if (utcp = gmtime(&t)) utc = *utcp;
__glsEndCriticalSection();
if (t != (time_t)-1 && utcp) {
outTime[0] = 1900 + utc.tm_year;
outTime[1] = 1 + utc.tm_mon;
outTime[2] = utc.tm_mday;
outTime[3] = utc.tm_hour;
outTime[4] = utc.tm_min;
outTime[5] = utc.tm_sec;
return outTime;
}
for (i = 0 ; i < 6 ; ++i) outTime[i] = 0;
return GLS_NONE;
}
GLSenum glsGetError(GLboolean inClear) {
const GLSenum outError = __GLS_ERROR;
if (inClear) __GLS_PUT_ERROR(GLS_NONE);
return outError;
}
GLint glsGetOpcodeCount(GLSenum inAPI) {
switch (inAPI) {
case GLS_API_GLS:
return __glsOpcodesGLSCount;
case GLS_API_GL:
return __glsOpcodesGLCount;
}
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
return GLS_NONE;
}
const GLSopcode* glsGetOpcodes(GLSenum inAPI) {
switch (inAPI) {
case GLS_API_GLS:
return __glsOpcodesGLS;
case GLS_API_GL:
return __glsOpcodesGL;
}
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
return GLS_NONE;
}
GLboolean glsIsContext(GLuint inContext) {
__GLScontext *ctx;
__glsBeginCriticalSection();
ctx = (__GLScontext *)__glsInt2PtrDict_find(
__glsContextDict, (GLint)inContext
);
__glsEndCriticalSection();
return (GLboolean)(ctx != GLS_NONE);
}
static GLboolean __glsFindExtension(
const GLubyte *inExtension, const GLubyte *inList
) {
const GLubyte *p0 = inList;
while (
p0 =
(const GLubyte *)strstr((const char *)p0, (const char *)inExtension)
) {
const GLubyte *const p1 = p0 + strlen((const char *)inExtension);
if (!*p1 || *p1 == ' ') return GL_TRUE;
p0 = p1;
}
return GL_FALSE;
}
GLboolean glsIsExtensionSupported(const GLubyte *inExtension) {
if (!__glsValidateString(inExtension)) return GL_FALSE;
if (!__glsFindExtension(inExtension, __glsExtensions)) return GL_FALSE;
if (!strncmp((const char *)inExtension, "GL_", 3)) {
const GLubyte *const p = glGetString(GL_EXTENSIONS);
if (!p || !__glsFindExtension(inExtension, p)) return GL_FALSE;
}
return GL_TRUE;
}
GLboolean glsIsUTF8String(const GLubyte *inString) {
GLuint b;
while (b = *inString) {
if (b & 0x80) goto slowPath;
++inString;
}
return GL_TRUE;
slowPath:
while (*inString) {
const GLint n = glsUTF8toUCS4(inString, &b);
if (!n) return GL_FALSE;
inString += n;
}
return GL_TRUE;
}
GLlong glsLong(GLint inHigh, GLuint inLow) {
#if __GLS_INT64
return ((GLlong)inHigh) << 32 | inLow;
#elif __GLS_MSB_FIRST
GLlong outVal;
outVal.uint0 = inHigh;
outVal.uint1 = inLow;
return outVal;
#else /* !__GLS_MSB_FIRST */
GLlong outVal;
outVal.uint0 = inLow;
outVal.uint1 = inHigh;
return outVal;
#endif /* __GLS_INT64 */
}
GLint glsLongHigh(GLlong inVal) {
#if __GLS_INT64
return (GLint)(inVal >> 32 & 0xffffffff);
#elif __GLS_MSB_FIRST
return inVal.uint0;
#else /* !__GLS_MSB_FIRST */
return inVal.uint1;
#endif /* __GLS_INT64 */
}
GLuint glsLongLow(GLlong inVal) {
#if __GLS_INT64
return (GLuint)(inVal & 0xffffffff);
#elif __GLS_MSB_FIRST
return inVal.uint1;
#else /* !__GLS_MSB_FIRST */
return inVal.uint0;
#endif /* __GLS_INT64 */
}
void glsPixelSetup(void) {
__glsPixelSetup_pack();
__glsPixelSetup_unpack();
}
GLulong glsULong(GLuint inHigh, GLuint inLow) {
#if __GLS_INT64
return ((GLulong)inHigh) << 32 | inLow;
#elif __GLS_MSB_FIRST
GLulong outVal;
outVal.uint0 = inHigh;
outVal.uint1 = inLow;
return outVal;
#else /* !__GLS_MSB_FIRST */
GLulong outVal;
outVal.uint0 = inLow;
outVal.uint1 = inHigh;
return outVal;
#endif /* __GLS_INT64 */
}
GLuint glsULongHigh(GLulong inVal) {
#if __GLS_INT64
return (GLuint)(inVal >> 32 & 0xffffffff);
#elif __GLS_MSB_FIRST
return inVal.uint0;
#else /* !__GLS_MSB_FIRST */
return inVal.uint1;
#endif /* __GLS_INT64 */
}
GLuint glsULongLow(GLulong inVal) {
#if __GLS_INT64
return (GLuint)(inVal & 0xffffffff);
#elif __GLS_MSB_FIRST
return inVal.uint1;
#else /* !__GLS_MSB_FIRST */
return inVal.uint0;
#endif /* __GLS_INT64 */
}
GLint glsUCS4toUTF8(GLuint inUCS4, GLubyte *outUTF8) {
const __GLSutf8format *format;
GLint outVal = 1;
for (format = __glsUTF8formats ; format->mask1 ; ++format, ++outVal) {
if (inUCS4 <= format->mask4) {
GLuint shift = format->shift;
*outUTF8++ = (GLubyte)(format->val1 | (inUCS4 >> shift));
while (shift) {
shift -= 6;
*outUTF8++ = (GLubyte)(0x80 | ((inUCS4 >> shift) & 0x3f));
}
return outVal;
}
}
return 0;
}
GLubyte* glsUCStoUTF8z(
size_t inUCSbytes,
const GLvoid *inUCSz,
size_t inUTF8max,
GLubyte *outUTF8z
) {
switch (inUCSbytes) {
case 1:
return glsUCS1toUTF8z(
(const GLubyte *)inUCSz, inUTF8max, outUTF8z
);
case 2:
return glsUCS2toUTF8z(
(const GLushort *)inUCSz, inUTF8max, outUTF8z
);
case 4:
return glsUCS4toUTF8z(
(const GLuint *)inUCSz, inUTF8max, outUTF8z
);
default:
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
return GLS_NONE;
}
}
GLubyte* glsUCS1toUTF8z(
const GLubyte *inUCS1z, size_t inUTF8max, GLubyte *outUTF8z
) {
GLuint b;
GLubyte *const limit = outUTF8z + inUTF8max - 1;
GLubyte *p = outUTF8z;
while (b = *inUCS1z++) {
if (p >= limit) return GLS_NONE;
p += glsUCS4toUTF8(b, p);
}
if (p > limit) return GLS_NONE;
*p = 0;
return outUTF8z;
}
GLubyte* glsUCS2toUTF8z(
const GLushort *inUCS2z, size_t inUTF8max, GLubyte *outUTF8z
) {
GLuint b;
GLubyte buf[3];
GLubyte *const limit = outUTF8z + inUTF8max - 1;
GLubyte *p = outUTF8z;
while (b = *inUCS2z++) {
GLubyte *bufPtr = buf;
GLubyte *p0 = p;
p += glsUCS4toUTF8(b, bufPtr);
if (p > limit) return GLS_NONE;
while (p0 < p) *p0++ = *bufPtr++;
}
*p = 0;
return outUTF8z;
}
GLubyte* glsUCS4toUTF8z(
const GLuint *inUCS4z, size_t inUTF8max, GLubyte *outUTF8z
) {
GLuint b;
GLubyte buf[6];
GLubyte *const limit = outUTF8z + inUTF8max - 1;
GLubyte *p = outUTF8z;
while (b = *inUCS4z++) {
GLubyte *bufPtr = buf;
GLubyte *p0 = p;
p += glsUCS4toUTF8(b, bufPtr);
if (p > limit) return GLS_NONE;
while (p0 < p) *p0++ = *bufPtr++;
}
*p = 0;
return outUTF8z;
}
GLint glsUTF8toUCS4(const GLubyte *inUTF8, GLuint *outUCS4) {
GLuint b, b0, ucs4;
const __GLSutf8format *format;
GLint outVal = 1;
ucs4 = b0 = *inUTF8++;
for (format = __glsUTF8formats ; format->mask1 ; ++format, ++outVal) {
if ((b0 & format->mask1) == format->val1) {
ucs4 &= format->mask4;
if (ucs4 < format->val4) return 0;
*outUCS4 = ucs4;
return outVal;
}
b = *inUTF8++ ^ 0x80;
if (b & 0xc0) return 0;
ucs4 = (ucs4 << 6) | b;
}
return 0;
}
GLboolean glsUTF8toUCSz(
size_t inUCSbytes,
const GLubyte *inUTF8z,
size_t inUCSmax,
GLvoid *outUCSz
) {
switch (inUCSbytes) {
case 1:
return glsUTF8toUCS1z(inUTF8z, inUCSmax, (GLubyte *)outUCSz);
case 2:
return glsUTF8toUCS2z(inUTF8z, inUCSmax, (GLushort *)outUCSz);
case 4:
return glsUTF8toUCS4z(inUTF8z, inUCSmax, (GLuint *)outUCSz);
default:
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
return GL_FALSE;
}
}
GLboolean glsUTF8toUCS1z(
const GLubyte *inUTF8z, size_t inUCS1max, GLubyte *outUCS1z
) {
GLuint b;
GLubyte *const limit = outUCS1z + inUCS1max - 1;
while (*inUTF8z) {
const GLint n = glsUTF8toUCS4(inUTF8z, &b);
if (n && b <= 0xff && outUCS1z < limit) {
inUTF8z += n;
*outUCS1z++ = (GLubyte)b;
} else {
return GL_FALSE;
}
}
if (outUCS1z > limit) return GL_FALSE;
*outUCS1z = 0;
return GL_TRUE;
}
GLboolean glsUTF8toUCS2z(
const GLubyte *inUTF8z, size_t inUCS2max, GLushort *outUCS2z
) {
GLuint b;
GLushort *const limit = outUCS2z + inUCS2max - 1;
while (*inUTF8z) {
const GLint n = glsUTF8toUCS4(inUTF8z, &b);
if (n && b <= 0xffff && outUCS2z < limit) {
inUTF8z += n;
*outUCS2z++ = (GLushort)b;
} else {
return GL_FALSE;
}
}
if (outUCS2z > limit) return GL_FALSE;
*outUCS2z = 0;
return GL_TRUE;
}
GLboolean glsUTF8toUCS4z(
const GLubyte *inUTF8z, size_t inUCS4max, GLuint *outUCS4z
) {
GLuint b;
GLuint *const limit = outUCS4z + inUCS4max - 1;
while (*inUTF8z) {
const GLint n = glsUTF8toUCS4(inUTF8z, &b);
if (n && outUCS4z < limit) {
inUTF8z += n;
*outUCS4z++ = b;
} else {
return GL_FALSE;
}
}
if (outUCS4z > limit) return GL_FALSE;
*outUCS4z = 0;
return GL_TRUE;
}