#include <string.h>
#include <X11/Xmd.h>
#include <GL/gl.h>
#include <GL/glxproto.h>
#if defined(__linux__) || defined (__GLIBC__) || defined(__GNU__)
#include <byteswap.h>
#elif defined(__OpenBSD__)
#include <sys/endian.h>
#define bswap_16 __swap16
#define bswap_32 __swap32
#define bswap_64 __swap64
#elif defined(__APPLE__)
#include <libkern/OSByteOrder.h>
#define bswap_16 OSSwapInt16
#define bswap_32 OSSwapInt32
#define bswap_64 OSSwapInt64
#else
#include <sys/endian.h>
#define bswap_16 bswap16
#define bswap_32 bswap32
#define bswap_64 bswap64
#endif
#include <inttypes.h>
#include "indirect_size.h"
#include "indirect_size_get.h"
#include "indirect_dispatch.h"
#include "glxserver.h"
#include "singlesize.h"
#include "glapitable.h"
#include "glapi.h"
#include "glthread.h"
#include "dispatch.h"
#include "glxext.h"
#include "indirect_table.h"
#include "indirect_util.h"
#define __GLX_PAD(a) (((a)+3)&~3)
extern xGLXSingleReply __glXReply;
GLint
__glGetBooleanv_variable_size( GLenum e )
{
if ( e == GL_COMPRESSED_TEXTURE_FORMATS ) {
GLint temp;
CALL_GetIntegerv( GET_DISPATCH(),
(GL_NUM_COMPRESSED_TEXTURE_FORMATS, & temp) );
return temp;
}
else {
return 0;
}
}
void *
__glXGetAnswerBuffer( __GLXclientState * cl, size_t required_size,
void * local_buffer, size_t local_size, unsigned alignment )
{
void * buffer = local_buffer;
const unsigned mask = alignment - 1;
if ( local_size < required_size ) {
const size_t worst_case_size = required_size + alignment;
intptr_t temp_buf;
if ( cl->returnBufSize < worst_case_size ) {
void * temp = xrealloc( cl->returnBuf, worst_case_size );
if ( temp == NULL ) {
return NULL;
}
cl->returnBuf = temp;
cl->returnBufSize = worst_case_size;
}
temp_buf = (intptr_t) cl->returnBuf;
temp_buf = (temp_buf + mask) & ~mask;
buffer = (void *) temp_buf;
}
return buffer;
}
void
__glXSendReply( ClientPtr client, const void * data, size_t elements,
size_t element_size, GLboolean always_array, CARD32 retval )
{
size_t reply_ints = 0;
if ( __glXErrorOccured() ) {
elements = 0;
}
else if ( (elements > 1) || always_array ) {
reply_ints = ((elements * element_size) + 3) >> 2;
}
__glXReply.length = reply_ints;
__glXReply.type = X_Reply;
__glXReply.sequenceNumber = client->sequence;
__glXReply.size = elements;
__glXReply.retval = retval;
(void) memcpy( & __glXReply.pad3, data, 8 );
WriteToClient( client, sz_xGLXSingleReply, (char *) & __glXReply );
if ( reply_ints != 0 ) {
WriteToClient( client, reply_ints * 4, (char *) data );
}
}
void
__glXSendReplySwap( ClientPtr client, const void * data, size_t elements,
size_t element_size, GLboolean always_array, CARD32 retval )
{
size_t reply_ints = 0;
if ( __glXErrorOccured() ) {
elements = 0;
}
else if ( (elements > 1) || always_array ) {
reply_ints = ((elements * element_size) + 3) >> 2;
}
__glXReply.length = bswap_32( reply_ints );
__glXReply.type = X_Reply;
__glXReply.sequenceNumber = bswap_16( client->sequence );
__glXReply.size = bswap_32( elements );
__glXReply.retval = bswap_32( retval );
(void) memcpy( & __glXReply.pad3, data, 8 );
WriteToClient( client, sz_xGLXSingleReply, (char *) & __glXReply );
if ( reply_ints != 0 ) {
WriteToClient( client, reply_ints * 4, (char *) data );
}
}
static int
get_decode_index(const struct __glXDispatchInfo *dispatch_info,
unsigned opcode)
{
int remaining_bits;
int next_remain;
const int_fast16_t * const tree = dispatch_info->dispatch_tree;
int_fast16_t index;
remaining_bits = dispatch_info->bits;
if (opcode >= (1U << remaining_bits)) {
return -1;
}
index = 0;
for (; remaining_bits > 0; remaining_bits = next_remain) {
unsigned mask;
unsigned child_index;
next_remain = remaining_bits - tree[index];
mask = ((1 << remaining_bits) - 1) &
~((1 << next_remain) - 1);
child_index = (opcode & mask) >> next_remain;
index = tree[index + 1 + child_index];
if (index == EMPTY_LEAF) {
return -1;
}
else if (IS_LEAF_INDEX(index)) {
unsigned func_index;
func_index = -index;
func_index += opcode & ((1 << next_remain) - 1);
return func_index;
}
}
return -1;
}
void *
__glXGetProtocolDecodeFunction(const struct __glXDispatchInfo *dispatch_info,
int opcode, int swapped_version)
{
const int func_index = get_decode_index(dispatch_info, opcode);
return (func_index < 0)
? NULL
: (void *) dispatch_info->dispatch_functions[func_index][swapped_version];
}
int
__glXGetProtocolSizeData(const struct __glXDispatchInfo *dispatch_info,
int opcode, __GLXrenderSizeData *data)
{
if (dispatch_info->size_table != NULL) {
const int func_index = get_decode_index(dispatch_info, opcode);
if ((func_index >= 0)
&& (dispatch_info->size_table[func_index][0] != 0)) {
const int var_offset =
dispatch_info->size_table[func_index][1];
data->bytes = dispatch_info->size_table[func_index][0];
data->varsize = (var_offset != ~0)
? dispatch_info->size_func_table[var_offset]
: NULL;
return 0;
}
}
return -1;
}