windows-nt/Source/XPSP1/NT/multimedia/opengl/gls/lib/exec.c
2020-09-26 16:20:57 +08:00

551 lines
17 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 <stdlib.h>
#include <string.h>
static GLclampf __glsFloatToClampf(GLfloat inVal) {
if (inVal < 0.f) inVal = 0.f;
if (inVal > 1.f) inVal = 1.f;
return inVal;
}
void __gls_exec_glsBeginGLS(
GLint inVersionMajor, GLint inVersionMinor
) {
__GLS_CONTEXT->streamVersion.major = inVersionMajor;
__GLS_CONTEXT->streamVersion.minor = inVersionMinor;
}
void __gls_exec_glsBlock(GLSenum inBlockType) {
__GLScontext *const ctx = __GLS_CONTEXT;
switch (inBlockType) {
case GLS_FRAME:
case GLS_INIT:
case GLS_STATIC:
ctx->blockType = inBlockType;
break;
case GLS_HEADER:
if (__glsHeader_reset(&ctx->header)) ctx->blockType = inBlockType;
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
}
GLSenum __gls_exec_glsCallStream(const GLubyte *inName) {
__GLScontext *const ctx = __GLS_CONTEXT;
__GLScontextStream *contextStream;
__GLSreadStream *readStream;
GLSenum outType = GLS_NONE;
__GLSversion versionSave;
if (ctx->abortMode) return outType;
if (ctx->callNesting >= __GLS_MAX_CALL_NESTING) {
__GLS_RAISE_ERROR(GLS_CALL_OVERFLOW);
glsAbortCall(GLS_ALL);
return outType;
}
if (!__glsValidateString(inName)) return outType;
++ctx->callNesting;
versionSave = ctx->streamVersion;
ctx->streamVersion.major = ctx->streamVersion.minor = 0;
if (
contextStream = __glsStr2PtrDict_find(ctx->contextStreamDict, inName)
) {
GLint i;
outType = GLS_CONTEXT;
for (i = 0 ; i < ctx->captureNesting ; ++i) {
if (ctx->writers[i]->contextStream == contextStream) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
outType = GLS_NONE;
break;
}
}
if (outType == GLS_CONTEXT) __glsContextStream_call(contextStream);
} else if (readStream = __glsReadStream_create(inName)) {
__GLSreader reader;
if (__glsReader_init_stream(
&reader, readStream, __GLS_READER_BUF_BYTES
)) {
outType = reader.type;
__glsReader_call(&reader);
__glsReader_final(&reader);
} else {
__GLS_RAISE_ERROR(GLS_INVALID_STREAM);
}
__glsReadStream_destroy(readStream);
} else {
__GLS_RAISE_ERROR(GLS_NOT_FOUND);
}
--ctx->callNesting;
switch (ctx->abortMode) {
case GLS_ALL:
if (!ctx->callNesting) glsAbortCall(GLS_NONE);
break;
case GLS_LAST:
glsAbortCall(GLS_NONE);
break;
}
ctx->streamVersion = versionSave;
return outType;
}
void __gls_exec_glsEndGLS(void) {
__GLS_CONTEXT->streamVersion.major = 0;
__GLS_CONTEXT->streamVersion.minor = 0;
}
void __gls_exec_glsError(GLSopcode inOpcode, GLSenum inError) {
if (
inError &&
(inError < GLS_CALL_OVERFLOW || inError > GLS_UNSUPPORTED_EXTENSION)
) {
inError = GLS_INVALID_ENUM;
}
__GLS_RAISE_ERROR( UintToPtr(inError) );
}
void __gls_exec_glsGLRC(GLuint inGLRC) {
__GLScontext *const ctx = __GLS_CONTEXT;
if (!inGLRC || inGLRC > (GLuint)ctx->header.glrcCount) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
} else {
ctx->currentGLRC = inGLRC;
}
}
void __gls_exec_glsGLRCLayer(
GLuint inGLRC, GLuint inLayer, GLuint inReadLayer
) {
__GLScontext *const ctx = __GLS_CONTEXT;
if (
!inGLRC ||
inGLRC > (GLuint)ctx->header.glrcCount ||
!inLayer ||
inLayer > (GLuint)ctx->header.layerCount ||
inReadLayer > (GLuint)ctx->header.layerCount
) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
} else {
__GLSglrc *const glrc = ctx->header.glrcs + inGLRC - 1;
glrc->layer = inLayer;
glrc->readLayer = inReadLayer;
}
}
void __gls_exec_glsHeaderGLRCi(GLuint inGLRC, GLSenum inAttrib, GLint inVal) {
__GLScontext *const ctx = __GLS_CONTEXT;
__GLSglrc *glrc;
if (ctx->blockType != GLS_HEADER) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
return;
}
if (!inGLRC || inGLRC > (GLuint)ctx->header.glrcCount) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
return;
}
glrc = ctx->header.glrcs + inGLRC - 1;
switch (inAttrib) {
case GLS_LAYER:
if (inVal < 1 || inVal > ctx->header.layerCount) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
} else {
glrc->layer = inVal;
}
break;
case GLS_READ_LAYER:
if (inVal < 0 || inVal > ctx->header.layerCount) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
} else {
glrc->readLayer = inVal;
}
break;
case GLS_SHARE_GLRC:
if (inVal < 0 || inVal > ctx->header.glrcCount) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
} else {
glrc->shareGLRC = inVal;
}
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
}
void __gls_exec_glsHeaderLayerf(
GLuint inLayer, GLSenum inAttrib, GLfloat inVal
) {
__GLScontext *const ctx = __GLS_CONTEXT;
__GLSlayer *layer;
if (ctx->blockType != GLS_HEADER) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
return;
}
if (!inLayer || inLayer > (GLuint)ctx->header.layerCount) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
return;
}
layer = ctx->header.layers + inLayer - 1;
switch (inAttrib) {
case GLS_INVISIBLE_ASPECT:
layer->invisibleAspect = inVal > 0.f ? inVal : 0.f;
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
}
void __gls_exec_glsHeaderLayeri(
GLuint inLayer, GLSenum inAttrib, GLint inVal
) {
__GLScontext *const ctx = __GLS_CONTEXT;
__GLSlayer *layer;
if (ctx->blockType != GLS_HEADER) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
return;
}
if (!inLayer || inLayer > (GLuint)ctx->header.layerCount) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
return;
}
layer = ctx->header.layers + inLayer - 1;
switch (inAttrib) {
case GLS_DISPLAY_FORMAT:
switch (inVal) {
case GLS_IIII:
case GLS_RGBA:
case GLS_RRRA:
layer->displayFormat = inVal;
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
break;
case GLS_DOUBLEBUFFER:
layer->doubleBuffer = inVal ? GL_TRUE : GL_FALSE;
break;
case GLS_INVISIBLE:
layer->invisible = inVal ? GL_TRUE : GL_FALSE;
break;
case GLS_INVISIBLE_HEIGHT_PIXELS:
layer->invisibleHeightPixels = inVal > 0 ? inVal : 0;
break;
case GLS_LEVEL:
layer->level = inVal;
break;
case GLS_STEREO:
layer->stereo = inVal ? GL_TRUE : GL_FALSE;
break;
case GLS_TRANSPARENT:
layer->transparent = inVal ? GL_TRUE : GL_FALSE;
break;
case GLS_INDEX_BITS:
layer->indexBits = inVal > 0 ? inVal : 0;
break;
case GLS_RED_BITS:
layer->redBits = inVal > 0 ? inVal : 0;
break;
case GLS_GREEN_BITS:
layer->greenBits = inVal > 0 ? inVal : 0;
break;
case GLS_BLUE_BITS:
layer->blueBits = inVal > 0 ? inVal : 0;
break;
case GLS_ALPHA_BITS:
layer->alphaBits = inVal > 0 ? inVal : 0;
break;
case GLS_DEPTH_BITS:
layer->depthBits = inVal > 0 ? inVal : 0;
break;
case GLS_STENCIL_BITS:
layer->stencilBits = inVal > 0 ? inVal : 0;
break;
case GLS_ACCUM_RED_BITS:
layer->accumRedBits = inVal > 0 ? inVal : 0;
break;
case GLS_ACCUM_GREEN_BITS:
layer->accumGreenBits = inVal > 0 ? inVal : 0;
break;
case GLS_ACCUM_BLUE_BITS:
layer->accumBlueBits = inVal > 0 ? inVal : 0;
break;
case GLS_ACCUM_ALPHA_BITS:
layer->accumAlphaBits = inVal > 0 ? inVal : 0;
break;
case GLS_AUX_BUFFERS:
layer->auxBuffers = inVal > 0 ? inVal : 0;
break;
#if __GL_SGIS_multisample
case GLS_SAMPLE_BUFFERS_SGIS:
layer->sampleBuffers = inVal > 0 ? inVal : 0;
break;
case GLS_SAMPLES_SGIS:
layer->samples = inVal > 0 ? inVal : 0;
break;
#endif /* __GL_SGIS_multisample */
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
}
void __gls_exec_glsHeaderf(GLSenum inAttrib, GLfloat inVal) {
__GLScontext *const ctx = __GLS_CONTEXT;
__GLSheader *header;
if (ctx->blockType != GLS_HEADER) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
return;
}
header = &ctx->header;
switch (inAttrib) {
case GLS_ASPECT:
header->aspect = inVal > 0.f ? inVal : 0.f;
break;
case GLS_BORDER_WIDTH:
header->borderWidth = inVal > 0.f ? inVal : 0.f;
break;
case GLS_CONTRAST_RATIO:
header->contrastRatio = inVal > 0.f ? inVal : 0.f;
break;
case GLS_HEIGHT_MM:
header->heightMM = inVal > 0.f ? inVal : 0.f;
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
}
void __gls_exec_glsHeaderfv(GLSenum inAttrib, const GLfloat *inVec) {
__GLScontext *const ctx = __GLS_CONTEXT;
__GLSheader *header;
GLint i;
if (ctx->blockType != GLS_HEADER) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
return;
}
header = &ctx->header;
switch (inAttrib) {
case GLS_BORDER_COLOR:
for (i = 0 ; i < 4 ; ++i) {
header->borderColor[i] = __glsFloatToClampf(inVec[i]);
}
break;
case GLS_GAMMA:
for (i = 0 ; i < 4 ; ++i) {
header->gamma[i] = inVec[i] > 0.f ? inVec[i] : 0.f;
}
break;
case GLS_ORIGIN:
for (i = 0 ; i < 2 ; ++i) header->origin[i] = inVec[i];
break;
case GLS_PAGE_COLOR:
for (i = 0 ; i < 4 ; ++i) {
header->pageColor[i] = __glsFloatToClampf(inVec[i]);
}
break;
case GLS_PAGE_SIZE:
for (i = 0 ; i < 2 ; ++i) {
header->pageSize[i] = inVec[i] > 0.f ? inVec[i] : 0.f;
}
break;
case GLS_RED_POINT:
for (i = 0 ; i < 2 ; ++i) {
header->redPoint[i] = inVec[i] > 0.f ? inVec[i] : 0.f;
}
break;
case GLS_GREEN_POINT:
for (i = 0 ; i < 2 ; ++i) {
header->greenPoint[i] = inVec[i] > 0.f ? inVec[i] : 0.f;
}
break;
case GLS_BLUE_POINT:
for (i = 0 ; i < 2 ; ++i) {
header->bluePoint[i] = inVec[i] > 0.f ? inVec[i] : 0.f;
}
break;
case GLS_WHITE_POINT:
for (i = 0 ; i < 2 ; ++i) {
header->whitePoint[i] = inVec[i] > 0.f ? inVec[i] : 0.f;
}
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
}
void __gls_exec_glsHeaderi(GLSenum inAttrib, GLint inVal) {
__GLScontext *const ctx = __GLS_CONTEXT;
__GLSheader *header;
if (ctx->blockType != GLS_HEADER) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
return;
}
header = &ctx->header;
switch (inAttrib) {
case GLS_FRAME_COUNT:
header->frameCount = inVal > 0 ? inVal : 0;
break;
case GLS_GLRC_COUNT:
if (inVal < header->glrcCount) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
} else if (inVal > header->glrcCount) {
GLint i;
__GLSglrc *glrcs = __glsMalloc(inVal * sizeof(__GLSglrc));
if (!glrcs) break;
memcpy(
glrcs,
header->glrcs,
header->glrcCount * sizeof(__GLSglrc)
);
for (i = header->glrcCount ; i < inVal ; ++i) {
__glsGLRC_init(glrcs + i);
}
header->glrcCount = inVal;
free(header->glrcs);
header->glrcs = glrcs;
}
break;
case GLS_HEIGHT_PIXELS:
header->heightPixels = inVal > 0 ? inVal : 0;
break;
case GLS_LAYER_COUNT:
if (inVal < header->layerCount) {
__GLS_RAISE_ERROR(GLS_INVALID_VALUE);
} else if (inVal > header->layerCount) {
GLint i;
__GLSlayer *layers = __glsMalloc(inVal * sizeof(__GLSlayer));
if (!layers) break;
memcpy(
layers,
header->layers,
header->layerCount * sizeof(__GLSlayer)
);
for (i = header->layerCount ; i < inVal ; ++i) {
__glsLayer_init(layers + i);
}
header->layerCount = inVal;
free(header->layers);
header->layers = layers;
}
break;
case GLS_TILEABLE:
header->tileable = inVal ? GL_TRUE : GL_FALSE;
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
}
void __gls_exec_glsHeaderiv(GLSenum inAttrib, const GLint *inVec) {
__GLScontext *const ctx = __GLS_CONTEXT;
__GLSheader *header;
GLint i;
if (ctx->blockType != GLS_HEADER) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
return;
}
header = &ctx->header;
switch (inAttrib) {
case GLS_CREATE_TIME:
for (i = 0 ; i < 6 ; ++i) {
header->createTime[i] = inVec[i] > 0 ? inVec[i] : 0;
}
break;
case GLS_MODIFY_TIME:
for (i = 0 ; i < 6 ; ++i) {
header->modifyTime[i] = inVec[i] > 0 ? inVec[i] : 0;
}
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
}
void __gls_exec_glsHeaderubz(GLSenum inAttrib, const GLubyte *inString) {
__GLScontext *const ctx = __GLS_CONTEXT;
__GLSheader *header;
if (ctx->blockType != GLS_HEADER) {
__GLS_RAISE_ERROR(GLS_INVALID_OPERATION);
return;
}
if (!__glsValidateString(inString)) return;
header = &ctx->header;
switch (inAttrib) {
case GLS_EXTENSIONS:
__glsString_assign(&header->extensions, inString);
break;
case GLS_AUTHOR:
__glsString_assign(&header->author, inString);
break;
case GLS_DESCRIPTION:
__glsString_assign(&header->description, inString);
break;
case GLS_NOTES:
__glsString_assign(&header->notes, inString);
break;
case GLS_TITLE:
__glsString_assign(&header->title, inString);
break;
case GLS_TOOLS:
__glsString_assign(&header->tools, inString);
break;
case GLS_VERSION:
__glsString_assign(&header->version, inString);
break;
default:
__GLS_RAISE_ERROR(GLS_INVALID_ENUM);
break;
}
}
void __gls_exec_glsRequireExtension(const GLubyte *inExtension) {
if (!__glsValidateString(inExtension)) return;
if (!glsIsExtensionSupported(inExtension)) {
__GLS_RAISE_ERROR(GLS_UNSUPPORTED_EXTENSION);
}
}
void __gls_exec_glsUnsupportedCommand(void) {
__GLS_RAISE_ERROR(GLS_UNSUPPORTED_COMMAND);
}