/* ** Initialize the per-client context storage. */ static void ResetClientState(int clientIndex) { __GLXclientState *cl = __glXClients[clientIndex]; Display **keep_be_displays; int i; if (cl->returnBuf) __glXFree(cl->returnBuf); if (cl->currentContexts) __glXFree(cl->currentContexts); if (cl->currentDrawables) __glXFree(cl->currentDrawables); if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf); for (i=0; i< screenInfo.numScreens; i++) { if (cl->be_displays[i]) XCloseDisplay( cl->be_displays[i] ); } keep_be_displays = cl->be_displays; memset(cl, 0, sizeof(__GLXclientState)); cl->be_displays = keep_be_displays; /* ** By default, assume that the client supports ** GLX major version 1 minor version 0 protocol. */ cl->GLClientmajorVersion = 1; cl->GLClientminorVersion = 0; if (cl->GLClientextensions) __glXFree(cl->GLClientextensions); memset(cl->be_displays, 0, screenInfo.numScreens * sizeof(Display *)); }
char *__glXcombine_strings(const char *cext_string, const char *sext_string) { size_t clen, slen; char *combo_string, *token, *s1; const char *s2, *end; /* safeguard to prevent potentially fatal errors in the string functions */ if (!cext_string) cext_string = ""; if (!sext_string) sext_string = ""; /* ** String can't be longer than min(cstring, sstring) ** pull tokens out of shortest string ** include space in combo_string for final separator and null terminator */ if ( (clen = __glXStrlen(cext_string)) > (slen = __glXStrlen(sext_string)) ) { combo_string = (char *) __glXMalloc(slen + 2); s1 = (char *) __glXMalloc(slen + 2); __glXStrcpy(s1, sext_string); s2 = cext_string; } else { combo_string = (char *) __glXMalloc(clen + 2); s1 = (char *) __glXMalloc(clen + 2); __glXStrcpy(s1, cext_string); s2 = sext_string; } if (!combo_string || !s1) { if (combo_string) __glXFree(combo_string); if (s1) __glXFree(s1); return NULL; } combo_string[0] = '\0'; /* Get first extension token */ token = __glXStrtok( s1, SEPARATOR); while ( token != NULL ) { /* ** if token in second string then save it ** beware of extension names which are prefixes of other extension names */ const char *p = s2; end = p + __glXStrlen(p); while (p < end) { size_t n = __glXStrcspn(p, SEPARATOR); if ((__glXStrlen(token) == n) && (__glXStrncmp(token, p, n) == 0)) { combo_string = __glXStrcat( combo_string, token); combo_string = __glXStrcat( combo_string, SEPARATOR); } p += (n + 1); } /* Get next extension token */ token = __glXStrtok( NULL, SEPARATOR); } __glXFree(s1); return combo_string; }
/* ** Free a context. */ GLboolean __glXFreeContext(__GLXcontext *cx) { if (cx->idExists || cx->isCurrent) return GL_FALSE; if (cx->feedbackBuf) __glXFree(cx->feedbackBuf); if (cx->selectBuf) __glXFree(cx->selectBuf); if (cx->real_ids) __glXFree(cx->real_ids); if (cx->real_vids) __glXFree(cx->real_vids); if (cx->pGlxPixmap) { /* ** The previous drawable was a glx pixmap, release it. */ cx->pGlxPixmap->refcnt--; __glXFreeGLXPixmap( cx->pGlxPixmap ); cx->pGlxPixmap = 0; } if (cx->pGlxReadPixmap) { /* ** The previous drawable was a glx pixmap, release it. */ cx->pGlxReadPixmap->refcnt--; __glXFreeGLXPixmap( cx->pGlxReadPixmap ); cx->pGlxReadPixmap = 0; } if (cx->pGlxWindow) { /* ** The previous drawable was a glx window, release it. */ cx->pGlxWindow->refcnt--; __glXFreeGLXWindow( cx->pGlxWindow ); cx->pGlxWindow = 0; } if (cx->pGlxReadWindow) { /* ** The previous drawable was a glx window, release it. */ cx->pGlxReadWindow->refcnt--; __glXFreeGLXWindow( cx->pGlxReadWindow ); cx->pGlxReadWindow = 0; } __glXFree(cx); if (cx == __glXLastContext) { __glXFlushContextCache(); } return GL_TRUE; }
void __glXScreenReset(void) { int i; for (i = 0; i < __glXNumActiveScreens; i++) { __glXFree(__glXActiveScreens[i].GLXvendor); __glXFree(__glXActiveScreens[i].GLXversion); __glXFree(__glXActiveScreens[i].GLXextensions); __glXFree(__glXActiveScreens[i].GLextensions); } xfree(__glXActiveScreens); __glXActiveScreens = NULL; __glXNumActiveScreens = 0; }
/* ** Free a GLX Pixmap. */ void __glXFreeGLXPixmap( __GLXpixmap *pGlxPixmap ) { if (!pGlxPixmap->idExists && !pGlxPixmap->refcnt) { PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw; /* ** The DestroyPixmap routine should decrement the refcount and free ** only if it's zero. */ (*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap); __glXFree(pGlxPixmap->be_xids); __glXFree(pGlxPixmap); } }
static int __glXSwapDispatch(ClientPtr client) { REQUEST(xGLXSingleReq); CARD8 opcode; int (*proc)(__GLXclientState *cl, GLbyte *pc); __GLXclientState *cl; opcode = stuff->glxCode; cl = __glXClients[client->index]; if (!cl) { cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState)); __glXClients[client->index] = cl; if (!cl) { return BadAlloc; } memset(cl, 0, sizeof(__GLXclientState)); cl->be_displays = (Display **) __glXMalloc( screenInfo.numScreens * sizeof(Display *) ); if (!cl->be_displays) { __glXFree( cl ); return BadAlloc; } memset(cl->be_displays, 0, screenInfo.numScreens * sizeof(Display *)); } if (!cl->inUse) { /* ** This is first request from this client. Associate a resource ** with the client so we will be notified when the client dies. */ XID xid = FakeClientID(client->index); if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) { return BadAlloc; } ResetClientState(client->index); cl->inUse = GL_TRUE; cl->client = client; } /* ** Check for valid opcode. */ if (opcode >= __GLX_SINGLE_TABLE_SIZE) { return BadRequest; } /* ** Use the opcode to index into the procedure table. */ proc = __glXSwapSingleTable[opcode]; return (*proc)(cl, (GLbyte *) stuff); }
/* ** Make a single GL bitmap from a single X glyph */ static int __glXMakeBitmapFromGlyph(FontPtr font, CharInfoPtr pci) { int i, j; int widthPadded; /* width of glyph in bytes, as padded by X */ int allocBytes; /* bytes to allocate to store bitmap */ int w; /* width of glyph in bits */ int h; /* height of glyph */ register unsigned char *pglyph; register unsigned char *p; unsigned char *allocbuf; #define __GL_CHAR_BUF_SIZE 2048 unsigned char buf[__GL_CHAR_BUF_SIZE]; w = GLYPHWIDTHPIXELS(pci); h = GLYPHHEIGHTPIXELS(pci); widthPadded = GLYPHWIDTHBYTESPADDED(pci); /* ** Use the local buf if possible, otherwise malloc. */ allocBytes = widthPadded * h; if (allocBytes <= __GL_CHAR_BUF_SIZE) { p = buf; allocbuf = 0; } else { p = (unsigned char *) __glXMalloc(allocBytes); if (!p) return BadAlloc; allocbuf = p; } /* ** We have to reverse the picture, top to bottom */ pglyph = FONTGLYPHBITS(FONTGLYPHS(font), pci) + (h-1)*widthPadded; for (j=0; j < h; j++) { for (i=0; i < widthPadded; i++) { p[i] = pglyph[i]; } pglyph -= widthPadded; p += widthPadded; } glBitmap(w, h, -pci->metrics.leftSideBearing, pci->metrics.descent, pci->metrics.characterWidth, 0, allocbuf ? allocbuf : buf); if (allocbuf) { __glXFree(allocbuf); } return Success; #undef __GL_CHAR_BUF_SIZE }
int DoGetString(__GLXclientState *cl, GLbyte *pc, GLboolean need_swap) { ClientPtr client; __GLXcontext *cx; GLenum name; const char *string; __GLX_DECLARE_SWAP_VARIABLES; int error; char *buf = NULL, *buf1 = NULL; GLint length = 0; /* If the client has the opposite byte order, swap the contextTag and * the name. */ if ( need_swap ) { __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + __GLX_SINGLE_HDR_SIZE); } cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; name = *(GLenum *)(pc + 0); string = (const char *)glGetString(name); client = cl->client; /* ** Restrict extensions to those that are supported by both the ** implementation and the connection. That is, return the ** intersection of client, server, and core extension strings. */ if (name == GL_EXTENSIONS) { buf1 = __glXcombine_strings(string, cl->GLClientextensions); buf = __glXcombine_strings(buf1, cx->pGlxScreen->GLextensions); if (buf1 != NULL) { __glXFree(buf1); } string = buf; } else if ( name == GL_VERSION ) { if ( atof( string ) > atof( GLServerVersion ) ) { buf = __glXMalloc( __glXStrlen( string ) + __glXStrlen( GLServerVersion ) + 4 ); if ( buf == NULL ) { string = GLServerVersion; } else { __glXSprintf( buf, "%s (%s)", GLServerVersion, string ); string = buf; } } } if (string) { length = __glXStrlen((const char *) string) + 1; } __GLX_BEGIN_REPLY(length); __GLX_PUT_SIZE(length); if ( need_swap ) { __GLX_SWAP_REPLY_SIZE(); __GLX_SWAP_REPLY_HEADER(); } __GLX_SEND_HEADER(); WriteToClient(client, length, (char *) string); if (buf != NULL) { __glXFree(buf); } return Success; }