diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/dyngen-exec.h qemu/dyngen-exec.h --- qemu.ori/dyngen-exec.h 2006-11-14 00:18:09.000000000 +0100 +++ qemu/dyngen-exec.h 2006-11-14 21:46:24.000000000 +0100 @@ -75,12 +75,16 @@ typedef signed long long int64_t; #define UINT32_MAX (4294967295U) #define UINT64_MAX ((uint64_t)(18446744073709551615)) +#ifndef _STDIO_H + typedef struct FILE FILE; extern int fprintf(FILE *, const char *, ...); extern int printf(const char *, ...); #undef NULL #define NULL 0 +#endif + #ifdef __i386__ #define AREG0 "ebp" #define AREG1 "ebx" diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/kqemu.c qemu/kqemu.c --- qemu.ori/kqemu.c 2006-11-14 00:18:09.000000000 +0100 +++ qemu/kqemu.c 2006-11-14 21:46:24.000000000 +0100 @@ -87,6 +87,7 @@ unsigned long *modified_ram_pages; unsigned int nb_modified_ram_pages; uint8_t *modified_ram_pages_table; extern uint32_t **l1_phys_map; +extern int enable_gl; #define cpuid(index, eax, ebx, ecx, edx) \ asm volatile ("cpuid" \ @@ -721,6 +722,7 @@ int kqemu_cpu_exec(CPUState *env) ret = ioctl(kqemu_fd, KQEMU_EXEC, kenv); #endif #endif + if (env->cpuid_features & CPUID_FXSR) save_native_fp_fxsave(env); else @@ -749,7 +751,6 @@ int kqemu_cpu_exec(CPUState *env) env->kernelgsbase = kenv->kernelgsbase; #endif #endif - /* flush pages as indicated by kqemu */ if (kenv->nb_pages_to_flush >= KQEMU_FLUSH_ALL) { tlb_flush(env, 1); @@ -825,13 +826,40 @@ int kqemu_cpu_exec(CPUState *env) else env->hflags &= ~HF_OSFXSR_MASK; + /* OPENGL Stuff */ + if (enable_gl && ((env->hflags & HF_CPL_MASK) == 3)) + { + int index = (env->eip >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + if (env->segs[R_CS].base != 0) + { + fprintf(stderr, "env->segs[R_CS].base != 0 !\n"); + } + else if (__builtin_expect(env->tlb_table[1][index].addr_code != + (env->eip & TARGET_PAGE_MASK), 0)) + { + ldub_code(env->eip); + } + if (env->tlb_table[1][index].addend) + { + unsigned char* ptr = env->eip + env->tlb_table[1][index].addend; + if (ptr[0] == 0xCD && ptr[1] == 0x99) + { + helper_opengl(env); + } + /*else if (ptr[0] == 0xCD && ptr[1] == 0x80) + { + fprintf(stderr, "system call %d\n", env->regs[R_EAX]); + }*/ + } + } + #ifdef DEBUG if (loglevel & CPU_LOG_INT) { fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret); } #endif if (ret == KQEMU_RET_SYSCALL) { - /* syscall instruction */ + /* syscall instruction */ return do_syscall(env, kenv); } else if ((ret & 0xff00) == KQEMU_RET_INT) { diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/Makefile.target qemu/Makefile.target --- qemu.ori/Makefile.target 2006-11-14 00:18:09.000000000 +0100 +++ qemu/Makefile.target 2006-11-16 20:59:49.000000000 +0100 @@ -285,8 +285,6 @@ ifdef CONFIG_GDBSTUB OBJS+=gdbstub.o endif -all: $(PROGS) - $(QEMU_USER): $(OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) ifeq ($(ARCH),alpha) @@ -435,8 +433,28 @@ ifdef CONFIG_WIN32 SDL_LIBS := $(filter-out -mwindows, $(SDL_LIBS)) -mconsole endif +ifeq ($(TARGET_BASE_ARCH), i386) +parse_gl_h: parse_gl_h.c + $(CC) -o $@ $< +server_stub.c: parse_gl_h + ./parse_gl_h +client_stub.c: parse_gl_h + ./parse_gl_h +gl_func.h: parse_gl_h + ./parse_gl_h +# -O2 doesn't work --> 'unable to find a register to spill in class `DIREG'' +GL_CFLAGS := -Wall -g -fno-strict-aliasing +helper_opengl.o: helper_opengl.c server_stub.c gl_func.h + $(CC) $(GL_CFLAGS) $(DEFINES) -c -o $@ $< +LIBOBJS+=helper_opengl.o +libGL.so: client_stub.c gl_func.h + $(CC) $(GL_CFLAGS) $(SRC_PATH)/target-i386/opengl_client.c -shared -o libGL.so -I. -I$(SRC_PATH)/target-i386 +PROGS+=libGL.so +GL_GENERATED_FILES=libGL.so parse_gl_h server_stub.c client_stub.c gl_func.h +endif + $(QEMU_SYSTEM): $(VL_OBJS) libqemu.a - $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS) + $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS) -lGL cocoa.o: cocoa.m $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< @@ -545,7 +563,7 @@ $(OBJS) $(LIBOBJS) $(VL_OBJS): config.h $(CC) $(DEFINES) -c -o $@ $< clean: - rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o fpu/*.o + rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o fpu/*.o $(GL_GENERATED_FILES) install: all ifneq ($(PROGS),) @@ -561,3 +579,5 @@ audio.o sdlaudio.o dsoundaudio.o ossaudi fmodaudio.o alsaaudio.o mixeng.o sb16.o es1370.o gus.o adlib.o: \ CFLAGS := $(CFLAGS) -Wall -Werror -W -Wsign-compare endif + +all: $(PROGS) diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/target-i386/gl_func_perso.h qemu/target-i386/gl_func_perso.h --- qemu.ori/target-i386/gl_func_perso.h 1970-01-01 01:00:00.000000000 +0100 +++ qemu/target-i386/gl_func_perso.h 2006-11-14 21:46:24.000000000 +0100 @@ -0,0 +1,93 @@ +/* + * Hand-implemented GL/GLX API + * + * Copyright (c) 2006 Even Rouault + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +MAGIC_MACRO(_exit_process), +MAGIC_MACRO(_moveResizeWindow), +MAGIC_MACRO(_changeWindowState), +MAGIC_MACRO(_needSync), + +MAGIC_MACRO(glXChooseVisual), +MAGIC_MACRO(glXQueryExtensionsString), +MAGIC_MACRO(glXQueryServerString), +MAGIC_MACRO(glXCreateContext), +MAGIC_MACRO(glXGetCurrentContext), +MAGIC_MACRO(glXGetCurrentDrawable), +MAGIC_MACRO(glXDestroyContext), +MAGIC_MACRO(glXGetClientString), +MAGIC_MACRO(glXQueryVersion), +MAGIC_MACRO(glXMakeCurrent), +MAGIC_MACRO(glXGetConfig), +MAGIC_MACRO(glXChooseFBConfig), +MAGIC_MACRO(glXCreatePbuffer), +MAGIC_MACRO(glXGetVisualFromFBConfig), +MAGIC_MACRO(glXUseXFont), +MAGIC_MACRO(glXIsDirect), +MAGIC_MACRO(glXGetProcAddress_fake), + +MAGIC_MACRO(glGetString), +MAGIC_MACRO(glGetIntegerv), +MAGIC_MACRO(glGetFloatv), +MAGIC_MACRO(glGetConvolutionParameteriv), +MAGIC_MACRO(glLightfv), +MAGIC_MACRO(glMaterialfv), +MAGIC_MACRO(glXSwapBuffers), +MAGIC_MACRO(glXQueryExtension), +MAGIC_MACRO(glLightModelfv), +MAGIC_MACRO(glMap1f), +MAGIC_MACRO(glMap1d), +MAGIC_MACRO(glMap2f), +MAGIC_MACRO(glMap2d), +MAGIC_MACRO(glGenTextures), +MAGIC_MACRO(glDeleteTextures), +MAGIC_MACRO(glTexImage1D), +MAGIC_MACRO(glTexImage2D), +MAGIC_MACRO(glCompressedTexImage2DARB), +MAGIC_MACRO(glTexSubImage2D), +MAGIC_MACRO(glCompressedTexSubImage2DARB), +MAGIC_MACRO(glTexImage3D), +MAGIC_MACRO(glGetTexLevelParameteriv), +MAGIC_MACRO(glFogfv), +MAGIC_MACRO(glBitmap), +MAGIC_MACRO(glTexGenfv), +MAGIC_MACRO(glTexEnvfv), +MAGIC_MACRO(glTexParameterfv), +MAGIC_MACRO(glTexParameteriv), +MAGIC_MACRO(glPointParameterfvARB), +MAGIC_MACRO(glCallLists), +MAGIC_MACRO(glGenProgramsARB), +MAGIC_MACRO(glProgramStringARB), +MAGIC_MACRO(glDeleteProgramsARB), +MAGIC_MACRO(glShaderSourceARB), +MAGIC_MACRO(glGetUniformLocationARB), +MAGIC_MACRO(glGetVertexAttribfvARB), +MAGIC_MACRO(glGetVertexAttribivARB), +MAGIC_MACRO(glGetVertexAttribdvARB), +MAGIC_MACRO(glGetProgramLocalParameterfvARB), +MAGIC_MACRO(glGetProgramLocalParameterdvARB), +MAGIC_MACRO(glGetProgramEnvParameterfvARB), +MAGIC_MACRO(glGetProgramEnvParameterdvARB), +MAGIC_MACRO(glGetProgramivARB), +MAGIC_MACRO(glGetProgramStringARB), +MAGIC_MACRO(glVertexPointer), +MAGIC_MACRO(glNormalPointer), +MAGIC_MACRO(glColorPointer), +MAGIC_MACRO(glTexCoordPointer), +MAGIC_MACRO(glDrawArrays), +MAGIC_MACRO(glDrawElements), diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/target-i386/glgetv_cst.h qemu/target-i386/glgetv_cst.h --- qemu.ori/target-i386/glgetv_cst.h 1970-01-01 01:00:00.000000000 +0100 +++ qemu/target-i386/glgetv_cst.h 2006-11-14 21:46:24.000000000 +0100 @@ -0,0 +1,250 @@ +struct token_name { + GLuint count; + GLenum token; + const char *name; +}; +#define MAKE_TOKEN_NAME(x) x, #x +static const struct token_name limits[] = { + { 1, MAKE_TOKEN_NAME(GL_ACCUM_ALPHA_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_ACCUM_BLUE_BITS) }, + { 4, MAKE_TOKEN_NAME(GL_ACCUM_CLEAR_VALUE) }, + { 1, MAKE_TOKEN_NAME(GL_ACCUM_GREEN_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_ACCUM_RED_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_ACTIVE_TEXTURE_ARB) }, + { 1, MAKE_TOKEN_NAME(GL_ALPHA_BIAS) }, + { 1, MAKE_TOKEN_NAME(GL_ALPHA_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_ALPHA_SCALE) }, + { 1, MAKE_TOKEN_NAME(GL_ALPHA_TEST) }, + { 1, MAKE_TOKEN_NAME(GL_ALPHA_TEST_FUNC) }, + { 1, MAKE_TOKEN_NAME(GL_ALPHA_TEST_REF) }, + { 1, MAKE_TOKEN_NAME(GL_ATTRIB_STACK_DEPTH) }, + { 1, MAKE_TOKEN_NAME(GL_AUTO_NORMAL) }, + { 1, MAKE_TOKEN_NAME(GL_AUX_BUFFERS) }, + { 1, MAKE_TOKEN_NAME(GL_BLEND) }, + { 4, MAKE_TOKEN_NAME(GL_BLEND_COLOR) }, + { 1, MAKE_TOKEN_NAME(GL_BLEND_DST) }, + { 1, MAKE_TOKEN_NAME(GL_BLEND_EQUATION) }, + { 1, MAKE_TOKEN_NAME(GL_BLEND_SRC) }, + { 1, MAKE_TOKEN_NAME(GL_BLUE_BIAS) }, + { 1, MAKE_TOKEN_NAME(GL_BLUE_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_BLUE_SCALE) }, + { 1, MAKE_TOKEN_NAME(GL_CLIP_PLANE0) }, + { 1, MAKE_TOKEN_NAME(GL_CLIP_PLANE1) }, + { 1, MAKE_TOKEN_NAME(GL_CLIP_PLANE2) }, + { 1, MAKE_TOKEN_NAME(GL_CLIP_PLANE3) }, + { 1, MAKE_TOKEN_NAME(GL_CLIP_PLANE4) }, + { 1, MAKE_TOKEN_NAME(GL_COLOR_ARRAY) }, + { 1, MAKE_TOKEN_NAME(GL_COLOR_ARRAY_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_COLOR_ARRAY_STRIDE) }, + { 1, MAKE_TOKEN_NAME(GL_COLOR_ARRAY_TYPE) }, + { 4, MAKE_TOKEN_NAME(GL_COLOR_CLEAR_VALUE) }, + { 1, MAKE_TOKEN_NAME(GL_COLOR_LOGIC_OP) }, + { 1, MAKE_TOKEN_NAME(GL_COLOR_MATERIAL) }, + { 1, MAKE_TOKEN_NAME(GL_COLOR_MATERIAL_FACE) }, + { 16, MAKE_TOKEN_NAME(GL_COLOR_MATRIX) }, + { 1, MAKE_TOKEN_NAME(GL_COLOR_TABLE) }, + { 4, MAKE_TOKEN_NAME(GL_COLOR_WRITEMASK) }, + { 1, MAKE_TOKEN_NAME(GL_CONVOLUTION_1D) }, + { 1, MAKE_TOKEN_NAME(GL_CONVOLUTION_2D) }, + { 1, MAKE_TOKEN_NAME(GL_CULL_FACE) }, + { 1, MAKE_TOKEN_NAME(GL_CULL_FACE_MODE) }, + { 4, MAKE_TOKEN_NAME(GL_CURRENT_COLOR) }, + { 1, MAKE_TOKEN_NAME(GL_CURRENT_INDEX) }, + { 3, MAKE_TOKEN_NAME(GL_CURRENT_NORMAL) }, + { 4, MAKE_TOKEN_NAME(GL_CURRENT_RASTER_COLOR) }, + { 1, MAKE_TOKEN_NAME(GL_CURRENT_RASTER_INDEX) }, + { 1, MAKE_TOKEN_NAME(GL_DEPTH_BIAS) }, + { 1, MAKE_TOKEN_NAME(GL_DEPTH_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_DEPTH_CLEAR_VALUE) }, + { 1, MAKE_TOKEN_NAME(GL_DEPTH_FUNC) }, + { 2, MAKE_TOKEN_NAME(GL_DEPTH_RANGE) }, + { 1, MAKE_TOKEN_NAME(GL_DEPTH_SCALE) }, + { 1, MAKE_TOKEN_NAME(GL_DEPTH_TEST) }, + { 1, MAKE_TOKEN_NAME(GL_DEPTH_WRITEMASK) }, + { 1, MAKE_TOKEN_NAME(GL_DITHER) }, + { 1, MAKE_TOKEN_NAME(GL_DOUBLEBUFFER) }, + { 1, MAKE_TOKEN_NAME(GL_DRAW_BUFFER) }, + { 1, MAKE_TOKEN_NAME(GL_EDGE_FLAG) }, + { 1, MAKE_TOKEN_NAME(GL_EDGE_FLAG_ARRAY) }, + { 1, MAKE_TOKEN_NAME(GL_FEEDBACK_BUFFER_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_FEEDBACK_BUFFER_TYPE) }, + { 1, MAKE_TOKEN_NAME(GL_FOG) }, + { 4, MAKE_TOKEN_NAME(GL_FOG_COLOR) }, + { 1, MAKE_TOKEN_NAME(GL_FOG_DENSITY) }, + { 1, MAKE_TOKEN_NAME(GL_FOG_END) }, + { 1, MAKE_TOKEN_NAME(GL_FOG_HINT) }, + { 1, MAKE_TOKEN_NAME(GL_FOG_INDEX) }, + { 1, MAKE_TOKEN_NAME(GL_FOG_MODE) }, + { 1, MAKE_TOKEN_NAME(GL_FOG_START) }, + { 1, MAKE_TOKEN_NAME(GL_FRONT_FACE) }, + { 1, MAKE_TOKEN_NAME(GL_GREEN_BIAS) }, + { 1, MAKE_TOKEN_NAME(GL_GREEN_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_GREEN_SCALE) }, + { 1, MAKE_TOKEN_NAME(GL_HISTOGRAM) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_ARRAY) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_ARRAY_STRIDE) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_ARRAY_TYPE) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_CLEAR_VALUE) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_LOGIC_OP) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_MODE) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_OFFSET) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_SHIFT) }, + { 1, MAKE_TOKEN_NAME(GL_INDEX_WRITEMASK) }, + { 1, MAKE_TOKEN_NAME(GL_LIGHT0) }, + { 1, MAKE_TOKEN_NAME(GL_LIGHT1) }, + { 1, MAKE_TOKEN_NAME(GL_LIGHT2) }, + { 1, MAKE_TOKEN_NAME(GL_LIGHT3) }, + { 1, MAKE_TOKEN_NAME(GL_LIGHT4) }, + { 1, MAKE_TOKEN_NAME(GL_LIGHT5) }, + { 1, MAKE_TOKEN_NAME(GL_LIGHT6) }, + { 1, MAKE_TOKEN_NAME(GL_LIGHTING) }, + { 4, MAKE_TOKEN_NAME(GL_LIGHT_MODEL_AMBIENT) }, + { 1, MAKE_TOKEN_NAME(GL_LIGHT_MODEL_TWO_SIDE) }, + { 1, MAKE_TOKEN_NAME(GL_LINE_SMOOTH) }, + { 1, MAKE_TOKEN_NAME(GL_LINE_SMOOTH_HINT) }, + { 1, MAKE_TOKEN_NAME(GL_LINE_STIPPLE) }, + { 1, MAKE_TOKEN_NAME(GL_LINE_STIPPLE_PATTERN) }, + { 1, MAKE_TOKEN_NAME(GL_LINE_STIPPLE_REPEAT) }, + { 1, MAKE_TOKEN_NAME(GL_LINE_WIDTH) }, + { 2, MAKE_TOKEN_NAME(GL_LINE_WIDTH_RANGE) }, + { 1, MAKE_TOKEN_NAME(GL_LIST_BASE) }, + { 1, MAKE_TOKEN_NAME(GL_LIST_INDEX) }, + { 1, MAKE_TOKEN_NAME(GL_LIST_MODE) }, + { 1, MAKE_TOKEN_NAME(GL_LOGIC_OP_MODE) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_COLOR_4) }, + { 2, MAKE_TOKEN_NAME(GL_MAP1_GRID_DOMAIN) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_GRID_SEGMENTS) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_INDEX) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_NORMAL) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_TEXTURE_COORD_1) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_TEXTURE_COORD_2) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_TEXTURE_COORD_3) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_TEXTURE_COORD_4) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_VERTEX_3) }, + { 1, MAKE_TOKEN_NAME(GL_MAP1_VERTEX_4) }, + { 1, MAKE_TOKEN_NAME(GL_MAP2_COLOR_4) }, + { 4, MAKE_TOKEN_NAME(GL_MAP2_GRID_DOMAIN) }, + { 2, MAKE_TOKEN_NAME(GL_MAP2_GRID_SEGMENTS) }, + { 1, MAKE_TOKEN_NAME(GL_MAP2_INDEX) }, + { 1, MAKE_TOKEN_NAME(GL_MAP2_NORMAL) }, + { 1, MAKE_TOKEN_NAME(GL_MAP2_TEXTURE_COORD_1) }, + { 1, MAKE_TOKEN_NAME(GL_MAP2_TEXTURE_COORD_2) }, + { 1, MAKE_TOKEN_NAME(GL_MAP2_TEXTURE_COORD_3) }, + { 1, MAKE_TOKEN_NAME(GL_MAP2_TEXTURE_COORD_4) }, + { 1, MAKE_TOKEN_NAME(GL_MAP2_VERTEX_3) }, + { 1, MAKE_TOKEN_NAME(GL_MAP2_VERTEX_4) }, + { 1, MAKE_TOKEN_NAME(GL_MAP_COLOR) }, + { 1, MAKE_TOKEN_NAME(GL_MAP_STENCIL) }, + { 1, MAKE_TOKEN_NAME(GL_MATRIX_MODE) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_3D_TEXTURE_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_CLIP_PLANES) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_ELEMENTS_INDICES) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_ELEMENTS_VERTICES) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_EVAL_ORDER) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_LIGHTS) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_LIST_NESTING) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_NAME_STACK_DEPTH) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_PIXEL_MAP_TABLE) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_TEXTURE_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_TEXTURE_UNITS_ARB) }, + { 2, MAKE_TOKEN_NAME(GL_MAX_VIEWPORT_DIMS) }, + { 1, MAKE_TOKEN_NAME(GL_MINMAX) }, + { 16, MAKE_TOKEN_NAME(GL_MODELVIEW_MATRIX) }, + { 1, MAKE_TOKEN_NAME(GL_MODELVIEW_STACK_DEPTH) }, + { 1, MAKE_TOKEN_NAME(GL_NAME_STACK_DEPTH) }, + { 1, MAKE_TOKEN_NAME(GL_NORMAL_ARRAY) }, + { 1, MAKE_TOKEN_NAME(GL_NORMAL_ARRAY_STRIDE) }, + { 1, MAKE_TOKEN_NAME(GL_NORMAL_ARRAY_TYPE) }, + { 1, MAKE_TOKEN_NAME(GL_NORMALIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PACK_ALIGNMENT) }, + { 1, MAKE_TOKEN_NAME(GL_PACK_IMAGE_HEIGHT) }, + { 1, MAKE_TOKEN_NAME(GL_PACK_LSB_FIRST) }, + { 1, MAKE_TOKEN_NAME(GL_PACK_ROW_LENGTH) }, + { 1, MAKE_TOKEN_NAME(GL_PACK_SKIP_IMAGES) }, + { 1, MAKE_TOKEN_NAME(GL_PACK_SKIP_PIXELS) }, + { 1, MAKE_TOKEN_NAME(GL_PACK_SKIP_ROWS) }, + { 1, MAKE_TOKEN_NAME(GL_PACK_SWAP_BYTES) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_A_TO_A_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_B_TO_B_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_G_TO_G_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_I_TO_A_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_I_TO_B_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_I_TO_G_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_I_TO_I_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_I_TO_R_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_R_TO_R_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_PIXEL_MAP_S_TO_S_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_POINT_SIZE) }, + { 2, MAKE_TOKEN_NAME(GL_POINT_SIZE_RANGE) }, + { 1, MAKE_TOKEN_NAME(GL_POINT_SMOOTH) }, + { 1, MAKE_TOKEN_NAME(GL_POINT_SMOOTH_HINT) }, + { 2, MAKE_TOKEN_NAME(GL_POLYGON_MODE) }, + { 1, MAKE_TOKEN_NAME(GL_POLYGON_OFFSET_FACTOR) }, + { 1, MAKE_TOKEN_NAME(GL_POLYGON_OFFSET_UNITS) }, + { 1, MAKE_TOKEN_NAME(GL_POLYGON_OFFSET_FILL) }, + { 1, MAKE_TOKEN_NAME(GL_POLYGON_OFFSET_LINE) }, + { 1, MAKE_TOKEN_NAME(GL_POLYGON_OFFSET_POINT) }, + { 1, MAKE_TOKEN_NAME(GL_POLYGON_SMOOTH) }, + { 1, MAKE_TOKEN_NAME(GL_POLYGON_SMOOTH_HINT) }, + { 1, MAKE_TOKEN_NAME(GL_POLYGON_STIPPLE) }, + { 16, MAKE_TOKEN_NAME(GL_PROJECTION_MATRIX) }, + { 1, MAKE_TOKEN_NAME(GL_READ_BUFFER) }, + { 1, MAKE_TOKEN_NAME(GL_RED_BIAS) }, + { 1, MAKE_TOKEN_NAME(GL_RED_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_RED_SCALE) }, + { 1, MAKE_TOKEN_NAME(GL_RENDER_MODE) }, + { 1, MAKE_TOKEN_NAME(GL_RESCALE_NORMAL) }, + { 1, MAKE_TOKEN_NAME(GL_RGBA_MODE) }, + { 4, MAKE_TOKEN_NAME(GL_SCISSOR_BOX) }, + { 1, MAKE_TOKEN_NAME(GL_SCISSOR_TEST) }, + { 1, MAKE_TOKEN_NAME(GL_SEPARABLE_2D) }, + { 1, MAKE_TOKEN_NAME(GL_SHADE_MODEL) }, + { 1, MAKE_TOKEN_NAME(GL_STENCIL_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_STENCIL_CLEAR_VALUE) }, + { 1, MAKE_TOKEN_NAME(GL_STENCIL_FAIL) }, + { 1, MAKE_TOKEN_NAME(GL_STENCIL_FUNC) }, + { 1, MAKE_TOKEN_NAME(GL_STENCIL_REF) }, + { 1, MAKE_TOKEN_NAME(GL_STENCIL_TEST) }, + { 1, MAKE_TOKEN_NAME(GL_STENCIL_VALUE_MASK) }, + { 1, MAKE_TOKEN_NAME(GL_STENCIL_WRITEMASK) }, + { 1, MAKE_TOKEN_NAME(GL_STEREO) }, + { 1, MAKE_TOKEN_NAME(GL_SUBPIXEL_BITS) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_1D) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_BINDING_1D) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_2D) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_BINDING_2D) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_3D) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_BINDING_3D) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_COORD_ARRAY) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_GEN_Q) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_GEN_R) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_GEN_S) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_GEN_T) }, + { 16, MAKE_TOKEN_NAME(GL_TEXTURE_MATRIX) }, + { 1, MAKE_TOKEN_NAME(GL_TEXTURE_STACK_DEPTH) }, + { 1, MAKE_TOKEN_NAME(GL_UNPACK_ALIGNMENT) }, + { 1, MAKE_TOKEN_NAME(GL_UNPACK_IMAGE_HEIGHT) }, + { 1, MAKE_TOKEN_NAME(GL_UNPACK_LSB_FIRST) }, + { 1, MAKE_TOKEN_NAME(GL_UNPACK_ROW_LENGTH) }, + { 1, MAKE_TOKEN_NAME(GL_UNPACK_SKIP_IMAGES) }, + { 1, MAKE_TOKEN_NAME(GL_UNPACK_SKIP_PIXELS) }, + { 1, MAKE_TOKEN_NAME(GL_UNPACK_SKIP_ROWS) }, + { 1, MAKE_TOKEN_NAME(GL_UNPACK_SWAP_BYTES) }, + { 1, MAKE_TOKEN_NAME(GL_VERTEX_ARRAY) }, + { 1, MAKE_TOKEN_NAME(GL_VERTEX_ARRAY_SIZE) }, + { 1, MAKE_TOKEN_NAME(GL_VERTEX_ARRAY_STRIDE) }, + { 1, MAKE_TOKEN_NAME(GL_VERTEX_ARRAY_TYPE) }, + { 4, MAKE_TOKEN_NAME(GL_VIEWPORT) }, + { 1, MAKE_TOKEN_NAME(GL_ZOOM_X) }, + { 1, MAKE_TOKEN_NAME(GL_ZOOM_Y) }, + { 2, MAKE_TOKEN_NAME(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_GENERAL_COMBINERS_NV) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_TEXTURE_LOD_BIAS) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_TEXTURE_LOD_BIAS_EXT) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB) }, + { 1, MAKE_TOKEN_NAME(GL_MAX_RECTANGLE_TEXTURE_SIZE_NV) }, + { 1, MAKE_TOKEN_NAME(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB) }, + { 1, MAKE_TOKEN_NAME(GL_PROGRAM_ERROR_POSITION_ARB) }, + { 0, (GLenum) 0, NULL } +}; diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/target-i386/helper.c qemu/target-i386/helper.c --- qemu.ori/target-i386/helper.c 2006-11-14 00:18:10.000000000 +0100 +++ qemu/target-i386/helper.c 2006-11-14 21:46:24.000000000 +0100 @@ -3782,6 +3782,16 @@ void update_fp_status(void) #endif } +void helper_opengl(CPUState *env); + +void helper_int99() +{ + regs_to_env(); + helper_opengl(env); + env_to_regs(); +} + + #if !defined(CONFIG_USER_ONLY) #define MMUSUFFIX _mmu diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/target-i386/helper_opengl.c qemu/target-i386/helper_opengl.c --- qemu.ori/target-i386/helper_opengl.c 1970-01-01 01:00:00.000000000 +0100 +++ qemu/target-i386/helper_opengl.c 2006-11-14 21:57:41.000000000 +0100 @@ -0,0 +1,1764 @@ +/* + * Host-side implementation of GL/GLX API + * + * Copyright (c) 2006 Even Rouault + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include +#include "exec.h" +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "opengl_func.h" + +#include "glgetv_cst.h" + +#define GET_EXT_PTR(type, func_name, args_decl) \ + static int detect = 0; \ + static type(*ptr_func)args_decl = NULL; \ + if (detect == 0) \ +{ \ + detect = 1; \ + ptr_func = glXGetProcAddress((const GLubyte*)#func_name); \ + assert (ptr_func); \ +} + +static inline void* get_phys_mem_addr(const CPUState *env, target_ulong addr) +{ + int is_user, index; + index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + is_user = ((env->hflags & HF_CPL_MASK) == 3); + if (is_user == 0) + { + fprintf(stderr, "not in userland !!!\n"); + return NULL; + } + if (__builtin_expect(env->tlb_table[is_user][index].addr_code != + (addr & TARGET_PAGE_MASK), 0)) + { + target_ulong ret = cpu_get_phys_page_debug(env, addr); + if (ret == -1) + { + fprintf(stderr, "cpu_get_phys_page_debug(env, %p) == %p\n", addr, ret); + fprintf(stderr, "not in phys mem %p (%p %p)\n", addr, env->tlb_table[is_user][index].addr_code, addr & TARGET_PAGE_MASK); + fprintf(stderr, "cpu_x86_handle_mmu_fault = %d\n", + cpu_x86_handle_mmu_fault(env, addr, 0, 1, 1)); + return NULL; + } + else + { + if (ret + TARGET_PAGE_SIZE <= phys_ram_size) + { + return phys_ram_base + ret + (((target_ulong)addr) & (TARGET_PAGE_SIZE - 1)); + } + else + { + fprintf(stderr, "cpu_get_phys_page_debug(env, %p) == %p\n", addr, ret); + fprintf(stderr, "ret=%p phys_ram_size=%p\n", ret, phys_ram_size); + return NULL; + } + } + } + else + { + return (void*)(addr + env->tlb_table[is_user][index].addend); + } +} + +#define MIN(a,b) (((a)<(b)) ? (a) : (b)) + +enum +{ + NOT_MAPPED, + MAPPED_CONTIGUOUS, + MAPPED_NOT_CONTIGUOUS +}; + +#define TARGET_ADDR_LOW_ALIGN(x) ((target_ulong)(x) & ~(TARGET_PAGE_SIZE - 1)) + +/* Return NOT_MAPPED if a page is not mapped into target physical memory */ +/* MAPPED_CONTIGUOUS if all pages are mapped into target physical memory and contiguous */ +/* MAPPED_NOT_CONTIGUOUS if all pages are mapped into target physical memory but not contiguous */ +static int get_target_mem_state(const CPUState *env, const void* target_addr, int len) +{ + void* aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr); + int to_end_page = (long)aligned_target_addr + TARGET_PAGE_SIZE - (long)target_addr; + int ret = MAPPED_CONTIGUOUS; + + if (aligned_target_addr != target_addr) + { + void* phys_addr = get_phys_mem_addr(env, aligned_target_addr); + void* last_phys_addr = phys_addr; + if (phys_addr == 0) + { + return NOT_MAPPED; + } + if (len > to_end_page) + { + len -= to_end_page; + aligned_target_addr += TARGET_PAGE_SIZE; + int i; + for(i=0;ivisual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + attr.override_redirect = 0; //fullscreen; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect; + + win = XCreateWindow( dpy, root, 0, 0, width, height, + 0, vis->depth, InputOutput, + vis->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetWMNormalHints(dpy, win, &sizehints); + XSetStandardProperties(dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + + /* + int loop = 1; + while (loop) { + while (XPending(dpy) > 0) { + XEvent event; + XNextEvent(dpy, &event); + switch (event.type) { + case CreateNotify: + { + if (((XCreateWindowEvent*)&event)->window == win) + { + loop = 0; + } + break; + } + } + } +}*/ + + return win; +} + + +typedef struct +{ + void* key; + void* value; +} Assoc; + + +#define MAX_HANDLED_PROCESS 100 +#define MAX_ASSOC_SIZE 100 + +typedef struct +{ + int process_id; + + int next_available_context_number; + + void* vertexPointer; + void* normalPointer; + void* colorPointer; + void* texCoordPointer; + int vertexPointerStride; + + int serverActiveTexture; + int clientActiveTexture; + int pointerArraysEnable[6]; + int texCoordPointerEnable[16]; + + Assoc association_fakecontext_glxcontext[MAX_ASSOC_SIZE]; + Assoc association_clientdrawable_serverdrawable[MAX_ASSOC_SIZE]; +} ProcessStruct; + +ProcessStruct processTab[MAX_HANDLED_PROCESS]; + +int last_process_id = 0; + +target_ulong args[50]; + + +#ifdef SYSTEMATIC_ERROR_CHECK +int last_error = 0; +#endif + + +#define ARG_TO_CHAR(x) (char)(x) +#define ARG_TO_UNSIGNED_CHAR(x) (unsigned char)(x) +#define ARG_TO_SHORT(x) (short)(x) +#define ARG_TO_UNSIGNED_SHORT(x) (unsigned short)(x) +#define ARG_TO_INT(x) (int)(x) +#define ARG_TO_UNSIGNED_INT(x) (unsigned int)(x) +#define ARG_TO_FLOAT(x) (*(float*)&(x)) +#define ARG_TO_DOUBLE(x) (*(double*)(x)) +#define ARG_TO_FLOAT16_ARRAY(x) (float*)(x) +#define ARG_TO_DOUBLE16_ARRAY(x) (double*)(x) + +#include "server_stub.c" + +int do_function_call(int func_number, int pid); + + +static const int attribDouble[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + None +}; + +void* get_association_fakecontext_glxcontext(ProcessStruct* process, void* fakecontext) +{ + int i; + for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) + { + if (process->association_fakecontext_glxcontext[i].key == fakecontext) + return process->association_fakecontext_glxcontext[i].value; + } + return NULL; +} +void set_association_fakecontext_glxcontext(ProcessStruct* process, void* fakecontext, void* glxcontext) +{ + int i; + for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) + { + if (process->association_fakecontext_glxcontext[i].key == fakecontext) + { + break; + } + } + if (i < MAX_ASSOC_SIZE) + { + process->association_fakecontext_glxcontext[i].key = fakecontext; + process->association_fakecontext_glxcontext[i].value = glxcontext; + } + else + { + fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); + } +} +void unset_association_fakecontext_glxcontext(ProcessStruct* process, void* fakecontext) +{ + int i; + for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) + { + if (process->association_fakecontext_glxcontext[i].key == fakecontext) + { + memmove(&process->association_fakecontext_glxcontext[i], + &process->association_fakecontext_glxcontext[i+1], + sizeof(Assoc) * (MAX_ASSOC_SIZE - 1 - i)); + return; + } + } +} + +void* get_association_clientdrawable_serverdrawable(ProcessStruct* process, void* clientdrawable) +{ + int i; + for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) + { + if (process->association_clientdrawable_serverdrawable[i].key == clientdrawable) + return process->association_clientdrawable_serverdrawable[i].value; + } + return NULL; +} +void* get_association_serverdrawable_clientdrawable(ProcessStruct* process, void* serverdrawable) +{ + int i; + for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) + { + if (process->association_clientdrawable_serverdrawable[i].value == serverdrawable) + return process->association_clientdrawable_serverdrawable[i].key; + } + return NULL; +} +void set_association_clientdrawable_serverdrawable(ProcessStruct* process, void* clientdrawable, void* serverdrawable) +{ + int i; + for(i=0;process->association_clientdrawable_serverdrawable[i].key != NULL;i++) + { + if (process->association_clientdrawable_serverdrawable[i].key == clientdrawable) + { + break; + } + } + if (i < MAX_ASSOC_SIZE) + { + process->association_clientdrawable_serverdrawable[i].key = clientdrawable; + process->association_clientdrawable_serverdrawable[i].value = serverdrawable; + } + else + { + fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); + } +} + +void display_client_server_state(ProcessStruct* process) +{ + int i; + printf("serverActiveTexture = %d\n", process->serverActiveTexture); + printf("clientActiveTexture = %d\n", process->clientActiveTexture); + for(i=0;i<6;i++) + { + if (i == 5) continue; + printf("pointerArraysEnable[%d] = %d\n", i, process->pointerArraysEnable[i]); + } + for(i=0;i<8;i++) + { + printf("texCoordPointerEnable[%d] = %d\n", i, process->texCoordPointerEnable[i]); + } +} + +int do_function_call(int func_number, int pid) +{ + char ret_char = 0; + int ret_int = 0; + void* ret_ptr = NULL; + const char* ret_str = NULL; + + int iProcess; + ProcessStruct* process = NULL; + for(iProcess=0;iProcessprocess_id = pid; + break; + } + } + if (process == NULL) + { + fprintf(stderr, "Too many processes !\n"); + return 0; + } + + //fprintf(stderr, "%s\n", tab_opengl_calls_name[func_number]); + + switch (func_number) + { + case _exit_process_func: + { + int i; + if (display_function_call) fprintf(stderr, "_exit_process\n"); + + for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) + { + GLXContext ctxt = process->association_fakecontext_glxcontext[i].value; + fprintf(stderr, "Destroy context corresponding to fake_context = %d\n", + process->association_fakecontext_glxcontext[i].key); + glXDestroyContext(dpy, ctxt); + } + + for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) + { + fprintf(stderr, "Destroy window corresponding to client_drawable = %p\n", + process->association_clientdrawable_serverdrawable[i].key); + + Window win = process->association_clientdrawable_serverdrawable[i].value; + XDestroyWindow(dpy, win); + + int loop = 1; + while (loop) { + while (XPending(dpy) > 0) { + XEvent event; + XNextEvent(dpy, &event); + switch (event.type) { + case DestroyNotify: + { + if (((XDestroyWindowEvent*)&event)->window == win) + { + loop = 0; + } + break; + } + } + } + } + } + + if (process->vertexPointer) free(process->vertexPointer); + if (process->normalPointer) free(process->normalPointer); + if (process->colorPointer) free(process->colorPointer); + if (process->texCoordPointer) free(process->texCoordPointer); + + memmove(&processTab[iProcess], &processTab[iProcess+1], (MAX_HANDLED_PROCESS - 1 - iProcess) * sizeof(ProcessStruct)); + + last_process_id = 0; + + break; + } + + case _changeWindowState_func: + { + GLXDrawable client_drawable = args[0]; + if (display_function_call) fprintf(stderr, "_changeWindowState_func client_drawable=%p\n", (void*)client_drawable); + + GLXDrawable drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); + if (drawable) + { + if (args[1] == IsViewable) + { + XMapWindow(dpy, drawable); + + int loop = 1; + while (loop) { + while (XPending(dpy) > 0) { + XEvent event; + XNextEvent(dpy, &event); + switch (event.type) { + case ConfigureNotify: + { + if (((XConfigureEvent*)&event)->window == drawable) + { + loop = 0; + } + break; + } + } + } + } + } + } + + break; + } + + case _moveResizeWindow_func: + { + GLXDrawable client_drawable = args[0]; + if (display_function_call) fprintf(stderr, "_moveResizeWindow client_drawable=%p\n", (void*)client_drawable); + + GLXDrawable drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); + if (drawable) + { + int* params = (int*)args[1]; + fprintf(stderr, "%d %d %d %d\n", params[0], params[1], params[2], params[3]); + XMoveResizeWindow(dpy, drawable, params[0], params[1], params[2], params[3]); + + int loop = 1; + while (loop) { + while (XPending(dpy) > 0) { + XEvent event; + XNextEvent(dpy, &event); + switch (event.type) { + case ConfigureNotify: + { + if (((XConfigureEvent*)&event)->window == drawable) + { + loop = 0; + } + break; + } + } + } + } + } + break; + } + + case _needSync_func: + { + if (display_function_call) fprintf(stderr, "_needSync\n"); + ret_int = 1; + break; + } + + case glXChooseVisual_func: + { + if (display_function_call) fprintf(stderr, "glXChooseVisual\n"); + ret_ptr = glXChooseVisual(dpy, 0, (void*)args[2]); + break; + } + + case glXQueryExtensionsString_func: + { + if (display_function_call) fprintf(stderr, "glXQueryExtensionsString\n"); + ret_str = glXQueryExtensionsString(dpy, 0); + break; + } + + case glXQueryServerString_func: + { + if (display_function_call) fprintf(stderr, "glXQueryServerString %d\n", args[2]); + ret_str = glXQueryServerString(dpy, 0, args[2]); + break; + } + + case glXGetClientString_func: + { + if (display_function_call) fprintf(stderr, "glXQueryServerString %d\n", args[1]); + ret_str = glXGetClientString(dpy, args[1]); + break; + } + + case glXCreateContext_func: + { + void* fake_shareList = args[2]; + if (1 || display_function_call) fprintf(stderr, "glXCreateContext fake_shareList=%p\n", fake_shareList); + + process->next_available_context_number ++; + void* fake_ctxt = (void*)process->next_available_context_number; + + GLXContext shareList = get_association_fakecontext_glxcontext(process, fake_shareList); + XVisualInfo* vis = get_visual(); + GLXContext ctxt = glXCreateContext(dpy, vis, shareList, args[3]); + set_association_fakecontext_glxcontext(process, fake_ctxt, ctxt); + + ret_ptr = fake_ctxt; + break; + } + + case glXGetCurrentContext_func: + { + if (display_function_call) fprintf(stderr, "glXGetCurrentContext\n"); + ret_ptr = get_association_fakecontext_glxcontext(process, glXGetCurrentContext()); + break; + } + + case glXGetCurrentDrawable_func: + { + if (display_function_call) fprintf(stderr, "glXGetCurrentDrawable\n"); + ret_ptr = get_association_serverdrawable_clientdrawable(process, glXGetCurrentDrawable()); + break; + } + + case glXDestroyContext_func: + { + GLXContext fake_ctxt = args[1]; + if (display_function_call) fprintf(stderr, "glXDestroyContext fake_ctxt=%p\n", fake_ctxt); + + GLXContext ctxt = get_association_fakecontext_glxcontext(process, fake_ctxt); + if (ctxt == NULL) + { + fprintf(stderr, "invalid fake_ctxt (%p) !\n", fake_ctxt); + } + else + { + glXDestroyContext(dpy, ctxt); + unset_association_fakecontext_glxcontext(process, fake_ctxt); + } + break; + } + + case glXQueryVersion_func: + { + if (display_function_call) fprintf(stderr, "glXQueryVersion\n"); + ret_int = glXQueryVersion(dpy, args[1], args[2]); + break; + } + + case glGetString_func: + { + if (display_function_call) fprintf(stderr, "glGetString %d\n", args[0]); + ret_str = (char*)glGetString(args[0]); + break; + } + + case glXMakeCurrent_func: + { + GLXDrawable client_drawable = args[1]; + GLXContext fake_ctxt = args[2]; + if (display_function_call) fprintf(stderr, "glXMakeCurrent client_drawable=%p fake_ctx=%p\n", (void*)client_drawable, fake_ctxt); + + if (client_drawable == NULL && fake_ctxt == NULL) + { + ret_int = glXMakeCurrent(dpy, NULL, NULL); + } + else + { + GLXContext ctxt = get_association_fakecontext_glxcontext(process, fake_ctxt); + GLXDrawable drawable; + if (ctxt == NULL) + { + fprintf(stderr, "invalid fake_ctxt (%p) !\n", fake_ctxt); + ret_int = 0; + } + else + { + drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); + if (drawable == NULL) + { + drawable = create_window("", 0, 0, 300, 300); + set_association_clientdrawable_serverdrawable(process, client_drawable, drawable); + } + + ret_int = glXMakeCurrent(dpy, drawable, ctxt); + } + } + break; + } + + case glXSwapBuffers_func: + { + GLXDrawable client_drawable = args[1]; + if (display_function_call) fprintf(stderr, "glXSwapBuffers client_drawable=%p\n", (void*)client_drawable); + + GLXDrawable drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); + if (drawable == 0) + { + fprintf(stderr, "unknown client_drawable (%p) !\n", client_drawable); + } + else + { + glXSwapBuffers(dpy, drawable); + } + break; + } + + case glXIsDirect_func: + { + GLXContext fake_ctxt = args[1]; + if (display_function_call) fprintf(stderr, "glXIsDirect fake_ctx=%p\n", fake_ctxt); + GLXContext ctxt = get_association_fakecontext_glxcontext(process, fake_ctxt); + if (ctxt == NULL) + { + fprintf(stderr, "invalid fake_ctxt (%p) !\n", fake_ctxt); + ret_char = False; + } + else + { + ret_char = glXIsDirect(dpy, ctxt); + } + break; + } + + case glXGetConfig_func: + { + if (display_function_call) fprintf(stderr, "glXGetConfig %d\n", args[2]); + ret_int = glXGetConfig(dpy, get_visual(), args[2], args[3]); + break; + } + + case glXUseXFont_func: + { + if (display_function_call) fprintf(stderr, "glXUseXFont\n"); + fprintf(stderr, "not implemented !\n"); + break; + } + + + case glXQueryExtension_func: + { + if (display_function_call) fprintf(stderr, "glXQueryExtension\n"); + ret_int = glXQueryExtension(dpy, args[1], args[2]); + break; + } + + case glXChooseFBConfig_func: + { + if (display_function_call) fprintf(stderr, "glXChooseFBConfig\n"); + fprintf(stderr, "not implemented !\n"); + ret_ptr = 0; + break; + } + + case glXCreatePbuffer_func: + { + if (display_function_call) fprintf(stderr, "glXCreatePbuffer\n"); + fprintf(stderr, "not implemented !\n"); + ret_ptr = NULL; + break; + } + + case glXGetVisualFromFBConfig_func: + { + if (display_function_call) fprintf(stderr, "glXGetVisualFromFBConfig\n"); + fprintf(stderr, "not implemented !\n"); + ret_ptr = NULL; + break; + } + + case glXGetProcAddress_fake_func: + { + if (display_function_call) fprintf(stderr, "glXGetProcAddress %s\n", args[0]); + ret_int = glXGetProcAddress(args[0]) != NULL; + break; + } + + case glFlush_func: + { + glFlush(); + break; + } + + case glGetIntegerv_func: + { + int param = args[0]; + if (display_function_call) fprintf(stderr, "glGetIntegerv %d\n", param); + glGetIntegerv(param, args[1]); + break; + } + + case glGetFloatv_func: + { + int param = args[0]; + if (display_function_call) fprintf(stderr, "glGetFloatv %d\n", param); + glGetIntegerv(param, args[1]); + break; + } + + case glGetConvolutionParameteriv_func: + { + if (display_function_call) fprintf(stderr, "glGetConvolutionParameteriv %d %d\n", args[0], args[1]); + glGetConvolutionParameteriv(args[0], args[1], args[2]); + break; + } + + case glLightfv_func: + { + if (display_function_call) fprintf(stderr, "glLightfv\n"); + glLightfv(args[0], args[1],(float*)args[2]); + break; + } + + case glMaterialfv_func: + { + if (display_function_call) fprintf(stderr, "glMaterialfv\n"); + glMaterialfv(args[0], args[1], (float*)args[2]); + break; + } + + case glLightModelfv_func: + { + if (display_function_call) fprintf(stderr, "glLightModelfv\n"); + glLightModelfv(args[0], (float*)args[1]); + break; + } + + case glMap1f_func: + { + if (display_function_call) fprintf(stderr, "glMap1f\n"); + glMap1f(args[0], + ARG_TO_FLOAT(args[1]), + ARG_TO_FLOAT(args[2]), + args[3], + args[4], + (float*)args[5]); + break; + } + + case glMap1d_func: + { + if (display_function_call) fprintf(stderr, "glMap1d\n"); + glMap1f(args[0], + ARG_TO_DOUBLE(args[1]), + ARG_TO_DOUBLE(args[2]), + args[3], + args[4], + (double*)args[5]); + break; + } + + case glMap2f_func: + { + if (display_function_call) fprintf(stderr, "glMap2f\n"); + glMap2f(args[0], + ARG_TO_FLOAT(args[1]), + ARG_TO_FLOAT(args[2]), + args[3], + args[4], + ARG_TO_FLOAT(args[5]), + ARG_TO_FLOAT(args[6]), + args[7], + args[8], + (float*)args[9]); + break; + } + + case glMap2d_func: + { + if (display_function_call) fprintf(stderr, "glMap2d\n"); + glMap2d(args[0], + ARG_TO_DOUBLE(args[1]), + ARG_TO_DOUBLE(args[2]), + args[3], + args[4], + ARG_TO_DOUBLE(args[5]), + ARG_TO_DOUBLE(args[6]), + args[7], + args[8], + (double*)args[9]); + break; + } + + case glGenTextures_func: + { + int nTextures = args[0]; + if (display_function_call) fprintf(stderr, "glGenTextures\n"); + glGenTextures(nTextures, args[1]); + break; + } + + case glDeleteTextures_func: + { + if (display_function_call) fprintf(stderr, "glDeleteTextures\n"); + glDeleteTextures(args[0], (int*)args[1]); + break; + } + + case glCallLists_func: + { + if (display_function_call) fprintf(stderr, "glCallLists\n"); + glCallLists(args[0], args[1], (void*)args[2]); + break; + } + + case glTexImage1D_func: + { + if (display_function_call) fprintf(stderr, "glTexImage1D\n"); + glTexImage1D(args[0], + args[1], + args[2], + args[3], + args[4], + args[5], + args[6], + (void*)args[7]); + break; + } + + case glTexImage2D_func: + { + if (display_function_call) fprintf(stderr, "glTexImage2D\n"); + glTexImage2D(args[0], + args[1], + args[2], + args[3], + args[4], + args[5], + args[6], + args[7], + (void*)args[8]); + break; + } + + case glTexSubImage2D_func: + { + if (display_function_call) fprintf(stderr, "glTexSubImage2D\n"); + glTexSubImage2D(args[0], + args[1], + args[2], + args[3], + args[4], + args[5], + args[6], + args[7], + (void*)args[8]); + break; + } + + case glCompressedTexImage2DARB_func: + { + if (display_function_call) fprintf(stderr, "glCompressedTexImage2DARB\n"); + GET_EXT_PTR(void, glCompressedTexImage2DARB, (int,int,int,int,int,int,int,void*)); + ptr_func(args[0], + args[1], + args[2], + args[3], + args[4], + args[5], + args[6], + (void*)args[7]); + break; + } + + case glCompressedTexSubImage2DARB_func: + { + if (display_function_call) fprintf(stderr, "glCompressedTexSubImage2DARB\n"); + GET_EXT_PTR(void, glCompressedTexSubImage2DARB, (int,int,int,int,int,int,int,void*)); + ptr_func (args[0], + args[1], + args[2], + args[3], + args[4], + args[5], + args[6], + (void*)args[7]); + break; + } + + case glGenProgramsARB_func: + { + if (display_function_call) fprintf(stderr, "glGenProgramsARB\n"); + GET_EXT_PTR(void, glGenProgramsARB, (int,int*)); + ptr_func(args[0], (int*)args[1]); + break; + } + + case glProgramStringARB_func: + { + if (display_function_call) fprintf(stderr, "glProgramStringARB\n"); + GET_EXT_PTR(void, glProgramStringARB, (int,int,int,void*)); + ptr_func(args[0], args[1], args[2], (void*)args[3]); + break; + } + + case glDeleteProgramsARB_func: + { + if (display_function_call) fprintf(stderr, "glDeleteProgramsARB\n"); + GET_EXT_PTR(void, glDeleteProgramsARB, (int,int*)); + ptr_func(args[0], (int*)args[1]); + break; + } + + case glShaderSourceARB_func: + { + if (display_function_call) fprintf(stderr, "glShaderSourceARB\n"); + GET_EXT_PTR(void, glShaderSourceARB, (int,int,char**,void*)); + ptr_func(args[0], 1, (char**)&args[1], NULL); + break; + } + + case glGetUniformLocationARB_func: + { + if (display_function_call) fprintf(stderr, "glGetUniformLocationARB\n"); + GET_EXT_PTR(int, glGetUniformLocationARB, (int,char*)); + ret_int = ptr_func(args[0], (char*)args[1]); + break; + } + + case glPointParameterfvARB_func: + { + if (display_function_call) fprintf(stderr, "glPointParameterfvARB\n"); + GET_EXT_PTR(void, glPointParameterfvARB, (int,float*)); + ptr_func(args[0], (float*)args[1]); + break; + } + + case glGetVertexAttribfvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetVertexAttribfvARB\n"); + GET_EXT_PTR(void, glGetVertexAttribfvARB, (int,int,float*)); + ptr_func(args[0], args[1], (float*)args[2]); + break; + } + + case glGetVertexAttribivARB_func: + { + if (display_function_call) fprintf(stderr, "glGetVertexAttribivARB\n"); + GET_EXT_PTR(void, glGetVertexAttribfvARB, (int,int,double*)); + ptr_func(args[0], args[1], (double*)args[2]); + break; + } + + case glGetVertexAttribdvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetVertexAttribdvARB\n"); + GET_EXT_PTR(void, glGetVertexAttribdvARB, (int,int,int*)); + ptr_func(args[0], args[1], (int*)args[2]); + break; + } + + case glGetProgramLocalParameterfvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetProgramLocalParameterfvARB\n"); + GET_EXT_PTR(void, glGetProgramLocalParameterfvARB, (int,int,float*)); + ptr_func(args[0], args[1], (float*)args[2]); + break; + } + + case glGetProgramLocalParameterdvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetProgramLocalParameterdvARB\n"); + GET_EXT_PTR(void, glGetProgramLocalParameterdvARB, (int,int,double*)); + ptr_func(args[0], args[1], (double*)args[2]); + break; + } + + case glGetProgramEnvParameterfvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetProgramEnvParameterfvARB\n"); + GET_EXT_PTR(void, glGetProgramEnvParameterfvARB, (int,int,float*)); + ptr_func(args[0], args[1], (float*)args[2]); + break; + } + + case glGetProgramEnvParameterdvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetProgramEnvParameterdvARB\n"); + GET_EXT_PTR(void, glGetProgramEnvParameterdvARB, (int,int,double*)); + ptr_func(args[0], args[1], (double*)args[2]); + break; + } + + case glGetProgramivARB_func: + { + if (display_function_call) fprintf(stderr, "glGetProgramivARB\n"); + GET_EXT_PTR(void, glGetProgramivARB, (int,int,int*)); + ptr_func(args[0], args[1], (int*)args[2]); + break; + } + + case glGetProgramStringARB_func: + { + assert(0); + /* + int len; + char* string; + { + GET_EXT_PTR(void, glGetProgramivARB, (int,int,int*)); + ptr_func(args[0], GL_PROGRAM_LENGTH_ARB, &len); + string = g_malloc(len); + } + if (display_function_call) fprintf(stderr, "glGetProgramStringARB\n"); + GET_EXT_PTR(void, glGetProgramStringARB, (int,int,void*)); + ptr_func(args[0], args[1], string); + len = strlen(string); + write_to_client(client, &len, sizeof(int)); + write_to_client(client, string, len); + g_free(string);*/ + break; + } + + case glTexImage3D_func: + { + if (display_function_call) fprintf(stderr, "glTexImage3D\n"); + glTexImage3D(args[0], + args[1], + args[2], + args[3], + args[4], + args[5], + args[6], + args[7], + args[8], + (void*)args[9]); + break; + } + + case glGetTexLevelParameteriv_func: + { + if (display_function_call) fprintf(stderr, "glGetTexLevelParameteriv\n"); + glGetTexLevelParameteriv(args[0], args[1], args[2], (int*)args[3]); + break; + } + + case glFogfv_func: + { + if (display_function_call) fprintf(stderr, "glFogfv\n"); + glFogfv(args[0], (float*)args[1]); + break; + } + + case glBitmap_func: + { + if (display_function_call) fprintf(stderr, "glBitmap\n"); + glBitmap (args[0], + args[1], + ARG_TO_FLOAT(args[2]), + ARG_TO_FLOAT(args[3]), + ARG_TO_FLOAT(args[4]), + ARG_TO_FLOAT(args[5]), + (void*)args[6]); + break; + } + + case glTexGenfv_func: + { + if (display_function_call) fprintf(stderr, "glTexGenfv\n"); + glTexGenfv(args[0], args[1], (float*)args[2]); + break; + } + + case glTexEnvfv_func: + { + if (display_function_call) fprintf(stderr, "glTexEnvfv\n"); + glTexEnvfv(args[0], args[1], (float*)args[2]); + break; + } + + case glTexParameterfv_func: + { + if (display_function_call) fprintf(stderr, "glTexParameterfv\n"); + glTexParameterfv(args[0], args[1], (float*)args[2]); + break; + } + + case glTexParameteriv_func: + { + if (display_function_call) fprintf(stderr, "glTexParameteriv\n"); + glTexParameteriv(args[0], args[1], (int*)args[2]); + break; + } + + case glVertexPointer_func: + { + if (display_function_call) fprintf(stderr, "glVertexPointer\n"); + if (process->vertexPointer) free(process->vertexPointer); + int size = args[3]; + process->vertexPointer = malloc(size); + memcpy(process->vertexPointer, args[4], size); + glVertexPointer(args[0], args[1], args[2], process->vertexPointer); + break; + } + + case glNormalPointer_func: + { + if (display_function_call) fprintf(stderr, "glNormalPointer\n"); + if (process->normalPointer) free(process->normalPointer); + int size = args[2]; + process->normalPointer = malloc(size); + memcpy(process->normalPointer, args[3], size); + glNormalPointer(args[0], args[1], process->normalPointer); + break; + } + + case glColorPointer_func: + { + if (display_function_call) fprintf(stderr, "glColorPointer\n"); + if (process->colorPointer) free(process->colorPointer); + int size = args[3]; + process->colorPointer = malloc(size); + memcpy(process->colorPointer, args[4], size); + glColorPointer(args[0], args[1], args[2], process->colorPointer); + + break; + } + + case glTexCoordPointer_func: + { + if (display_function_call) fprintf(stderr, "glTexCoordPointer\n"); + if (process->texCoordPointer) free(process->texCoordPointer); + int size = args[3]; + process->texCoordPointer = malloc(size); + memcpy(process->texCoordPointer, args[4], size); + glTexCoordPointer(args[0], args[1], args[2], process->texCoordPointer); + break; + } + + case glBegin_func: + { + //display_client_server_state(client); + glBegin(args[0]); + break; + } + + case glActiveTexture_func: + case glActiveTextureARB_func: + { + process->serverActiveTexture = args[0] - GL_TEXTURE0_ARB; + //printf("set server active texture %d\n", clientActiveTexture); + glActiveTexture(args[0]); + break; + } + + case glClientActiveTexture_func: + case glClientActiveTextureARB_func: + { + process->clientActiveTexture = args[0] - GL_TEXTURE0_ARB; + //printf("set client active texture %d\n", clientActiveTexture); + glClientActiveTexture(args[0]); + break; + } + + case glEnableClientState_func: + { + int num = args[0] - GL_VERTEX_ARRAY; + if (num == GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY) + { + //printf("enable texture %d\n", clientActiveTexture); + process->texCoordPointerEnable[process->clientActiveTexture] = 1; + } + else if (num >= 0 && num < 6) + { + //printf("enable feature %d\n", num); + process->pointerArraysEnable[num] = 1; + } + glEnableClientState(args[0]); + break; + } + + case glDisableClientState_func: + { + int num = args[0] - GL_VERTEX_ARRAY; + if (num == GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY) + { + //printf("disable texture %d\n", clientActiveTexture); + process->texCoordPointerEnable[process->clientActiveTexture] = 0; + } + else if (num >= 0 && num < 6) + { + //printf("disable feature %d\n", num); + process->pointerArraysEnable[num] = 0; + } + glDisableClientState(args[0]); + break; + } + + case glArrayElement_func: + { + if (display_function_call) fprintf(stderr, "glArrayElement\n"); + glArrayElement(args[0]); + break; + } + + case glDrawArrays_func: + { + if (display_function_call) fprintf(stderr, "glDrawArrays\n"); + //printf("glDrawArrays %d %d %d\n",args[0], args[1],args[2]); + glDrawArrays(args[0], args[1],args[2]); + break; + } + + case glDrawElements_func: + { + if (display_function_call) fprintf(stderr, "glDrawElements\n"); + glDrawElements(args[0], args[1],args[2],(void*)args[3]); + break; + } + + case glGetError_func: + { +#ifdef SYSTEMATIC_ERROR_CHECK + ret_int = last_error; +#else + ret_int = glGetError(); +#endif + break; + } + + default: + execute_func(func_number, &ret_int, &ret_char); + break; + } + +#ifdef SYSTEMATIC_ERROR_CHECK + if (funcNumber == glGetError_func) + { + last_error = 0; + } + else + { + last_error = glGetError(); + if (last_error != 0) + { + printf("error %s 0x%X\n", tab_opengl_calls_name[func_number], last_error); + } + } +#endif + + Signature* signature = (Signature*)tab_opengl_calls[func_number]; + int ret_type = signature->ret_type; + int nb_args = signature->nb_args; + switch(ret_type) + { + case TYPE_NONE: + break; + + case TYPE_CHAR: + case TYPE_UNSIGNED_CHAR: + ret_int = ret_char; + break; + + case TYPE_INT: + case TYPE_UNSIGNED_INT: + break; + + case TYPE_POINTER: + ret_int = ret_ptr; + break; + + case TYPE_VISUAL_INFO: + //memcpy(args[nb_args], ret_ptr, sizeof(XVisualInfo)); + XFree(ret_ptr); + break; + + case TYPE_CONST_CHAR: + { + strncpy(ret_string, ret_str, 32768); + break; + } + + default: + fprintf(stderr, "unexpected ret type : %d\n", ret_type); + exit(-1); + break; + } + + return ret_int; +} + +int doing_opengl = 0; +static int last_func_number = -1; + +static int decode_call_int(CPUState *env, int func_number, int pid, target_ulong target_ret_string, + target_ulong in_args, target_ulong in_args_size) +{ + Signature* signature = (Signature*)tab_opengl_calls[func_number]; + int ret_type = signature->ret_type; + int has_out_parameters = signature->has_out_parameters; + int nb_args = signature->nb_args; + int* args_type = signature->args_type; + int i; + int ret; + const int* args_size = NULL; + target_ulong saved_out_ptr[50]; + + if (last_func_number == _exit_process_func && func_number == _exit_process_func) + { + last_func_number = -1; + return 0; + } + + if (last_process_id == 0) + { + last_process_id = pid; + } + else if (last_process_id != pid) + { + fprintf(stderr, "damnit. I don't support (yet) opengl calls coming from // processes... Sorry !\n"); + return 0; + } + + if (dpy == NULL) + { + dpy = XOpenDisplay(NULL); + memset(processTab, 0, sizeof(processTab)); + ret_string = malloc(32768); + } + + reset_host_offset(); + + if (nb_args) + { + if (memcpy_target_to_host(env, args, in_args, sizeof(target_ulong) * nb_args) == 0) + { + fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid); + fprintf(stderr, "cannot get call parameters\n"); + return 0; + } + + args_size = (const int*)get_host_read_pointer(env, in_args_size, sizeof(int) * nb_args); + if (args_size == NULL) + { + fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid); + fprintf(stderr, "cannot get call parameters size\n"); + return 0; + } + } + + for(i=0;icr[3]); + if( ! (func_number >= 0 && func_number < GL_N_CALLS) ) + { + fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed\n"); + return 0; + } + if (func_number == glDrawElements_func) + { + fprintf(stderr, "entering call %s pid=%d\n", tab_opengl_calls_name[func_number], pid); + } + ret = decode_call_int(env, func_number, pid, target_ret_string, in_args, in_args_size); + if (func_number == glDrawElements_func) + { + fprintf(stderr, "leaving call %s pid=%d\n", tab_opengl_calls_name[func_number], pid); + } + return ret; +} + +void helper_opengl(CPUState *env) +{ + doing_opengl = 1; + env->regs[R_EAX] = decode_call(env, + env->regs[R_EAX], + env->regs[R_EBX], + env->regs[R_ECX], + env->regs[R_EDX], + env->regs[R_ESI]); + doing_opengl = 0; +} Les fichiers binaires qemu.ori/target-i386/libGL.so.1 et qemu/target-i386/libGL.so.1 sont différents. diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/target-i386/op.c qemu/target-i386/op.c --- qemu.ori/target-i386/op.c 2006-11-14 00:18:10.000000000 +0100 +++ qemu/target-i386/op.c 2006-11-14 21:46:24.000000000 +0100 @@ -132,6 +132,13 @@ static inline target_long lshift(target_ #endif +void helper_int99(void); + +void OPPROTO op_int99(void) +{ + helper_int99(); +} + /* operations with flags */ /* update flags with T0 and T1 (add/sub case) */ diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/target-i386/opengl_client.c qemu/target-i386/opengl_client.c --- qemu.ori/target-i386/opengl_client.c 1970-01-01 01:00:00.000000000 +0100 +++ qemu/target-i386/opengl_client.c 2006-11-14 21:46:24.000000000 +0100 @@ -0,0 +1,1956 @@ +/* + * Guest-side implementation of GL/GLX API. Replacement of standard libGL.so + * + * Copyright (c) 2006 Even Rouault + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* gcc -Wall -g opengl_client.c -shared -o libGL.so.1 */ + +#define _GNU_SOURCE +#define _XOPEN_SOURCE 600 +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define EXT_FUNC(x) x + +#define CHECK_PROC_WITH_RET(x) \ + static int detect = -1; \ + if (detect < 0) \ + { \ + detect = (glXGetProcAddress((const GLubyte *)#x) != NULL); \ + } \ + if (detect == 0) \ + { \ + fprintf(stderr, "Symbol " #x " not available in server libGL\n"); \ + return 0; \ + } + +#define CHECK_PROC(x) \ + static int detect = -1; \ + if (detect < 0) \ + { \ + detect = (glXGetProcAddress((const GLubyte *)#x) != NULL); \ + } \ + if (detect == 0) \ + { \ + fprintf(stderr, "Symbol " #x " not available in server libGL\n"); \ + return; \ + } + +#include "opengl_func.h" + +#include "glgetv_cst.h" + +typedef struct +{ + int size; + int type; + int stride; + const void* ptr; +} VertexNormalColorPointerStruct; + +static VertexNormalColorPointerStruct vertexPointer = {0}; +static VertexNormalColorPointerStruct normalPointer = {0}; +static VertexNormalColorPointerStruct colorPointer = {0}; +static VertexNormalColorPointerStruct texCoordPointer[16] = {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},}; +static int clientActiveTexture = 0; +static int pointerArraysEnable[6] = { 0 }; +static int texCoordPointerEnable[16] = { 0 }; + + +static struct sigaction old_action; +void sigsegv_handler(int signum, siginfo_t* info, void* ptr) +{ + struct ucontext* context = (struct ucontext*)ptr; + unsigned char* eip_ptr = context->uc_mcontext.gregs[REG_EIP]; + if (eip_ptr[0] == 0xCD && eip_ptr[1] == 0x99) + { + context->uc_mcontext.gregs[REG_EIP] += 2; + } + else + { + fprintf(stderr, "unhandled SIGSEGV\n"); + exit(-1); // FIXME + if (old_action.sa_flags & SA_SIGINFO) + { + old_action.sa_sigaction(signum, info, ptr); + } + else + { + old_action.sa_handler(signum); + } + } +} + +int call_opengl(int func_number, int pid, void* ret_string, void* args, void* args_size) +{ + __asm__ ("push %ebx"); + __asm__ ("push %ecx"); + __asm__ ("push %edx"); + __asm__ ("push %esi"); + __asm__ ("mov %0, %%eax"::"m"(func_number)); + __asm__ ("mov %0, %%ebx"::"m"(pid)); + __asm__ ("mov %0, %%ecx"::"m"(ret_string)); + __asm__ ("mov %0, %%edx"::"m"(args)); + __asm__ ("mov %0, %%esi"::"m"(args_size)); + __asm__ ("int $0x99"); + __asm__ ("pop %esi"); + __asm__ ("pop %edx"); + __asm__ ("pop %ecx"); + __asm__ ("pop %ebx"); +} + +static void do_opengl_call(int func_number, void* ret_ptr, ...); + +static int pid_fork = -1; +static int stop_now = 0; + +static void sigint_exit_process_func(int ignored) +{ + stop_now = 1; + if (pid_fork > 0) + { + call_opengl(_exit_process_func, pid_fork, NULL, NULL, NULL); + pid_fork = 0; + } + exit(0); +} + +static void real_sigint_exit_process_func(int ignored) +{ + call_opengl(_exit_process_func, getpid(), NULL, NULL, NULL); + exit(0); +} + + +static void do_init() +{ + static int init_done = 0; + if (init_done == 0) + { + init_done = 1; + + pid_fork = fork(); + if (pid_fork > 0) + { + struct sigaction action; + action.sa_sigaction = sigsegv_handler; + sigemptyset(&(action.sa_mask)); + action.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &action, &old_action); + + signal(SIGINT, sigint_exit_process_func); + signal(SIGKILL, sigint_exit_process_func); + signal(SIGQUIT, sigint_exit_process_func); + int status; + wait(&status); + if (pid_fork > 0) + { + call_opengl(_exit_process_func, pid_fork, NULL, NULL, NULL); + pid_fork = 0; + } + if (WIFEXITED(status)) + { + exit(WEXITSTATUS(status)); + } + else + { + exit(0); + } + } + + signal(SIGINT, real_sigint_exit_process_func); + + struct sigaction action; + action.sa_sigaction = sigsegv_handler; + sigemptyset(&(action.sa_mask)); + action.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &action, &old_action); + } +} + +static int try_to_put_into_phys_memory(void* addr, int len) +{ + int pagesize = getpagesize(); + int i; + void* aligned_addr = ((long)addr & (~(pagesize - 1))); + int to_end_page = (long)aligned_addr + pagesize - (long)addr; + char c = 0; + if (aligned_addr != addr) + { + c += ((char*)addr)[0]; + if (len <= to_end_page) + { + return c; + } + len -= to_end_page; + addr = aligned_addr + pagesize; + } + for(i=0;i= 0 && func_number < GL_N_CALLS) ) + { + fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed\n"); + return; + } + + Signature* signature = (Signature*)tab_opengl_calls[func_number]; + int ret_type = signature->ret_type; + int nb_args = signature->nb_args; + int* args_type = signature->args_type; + static long args[100] = {0}; + static int args_size[100]={0}; + static double args_double[100]={0}; + static char* ret_string = NULL; + int ret_int; + va_list list; + int i; + + do_init(); + + if (ret_string == NULL) + { + int pagesize = getpagesize(); + int nbPages = 32768 / pagesize; + posix_memalign(&ret_string, pagesize, 32768); + memset(ret_string, 0, 32768); + int ret = mlock(ret_string, 32768); + if (ret == -1) + { + fprintf(stderr, "errno = %d, ENOMEM=%d, EPERM=%d, EINVAL=%d\n", errno, ENOMEM, EPERM, EINVAL); + assert(0); + } + } + + //fprintf(stderr, "%s\n", tab_opengl_calls_name[func_number]); + + va_start(list, ret_ptr); + for(i=0;i= 0 && clientActiveTexture < 16); + } + else + if (func_number == glEnableClientState_func) + { + int num = (int)args[0] - GL_VERTEX_ARRAY; + if (num == GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY) + { + //printf("enable texture %d\n", clientActiveTexture); + texCoordPointerEnable[clientActiveTexture] = 1; + } + else + if (num >= 0 && num < 6) + { + //printf("enable feature %d\n", num); + pointerArraysEnable[num] = 1; + } + } + else if (func_number == glDisableClientState_func) + { + int num = (int)args[0] - GL_VERTEX_ARRAY; + if (num == GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY) + { + //printf("disable texture %d\n", clientActiveTexture); + texCoordPointerEnable[clientActiveTexture] = 0; + } + else + if (num >= 0 && num < 6) + { + //printf("disable feature %d\n", num); + pointerArraysEnable[num] = 0; + } + } + else if (func_number == glPushClientAttrib_func) + { + if ((int)args[0] & GL_CLIENT_VERTEX_ARRAY_BIT) + { + printf("save vertex array\n"); + } + } + + /* We set fake values into the pointers to avoid make QEMU crash */ + switch (func_number) + { + case glXQueryVersion_func: + { + int* ptr; + ptr = (int*)args[1]; + if (ptr) *ptr = 0; + ptr = (int*)args[2]; + if (ptr) *ptr = 0; + break; + } + + case glXGetConfig_func: + { + *(int*)args[3] = 0; + break; + } + + case glGetIntegerv_func: + { + int* ptr = (int*)args[1]; + int param = (int)args[0]; + i = 0; + while(limits[i].count) + { + if (limits[i].token == param) + { + memset(ptr, 0, limits[i].count * sizeof(int)); + break; + } + i++; + } + if (limits[i].count == 0) + { + fprintf(stderr, "unknown name for glGetIntegerv : %d\n", param); + } + args_size[1] = limits[i].count * sizeof(int); + break; + } + + case glGetFloatv_func: + { + float* ptr = (float*)args[1]; + int param = (int)args[0]; + i = 0; + while(limits[i].count) + { + if (limits[i].token == param) + { + memset(ptr, 0, limits[i].count * sizeof(float)); + break; + } + i++; + } + if (limits[i].count == 0) + { + fprintf(stderr, "unknown name for glGetFloatv : %d\n", param); + } + args_size[1] = limits[i].count * sizeof(float); + break; + } + + case glGetConvolutionParameteriv_func: + { + int* ptr = (int*)args[2]; + args_size[2] = (((int)args[1] == GL_CONVOLUTION_BORDER_COLOR) ? 4 : 1) * sizeof(int); + memset(ptr, 0, (((int)args[1] == GL_CONVOLUTION_BORDER_COLOR) ? 4 : 1) * sizeof(int)); + break; + } + + case glXQueryExtension_func: + { + int* ptr; + ptr = (int*)args[1]; + if (ptr) *ptr = 0; + ptr = (int*)args[2]; + if (ptr) *ptr = 0; + break; + } + + case glGenTextures_func: + { + assert(args[1]); + memset(args[1], 0, (int)args[0] * sizeof(int)); + args_size[1] = (int)args[0] * sizeof(int); + break; + } + + case glGetTexLevelParameteriv_func: + { + int* ptr = (int*)args[3]; + assert(ptr); + *ptr = 0; + break; + } + + case glGenProgramsARB_func: + { + assert(args[1]); + *(int*)args[1] = 0; + break; + } + + case glXChooseFBConfig_func: + { + assert(args[3]); + *(int*)args[3] = 0; + break; + } + + case glGetVertexAttribfvARB_func: + { + assert(args[2]); + memset(args[2], 0, (((int)args[1] == GL_CURRENT_VERTEX_ATTRIB_ARB) ? 4 : 1) * sizeof(float)); + args_size[2] = (((int)args[1] == GL_CURRENT_VERTEX_ATTRIB_ARB) ? 4 : 1) * sizeof(float); + break; + } + + case glGetVertexAttribivARB_func: + { + assert(args[2]); + memset(args[2], 0, (((int)args[1] == GL_CURRENT_VERTEX_ATTRIB_ARB) ? 4 : 1) * sizeof(int)); + args_size[2] = (((int)args[1] == GL_CURRENT_VERTEX_ATTRIB_ARB) ? 4 : 1) * sizeof(int); + break; + } + + case glGetVertexAttribdvARB_func: + { + assert(args[2]); + memset(args[2], 0, (((int)args[1] == GL_CURRENT_VERTEX_ATTRIB_ARB) ? 4 : 1) * sizeof(double)); + args_size[2] = (((int)args[1] == GL_CURRENT_VERTEX_ATTRIB_ARB) ? 4 : 1) * sizeof(double); + break; + } + + case glGetProgramLocalParameterfvARB_func: + { + assert(args[2]); + memset(args[2], 0, 4 * sizeof(float)); + args_size[2] = 4 * sizeof(float); + break; + } + + case glGetProgramLocalParameterdvARB_func: + { + assert(args[2]); + memset(args[2], 0, 4 * sizeof(double)); + args_size[2] = 4 * sizeof(double); + break; + } + + case glGetProgramEnvParameterfvARB_func: + { + assert(args[2]); + memset(args[2], 0, 4 * sizeof(float)); + args_size[2] = 4 * sizeof(float); + break; + } + + case glGetProgramEnvParameterdvARB_func: + { + assert(args[2]); + memset(args[2], 0, 4 * sizeof(double)); + args_size[2] = 4 * sizeof(double); + break; + } + + case glGetProgramivARB_func: + { + assert(args[2]); + memset(args[2], 0, sizeof(int)); + break; + } + + case glGetProgramStringARB_func: + { + int len; + assert(args[2]); + assert(0); // FIXME + /*read_from_sock(sock, &len, sizeof(int)); + read_from_sock(sock, args[2], len);*/ + } + + default: + break; + } + + if (signature->ret_type == TYPE_CONST_CHAR) + { + try_to_put_into_phys_memory(ret_string, 32768); + } + + // DO CALL + if (stop_now) + return; + + ret_int = call_opengl(func_number, getpid(), (signature->ret_type == TYPE_CONST_CHAR) ? ret_string : NULL, args, args_size); + + if (signature->ret_type == TYPE_UNSIGNED_INT || + signature->ret_type == TYPE_INT) + { + *(int*)ret_ptr = ret_int; + } + else if (signature->ret_type == TYPE_UNSIGNED_CHAR || + signature->ret_type == TYPE_CHAR) + { + *(char*)ret_ptr = ret_int; + } + else if (signature->ret_type == TYPE_POINTER) + { + *(void**)ret_ptr = (void*)ret_int; + } + else if (signature->ret_type == TYPE_CONST_CHAR) + { + char* ret_str = NULL; + if (func_number == glXQueryExtensionsString_func) + { + static char* glXQueryExtensionsString_ret = NULL; + if (glXQueryExtensionsString_ret) free(glXQueryExtensionsString_ret); + glXQueryExtensionsString_ret = ret_str = strdup(ret_string); + } + else if (func_number == glXQueryServerString_func) + { + static char* glXQueryServerString_ret[100] = {NULL}; + int name = (int)args[2]; + assert(name >= 0 && name < 100); + if (glXQueryServerString_ret[name]) free(glXQueryServerString_ret[name]); + glXQueryServerString_ret[name] = ret_str = strdup(ret_string); + } + else if (func_number == glXGetClientString_func) + { + static char* glXGetClientString_ret[100] = {NULL}; + int name = (int)args[1]; + assert(name >= 0 && name < 100); + if (glXGetClientString_ret[name]) free(glXGetClientString_ret[name]); + glXGetClientString_ret[name] = ret_str = strdup(ret_string); + } + else if (func_number == glGetString_func) + { + static char* glGetString_ret[10000] = {NULL}; + int name = (int)args[0]; + assert(name >= 0 && name < 10000); + if (glGetString_ret[name]) free(glGetString_ret[name]); + glGetString_ret[name] = ret_str = strdup(ret_string); + } + else + { + exit(-1); + } + *(char**)(ret_ptr) = ret_str; + } + + /*switch (func_number) + { + case glXChooseVisual_func: + { + Display* dpy = args[0]; + int screen = (int)args[1]; + + XVisualInfo temp, *vis; + long mask; + int n; + + mask = VisualScreenMask | VisualDepthMask | VisualClassMask; + temp.screen = screen; + temp.depth = DefaultDepth(dpy,screen); + temp.class = DefaultVisual(dpy,screen)->class; + temp.visualid = DefaultVisual(dpy,screen)->visualid; + mask |= VisualIDMask; + + vis = XGetVisualInfo( dpy, mask, &temp, &n ); + + *(void**)(ret_ptr) = vis; + break; + } + + default: + break; +}*/ +} + +void glGetIntegerv( GLenum pname, GLint *params ) +{ + do_opengl_call(glGetIntegerv_func, NULL, pname, params); +} + +void glGetFloatv( GLenum pname, GLfloat *params ) +{ + do_opengl_call(glGetFloatv_func, NULL, pname, params); +} + +const char *glXQueryExtensionsString( Display *dpy, int screen ) +{ + const char* ret = NULL; + do_opengl_call(glXQueryExtensionsString_func, &ret, dpy, screen); + return ret; +} + +XVisualInfo* glXChooseVisual( Display *dpy, int screen, + int *attribList ) +{ + XVisualInfo temp, *vis; + long mask; + int n; + + mask = VisualScreenMask | VisualDepthMask | VisualClassMask; + temp.screen = screen; + temp.depth = DefaultDepth(dpy,screen); + temp.class = DefaultVisual(dpy,screen)->class; + temp.visualid = DefaultVisual(dpy,screen)->visualid; + mask |= VisualIDMask; + + vis = XGetVisualInfo( dpy, mask, &temp, &n ); + + //do_opengl_call(glXChooseVisual_func, vis, dpy, screen, attribList); + + return vis; +} + +const char *glXQueryServerString( Display *dpy, int screen, int name ) +{ + const char* ret = NULL; + do_opengl_call(glXQueryServerString_func, &ret, dpy, screen, name); + return ret; +} + +const char *glXGetClientString( Display *dpy, int name ) +{ + const char* ret = NULL; + do_opengl_call(glXGetClientString_func, &ret, dpy, name); + return ret; +} + +GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis, + GLXContext shareList, Bool direct ) +{ + GLXContext ret = NULL; + do_opengl_call(glXCreateContext_func, &ret, dpy, vis, shareList, direct); + printf("glXCreateContext = %p\n", ret); + return ret; +} + +GLXContext glXGetCurrentContext (void) +{ + GLXContext ret = NULL; + do_opengl_call(glXGetCurrentContext_func, &ret); + printf("glXGetCurrentContext = %p\n", ret); + return ret; +} + +GLXDrawable glXGetCurrentDrawable (void) +{ + GLXDrawable ret = 0; + do_opengl_call(glXGetCurrentDrawable_func, &ret); + printf("glXGetCurrentDrawable = %p\n", (void*)ret); + return ret; +} + +void glXDestroyContext( Display *dpy, GLXContext ctx ) +{ + printf("glXDestroyContext %p\n", ctx); + do_opengl_call(glXDestroyContext_func, NULL, dpy, ctx); +} + +Bool glXQueryVersion( Display *dpy, int *maj, int *min ) +{ + Bool ret = False; + do_opengl_call(glXQueryVersion_func, &ret, dpy, maj, min); + return ret; +} + + +typedef struct +{ + int x; + int y; + int width; + int height; + int map_state; +} WindowPosStruct; + +static WindowPosStruct oldPos = {0}; + +static void _get_window_pos(Display *dpy, Window win, WindowPosStruct* pos) +{ + XWindowAttributes window_attributes_return; + Window child; + int x, y; + Window root = DefaultRootWindow(dpy); + XGetWindowAttributes(dpy, win, &window_attributes_return); + XTranslateCoordinates(dpy, win, root, 0, 0, &x, &y, &child); + /*printf("%d %d %d %d\n", x, y, + window_attributes_return.width, window_attributes_return.height);*/ + pos->x = x; + pos->y = y; + pos->width = window_attributes_return.width; + pos->height = window_attributes_return.height; + pos->map_state = window_attributes_return.map_state; +} + +static GLXPbuffer pbuffer = NULL; + +static void _move_win_if_necessary(Display *dpy, Window win) +{ + if (pbuffer != NULL && win == pbuffer) + { + return; + } + + WindowPosStruct pos; + _get_window_pos(dpy, win, &pos); + if (memcmp(&pos, &oldPos, sizeof(oldPos)) != 0) + { + if (pos.map_state != oldPos.map_state) + { + do_opengl_call(_changeWindowState_func, NULL, win, pos.map_state); + } + memcpy(&oldPos, &pos, sizeof(oldPos)); + do_opengl_call(_moveResizeWindow_func, NULL, win, &pos); + } +} + +Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx) +{ + Bool ret = False; + do_opengl_call(glXMakeCurrent_func, &ret, dpy, drawable, ctx); + _move_win_if_necessary(dpy, drawable); + return ret; +} + + +Bool glXIsDirect( Display *dpy, GLXContext ctx ) +{ + Bool ret = False; + do_opengl_call(glXIsDirect_func, &ret, dpy, ctx); + return ret; +} + +int glXGetConfig( Display *dpy, XVisualInfo *visual, + int attrib, int *value ) +{ + int ret = 0; + do_opengl_call(glXGetConfig_func, &ret, dpy, visual, attrib, value); + return ret; +} + +void glXSwapBuffers( Display *dpy, GLXDrawable drawable ) +{ + _move_win_if_necessary(dpy, drawable); + do_opengl_call(glXSwapBuffers_func, NULL, dpy, drawable); +} + +Bool glXQueryExtension( Display *dpy, + int *errorBase, + int *eventBase ) +{ + Bool ret; + do_opengl_call(glXQueryExtension_func, &ret, dpy, errorBase, eventBase); + return ret; +} + +void glXWaitGL (void) +{ +} + +void glXWaitX (void) +{ +} + +#if 0 +GLXFBConfig* fbConfig = NULL; + +GLXFBConfig *glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ) +{ + GLXFBConfig * ret = NULL; + do_opengl_call(glXChooseFBConfig_func, &ret, dpy, screen, attribList, nitems); + fbConfig = ret = malloc(sizeof(GLXFBConfig) * (*nitems)); + int i; + for(i=0;i<*nitems;i++) + { + fbConfig[i] = i + 1; + } + printf("nitems = %d\n", *nitems); + return ret; +} + +GLXPbuffer glXCreatePbuffer(Display *dpy, + GLXFBConfig config, + const int *AttributeList) +{ + GLXPbuffer ret = NULL; + int i = (int)config - 1; + printf("fb config %d\n", i); + do_opengl_call(glXCreatePbuffer_func, &ret, dpy, i, AttributeList); + printf("pbuffer = %p\n", ret); + pbuffer = ret; + return ret; +} + +XVisualInfo *glXGetVisualFromFBConfig( Display *dpy, + GLXFBConfig config ) +{ + int screen = 0; + + XVisualInfo temp, *vis; + long mask; + int n; + + mask = VisualScreenMask | VisualDepthMask | VisualClassMask; + temp.screen = screen; + temp.depth = DefaultDepth(dpy,screen); + temp.class = DefaultVisual(dpy,screen)->class; + temp.visualid = DefaultVisual(dpy,screen)->visualid; + mask |= VisualIDMask; + + vis = XGetVisualInfo( dpy, mask, &temp, &n ); + + int i = (int)config - 1; + do_opengl_call(glXGetVisualFromFBConfig_func, vis, dpy, i); + + return vis; + +} + +void glXUseXFont( Font font_id, int first, int count, int list ) +{ + fprintf(stderr, "glXUseXFont : unsupported call\n"); + //do_opengl_call(glXUseXFont_func, NULL, font, first, count, list); +} +#endif + +#include "client_stub.c" + +const GLubyte * glGetString( GLenum name ) +{ + const GLubyte* ret = NULL; + do_opengl_call(glGetString_func, &ret, name); + return ret; +} + +void glGetConvolutionParameteriv( GLenum target, GLenum pname, + GLint *params ) +{ + do_opengl_call(glGetConvolutionParameteriv_func, NULL, target, pname, params); +} + +void glLightfv( GLenum light, GLenum pname, const GLfloat *params ) +{ + int size = 0; + switch(pname) + { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + case GL_POSITION: + size = 4; + break; + + case GL_SPOT_DIRECTION: + size = 3; + break; + + case GL_SPOT_EXPONENT: + case GL_SPOT_CUTOFF: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: + size = 1; + break; + + default: + fprintf(stderr, "unhandled pname = %d\n", pname); + return; + } + do_opengl_call(glLightfv_func, NULL, light, pname, size, params); +} + +void glMaterialfv( GLenum face, GLenum pname, const GLfloat *params ) +{ + int size = 0; + switch(pname) + { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + case GL_EMISSION: + case GL_AMBIENT_AND_DIFFUSE: + size = 4; + break; + + case GL_SHININESS: + size = 1; + break; + + case GL_COLOR_INDEXES: + size = 3; + break; + + default: + fprintf(stderr, "unhandled pname = %d\n", pname); + return; + } + do_opengl_call(glMaterialfv_func, NULL, face, pname, size, params); +} + +void glLightModelfv( GLenum pname, + const GLfloat *params ) +{ + int size = 0; + switch(pname) + { + case GL_LIGHT_MODEL_AMBIENT: + size = 4; + break; + + case GL_LIGHT_MODEL_COLOR_CONTROL: + fprintf(stderr, "not sure how to handle GL_LIGHT_MODEL_COLOR_CONTROL. Exiting\n"); + return; + + case GL_LIGHT_MODEL_LOCAL_VIEWER: + case GL_LIGHT_MODEL_TWO_SIDE: + size = 1; + break; + + default: + fprintf(stderr, "unhandled pname = %d\n", pname); + return; + } + do_opengl_call(glLightModelfv_func, NULL, pname, size, params); +} + +static int glMap1_get_multiplier(GLenum target) +{ + switch (target) + { + case GL_MAP1_VERTEX_3: + case GL_MAP1_NORMAL: + case GL_MAP1_TEXTURE_COORD_3: + return 3; + break; + + case GL_MAP1_VERTEX_4: + case GL_MAP1_COLOR_4: + case GL_MAP1_TEXTURE_COORD_4: + return 4; + break; + + case GL_MAP1_INDEX: + case GL_MAP1_TEXTURE_COORD_1: + return 1; + break; + + case GL_MAP1_TEXTURE_COORD_2: + return 2; + break; + + default: + fprintf(stderr, "unhandled target = %d\n", target); + return 0; + } +} + +void glMap1f( GLenum target, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat *points ) +{ + int num_points = order; + int multiplier = glMap1_get_multiplier(target); + if (multiplier) + { + num_points *= multiplier; + do_opengl_call(glMap1f_func, NULL, + target, u1, u2, stride, order, num_points, points); + } +} + +void glMap1d( GLenum target, + GLdouble u1, + GLdouble u2, + GLint stride, + GLint order, + const GLdouble *points ) +{ + int num_points = order; + int multiplier = glMap1_get_multiplier(target); + if (multiplier) + { + num_points *= multiplier; + do_opengl_call(glMap1d_func, NULL, + target, u1, u2, stride, order, num_points, points); + } +} + +static int glMap2_get_multiplier(GLenum target) +{ + switch (target) + { + case GL_MAP2_VERTEX_3: + case GL_MAP2_NORMAL: + case GL_MAP2_TEXTURE_COORD_3: + return 3; + break; + + case GL_MAP2_VERTEX_4: + case GL_MAP2_COLOR_4: + case GL_MAP2_TEXTURE_COORD_4: + return 4; + break; + + case GL_MAP2_INDEX: + case GL_MAP2_TEXTURE_COORD_1: + return 1; + break; + + case GL_MAP2_TEXTURE_COORD_2: + return 2; + break; + + default: + fprintf(stderr, "unhandled target = %d\n", target); + return 0; + } +} + +void glMap2f( GLenum target, + GLfloat u1, + GLfloat u2, + GLint ustride, + GLint uorder, + GLfloat v1, + GLfloat v2, + GLint vstride, + GLint vorder, + const GLfloat *points ) +{ + int num_points = uorder * vorder; + int multiplier = glMap2_get_multiplier(target); + if (multiplier) + { + num_points *= multiplier; + do_opengl_call(glMap2f_func, NULL, + target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, num_points, points); + } +} + + +void glMap2d( GLenum target, + GLdouble u1, + GLdouble u2, + GLint ustride, + GLint uorder, + GLdouble v1, + GLdouble v2, + GLint vstride, + GLint vorder, + const GLdouble *points ) +{ + int num_points = uorder * vorder; + int multiplier = glMap2_get_multiplier(target); + if (multiplier) + { + num_points *= multiplier; + do_opengl_call(glMap2d_func, NULL, + target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, num_points, points); + } +} + +void glGenTextures( GLsizei n, GLuint *textures ) +{ + do_opengl_call(glGenTextures_func, NULL, n, textures); +} + +void glDeleteTextures ( GLsizei n, const GLuint *textures ) +{ + do_opengl_call(glDeleteTextures_func, NULL, n, n, textures); +} + +void glCallLists( GLsizei n, + GLenum type, + const GLvoid *lists ) +{ + int size = n; + switch(type) + { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + break; + + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_2_BYTES: + size *= 2; + break; + + case GL_3_BYTES: + size *= 3; + break; + + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + case GL_4_BYTES: + size *= 4; + break; + + default: + fprintf(stderr, "unsupported type = %d\n", type); + return; + } + do_opengl_call(glCallLists_func, NULL, n, type, size, lists); +} + +void EXT_FUNC(glGenProgramsARB) (GLsizei n, GLuint* programs) +{ + CHECK_PROC(glGenProgramsARB); + do_opengl_call(glGenProgramsARB_func, NULL, n, programs); +} + +void EXT_FUNC(glDeleteProgramsARB) (GLsizei n, const GLuint *programs) +{ + CHECK_PROC(glDeleteProgramsARB); + do_opengl_call(glDeleteProgramsARB_func, NULL, n, programs); +} + +void EXT_FUNC(glProgramStringARB) (GLenum a, GLenum b, GLsizei c, const GLvoid *d) +{ + CHECK_PROC(glProgramStringARB); + do_opengl_call(glProgramStringARB_func, NULL, a, b, c, c, d); +} + +void EXT_FUNC(glShaderSourceARB) (GLhandleARB handle , GLsizei size, const GLcharARB* *p_tab_prog, const GLint * d) +{ + CHECK_PROC(glShaderSourceARB); + if (size == 1 && d == NULL && p_tab_prog != NULL) + { + do_opengl_call(glShaderSourceARB_func, NULL, handle, *p_tab_prog); + } + else + { + fprintf(stderr, "Unsupported parameters for glShaderSourceARB\n"); + } +} + +GLint EXT_FUNC(glGetUniformLocationARB) (GLhandleARB handle, const GLcharARB *txt) +{ + int ret; + CHECK_PROC_WITH_RET(glGetUniformLocationARB); + do_opengl_call(glGetUniformLocationARB_func, &ret, handle, txt); + return ret; +} + +void EXT_FUNC(glCompressedTexImage2DARB)(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid * data) +{ + CHECK_PROC(glCompressedTexImage2DARB); + do_opengl_call(glCompressedTexImage2DARB_func, NULL, + target, level, internalformat, width, height, border, imageSize, imageSize, data); +} + + +void EXT_FUNC(glCompressedTexSubImage2DARB)(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const GLvoid * data) +{ + CHECK_PROC(glCompressedTexSubImage2DARB); + do_opengl_call(glCompressedTexSubImage2DARB_func, NULL, + target, level, xoffset, yoffset, width, height, format, imageSize, imageSize, data); +} + +void EXT_FUNC(glPointParameterfvARB)(GLenum pname, const GLfloat * params) +{ + int size; + CHECK_PROC(glPointParameterfvARB); + size = (pname == GL_POINT_DISTANCE_ATTENUATION) ? 3 : 1; + do_opengl_call(glPointParameterfvARB_func, NULL, pname, size, params); +} + +void EXT_FUNC(glGetVertexAttribfvARB)(GLuint index, GLenum pname, GLfloat *params) +{ + CHECK_PROC(glGetVertexAttribfvARB); + do_opengl_call(glGetVertexAttribfvARB_func, NULL, index, pname, params); +} + +void EXT_FUNC(glGetVertexAttribivARB)(GLuint index, GLenum pname, GLint *params) +{ + CHECK_PROC(glGetVertexAttribivARB); + do_opengl_call(glGetVertexAttribivARB_func, NULL, index, pname, params); +} + +void EXT_FUNC(glGetVertexAttribdvARB)(GLuint index, GLenum pname, GLdouble *params) +{ + CHECK_PROC(glGetVertexAttribdvARB); + do_opengl_call(glGetVertexAttribdvARB_func, NULL, index, pname, params); +} + +void EXT_FUNC(glGetProgramLocalParameterfvARB) (GLenum target, GLuint index, GLfloat *params) +{ + CHECK_PROC(glGetProgramLocalParameterfvARB); + do_opengl_call(glGetProgramLocalParameterfvARB_func, NULL, target, index, params); +} + +void EXT_FUNC(glGetProgramLocalParameterdvARB) (GLenum target, GLuint index, GLdouble *params) +{ + CHECK_PROC(glGetProgramLocalParameterdvARB); + do_opengl_call(glGetProgramLocalParameterdvARB_func, NULL, target, index, params); +} + +void EXT_FUNC(glGetProgramEnvParameterfvARB) (GLenum target, GLuint index, GLfloat *params) +{ + CHECK_PROC(glGetProgramEnvParameterfvARB); + do_opengl_call(glGetProgramEnvParameterfvARB_func, NULL, target, index, params); +} + +void EXT_FUNC(glGetProgramEnvParameterdvARB) (GLenum target, GLuint index, GLdouble *params) +{ + CHECK_PROC(glGetProgramEnvParameterdvARB); + do_opengl_call(glGetProgramEnvParameterdvARB_func, NULL, target, index, params); +} + +void EXT_FUNC(glGetProgramivARB) (GLenum target, GLenum pname, GLint *params) +{ + CHECK_PROC(glGetProgramivARB); + do_opengl_call(glGetProgramivARB_func, NULL, target, pname, params); +} + +void EXT_FUNC(glGetProgramStringARB) (GLenum target, GLenum pname, GLvoid *string) +{ + CHECK_PROC(glGetProgramStringARB); + do_opengl_call(glGetProgramStringARB_func, NULL, target, pname, string); +} + +static int getTexImageFactorFromFormat(int format) +{ + switch (format) + { + case GL_COLOR_INDEX: + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + return 1; + break; + + case GL_LUMINANCE_ALPHA: + return 2; + break; + + case GL_RGB: + case GL_BGR: + return 3; + break; + + case GL_RGBA: + case GL_BGRA: + return 4; + break; + + default: + fprintf(stderr, "unknown texture format : %d\n", format); + return 0; + } +} + +void glTexImage1D(GLenum target, + GLint level, + GLint internalFormat, + GLsizei width, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels ) +{ + int size = width * getTexImageFactorFromFormat(format); + + if (type != GL_UNSIGNED_BYTE) + { + fprintf(stderr, "unknown pixel type : %d\n", type); + return; + } + + if (pixels == NULL) size = 0; + do_opengl_call(glTexImage1D_func, NULL, target, level, internalFormat, width, border, format, type, size, pixels); + +} + +void glTexImage2D( GLenum target, + GLint level, + GLint internalFormat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels ) +{ + int size = width * height * getTexImageFactorFromFormat(format); + + if (type != GL_UNSIGNED_BYTE) + { + fprintf(stderr, "unknown pixel type : %d\n", type); + return; + } + + if (pixels == NULL) size = 0; + do_opengl_call(glTexImage2D_func, NULL, target, level, internalFormat, width, height, border, format, type, size, pixels); +} + +void glTexSubImage2D( GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const GLvoid *pixels ) +{ + int size = width * height * getTexImageFactorFromFormat(format); + + if (type != GL_UNSIGNED_BYTE) + { + fprintf(stderr, "unknown pixel type : %d\n", type); + return; + } + + do_opengl_call(glTexSubImage2D_func, NULL, target, level, xoffset, yoffset, width, height, format, type, size, pixels); +} + +void glTexImage3D( GLenum target, + GLint level, + GLint internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels ) +{ + int size = width * height * depth * getTexImageFactorFromFormat(format); + + if (type != GL_UNSIGNED_BYTE) + { + fprintf(stderr, "unknown pixel type : %d\n", type); + return; + } + + do_opengl_call(glTexImage3D_func, NULL, target, level, internalFormat, width, height, depth, border, format, type, size, pixels); +} + +void glGetTexLevelParameteriv( GLenum target, + GLint level, + GLenum pname, + GLint *params ) +{ + do_opengl_call(glGetTexLevelParameteriv_func, NULL, target, level, pname, params); +} + +void glTexParameterfv( GLenum target, + GLenum pname, + const GLfloat *params ) +{ + int size = (pname == GL_TEXTURE_BORDER_COLOR) ? 4 : 1; + do_opengl_call(glTexParameterfv_func, NULL, target, pname, size, params); +} + +void glTexParameteriv( GLenum target, + GLenum pname, + const GLint *params ) +{ + int size = (pname == GL_TEXTURE_BORDER_COLOR) ? 4 : 1; + do_opengl_call(glTexParameteriv_func, NULL, target, pname, size, params); +} + +void glFogfv( GLenum pname, const GLfloat *params ) +{ + int size; + if (pname == GL_FOG_COLOR) + size = 4; + else + size = 1; + do_opengl_call(glFogfv_func, NULL, pname, size, params); +} + +void glBitmap(GLsizei width, + GLsizei height, + GLfloat xorig, + GLfloat yorig, + GLfloat xmove, + GLfloat ymove, + const GLubyte *bitmap ) +{ + int size = width * height; + //printf("bitmap %d %d %d\n", width, height, size); + do_opengl_call(glBitmap_func, NULL, width, height, xorig, yorig, xmove, ymove, size, bitmap); +} + +void glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) +{ + int size = (pname == GL_TEXTURE_GEN_MODE) ? 1 : 4; + do_opengl_call(glTexGenfv_func, NULL, coord, pname, size, params); +} + +void glTexEnvfv( GLenum target, + GLenum pname, + const GLfloat *params ) +{ + int size = (pname == GL_TEXTURE_ENV_MODE) ? 1 : 4; + do_opengl_call(glTexEnvfv_func, NULL, target, pname, size, params); +} + +void glVertexPointer( GLint size, + GLenum type, + GLsizei stride, + const GLvoid *ptr ) +{ + //printf("glVertexPointer %d %d %d %p\n", size, type, stride, ptr); + vertexPointer.size = size; + vertexPointer.type = type; + vertexPointer.stride = stride; + vertexPointer.ptr = ptr; +} + +void glNormalPointer( GLenum type, + GLsizei stride, + const GLvoid *ptr ) +{ + //printf("glNormalPointer %d %d %p\n", type, stride, ptr); + normalPointer.size = 3; + normalPointer.type = type; + normalPointer.stride = stride; + normalPointer.ptr = ptr; +} + +void glColorPointer( GLint size, + GLenum type, + GLsizei stride, + const GLvoid *ptr ) +{ + //printf("glColorPointer %d %d %d %p\n", size, type, stride, ptr); + colorPointer.size = size; + colorPointer.type = type; + colorPointer.stride = stride; + colorPointer.ptr = ptr; +} + +void glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) +{ + //printf("glTexCoordPointer %d %d %d %p\n", size, type, stride, ptr); + texCoordPointer[clientActiveTexture].size = size; + texCoordPointer[clientActiveTexture].type = type; + texCoordPointer[clientActiveTexture].stride = stride; + texCoordPointer[clientActiveTexture].ptr = ptr; +} + +static int getMulFactorFromPointerArray(VertexNormalColorPointerStruct* array) +{ + switch(array->type) + { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + return array->stride + array->size; + break; + + case GL_SHORT: + case GL_UNSIGNED_SHORT: + return array->stride + 2 * array->size; + break; + + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + return array->stride + 4 * array->size; + break; + + case GL_DOUBLE: + return array->stride + 8 * array->size; + break; + + default: + fprintf(stderr, "unsupported type = %d\n", array->type); + return 0; + } +} + +void _glArraySend(int func, VertexNormalColorPointerStruct* array, int nbElts) +{ + int data_size = nbElts * getMulFactorFromPointerArray(array); + if (func == glNormalPointer_func) + do_opengl_call(func, NULL, + array->type, array->stride, data_size, data_size, array->ptr); + else + do_opengl_call(func, NULL, + array->size, array->type, array->stride, data_size, data_size, array->ptr); +} + + +void _glArraysSend(int nbElts) +{ + if (pointerArraysEnable[GL_VERTEX_ARRAY - GL_VERTEX_ARRAY]) + { + //printf("vertex enable\n"); + _glArraySend(glVertexPointer_func, &vertexPointer, nbElts); + } + + if (pointerArraysEnable[GL_NORMAL_ARRAY - GL_VERTEX_ARRAY]) + { + //printf("normal enable\n"); + _glArraySend(glNormalPointer_func, &normalPointer, nbElts); + } + + if (pointerArraysEnable[GL_COLOR_ARRAY - GL_VERTEX_ARRAY]) + { + //printf("color enable\n"); + _glArraySend(glColorPointer_func, &colorPointer, nbElts); + } + + //if (pointerArraysEnable[GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY]) + if (texCoordPointerEnable[clientActiveTexture]) + { + printf("texture enable\n"); + _glArraySend(glTexCoordPointer_func, &texCoordPointer[clientActiveTexture], nbElts); + } +} + +void glDrawArrays( GLenum mode, + GLint first, + GLsizei count ) +{ + _glArraysSend(first + count); + do_opengl_call(glDrawArrays_func, NULL, mode, first, count); +} + + +void glDrawElements( GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices ) +{ + int i; + int size = count; + int maxIndice = -1; + + if (count == 0) return; + + switch(type) + { + case GL_UNSIGNED_BYTE: + { + unsigned char* c = indices; + for(i=0;i maxIndice) maxIndice = c[i]; + } + break; + } + + case GL_UNSIGNED_SHORT: + { + size *= 2; + unsigned short* s = indices; + for(i=0;i maxIndice) maxIndice = s[i]; + } + break; + } + + case GL_UNSIGNED_INT: + { + size *= 4; + unsigned int* _int = indices; + for(i=0;i maxIndice) maxIndice = _int[i]; + } + break; + } + + default: + fprintf(stderr, "unsupported type = %d\n", type); + return; + } + + //printf("glDrawElements : %d %d %d %p %d\n", mode, count, type, indices, maxIndice); + +#if 0 + do_opengl_call(glBegin_func, NULL, mode); + if (type == GL_UNSIGNED_INT) + { + for(i=0;i void glShaderSourceARB (GLhandleARB handle , const GLcharARB* prog) */ +static const int glShaderSourceARB_signature[] = { TYPE_NONE, 0, 2, TYPE_INT, TYPE_NULL_TERMINATED_STRING }; + +/* GLint glGetUniformLocationARB (GLhandleARB handle, const GLcharARB *txt) */ +static const int glGetUniformLocationARB_signature[] = { TYPE_INT, 0, 2, TYPE_INT, TYPE_NULL_TERMINATED_STRING }; + +/* void EXT_FUNC(glGetVertexAttribfvARB)(GLuint index, GLenum pname, GLfloat *params) */ +static const int glGetVertexAttribfvARB_signature[] = { TYPE_NONE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_FLOAT_ARRAY }; +static const int glGetVertexAttribivARB_signature[] = { TYPE_NONE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_INT_ARRAY }; +static const int glGetVertexAttribdvARB_signature[] = { TYPE_NONE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_DOUBLE_ARRAY }; + +/* void EXT_FUNC(glGetProgramLocalParameterfvARB) (GLenum target, GLuint index, GLfloat *params) */ +static const int glGetProgramLocalParameterfvARB_signature[] = { TYPE_NONE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_FLOAT_ARRAY }; +static const int glGetProgramLocalParameterdvARB_signature[] = { TYPE_NONE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_DOUBLE_ARRAY }; +static const int glGetProgramEnvParameterfvARB_signature[] = { TYPE_NONE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_FLOAT_ARRAY }; +static const int glGetProgramEnvParameterdvARB_signature[] = { TYPE_NONE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_DOUBLE_ARRAY }; + +/* void EXT_FUNC(glGetProgramivARB) (GLenum target, GLenum pname, GLint *params) */ +static const int glGetProgramivARB_signature[] = { TYPE_NONE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_INT_POINTER }; + +/* void EXT_FUNC(glGetProgramStringARB) (GLenum target, GLenum pname, GLvoid *string) */ +static const int glGetProgramStringARB_signature[] = { TYPE_NONE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_CHAR_ARRAY }; + +/*void glVertexPointer( GLint size, + GLenum type, + GLsizei stride, + const GLvoid *ptr )*/ +static const int glVertexPointer_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; +static const int glNormalPointer_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; +static const int glColorPointer_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; +static const int glTexCoordPointer_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; +static const int glDrawArrays_signature[] = { TYPE_NONE, 0, 3, TYPE_INT, TYPE_INT, TYPE_INT }; + +/*void glDrawElements( GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices )*/ +static const int glDrawElements_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; + +#include "gl_func.h" diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/target-i386/parse_gl_h.c qemu/target-i386/parse_gl_h.c --- qemu.ori/target-i386/parse_gl_h.c 1970-01-01 01:00:00.000000000 +0100 +++ qemu/target-i386/parse_gl_h.c 2006-11-14 21:54:22.000000000 +0100 @@ -0,0 +1,645 @@ +/* + * Parse gl.h et glx.h to auto-generate source code + * + * Copyright (c) 2006 Even Rouault + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* gcc parse_gl_h.c -o parse_gl_h && ./parse_gl_h */ +#include +#include +#include + +int isExt(const char* name) +{ + return (strstr(name, "ARB") != NULL) || + (strstr(name, "EXT") != NULL) || + (strstr(name, "ATI") != NULL) || + (strstr(name, "NV") != NULL) || + (strstr(name, "MESA") != NULL) || + (strstr(name, "SGI") != NULL); +} + +char* get_arg_type(char* s) +{ + while(*s == ' ' || *s == '\t') s++; + char* n = s; + char* c = strstr(n, "const"); + if (c) + n += 6; + + char* t = strstr(n, " "); + if (t) + { + if (t[1] == '*') + t += 2; + t[0] = 0; + char* ori = t; + t = strstr(t+1, "["); + if (t) + { + memmove(ori, t, strlen(t)); + strstr(ori, "]")[1] = 0; + } + } + return strdup(s); +} + +typedef struct +{ + char* type; + char* name; + int nargs; + char** args; + int ok; +} FuncDesc; + +char* get_type_string(char* type) +{ + if (strstr(type, "[16]")) + { + if (strstr(type, "float")) + return ("TYPE_16FLOAT"); + else if (strstr(type, "double")) + return ("TYPE_16DOUBLE"); + else + { + printf("inconnu %s\n", type); + exit(-1); + } + } + else if (strcmp(type, "void") == 0) + return("TYPE_NONE"); + else if (strcmp(type, "GLbyte") == 0) + return("TYPE_CHAR"); + else if (strcmp(type, "GLubyte") == 0 || + strcmp(type, "GLboolean") == 0) + return("TYPE_UNSIGNED_CHAR"); + else if (strcmp(type, "GLshort") == 0) + return("TYPE_SHORT"); + else if (strcmp(type, "GLushort") == 0 || + strcmp(type, "GLhalfNV") == 0) + return("TYPE_UNSIGNED_SHORT"); + else if (strcmp(type, "GLint") == 0 || + strcmp(type, "GLsizei") == 0) + return("TYPE_INT"); + else if (strcmp(type, "GLenum") == 0 || + strcmp(type, "GLuint") == 0 || + strcmp(type, "GLhandleARB") == 0 || + strcmp(type, "GLbitfield") == 0) + return("TYPE_UNSIGNED_INT"); + else if (strcmp(type, "GLfloat") == 0 || + strcmp(type, "GLclampf") == 0) + return("TYPE_FLOAT"); + else if (strcmp(type, "GLdouble") == 0 || + strcmp(type, "GLclampd") == 0) + return("TYPE_DOUBLE"); + else + { + printf("inconnu %s\n", type); + exit(-1); + } +} + +typedef struct +{ + char* letter; + char* signature_type_name; + char* gl_c_type_name; + char* c_type_name; +} ForIsKnownArgVector; + +int is_known_arg_vector(FuncDesc* desc, char** p_signature_type_name, char** p_c_type_name) +{ + static ForIsKnownArgVector my_tab[] = + { + { "b", "CHAR", "byte", "char" }, + { "s", "SHORT", "short", "short" }, + { "i", "INT", "int", "int" }, + { "ub", "CHAR", "byte", "unsigned char" }, + { "us", "SHORT", "short", "unsigned short" }, + { "ui", "INT", "int", "unsigned int" }, + { "Nb", "CHAR", "byte", "char" }, + { "Ns", "SHORT", "short", "short" }, + { "Ni", "INT", "int", "int" }, + { "Nub", "CHAR", "byte", "unsigned char" }, + { "Nus", "SHORT", "short", "unsigned short" }, + { "Nui", "INT", "int", "unsigned int" }, + + { "f", "FLOAT", "float", "float" }, + { "d", "DOUBLE", "double", "double" }, + }; + + if (desc->nargs == 0) + return 0; + + int i , j; + + static char signatures[14][4][20] = {0}; + char signature[10]; + + for(i=0;i<14;i++) + { + for(j=1;j<=4;j++) + { + sprintf(signature, "%d%sv", j, my_tab[i].letter); + if (strstr(desc->name, signature) && + strstr(desc->args[desc->nargs - 1], my_tab[i].gl_c_type_name) && + strstr(desc->args[desc->nargs - 1], "*")) + { + if (p_signature_type_name) + { + if (signatures[i][j][0] == 0) + sprintf(signatures[i][j], "TYPE_%d%s", j, my_tab[i].signature_type_name); + *p_signature_type_name = signatures[i][j]; + } + if (p_c_type_name) *p_c_type_name = my_tab[i].c_type_name; + return 1; + } + } + } + return 0; +} + +int parse(FILE* f, FuncDesc* funcDesc, int ignoreEXT) +{ + char buffer[256]; + int funcDescCount = 0; + while(fgets(buffer, 256, f)) + { + if (strncmp(buffer, "GLAPI", 5) == 0 && strstr(buffer, "APIENTRY") && strstr(buffer, "(")) + { + if (strstr(buffer, "glDrawArrays")) + { + continue; + } + if (strstr(buffer, "glGetIntegerv")) + { + continue; + } + + char** args = malloc(15 * sizeof(char*)); + int narg = 0; + char* type = buffer + 6; + char* n = strstr(type, "GLAPIENTRY") ? strstr(type, "GLAPIENTRY") : strstr(type, "APIENTRY"); + int skip_length = strstr(type, "GLAPIENTRY") ? 11 : 9; + n[-1] = 0; + type = strdup(type); + n += skip_length; + char* fonc = n; + n = strstr(n, "("); + if (n[-1] == ' ') n[-1] = 0; + n[0] = 0; + fonc = strdup(fonc); + /*if (strstr(fonc, "glLockArraysEXT") || strstr(fonc, "glUnlockArraysEXT")) + { + } + else*/ + if ((ignoreEXT == 1 && isExt(fonc)) || (ignoreEXT == 0 && !isExt(fonc))) + { + free(type); + free(fonc); + continue; + } + n++; + while(1) + { + char* virg = strstr(n, ","); + if (virg) + { + args[narg] = n; + virg[0] = 0; + args[narg] = get_arg_type(args[narg]); + narg++; + n = virg+1; + } + else + break; + } + while (strstr(n, ")") == 0) + { + fgets(buffer, 256, f); + n = buffer; + while(1) + { + char* virg = strstr(n, ","); + if (virg) + { + args[narg] = n; + virg[0] = 0; + args[narg] = get_arg_type(args[narg]); + narg++; + n = virg+1; + } + else + break; + } + } + char* par = strstr(n, ")"); + args[narg] = n; + par[0] = 0; + args[narg] = get_arg_type(args[narg]); + narg++; + int i; + + + /*printf("%s %s (", type, fonc); + for(i=0;i= 0) + { + j = funcDesc[i].nargs-1; + if (strstr(funcDesc[i].args[j], "[16]") == NULL) + { + pointer |= strstr(funcDesc[i].args[j], "*") != NULL; + pointer |= strstr(funcDesc[i].args[j], "[") != NULL; + } + } + } + } + if (pointer && funcDesc[i].nargs == 1 && + (strstr(funcDesc[i].name, "Matrixf") || strstr(funcDesc[i].name, "Matrixd"))) + { + free(funcDesc[i].args[0]); + if (strstr(funcDesc[i].name, "Matrixf")) + funcDesc[i].args[0] = strdup("GLfloat m[16]"); + else + funcDesc[i].args[0] = strdup("GLdouble m[16]"); + pointer = 0; + } + if (pointer == 0) + { + funcDesc[i].ok = 1; + if (first == 1) + { + first = 0; + } + fprintf(header, " %s_func,\n", funcDesc[i].name); + if (funcDesc[i].nargs == 1 && strcmp(funcDesc[i].args[0], "void") == 0) + { + funcDesc[i].nargs = 0; + } + /*printf("%s %s (", funcDesc[i].type, funcDesc[i].name); + for(j=0;jis_jmp = 3; } +extern int enable_gl; + /* an interrupt is different from an exception because of the priviledge checks */ static void gen_interrupt(DisasContext *s, int intno, target_ulong cur_eip, target_ulong next_eip) { + if (enable_gl && intno == 0x99) + { + gen_op_int99(); + } + else + { if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_jmp_im(cur_eip); gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip)); s->is_jmp = 3; + } } static void gen_debug(DisasContext *s, target_ulong cur_eip) diff -Nrup --exclude=CVS --exclude='*~' --exclude='config-host*' --exclude=Makefile --exclude=config.mak --exclude=config.h qemu.ori/vl.c qemu/vl.c --- qemu.ori/vl.c 2006-11-14 00:18:09.000000000 +0100 +++ qemu/vl.c 2006-11-14 21:46:24.000000000 +0100 @@ -162,6 +162,7 @@ int vnc_display = -1; int acpi_enabled = 1; int fd_bootchk = 1; int no_reboot = 0; +int enable_gl = 0; /***********************************************************/ /* x86 ISA bus support */ @@ -842,6 +843,8 @@ static int timer_load(QEMUFile *f, void return 0; } +extern int doing_opengl; + #ifdef _WIN32 void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) @@ -886,8 +889,9 @@ static void host_alarm_handler(int host_ SetEvent(host_alarm); #endif CPUState *env = cpu_single_env; - if (env) { - /* stop the currently executing cpu because a timer occured */ + if (env && !doing_opengl) { + //printf("alarm handler\n"); + /* stop the currently executing cpu because a timer occured */ cpu_interrupt(env, CPU_INTERRUPT_EXIT); #ifdef USE_KQEMU if (env->kqemu_enabled) { @@ -5792,7 +5796,7 @@ int main_loop(void) } } cur_cpu = env; - + if (shutdown_requested) { ret = EXCP_INTERRUPT; break; @@ -5934,6 +5938,7 @@ void help(void) "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n" " (default is CL-GD5446 PCI VGA)\n" "-no-acpi disable ACPI\n" + "-enable-gl (Experimental !) Enable accelerated OpenGL\n" #endif "-no-reboot exit instead of rebooting\n" "-loadvm file start right away with a saved state (loadvm in monitor)\n" @@ -6017,6 +6022,10 @@ enum { QEMU_OPTION_vnc, QEMU_OPTION_no_acpi, QEMU_OPTION_no_reboot, + +#ifdef TARGET_I386 + QEMU_OPTION_enable_gl, +#endif }; typedef struct QEMUOption { @@ -6094,6 +6103,10 @@ const QEMUOption qemu_options[] = { { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, { "no-acpi", 0, QEMU_OPTION_no_acpi }, { "no-reboot", 0, QEMU_OPTION_no_reboot }, + +#ifdef TARGET_I386 + { "enable-gl", 0, QEMU_OPTION_enable_gl }, +#endif { NULL }, }; @@ -6741,6 +6754,11 @@ int main(int argc, char **argv) case QEMU_OPTION_no_reboot: no_reboot = 1; break; +#ifdef TARGET_I386 + case QEMU_OPTION_enable_gl: + enable_gl = 1; + break; +#endif } } }