update source for tizen_2.1
[sdk/emulator/qemu.git] / tizen / src / hw / opengl_exec.c
1 /*
2  *  Host-side implementation of GL/GLX API
3  *
4  *  Copyright (c) 2006,2007 Even Rouault
5  *
6  *  modified by:
7  *    Gordon Williams <gordon.williams@collabora.co.uk>
8  *    Ian Molton <ian.molton@collabora.co.uk>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISiNG FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  * THE SOFTWARE.
27  */
28
29 #include <stdlib.h>
30 #include <assert.h>
31 #include <string.h>
32 #include <sys/types.h> // for pid_t
33
34 #include "qemu-common.h"
35
36 /* GW: dyngen-exec.h defines its own version of stuff that is in stdio.h - 
37    only it misses things and is mildly different to stdio \o/. Hence
38    don't include stdio and make our own defines. */
39
40 /*
41 #ifdef DEBUG_GL
42 #ifdef _WIN32
43 #define DEBUGF(...) printf(__VA_ARGS__)
44 #else
45 #define DEBUGF(...) fprintf(stderr, __VA_ARGS__)
46 #endif
47 #else
48 #define DEBUGF(...) while(0) {printf(__VA_ARGS__); }
49 #endif
50 */
51 #include "tizen/src/debug_ch.h"
52 MULTI_DEBUG_CHANNEL(qemu, opengl);
53 #define DEBUGF          TRACE
54
55 #define GL_GLEXT_PROTOTYPES
56 #define GLX_GLXEXT_PROTOTYPES
57 #include <mesa_gl.h>
58
59 #include "qemu-queue.h"
60 #include "opengl_func.h"
61 #include "mesa_mipmap.h"
62 #include "opengl_process.h"
63 #include "range_alloc.h"
64 #include "gloffscreen.h"
65
66
67 /** Misc X11/GLX defines - we don't want to include the whole files for these
68  * as we need them on Windows too */
69 typedef int Bool;
70 const Bool True = 1;
71 const Bool False = 0;
72 typedef struct __GLXFBConfigRec GLXFBConfig;
73 struct __GLXFBConfigRec {
74   int formatFlags;
75 };
76
77 // #defines from glx.h
78 #define GLX_VENDOR              1
79 #define GLX_VERSION             2
80 #define GLX_EXTENSIONS          3
81
82 /* We'll say the XVisual Id is actually just an index into here */
83 const GLXFBConfig FBCONFIGS[] = {
84     {GLO_FF_ALPHA|GLO_FF_BITS_32},
85     {GLO_FF_ALPHA|GLO_FF_BITS_32|GLO_FF_DEPTH_24},
86     {GLO_FF_ALPHA|GLO_FF_BITS_32|GLO_FF_DEPTH_24|GLO_FF_STENCIL_8},
87 /*
88     {GLO_FF_BITS_32},
89     {GLO_FF_BITS_32|GLO_FF_DEPTH_24},
90     {GLO_FF_BITS_32|GLO_FF_DEPTH_24|GLO_FF_STENCIL_8},
91
92     {GLO_FF_BITS_24},
93     {GLO_FF_BITS_24|GLO_FF_DEPTH_24},
94     {GLO_FF_BITS_24|GLO_FF_DEPTH_24|GLO_FF_STENCIL_8},
95 */
96 /*
97     {GLO_FF_BITS_16},
98     {GLO_FF_BITS_16|GLO_FF_DEPTH_24},
99     {GLO_FF_BITS_16|GLO_FF_DEPTH_24|GLO_FF_STENCIL_8},*/
100 };
101
102 #define FAKE_GL_VENDOR     "Qemu"
103 #define FAKE_GL_RENDERER   "VMGL Passthrough"
104 #define FAKE_GL_VERSION    "1.4"
105 #define FAKE_GL_MAJOR      1
106
107
108 #define FAKE_GLX_VENDOR     "Qemu"
109 #define FAKE_GLX_VERSION_STRING "1.2"
110 #define FAKE_GLX_VERSION_MAJOR 1
111 #define FAKE_GLX_VERSION_MINOR 2
112
113 void *g_malloc(size_t size);
114 void *g_realloc(void *ptr, size_t size);
115 void g_free(void *ptr);
116
117 /*#define glGetError() 0*/
118
119 #define GET_EXT_PTR(type, funcname, args_decl) \
120     static int detect_##funcname = 0; \
121     static type(*ptr_func_##funcname)args_decl = NULL; \
122     if (detect_##funcname == 0) \
123     { \
124         detect_##funcname = 1; \
125         ptr_func_##funcname = (type(*)args_decl)glo_getprocaddress((const char*)#funcname); \
126         assert (ptr_func_##funcname); \
127     }
128
129 #define GET_EXT_PTR_NO_FAIL(type, funcname, args_decl) \
130     static int detect_##funcname = 0; \
131     static type(*ptr_func_##funcname)args_decl = NULL; \
132     if (detect_##funcname == 0) \
133     { \
134         detect_##funcname = 1; \
135         ptr_func_##funcname = (type(*)args_decl)glo_getprocaddress((const char*)#funcname); \
136     }
137
138 #ifndef WIN32
139 #include <dlfcn.h>
140 #endif
141
142 static void *get_glu_ptr(const char *name)
143 {
144     static void *handle = (void *) -1;
145
146     if (handle == (void *) -1) {
147 #ifndef WIN32
148         handle = dlopen("libGLU.so", RTLD_LAZY);
149         if (!handle)
150             DEBUGF("can't load libGLU.so : %s\n", dlerror());
151 #else
152         handle = (void *) LoadLibrary("glu32.dll");
153         if (!handle)
154             DEBUGF("can't load glu32.dll\n");
155 #endif
156     }
157     if (handle) {
158 #ifndef WIN32
159         return dlsym(handle, name);
160 #else
161         return GetProcAddress(handle, name);
162 #endif
163     }
164     return NULL;
165 }
166
167 #define GET_GLU_PTR(type, funcname, args_decl) \
168     static int detect_##funcname = 0; \
169     static type(*ptr_func_##funcname)args_decl = NULL; \
170     if (detect_##funcname == 0) \
171     { \
172         detect_##funcname = 1; \
173         ptr_func_##funcname = (type(*)args_decl)get_glu_ptr(#funcname); \
174     }
175
176 int display_function_call = 0;
177 extern int kill_process;
178
179 typedef struct {
180     void *key;
181     void *value;
182 } Assoc;
183
184 #define MAX_HANDLED_PROCESS 100
185 #define MAX_ASSOC_SIZE 100
186
187 #define MAX_FBCONFIG 10
188
189 #define MAX_PENDING_DRAWABLE 8
190
191 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
192 #define DIM(X) (sizeof(X) / sizeof(X[0]))
193
194 typedef struct {
195     GLbitfield mask;
196     int activeTextureIndex;
197 } ClientState;
198
199 #define MAX_CLIENT_STATE_STACK_SIZE 16
200
201 typedef void *ClientGLXDrawable;
202
203 typedef struct GLState GLState;
204
205 enum {
206     SURFACE_WINDOW,
207     SURFACE_PIXMAP,
208     SURFACE_PBUFFER,
209 };
210
211 enum {
212         SURFACE_PENDING,    /* Created with light-weight context */
213         SURFACE_ACTIVE,     /* Ready after MakeCurrent */
214 };
215
216 typedef struct QGloSurface {
217     GLState *glstate;
218     GloSurface *surface;
219     ClientGLXDrawable *client_drawable;
220     int type; /* window, pixmap or pbuffer */
221     int ready;
222         int status;
223     int ref;
224     QTAILQ_ENTRY(QGloSurface) next;
225 } QGloSurface;
226
227 #define MAX_PIXMAP_TEXTURE 32
228 typedef struct PixmapTexture {
229     unsigned int used;
230     unsigned int texture;
231     ClientGLXDrawable drawable;
232 } PixmapTexture;
233
234 struct GLState {
235     int ref;
236     int fake_ctxt;
237     int fake_shareList;
238
239     GloContext *context; // context (owned by this)
240     QGloSurface *current_qsurface; // current rendering surface/drawable
241     QTAILQ_HEAD(, QGloSurface) qsurfaces; // list of surfaces/drawables for
242                                           // this context
243
244     void *vertexPointer;
245     void *normalPointer;
246     void *colorPointer;
247     void *secondaryColorPointer;
248     void *indexPointer;
249     void *texCoordPointer[NB_MAX_TEXTURES];
250     void *edgeFlagPointer;
251     void *vertexAttribPointer[MY_GL_MAX_VERTEX_ATTRIBS_ARB];
252     void *vertexAttribPointerNV[MY_GL_MAX_VERTEX_ATTRIBS_NV];
253     void *weightPointer;
254     void *matrixIndexPointer;
255     void *fogCoordPointer;
256     void *variantPointerEXT[MY_GL_MAX_VARIANT_POINTER_EXT];
257     void *interleavedArrays;
258     void *elementPointerATI;
259
260     int vertexPointerSize;
261     int normalPointerSize;
262     int colorPointerSize;
263     int secondaryColorPointerSize;
264     int indexPointerSize;
265     int texCoordPointerSize[NB_MAX_TEXTURES];
266     int edgeFlagPointerSize;
267     int vertexAttribPointerSize[MY_GL_MAX_VERTEX_ATTRIBS_ARB];
268     int vertexAttribPointerNVSize[MY_GL_MAX_VERTEX_ATTRIBS_NV];
269     int weightPointerSize;
270     int matrixIndexPointerSize;
271     int fogCoordPointerSize;
272     int variantPointerEXTSize[MY_GL_MAX_VARIANT_POINTER_EXT];
273     int interleavedArraysSize;
274     int elementPointerATISize;
275
276     int selectBufferSize;
277     void *selectBufferPtr;
278     int feedbackBufferSize;
279     void *feedbackBufferPtr;
280
281     ClientState clientStateStack[MAX_CLIENT_STATE_STACK_SIZE];
282     int clientStateSp;
283     int activeTextureIndex;
284
285     unsigned int ownTabTextures[32768];
286     unsigned int *tabTextures;
287     /* The mapping between the texture and pixmap used as texture */
288     PixmapTexture pixmapTextures[MAX_PIXMAP_TEXTURE];
289     unsigned int bindTexture2D;
290     RangeAllocator ownTextureAllocator;
291     RangeAllocator *textureAllocator;
292
293     unsigned int ownTabBuffers[32768];
294     unsigned int *tabBuffers;
295     RangeAllocator ownBufferAllocator;
296     RangeAllocator *bufferAllocator;
297
298     unsigned int ownTabLists[32768];
299     unsigned int *tabLists;
300     RangeAllocator ownListAllocator;
301     RangeAllocator *listAllocator;
302
303 };
304
305 typedef struct {
306     ProcessStruct p;
307
308     int next_available_context_number;
309
310     int nb_states;
311     GLState default_state;
312     GLState **glstates;
313     GLState *current_state;
314
315     /* Pending drawables that will be used as texture  */
316     ClientGLXDrawable pending_drawables[MAX_PENDING_DRAWABLE];
317
318     /* Created Pixmap surfaces, will link to context in MakeCurrent */
319     QGloSurface **pending_qsurfaces;
320     int nb_qsurf;
321
322     int nfbconfig;
323     const GLXFBConfig *fbconfigs[MAX_FBCONFIG];
324     int fbconfigs_max[MAX_FBCONFIG];
325     int nfbconfig_total;
326
327     int primitive;
328     int bufsize;
329     int bufstart;
330     arg_t *cmdbuf;
331 } ProcessState;
332
333 static ProcessState processes[MAX_HANDLED_PROCESS];
334
335 static char *strip_extensions(const char *avail, const char *ext[]) {
336     char *pos, *supported, *srcp;
337
338     supported = (char *)g_malloc(strlen(avail) + 2);
339
340     pos = supported;
341     while(*ext) {
342         srcp = (char*)avail;
343         while((srcp = strstr(srcp, *ext))) {
344             int len = strlen(*ext);
345             if(*(srcp+len) == ' ' || *(srcp+len) == '\0') {
346                 strcpy(pos, *ext);
347                 pos += len;
348                 if(*(srcp+len) == ' ') {
349                     *pos = ' ';
350                     pos++;
351                 }
352                 break;
353             }
354             srcp += len;
355         }
356         ext++;
357     }
358     *pos = ' ';
359     *pos = '\0';
360
361   return supported;
362 }
363
364 static const char *glx_ext_supported[] = {
365     "GLX_ARB_multisample",
366     0
367 };
368
369 static char *supported_glx_extensions() {
370     static char *supported;
371
372     if(!supported)
373       supported = strip_extensions(glo_glXQueryExtensionsString(),
374                                    glx_ext_supported);
375
376     return supported;
377 }
378
379 static const char *gl_ext_supported[] = {
380 // Mandatory OpenGL 1.4 Extensions
381     "GL_ARB_depth_texture",
382     "GL_ARB_multisample",
383     "GL_ARB_multitexture",
384     "GL_ARB_point_parameters",
385     "GL_ARB_shadow",
386     "GL_ARB_texture_border_clamp",
387     "GL_ARB_texture_compression",
388     "GL_ARB_texture_cube_map",
389     "GL_ARB_texture_env_add",
390     "GL_ARB_texture_env_combine",
391     "GL_ARB_texture_env_crossbar",
392     "GL_ARB_texture_env_dot3",
393     "GL_ARB_texture_mirrored_repeat",
394     "GL_ARB_transpose_matrix",
395     "GL_ARB_window_pos",
396     "GL_EXT_bgra",
397     "GL_EXT_blend_color",
398     "GL_EXT_blend_func_separate",
399     "GL_EXT_blend_logic_op",
400     "GL_EXT_blend_minmax",
401     "GL_EXT_blend_subtract",
402     "GL_EXT_copy_texture",
403     "GL_EXT_draw_range_elements",
404     "GL_EXT_fog_coord",
405     "GL_EXT_multi_draw_arrays",
406     "GL_EXT_packed_pixels",
407     "GL_EXT_point_parameters",
408     "GL_EXT_polygon_offset",
409     "GL_EXT_rescale_normal",
410     "GL_EXT_secondary_color",
411     "GL_EXT_separate_specular_color",
412     "GL_EXT_stencil_wrap",
413     "GL_EXT_subtexture",
414     "GL_EXT_texture",
415     "GL_EXT_texture3D",
416     "GL_EXT_texture_edge_clamp",
417     "GL_EXT_texture_env_add",
418     "GL_EXT_texture_env_combine",
419     "GL_EXT_texture_lod",
420     "GL_EXT_texture_lod_bias",
421     "GL_EXT_texture_object",
422     "GL_APPLE_packed_pixels",
423     "GL_NV_blend_square",
424     "GL_SGIS_generate_mipmap",
425     "GL_SGIS_texture_border_clamp",
426     "GL_SGIS_texture_edge_clamp",
427     "GL_SGIS_texture_lod",
428 // Optional extensions. If you get problems try disabling the below.
429     "GL_EXT_compiled_vertex_array",
430     "GL_ARB_copy_buffer",
431     "GL_ARB_depth_clamp",
432     "GL_ARB_draw_buffers ",
433     "GL_ARB_draw_elements_base_vertex",
434     "GL_ARB_fragment_program",
435     "GL_ARB_fragment_program_shadow",
436     "GL_ARB_fragment_shader",
437     "GL_ARB_framebuffer_object",
438     "GL_ARB_half_float_pixel",
439     "GL_ARB_map_buffer_range",                                           
440     "GL_ARB_occlusion_query",
441     "GL_ARB_pixel_buffer_object",
442     "GL_ARB_point_sprite",
443     "GL_ARB_provoking_vertex",
444     "GL_ARB_seamless_cube_map",
445     "GL_ARB_shader_objects",
446     "GL_ARB_shading_language_100",
447     "GL_ARB_shading_language_120",
448     "GL_ARB_sync",                                                           
449     "GL_ARB_texture_non_power_of_two",
450     "GL_ARB_texture_rectangle",
451     "GL_ARB_vertex_array_bgra",                           
452     "GL_ARB_vertex_array_object",
453     "GL_ARB_vertex_buffer_object",
454     "GL_ARB_vertex_program",
455     "GL_ARB_vertex_shader,"
456     "GL_EXT_abgr",
457     "GL_EXT_blend_equation_separate",
458     "GL_EXT_cull_vertex",
459     "GL_EXT_framebuffer_blit",
460     "GL_EXT_framebuffer_object",
461     "GL_EXT_gpu_program_parameters",                            
462     "GL_EXT_packed_depth_stencil",                        
463     "GL_EXT_pixel_buffer_object",
464     "GL_EXT_provoking_vertex",
465     "GL_EXT_shadow_funcs",
466     "GL_EXT_stencil_two_side",
467     "GL_EXT_texture_cube_map",   
468     "GL_EXT_texture_env_dot3",                              
469     "GL_EXT_texture_filter_anisotropic",
470     "GL_EXT_texture_rectangle",
471     "GL_EXT_texture_sRGB",
472     "GL_EXT_texture_swizzle",
473     "GL_EXT_vertex_array",
474     "GL_EXT_vertex_array_bgra",
475     "GL_3DFX_texture_compression_FXT1",
476     "GL_APPLE_client_storage",
477     "GL_APPLE_vertex_array_object",                          
478     "GL_ATI_blend_equation_separate",
479     "GL_ATI_envmap_bumpmap",
480     "GL_ATI_texture_env_combine3",
481     "GL_ATI_separate_stencil",
482     "GL_IBM_multimode_draw_arrays",
483     "GL_IBM_rasterpos_clip",
484     "GL_IBM_texture_mirrored_repeat",
485     "GL_INGR_blend_func_separate", 
486     "GL_MESA_pack_invert",
487     "GL_MESA_texture_signed_rgba",
488     "GL_MESA_ycbcr_texture",
489     "GL_MESA_window_pos",
490     "GL_NV_depth_clamp",
491     "GL_NV_light_max_exponent",
492     "GL_NV_packed_depth_stencil",
493     "GL_NV_texture_env_combine4",
494     "GL_NV_texture_rectangle",
495     "GL_NV_texgen_reflection",
496     "GL_NV_vertex_program",
497     "GL_NV_vertex_program1_1",
498     "GL_OES_read_format",
499     "GL_SUN_multi_draw_arrays",
500     0
501 };
502
503 static char *compute_gl_extensions() {
504     static char *supported;
505
506     if(!supported)
507         supported = strip_extensions((const char *)glGetString(GL_EXTENSIONS),
508                                      gl_ext_supported);
509
510     return supported;
511 }
512
513 static inline QGloSurface *get_qsurface_from_client_drawable(GLState *state, ClientGLXDrawable client_drawable) {
514     QGloSurface *qsurface;
515
516     if(state->current_qsurface->client_drawable == client_drawable)
517         return state->current_qsurface;
518
519     QTAILQ_FOREACH(qsurface, &state->qsurfaces, next) {
520         if (qsurface->client_drawable == client_drawable)
521             return qsurface;
522     }
523
524     return NULL;
525 }
526
527 // This must always be called only on surfaces belonging to the current context
528 static inline void render_surface(QGloSurface *qsurface, int bpp, int stride, char *buffer)
529 {
530     int w, h;
531     if(!qsurface->ready)
532         return;
533
534     glo_surface_get_size(qsurface->surface, &w, &h);
535
536     glo_surface_getcontents(qsurface->surface, stride, bpp, buffer);
537 }
538
539 // This must always be called only on surfaces belonging to the current context
540 static inline void resize_surface(ProcessState *process, QGloSurface *qsurface,
541                                   int w, int h) {
542     GLState *glstate = qsurface->glstate;
543     GloSurface *old_surface = qsurface->surface;
544     GloSurface *surface;
545
546     DEBUGF("resize_start\n");
547
548     glo_surface_destroy(old_surface);
549
550     surface = glo_surface_create(w, h, glstate->context);
551     qsurface->surface = surface;
552
553     // Client doesnt know surface is new - need to MakeCurrent
554     if(process->current_state == qsurface->glstate) {
555         glo_surface_makecurrent(qsurface->surface);
556         // set the viewport while the window size is changed. It is needed
557         // especially for the case that glViewport is not explicitly called
558         // in program. In this case, the viewport is set to incorrectly
559         // in the first MakeCurrent when the window size is not known.
560         // It will not impact normal GL programs with glViewport set as 
561         // programmers want.
562         glViewport (0, 0, w, h);
563     }
564     else {
565         DEBUGF("Error: Surface is not current! %p %p\n",
566                process->current_state,
567                process->current_state->current_qsurface);
568         exit(1);
569     }
570
571     glstate->current_qsurface->ready = 1;
572     DEBUGF( "resize_done\n");
573 }
574
575
576 void init_process_tab()
577 {
578     memset(processes, 0, sizeof(processes));
579 }
580
581 #define ARG_TO_CHAR(x)                (char)(x)
582 #define ARG_TO_UNSIGNED_CHAR(x)       (unsigned char)(x)
583 #define ARG_TO_SHORT(x)               (short)(x)
584 #define ARG_TO_UNSIGNED_SHORT(x)      (unsigned short)(x)
585 #define ARG_TO_INT(x)                 (int)(x)
586 #define ARG_TO_UNSIGNED_INT(x)        (unsigned int)(x)
587 #define ARG_TO_FLOAT(x)               (*(float*)&(x))
588 #define ARG_TO_DOUBLE(x)              (*(double*)(x))
589
590 #include "server_stub.c"
591
592 //typedef void *ClientGLXDrawable;
593 static inline ClientGLXDrawable to_drawable(arg_t arg)
594 {
595 #ifdef TARGET_X86_64
596     if (arg > (unsigned long) -1) {
597         DEBUGF( "GLXDrawable too big for this implementation\n");
598         exit(-1);
599     }
600 #endif
601     return (void *) (unsigned long) arg;
602 }
603
604 /* ---- */
605
606 /* Bind a qsurface to a context (GLState) */
607 static void bind_qsurface(GLState *state,
608                           QGloSurface *qsurface)
609 {
610     qsurface->glstate = state;
611
612         if ( qsurface->type == SURFACE_WINDOW )
613                 QTAILQ_INSERT_HEAD(&state->qsurfaces, qsurface, next);
614
615     state->current_qsurface = qsurface;
616 }
617
618 /* Unbind a qsurface from a context (GLState) */
619 static void unbind_qsurface(GLState *state,
620                           QGloSurface *qsurface)
621 {
622     qsurface->glstate = NULL;
623
624         if ( qsurface->type == SURFACE_WINDOW )
625                 QTAILQ_REMOVE(&state->qsurfaces, qsurface, next);
626
627         if ( state->current_qsurface == qsurface )
628                 state->current_qsurface = NULL;
629 }
630
631 /* Find the qsurface with required drawable in all pixmap/pbuffer surfaces */
632 QGloSurface* find_qsurface_from_client_drawable(ProcessState *process, ClientGLXDrawable client_drawable)
633 {
634     int i;
635     QGloSurface *qsurface;
636
637     for ( i = 0; i < process->nb_qsurf; i++ )
638     {
639         qsurface = process->pending_qsurfaces[i];
640         if ( qsurface && qsurface->client_drawable == client_drawable )
641             return qsurface;
642     }
643
644     return NULL;
645 }
646
647 /* Make the appropriate qsurface current for a given client_drawable */
648 static int set_current_qsurface(GLState *state,
649                                 ClientGLXDrawable client_drawable)
650 {
651     QGloSurface *qsurface;
652
653     if(state->current_qsurface && state->current_qsurface->client_drawable == client_drawable)
654         return 1;
655
656     QTAILQ_FOREACH(qsurface, &state->qsurfaces, next) {
657         if(qsurface->client_drawable == client_drawable) {
658             state->current_qsurface = qsurface;
659                         qsurface->glstate = state;
660             return 1;
661         }
662     }
663
664     state->current_qsurface = NULL;
665
666     return 0;
667 }
668
669 /* */
670 static int keep_drawable(ProcessState *process, ClientGLXDrawable drawable)
671 {
672     int i;
673     for ( i = 0; i < MAX_PENDING_DRAWABLE; i++)
674     {
675         if ( process->pending_drawables[i] == 0 )
676         {
677             process->pending_drawables[i] = drawable;
678             return 1;
679         }
680     }
681     return 0;
682 }
683
684 static int link_drawable(ProcessState *process, ClientGLXDrawable drawable)
685 {
686     int i;
687     for ( i = 0; i < MAX_PENDING_DRAWABLE; i++ )
688     {
689         if ( process->pending_drawables[i] == drawable )
690         {
691             process->pending_drawables[i] = 0;
692             return 1;
693         }
694     }
695     return 0;
696 }
697
698 /* Need to create pixmap/pbuffer surface when guest do so, as guest may use it
699  * before MakeCurrent. As no context available at this point, do the following:
700  * 1. Create one light-weight context just for surface creation.
701  * 2. Store this qsurface, and link it with right context when MakeCurrent
702  */
703 static void keep_qsurface(ProcessState *process, QGloSurface *qsurface)
704 {
705     process->pending_qsurfaces =
706         g_realloc(process->pending_qsurfaces,
707                   (process->nb_qsurf + 1) * sizeof(QGloSurface*));
708
709     process->pending_qsurfaces[process->nb_qsurf] = qsurface;
710
711     process->nb_qsurf++;
712 }
713
714 static int link_qsurface(ProcessState *process, GLState *glstate, ClientGLXDrawable client_drawable)
715 {
716     int i;
717     QGloSurface *qsurface;
718     for ( i = 0; i < process->nb_qsurf; i++ )
719     {
720         qsurface = process->pending_qsurfaces[i];
721         if ( qsurface && qsurface->client_drawable == client_drawable )
722         {
723             /* XXX:Current limitation is that each surface is binded to one
724              * context, and not accessible from another context. It's hard for
725              * glEGLImageTargetTexture2DOES implementation, in which we need
726              * find a pixmap surface from another context that is not owner of
727              * this pixmap. So do not move this pending pixmap surface into
728              * current context. In future need decople of surface and context.
729              * */
730 #if 0
731             memmove(&process->pending_qsurfaces[i],
732                     &process->pending_qsurfaces[i+1],
733                     (process->nb_qsurf - i - 1) * sizeof(QGloSurface*));
734 #endif
735
736             qsurface->ref = 1;
737                         if(qsurface->status == SURFACE_PENDING)
738                         {
739                                 glo_surface_update_context(qsurface->surface, glstate->context, 1);
740                                 qsurface->status = SURFACE_ACTIVE;
741                         }
742                         else
743                         {
744                                 unbind_qsurface(qsurface->glstate, qsurface);
745                                 glo_surface_update_context(qsurface->surface, glstate->context, 0);
746
747                         }
748
749             bind_qsurface(glstate, qsurface);
750             return 1;
751         }
752     }
753
754     return 0;
755 }
756
757 /* Pixmap and Pbuffer can be used as texture via glEGLImageTargetTexture2DOES
758  * and glXBindTexImage, so need keep the mapping between them to add proper
759  * action when bind the texture again
760  */
761 static void del_pixmap_texture_mapping(GLState *state,
762         unsigned int texture)
763 {
764     int i;
765     for ( i = 0; i < MAX_PIXMAP_TEXTURE; i++ )
766     {
767         if ( state->pixmapTextures[i].used &&
768              state->pixmapTextures[i].texture == texture )
769         {
770             state->pixmapTextures[i].used = 0;
771             state->pixmapTextures[i].texture = 0;
772             state->pixmapTextures[i].drawable = 0;
773             return;
774         }
775     }
776 }
777
778 static void remove_pixmap_texture_mapping(GLState *state,
779         ClientGLXDrawable drawable)
780 {
781     int i;
782     for ( i = 0; i < MAX_PIXMAP_TEXTURE; i++ )
783     {
784         if ( state->pixmapTextures[i].used &&
785              state->pixmapTextures[i].drawable == drawable )
786         {
787             state->pixmapTextures[i].used = 0;
788             state->pixmapTextures[i].texture = 0;
789             state->pixmapTextures[i].drawable = 0;
790             return;
791         }
792     }
793 }
794
795 static int add_pixmap_texture_mapping(GLState *state,
796         unsigned int texture, ClientGLXDrawable drawable)
797 {
798     int i;
799     for ( i = 0; i < MAX_PIXMAP_TEXTURE; i++ )
800     {
801         if (  state->pixmapTextures[i].texture == texture ||
802              !state->pixmapTextures[i].used )
803         {
804             state->pixmapTextures[i].used = 1;
805             state->pixmapTextures[i].texture = texture;
806             state->pixmapTextures[i].drawable = drawable;
807             return 1;
808         }
809     }
810
811     return 0;
812 }
813
814 static ClientGLXDrawable find_pixmap_texture(GLState *state,
815         unsigned int texture)
816 {
817     int i;
818     for ( i = 0; i < MAX_PIXMAP_TEXTURE; i++ )
819     {
820         if ( state->pixmapTextures[i].used &&
821              state->pixmapTextures[i].texture == texture )
822             return state->pixmapTextures[i].drawable;
823     }
824
825     return 0;
826 }
827
828 static int get_server_texture(ProcessState *process,
829                               unsigned int client_texture)
830 {
831     unsigned int server_texture = 0;
832
833     if (client_texture < 32768) {
834         server_texture = process->current_state->tabTextures[client_texture];
835     } else {
836         DEBUGF( "invalid texture name %d\n", client_texture);
837     }
838     return server_texture;
839 }
840
841 static int get_server_buffer(ProcessState *process,
842                              unsigned int client_buffer)
843 {
844     unsigned int server_buffer = 0;
845
846     if (client_buffer < 32768) {
847         server_buffer = process->current_state->tabBuffers[client_buffer];
848     } else {
849         DEBUGF( "invalid buffer name %d\n", client_buffer);
850     }
851     return server_buffer;
852 }
853
854
855 static int get_server_list(ProcessState *process, unsigned int client_list)
856 {
857     unsigned int server_list = 0;
858
859     if (client_list < 32768) {
860         server_list = process->current_state->tabLists[client_list];
861     } else {
862         DEBUGF( "invalid list name %d\n", client_list);
863     }
864     return server_list;
865 }
866
867 const GLXFBConfig *get_fbconfig(ProcessState *process, int client_fbconfig)
868 {
869     int i;
870     int nbtotal = 0;
871
872     for (i = 0; i < process->nfbconfig; i++) {
873         assert(client_fbconfig >= 1 + nbtotal);
874         if (client_fbconfig <= nbtotal + process->fbconfigs_max[i]) {
875             return &process->fbconfigs[i][client_fbconfig - 1 - nbtotal];
876         }
877         nbtotal += process->fbconfigs_max[i];
878     }
879     return 0;
880 }
881
882 static int glXChooseVisualFunc(const int *attrib_list)
883 {
884     if (attrib_list == NULL)
885         return 0;
886
887     int formatFlags = glo_flags_get_from_glx(attrib_list, True);
888     int i;
889     int bestConfig = 0;
890     int bestScore = -1;
891
892     for (i=0;i<DIM(FBCONFIGS);i++) {
893         int score = glo_flags_score(formatFlags, FBCONFIGS[i].formatFlags);
894         if (bestScore < 0 || score<=bestScore) {
895             bestScore = score;
896             bestConfig = i;
897         }
898     }
899
900     if (bestScore > 0)
901         DEBUGF( "Got format flags %d but we couldn't find an exactly matching config, chose %d\n", formatFlags, bestConfig);
902
903     return bestConfig;
904 }
905
906 static int glXGetConfigFunc(int visualid, int attrib, int *value) {
907     const GLXFBConfig *config = &FBCONFIGS[0]; // default
908     int v;
909
910     if (visualid>=0 && visualid<DIM(FBCONFIGS))
911         config = &FBCONFIGS[visualid];
912     else
913         DEBUGF( "Unknown visual ID %d\n", visualid);
914
915     v = glo_get_glx_from_flags(config->formatFlags, attrib);
916     if (value)
917        *value = v;
918     return 0;
919 }
920
921 static const GLXFBConfig * glXGetFBConfigsFunc(int screen, int *nelements) {
922     *nelements = DIM(FBCONFIGS);
923     return &FBCONFIGS[0];
924 }
925
926 static int glXGetFBConfigAttribFunc(const GLXFBConfig *fbconfig, int attrib, int *value) {
927     // TODO other enums - see http://www.opengl.org/sdk/docs/man/xhtml/glXGetFBConfigAttrib.xml
928
929     int v = glo_get_glx_from_flags(fbconfig->formatFlags, attrib);
930     if (value) *value = v;
931     return 0;
932 }
933
934 static const GLXFBConfig *glXChooseFBConfigFunc(int screen, const int *attrib_list, int *nelements) {
935     if (attrib_list != NULL) {
936         int formatFlags = glo_flags_get_from_glx(attrib_list, False);
937         int i;
938         int bestConfig = 0;
939         int bestScore = -1;
940
941         for (i=0;i<DIM(FBCONFIGS);i++) {
942             int score = glo_flags_score(formatFlags, FBCONFIGS[i].formatFlags);
943             if (bestScore < 0 || score<=bestScore) {
944                 bestScore = score;
945                 bestConfig = i;
946             }
947         }
948
949         if (bestScore > 0) {
950             DEBUGF( "Got format flags %d but we couldn't find an exactly matching config, chose %d\n", formatFlags, bestConfig);
951         }
952
953         if (nelements)
954             *nelements=1;
955
956         return &FBCONFIGS[bestConfig];
957     }
958
959     if (nelements)
960         *nelements=0;
961
962     return 0;
963 }
964
965 static void do_glClientActiveTextureARB(int texture)
966 {
967     GET_EXT_PTR_NO_FAIL(void, glClientActiveTextureARB, (int));
968
969     if (ptr_func_glClientActiveTextureARB) {
970         ptr_func_glClientActiveTextureARB(texture);
971     }
972 }
973
974 static void destroy_gl_state(GLState *state)
975 {
976     int i;
977
978     QGloSurface *qsurface, *tmp;
979
980     QTAILQ_FOREACH_SAFE(qsurface, &state->qsurfaces, next, tmp) {
981         glo_surface_destroy(qsurface->surface);
982         QTAILQ_REMOVE(&state->qsurfaces, qsurface, next);
983         g_free(qsurface);
984     }
985         
986     if (state->context)
987       glo_context_destroy(state->context);
988
989     if (state->vertexPointer)
990         g_free(state->vertexPointer);
991     if (state->normalPointer)
992         g_free(state->normalPointer);
993     if (state->indexPointer)
994         g_free(state->indexPointer);
995     if (state->colorPointer)
996         g_free(state->colorPointer);
997     if (state->secondaryColorPointer)
998         g_free(state->secondaryColorPointer);
999     for (i = 0; i < NB_MAX_TEXTURES; i++) {
1000         if (state->texCoordPointer[i])
1001             g_free(state->texCoordPointer[i]);
1002     }
1003     for (i = 0; i < MY_GL_MAX_VERTEX_ATTRIBS_ARB; i++) {
1004         if (state->vertexAttribPointer[i])
1005             g_free(state->vertexAttribPointer[i]);
1006     }
1007     for (i = 0; i < MY_GL_MAX_VERTEX_ATTRIBS_NV; i++) {
1008         if (state->vertexAttribPointerNV[i])
1009             g_free(state->vertexAttribPointerNV[i]);
1010     }
1011     if (state->weightPointer)
1012         g_free(state->weightPointer);
1013     if (state->matrixIndexPointer)
1014         g_free(state->matrixIndexPointer);
1015     if (state->fogCoordPointer)
1016         g_free(state->fogCoordPointer);
1017     for (i = 0; i < MY_GL_MAX_VARIANT_POINTER_EXT; i++) {
1018         if (state->variantPointerEXT[i])
1019             g_free(state->variantPointerEXT[i]);
1020     }
1021     if (state->interleavedArrays)
1022         g_free(state->interleavedArrays);
1023     if (state->elementPointerATI)
1024         g_free(state->elementPointerATI);
1025 }
1026
1027 static void init_gl_state(GLState *state)
1028 {
1029     state->textureAllocator = &state->ownTextureAllocator;
1030     state->tabTextures = state->ownTabTextures;
1031     state->bufferAllocator = &state->ownBufferAllocator;
1032     state->tabBuffers = state->ownTabBuffers;
1033     state->listAllocator = &state->ownListAllocator;
1034     state->tabLists = state->ownTabLists;
1035 }
1036
1037 /*
1038  * Translate the nth element of list from type to GLuint.
1039  */
1040 static GLuint translate_id(GLsizei n, GLenum type, const GLvoid *list)
1041 {
1042     GLbyte *bptr;
1043     GLubyte *ubptr;
1044     GLshort *sptr;
1045     GLushort *usptr;
1046     GLint *iptr;
1047     GLuint *uiptr;
1048     GLfloat *fptr;
1049
1050     switch (type) {
1051     case GL_BYTE:
1052         bptr = (GLbyte *) list;
1053         return (GLuint) *(bptr + n);
1054     case GL_UNSIGNED_BYTE:
1055         ubptr = (GLubyte *) list;
1056         return (GLuint) *(ubptr + n);
1057     case GL_SHORT:
1058         sptr = (GLshort *) list;
1059         return (GLuint) *(sptr + n);
1060     case GL_UNSIGNED_SHORT:
1061         usptr = (GLushort *) list;
1062         return (GLuint) *(usptr + n);
1063     case GL_INT:
1064         iptr = (GLint *) list;
1065         return (GLuint) *(iptr + n);
1066     case GL_UNSIGNED_INT:
1067         uiptr = (GLuint *) list;
1068         return (GLuint) *(uiptr + n);
1069     case GL_FLOAT:
1070         fptr = (GLfloat *) list;
1071         return (GLuint) *(fptr + n);
1072     case GL_2_BYTES:
1073         ubptr = ((GLubyte *) list) + 2 * n;
1074         return (GLuint) (*ubptr << 8) + (GLuint) *(ubptr + 1);
1075     case GL_3_BYTES:
1076         ubptr = ((GLubyte *) list) + 3 * n;
1077         return (GLuint) (*ubptr << 16) + (GLuint) (*(ubptr + 1) << 8) +
1078             (GLuint) *(ubptr + 2);
1079     case GL_4_BYTES:
1080         ubptr = ((GLubyte *) list) + 4 * n;
1081         return (GLuint) (*ubptr << 24) + (GLuint) (*(ubptr + 1) << 16) +
1082             (GLuint) (*(ubptr + 2) << 8) + (GLuint) *(ubptr + 3);
1083     default:
1084         return 0;
1085     }
1086 }
1087
1088 GLState *_create_context(ProcessState *process, int fake_ctxt, int fake_shareList)
1089 {
1090     // FIXMEIM - realloc? really?
1091     process->glstates = g_realloc(process->glstates,
1092                                   (process->nb_states + 1) * sizeof(GLState *));
1093
1094     process->glstates[process->nb_states] = g_malloc(sizeof(GLState));
1095     memset(process->glstates[process->nb_states], 0, sizeof(GLState));
1096
1097     process->glstates[process->nb_states]->ref = 1;
1098     process->glstates[process->nb_states]->fake_ctxt = fake_ctxt;
1099     process->glstates[process->nb_states]->fake_shareList = fake_shareList;
1100
1101     init_gl_state(process->glstates[process->nb_states]);
1102
1103     if (fake_shareList) {
1104         int i;
1105
1106         for (i = 0; i < process->nb_states; i++) {
1107             if (process->glstates[i]->fake_ctxt == fake_shareList) {
1108                 process->glstates[i]->ref++;
1109                 process->glstates[process->nb_states]->textureAllocator =
1110                     process->glstates[i]->textureAllocator;
1111                 process->glstates[process->nb_states]->tabTextures =
1112                     process->glstates[i]->tabTextures;
1113                 process->glstates[process->nb_states]->bufferAllocator =
1114                     process->glstates[i]->bufferAllocator;
1115                 process->glstates[process->nb_states]->tabBuffers =
1116                     process->glstates[i]->tabBuffers;
1117                 process->glstates[process->nb_states]->listAllocator =
1118                     process->glstates[i]->listAllocator;
1119                 process->glstates[process->nb_states]->tabLists =
1120                     process->glstates[i]->tabLists;
1121                 break;
1122             }
1123         }
1124     }
1125     process->nb_states++;
1126
1127     return process->glstates[process->nb_states-1];
1128 }
1129
1130 GLState *get_glstate_for_fake_ctxt(ProcessState *process, int fake_ctxt)
1131 {
1132     int i;
1133     for (i = 0; i < process->nb_states; i++) {
1134         if (process->glstates[i]->fake_ctxt == fake_ctxt)
1135             return process->glstates[i];
1136         }
1137
1138     return 0;
1139 }
1140
1141 void gl_disconnect(ProcessState *process)
1142 {
1143     int i;
1144     for (i = 0; i < process->nb_states; i++) {
1145         destroy_gl_state(process->glstates[i]);
1146         g_free(process->glstates[i]);
1147     }
1148     destroy_gl_state(&process->default_state);
1149     g_free(process->glstates);
1150
1151     if (process->cmdbuf)
1152         g_free(process->cmdbuf);
1153
1154     for (i = 0; &processes[i] != process; i ++) {
1155                 ; // do nothing
1156         }
1157
1158         memmove(&processes[i], &processes[i + 1],
1159                         (MAX_HANDLED_PROCESS - 1 - i) * sizeof(ProcessState));
1160 }
1161
1162 static const int beginend_allowed[GL_N_CALLS] = {
1163 #undef MAGIC_MACRO
1164 #define MAGIC_MACRO(name) [name ## _func] = 1,
1165 #include "gl_beginend.h"
1166 };
1167
1168 ProcessStruct *vmgl_get_process(pid_t pid)
1169 {
1170     ProcessState *process = NULL;
1171     static int first;
1172     int i;
1173
1174     if(!first) {
1175         first = 1;
1176         init_process_tab();
1177     }
1178
1179     /* Lookup a process stuct. If there isnt one associated with this pid
1180      * then we create one.
1181      * process->current_state contains info on which of the guests contexts is
1182      * current.
1183      */
1184     for (i = 0; i < MAX_HANDLED_PROCESS; i ++) {
1185         if (processes[i].p.process_id == pid) {
1186             process = &processes[i];
1187             break;
1188         } else if (processes[i].p.process_id == 0) {
1189             process = &processes[i];
1190             memset(process, 0, sizeof(ProcessState));
1191             process->p.process_id = pid;
1192             init_gl_state(&process->default_state);
1193             process->current_state = &process->default_state;
1194             break;
1195         }
1196         }
1197
1198     if (process == NULL) {
1199         DEBUGF( "Too many processes !\n");
1200         exit(-1);
1201     }
1202
1203     return (ProcessStruct *)process; // Cast is ok due to struct defn.
1204 }
1205
1206 void vmgl_context_switch(ProcessStruct *p, int switch_gl_context)
1207 {
1208     ProcessState *process = (ProcessState *)p;
1209     if(switch_gl_context) {
1210         if(process->current_state->current_qsurface)
1211             glo_surface_makecurrent(process->current_state->current_qsurface->surface);
1212         else
1213             glo_surface_makecurrent(0); // should never happen
1214     }
1215 }
1216
1217 static const char *opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf)
1218 {
1219         char *start;
1220         char *ret;
1221         char *p;
1222         int retlen;
1223     static const char *delim = " \t\n\r/";
1224
1225         if (prevbuf)
1226                 free(prevbuf);
1227
1228     if (s) {
1229         *saveptr = s;
1230     } else {
1231         if (!(*saveptr) || !(*n))
1232             return NULL;
1233         s = *saveptr;
1234     }
1235
1236     for (; *n && strchr(delim, *s); s++, (*n)--) {
1237         if (*s == '/' && *n > 1) {
1238             if (s[1] == '/') {
1239                 do {
1240                     s++, (*n)--;
1241                 } while (*n > 1 && s[1] != '\n' && s[1] != '\r');
1242             } else if (s[1] == '*') {
1243                 do {
1244                     s++, (*n)--;
1245                 } while (*n > 2 && (s[1] != '*' || s[2] != '/'));
1246                 s++, (*n)--;
1247                                 s++, (*n)--;
1248                                 if (*n == 0) {
1249                                         break;
1250                                 }
1251                         } else {
1252                                 break;
1253             }
1254         }
1255     }
1256
1257         start = s;
1258     for (; *n && *s && !strchr(delim, *s); s++, (*n)--) {
1259                 ; // do nothing
1260         }
1261
1262         if (*n > 0) 
1263                 s++, (*n)--;
1264
1265         *saveptr = s;
1266
1267         retlen = s - start;
1268         ret = malloc(retlen + 1);
1269         p = ret;
1270
1271         if (retlen == 0) {
1272                 *p = 0;
1273                 return;
1274         }
1275
1276         while (retlen > 0) {
1277         if (*start == '/' && retlen > 1) {
1278             if (start[1] == '/') {
1279                 do {
1280                     start++, retlen--;
1281                 } while (retlen > 1 && start[1] != '\n' && start[1] != '\r');
1282                                 start++, retlen--;
1283                                 continue;
1284             } else if (start[1] == '*') {
1285                 do {
1286                     start++, retlen--;
1287                 } while (retlen > 2 && (start[1] != '*' || start[2] != '/'));
1288                 start += 3, retlen -= 3;
1289                                 continue;
1290             }
1291         }
1292                 *(p++) = *(start++), retlen--;
1293         }
1294         
1295         *p = 0;
1296         return ret;
1297 }
1298
1299 static char *do_eglShaderPatch(const char *source, int length, int *patched_len)
1300 {
1301         char *saveptr = NULL;
1302         char *sp;
1303         char *p = NULL;
1304
1305     if (!length) 
1306         length = strlen(source);
1307     
1308     *patched_len = 0;
1309     int patched_size = length;
1310     char *patched = malloc(patched_size + 1);
1311
1312     if (!patched) 
1313         return NULL;
1314
1315     p = opengl_strtok(source, &length, &saveptr, NULL);
1316     for (; p; p = opengl_strtok(0, &length, &saveptr, p)) {
1317         if (!strncmp(p, "lowp", 4) || !strncmp(p, "mediump", 7) || !strncmp(p, "highp", 5)) {
1318             continue;
1319         } else if (!strncmp(p, "precision", 9)) {
1320             while ((p = opengl_strtok(0, &length, &saveptr, p)) && !strchr(p, ';')) {
1321                                 // do nothing
1322                                 ;
1323                         }
1324         } else {
1325             if (!strncmp(p, "gl_MaxVertexUniformVectors", 26)) {
1326                 p = "(gl_MaxVertexUniformComponents / 4)";
1327             } else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28)) {
1328                 p = "(gl_MaxFragmentUniformComponents / 4)";
1329             } else if (!strncmp(p, "gl_MaxVaryingVectors", 20)) {
1330                 p = "(gl_MaxVaryingFloats / 4)";
1331             }
1332
1333             int new_len = strlen(p);
1334             if (*patched_len + new_len > patched_size) {
1335                 patched_size *= 2;
1336                 patched = realloc(patched, patched_size + 1);
1337
1338                 if (!patched) 
1339                     return NULL;
1340             }
1341
1342             memcpy(patched + *patched_len, p, new_len);
1343             *patched_len += new_len;
1344         }     
1345     }
1346
1347     patched[*patched_len] = 0;
1348     /* check that we don't leave dummy preprocessor lines */
1349     for (sp = patched; *sp;) {
1350         for (; *sp == ' ' || *sp == '\t'; sp++) {
1351                         ; // do nothing
1352                 }
1353         if (!strncmp(sp, "#define", 7)) {
1354             for (p = sp + 7; *p == ' ' || *p == '\t'; p++) {
1355                                 ; // do nothing
1356                         }
1357             if (*p == '\n' || *p == '\r' || *p == '/') {
1358                 memset(sp, 0x20, 7);
1359             }
1360         }
1361         for (; *sp && *sp != '\n' && *sp != '\r'; sp++) {
1362                         ; // do nothing
1363                 }
1364         for (; *sp == '\n' || *sp == '\r'; sp++) {
1365                         ; // do nothing
1366                 }
1367     }
1368     return patched;
1369 }
1370
1371 static int 
1372 shadersrc_gles_to_gl(GLsizei count, const char** string, char **s, const GLint* length, GLint *l)
1373 {
1374         int i;
1375
1376         for(i = 0; i < count; ++i) {
1377                 GLint len;
1378                 if(length) {
1379                         len = length[i];
1380                         if (len < 0) 
1381                                 len = string[i] ? strlen(string[i]) : 0;
1382                 } else
1383                         len = string[i] ? strlen(string[i]) : 0;
1384
1385                 if(string[i]) {
1386                         s[i] = do_eglShaderPatch(string[i], len, &l[i]);
1387                         if(!s[i]) {
1388                                 while(i) {
1389                                         free(s[--i]);
1390                                 }
1391
1392                                 free(l);
1393                                 free(s);
1394                                 return -1;
1395                         }
1396                 } else {
1397                         s[i] = NULL;
1398                         l[i] = 0;
1399                 }
1400         }
1401         
1402         return 0;
1403 }
1404
1405 #ifdef __APPLE__
1406 /* XXX:This is work around fix Mac host GL driver's bug that cause webapp
1407  * screen crash. When one context use textures from other sharing context, some
1408  * textures are not initialized or shared successfully. So use glGetTexImage to
1409  * read texture back right after glTexSubImage2D, thus guarantee a
1410  * synchronization.
1411  */
1412 static void mac_dump_texture()
1413 {
1414         int w, h;
1415         unsigned char *buf;
1416
1417         /* only handle target=GL_TEXTURE_2D, level=0, format=GL_RGBA, type=GL_UNSIGNED_BYTE */
1418         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
1419         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
1420
1421         if ( w == 0 && h == 0 )
1422                 return;
1423
1424         buf = g_malloc( (w*4) * h); /* XXX:need allignment? */
1425
1426         glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1427
1428         g_free(buf);
1429 }
1430 #endif
1431
1432 int do_function_call(ProcessState *process, int func_number, unsigned long *args, char *ret_string)
1433 {
1434     union gl_ret_type ret;
1435
1436     Signature *signature = (Signature *) tab_opengl_calls[func_number];
1437     int ret_type = signature->ret_type;
1438
1439     ret.s = NULL;
1440
1441     if (display_function_call) {
1442         DEBUGF( "[%d]> %s\n", process->p.process_id,
1443                 tab_opengl_calls_name[func_number]);
1444     }
1445         TRACE( "[%d]> %s\n", process->p.process_id,
1446                         tab_opengl_calls_name[func_number]);
1447
1448     switch (func_number) {
1449     case -1:
1450         break;
1451
1452     case _resize_surface_func:
1453         {
1454             ClientGLXDrawable client_drawable = to_drawable(args[0]);
1455             QGloSurface *qsurface = get_qsurface_from_client_drawable(
1456                                         process->current_state, client_drawable);
1457
1458             // We have to assume the current context here
1459             // since we assume that a drawable must belong to a specific context
1460             resize_surface(process, qsurface, (int)args[1], (int)args[2]);
1461             break;
1462
1463         }
1464
1465     case _render_surface_func:
1466         {
1467             ClientGLXDrawable client_drawable = to_drawable(args[0]);
1468             QGloSurface *qsurface = get_qsurface_from_client_drawable(
1469                                         process->current_state, client_drawable);
1470             int bpp    = (int)args[1];
1471             int stride = (int)args[2];
1472             char *render_buffer = (char*)args[3];
1473
1474 //            DEBUGF( "win: %08x stride: %d buf: %08x cl_dr: %08x qsurf: %08x\n", args[0], args[1], args[2], client_drawable, qsurface);
1475
1476             // We have to assume the current context here
1477             // since we assume that a drawable must belong to a specific context
1478             render_surface(qsurface, bpp, stride, render_buffer);
1479             break;
1480
1481         }
1482
1483     case glXWaitGL_func:
1484         {
1485             glFinish(); //glXWaitGL();
1486             ret.i = 0;
1487             break;
1488         }
1489
1490     case glXWaitX_func:
1491         {
1492             // FIXME GW Maybe we should just do this on the server?
1493             //glXWaitX();
1494             ret.i = 0;
1495             break;
1496         }
1497
1498     case glXChooseVisual_func:
1499         {
1500             ret.i = glXChooseVisualFunc((int *) &args[2]);
1501             break;
1502         }
1503
1504     case glXQueryExtensionsString_func:
1505         {
1506             ret.s = supported_glx_extensions();//glXQueryExtensionsString(dpy, 0);
1507             break;
1508         }
1509
1510     case glXQueryServerString_func:
1511         {
1512             switch (args[2]) {
1513             case GLX_VENDOR : ret.s = FAKE_GLX_VENDOR; break;
1514             case GLX_VERSION : ret.s = FAKE_GLX_VERSION_STRING; break;
1515             case GLX_EXTENSIONS : ret.s = supported_glx_extensions(); break;
1516             default: ret.s = 0;
1517             }
1518             break;
1519         }
1520
1521     case glXGetClientString_func:
1522         {
1523             switch (args[1]) {
1524             case GLX_VENDOR : ret.s = FAKE_GLX_VENDOR; break;
1525             case GLX_VERSION : ret.s = FAKE_GLX_VERSION_STRING; break;
1526             case GLX_EXTENSIONS : ret.s = "GLX_ARB_get_proc_address "; break;
1527             default: ret.s = 0;
1528             }
1529             break;
1530         }
1531
1532     case glXGetScreenDriver_func:
1533         {
1534             // FIXME GW What is this? not documented anywhere!!
1535             //GET_EXT_PTR(const char *, glXGetScreenDriver, (Display *, int));
1536             //ret.s = ptr_func_glXGetScreenDriver(dpy, 0);
1537             ret.s = "";
1538             break;
1539         }
1540
1541     case glXGetDriverConfig_func:
1542         {
1543             // FIXME GW What is this? not documented anywhere!!
1544             //GET_EXT_PTR(const char *, glXGetDriverConfig, (const char *));
1545             //ret.s = ptr_func_glXGetDriverConfig((const char *) args[0]);
1546             ret.s = "";
1547             break;
1548         }
1549
1550     case glXCreateContext_func:
1551         {
1552             int visualid = (int) args[1];
1553             int fake_shareList = (int) args[2];
1554
1555             if (display_function_call)
1556                 DEBUGF( "visualid=%d, fake_shareList=%d\n", visualid,
1557                         fake_shareList);
1558
1559             GLState *shareListState = get_glstate_for_fake_ctxt(process, fake_shareList);
1560             int fake_ctxt = ++process->next_available_context_number;
1561
1562             ret.i = fake_ctxt;
1563
1564             // Work out format flags from visual id
1565             int formatFlags = GLO_FF_DEFAULT;
1566             if (visualid>=0 && visualid<DIM(FBCONFIGS))
1567               formatFlags = FBCONFIGS[visualid].formatFlags;
1568
1569             GLState *state = _create_context(process, fake_ctxt, fake_shareList);
1570             state->context = glo_context_create(formatFlags,
1571                                                 (GloContext*)shareListState?shareListState->context:0);
1572
1573             DEBUGF( " created context %p for %08x\n", state, fake_ctxt);
1574             break;
1575         }
1576
1577
1578     case glXCreateNewContext_func:
1579         {
1580             int client_fbconfig = args[1];
1581
1582             ret.i = 0;
1583             const GLXFBConfig *fbconfig = get_fbconfig(process, client_fbconfig);
1584
1585             if (fbconfig) {
1586                 int fake_shareList = args[3];
1587                 GLState *shareListState = get_glstate_for_fake_ctxt(process, fake_shareList);
1588
1589                 process->next_available_context_number++;
1590                 int fake_ctxt = process->next_available_context_number;
1591                 ret.i = fake_ctxt;
1592
1593                 GLState *state = _create_context(process, fake_ctxt, fake_shareList);
1594                 state->context = glo_context_create(fbconfig->formatFlags,
1595                                                     shareListState?shareListState->context:0); // FIXME GW get from fbconfig
1596             }
1597             break;
1598         }
1599
1600     case glXCopyContext_func:
1601         {
1602           DEBUGF( " glXCopyContext not supported (does anything use it?)\n");
1603             break;
1604         }
1605
1606     case glXDestroyContext_func:
1607         {
1608             int fake_ctxt = (int) args[1];
1609
1610             if (display_function_call)
1611                 DEBUGF( "fake_ctxt=%d\n", fake_ctxt);
1612
1613             int i;
1614             for (i = 0; i < process->nb_states; i ++) {
1615                 if (process->glstates[i]->fake_ctxt == fake_ctxt) {
1616                      /*XXX: DestroyContext should not switch current context, or
1617                      * else guest still try to access it and cause qemu
1618                      * segfalt. But not sure if any corner case, so comment it
1619                      * for now and will remove it completely in future.
1620                      */
1621                     // this was our GLState...
1622                     // process->current_state = &process->default_state;
1623
1624                     int fake_shareList =
1625                         process->glstates[i]->fake_shareList;
1626                     process->glstates[i]->ref--;
1627                     if (process->glstates[i]->ref == 0) {
1628                         DEBUGF(
1629                                 "destroy_gl_state fake_ctxt = %d\n",
1630                                 process->glstates[i]->fake_ctxt);
1631                         destroy_gl_state(process->glstates[i]);
1632                         g_free(process->glstates[i]);
1633                         memmove(&process->glstates[i],
1634                                 &process->glstates[i + 1],
1635                                 (process->nb_states - i - 1) *
1636                                 sizeof(GLState *));
1637                         process->nb_states --;
1638                     }
1639
1640                     if (fake_shareList) {
1641                         for (i = 0; i < process->nb_states; i++) {
1642                             if (process->glstates[i]->fake_ctxt ==
1643                                 fake_shareList) {
1644                                 process->glstates[i]->ref--;
1645                                 if (process->glstates[i]->ref == 0) {
1646                                     DEBUGF(
1647                                             "destroy_gl_state fake_ctxt = %d\n",
1648                                             process->glstates[i]->
1649                                             fake_ctxt);
1650                                     destroy_gl_state(process->
1651                                                      glstates[i]);
1652                                     g_free(process->glstates[i]);
1653                                     memmove(&process->glstates[i],
1654                                             &process->glstates[i + 1],
1655                                             (process->nb_states - i - 1) *
1656                                             sizeof(GLState *));
1657                                     process->nb_states --;
1658                                 }
1659                                 break;
1660                             }
1661                         }
1662                     }
1663
1664                     break;
1665                 }
1666             }
1667             break;
1668         }
1669
1670     case glXQueryVersion_func:
1671         {
1672             int *major = (int *) args[1];
1673             int *minor = (int *) args[2];
1674             //ret.i = glXQueryVersion(dpy, (int *) args[1], (int *) args[2]);
1675             if (major) *major=FAKE_GLX_VERSION_MAJOR;
1676             if (minor) *minor=FAKE_GLX_VERSION_MINOR;
1677             ret.i = True;
1678             break;
1679         }
1680
1681     case glGetString_func:
1682         {
1683             switch (args[0]) {
1684               case GL_VENDOR:
1685                 ret.s = FAKE_GL_VENDOR;
1686               break;
1687               case GL_RENDERER:
1688                 ret.s = FAKE_GL_RENDERER;
1689               break;
1690               case GL_VERSION:
1691                 ret.s = FAKE_GL_VERSION;
1692               break;
1693               case GL_EXTENSIONS:
1694                 ret.s = compute_gl_extensions();
1695               break;
1696               case GL_SHADING_LANGUAGE_VERSION:
1697                 if(FAKE_GL_MAJOR < 2) {
1698                   ret.s = "";
1699                   break;
1700                 }
1701               // Fall through.
1702               default:
1703                 ret.s = (char *) glGetString(args[0]);
1704               break;
1705             }
1706             break;
1707         }
1708
1709     case glXMakeCurrent_func:
1710         {
1711             ClientGLXDrawable client_drawable = to_drawable(args[1]);
1712             int fake_ctxt = (int) args[2];
1713             GLState *glstate = NULL;
1714
1715 //            DEBUGF( "Makecurrent: fake_ctx=%d client_drawable=%08x\n", fake_ctxt, client_drawable);
1716
1717             if (client_drawable == 0 && fake_ctxt == 0) {
1718                 /* Release context */
1719                 if(process->current_state->current_qsurface)
1720                     process->current_state->current_qsurface->ref--;
1721                 process->current_state = &process->default_state;
1722
1723 //                DEBUGF( " --release\n");
1724                 glo_surface_makecurrent(0);
1725             } else { /* Lookup GLState struct for this context */
1726                 glstate = get_glstate_for_fake_ctxt(process, fake_ctxt);
1727                 if (!glstate) {
1728                     DEBUGF( " --invalid fake_ctxt (%d)!\n", fake_ctxt);
1729                 } else {
1730                                         if(!set_current_qsurface(glstate, client_drawable) &&
1731                                            !link_qsurface(process, glstate, client_drawable) ) {
1732                        // If there is no surface, create one.
1733                        QGloSurface *qsurface = calloc(1, sizeof(QGloSurface));
1734                        qsurface->surface = glo_surface_create(4, 4,
1735                                                               glstate->context);
1736                        qsurface->client_drawable = client_drawable;
1737                        qsurface->ref = 1;
1738                                            qsurface->type = SURFACE_WINDOW;
1739                                            qsurface->status = SURFACE_ACTIVE;
1740
1741                        bind_qsurface(glstate, qsurface);
1742 //                       DEBUGF( " --Client drawable not found, create new surface: %16x %16lx\n", (unsigned int)qsurface, (unsigned long int)client_drawable);
1743
1744                     }
1745                     else {
1746 //                       DEBUGF( " --Client drawable found, using surface: %16x %16lx\n", (unsigned int)glstate->current_qsurface, (unsigned long int)client_drawable);
1747                     }
1748 #if 0
1749                     /*Test old surface contents */
1750                     int reset_texture = 0;
1751                     GLState *old_glstate = NULL;
1752                     /* Switch from pixmap */
1753                     if (process->current_state->current_qsurface && SURFACE_PIXMAP == process->current_state->current_qsurface->type )
1754                     {
1755                         glo_surface_updatecontents(process->current_state->current_qsurface->surface);
1756                         reset_texture = 1;
1757                         old_glstate = process->current_state;
1758                     }
1759                     fprintf(stderr, "edwin:MakeCurrent: drawable=0x%x,qsurface=%p.\n", client_drawable, glstate->current_qsurface);
1760
1761 #endif
1762                     /* Switch in pixmap surface */
1763                     if (glstate->current_qsurface && SURFACE_PIXMAP == glstate->current_qsurface->type )
1764                     {
1765                         /* Release it if the surface is used as texture target */
1766                         glo_surface_release_texture(glstate->current_qsurface);
1767                     }
1768
1769                     process->current_state = glstate;
1770
1771                     ret.i = glo_surface_makecurrent(glstate->current_qsurface->surface);
1772 /*                    if (reset_texture)*/
1773 /*                        glo_surface_as_texture(process->current_state->context, old_glstate->current_qsurface->surface);*/
1774                 }
1775             }
1776             break;
1777         }
1778
1779     case glXSwapBuffers_func:
1780         {
1781             // Does nothing - window data is copied via render_surface()
1782             break;
1783         }
1784     case glXIsDirect_func:
1785         {
1786             // int fake_ctxt = (int) args[1];
1787
1788             // Does this go direct and skip the X server? We'll just say
1789             // yes for now.
1790             ret.c = True;
1791
1792             break;
1793         }
1794
1795     case glXGetConfig_func:
1796         {
1797             int visualid = args[1];
1798             ret.i = glXGetConfigFunc(visualid, args[2], (int *) args[3]);
1799             break;
1800         }
1801
1802     case glXGetConfig_extended_func:
1803         {
1804             int visualid = args[1];
1805             int n = args[2];
1806             int i;
1807             int *attribs = (int *) args[3];
1808             int *values = (int *) args[4];
1809             int *res = (int *) args[5];
1810
1811             for (i = 0; i < n; i++) {
1812                 res[i] = glXGetConfigFunc(visualid, attribs[i], &values[i]);
1813             }
1814             break;
1815         }
1816
1817     case glXUseXFont_func:
1818         {
1819             /* implementation is client-side only :-) */
1820             break;
1821         }
1822
1823     case glXQueryExtension_func:
1824         {
1825             int *errorBase = (int *) args[1];
1826             int *eventBase = (int *) args[2];
1827             if (errorBase) *errorBase = 0; /* FIXME GW */
1828             if (eventBase) *eventBase = 0; /* FIXME GW */
1829             ret.i = True;
1830             break;
1831         }
1832
1833     case glXChooseFBConfig_func:
1834         {
1835             if (process->nfbconfig == MAX_FBCONFIG) {
1836                 *(int *) args[3] = 0;
1837                 ret.i = 0;
1838             } else {
1839                 const GLXFBConfig *fbconfigs =
1840                     glXChooseFBConfigFunc(args[1], (int *) args[2], (int *) args[3]);
1841                 if (fbconfigs) {
1842                     process->fbconfigs[process->nfbconfig] = fbconfigs;
1843                     process->fbconfigs_max[process->nfbconfig] =
1844                         *(int *) args[3];
1845                     process->nfbconfig++;
1846                     ret.i = 1 + process->nfbconfig_total;
1847                     process->nfbconfig_total +=
1848                         process->fbconfigs_max[process->nfbconfig];
1849                 } else {
1850                     ret.i = 0;
1851                 }
1852             }
1853             break;
1854         }
1855     case glXGetFBConfigs_func:
1856         {
1857             if (process->nfbconfig == MAX_FBCONFIG) {
1858                 *(int *) args[2] = 0;
1859                 ret.i = 0;
1860             } else {
1861                 const GLXFBConfig *fbconfigs =
1862                     glXGetFBConfigsFunc(args[1], (int *) args[2]);
1863                 if (fbconfigs) {
1864                     process->fbconfigs[process->nfbconfig] = fbconfigs;
1865                     process->fbconfigs_max[process->nfbconfig] =
1866                         *(int *) args[2];
1867                     process->nfbconfig++;
1868                     ret.i = 1 + process->nfbconfig_total;
1869                     process->nfbconfig_total +=
1870                         process->fbconfigs_max[process->nfbconfig];
1871                 } else {
1872                     ret.i = 0;
1873                 }
1874             }
1875             break;
1876         }
1877     case glXGetFBConfigAttrib_func:
1878         {
1879             int client_fbconfig = args[1];
1880
1881             ret.i = 0;
1882             const GLXFBConfig *fbconfig = get_fbconfig(process, client_fbconfig);
1883
1884             if (fbconfig)
1885                 ret.i =
1886                     glXGetFBConfigAttribFunc(fbconfig, args[2], (int *) args[3]);
1887             break;
1888         }
1889
1890     case glXGetFBConfigAttrib_extended_func:
1891         {
1892             int client_fbconfig = args[1];
1893             int n = args[2];
1894             int i;
1895             int *attribs = (int *) args[3];
1896             int *values = (int *) args[4];
1897             int *res = (int *) args[5];
1898             const GLXFBConfig *fbconfig = get_fbconfig(process, client_fbconfig);
1899
1900             for (i = 0; i < n; i++) {
1901                 if (fbconfig) {
1902                     res[i] =
1903                         glXGetFBConfigAttribFunc(fbconfig, attribs[i], &values[i]);
1904                 } else {
1905                     res[i] = 0;
1906                 }
1907             }
1908             break;
1909         }
1910     case glXQueryContext_func:
1911         {
1912             DEBUGF( "glXQueryContext not implemented\n");
1913             ret.i = 0;
1914 #if 0 //GW
1915             GET_EXT_PTR(int, glXQueryContext,
1916                         (Display *, GLXContext, int, int *));
1917             int fake_ctxt = (int) args[1];
1918
1919             if (display_function_call)
1920                 DEBUGF( "fake_ctx=%i\n", fake_ctxt);
1921             GLXContext ctxt =
1922                 get_association_fakecontext_glxcontext(process, fake_ctxt);
1923             if (ctxt == NULL) {
1924                 DEBUGF( "invalid fake_ctxt (%i) !\n", fake_ctxt);
1925                 ret.i = 0;
1926             } else {
1927                 ret.i =
1928                     ptr_func_glXQueryContext(dpy, ctxt, args[2],
1929                                              (int *) args[3]);
1930             }
1931 #endif
1932             break;
1933         }
1934
1935     case glXQueryDrawable_func:
1936         {
1937             // TODO GW one of:
1938             // GLX_WIDTH, GLX_HEIGHT, GLX_PRESERVED_CONTENTS, GLX_LARGEST_PBUFFER, GLX_FBCONFIG_ID
1939             DEBUGF( "FIXME: glXQueryDrawable not implemented\n");
1940             ret.i = 0;
1941 #if 0 //GW
1942             GET_EXT_PTR(void, glXQueryDrawable,
1943                         (Display *, GLXDrawable, int, int *));
1944             ClientGLXDrawable client_drawable = to_drawable(args[1]);
1945             GLXDrawable drawable =
1946                     get_association_clientdrawable_serverdrawable(
1947                                     glstate, client_drawable);
1948
1949             if (display_function_call)
1950                 DEBUGF( "client_drawable=%p\n",
1951                                 client_drawable);
1952
1953             if (!drawable)
1954                 DEBUGF( "invalid client_drawable (%p) !\n",
1955                                 client_drawable);
1956             else
1957                 ptr_func_glXQueryDrawable(dpy, drawable,
1958                                 args[2], (int *) args[3]);
1959 #endif
1960             break;
1961         }
1962     case glXGetVisualFromFBConfig_func:
1963         {
1964             int client_fbconfig = args[1];
1965
1966             ret.i = 0;
1967             const GLXFBConfig *fbconfig = get_fbconfig(process, client_fbconfig);
1968
1969             if (fbconfig) {
1970                 // we tread visualid as the index into the fbconfigs array
1971                 ret.i = &FBCONFIGS[0] - fbconfig;
1972                 if (display_function_call)
1973                     DEBUGF( "visualid = %d\n", ret.i);
1974             }
1975             break;
1976         }
1977     case glXSwapIntervalSGI_func:
1978         {
1979             /*GET_EXT_PTR(int, glXSwapIntervalSGI, (int));
1980             ret.i = ptr_func_glXSwapIntervalSGI(args[0]);*/
1981             ret.i = 0;
1982             break;
1983         }
1984
1985     case glXGetProcAddress_fake_func:
1986         {
1987 //            if (display_function_call)
1988             //DEBUGF( "glXGetProcAddress %s  ", (char *) args[0]);
1989             ret.i = glo_getprocaddress((const char *) args[0]) != NULL;
1990             //   DEBUGF( " == %08x\n", ret.i);
1991             ret.i = 0;
1992             break;
1993         }
1994
1995     case glXGetProcAddress_global_fake_func:
1996         {
1997             int nbElts = args[0];
1998             char *huge_buffer = (char *) args[1];
1999             char *result = (char *) args[2];
2000             int i;
2001
2002             for (i = 0; i < nbElts; i++) {
2003                 int len = strlen(huge_buffer);
2004                 //DEBUGF( "glXGetProcAddress_global %s  ", (char *)huge_buffer);
2005                 result[i] =
2006                     glo_getprocaddress((const char *) huge_buffer) !=
2007                     NULL;
2008                 huge_buffer += len + 1;
2009             }
2010             break;
2011         }
2012     case glXCreatePixmap_func:
2013         {
2014             int client_fbconfig = args[1];
2015
2016             ret.i = 0;
2017             const GLXFBConfig *fbconfig = get_fbconfig(process, client_fbconfig);
2018
2019             if (fbconfig) {
2020
2021                 /* Create a light-weight context just for creating surface */
2022                 GloContext *context = __glo_context_create(fbconfig->formatFlags);
2023
2024                 /* glXPixmap same as input Pixmap */
2025                 ClientGLXDrawable client_drawable = to_drawable(args[2]);
2026
2027                 QGloSurface *qsurface = calloc(1, sizeof(QGloSurface));
2028
2029                 /* get the width and height */
2030                 int width, height;
2031                 glo_geometry_get_from_glx((int*)args[3], &width, &height);
2032
2033                 DEBUGF( "glXCreatePixmap: %dX%d.\n", width, height);
2034                 qsurface->surface = glo_surface_create(width, height, context);
2035                 qsurface->client_drawable = client_drawable;
2036                                 qsurface->type = SURFACE_PIXMAP;
2037                                 qsurface->status = SURFACE_PENDING;
2038                 /*                qsurface->ref = 1;*/
2039
2040                 /* Keep this surface, will link it with context in MakeCurrent */
2041                 keep_qsurface(process, qsurface);
2042
2043                 /* If this pixmap is linked as texture previously */
2044                                 if (link_drawable(process, client_drawable))
2045                                         glo_surface_as_texture(process->current_state->context,
2046                                                         qsurface->surface);
2047
2048
2049                 ret.i = client_drawable;
2050
2051             }
2052             break;
2053         }
2054     case glXDestroyPixmap_func:
2055         {
2056             /* glXPixmap same as input Pixmap */
2057             ClientGLXDrawable client_drawable = to_drawable(args[1]);
2058             QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
2059             if ( qsurface &&
2060                  qsurface != process->current_state->current_qsurface &&
2061                  qsurface->glstate == NULL &&
2062                  qsurface->type == SURFACE_PIXMAP )
2063             {
2064                 glo_surface_destroy(qsurface->surface);
2065                 g_free(qsurface);
2066             }
2067             break;
2068         }
2069     case glEGLImageTargetTexture2DOES_fake_func:
2070         {
2071             int target = args[0];
2072             ClientGLXDrawable client_drawable = to_drawable(args[1]);
2073             QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
2074
2075             /* Only support GL_TEXTURE_2D according to spec */
2076             if ( target == GL_TEXTURE_2D )
2077                 add_pixmap_texture_mapping(process->current_state,
2078                         process->current_state->bindTexture2D,
2079                         client_drawable);
2080             
2081             if ( !qsurface )
2082             {
2083                 if ( !keep_drawable(process, client_drawable) )
2084                 {
2085                     DEBUGF( "No space to store drawable for ImageTargetTexture. Need call CreatePixmapSurface     to free them.\n");
2086                     break;
2087                 }
2088             }
2089             else
2090                                 glo_surface_as_texture(process->current_state->context, qsurface->surface);
2091
2092                         break;
2093                 }
2094         case glXBindTexImageARB_fake_func:
2095                 {
2096                         ClientGLXDrawable client_drawable = to_drawable(args[1]);
2097                         QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
2098                         ret.i = 0;
2099
2100
2101                         if ( qsurface )
2102                         {
2103                                 add_pixmap_texture_mapping(process->current_state,
2104                                                 process->current_state->bindTexture2D,
2105                                                 client_drawable);
2106                                 glo_surface_as_texture(process->current_state->context, qsurface->surface);
2107                                 ret.i = 1;
2108                         }
2109                         else
2110                                 DEBUGF( "Not found pbuffer surface for BindTexImage!\n");
2111
2112                         break;
2113                 }
2114         case glXReleaseTexImageARB_fake_func:
2115                 {
2116                         ClientGLXDrawable client_drawable = to_drawable(args[1]);
2117                         QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
2118
2119                         if ( qsurface )
2120                         {
2121                                 remove_pixmap_texture_mapping(process->current_state,
2122                                                 client_drawable);
2123                                 glo_surface_release_texture(qsurface->surface);
2124                         }
2125
2126                         break;
2127                 }
2128         case glXCreatePbuffer_func:
2129                 {
2130                         int client_fbconfig = args[1];
2131
2132                         ret.i = 0;
2133                         const GLXFBConfig *fbconfig = get_fbconfig(process, client_fbconfig);
2134
2135                         if (fbconfig) {
2136
2137                                 /* Create a light-weight context just for creating surface */
2138                                 GloContext *context = __glo_context_create(fbconfig->formatFlags);
2139
2140                                 QGloSurface *qsurface = calloc(1, sizeof(QGloSurface));
2141
2142                                 /* get the width and height */
2143                                 int width, height;
2144                                 glo_geometry_get_from_glx((int*)args[2], &width, &height);
2145
2146                                 DEBUGF( "glXCreatePbuffer: %dX%d.\n", width, height);
2147                                 qsurface->surface = glo_surface_create(width, height, context);
2148                                 /* Use GloSurface handler as no input client_drawable, and
2149                                  * keep only low 32bit of handler on x86_64 host.  */
2150                                 qsurface->client_drawable = (int)qsurface->surface;
2151                                 qsurface->type = SURFACE_PBUFFER;
2152                                 qsurface->status = SURFACE_PENDING;
2153                                 /*                qsurface->ref = 1;*/
2154
2155                                 /* Keep this surface, will link it with context in MakeCurrent */
2156                                 keep_qsurface(process, qsurface);
2157
2158                                 ret.i = qsurface->client_drawable;
2159
2160                         }
2161                         break;
2162                 }
2163         case glXDestroyPbuffer_func:
2164                 {
2165             ClientGLXDrawable client_drawable = to_drawable(args[1]);
2166             QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
2167             if ( qsurface &&
2168                  qsurface != process->current_state->current_qsurface &&
2169                  qsurface->glstate == NULL &&
2170                  qsurface->type == SURFACE_PBUFFER )
2171             {
2172                 glo_surface_destroy(qsurface->surface);
2173                 g_free(qsurface);
2174             }
2175             break;
2176                 }
2177
2178 /* Begin of texture stuff */
2179     case glBindTexture_func:
2180     case glBindTextureEXT_func:
2181         {
2182             int target = args[0];
2183             unsigned int client_texture = args[1];
2184             unsigned int server_texture;
2185
2186             if (client_texture == 0) {
2187                 glBindTexture(target, 0);
2188             } else {
2189                 alloc_value(process->current_state->textureAllocator,
2190                             client_texture);
2191                 server_texture =
2192                     process->current_state->tabTextures[client_texture];
2193                 if (server_texture == 0) {
2194                     glGenTextures(1, &server_texture);
2195                     process->current_state->tabTextures[client_texture] =
2196                         server_texture;
2197                 }
2198                 glBindTexture(target, server_texture);
2199             }
2200
2201             if ( target == GL_TEXTURE_2D ) {
2202                 QGloSurface *qsurface = NULL;
2203                 ClientGLXDrawable drawable =
2204                     find_pixmap_texture(process->current_state, client_texture);
2205
2206                 if ( drawable )
2207                 {
2208                     qsurface = find_qsurface_from_client_drawable(process, drawable);
2209
2210                     if ( qsurface )
2211                     {
2212                         glo_surface_as_texture(process->current_state->context, qsurface->surface);
2213                         fprintf(stderr, "edwin:bindtexture: drawable=0x%x,qsurface=%p.\n", drawable, qsurface);
2214                     }
2215                 }
2216
2217                 process->current_state->bindTexture2D = client_texture;
2218             }
2219                         break;
2220         }
2221
2222     case glGenTextures_fake_func:
2223         {
2224             //GET_EXT_PTR(void, glGenTextures, (GLsizei n, GLuint *textures));
2225             int i;
2226             int n = args[0];
2227             unsigned int *clientTabTextures = g_malloc(n * sizeof(int));
2228             unsigned int *serverTabTextures = g_malloc(n * sizeof(int));
2229
2230             alloc_range(process->current_state->textureAllocator, n,
2231                         clientTabTextures);
2232
2233             //ptr_func_glGenTextures(n, serverTabTextures);
2234                 glGenTextures(n, serverTabTextures);
2235             for (i = 0; i < n; i++) {
2236                 process->current_state->tabTextures[clientTabTextures[i]] =
2237                     serverTabTextures[i];
2238             }
2239
2240             g_free(clientTabTextures);
2241             g_free(serverTabTextures);
2242             break;
2243         }
2244
2245
2246     case glDeleteTextures_func:
2247         {
2248             //GET_EXT_PTR(void, glDeleteTextures,
2249             //            (GLsizei n, const GLuint *textures));
2250             int i;
2251             int n = args[0];
2252             unsigned int *clientTabTextures = (unsigned int *) args[1];
2253
2254             delete_range(process->current_state->textureAllocator, n,
2255                          clientTabTextures);
2256
2257             unsigned int *serverTabTextures = g_malloc(n * sizeof(int));
2258
2259             for (i = 0; i < n; i++) {
2260                 serverTabTextures[i] =
2261                     get_server_texture(process, clientTabTextures[i]);
2262             }
2263             //ptr_func_glDeleteTextures(n, serverTabTextures);
2264                 glDeleteTextures(n, serverTabTextures);
2265             for (i = 0; i < n; i++) {
2266                 process->current_state->tabTextures[clientTabTextures[i]] = 0;
2267             }
2268             g_free(serverTabTextures);
2269
2270             for ( i = 0; i < n; i++ )
2271             {
2272                 del_pixmap_texture_mapping(process->current_state, clientTabTextures[i]);
2273             }
2274             break;
2275         }
2276
2277     case glPrioritizeTextures_func:
2278         {
2279             GET_EXT_PTR(void, glPrioritizeTextures,
2280                         (GLsizei n, const GLuint *textures,
2281                          const GLclampf *priorities));
2282
2283             int i;
2284             int n = args[0];
2285             unsigned int *textures = (unsigned int *) args[1];
2286
2287             for (i = 0; i < n; i++) {
2288                 textures[i] = get_server_texture(process, textures[i]);
2289             }
2290             ptr_func_glPrioritizeTextures(n, textures,
2291                                           (const GLclampf *) args[2]);
2292             break;
2293         }
2294
2295     case glAreTexturesResident_func:
2296         {
2297             GET_EXT_PTR(void, glAreTexturesResident,
2298                         (GLsizei n, const GLuint *textures,
2299                          GLboolean *residences));
2300             int i;
2301             int n = args[0];
2302             unsigned int *textures = (unsigned int *) args[1];
2303
2304             for (i = 0; i < n; i++) {
2305                 textures[i] = get_server_texture(process, textures[i]);
2306             }
2307             ptr_func_glAreTexturesResident(n, textures,
2308                                            (GLboolean *) args[2]);
2309             break;
2310         }
2311
2312     case glIsTexture_func:
2313     case glIsTextureEXT_func:
2314         {
2315             //GET_EXT_PTR(GLboolean, glIsTexture, (GLuint texture));
2316             unsigned int client_texture = args[0];
2317             unsigned int server_texture =
2318                 get_server_texture(process, client_texture);
2319             if (server_texture)
2320             //    ret.c = ptr_func_glIsTexture(server_texture);
2321                 ret.c = glIsTexture(server_texture);
2322             else
2323                 ret.c = 0;
2324             break;
2325         }
2326
2327     case glFramebufferTexture1DEXT_func:
2328         {
2329             GET_EXT_PTR(void, glFramebufferTexture1DEXT,
2330                         (int, int, int, int, int));
2331             unsigned int client_texture = args[3];
2332             unsigned int server_texture =
2333                 get_server_texture(process, client_texture);
2334             if (server_texture)
2335                 ptr_func_glFramebufferTexture1DEXT(args[0], args[1], args[2],
2336                                                    server_texture, args[4]);
2337             break;
2338         }
2339
2340     case glFramebufferTexture2D_func:
2341         //DEBUGF( "wooooot!\n");
2342     case glFramebufferTexture2DEXT_func:
2343         {
2344             GET_EXT_PTR(void, glFramebufferTexture2DEXT,
2345                         (int, int, int, int, int));
2346             unsigned int client_texture = args[3];
2347             unsigned int server_texture =
2348                 get_server_texture(process, client_texture);
2349             if (server_texture)
2350                 ptr_func_glFramebufferTexture2DEXT(args[0], args[1], args[2],
2351                                                    server_texture, args[4]);
2352             break;
2353         }
2354
2355     case glFramebufferTexture3DEXT_func:
2356         {
2357             GET_EXT_PTR(void, glFramebufferTexture3DEXT,
2358                         (int, int, int, int, int, int));
2359             unsigned int client_texture = args[3];
2360             unsigned int server_texture =
2361                 get_server_texture(process, client_texture);
2362             if (server_texture)
2363                 ptr_func_glFramebufferTexture3DEXT(args[0], args[1], args[2],
2364                                                    server_texture, args[4],
2365                                                    args[5]);
2366             break;
2367         }
2368 /* End of texture stuff */
2369
2370 /* Begin of list stuff */
2371     case glIsList_func:
2372         {
2373             unsigned int client_list = args[0];
2374             unsigned int server_list = get_server_list(process, client_list);
2375
2376             if (server_list)
2377                 ret.c = glIsList(server_list);
2378             else
2379                 ret.c = 0;
2380             break;
2381         }
2382
2383     case glDeleteLists_func:
2384         {
2385             int i;
2386             unsigned int first_client = args[0];
2387             int n = args[1];
2388
2389             unsigned int first_server =
2390                 get_server_list(process, first_client);
2391             for (i = 0; i < n; i++) {
2392                 if (get_server_list(process, first_client + i) !=
2393                     first_server + i)
2394                     break;
2395             }
2396             if (i == n) {
2397                 glDeleteLists(first_server, n);
2398             } else {
2399                 for (i = 0; i < n; i++) {
2400                     glDeleteLists(get_server_list(process, first_client + i),
2401                                   1);
2402                 }
2403             }
2404
2405             for (i = 0; i < n; i++) {
2406                 process->current_state->tabLists[first_client + i] = 0;
2407             }
2408             delete_consecutive_values(process->current_state->listAllocator,
2409                                       first_client, n);
2410             break;
2411         }
2412
2413     case glGenLists_fake_func:
2414         {
2415             int i;
2416             int n = args[0];
2417             unsigned int server_first = glGenLists(n);
2418
2419             if (server_first) {
2420                 unsigned int client_first =
2421                     alloc_range(process->current_state->listAllocator, n,
2422                                 NULL);
2423                 for (i = 0; i < n; i++) {
2424                     process->current_state->tabLists[client_first + i] =
2425                         server_first + i;
2426                 }
2427             }
2428             break;
2429         }
2430
2431     case glNewList_func:
2432         {
2433             unsigned int client_list = args[0];
2434             int mode = args[1];
2435
2436             alloc_value(process->current_state->listAllocator, client_list);
2437             unsigned int server_list = get_server_list(process, client_list);
2438
2439             if (server_list == 0) {
2440                 server_list = glGenLists(1);
2441                 process->current_state->tabLists[client_list] = server_list;
2442             }
2443             glNewList(server_list, mode);
2444             break;
2445         }
2446
2447     case glCallList_func:
2448         {
2449             unsigned int client_list = args[0];
2450             unsigned int server_list = get_server_list(process, client_list);
2451
2452             glCallList(server_list);
2453             break;
2454         }
2455
2456     case glCallLists_func:
2457         {
2458             int i;
2459             int n = args[0];
2460             int type = args[1];
2461             const GLvoid *lists = (const GLvoid *) args[2];
2462             int *new_lists = g_malloc(sizeof(int) * n);
2463
2464             for (i = 0; i < n; i++) {
2465                 new_lists[i] =
2466                     get_server_list(process, translate_id(i, type, lists));
2467             }
2468             glCallLists(n, GL_UNSIGNED_INT, new_lists);
2469             g_free(new_lists);
2470             break;
2471         }
2472
2473
2474 /* End of list stuff */
2475
2476 /* Begin of buffer stuff */
2477     case glBindBufferARB_func:
2478         {
2479             GET_EXT_PTR(void, glBindBufferARB, (int, int));
2480             int target = args[0];
2481             unsigned int client_buffer = args[1];
2482             unsigned int server_buffer;
2483
2484             if (client_buffer == 0) {
2485                 ptr_func_glBindBufferARB(target, 0);
2486             } else {
2487                 server_buffer = get_server_buffer(process, client_buffer);
2488                 ptr_func_glBindBufferARB(target, server_buffer);
2489             }
2490             break;
2491         }
2492
2493     case glGenBuffersARB_fake_func:
2494         {
2495             GET_EXT_PTR(void, glGenBuffersARB, (int, unsigned int *));
2496             int i;
2497             int n = args[0];
2498             unsigned int *clientTabBuffers = g_malloc(n * sizeof(int));
2499             unsigned int *serverTabBuffers = g_malloc(n * sizeof(int));
2500
2501             alloc_range(process->current_state->bufferAllocator, n,
2502                         clientTabBuffers);
2503
2504             ptr_func_glGenBuffersARB(n, serverTabBuffers);
2505             for (i = 0; i < n; i++) {
2506                 process->current_state->tabBuffers[clientTabBuffers[i]] =
2507                     serverTabBuffers[i];
2508             }
2509
2510             g_free(clientTabBuffers);
2511             g_free(serverTabBuffers);
2512             break;
2513         }
2514
2515
2516     case glDeleteBuffersARB_func:
2517         {
2518             GET_EXT_PTR(void, glDeleteBuffersARB, (int, int *));
2519             int i;
2520             int n = args[0];
2521             unsigned int *clientTabBuffers = (unsigned int *) args[1];
2522
2523             delete_range(process->current_state->bufferAllocator, n,
2524                          clientTabBuffers);
2525
2526             int *serverTabBuffers = g_malloc(n * sizeof(int));
2527
2528             for (i = 0; i < n; i++) {
2529                 serverTabBuffers[i] =
2530                     get_server_buffer(process, clientTabBuffers[i]);
2531             }
2532             ptr_func_glDeleteBuffersARB(n, serverTabBuffers);
2533             for (i = 0; i < n; i++) {
2534                 process->current_state->tabBuffers[clientTabBuffers[i]] = 0;
2535             }
2536             g_free(serverTabBuffers);
2537             break;
2538         }
2539
2540     case glIsBufferARB_func:
2541         {
2542             GET_EXT_PTR(int, glIsBufferARB, (int));
2543             unsigned int client_buffer = args[0];
2544             unsigned int server_buffer =
2545                 get_server_buffer(process, client_buffer);
2546             if (server_buffer)
2547                 ret.i = ptr_func_glIsBufferARB(server_buffer);
2548             else
2549                 ret.i = 0;
2550             break;
2551         }
2552
2553 /* End of buffer stuff */
2554
2555     case glShaderSourceARB_fake_func:
2556         {
2557             GET_EXT_PTR(void, glShaderSourceARB, (int, int, char **, void *));
2558             int size = args[1];
2559             int i;
2560             int acc_length = 0;
2561             GLcharARB **tab_prog = g_malloc(size * sizeof(GLcharARB *));
2562             int *tab_length = (int *) args[3];
2563
2564             for (i = 0; i < size; i++) {
2565                 tab_prog[i] = ((GLcharARB *) args[2]) + acc_length;
2566                 acc_length += tab_length[i];
2567             }
2568             ptr_func_glShaderSourceARB(args[0], args[1], tab_prog,
2569                                        tab_length);
2570             g_free(tab_prog);
2571             break;
2572         }
2573
2574     case glShaderSource_fake_func:
2575                 {
2576                         GET_EXT_PTR(void, glShaderSource, (int, int, char **, void *));
2577                         int size = args[1];
2578                         int i;
2579                         int acc_length = 0;
2580                         GLcharARB **tab_prog = g_malloc(size * sizeof(GLcharARB *));
2581                         int *tab_length = (int *) args[3];
2582
2583                         char **tab_prog_new;
2584                         GLint *tab_length_new;
2585
2586                         tab_prog_new = malloc(args[1]* sizeof(char*));
2587                         tab_length_new = malloc(args[1]* sizeof(GLint));
2588
2589                         memset(tab_prog_new, 0, args[1] * sizeof(char*));
2590                         memset(tab_length_new, 0, args[1] * sizeof(GLint));
2591
2592
2593                         for (i = 0; i < size; i++) {
2594                                 tab_prog[i] = ((GLcharARB *) args[2]) + acc_length;
2595                                 acc_length += tab_length[i];
2596                         }
2597
2598                         shadersrc_gles_to_gl(args[1], tab_prog, tab_prog_new, tab_length, tab_length_new);
2599
2600                         if (!tab_prog_new || !tab_length_new)
2601                                 break;
2602
2603                         ptr_func_glShaderSource(args[0], args[1], tab_prog_new, tab_length_new);
2604
2605                         for (i = 0; i < args[1]; i++) {
2606                                 free(tab_prog_new[i]);
2607                         }
2608
2609                         free(tab_prog_new);
2610                         free(tab_length_new);
2611
2612                         free(tab_prog);
2613
2614                         break;
2615                 }
2616
2617     case glVertexPointer_fake_func:
2618         {
2619             int offset = args[0];
2620             int size = args[1];
2621             int type = args[2];
2622             int stride = args[3];
2623             int bytes_size = args[4];
2624
2625             process->current_state->vertexPointerSize =
2626                 MAX(process->current_state->vertexPointerSize,
2627                     offset + bytes_size);
2628             process->current_state->vertexPointer =
2629                 g_realloc(process->current_state->vertexPointer,
2630                         process->current_state->vertexPointerSize);
2631             memcpy(process->current_state->vertexPointer + offset,
2632                    (void *) args[5], bytes_size);
2633             /* DEBUGF( "glVertexPointer_fake_func size=%d, type=%d,
2634              * stride=%d, byte_size=%d\n", size, type, stride, bytes_size); */
2635             glVertexPointer(size, type, stride,
2636                             process->current_state->vertexPointer);
2637             break;
2638         }
2639
2640     case glNormalPointer_fake_func:
2641         {
2642             int offset = args[0];
2643             int type = args[1];
2644             int stride = args[2];
2645             int bytes_size = args[3];
2646
2647             process->current_state->normalPointerSize =
2648                 MAX(process->current_state->normalPointerSize,
2649                     offset + bytes_size);
2650             process->current_state->normalPointer =
2651                 g_realloc(process->current_state->normalPointer,
2652                         process->current_state->normalPointerSize);
2653             memcpy(process->current_state->normalPointer + offset,
2654                    (void *) args[4], bytes_size);
2655             // DEBUGF( "glNormalPointer_fake_func type=%d, stride=%d, 
2656             // byte_size=%d\n", type, stride, bytes_size);
2657             glNormalPointer(type, stride,
2658                             process->current_state->normalPointer);
2659             break;
2660         }
2661
2662     case glIndexPointer_fake_func:
2663         {
2664             int offset = args[0];
2665             int type = args[1];
2666             int stride = args[2];
2667             int bytes_size = args[3];
2668
2669             process->current_state->indexPointerSize =
2670                 MAX(process->current_state->indexPointerSize,
2671                     offset + bytes_size);
2672             process->current_state->indexPointer =
2673                 g_realloc(process->current_state->indexPointer,
2674                         process->current_state->indexPointerSize);
2675             memcpy(process->current_state->indexPointer + offset,
2676                    (void *) args[4], bytes_size);
2677             // DEBUGF( "glIndexPointer_fake_func type=%d, stride=%d,
2678             // byte_size=%d\n", type, stride, bytes_size);
2679             glIndexPointer(type, stride,
2680                            process->current_state->indexPointer);
2681             break;
2682         }
2683
2684     case glEdgeFlagPointer_fake_func:
2685         {
2686             int offset = args[0];
2687             int stride = args[1];
2688             int bytes_size = args[2];
2689
2690             process->current_state->edgeFlagPointerSize =
2691                 MAX(process->current_state->edgeFlagPointerSize,
2692                     offset + bytes_size);
2693             process->current_state->edgeFlagPointer =
2694                 g_realloc(process->current_state->edgeFlagPointer,
2695                         process->current_state->edgeFlagPointerSize);
2696             memcpy(process->current_state->edgeFlagPointer + offset,
2697                    (void *) args[3], bytes_size);
2698             // DEBUGF( "glEdgeFlagPointer_fake_func stride = %d,
2699             // bytes_size=%d\n", stride, bytes_size);
2700             glEdgeFlagPointer(stride,
2701                               process->current_state->edgeFlagPointer);
2702             break;
2703         }
2704
2705     case glVertexAttribPointerARB_fake_func:
2706         {
2707             GET_EXT_PTR(void, glVertexAttribPointerARB,
2708                         (int, int, int, int, int, void *));
2709             int offset = args[0];
2710             int index = args[1];
2711             int size = args[2];
2712             int type = args[3];
2713             int normalized = args[4];
2714             int stride = args[5];
2715             int bytes_size = args[6];
2716
2717             process->current_state->vertexAttribPointerSize[index] =
2718                 MAX(process->current_state->vertexAttribPointerSize[index],
2719                     offset + bytes_size);
2720             process->current_state->vertexAttribPointer[index] =
2721                 g_realloc(process->current_state->vertexAttribPointer[index],
2722                         process->current_state->
2723                         vertexAttribPointerSize[index]);
2724             memcpy(process->current_state->vertexAttribPointer[index] +
2725                    offset, (void *) args[7], bytes_size);
2726             ptr_func_glVertexAttribPointerARB(index, size, type, normalized,
2727                                               stride,
2728                                               process->current_state->
2729                                               vertexAttribPointer[index]);
2730             break;
2731         }
2732
2733     case glVertexAttribPointerNV_fake_func:
2734         {
2735             GET_EXT_PTR(void, glVertexAttribPointerNV,
2736                         (int, int, int, int, void *));
2737             int offset = args[0];
2738             int index = args[1];
2739             int size = args[2];
2740             int type = args[3];
2741             int stride = args[4];
2742             int bytes_size = args[5];
2743
2744             process->current_state->vertexAttribPointerNVSize[index] =
2745                 MAX(process->current_state->vertexAttribPointerNVSize[index],
2746                     offset + bytes_size);
2747             process->current_state->vertexAttribPointerNV[index] =
2748                 g_realloc(process->current_state->vertexAttribPointerNV[index],
2749                         process->current_state->
2750                         vertexAttribPointerNVSize[index]);
2751             memcpy(process->current_state->vertexAttribPointerNV[index] +
2752                    offset, (void *) args[6], bytes_size);
2753             ptr_func_glVertexAttribPointerNV(index, size, type, stride,
2754                                              process->current_state->
2755                                              vertexAttribPointerNV[index]);
2756             break;
2757         }
2758
2759     case glColorPointer_fake_func:
2760         {
2761             int offset = args[0];
2762             int size = args[1];
2763             int type = args[2];
2764             int stride = args[3];
2765             int bytes_size = args[4];
2766
2767             process->current_state->colorPointerSize =
2768                 MAX(process->current_state->colorPointerSize,
2769                     offset + bytes_size);
2770             process->current_state->colorPointer =
2771                 g_realloc(process->current_state->colorPointer,
2772                         process->current_state->colorPointerSize);
2773             memcpy(process->current_state->colorPointer + offset,
2774                    (void *) args[5], bytes_size);
2775             // DEBUGF( "glColorPointer_fake_func bytes_size = %d\n",
2776             // bytes_size);
2777             glColorPointer(size, type, stride,
2778                            process->current_state->colorPointer);
2779
2780             break;
2781         }
2782
2783     case glSecondaryColorPointer_fake_func:
2784         {
2785             GET_EXT_PTR(void, glSecondaryColorPointer,
2786                         (int, int, int, void *));
2787             int offset = args[0];
2788             int size = args[1];
2789             int type = args[2];
2790             int stride = args[3];
2791             int bytes_size = args[4];
2792
2793             process->current_state->secondaryColorPointerSize =
2794                 MAX(process->current_state->secondaryColorPointerSize,
2795                     offset + bytes_size);
2796             process->current_state->secondaryColorPointer =
2797                 g_realloc(process->current_state->secondaryColorPointer,
2798                         process->current_state->secondaryColorPointerSize);
2799             memcpy(process->current_state->secondaryColorPointer + offset,
2800                    (void *) args[5], bytes_size);
2801             // DEBUGF( "glSecondaryColorPointer_fake_func bytes_size
2802             // = %d\n", bytes_size);
2803             ptr_func_glSecondaryColorPointer(size, type, stride,
2804                                              process->current_state->
2805                                              secondaryColorPointer);
2806
2807             break;
2808         }
2809
2810     case glPushClientAttrib_func:
2811         {
2812             int mask = args[0];
2813
2814             if (process->current_state->clientStateSp <
2815                 MAX_CLIENT_STATE_STACK_SIZE) {
2816                 process->current_state->clientStateStack[process->
2817                                                          current_state->
2818                                                          clientStateSp].mask =
2819                     mask;
2820                 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
2821                     process->current_state->clientStateStack[process->
2822                                                              current_state->
2823                                                              clientStateSp].
2824                         activeTextureIndex =
2825                         process->current_state->activeTextureIndex;
2826                 }
2827                 process->current_state->clientStateSp++;
2828             }
2829             glPushClientAttrib(mask);
2830             break;
2831         }
2832
2833     case glPopClientAttrib_func:
2834         {
2835             if (process->current_state->clientStateSp > 0) {
2836                 process->current_state->clientStateSp--;
2837                 if (process->current_state->
2838                     clientStateStack[process->current_state->clientStateSp].
2839                     mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
2840                     process->current_state->activeTextureIndex =
2841                         process->current_state->clientStateStack[process->
2842                                                                  current_state->
2843                                                                  clientStateSp].
2844                         activeTextureIndex;
2845                 }
2846             }
2847             glPopClientAttrib();
2848             break;
2849         }
2850
2851     case glClientActiveTexture_func:
2852     case glClientActiveTextureARB_func:
2853         {
2854             int activeTexture = args[0];
2855
2856             process->current_state->activeTextureIndex =
2857                 activeTexture - GL_TEXTURE0_ARB;
2858             do_glClientActiveTextureARB(activeTexture);
2859             break;
2860         }
2861
2862     case glTexCoordPointer_fake_func:
2863         {
2864             int offset = args[0];
2865             int index = args[1];
2866             int size = args[2];
2867             int type = args[3];
2868             int stride = args[4];
2869             int bytes_size = args[5];
2870
2871             process->current_state->texCoordPointerSize[index] =
2872                 MAX(process->current_state->texCoordPointerSize[index],
2873                     offset + bytes_size);
2874             process->current_state->texCoordPointer[index] =
2875                 g_realloc(process->current_state->texCoordPointer[index],
2876                         process->current_state->texCoordPointerSize[index]);
2877             memcpy(process->current_state->texCoordPointer[index] + offset,
2878                    (void *) args[6], bytes_size);
2879             /* DEBUGF( "glTexCoordPointer_fake_func size=%d, type=%d, 
2880              * stride=%d, byte_size=%d\n", size, type, stride, bytes_size); */
2881             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + index);
2882             glTexCoordPointer(size, type, stride,
2883                               process->current_state->texCoordPointer[index]);
2884             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
2885                                         process->current_state->
2886                                         activeTextureIndex);
2887             break;
2888         }
2889
2890     case glWeightPointerARB_fake_func:
2891         {
2892             GET_EXT_PTR(void, glWeightPointerARB, (int, int, int, void *));
2893             int offset = args[0];
2894             int size = args[1];
2895             int type = args[2];
2896             int stride = args[3];
2897             int bytes_size = args[4];
2898
2899             process->current_state->weightPointerSize =
2900                 MAX(process->current_state->weightPointerSize,
2901                     offset + bytes_size);
2902             process->current_state->weightPointer =
2903                 g_realloc(process->current_state->weightPointer,
2904                         process->current_state->weightPointerSize);
2905             memcpy(process->current_state->weightPointer + offset,
2906                    (void *) args[5], bytes_size);
2907             /* DEBUGF( "glWeightPointerARB_fake_func size=%d,
2908              * type=%d, stride=%d, byte_size=%d\n", size, type, stride,
2909              * bytes_size); */
2910             ptr_func_glWeightPointerARB(size, type, stride,
2911                                         process->current_state->
2912                                         weightPointer);
2913             break;
2914         }
2915
2916     case glMatrixIndexPointerARB_fake_func:
2917         {
2918             GET_EXT_PTR(void, glMatrixIndexPointerARB,
2919                         (int, int, int, void *));
2920             int offset = args[0];
2921             int size = args[1];
2922             int type = args[2];
2923             int stride = args[3];
2924             int bytes_size = args[4];
2925
2926             process->current_state->matrixIndexPointerSize =
2927                 MAX(process->current_state->matrixIndexPointerSize,
2928                     offset + bytes_size);
2929             process->current_state->matrixIndexPointer =
2930                 g_realloc(process->current_state->matrixIndexPointer,
2931                         process->current_state->matrixIndexPointerSize);
2932             memcpy(process->current_state->matrixIndexPointer + offset,
2933                    (void *) args[5], bytes_size);
2934             /* DEBUGF( "glMatrixIndexPointerARB_fake_func size=%d,
2935              * type=%d, stride=%d, byte_size=%d\n", size, type, stride,
2936              * bytes_size); */
2937             ptr_func_glMatrixIndexPointerARB(size, type, stride,
2938                                              process->current_state->
2939                                              matrixIndexPointer);
2940             break;
2941         }
2942
2943     case glFogCoordPointer_fake_func:
2944         {
2945             GET_EXT_PTR(void, glFogCoordPointer, (int, int, void *));
2946             int offset = args[0];
2947             int type = args[1];
2948             int stride = args[2];
2949             int bytes_size = args[3];
2950
2951             process->current_state->fogCoordPointerSize =
2952                 MAX(process->current_state->fogCoordPointerSize,
2953                     offset + bytes_size);
2954             process->current_state->fogCoordPointer =
2955                 g_realloc(process->current_state->fogCoordPointer,
2956                         process->current_state->fogCoordPointerSize);
2957             memcpy(process->current_state->fogCoordPointer + offset,
2958                    (void *) args[4], bytes_size);
2959             // DEBUGF( "glFogCoordPointer_fake_func type=%d,
2960             // stride=%d, byte_size=%d\n", type, stride, bytes_size);
2961             ptr_func_glFogCoordPointer(type, stride,
2962                                        process->current_state->
2963                                        fogCoordPointer);
2964             break;
2965         }
2966
2967     case glVariantPointerEXT_fake_func:
2968         {
2969             GET_EXT_PTR(void, glVariantPointerEXT, (int, int, int, void *));
2970             int offset = args[0];
2971             int id = args[1];
2972             int type = args[2];
2973             int stride = args[3];
2974             int bytes_size = args[4];
2975
2976             process->current_state->variantPointerEXTSize[id] =
2977                 MAX(process->current_state->variantPointerEXTSize[id],
2978                     offset + bytes_size);
2979             process->current_state->variantPointerEXT[id] =
2980                 g_realloc(process->current_state->variantPointerEXT[id],
2981                         process->current_state->variantPointerEXTSize[id]);
2982             memcpy(process->current_state->variantPointerEXT[id] + offset,
2983                    (void *) args[5], bytes_size);
2984             // DEBUGF( "glVariantPointerEXT_fake_func[%d] type=%d,
2985             // stride=%d, byte_size=%d\n", id, type, stride, bytes_size);
2986             ptr_func_glVariantPointerEXT(id, type, stride,
2987                                          process->current_state->
2988                                          variantPointerEXT[id]);
2989             break;
2990         }
2991
2992     case glInterleavedArrays_fake_func:
2993         {
2994             GET_EXT_PTR(void, glInterleavedArrays, (int, int, void *));
2995             int offset = args[0];
2996             int format = args[1];
2997             int stride = args[2];
2998             int bytes_size = args[3];
2999
3000             process->current_state->interleavedArraysSize =
3001                 MAX(process->current_state->interleavedArraysSize,
3002                     offset + bytes_size);
3003             process->current_state->interleavedArrays =
3004                 g_realloc(process->current_state->interleavedArrays,
3005                         process->current_state->interleavedArraysSize);
3006             memcpy(process->current_state->interleavedArrays + offset,
3007                    (void *) args[4], bytes_size);
3008             // DEBUGF( "glInterleavedArrays_fake_func format=%d,
3009             // stride=%d, byte_size=%d\n", format, stride, bytes_size);
3010             ptr_func_glInterleavedArrays(format, stride,
3011                                          process->current_state->
3012                                          interleavedArrays);
3013             break;
3014         }
3015
3016     case glElementPointerATI_fake_func:
3017         {
3018             GET_EXT_PTR(void, glElementPointerATI, (int, void *));
3019             int type = args[0];
3020             int bytes_size = args[1];
3021
3022             process->current_state->elementPointerATISize = bytes_size;
3023             process->current_state->elementPointerATI =
3024                 g_realloc(process->current_state->elementPointerATI,
3025                         process->current_state->elementPointerATISize);
3026             memcpy(process->current_state->elementPointerATI,
3027                    (void *) args[2], bytes_size);
3028             // DEBUGF( "glElementPointerATI_fake_func type=%d,
3029             // byte_size=%d\n", type, bytes_size);
3030             ptr_func_glElementPointerATI(type,
3031                                          process->current_state->
3032                                          elementPointerATI);
3033             break;
3034         }
3035
3036     case glTexCoordPointer01_fake_func:
3037         {
3038             int size = args[0];
3039             int type = args[1];
3040             int stride = args[2];
3041             int bytes_size = args[3];
3042
3043             process->current_state->texCoordPointerSize[0] = bytes_size;
3044             process->current_state->texCoordPointer[0] =
3045                 g_realloc(process->current_state->texCoordPointer[0],
3046                         bytes_size);
3047             memcpy(process->current_state->texCoordPointer[0],
3048                    (void *) args[4], bytes_size);
3049             /* DEBUGF( "glTexCoordPointer01_fake_func size=%d,
3050              * type=%d, stride=%d, byte_size=%d\n", size, type, stride,
3051              * bytes_size); */
3052             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0);
3053             glTexCoordPointer(size, type, stride,
3054                               process->current_state->texCoordPointer[0]);
3055             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1);
3056             glTexCoordPointer(size, type, stride,
3057                               process->current_state->texCoordPointer[0]);
3058             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
3059                                         process->current_state->
3060                                         activeTextureIndex);
3061             break;
3062         }
3063
3064     case glTexCoordPointer012_fake_func:
3065         {
3066             int size = args[0];
3067             int type = args[1];
3068             int stride = args[2];
3069             int bytes_size = args[3];
3070
3071             process->current_state->texCoordPointerSize[0] = bytes_size;
3072             process->current_state->texCoordPointer[0] =
3073                 g_realloc(process->current_state->texCoordPointer[0],
3074                         bytes_size);
3075             memcpy(process->current_state->texCoordPointer[0],
3076                    (void *) args[4], bytes_size);
3077             /* DEBUGF( "glTexCoordPointer012_fake_func size=%d,
3078              * type=%d, stride=%d, byte_size=%d\n", size, type, stride,
3079              * bytes_size); */
3080             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0);
3081             glTexCoordPointer(size, type, stride,
3082                               process->current_state->texCoordPointer[0]);
3083             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1);
3084             glTexCoordPointer(size, type, stride,
3085                               process->current_state->texCoordPointer[0]);
3086             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 2);
3087             glTexCoordPointer(size, type, stride,
3088                               process->current_state->texCoordPointer[0]);
3089             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
3090                                         process->current_state->
3091                                         activeTextureIndex);
3092             break;
3093         }
3094
3095     case glVertexAndNormalPointer_fake_func:
3096         {
3097             int vertexPointerSize = args[0];
3098             int vertexPointerType = args[1];
3099             int vertexPointerStride = args[2];
3100             int normalPointerType = args[3];
3101             int normalPointerStride = args[4];
3102             int bytes_size = args[5];
3103             void *ptr = (void *) args[6];
3104
3105             process->current_state->vertexPointerSize = bytes_size;
3106             process->current_state->vertexPointer =
3107                 g_realloc(process->current_state->vertexPointer, bytes_size);
3108             memcpy(process->current_state->vertexPointer, ptr, bytes_size);
3109             glVertexPointer(vertexPointerSize, vertexPointerType,
3110                             vertexPointerStride,
3111                             process->current_state->vertexPointer);
3112             glNormalPointer(normalPointerType, normalPointerStride,
3113                             process->current_state->vertexPointer);
3114             break;
3115         }
3116
3117     case glVertexNormalPointerInterlaced_fake_func:
3118         {
3119             int i = 0;
3120             int offset = args[i++];
3121             int vertexPointerSize = args[i++];
3122             int vertexPointerType = args[i++];
3123             int stride = args[i++];
3124             int normalPointerOffset = args[i++];
3125             int normalPointerType = args[i++];
3126             int bytes_size = args[i++];
3127             void *ptr = (void *) args[i++];
3128
3129             process->current_state->vertexPointerSize =
3130                 MAX(process->current_state->vertexPointerSize,
3131                     offset + bytes_size);
3132             process->current_state->vertexPointer =
3133                 g_realloc(process->current_state->vertexPointer,
3134                         process->current_state->vertexPointerSize);
3135             memcpy(process->current_state->vertexPointer + offset, ptr,
3136                    bytes_size);
3137             glVertexPointer(vertexPointerSize, vertexPointerType, stride,
3138                             process->current_state->vertexPointer);
3139             glNormalPointer(normalPointerType, stride,
3140                             process->current_state->vertexPointer +
3141                             normalPointerOffset);
3142             break;
3143         }
3144
3145     case glTuxRacerDrawElements_fake_func:
3146         {
3147             int mode = args[0];
3148             int count = args[1];
3149             int isColorEnabled = args[2];
3150             void *ptr = (void *) args[3];
3151             int stride =
3152                 6 * sizeof(float) +
3153                 ((isColorEnabled) ? 4 * sizeof(unsigned char) : 0);
3154             glVertexPointer(3, GL_FLOAT, stride, ptr);
3155             glNormalPointer(GL_FLOAT, stride, ptr + 3 * sizeof(float));
3156             if (isColorEnabled)
3157                 glColorPointer(4, GL_UNSIGNED_BYTE, stride,
3158                                ptr + 6 * sizeof(float));
3159             glDrawArrays(mode, 0, count);
3160
3161 #ifdef __APPLE__  //only for mac
3162                         {
3163                                 int prev_fbo;
3164                                 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prev_fbo);
3165                                 if ( prev_fbo != 0 )
3166                                         glFlush();
3167                         }
3168 #endif
3169
3170             break;
3171         }
3172
3173     case glVertexNormalColorPointerInterlaced_fake_func:
3174         {
3175             int i = 0;
3176             int offset = args[i++];
3177             int vertexPointerSize = args[i++];
3178             int vertexPointerType = args[i++];
3179             int stride = args[i++];
3180             int normalPointerOffset = args[i++];
3181             int normalPointerType = args[i++];
3182             int colorPointerOffset = args[i++];
3183             int colorPointerSize = args[i++];
3184             int colorPointerType = args[i++];
3185             int bytes_size = args[i++];
3186             void *ptr = (void *) args[i++];
3187
3188             process->current_state->vertexPointerSize =
3189                 MAX(process->current_state->vertexPointerSize,
3190                     offset + bytes_size);
3191             process->current_state->vertexPointer =
3192                 g_realloc(process->current_state->vertexPointer,
3193                         process->current_state->vertexPointerSize);
3194             memcpy(process->current_state->vertexPointer + offset, ptr,
3195                    bytes_size);
3196             glVertexPointer(vertexPointerSize, vertexPointerType, stride,
3197                             process->current_state->vertexPointer);
3198             glNormalPointer(normalPointerType, stride,
3199                             process->current_state->vertexPointer +
3200                             normalPointerOffset);
3201             glColorPointer(colorPointerSize, colorPointerType, stride,
3202                            process->current_state->vertexPointer +
3203                            colorPointerOffset);
3204             break;
3205         }
3206
3207     case glVertexColorTexCoord0PointerInterlaced_fake_func:
3208         {
3209             int i = 0;
3210             int offset = args[i++];
3211             int vertexPointerSize = args[i++];
3212             int vertexPointerType = args[i++];
3213             int stride = args[i++];
3214             int colorPointerOffset = args[i++];
3215             int colorPointerSize = args[i++];
3216             int colorPointerType = args[i++];
3217             int texCoord0PointerOffset = args[i++];
3218             int texCoord0PointerSize = args[i++];
3219             int texCoord0PointerType = args[i++];
3220             int bytes_size = args[i++];
3221             void *ptr = (void *) args[i++];
3222
3223             process->current_state->vertexPointerSize =
3224                 MAX(process->current_state->vertexPointerSize,
3225                     offset + bytes_size);
3226             process->current_state->vertexPointer =
3227                 g_realloc(process->current_state->vertexPointer,
3228                         process->current_state->vertexPointerSize);
3229             memcpy(process->current_state->vertexPointer + offset, ptr,
3230                    bytes_size);
3231             glVertexPointer(vertexPointerSize, vertexPointerType, stride,
3232                             process->current_state->vertexPointer);
3233             glColorPointer(colorPointerSize, colorPointerType, stride,
3234                            process->current_state->vertexPointer +
3235                            colorPointerOffset);
3236             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0);
3237             glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType,
3238                               stride,
3239                               process->current_state->vertexPointer +
3240                               texCoord0PointerOffset);
3241             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
3242                                         process->current_state->
3243                                         activeTextureIndex);
3244             break;
3245         }
3246
3247     case glVertexNormalTexCoord0PointerInterlaced_fake_func:
3248         {
3249             int i = 0;
3250             int offset = args[i++];
3251             int vertexPointerSize = args[i++];
3252             int vertexPointerType = args[i++];
3253             int stride = args[i++];
3254             int normalPointerOffset = args[i++];
3255             int normalPointerType = args[i++];
3256             int texCoord0PointerOffset = args[i++];
3257             int texCoord0PointerSize = args[i++];
3258             int texCoord0PointerType = args[i++];
3259             int bytes_size = args[i++];
3260             void *ptr = (void *) args[i++];
3261
3262             process->current_state->vertexPointerSize =
3263                 MAX(process->current_state->vertexPointerSize,
3264                     offset + bytes_size);
3265             process->current_state->vertexPointer =
3266                 g_realloc(process->current_state->vertexPointer,
3267                         process->current_state->vertexPointerSize);
3268             memcpy(process->current_state->vertexPointer + offset, ptr,
3269                    bytes_size);
3270             glVertexPointer(vertexPointerSize, vertexPointerType, stride,
3271                             process->current_state->vertexPointer);
3272             glNormalPointer(normalPointerType, stride,
3273                             process->current_state->vertexPointer +
3274                             normalPointerOffset);
3275             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0);
3276             glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType,
3277                               stride,
3278                               process->current_state->vertexPointer +
3279                               texCoord0PointerOffset);
3280             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
3281                                         process->current_state->
3282                                         activeTextureIndex);
3283             break;
3284         }
3285
3286     case glVertexNormalTexCoord01PointerInterlaced_fake_func:
3287         {
3288             int i = 0;
3289             int offset = args[i++];
3290             int vertexPointerSize = args[i++];
3291             int vertexPointerType = args[i++];
3292             int stride = args[i++];
3293             int normalPointerOffset = args[i++];
3294             int normalPointerType = args[i++];
3295             int texCoord0PointerOffset = args[i++];
3296             int texCoord0PointerSize = args[i++];
3297             int texCoord0PointerType = args[i++];
3298             int texCoord1PointerOffset = args[i++];
3299             int texCoord1PointerSize = args[i++];
3300             int texCoord1PointerType = args[i++];
3301             int bytes_size = args[i++];
3302             void *ptr = (void *) args[i++];
3303
3304             process->current_state->vertexPointerSize =
3305                 MAX(process->current_state->vertexPointerSize,
3306                     offset + bytes_size);
3307             process->current_state->vertexPointer =
3308                 g_realloc(process->current_state->vertexPointer,
3309                         process->current_state->vertexPointerSize);
3310             memcpy(process->current_state->vertexPointer + offset, ptr,
3311                    bytes_size);
3312             glVertexPointer(vertexPointerSize, vertexPointerType, stride,
3313                             process->current_state->vertexPointer);
3314             glNormalPointer(normalPointerType, stride,
3315                             process->current_state->vertexPointer +
3316                             normalPointerOffset);
3317             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0);
3318             glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType,
3319                               stride,
3320                               process->current_state->vertexPointer +
3321                               texCoord0PointerOffset);
3322             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1);
3323             glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType,
3324                               stride,
3325                               process->current_state->vertexPointer +
3326                               texCoord1PointerOffset);
3327             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
3328                                         process->current_state->
3329                                         activeTextureIndex);
3330             break;
3331         }
3332
3333     case glVertexNormalTexCoord012PointerInterlaced_fake_func:
3334         {
3335             int i = 0;
3336             int offset = args[i++];
3337             int vertexPointerSize = args[i++];
3338             int vertexPointerType = args[i++];
3339             int stride = args[i++];
3340             int normalPointerOffset = args[i++];
3341             int normalPointerType = args[i++];
3342             int texCoord0PointerOffset = args[i++];
3343             int texCoord0PointerSize = args[i++];
3344             int texCoord0PointerType = args[i++];
3345             int texCoord1PointerOffset = args[i++];
3346             int texCoord1PointerSize = args[i++];
3347             int texCoord1PointerType = args[i++];
3348             int texCoord2PointerOffset = args[i++];
3349             int texCoord2PointerSize = args[i++];
3350             int texCoord2PointerType = args[i++];
3351             int bytes_size = args[i++];
3352             void *ptr = (void *) args[i++];
3353
3354             process->current_state->vertexPointerSize =
3355                 MAX(process->current_state->vertexPointerSize,
3356                     offset + bytes_size);
3357             process->current_state->vertexPointer =
3358                 g_realloc(process->current_state->vertexPointer,
3359                         process->current_state->vertexPointerSize);
3360             memcpy(process->current_state->vertexPointer + offset, ptr,
3361                    bytes_size);
3362             glVertexPointer(vertexPointerSize, vertexPointerType, stride,
3363                             process->current_state->vertexPointer);
3364             glNormalPointer(normalPointerType, stride,
3365                             process->current_state->vertexPointer +
3366                             normalPointerOffset);
3367             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0);
3368             glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType,
3369                               stride,
3370                               process->current_state->vertexPointer +
3371                               texCoord0PointerOffset);
3372             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1);
3373             glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType,
3374                               stride,
3375                               process->current_state->vertexPointer +
3376                               texCoord1PointerOffset);
3377             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 2);
3378             glTexCoordPointer(texCoord2PointerSize, texCoord2PointerType,
3379                               stride,
3380                               process->current_state->vertexPointer +
3381                               texCoord2PointerOffset);
3382             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
3383                                         process->current_state->
3384                                         activeTextureIndex);
3385             break;
3386         }
3387
3388     case glVertexNormalColorTexCoord0PointerInterlaced_fake_func:
3389         {
3390             int i = 0;
3391             int offset = args[i++];
3392             int vertexPointerSize = args[i++];
3393             int vertexPointerType = args[i++];
3394             int stride = args[i++];
3395             int normalPointerOffset = args[i++];
3396             int normalPointerType = args[i++];
3397             int colorPointerOffset = args[i++];
3398             int colorPointerSize = args[i++];
3399             int colorPointerType = args[i++];
3400             int texCoord0PointerOffset = args[i++];
3401             int texCoord0PointerSize = args[i++];
3402             int texCoord0PointerType = args[i++];
3403             int bytes_size = args[i++];
3404             void *ptr = (void *) args[i++];
3405
3406             process->current_state->vertexPointerSize =
3407                 MAX(process->current_state->vertexPointerSize,
3408                     offset + bytes_size);
3409             process->current_state->vertexPointer =
3410                 g_realloc(process->current_state->vertexPointer,
3411                         process->current_state->vertexPointerSize);
3412             memcpy(process->current_state->vertexPointer + offset, ptr,
3413                    bytes_size);
3414             glVertexPointer(vertexPointerSize, vertexPointerType, stride,
3415                             process->current_state->vertexPointer);
3416             glNormalPointer(normalPointerType, stride,
3417                             process->current_state->vertexPointer +
3418                             normalPointerOffset);
3419             glColorPointer(colorPointerSize, colorPointerType, stride,
3420                            process->current_state->vertexPointer +
3421                            colorPointerOffset);
3422             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0);
3423             glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType,
3424                               stride,
3425                               process->current_state->vertexPointer +
3426                               texCoord0PointerOffset);
3427             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
3428                                         process->current_state->
3429                                         activeTextureIndex);
3430             break;
3431         }
3432
3433     case glVertexNormalColorTexCoord01PointerInterlaced_fake_func:
3434         {
3435             int i = 0;
3436             int offset = args[i++];
3437             int vertexPointerSize = args[i++];
3438             int vertexPointerType = args[i++];
3439             int stride = args[i++];
3440             int normalPointerOffset = args[i++];
3441             int normalPointerType = args[i++];
3442             int colorPointerOffset = args[i++];
3443             int colorPointerSize = args[i++];
3444             int colorPointerType = args[i++];
3445             int texCoord0PointerOffset = args[i++];
3446             int texCoord0PointerSize = args[i++];
3447             int texCoord0PointerType = args[i++];
3448             int texCoord1PointerOffset = args[i++];
3449             int texCoord1PointerSize = args[i++];
3450             int texCoord1PointerType = args[i++];
3451             int bytes_size = args[i++];
3452             void *ptr = (void *) args[i++];
3453
3454             process->current_state->vertexPointerSize =
3455                 MAX(process->current_state->vertexPointerSize,
3456                     offset + bytes_size);
3457             process->current_state->vertexPointer =
3458                 g_realloc(process->current_state->vertexPointer,
3459                         process->current_state->vertexPointerSize);
3460             memcpy(process->current_state->vertexPointer + offset, ptr,
3461                    bytes_size);
3462             glVertexPointer(vertexPointerSize, vertexPointerType, stride,
3463                             process->current_state->vertexPointer);
3464             glNormalPointer(normalPointerType, stride,
3465                             process->current_state->vertexPointer +
3466                             normalPointerOffset);
3467             glColorPointer(colorPointerSize, colorPointerType, stride,
3468                            process->current_state->vertexPointer +
3469                            colorPointerOffset);
3470             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0);
3471             glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType,
3472                               stride,
3473                               process->current_state->vertexPointer +
3474                               texCoord0PointerOffset);
3475             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1);
3476             glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType,
3477                               stride,
3478                               process->current_state->vertexPointer +
3479                               texCoord1PointerOffset);
3480             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
3481                                         process->current_state->
3482                                         activeTextureIndex);
3483             break;
3484         }
3485
3486     case glVertexNormalColorTexCoord012PointerInterlaced_fake_func:
3487         {
3488             int i = 0;
3489             int offset = args[i++];
3490             int vertexPointerSize = args[i++];
3491             int vertexPointerType = args[i++];
3492             int stride = args[i++];
3493             int normalPointerOffset = args[i++];
3494             int normalPointerType = args[i++];
3495             int colorPointerOffset = args[i++];
3496             int colorPointerSize = args[i++];
3497             int colorPointerType = args[i++];
3498             int texCoord0PointerOffset = args[i++];
3499             int texCoord0PointerSize = args[i++];
3500             int texCoord0PointerType = args[i++];
3501             int texCoord1PointerOffset = args[i++];
3502             int texCoord1PointerSize = args[i++];
3503             int texCoord1PointerType = args[i++];
3504             int texCoord2PointerOffset = args[i++];
3505             int texCoord2PointerSize = args[i++];
3506             int texCoord2PointerType = args[i++];
3507             int bytes_size = args[i++];
3508             void *ptr = (void *) args[i++];
3509
3510             process->current_state->vertexPointerSize =
3511                 MAX(process->current_state->vertexPointerSize,
3512                     offset + bytes_size);
3513             process->current_state->vertexPointer =
3514                 g_realloc(process->current_state->vertexPointer,
3515                         process->current_state->vertexPointerSize);
3516             memcpy(process->current_state->vertexPointer + offset, ptr,
3517                    bytes_size);
3518             glVertexPointer(vertexPointerSize, vertexPointerType, stride,
3519                             process->current_state->vertexPointer);
3520             glNormalPointer(normalPointerType, stride,
3521                             process->current_state->vertexPointer +
3522                             normalPointerOffset);
3523             glColorPointer(colorPointerSize, colorPointerType, stride,
3524                            process->current_state->vertexPointer +
3525                            colorPointerOffset);
3526             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0);
3527             glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType,
3528                               stride,
3529                               process->current_state->vertexPointer +
3530                               texCoord0PointerOffset);
3531             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1);
3532             glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType,
3533                               stride,
3534                               process->current_state->vertexPointer +
3535                               texCoord1PointerOffset);
3536             do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 2);
3537             glTexCoordPointer(texCoord2PointerSize, texCoord2PointerType,
3538                               stride,
3539                               process->current_state->vertexPointer +
3540                               texCoord2PointerOffset);
3541             do_glClientActiveTextureARB(GL_TEXTURE0_ARB +
3542                                         process->current_state->
3543                                         activeTextureIndex);
3544             break;
3545         }
3546
3547     case _glVertexPointer_buffer_func:
3548         {
3549             glVertexPointer(args[0], args[1], args[2], (void *) args[3]);
3550             break;
3551         }
3552
3553     case _glNormalPointer_buffer_func:
3554         {
3555             glNormalPointer(args[0], args[1], (void *) args[2]);
3556             break;
3557         }
3558
3559     case _glColorPointer_buffer_func:
3560         {
3561             glColorPointer(args[0], args[1], args[2], (void *) args[3]);
3562             break;
3563         }
3564
3565     case _glSecondaryColorPointer_buffer_func:
3566         {
3567             GET_EXT_PTR(void, glSecondaryColorPointer,
3568                         (int, int, int, void *));
3569             ptr_func_glSecondaryColorPointer(args[0], args[1], args[2],
3570                                              (void *) args[3]);
3571             break;
3572         }
3573
3574     case _glIndexPointer_buffer_func:
3575         {
3576             glIndexPointer(args[0], args[1], (void *) args[2]);
3577             break;
3578         }
3579
3580     case _glTexCoordPointer_buffer_func:
3581         {
3582             glTexCoordPointer(args[0], args[1], args[2], (void *) args[3]);
3583             break;
3584         }
3585
3586     case _glEdgeFlagPointer_buffer_func:
3587         {
3588             glEdgeFlagPointer(args[0], (void *) args[1]);
3589             break;
3590         }
3591
3592     case _glVertexAttribPointerARB_buffer_func:
3593         {
3594             GET_EXT_PTR(void, glVertexAttribPointerARB,
3595                         (int, int, int, int, int, void *));
3596             ptr_func_glVertexAttribPointerARB(args[0], args[1], args[2],
3597                                               args[3], args[4],
3598                                               (void *) args[5]);
3599             break;
3600         }
3601
3602     case _glWeightPointerARB_buffer_func:
3603         {
3604             GET_EXT_PTR(void, glWeightPointerARB, (int, int, int, void *));
3605
3606             ptr_func_glWeightPointerARB(args[0], args[1], args[2],
3607                                         (void *) args[3]);
3608             break;
3609         }
3610
3611     case _glMatrixIndexPointerARB_buffer_func:
3612         {
3613             GET_EXT_PTR(void, glMatrixIndexPointerARB,
3614                         (int, int, int, void *));
3615             ptr_func_glMatrixIndexPointerARB(args[0], args[1], args[2],
3616                                              (void *) args[3]);
3617             break;
3618         }
3619
3620     case _glFogCoordPointer_buffer_func:
3621         {
3622             GET_EXT_PTR(void, glFogCoordPointer, (int, int, void *));
3623
3624             ptr_func_glFogCoordPointer(args[0], args[1], (void *) args[2]);
3625             break;
3626         }
3627
3628     case _glVariantPointerEXT_buffer_func:
3629         {
3630             GET_EXT_PTR(void, glVariantPointerEXT, (int, int, int, void *));
3631
3632             ptr_func_glVariantPointerEXT(args[0], args[1], args[2],
3633                                          (void *) args[3]);
3634             break;
3635         }
3636
3637     case _glDrawElements_buffer_func:
3638         {
3639             glDrawElements(args[0], args[1], args[2], (void *) args[3]);
3640
3641 #ifdef __APPLE__  //only for mac
3642                         {
3643                                 int prev_fbo;
3644                                 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prev_fbo);
3645                                 if ( prev_fbo != 0 )
3646                                         glFlush();
3647                         }
3648 #endif
3649
3650             break;
3651         }
3652 #ifndef _WIN32
3653     case _glDrawRangeElements_buffer_func:
3654         {
3655             glDrawRangeElements(args[0], args[1], args[2], args[3], args[4],
3656                                 (void *) args[5]);
3657             break;
3658         }
3659 #endif
3660     case _glMultiDrawElements_buffer_func:
3661         {
3662             GET_EXT_PTR(void, glMultiDrawElements,
3663                         (int, int *, int, void **, int));
3664             ptr_func_glMultiDrawElements(args[0], (int *) args[1], args[2],
3665                                        (void **) args[3], args[4]);
3666 #ifdef __APPLE__  //only for mac
3667                         {
3668                                 int prev_fbo;
3669                                 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prev_fbo);
3670                                 if ( prev_fbo != 0 )
3671                                         glFlush();
3672                         }
3673 #endif
3674
3675                         break;
3676                 }
3677 #ifdef __APPLE__  // only for mac
3678         case glDrawArrays_func:
3679                 {
3680                         int prev_fbo;
3681                         glDrawArrays(ARG_TO_UNSIGNED_INT(args[0]), ARG_TO_INT(args[1]), ARG_TO_INT(args[2]));
3682                         glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prev_fbo);
3683                         if ( prev_fbo != 0 )
3684                                 glFlush();
3685                         break;
3686                 }
3687         case glDrawElements_func:
3688                 {
3689                         int prev_fbo;
3690                         glDrawElements(ARG_TO_UNSIGNED_INT(args[0]), ARG_TO_INT(args[1]), ARG_TO_UNSIGNED_INT(args[2]), (const void*)(args[3]));
3691                         glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prev_fbo);
3692                         if ( prev_fbo != 0 )
3693                                 glFlush();
3694                         break;
3695                 }
3696 #endif
3697
3698     case _glGetError_fake_func:
3699         {
3700             break;
3701         }
3702
3703     case glGetIntegerv_func:
3704         {
3705             glGetIntegerv(args[0], (int *) args[1]);
3706             break;
3707         }
3708
3709     case _glReadPixels_pbo_func:
3710         {
3711             glReadPixels(ARG_TO_INT(args[0]), ARG_TO_INT(args[1]),
3712                          ARG_TO_INT(args[2]), ARG_TO_INT(args[3]),
3713                          ARG_TO_UNSIGNED_INT(args[4]),
3714                          ARG_TO_UNSIGNED_INT(args[5]), (void *) (args[6]));
3715             break;
3716         }
3717
3718     case _glDrawPixels_pbo_func:
3719         {
3720             glDrawPixels(ARG_TO_INT(args[0]), ARG_TO_INT(args[1]),
3721                          ARG_TO_UNSIGNED_INT(args[2]),
3722                          ARG_TO_UNSIGNED_INT(args[3]),
3723                          (const void *) (args[4]));
3724             break;
3725         }
3726
3727     case _glMapBufferARB_fake_func:
3728         {
3729             GET_EXT_PTR(GLvoid *, glMapBufferARB, (GLenum, GLenum));
3730             GET_EXT_PTR(GLboolean, glUnmapBufferARB, (GLenum));
3731             int target = args[0];
3732             int size = args[1];
3733             void *dst_ptr = (void *) args[2];
3734             void *src_ptr = ptr_func_glMapBufferARB(target, GL_READ_ONLY);
3735
3736             if (src_ptr) {
3737                 memcpy(dst_ptr, src_ptr, size);
3738                 ret.i = ptr_func_glUnmapBufferARB(target);
3739             } else {
3740                 ret.i = 0;
3741             }
3742             break;
3743         }
3744
3745     case fake_gluBuild2DMipmaps_func:
3746         {
3747             GET_GLU_PTR(GLint, gluBuild2DMipmaps,
3748                         (GLenum arg_0, GLint arg_1, GLsizei arg_2,
3749                          GLsizei arg_3, GLenum arg_4, GLenum arg_5,
3750                          const GLvoid *arg_6));
3751             if (ptr_func_gluBuild2DMipmaps == NULL)
3752                 ptr_func_gluBuild2DMipmaps = mesa_gluBuild2DMipmaps;
3753             ptr_func_gluBuild2DMipmaps(ARG_TO_UNSIGNED_INT(args[0]),
3754                                        ARG_TO_INT(args[1]),
3755                                        ARG_TO_INT(args[2]),
3756                                        ARG_TO_INT(args[3]),
3757                                        ARG_TO_UNSIGNED_INT(args[4]),
3758                                        ARG_TO_UNSIGNED_INT(args[5]),
3759                                        (const void *) (args[6]));
3760             break;
3761         }
3762
3763     case _glSelectBuffer_fake_func:
3764         {
3765             process->current_state->selectBufferSize = args[0] * 4;
3766             process->current_state->selectBufferPtr =
3767                 g_realloc(process->current_state->selectBufferPtr,
3768                         process->current_state->selectBufferSize);
3769             glSelectBuffer(args[0], process->current_state->selectBufferPtr);
3770             break;
3771         }
3772
3773     case _glGetSelectBuffer_fake_func:
3774         {
3775             void *ptr = (void *) args[0];
3776
3777             memcpy(ptr, process->current_state->selectBufferPtr,
3778                    process->current_state->selectBufferSize);
3779             break;
3780         }
3781
3782     case _glFeedbackBuffer_fake_func:
3783         {
3784             process->current_state->feedbackBufferSize = args[0] * 4;
3785             process->current_state->feedbackBufferPtr =
3786                 g_realloc(process->current_state->feedbackBufferPtr,
3787                         process->current_state->feedbackBufferSize);
3788             glFeedbackBuffer((GLsizei)args[0], (GLenum) args[1],
3789                              process->current_state->feedbackBufferPtr);
3790             break;
3791         }
3792
3793     case _glGetFeedbackBuffer_fake_func:
3794         {
3795             void *ptr = (void *) args[0];
3796
3797             memcpy(ptr, process->current_state->feedbackBufferPtr,
3798                    process->current_state->feedbackBufferSize);
3799             break;
3800         }
3801
3802         /* 
3803          * case glEnableClientState_func: { if (display_function_call)
3804          * DEBUGF( "cap : %s\n", nameArrays[args[0] -
3805          * GL_VERTEX_ARRAY]); glEnableClientState(args[0]); break; }
3806          * 
3807          * case glDisableClientState_func: { if (display_function_call)
3808          * DEBUGF( "cap : %s\n", nameArrays[args[0] -
3809          * GL_VERTEX_ARRAY]); glDisableClientState(args[0]); break; }
3810          * 
3811          * case glClientActiveTexture_func: case
3812          * glClientActiveTextureARB_func: { if (display_function_call)
3813          * DEBUGF( "client activeTexture %d\n", args[0] -
3814          * GL_TEXTURE0_ARB); glClientActiveTextureARB(args[0]); break; }
3815          * 
3816          * case glActiveTextureARB_func: { if (display_function_call)
3817          * DEBUGF( "server activeTexture %d\n", args[0] -
3818          * GL_TEXTURE0_ARB); glActiveTextureARB(args[0]); break; }
3819          * 
3820          * case glLockArraysEXT_func: break;
3821          * 
3822          * case glUnlockArraysEXT_func: break;
3823          * 
3824          * case glArrayElement_func: { glArrayElement(args[0]); break; }
3825          * 
3826          * case glDrawArrays_func: { glDrawArrays(args[0],args[1],args[2]);
3827          * break; }
3828          * 
3829          * case glDrawElements_func: {
3830          * glDrawElements(args[0],args[1],args[2],(void*)args[3]); break; }
3831          * 
3832          * case glDrawRangeElements_func: {
3833          * glDrawRangeElements(args[0],args[1],args[2],args[3],args[4],(void*)args[5]);
3834          * break; } */
3835
3836     case glGetError_func:
3837         {
3838             ret.i = glGetError();
3839             break;
3840         }
3841
3842     case glNewObjectBufferATI_func:
3843         {
3844             GET_EXT_PTR(int, glNewObjectBufferATI, (int, void *, int));
3845
3846             ret.i = ptr_func_glNewObjectBufferATI(args[0],
3847                             (void *) args[1], args[2]);
3848             break;
3849         }
3850
3851     case glClear_func:
3852         glClear((GLbitfield)args[0]);
3853         break;
3854 #if 0
3855         /* HACK workaround for an unexplainable issue */
3856         if (args[0] & GL_COLOR_BUFFER_BIT)
3857             glClear(GL_COLOR_BUFFER_BIT);
3858         if (args[0] & GL_STENCIL_BUFFER_BIT)
3859             glClear(GL_STENCIL_BUFFER_BIT);
3860         if (args[0] & GL_DEPTH_BUFFER_BIT)
3861             glClear(GL_DEPTH_BUFFER_BIT);
3862         if (args[0] & GL_ACCUM_BUFFER_BIT)
3863             glClear(GL_ACCUM_BUFFER_BIT);
3864         break;
3865 #endif
3866
3867 #ifdef _WIN32
3868         /* workaround for bug T_SDK-128. If GL_UNPACK_ROW_LENGTH==0, GL driver
3869          * should calculate it for glTexSubImage2D according to width parameter and
3870          * GL_UNPACK_ALIGNMENT. But on windows, some vender's driver like nvidia,
3871          * don't follow it. So we need do it for the driver, and probably remove
3872          * this hack in future if driver get fixed.
3873          */
3874         case glTexSubImage2D_func:
3875                 {
3876                         int origin_row_length, alignment, width;
3877
3878                         if (args[6] == GL_ALPHA) {
3879                                 width = args[4];
3880                                 glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
3881                                 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &origin_row_length);
3882
3883                                 if (width%alignment != 0) {
3884                                         width = (width/alignment + 1) * alignment;
3885                                 }
3886
3887                                 glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
3888                         }
3889
3890                         glTexSubImage2D(ARG_TO_UNSIGNED_INT(args[0]), ARG_TO_INT(args[1]),
3891                                                 ARG_TO_INT(args[2]), ARG_TO_INT(args[3]),
3892                                                 ARG_TO_INT(args[4]), ARG_TO_INT(args[5]),
3893                                                 ARG_TO_UNSIGNED_INT(args[6]),
3894                                                 ARG_TO_UNSIGNED_INT(args[7]), (const void*)(args[8]));
3895
3896                         if (args[6] == GL_ALPHA)
3897                                 glPixelStorei(GL_UNPACK_ROW_LENGTH, origin_row_length);
3898
3899                         break;
3900                 }
3901 #endif
3902
3903 #ifdef __APPLE__
3904         case glTexSubImage2D_func:
3905                 {
3906
3907                         glTexSubImage2D(ARG_TO_UNSIGNED_INT(args[0]), ARG_TO_INT(args[1]),
3908                                         ARG_TO_INT(args[2]), ARG_TO_INT(args[3]),
3909                                         ARG_TO_INT(args[4]), ARG_TO_INT(args[5]),
3910                                         ARG_TO_UNSIGNED_INT(args[6]), ARG_TO_UNSIGNED_INT(args[7]),
3911                                         (const void*)(args[8]));
3912
3913                         if ( ARG_TO_UNSIGNED_INT(args[0]) == GL_TEXTURE_2D &&
3914                                         ARG_TO_INT(args[1]) == 0 &&
3915                                         ARG_TO_UNSIGNED_INT(args[6]) == GL_RGBA &&
3916                                         ARG_TO_UNSIGNED_INT(args[7]) == GL_UNSIGNED_BYTE )
3917                                 mac_dump_texture();
3918                         else
3919                                 fprintf(stderr, "!!! Probable screen crash, no work around as glTexSubImage2d parameters do not match!\n");
3920
3921                         break;
3922                 }
3923 #endif
3924
3925     default:
3926         execute_func(func_number, (void**)args, &ret);
3927         break;
3928     }
3929
3930     switch (ret_type) {
3931     case TYPE_NONE:
3932     case TYPE_CHAR:
3933     case TYPE_UNSIGNED_CHAR:
3934     case TYPE_INT:
3935     case TYPE_UNSIGNED_INT:
3936         break;
3937
3938     case TYPE_CONST_CHAR:
3939         {
3940             strncpy(ret_string, (ret.s) ? ret.s : "", 32768);
3941             break;
3942         }
3943
3944     default:
3945         DEBUGF( "unexpected ret type : %d\n", ret_type);
3946         exit(-1);
3947         break;
3948     }
3949
3950     if (display_function_call)
3951         DEBUGF( "[%d]< %s\n", process->p.process_id,
3952                 tab_opengl_calls_name[func_number]);
3953
3954     return ret.i;
3955 }