From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1GknyR-0006de-GS for qemu-devel@nongnu.org; Thu, 16 Nov 2006 15:36:39 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1GknyN-0006Yq-HI for qemu-devel@nongnu.org; Thu, 16 Nov 2006 15:36:39 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1GknyN-0006Ya-Bw for qemu-devel@nongnu.org; Thu, 16 Nov 2006 15:36:35 -0500 Received: from [212.247.155.76] (helo=swip.net) by monty-python.gnu.org with esmtp (Exim 4.52) id 1GknyL-0002KV-L8 for qemu-devel@nongnu.org; Thu, 16 Nov 2006 15:36:35 -0500 Received: from [83.179.41.43] (HELO pc-amd64) by mailfe11.swip.net (CommuniGate Pro SMTP 5.0.12) with ESMTP id 160467900 for qemu-devel@nongnu.org; Thu, 16 Nov 2006 21:36:26 +0100 From: Even Rouault MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_JvMXFKLuzxMbCe1" Message-Id: <200611162136.25324.even.rouault@mines-paris.org> Subject: [Qemu-devel] [PATCH] Experimental initial patch providing accelerated OpenGL for Linux i386 (2nd attempt to post) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Date: Thu, 16 Nov 2006 20:36:39 -0000 To: qemu-devel@nongnu.org --Boundary-00=_JvMXFKLuzxMbCe1 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Here's an attempt of providing accelerated OpenGL for QEMU. I must underline first that it should really really be considered as=20 experimental or a proof-of-concept. There's still a lot of work to do to make it reliable and releasable. So what is it exactly ? =2D a patch for QEMU itself that intercepts any call to 'int $0x99' which i= s the=20 interface I have chosen to dedicate to =A0 communication between guest user programs and QEMU. The modification of= QEMU=20 existing code is very slight. =A0 The essential of code on the guest side is in new files. =2D a replacement libGL.so library that must be used inside the Linux guest= =2E The=20 library redirects guest OpenGL and GLX calls =A0 to host side, where your host libGL.so will do the real job. It works currently only with Linux x86 as guest and host OS. Now, the good news : which programs do currently work with this patch ? =2D glxinfo =2D glxgears. I get ~330 FPS with QEMU/GL (direct GLX), ~210 FPS through a = SSH=20 console on the guest OS (indirect GLX) =2D some mesa demos programs. =A0 =A0 * tunnel =A0 =A0 : ~26 FPS with QEMU/GL, =A0~3 FPS through a SSH co= nsole on the=20 guest OS =A0 =A0 * teapot =A0 =A0 : ~50 FPS with QEMU/GL, =A0~7 FPS through a SSH co= nsole on the=20 guest OS =A0 =A0 * fire =A0 =A0 =A0 : ~14 FPS with QEMU/GL, =A0~2 FPS through a SSH = console on the=20 guest OS =A0 =A0 * arbfplight : ~100 FPS with QEMU/GL, =A0not possible through a SSH= console=20 on the guest OS (GL_ARB_vertex_program not available) =2D ... and ppracer ! (some crash from time to time. Starting at ~20 FPS at= the=20 beginning of the race, and finishing at ~10 FPS... strange...) How fast is it ? Enough fast to have 15 FPS in ppracer with KQEMU disabled. When KQEMU is enabled, paradoxically, the performance is really poor :-( Successfully tested on the following platforms : =2D Ubuntu Edgy x86 as host with ATI FGLRX driver / FC5 x86 as guest =2D Ubuntu Dapper x86 as host with NVIDIA Proprietary driver / Ubuntu Dappe= r x86=20 as guest Which programs do not work : probably most for the moment ;-) I'd like to make it work with XGL (I've downloaded the latest Mandriva 2007= =20 Live CD and I'm quite impatient to enable the 3D in it) and GoogleEarth. How to use it ? (ONLY on Linux i386 and with only i386-softmmu as target-li= st) * Apply the patch and recompile QEMU=20 * Lauch QEMU with -enable-gl option * Get the compiled libGL.so from ./i386-softmmu and copy it to the guest OS * In the guest OS : LD_LIBRARY_PATH=3D/path/to/replacement/libGL.so glxgears TODO list : =2D implement correctly full OpenGL API =2D improve vertex arrays support =2D maybe fix how the end of the guest process is detected =2D make replacement libGL work when compiled with optimization flags =2D integrate in a better way the window that popups on the guest side with= the=20 main qemu window =2D integrate it properly into QEMU build system (helper_opengl.c can't com= pile=20 with -O2 : 'unable to find a register to spill in class `DIREG'') =2D understand why it's slower when KQEMU enabled and try to fix that if=20 possible =2D enable several guest OS processes to use OpenGL at the same time =2D make it run on x86_64, and allowing any combination guest x86/x86_64 an= d=20 host x86/x86_64, other archs =2D port it to other UNIX-like OS with X =2D improve security if possible (preventing malicious guest code from cras= hing=20 host qemu) =2D clean the code ! =2D much testing and debugging =2D port it to Windows platform (first OpenGL / WGL, then D3D through Wine= =20 libs ?) =2D make a patch to Valgrind to make it happy with 'int $0x99' when running= on=20 guest side =2D ... The new files : =2D opengl_client.c =A0: the OpenGL guest library =2D helper_opengl.c : main guest-side code =2D gl_func.h, server_stub.c, client_stub.c : generated files by parse_gl_h= =2Ec=20 from gl.h parsing =2D glgetv_cst.h =A0: generated file from parsing of a man page =2D gl_func_perso.h, opengl_func.h : hand-written "prototypes" In the mean time, enjoy ! --Boundary-00=_JvMXFKLuzxMbCe1 Content-Type: text/x-diff; charset="us-ascii"; name="qemu_opengl.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="qemu_opengl.patch" diff -Nrup --exclude=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/dynge= n-exec.h qemu/dyngen-exec.h =2D-- 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)) =20 +#ifndef _STDIO_H + typedef struct FILE FILE; extern int fprintf(FILE *, const char *, ...); extern int printf(const char *, ...); #undef NULL #define NULL 0 =20 +#endif + #ifdef __i386__ #define AREG0 "ebp" #define AREG1 "ebx" diff -Nrup --exclude=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/kqemu= =2Ec qemu/kqemu.c =2D-- 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; =20 #define cpuid(index, eax, ebx, ecx, edx) \ asm volatile ("cpuid" \ @@ -721,6 +722,7 @@ int kqemu_cpu_exec(CPUState *env) ret =3D 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 =3D kenv->kernelgsbase; #endif #endif =2D /* flush pages as indicated by kqemu */ if (kenv->nb_pages_to_flush >=3D KQEMU_FLUSH_ALL) { tlb_flush(env, 1); @@ -825,13 +826,40 @@ int kqemu_cpu_exec(CPUState *env) else env->hflags &=3D ~HF_OSFXSR_MASK; =20 + /* OPENGL Stuff */ + if (enable_gl && ((env->hflags & HF_CPL_MASK) =3D=3D 3)) + { + int index =3D (env->eip >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + if (env->segs[R_CS].base !=3D 0) + { + fprintf(stderr, "env->segs[R_CS].base !=3D 0 !\n"); + } + else if (__builtin_expect(env->tlb_table[1][index].addr_code !=3D=20 + (env->eip & TARGET_PAGE_MASK), 0)) + { + ldub_code(env->eip); + } + if (env->tlb_table[1][index].addend) + { + unsigned char* ptr =3D env->eip + env->tlb_table[1][index].addend; + if (ptr[0] =3D=3D 0xCD && ptr[1] =3D=3D 0x99) + { + helper_opengl(env); + } + /*else if (ptr[0] =3D=3D 0xCD && ptr[1] =3D=3D 0x80) + { + fprintf(stderr, "system call %d\n", env->regs[R_EAX]); + }*/ + } + } + =20 #ifdef DEBUG if (loglevel & CPU_LOG_INT) { fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=3D0x%x\n", ret); } #endif if (ret =3D=3D KQEMU_RET_SYSCALL) { =2D /* syscall instruction */ + /* syscall instruction */ return do_syscall(env, kenv); } else=20 if ((ret & 0xff00) =3D=3D KQEMU_RET_INT) { diff -Nrup --exclude=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/Makef= ile.target qemu/Makefile.target =2D-- 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+=3Dgdbstub.o endif =20 =2Dall: $(PROGS) =2D $(QEMU_USER): $(OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) ifeq ($(ARCH),alpha) @@ -435,8 +433,28 @@ ifdef CONFIG_WIN32 SDL_LIBS :=3D $(filter-out -mwindows, $(SDL_LIBS)) -mconsole endif =20 +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 :=3D -Wall -g -fno-strict-aliasing +helper_opengl.o: helper_opengl.c server_stub.c gl_func.h + $(CC) $(GL_CFLAGS) $(DEFINES) -c -o $@ $< +LIBOBJS+=3Dhelper_opengl.o +libGL.so: client_stub.c gl_func.h + $(CC) $(GL_CFLAGS) $(SRC_PATH)/target-i386/opengl_client.c -shared -o lib= GL.so -I. -I$(SRC_PATH)/target-i386 +PROGS+=3DlibGL.so +GL_GENERATED_FILES=3DlibGL.so parse_gl_h server_stub.c client_stub.c gl_fu= nc.h +endif + $(QEMU_SYSTEM): $(VL_OBJS) libqemu.a =2D $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIB= S) + $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS)= -lGL =20 cocoa.o: cocoa.m $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $< @@ -545,7 +563,7 @@ $(OBJS) $(LIBOBJS) $(VL_OBJS): config.h=20 $(CC) $(DEFINES) -c -o $@ $< =20 clean: =2D 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) =20 install: all=20 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 :=3D $(CFLAGS) -Wall -Werror -W -Wsign-compare endif + +all: $(PROGS) diff -Nrup --exclude=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/targe= t-i386/gl_func_perso.h qemu/target-i386/gl_func_perso.h =2D-- qemu.ori/target-i386/gl_func_perso.h 1970-01-01 01:00:00.000000000 +0= 100 +++ qemu/target-i386/gl_func_perso.h 2006-11-14 21:46:24.000000000 +0100 @@ -0,0 +1,93 @@ +/* + * Hand-implemented GL/GLX API + *=20 + * 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 U= SA + */ + +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=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/targe= t-i386/glgetv_cst.h qemu/target-i386/glgetv_cst.h =2D-- 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[] =3D { + { 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=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/targe= t-i386/helper.c qemu/target-i386/helper.c =2D-- 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 } =20 +void helper_opengl(CPUState *env); + +void helper_int99() +{ + regs_to_env(); + helper_opengl(env); + env_to_regs(); +} + + #if !defined(CONFIG_USER_ONLY)=20 =20 #define MMUSUFFIX _mmu diff -Nrup --exclude=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/targe= t-i386/helper_opengl.c qemu/target-i386/helper_opengl.c =2D-- qemu.ori/target-i386/helper_opengl.c 1970-01-01 01:00:00.000000000 +0= 100 +++ 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 + *=20 + * 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 U= SA + */ + + +#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 =3D 0; \ + static type(*ptr_func)args_decl =3D NULL; \ + if (detect =3D=3D 0) \ +{ \ + detect =3D 1; \ + ptr_func =3D glXGetProcAddress((const GLubyte*)#func_name); \ + assert (ptr_func); \ +} + +static inline void* get_phys_mem_addr(const CPUState *env, target_ulong ad= dr) +{ + int is_user, index; + index =3D (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + is_user =3D ((env->hflags & HF_CPL_MASK) =3D=3D 3); + if (is_user =3D=3D 0) + { + fprintf(stderr, "not in userland !!!\n"); + return NULL; + } + if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=3D=20 + (addr & TARGET_PAGE_MASK), 0)) + { + target_ulong ret =3D cpu_get_phys_page_debug(env, addr); + if (ret =3D=3D -1) + { + fprintf(stderr, "cpu_get_phys_page_debug(env, %p) =3D=3D %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 =3D %d\n", + cpu_x86_handle_mmu_fault(env, addr, 0, 1, 1)); + return NULL; + } + else + { + if (ret + TARGET_PAGE_SIZE <=3D 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) =3D=3D %p\n", ad= dr, ret); + fprintf(stderr, "ret=3D%p phys_ram_size=3D%p\n", ret, phys_ram_siz= e); + 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 = =2D 1)) + +/* Return NOT_MAPPED if a page is not mapped into target physical memory */ +/* MAPPED_CONTIGUOUS if all pages are mapped into target physical m= emory and contiguous */ +/* MAPPED_NOT_CONTIGUOUS if all pages are mapped into target physic= al memory but not contiguous */ +static int get_target_mem_state(const CPUState *env, const void* target_ad= dr, int len) +{ + void* aligned_target_addr =3D TARGET_ADDR_LOW_ALIGN(target_addr); + int to_end_page =3D (long)aligned_target_addr + TARGET_PAGE_SIZE - (long= )target_addr; + int ret =3D MAPPED_CONTIGUOUS; + =20 + if (aligned_target_addr !=3D target_addr) + { + void* phys_addr =3D get_phys_mem_addr(env, aligned_target_addr); + void* last_phys_addr =3D phys_addr; + if (phys_addr =3D=3D 0) + { + return NOT_MAPPED; + } + if (len > to_end_page) + { + len -=3D to_end_page; + aligned_target_addr +=3D TARGET_PAGE_SIZE; + int i; + for(i=3D0;ivisual, AllocNone); + attr.event_mask =3D StructureNotifyMask | ExposureMask | KeyPressMask; + attr.override_redirect =3D 0; //fullscreen; + mask =3D CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOver= rideRedirect; + + win =3D XCreateWindow( dpy, root, 0, 0, width, height, + 0, vis->depth, InputOutput, + vis->visual, mask, &attr ); + + /* set hints and properties */ + { + XSizeHints sizehints; + sizehints.x =3D x; + sizehints.y =3D y; + sizehints.width =3D width; + sizehints.height =3D height; + sizehints.flags =3D USSize | USPosition; + XSetWMNormalHints(dpy, win, &sizehints); + XSetStandardProperties(dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + =20 + /* + int loop =3D 1; + while (loop) { + while (XPending(dpy) > 0) { + XEvent event; + XNextEvent(dpy, &event); + switch (event.type) { + case CreateNotify: + { + if (((XCreateWindowEvent*)&event)->window =3D=3D win) + { + loop =3D 0; + } + break; + } + } + } +}*/ + =20 + return win; +} + + +typedef struct +{ + void* key; + void* value; +} Assoc; + + +#define MAX_HANDLED_PROCESS 100 +#define MAX_ASSOC_SIZE 100 + +typedef struct +{ + int process_id; + =20 + 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 =3D 0; + +target_ulong args[50]; + + +#ifdef SYSTEMATIC_ERROR_CHECK +int last_error =3D 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[] =3D { + 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=3D0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcont= ext[i].key !=3D NULL;i++) + { + if (process->association_fakecontext_glxcontext[i].key =3D=3D fakecont= ext) + return process->association_fakecontext_glxcontext[i].value; + } + return NULL; +} +void set_association_fakecontext_glxcontext(ProcessStruct* process, void* = fakecontext, void* glxcontext) +{ + int i; + for(i=3D0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcont= ext[i].key !=3D NULL;i++) + { + if (process->association_fakecontext_glxcontext[i].key =3D=3D fakecont= ext) + { + break; + } + } + if (i < MAX_ASSOC_SIZE) + { + process->association_fakecontext_glxcontext[i].key =3D fakecontext; + process->association_fakecontext_glxcontext[i].value =3D glxcontext; + } + else + { + fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); + } +} +void unset_association_fakecontext_glxcontext(ProcessStruct* process, void= * fakecontext) +{ + int i; + for(i=3D0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcont= ext[i].key !=3D NULL;i++) + { + if (process->association_fakecontext_glxcontext[i].key =3D=3D fakecont= ext) + { + 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=3D0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serv= erdrawable[i].key !=3D NULL;i++) + { + if (process->association_clientdrawable_serverdrawable[i].key =3D=3D c= lientdrawable) + return process->association_clientdrawable_serverdrawable[i].value; + } + return NULL; +} +void* get_association_serverdrawable_clientdrawable(ProcessStruct* process= , void* serverdrawable) +{ + int i; + for(i=3D0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serv= erdrawable[i].key !=3D NULL;i++) + { + if (process->association_clientdrawable_serverdrawable[i].value =3D=3D= 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=3D0;process->association_clientdrawable_serverdrawable[i].key !=3D= NULL;i++) + { + if (process->association_clientdrawable_serverdrawable[i].key =3D=3D c= lientdrawable) + { + break; + } + } + if (i < MAX_ASSOC_SIZE) + { + process->association_clientdrawable_serverdrawable[i].key =3D clientdr= awable; + process->association_clientdrawable_serverdrawable[i].value =3D server= drawable; + } + else + { + fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); + } +} + +void display_client_server_state(ProcessStruct* process) +{ + int i; + printf("serverActiveTexture =3D %d\n", process->serverActiveTexture); + printf("clientActiveTexture =3D %d\n", process->clientActiveTexture); + for(i=3D0;i<6;i++) + { + if (i =3D=3D 5) continue; + printf("pointerArraysEnable[%d] =3D %d\n", i, process->pointerArraysEn= able[i]); + } + for(i=3D0;i<8;i++) + { + printf("texCoordPointerEnable[%d] =3D %d\n", i, process->texCoordPoint= erEnable[i]); + } +} + +int do_function_call(int func_number, int pid) +{ + char ret_char =3D 0; + int ret_int =3D 0; + void* ret_ptr =3D NULL; + const char* ret_str =3D NULL; + =20 + int iProcess; + ProcessStruct* process =3D NULL; + for(iProcess=3D0;iProcessprocess_id =3D pid; + break; + } + } + if (process =3D=3D 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"); + =20 + for(i=3D0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glx= context[i].key !=3D NULL;i++) + { + GLXContext ctxt =3D process->association_fakecontext_glxcontext[i]= =2Evalue; + fprintf(stderr, "Destroy context corresponding to fake_context =3D= %d\n", + process->association_fakecontext_glxcontext[i].key); + glXDestroyContext(dpy, ctxt); + } + =20 + for(i=3D0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_= serverdrawable[i].key !=3D NULL;i++) + { + fprintf(stderr, "Destroy window corresponding to client_drawable = =3D %p\n", + process->association_clientdrawable_serverdrawable[i].key); + =20 + Window win =3D process->association_clientdrawable_serverdrawable[= i].value; + XDestroyWindow(dpy, win); + =20 + int loop =3D 1; + while (loop) { + while (XPending(dpy) > 0) { + XEvent event; + XNextEvent(dpy, &event); + switch (event.type) { + case DestroyNotify: + { + if (((XDestroyWindowEvent*)&event)->window =3D=3D win) + { + loop =3D 0; + } + break; + } + } + } + } + } + =20 + if (process->vertexPointer) free(process->vertexPointer); + if (process->normalPointer) free(process->normalPointer); + if (process->colorPointer) free(process->colorPointer); + if (process->texCoordPointer) free(process->texCoordPointer); + =20 + memmove(&processTab[iProcess], &processTab[iProcess+1], (MAX_HANDLED= _PROCESS - 1 - iProcess) * sizeof(ProcessStruct)); + =20 + last_process_id =3D 0; + + break; + } + =20 + case _changeWindowState_func: + { + GLXDrawable client_drawable =3D args[0]; + if (display_function_call) fprintf(stderr, "_changeWindowState_func = client_drawable=3D%p\n", (void*)client_drawable); + =20 + GLXDrawable drawable =3D get_association_clientdrawable_serverdrawab= le(process, client_drawable); + if (drawable) + { + if (args[1] =3D=3D IsViewable) + { + XMapWindow(dpy, drawable); + =20 + int loop =3D 1; + while (loop) { + while (XPending(dpy) > 0) { + XEvent event; + XNextEvent(dpy, &event); + switch (event.type) { + case ConfigureNotify: + { + if (((XConfigureEvent*)&event)->window =3D=3D drawable) + { + loop =3D 0; + } + break; + } + } + } + } + } + } + =20 + break; + } + =20 + case _moveResizeWindow_func: + { + GLXDrawable client_drawable =3D args[0]; + if (display_function_call) fprintf(stderr, "_moveResizeWindow client= _drawable=3D%p\n", (void*)client_drawable); + =20 + GLXDrawable drawable =3D get_association_clientdrawable_serverdrawab= le(process, client_drawable); + if (drawable) + { + int* params =3D (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]); + =20 + int loop =3D 1; + while (loop) { + while (XPending(dpy) > 0) { + XEvent event; + XNextEvent(dpy, &event); + switch (event.type) { + case ConfigureNotify: + { + if (((XConfigureEvent*)&event)->window =3D=3D drawable) + { + loop =3D 0; + } + break; + } + } + } + } + } + break; + } + + case _needSync_func: + { + if (display_function_call) fprintf(stderr, "_needSync\n"); + ret_int =3D 1; + break; + } + =20 + case glXChooseVisual_func: + { + if (display_function_call) fprintf(stderr, "glXChooseVisual\n"); + ret_ptr =3D glXChooseVisual(dpy, 0, (void*)args[2]); + break; + } + =20 + case glXQueryExtensionsString_func: + { + if (display_function_call) fprintf(stderr, "glXQueryExtensionsString= \n"); + ret_str =3D glXQueryExtensionsString(dpy, 0); + break; + } + =20 + case glXQueryServerString_func: + { + if (display_function_call) fprintf(stderr, "glXQueryServerString %d\= n", args[2]); + ret_str =3D glXQueryServerString(dpy, 0, args[2]); + break; + } + =20 + case glXGetClientString_func: + { + if (display_function_call) fprintf(stderr, "glXQueryServerString %d\= n", args[1]); + ret_str =3D glXGetClientString(dpy, args[1]); + break; + } + =20 + case glXCreateContext_func: + { + void* fake_shareList =3D args[2]; + if (1 || display_function_call) fprintf(stderr, "glXCreateContext fa= ke_shareList=3D%p\n", fake_shareList); + =20 + process->next_available_context_number ++; + void* fake_ctxt =3D (void*)process->next_available_context_number; + =20 + GLXContext shareList =3D get_association_fakecontext_glxcontext(proc= ess, fake_shareList); + XVisualInfo* vis =3D get_visual(); + GLXContext ctxt =3D glXCreateContext(dpy, vis, shareList, args[3]); + set_association_fakecontext_glxcontext(process, fake_ctxt, ctxt); + =20 + ret_ptr =3D fake_ctxt; + break; + } + =20 + case glXGetCurrentContext_func: + { + if (display_function_call) fprintf(stderr, "glXGetCurrentContext\n"); + ret_ptr =3D get_association_fakecontext_glxcontext(process, glXGetCu= rrentContext()); + break; + } + =20 + case glXGetCurrentDrawable_func: + { + if (display_function_call) fprintf(stderr, "glXGetCurrentDrawable\n"= ); + ret_ptr =3D get_association_serverdrawable_clientdrawable(process, g= lXGetCurrentDrawable()); + break; + } + =20 + case glXDestroyContext_func: + { + GLXContext fake_ctxt =3D args[1]; + if (display_function_call) fprintf(stderr, "glXDestroyContext fake_c= txt=3D%p\n", fake_ctxt); + =20 + GLXContext ctxt =3D get_association_fakecontext_glxcontext(process, = fake_ctxt); + if (ctxt =3D=3D NULL) + { + fprintf(stderr, "invalid fake_ctxt (%p) !\n", fake_ctxt); + } + else + { + glXDestroyContext(dpy, ctxt); + unset_association_fakecontext_glxcontext(process, fake_ctxt); + } + break; + } + =20 + case glXQueryVersion_func: + { + if (display_function_call) fprintf(stderr, "glXQueryVersion\n"); + ret_int =3D glXQueryVersion(dpy, args[1], args[2]); + break; + } + =20 + case glGetString_func: + { + if (display_function_call) fprintf(stderr, "glGetString %d\n", args[= 0]); + ret_str =3D (char*)glGetString(args[0]); + break; + } + =20 + case glXMakeCurrent_func: + { + GLXDrawable client_drawable =3D args[1]; + GLXContext fake_ctxt =3D args[2]; + if (display_function_call) fprintf(stderr, "glXMakeCurrent client_dr= awable=3D%p fake_ctx=3D%p\n", (void*)client_drawable, fake_ctxt); + =20 + if (client_drawable =3D=3D NULL && fake_ctxt =3D=3D NULL) + { + ret_int =3D glXMakeCurrent(dpy, NULL, NULL); + } + else + { + GLXContext ctxt =3D get_association_fakecontext_glxcontext(process= , fake_ctxt); + GLXDrawable drawable; + if (ctxt =3D=3D NULL) + { + fprintf(stderr, "invalid fake_ctxt (%p) !\n", fake_ctxt); + ret_int =3D 0; + } + else + { + drawable =3D get_association_clientdrawable_serverdrawable(proce= ss, client_drawable); + if (drawable =3D=3D NULL) + { + drawable =3D create_window("", 0, 0, 300, 300); + set_association_clientdrawable_serverdrawable(process, client_= drawable, drawable); + } + =20 + ret_int =3D glXMakeCurrent(dpy, drawable, ctxt); + } + } + break; + } + =20 + case glXSwapBuffers_func: + { + GLXDrawable client_drawable =3D args[1]; + if (display_function_call) fprintf(stderr, "glXSwapBuffers client_dr= awable=3D%p\n", (void*)client_drawable); + =20 + GLXDrawable drawable =3D get_association_clientdrawable_serverdrawab= le(process, client_drawable); + if (drawable =3D=3D 0) + { + fprintf(stderr, "unknown client_drawable (%p) !\n", client_drawabl= e); + } + else + { + glXSwapBuffers(dpy, drawable); + } + break; + } + =20 + case glXIsDirect_func: + { + GLXContext fake_ctxt =3D args[1]; + if (display_function_call) fprintf(stderr, "glXIsDirect fake_ctx=3D%= p\n", fake_ctxt); + GLXContext ctxt =3D get_association_fakecontext_glxcontext(process, = fake_ctxt); + if (ctxt =3D=3D NULL) + { + fprintf(stderr, "invalid fake_ctxt (%p) !\n", fake_ctxt); + ret_char =3D False; + } + else + { + ret_char =3D glXIsDirect(dpy, ctxt); + } + break; + } + =20 + case glXGetConfig_func: + { + if (display_function_call) fprintf(stderr, "glXGetConfig %d\n", args= [2]); + ret_int =3D glXGetConfig(dpy, get_visual(), args[2], args[3]); + break; + } + =20 + case glXUseXFont_func: + { + if (display_function_call) fprintf(stderr, "glXUseXFont\n"); + fprintf(stderr, "not implemented !\n"); + break; + } + =20 + =20 + case glXQueryExtension_func: + { + if (display_function_call) fprintf(stderr, "glXQueryExtension\n"); + ret_int =3D glXQueryExtension(dpy, args[1], args[2]); + break; + } + =20 + case glXChooseFBConfig_func: + { + if (display_function_call) fprintf(stderr, "glXChooseFBConfig\n"); + fprintf(stderr, "not implemented !\n"); + ret_ptr =3D 0; + break; + } + =20 + case glXCreatePbuffer_func: + { + if (display_function_call) fprintf(stderr, "glXCreatePbuffer\n"); + fprintf(stderr, "not implemented !\n"); + ret_ptr =3D NULL; + break; + } + =20 + case glXGetVisualFromFBConfig_func: + { + if (display_function_call) fprintf(stderr, "glXGetVisualFromFBConfig= \n"); + fprintf(stderr, "not implemented !\n"); + ret_ptr =3D NULL; + break; + } + =20 + case glXGetProcAddress_fake_func: + { + if (display_function_call) fprintf(stderr, "glXGetProcAddress %s\n",= args[0]); + ret_int =3D glXGetProcAddress(args[0]) !=3D NULL; + break; + } + =20 + case glFlush_func: + { + glFlush(); + break; + } + =20 + case glGetIntegerv_func: + { + int param =3D args[0]; + if (display_function_call) fprintf(stderr, "glGetIntegerv %d\n", par= am); + glGetIntegerv(param, args[1]); + break; + } + =20 + case glGetFloatv_func: + { + int param =3D args[0]; + if (display_function_call) fprintf(stderr, "glGetFloatv %d\n", param= ); + glGetIntegerv(param, args[1]); + break; + } + =20 + case glGetConvolutionParameteriv_func: + { + if (display_function_call) fprintf(stderr, "glGetConvolutionParamete= riv %d %d\n", args[0], args[1]); + glGetConvolutionParameteriv(args[0], args[1], args[2]); + break; + } + =20 + case glLightfv_func: + { + if (display_function_call) fprintf(stderr, "glLightfv\n"); + glLightfv(args[0], args[1],(float*)args[2]); + break; + } + =20 + case glMaterialfv_func: + { + if (display_function_call) fprintf(stderr, "glMaterialfv\n"); + glMaterialfv(args[0], args[1], (float*)args[2]); + break; + } + =20 + case glLightModelfv_func: + { + if (display_function_call) fprintf(stderr, "glLightModelfv\n"); + glLightModelfv(args[0], (float*)args[1]); + break; + } + =20 + 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; + } + =20 + 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; + } + =20 + 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; + } + =20 + case glGenTextures_func: + { + int nTextures =3D args[0]; + if (display_function_call) fprintf(stderr, "glGenTextures\n"); + glGenTextures(nTextures, args[1]); + break; + } + =20 + case glDeleteTextures_func: + { + if (display_function_call) fprintf(stderr, "glDeleteTextures\n"); + glDeleteTextures(args[0], (int*)args[1]); + break; + } + =20 + case glCallLists_func: + { + if (display_function_call) fprintf(stderr, "glCallLists\n"); + glCallLists(args[0], args[1], (void*)args[2]); + break; + } + =20 + 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; + } + =20 + 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, "glCompressedTexImage2DAR= B\n"); + GET_EXT_PTR(void, glCompressedTexImage2DARB, (int,int,int,int,int,in= t,int,void*)); + ptr_func(args[0], + args[1], + args[2], + args[3], + args[4], + args[5], + args[6], + (void*)args[7]); + break; + } + =20 + case glCompressedTexSubImage2DARB_func: + { + if (display_function_call) fprintf(stderr, "glCompressedTexSubImage2= DARB\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; + } + =20 + 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; + } + =20 + 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; + } + =20 + 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; + } + =20 + case glGetUniformLocationARB_func: + { + if (display_function_call) fprintf(stderr, "glGetUniformLocationARB\= n"); + GET_EXT_PTR(int, glGetUniformLocationARB, (int,char*)); + ret_int =3D 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; + } + =20 + 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; + } + =20 + 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; + } + =20 + 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; + } + =20 + case glGetProgramLocalParameterfvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetProgramLocalParamet= erfvARB\n"); + GET_EXT_PTR(void, glGetProgramLocalParameterfvARB, (int,int,float*)); + ptr_func(args[0], args[1], (float*)args[2]); + break; + } + =20 + case glGetProgramLocalParameterdvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetProgramLocalParamet= erdvARB\n"); + GET_EXT_PTR(void, glGetProgramLocalParameterdvARB, (int,int,double*)= ); + ptr_func(args[0], args[1], (double*)args[2]); + break; + } + =20 + case glGetProgramEnvParameterfvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetProgramEnvParameter= fvARB\n"); + GET_EXT_PTR(void, glGetProgramEnvParameterfvARB, (int,int,float*)); + ptr_func(args[0], args[1], (float*)args[2]); + break; + } + =20 + case glGetProgramEnvParameterdvARB_func: + { + if (display_function_call) fprintf(stderr, "glGetProgramEnvParameter= dvARB\n"); + GET_EXT_PTR(void, glGetProgramEnvParameterdvARB, (int,int,double*)); + ptr_func(args[0], args[1], (double*)args[2]); + break; + } + =20 + 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; + } + =20 + 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 =3D 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 =3D 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; + } + =20 + case glGetTexLevelParameteriv_func: + { + if (display_function_call) fprintf(stderr, "glGetTexLevelParameteriv= \n"); + glGetTexLevelParameteriv(args[0], args[1], args[2], (int*)args[3]); + break; + } + =20 + case glFogfv_func: + { + if (display_function_call) fprintf(stderr, "glFogfv\n"); + glFogfv(args[0], (float*)args[1]); + break; + } + =20 + 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; + } + =20 + case glTexGenfv_func: + { + if (display_function_call) fprintf(stderr, "glTexGenfv\n"); + glTexGenfv(args[0], args[1], (float*)args[2]); + break; + } + =20 + case glTexEnvfv_func: + { + if (display_function_call) fprintf(stderr, "glTexEnvfv\n"); + glTexEnvfv(args[0], args[1], (float*)args[2]); + break; + } + =20 + case glTexParameterfv_func: + { + if (display_function_call) fprintf(stderr, "glTexParameterfv\n"); + glTexParameterfv(args[0], args[1], (float*)args[2]); + break; + } + =20 + case glTexParameteriv_func: + { + if (display_function_call) fprintf(stderr, "glTexParameteriv\n"); + glTexParameteriv(args[0], args[1], (int*)args[2]); + break; + } + =20 + case glVertexPointer_func: + { + if (display_function_call) fprintf(stderr, "glVertexPointer\n"); + if (process->vertexPointer) free(process->vertexPointer); + int size =3D args[3]; + process->vertexPointer =3D malloc(size); + memcpy(process->vertexPointer, args[4], size); + glVertexPointer(args[0], args[1], args[2], process->vertexPointer); + break; + } + =20 + case glNormalPointer_func: + { + if (display_function_call) fprintf(stderr, "glNormalPointer\n"); + if (process->normalPointer) free(process->normalPointer); + int size =3D args[2]; + process->normalPointer =3D malloc(size); + memcpy(process->normalPointer, args[3], size); + glNormalPointer(args[0], args[1], process->normalPointer); + break; + } + =20 + case glColorPointer_func: + { + if (display_function_call) fprintf(stderr, "glColorPointer\n"); + if (process->colorPointer) free(process->colorPointer); + int size =3D args[3]; + process->colorPointer =3D malloc(size); + memcpy(process->colorPointer, args[4], size); + glColorPointer(args[0], args[1], args[2], process->colorPointer); + + break; + } + =20 + case glTexCoordPointer_func: + { + if (display_function_call) fprintf(stderr, "glTexCoordPointer\n"); + if (process->texCoordPointer) free(process->texCoordPointer); + int size =3D args[3]; + process->texCoordPointer =3D malloc(size); + memcpy(process->texCoordPointer, args[4], size); + glTexCoordPointer(args[0], args[1], args[2], process->texCoordPointe= r); + break; + } + =20 + case glBegin_func: + { + //display_client_server_state(client); + glBegin(args[0]); + break; + } + =20 + case glActiveTexture_func: + case glActiveTextureARB_func: + { + process->serverActiveTexture =3D args[0] - GL_TEXTURE0_ARB; + //printf("set server active texture %d\n", clientActiveTexture); + glActiveTexture(args[0]); + break; + } + =20 + case glClientActiveTexture_func: + case glClientActiveTextureARB_func: + { + process->clientActiveTexture =3D args[0] - GL_TEXTURE0_ARB; + //printf("set client active texture %d\n", clientActiveTexture); + glClientActiveTexture(args[0]); + break; + } + =20 + case glEnableClientState_func: + { + int num =3D args[0] - GL_VERTEX_ARRAY; + if (num =3D=3D GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY) + { + //printf("enable texture %d\n", clientActiveTexture); + process->texCoordPointerEnable[process->clientActiveTexture] =3D 1; + } + else if (num >=3D 0 && num < 6) + { + //printf("enable feature %d\n", num); + process->pointerArraysEnable[num] =3D 1; + } + glEnableClientState(args[0]); + break; + } + =20 + case glDisableClientState_func: + { + int num =3D args[0] - GL_VERTEX_ARRAY; + if (num =3D=3D GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY) + { + //printf("disable texture %d\n", clientActiveTexture); + process->texCoordPointerEnable[process->clientActiveTexture] =3D 0; + } + else if (num >=3D 0 && num < 6) + { + //printf("disable feature %d\n", num); + process->pointerArraysEnable[num] =3D 0; + } + glDisableClientState(args[0]); + break; + } + =20 + case glArrayElement_func: + { + if (display_function_call) fprintf(stderr, "glArrayElement\n"); + glArrayElement(args[0]); + break; + } + =20 + 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; + } + =20 + case glDrawElements_func: + { + if (display_function_call) fprintf(stderr, "glDrawElements\n"); + glDrawElements(args[0], args[1],args[2],(void*)args[3]); + break; + } + =20 + case glGetError_func: + { +#ifdef SYSTEMATIC_ERROR_CHECK + ret_int =3D last_error; +#else + ret_int =3D glGetError(); +#endif + break; + } + =20 + default: + execute_func(func_number, &ret_int, &ret_char); + break; + } + +#ifdef SYSTEMATIC_ERROR_CHECK + if (funcNumber =3D=3D glGetError_func) + { + last_error =3D 0; + } + else + { + last_error =3D glGetError(); + if (last_error !=3D 0) + { + printf("error %s 0x%X\n", tab_opengl_calls_name[func_number], last_= error); + } + } +#endif + + Signature* signature =3D (Signature*)tab_opengl_calls[func_number]; + int ret_type =3D signature->ret_type; + int nb_args =3D signature->nb_args; + switch(ret_type) + { + case TYPE_NONE: + break; + =20 + case TYPE_CHAR: + case TYPE_UNSIGNED_CHAR: + ret_int =3D ret_char; + break; + =20 + case TYPE_INT: + case TYPE_UNSIGNED_INT: + break; + =20 + case TYPE_POINTER: + ret_int =3D ret_ptr; + break; + =20 + case TYPE_VISUAL_INFO: + //memcpy(args[nb_args], ret_ptr, sizeof(XVisualInfo)); + XFree(ret_ptr); + break; + =20 + case TYPE_CONST_CHAR: + { + strncpy(ret_string, ret_str, 32768); + break; + } + =20 + default: + fprintf(stderr, "unexpected ret type : %d\n", ret_type); + exit(-1); + break; + } + + return ret_int; +} +=20 +int doing_opengl =3D 0; +static int last_func_number =3D -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 =3D (Signature*)tab_opengl_calls[func_number]; + int ret_type =3D signature->ret_type; + int has_out_parameters =3D signature->has_out_parameters; + int nb_args =3D signature->nb_args; + int* args_type =3D signature->args_type; + int i; + int ret; + const int* args_size =3D NULL; + target_ulong saved_out_ptr[50]; + =20 + if (last_func_number =3D=3D _exit_process_func && func_number =3D=3D _ex= it_process_func) + { + last_func_number =3D -1; + return 0; + } + =20 + if (last_process_id =3D=3D 0) + { + last_process_id =3D pid; + } + else if (last_process_id !=3D pid) + { + fprintf(stderr, "damnit. I don't support (yet) opengl calls coming fro= m // processes... Sorry !\n"); + return 0; + } + =20 + if (dpy =3D=3D NULL) + { + dpy =3D XOpenDisplay(NULL); + memset(processTab, 0, sizeof(processTab)); + ret_string =3D malloc(32768); + } + =20 + reset_host_offset(); + =20 + if (nb_args) + { + if (memcpy_target_to_host(env, args, in_args, sizeof(target_ulong) * n= b_args) =3D=3D 0) + { + fprintf(stderr, "call %s pid=3D%d\n", tab_opengl_calls_name[func_num= ber], pid); + fprintf(stderr, "cannot get call parameters\n"); + return 0; + } + =20 + args_size =3D (const int*)get_host_read_pointer(env, in_args_size, siz= eof(int) * nb_args); + if (args_size =3D=3D NULL) + { + fprintf(stderr, "call %s pid=3D%d\n", tab_opengl_calls_name[func_num= ber], pid); + fprintf(stderr, "cannot get call parameters size\n"); + return 0; + } + } + =20 + for(i=3D0;icr[3]); + if( ! (func_number >=3D 0 && func_number < GL_N_CALLS) ) + { + fprintf(stderr, "func_number >=3D 0 && func_number < GL_N_CALLS failed= \n"); + return 0; + } + if (func_number =3D=3D glDrawElements_func) + { + fprintf(stderr, "entering call %s pid=3D%d\n", tab_opengl_calls_name[f= unc_number], pid); + } + ret =3D decode_call_int(env, func_number, pid, target_ret_string, in_arg= s, in_args_size); + if (func_number =3D=3D glDrawElements_func) + { + fprintf(stderr, "leaving call %s pid=3D%d\n", tab_opengl_calls_name[fu= nc_number], pid); + } + return ret; +} + +void helper_opengl(CPUState *env) +{ + doing_opengl =3D 1; + env->regs[R_EAX] =3D 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 =3D 0; +} Les fichiers binaires qemu.ori/target-i386/libGL.so.1 et qemu/target-i386/l= ibGL.so.1 sont diff=C3=A9rents. diff -Nrup --exclude=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/targe= t-i386/op.c qemu/target-i386/op.c =2D-- 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_ =20 #endif =20 +void helper_int99(void); + +void OPPROTO op_int99(void) +{ + helper_int99(); +} + /* operations with flags */ =20 /* update flags with T0 and T1 (add/sub case) */ diff -Nrup --exclude=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/targe= t-i386/opengl_client.c qemu/target-i386/opengl_client.c =2D-- qemu.ori/target-i386/opengl_client.c 1970-01-01 01:00:00.000000000 +0= 100 +++ 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= =2Eso + *=20 + * 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 U= SA + */ + + +/* 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 =3D -1; \ + if (detect < 0) \ + { \ + detect =3D (glXGetProcAddress((const GLubyte *)#x) !=3D NULL); \ + } \ + if (detect =3D=3D 0) \ + { \ + fprintf(stderr, "Symbol " #x " not available in server libGL\n"); \ + return 0; \ + }=20 + +#define CHECK_PROC(x) \ + static int detect =3D -1; \ + if (detect < 0) \ + { \ + detect =3D (glXGetProcAddress((const GLubyte *)#x) !=3D NULL); \ + } \ + if (detect =3D=3D 0) \ + { \ + fprintf(stderr, "Symbol " #x " not available in server libGL\n"); \ + return; \ + }=20 + +#include "opengl_func.h" + +#include "glgetv_cst.h" + +typedef struct +{ + int size; + int type; + int stride; + const void* ptr; +} VertexNormalColorPointerStruct; + +static VertexNormalColorPointerStruct vertexPointer =3D {0}; +static VertexNormalColorPointerStruct normalPointer =3D {0}; +static VertexNormalColorPointerStruct colorPointer =3D {0}; +static VertexNormalColorPointerStruct texCoordPointer[16] =3D {{0},{0},{0}= ,{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},}; +static int clientActiveTexture =3D 0; +static int pointerArraysEnable[6] =3D { 0 }; +static int texCoordPointerEnable[16] =3D { 0 }; + + +static struct sigaction old_action; +void sigsegv_handler(int signum, siginfo_t* info, void* ptr) +{ + struct ucontext* context =3D (struct ucontext*)ptr; + unsigned char* eip_ptr =3D context->uc_mcontext.gregs[REG_EIP]; + if (eip_ptr[0] =3D=3D 0xCD && eip_ptr[1] =3D=3D 0x99) + { + context->uc_mcontext.gregs[REG_EIP] +=3D 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, vo= id* 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 =3D -1; +static int stop_now =3D 0; + +static void sigint_exit_process_func(int ignored) +{ + stop_now =3D 1; + if (pid_fork > 0) + { + call_opengl(_exit_process_func, pid_fork, NULL, NULL, NULL); + pid_fork =3D 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 =3D 0; + if (init_done =3D=3D 0) + { + init_done =3D 1; + =20 + pid_fork =3D fork(); + if (pid_fork > 0) + { + struct sigaction action; + action.sa_sigaction =3D sigsegv_handler; + sigemptyset(&(action.sa_mask)); + action.sa_flags =3D 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 =3D 0; + } + if (WIFEXITED(status)) + { + exit(WEXITSTATUS(status)); + } + else + { + exit(0); + } + } + =20 + signal(SIGINT, real_sigint_exit_process_func); + =20 + struct sigaction action; + action.sa_sigaction =3D sigsegv_handler; + sigemptyset(&(action.sa_mask)); + action.sa_flags =3D SA_SIGINFO; + sigaction(SIGSEGV, &action, &old_action); + } +} + +static int try_to_put_into_phys_memory(void* addr, int len) +{ + int pagesize =3D getpagesize(); + int i; + void* aligned_addr =3D ((long)addr & (~(pagesize - 1))); + int to_end_page =3D (long)aligned_addr + pagesize - (long)addr; + char c =3D 0; + if (aligned_addr !=3D addr) + { + c +=3D ((char*)addr)[0]; + if (len <=3D to_end_page) + { + return c; + } + len -=3D to_end_page; + addr =3D aligned_addr + pagesize; + } + for(i=3D0;i=3D 0 && func_number < GL_N_CALLS) ) + { + fprintf(stderr, "func_number >=3D 0 && func_number < GL_N_CALLS failed= \n"); + return; + } + + Signature* signature =3D (Signature*)tab_opengl_calls[func_number]; + int ret_type =3D signature->ret_type; + int nb_args =3D signature->nb_args; + int* args_type =3D signature->args_type; + static long args[100] =3D {0}; + static int args_size[100]=3D{0}; + static double args_double[100]=3D{0}; + static char* ret_string =3D NULL; + int ret_int; + va_list list; + int i; + =20 + do_init(); + + if (ret_string =3D=3D NULL) + { + int pagesize =3D getpagesize(); + int nbPages =3D 32768 / pagesize; + posix_memalign(&ret_string, pagesize, 32768); + memset(ret_string, 0, 32768); + int ret =3D mlock(ret_string, 32768); + if (ret =3D=3D -1) + { + fprintf(stderr, "errno =3D %d, ENOMEM=3D%d, EPERM=3D%d, EINVAL=3D%d\= n", errno, ENOMEM, EPERM, EINVAL); + assert(0); + } + } + =20 + //fprintf(stderr, "%s\n", tab_opengl_calls_name[func_number]); + =20 + va_start(list, ret_ptr); + for(i=3D0;i=3D 0 && clientActiveTexture < 16); + } + else + if (func_number =3D=3D glEnableClientState_func) + { + int num =3D (int)args[0] - GL_VERTEX_ARRAY; + if (num =3D=3D GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY) + { + //printf("enable texture %d\n", clientActiveTexture); + texCoordPointerEnable[clientActiveTexture] =3D 1; + } + else + if (num >=3D 0 && num < 6) + { + //printf("enable feature %d\n", num); + pointerArraysEnable[num] =3D 1; + } + } + else if (func_number =3D=3D glDisableClientState_func) + { + int num =3D (int)args[0] - GL_VERTEX_ARRAY; + if (num =3D=3D GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY) + { + //printf("disable texture %d\n", clientActiveTexture); + texCoordPointerEnable[clientActiveTexture] =3D 0; + } + else + if (num >=3D 0 && num < 6) + { + //printf("disable feature %d\n", num); + pointerArraysEnable[num] =3D 0; + } + } + else if (func_number =3D=3D 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 =3D (int*)args[1]; + if (ptr) *ptr =3D 0; + ptr =3D (int*)args[2]; + if (ptr) *ptr =3D 0; + break; + } + =20 + case glXGetConfig_func: + { + *(int*)args[3] =3D 0; + break; + } + =20 + case glGetIntegerv_func: + { + int* ptr =3D (int*)args[1]; + int param =3D (int)args[0]; + i =3D 0; + while(limits[i].count) + { + if (limits[i].token =3D=3D param) + { + memset(ptr, 0, limits[i].count * sizeof(int)); + break; + } + i++; + } + if (limits[i].count =3D=3D 0) + { + fprintf(stderr, "unknown name for glGetIntegerv : %d\n", param); + } + args_size[1] =3D limits[i].count * sizeof(int); + break; + } + =20 + case glGetFloatv_func: + { + float* ptr =3D (float*)args[1]; + int param =3D (int)args[0]; + i =3D 0; + while(limits[i].count) + { + if (limits[i].token =3D=3D param) + { + memset(ptr, 0, limits[i].count * sizeof(float)); + break; + } + i++; + } + if (limits[i].count =3D=3D 0) + { + fprintf(stderr, "unknown name for glGetFloatv : %d\n", param); + } + args_size[1] =3D limits[i].count * sizeof(float); + break; + } + =20 + case glGetConvolutionParameteriv_func: + { + int* ptr =3D (int*)args[2]; + args_size[2] =3D (((int)args[1] =3D=3D GL_CONVOLUTION_BORDER_COLOR) = ? 4 : 1) * sizeof(int); + memset(ptr, 0, (((int)args[1] =3D=3D GL_CONVOLUTION_BORDER_COLOR) ? = 4 : 1) * sizeof(int)); + break; + } + =20 + case glXQueryExtension_func: + { + int* ptr; + ptr =3D (int*)args[1]; + if (ptr) *ptr =3D 0; + ptr =3D (int*)args[2]; + if (ptr) *ptr =3D 0; + break; + } + =20 + case glGenTextures_func: + { + assert(args[1]); + memset(args[1], 0, (int)args[0] * sizeof(int)); + args_size[1] =3D (int)args[0] * sizeof(int); + break; + } + =20 + case glGetTexLevelParameteriv_func: + { + int* ptr =3D (int*)args[3]; + assert(ptr); + *ptr =3D 0; + break; + } + =20 + case glGenProgramsARB_func: + { + assert(args[1]); + *(int*)args[1] =3D 0; + break; + } + =20 + case glXChooseFBConfig_func: + { + assert(args[3]); + *(int*)args[3] =3D 0; + break; + } + =20 + case glGetVertexAttribfvARB_func: + { + assert(args[2]); + memset(args[2], 0, (((int)args[1] =3D=3D GL_CURRENT_VERTEX_ATTRIB_AR= B) ? 4 : 1) * sizeof(float)); + args_size[2] =3D (((int)args[1] =3D=3D GL_CURRENT_VERTEX_ATTRIB_ARB)= ? 4 : 1) * sizeof(float); + break; + } + =20 + case glGetVertexAttribivARB_func: + { + assert(args[2]); + memset(args[2], 0, (((int)args[1] =3D=3D GL_CURRENT_VERTEX_ATTRIB_AR= B) ? 4 : 1) * sizeof(int)); + args_size[2] =3D (((int)args[1] =3D=3D GL_CURRENT_VERTEX_ATTRIB_ARB)= ? 4 : 1) * sizeof(int); + break; + } + =20 + case glGetVertexAttribdvARB_func: + { + assert(args[2]); + memset(args[2], 0, (((int)args[1] =3D=3D GL_CURRENT_VERTEX_ATTRIB_AR= B) ? 4 : 1) * sizeof(double)); + args_size[2] =3D (((int)args[1] =3D=3D GL_CURRENT_VERTEX_ATTRIB_ARB)= ? 4 : 1) * sizeof(double); + break; + } + =20 + case glGetProgramLocalParameterfvARB_func: + { + assert(args[2]); + memset(args[2], 0, 4 * sizeof(float)); + args_size[2] =3D 4 * sizeof(float); + break; + } + =20 + case glGetProgramLocalParameterdvARB_func: + { + assert(args[2]); + memset(args[2], 0, 4 * sizeof(double)); + args_size[2] =3D 4 * sizeof(double); + break; + } + =20 + case glGetProgramEnvParameterfvARB_func: + { + assert(args[2]); + memset(args[2], 0, 4 * sizeof(float)); + args_size[2] =3D 4 * sizeof(float); + break; + } + =20 + case glGetProgramEnvParameterdvARB_func: + { + assert(args[2]); + memset(args[2], 0, 4 * sizeof(double)); + args_size[2] =3D 4 * sizeof(double); + break; + } + =20 + case glGetProgramivARB_func: + { + assert(args[2]); + memset(args[2], 0, sizeof(int)); + break; + } + =20 + 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);*/ + } + =20 + default: + break; + } + =20 + if (signature->ret_type =3D=3D TYPE_CONST_CHAR) + { + try_to_put_into_phys_memory(ret_string, 32768); + } + =20 + // DO CALL + if (stop_now) + return; + =20 + ret_int =3D call_opengl(func_number, getpid(), (signature->ret_type =3D= =3D TYPE_CONST_CHAR) ? ret_string : NULL, args, args_size); + =20 + if (signature->ret_type =3D=3D TYPE_UNSIGNED_INT || + signature->ret_type =3D=3D TYPE_INT) + { + *(int*)ret_ptr =3D ret_int; + } + else if (signature->ret_type =3D=3D TYPE_UNSIGNED_CHAR || + signature->ret_type =3D=3D TYPE_CHAR) + { + *(char*)ret_ptr =3D ret_int; + } + else if (signature->ret_type =3D=3D TYPE_POINTER) + { + *(void**)ret_ptr =3D (void*)ret_int; + } + else if (signature->ret_type =3D=3D TYPE_CONST_CHAR) + { + char* ret_str =3D NULL; + if (func_number =3D=3D glXQueryExtensionsString_func) + { + static char* glXQueryExtensionsString_ret =3D NULL; + if (glXQueryExtensionsString_ret) free(glXQueryExtensionsString_ret); + glXQueryExtensionsString_ret =3D ret_str =3D strdup(ret_string); + } + else if (func_number =3D=3D glXQueryServerString_func) + { + static char* glXQueryServerString_ret[100] =3D {NULL}; + int name =3D (int)args[2]; + assert(name >=3D 0 && name < 100); + if (glXQueryServerString_ret[name]) free(glXQueryServerString_ret[na= me]); + glXQueryServerString_ret[name] =3D ret_str =3D strdup(ret_string); + } + else if (func_number =3D=3D glXGetClientString_func) + { + static char* glXGetClientString_ret[100] =3D {NULL}; + int name =3D (int)args[1]; + assert(name >=3D 0 && name < 100); + if (glXGetClientString_ret[name]) free(glXGetClientString_ret[name]); + glXGetClientString_ret[name] =3D ret_str =3D strdup(ret_string); + } + else if (func_number =3D=3D glGetString_func) + { + static char* glGetString_ret[10000] =3D {NULL}; + int name =3D (int)args[0]; + assert(name >=3D 0 && name < 10000); + if (glGetString_ret[name]) free(glGetString_ret[name]); + glGetString_ret[name] =3D ret_str =3D strdup(ret_string); + } + else + { + exit(-1); + } + *(char**)(ret_ptr) =3D ret_str; + } + =20 + /*switch (func_number) + { + case glXChooseVisual_func: + { + Display* dpy =3D args[0]; + int screen =3D (int)args[1]; + =20 + XVisualInfo temp, *vis; + long mask; + int n; + + mask =3D VisualScreenMask | VisualDepthMask | VisualClassMask; + temp.screen =3D screen; + temp.depth =3D DefaultDepth(dpy,screen); + temp.class =3D DefaultVisual(dpy,screen)->class; + temp.visualid =3D DefaultVisual(dpy,screen)->visualid; + mask |=3D VisualIDMask; + + vis =3D XGetVisualInfo( dpy, mask, &temp, &n ); + =20 + *(void**)(ret_ptr) =3D vis; + break; + } + =20 + 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 =3D 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; + =20 + mask =3D VisualScreenMask | VisualDepthMask | VisualClassMask; + temp.screen =3D screen; + temp.depth =3D DefaultDepth(dpy,screen); + temp.class =3D DefaultVisual(dpy,screen)->class; + temp.visualid =3D DefaultVisual(dpy,screen)->visualid; + mask |=3D VisualIDMask; + + vis =3D XGetVisualInfo( dpy, mask, &temp, &n ); + =20 + //do_opengl_call(glXChooseVisual_func, vis, dpy, screen, attribList); + =20 + return vis; +} + +const char *glXQueryServerString( Display *dpy, int screen, int name ) +{ + const char* ret =3D NULL; + do_opengl_call(glXQueryServerString_func, &ret, dpy, screen, name); + return ret; +} + +const char *glXGetClientString( Display *dpy, int name ) +{ + const char* ret =3D NULL; + do_opengl_call(glXGetClientString_func, &ret, dpy, name); + return ret; +} + +GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis, + GLXContext shareList, Bool direct ) +{ + GLXContext ret =3D NULL; + do_opengl_call(glXCreateContext_func, &ret, dpy, vis, shareList, direct); + printf("glXCreateContext =3D %p\n", ret); + return ret; +} + +GLXContext glXGetCurrentContext (void) +{ + GLXContext ret =3D NULL; + do_opengl_call(glXGetCurrentContext_func, &ret); + printf("glXGetCurrentContext =3D %p\n", ret); + return ret; +} + +GLXDrawable glXGetCurrentDrawable (void) +{ + GLXDrawable ret =3D 0; + do_opengl_call(glXGetCurrentDrawable_func, &ret); + printf("glXGetCurrentDrawable =3D %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 =3D 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 =3D {0}; + +static void _get_window_pos(Display *dpy, Window win, WindowPosStruct* pos) +{ + XWindowAttributes window_attributes_return; + Window child; + int x, y; + Window root =3D 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 =3D x; + pos->y =3D y; + pos->width =3D window_attributes_return.width; + pos->height =3D window_attributes_return.height; + pos->map_state =3D window_attributes_return.map_state; +} + +static GLXPbuffer pbuffer =3D NULL; + +static void _move_win_if_necessary(Display *dpy, Window win) +{ + if (pbuffer !=3D NULL && win =3D=3D pbuffer) + { + return; + } + =20 + WindowPosStruct pos; + _get_window_pos(dpy, win, &pos); + if (memcmp(&pos, &oldPos, sizeof(oldPos)) !=3D 0) + { + if (pos.map_state !=3D 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 =3D 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 =3D False; + do_opengl_call(glXIsDirect_func, &ret, dpy, ctx); + return ret; +} + +int glXGetConfig( Display *dpy, XVisualInfo *visual, + int attrib, int *value ) +{ + int ret =3D 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 =3D NULL; + +GLXFBConfig *glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ) +{ + GLXFBConfig * ret =3D NULL; + do_opengl_call(glXChooseFBConfig_func, &ret, dpy, screen, attribList, ni= tems); + fbConfig =3D ret =3D malloc(sizeof(GLXFBConfig) * (*nitems)); + int i; + for(i=3D0;i<*nitems;i++) + { + fbConfig[i] =3D i + 1; + } + printf("nitems =3D %d\n", *nitems); + return ret; +} + +GLXPbuffer glXCreatePbuffer(Display *dpy, + GLXFBConfig config, + const int *AttributeList) +{ + GLXPbuffer ret =3D NULL; + int i =3D (int)config - 1; + printf("fb config %d\n", i); + do_opengl_call(glXCreatePbuffer_func, &ret, dpy, i, AttributeList); + printf("pbuffer =3D %p\n", ret); + pbuffer =3D ret; + return ret; +} + +XVisualInfo *glXGetVisualFromFBConfig( Display *dpy, + GLXFBConfig config ) +{ + int screen =3D 0; + =20 + XVisualInfo temp, *vis; + long mask; + int n; + =20 + mask =3D VisualScreenMask | VisualDepthMask | VisualClassMask; + temp.screen =3D screen; + temp.depth =3D DefaultDepth(dpy,screen); + temp.class =3D DefaultVisual(dpy,screen)->class; + temp.visualid =3D DefaultVisual(dpy,screen)->visualid; + mask |=3D VisualIDMask; + + vis =3D XGetVisualInfo( dpy, mask, &temp, &n ); + =20 + int i =3D (int)config - 1; + do_opengl_call(glXGetVisualFromFBConfig_func, vis, dpy, i); + =20 + return vis; + =20 +} + +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 =3D 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, pa= rams); +} + +void glLightfv( GLenum light, GLenum pname, const GLfloat *params ) +{ + int size =3D 0; + switch(pname) + { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + case GL_POSITION: + size =3D 4; + break; + =20 + case GL_SPOT_DIRECTION: + size =3D 3; + break; + =20 + case GL_SPOT_EXPONENT: + case GL_SPOT_CUTOFF: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: + size =3D 1; + break; + =20 + default: + fprintf(stderr, "unhandled pname =3D %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 =3D 0; + switch(pname) + { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + case GL_EMISSION: + case GL_AMBIENT_AND_DIFFUSE: + size =3D 4; + break; + =20 + case GL_SHININESS: + size =3D 1; + break; + =20 + case GL_COLOR_INDEXES: + size =3D 3; + break; + =20 + default: + fprintf(stderr, "unhandled pname =3D %d\n", pname); + return; + } + do_opengl_call(glMaterialfv_func, NULL, face, pname, size, params); +} + +void glLightModelfv( GLenum pname, + const GLfloat *params ) +{ + int size =3D 0; + switch(pname) + { + case GL_LIGHT_MODEL_AMBIENT: + size =3D 4; + break; + =20 + case GL_LIGHT_MODEL_COLOR_CONTROL: + fprintf(stderr, "not sure how to handle GL_LIGHT_MODEL_COLOR_CONTROL= =2E Exiting\n"); + return; + =20 + case GL_LIGHT_MODEL_LOCAL_VIEWER: + case GL_LIGHT_MODEL_TWO_SIDE: + size =3D 1; + break; + =20 + default: + fprintf(stderr, "unhandled pname =3D %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; + =20 + case GL_MAP1_VERTEX_4: + case GL_MAP1_COLOR_4: + case GL_MAP1_TEXTURE_COORD_4: + return 4; + break; + =20 + case GL_MAP1_INDEX: + case GL_MAP1_TEXTURE_COORD_1: + return 1; + break; + =20 + case GL_MAP1_TEXTURE_COORD_2: + return 2; + break; + =20 + default: + fprintf(stderr, "unhandled target =3D %d\n", target); + return 0; + } +} + +void glMap1f( GLenum target, + GLfloat u1, + GLfloat u2, + GLint stride, + GLint order, + const GLfloat *points ) +{ + int num_points =3D order; + int multiplier =3D glMap1_get_multiplier(target); + if (multiplier) + { + num_points *=3D 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 =3D order; + int multiplier =3D glMap1_get_multiplier(target); + if (multiplier) + { + num_points *=3D 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; + =20 + case GL_MAP2_VERTEX_4: + case GL_MAP2_COLOR_4: + case GL_MAP2_TEXTURE_COORD_4: + return 4; + break; + =20 + case GL_MAP2_INDEX: + case GL_MAP2_TEXTURE_COORD_1: + return 1; + break; + =20 + case GL_MAP2_TEXTURE_COORD_2: + return 2; + break; + =20 + default: + fprintf(stderr, "unhandled target =3D %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 =3D uorder * vorder; + int multiplier =3D glMap2_get_multiplier(target); + if (multiplier) + { + num_points *=3D 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 =3D uorder * vorder; + int multiplier =3D glMap2_get_multiplier(target); + if (multiplier) + { + num_points *=3D 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 =3D n; + switch(type) + { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + break; + =20 + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_2_BYTES: + size *=3D 2; + break; + =20 + case GL_3_BYTES: + size *=3D 3; + break; + =20 + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + case GL_4_BYTES: + size *=3D 4; + break; + =20 + default: + fprintf(stderr, "unsupported type =3D %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 GL= void *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 =3D=3D 1 && d =3D=3D NULL && p_tab_prog !=3D 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 GLcharA= RB *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, ima= geSize, 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, i= mageSize, imageSize, data); +} + +void EXT_FUNC(glPointParameterfvARB)(GLenum pname, const GLfloat * params) +{ + int size; + CHECK_PROC(glPointParameterfvARB); + size =3D (pname =3D=3D 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 *p= arams) +{ + 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 inde= x, GLfloat *params) +{ + CHECK_PROC(glGetProgramLocalParameterfvARB); + do_opengl_call(glGetProgramLocalParameterfvARB_func, NULL, target, index= , params); +} + +void EXT_FUNC(glGetProgramLocalParameterdvARB) (GLenum target, GLuint inde= x, 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 *para= ms) +{ + 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; + =20 + case GL_LUMINANCE_ALPHA: + return 2; + break; + =20 + case GL_RGB: + case GL_BGR: + return 3; + break; + =20 + case GL_RGBA: + case GL_BGRA: + return 4; + break; + =20 + 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 =3D width * getTexImageFactorFromFormat(format); + =20 + if (type !=3D GL_UNSIGNED_BYTE) + { + fprintf(stderr, "unknown pixel type : %d\n", type); + return; + } + + if (pixels =3D=3D NULL) size =3D 0; + do_opengl_call(glTexImage1D_func, NULL, target, level, internalFormat, w= idth, 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 =3D width * height * getTexImageFactorFromFormat(format); + =20 + if (type !=3D GL_UNSIGNED_BYTE) + { + fprintf(stderr, "unknown pixel type : %d\n", type); + return; + } + + if (pixels =3D=3D NULL) size =3D 0; + do_opengl_call(glTexImage2D_func, NULL, target, level, internalFormat, w= idth, 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 =3D width * height * getTexImageFactorFromFormat(format); + =20 + if (type !=3D GL_UNSIGNED_BYTE) + { + fprintf(stderr, "unknown pixel type : %d\n", type); + return; + } + + do_opengl_call(glTexSubImage2D_func, NULL, target, level, xoffset, yoffs= et, 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 =3D width * height * depth * getTexImageFactorFromFormat(format= ); + =20 + if (type !=3D GL_UNSIGNED_BYTE) + { + fprintf(stderr, "unknown pixel type : %d\n", type); + return; + } + + do_opengl_call(glTexImage3D_func, NULL, target, level, internalFormat, w= idth, 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 =3D (pname =3D=3D 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 =3D (pname =3D=3D 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 =3D=3D GL_FOG_COLOR) + size =3D 4; + else + size =3D 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 )=20 +{ + int size =3D 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 =3D (pname =3D=3D 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 =3D (pname =3D=3D 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 =3D size; + vertexPointer.type =3D type; + vertexPointer.stride =3D stride; + vertexPointer.ptr =3D ptr; +} + +void glNormalPointer( GLenum type, + GLsizei stride, + const GLvoid *ptr ) +{ + //printf("glNormalPointer %d %d %p\n", type, stride, ptr); + normalPointer.size =3D 3; + normalPointer.type =3D type; + normalPointer.stride =3D stride; + normalPointer.ptr =3D 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 =3D size; + colorPointer.type =3D type; + colorPointer.stride =3D stride; + colorPointer.ptr =3D ptr; +} + +void glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLv= oid *ptr ) +{ + //printf("glTexCoordPointer %d %d %d %p\n", size, type, stride, ptr); + texCoordPointer[clientActiveTexture].size =3D size; + texCoordPointer[clientActiveTexture].type =3D type; + texCoordPointer[clientActiveTexture].stride =3D stride; + texCoordPointer[clientActiveTexture].ptr =3D ptr; +} + +static int getMulFactorFromPointerArray(VertexNormalColorPointerStruct* ar= ray) +{ + switch(array->type) + { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + return array->stride + array->size; + break; + =20 + case GL_SHORT: + case GL_UNSIGNED_SHORT: + return array->stride + 2 * array->size; + break; + =20 + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + return array->stride + 4 * array->size; + break; + =20 + case GL_DOUBLE: + return array->stride + 8 * array->size; + break; + + default: + fprintf(stderr, "unsupported type =3D %d\n", array->type); + return 0; + } +} + +void _glArraySend(int func, VertexNormalColorPointerStruct* array, int nbE= lts) +{ + int data_size =3D nbElts * getMulFactorFromPointerArray(array); + if (func =3D=3D glNormalPointer_func) + do_opengl_call(func, NULL, + array->type, array->stride, data_size, data_size, arra= y->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); + } + =20 + if (pointerArraysEnable[GL_NORMAL_ARRAY - GL_VERTEX_ARRAY]) + { + //printf("normal enable\n"); + _glArraySend(glNormalPointer_func, &normalPointer, nbElts); + } + =20 + if (pointerArraysEnable[GL_COLOR_ARRAY - GL_VERTEX_ARRAY]) + { + //printf("color enable\n"); + _glArraySend(glColorPointer_func, &colorPointer, nbElts); + } + =20 + //if (pointerArraysEnable[GL_TEXTURE_COORD_ARRAY - GL_VERTEX_ARRAY]) + if (texCoordPointerEnable[clientActiveTexture]) + { + printf("texture enable\n"); + _glArraySend(glTexCoordPointer_func, &texCoordPointer[clientActiveText= ure], 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 =3D count; + int maxIndice =3D -1; + =20 + if (count =3D=3D 0) return; + =20 + switch(type) + { + case GL_UNSIGNED_BYTE: + { + unsigned char* c =3D indices; + for(i=3D0;i maxIndice) maxIndice =3D c[i]; + } + break; + } + =20 + case GL_UNSIGNED_SHORT: + { + size *=3D 2; + unsigned short* s =3D indices; + for(i=3D0;i maxIndice) maxIndice =3D s[i]; + } + break; + } + =20 + case GL_UNSIGNED_INT: + { + size *=3D 4; + unsigned int* _int =3D indices; + for(i=3D0;i maxIndice) maxIndice =3D _int[i]; + } + break; + } + + default: + fprintf(stderr, "unsupported type =3D %d\n", type); + return; + } + =20 + //printf("glDrawElements : %d %d %d %p %d\n", mode, count, type, indices= , maxIndice); + +#if 0 + do_opengl_call(glBegin_func, NULL, mode); + if (type =3D=3D GL_UNSIGNED_INT) + { + for(i=3D0;i void glShaderSourceARB (GLhandleARB handle , const GLcharARB* prog)= */ +static const int glShaderSourceARB_signature[] =3D { TYPE_NONE, 0, 2, TYPE= _INT, TYPE_NULL_TERMINATED_STRING }; + +/* GLint glGetUniformLocationARB (GLhandleARB handle, const GLcharARB *txt= ) */ +static const int glGetUniformLocationARB_signature[] =3D { TYPE_INT, 0, 2,= TYPE_INT, TYPE_NULL_TERMINATED_STRING }; + +/* void EXT_FUNC(glGetVertexAttribfvARB)(GLuint index, GLenum pname, GLflo= at *params) */ +static const int glGetVertexAttribfvARB_signature[] =3D { TYPE_NONE, 1, 3,= TYPE_INT, TYPE_INT, TYPE_OUT_FLOAT_ARRAY }; +static const int glGetVertexAttribivARB_signature[] =3D { TYPE_NONE, 1, 3,= TYPE_INT, TYPE_INT, TYPE_OUT_INT_ARRAY }; +static const int glGetVertexAttribdvARB_signature[] =3D { TYPE_NONE, 1, 3,= TYPE_INT, TYPE_INT, TYPE_OUT_DOUBLE_ARRAY }; + +/* void EXT_FUNC(glGetProgramLocalParameterfvARB) (GLenum target, GLuint i= ndex, GLfloat *params) */ +static const int glGetProgramLocalParameterfvARB_signature[] =3D { TYPE_NO= NE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_FLOAT_ARRAY }; +static const int glGetProgramLocalParameterdvARB_signature[] =3D { TYPE_NO= NE, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_DOUBLE_ARRAY }; +static const int glGetProgramEnvParameterfvARB_signature[] =3D { TYPE_NONE= , 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_FLOAT_ARRAY }; +static const int glGetProgramEnvParameterdvARB_signature[] =3D { TYPE_NONE= , 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_DOUBLE_ARRAY }; + +/* void EXT_FUNC(glGetProgramivARB) (GLenum target, GLenum pname, GLint *p= arams) */ +static const int glGetProgramivARB_signature[] =3D { TYPE_NONE, 1, 3, TYPE= _INT, TYPE_INT, TYPE_OUT_INT_POINTER }; + +/* void EXT_FUNC(glGetProgramStringARB) (GLenum target, GLenum pname, GLvo= id *string) */ +static const int glGetProgramStringARB_signature[] =3D { 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[] =3D { TYPE_NONE, 0, 5, TYPE_I= NT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; +static const int glNormalPointer_signature[] =3D { TYPE_NONE, 0, 4, TYPE_I= NT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; +static const int glColorPointer_signature[] =3D { TYPE_NONE, 0, 5, TYPE_IN= T, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; +static const int glTexCoordPointer_signature[] =3D { TYPE_NONE, 0, 5, TYPE= _INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; +static const int glDrawArrays_signature[] =3D { 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[] =3D { TYPE_NONE, 0, 4, TYPE_IN= T, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; + +#include "gl_func.h" diff -Nrup --exclude=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/targe= t-i386/parse_gl_h.c qemu/target-i386/parse_gl_h.c =2D-- 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 + *=20 + * 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") !=3D NULL) || + (strstr(name, "EXT") !=3D NULL) || + (strstr(name, "ATI") !=3D NULL) || + (strstr(name, "NV") !=3D NULL) || + (strstr(name, "MESA") !=3D NULL) || + (strstr(name, "SGI") !=3D NULL); +} + +char* get_arg_type(char* s) +{ + while(*s =3D=3D ' ' || *s =3D=3D '\t') s++; + char* n =3D s; + char* c =3D strstr(n, "const"); + if (c) + n +=3D 6; + =20 + char* t =3D strstr(n, " "); + if (t) + { + if (t[1] =3D=3D '*') + t +=3D 2; + t[0] =3D 0; + char* ori =3D t; + t =3D strstr(t+1, "["); + if (t) + { + memmove(ori, t, strlen(t)); + strstr(ori, "]")[1] =3D 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") =3D=3D 0) + return("TYPE_NONE"); + else if (strcmp(type, "GLbyte") =3D=3D 0) + return("TYPE_CHAR"); + else if (strcmp(type, "GLubyte") =3D=3D 0 || + strcmp(type, "GLboolean") =3D=3D 0) + return("TYPE_UNSIGNED_CHAR"); + else if (strcmp(type, "GLshort") =3D=3D 0) + return("TYPE_SHORT"); + else if (strcmp(type, "GLushort") =3D=3D 0 || + strcmp(type, "GLhalfNV") =3D=3D 0) + return("TYPE_UNSIGNED_SHORT"); + else if (strcmp(type, "GLint") =3D=3D 0 || + strcmp(type, "GLsizei") =3D=3D 0) + return("TYPE_INT"); + else if (strcmp(type, "GLenum") =3D=3D 0 || + strcmp(type, "GLuint") =3D=3D 0 || + strcmp(type, "GLhandleARB") =3D=3D 0 || + strcmp(type, "GLbitfield") =3D=3D 0) + return("TYPE_UNSIGNED_INT"); + else if (strcmp(type, "GLfloat") =3D=3D 0 || + strcmp(type, "GLclampf") =3D=3D 0) + return("TYPE_FLOAT"); + else if (strcmp(type, "GLdouble") =3D=3D 0 || + strcmp(type, "GLclampd") =3D=3D 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[] =3D + { + { "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" }, + =20 + { "f", "FLOAT", "float", "float" }, + { "d", "DOUBLE", "double", "double" }, + }; + =20 + if (desc->nargs =3D=3D 0) + return 0; + =20 + int i , j; + =20 + static char signatures[14][4][20] =3D {0}; + char signature[10]; + =20 + for(i=3D0;i<14;i++) + { + for(j=3D1;j<=3D4;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] =3D=3D 0) + sprintf(signatures[i][j], "TYPE_%d%s", j, my_tab[i].signature_= type_name); + *p_signature_type_name =3D signatures[i][j]; + } + if (p_c_type_name) *p_c_type_name =3D my_tab[i].c_type_name; + return 1; + } + } + } + return 0; +} + +int parse(FILE* f, FuncDesc* funcDesc, int ignoreEXT) +{ + char buffer[256]; + int funcDescCount =3D 0; + while(fgets(buffer, 256, f)) + { + if (strncmp(buffer, "GLAPI", 5) =3D=3D 0 && strstr(buffer, "APIENTRY")= && strstr(buffer, "(")) + { + if (strstr(buffer, "glDrawArrays")) + { + continue; + } + if (strstr(buffer, "glGetIntegerv")) + { + continue; + } + =20 + char** args =3D malloc(15 * sizeof(char*)); + int narg =3D 0; + char* type =3D buffer + 6; + char* n =3D strstr(type, "GLAPIENTRY") ? strstr(type, "GLAPIENTRY") = : strstr(type, "APIENTRY"); + int skip_length =3D strstr(type, "GLAPIENTRY") ? 11 : 9; + n[-1] =3D 0; + type =3D strdup(type); + n +=3D skip_length; + char* fonc =3D n; + n =3D strstr(n, "("); + if (n[-1] =3D=3D ' ') n[-1] =3D 0; + n[0] =3D 0; + fonc =3D strdup(fonc); + /*if (strstr(fonc, "glLockArraysEXT") || strstr(fonc, "glUnlockArray= sEXT")) + { + } + else*/ + if ((ignoreEXT =3D=3D 1 && isExt(fonc)) || (ignoreEXT =3D=3D 0 && !i= sExt(fonc))) + { + free(type); + free(fonc); + continue; + } + n++; + while(1) + { + char* virg =3D strstr(n, ","); + if (virg) + { + args[narg] =3D n; + virg[0] =3D 0; + args[narg] =3D get_arg_type(args[narg]); + narg++; + n =3D virg+1; + } + else + break; + } + while (strstr(n, ")") =3D=3D 0) + { + fgets(buffer, 256, f); + n =3D buffer; + while(1) + { + char* virg =3D strstr(n, ","); + if (virg) + { + args[narg] =3D n; + virg[0] =3D 0; + args[narg] =3D get_arg_type(args[narg]); + narg++; + n =3D virg+1; + } + else + break; + } + } + char* par =3D strstr(n, ")"); + args[narg] =3D n; + par[0] =3D 0; + args[narg] =3D get_arg_type(args[narg]); + narg++; + int i; + =20 + =20 + /*printf("%s %s (", type, fonc); + for(i=3D0;i=3D 0) + { + j =3D funcDesc[i].nargs-1; + if (strstr(funcDesc[i].args[j], "[16]") =3D=3D NULL) + { + pointer |=3D strstr(funcDesc[i].args[j], "*") !=3D NULL; + pointer |=3D strstr(funcDesc[i].args[j], "[") !=3D NULL; + } + } + } + } + if (pointer && funcDesc[i].nargs =3D=3D 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] =3D strdup("GLfloat m[16]"); + else + funcDesc[i].args[0] =3D strdup("GLdouble m[16]"); + pointer =3D 0; + } + if (pointer =3D=3D 0) + { + funcDesc[i].ok =3D 1; + if (first =3D=3D 1) + { + first =3D 0; + } + fprintf(header, " %s_func,\n", funcDesc[i].name); + if (funcDesc[i].nargs =3D=3D 1 && strcmp(funcDesc[i].args[0], "voi= d") =3D=3D 0) + { + funcDesc[i].nargs =3D 0; + } + /*printf("%s %s (", funcDesc[i].type, funcDesc[i].name); + for(j=3D0;jis_jmp =3D 3; } =20 +extern int enable_gl; + /* an interrupt is different from an exception because of the priviledge checks */ static void gen_interrupt(DisasContext *s, int intno,=20 target_ulong cur_eip, target_ulong next_eip) { + if (enable_gl && intno =3D=3D 0x99) + { + gen_op_int99(); + } + else + { if (s->cc_op !=3D 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 =3D 3; + } } =20 static void gen_debug(DisasContext *s, target_ulong cur_eip) diff -Nrup --exclude=3DCVS --exclude=3D'*~' --exclude=3D'config-host*' --ex= clude=3DMakefile --exclude=3Dconfig.mak --exclude=3Dconfig.h qemu.ori/vl.c = qemu/vl.c =2D-- 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 =3D -1; int acpi_enabled =3D 1; int fd_bootchk =3D 1; int no_reboot =3D 0; +int enable_gl =3D 0; =20 /***********************************************************/ /* x86 ISA bus support */ @@ -842,6 +843,8 @@ static int timer_load(QEMUFile *f, void=20 return 0; } =20 +extern int doing_opengl; + #ifdef _WIN32 void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,=20 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PT= R dw2) @@ -886,8 +889,9 @@ static void host_alarm_handler(int host_ SetEvent(host_alarm); #endif CPUState *env =3D cpu_single_env; =2D if (env) { =2D /* 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 =3D env; =2D + =20 if (shutdown_requested) { ret =3D EXCP_INTERRUPT; break; @@ -5934,6 +5938,7 @@ void help(void) "-std-vga simulate a standard VGA card with VESA Bochs E= xtensions\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, + =20 +#ifdef TARGET_I386 + QEMU_OPTION_enable_gl, +#endif }; =20 typedef struct QEMUOption { @@ -6094,6 +6103,10 @@ const QEMUOption qemu_options[] =3D { { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, { "no-acpi", 0, QEMU_OPTION_no_acpi }, { "no-reboot", 0, QEMU_OPTION_no_reboot }, + =20 +#ifdef TARGET_I386 + { "enable-gl", 0, QEMU_OPTION_enable_gl }, +#endif { NULL }, }; =20 @@ -6741,6 +6754,11 @@ int main(int argc, char **argv) case QEMU_OPTION_no_reboot: no_reboot =3D 1; break; +#ifdef TARGET_I386 + case QEMU_OPTION_enable_gl: + enable_gl =3D 1; + break; +#endif } } } --Boundary-00=_JvMXFKLuzxMbCe1--