summaryrefslogtreecommitdiff
path: root/meta/packages
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages')
-rw-r--r--meta/packages/qemu/qemu-0.9.1+svnr6190/qemu-add-gl-host-code.patch33906
-rw-r--r--meta/packages/qemu/qemu_svn.bb6
2 files changed, 33910 insertions, 2 deletions
diff --git a/meta/packages/qemu/qemu-0.9.1+svnr6190/qemu-add-gl-host-code.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/qemu-add-gl-host-code.patch
new file mode 100644
index 0000000000..23aef3830a
--- /dev/null
+++ b/meta/packages/qemu/qemu-0.9.1+svnr6190/qemu-add-gl-host-code.patch
@@ -0,0 +1,33906 @@
+Index: trunk/Makefile.target
+===================================================================
+--- trunk.orig/Makefile.target 2009-01-19 23:00:33.000000000 +0000
++++ trunk/Makefile.target 2009-01-19 23:08:18.000000000 +0000
+@@ -199,6 +199,10 @@
+ CPPFLAGS+=-I$(SRC_PATH)/fpu
+ LIBOBJS+= op_helper.o helper.o
+
++ifeq ($(TARGET_BASE_ARCH), i386)
++LIBOBJS+=helper_opengl.o opengl_exec.o
++endif
++
+ ifeq ($(TARGET_BASE_ARCH), arm)
+ LIBOBJS+= neon_helper.o iwmmxt_helper.o
+ endif
+@@ -277,6 +281,21 @@
+ cpu-exec.o: cpu-exec.c
+ $(CC) $(HELPER_CFLAGS) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
+
++parse_gl_h: parse_gl_h.c
++ $(CC) -g -o $@ $<
++server_stub.c: parse_gl_h
++ ./parse_gl_h
++gl_func.h: parse_gl_h
++ ./parse_gl_h
++GL_CFLAGS := -Wall -g -O2 -fno-strict-aliasing
++opengl_func.h: gl_func.h
++helper_opengl.o: helper_opengl.c opengl_func.h server_stub.c
++ $(CC) $(GL_CFLAGS) $(DEFINES) -c -o $@ $< -I.. -I. -I../fpu -I../target-i386 -DNEED_CPU_H
++gl_beginend.h: ../target-i386/beginend_funcs.sh
++ $< > $@
++opengl_exec.o : opengl_exec.c server_stub.c gl_func.h opengl_func.h gl_beginend.h
++ $(CC) $(GL_CFLAGS) $(DEFINES) -c -o $@ $< -I. -I../target-i386
++
+ #########################################################
+ # Linux user emulator target
+
+@@ -639,7 +658,7 @@
+ OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
+ OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
+ OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
+-CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
++CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE -DTARGET_OPENGL_OK
+ endif
+ ifeq ($(TARGET_BASE_ARCH), ppc)
+ CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
+@@ -774,7 +793,7 @@
+ endif
+
+ $(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a
+- $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS)
++ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS) -lGL -lGLU
+
+ endif # !CONFIG_USER_ONLY
+
+Index: trunk/hw/vmware_vga.c
+===================================================================
+--- trunk.orig/hw/vmware_vga.c 2009-01-05 11:10:15.000000000 +0000
++++ trunk/hw/vmware_vga.c 2009-01-19 23:06:08.000000000 +0000
+@@ -485,6 +485,8 @@
+
+ #define CMD(f) le32_to_cpu(s->cmd->f)
+
++static uint32_t last_cmd;
++
+ static inline int vmsvga_fifo_empty(struct vmsvga_state_s *s)
+ {
+ if (!s->config || !s->enable)
+@@ -494,11 +496,18 @@
+
+ static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s)
+ {
+- uint32_t cmd = s->fifo[CMD(stop) >> 2];
+- s->cmd->stop = cpu_to_le32(CMD(stop) + 4);
+- if (CMD(stop) >= CMD(max))
++ int offset = CMD(stop);
++
++ if (unlikely(s->cmd->next_cmd == s->cmd->stop)) {
++ fprintf(stderr, "%s: FIFO empty during CMD %i\n",
++ __FUNCTION__, last_cmd);
++ return 0x00000000;
++ }
++
++ s->cmd->stop = cpu_to_le32(offset + 4);
++ if (offset + 4 >= CMD(max))
+ s->cmd->stop = s->cmd->min;
+- return cmd;
++ return s->fifo[offset >> 2];
+ }
+
+ static inline uint32_t vmsvga_fifo_read(struct vmsvga_state_s *s)
+@@ -508,12 +517,12 @@
+
+ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
+ {
+- uint32_t cmd, colour;
++ uint32_t colour;
+ int args = 0;
+ int x, y, dx, dy, width, height;
+ struct vmsvga_cursor_definition_s cursor;
+ while (!vmsvga_fifo_empty(s))
+- switch (cmd = vmsvga_fifo_read(s)) {
++ switch (last_cmd = vmsvga_fifo_read(s)) {
+ case SVGA_CMD_UPDATE:
+ case SVGA_CMD_UPDATE_VERBOSE:
+ x = vmsvga_fifo_read(s);
+@@ -613,7 +622,7 @@
+ while (args --)
+ vmsvga_fifo_read(s);
+ printf("%s: Unknown command 0x%02x in SVGA command FIFO\n",
+- __FUNCTION__, cmd);
++ __FUNCTION__, last_cmd);
+ break;
+ }
+
+Index: trunk/kqemu.c
+===================================================================
+--- trunk.orig/kqemu.c 2009-01-05 11:10:24.000000000 +0000
++++ trunk/kqemu.c 2009-01-19 23:06:08.000000000 +0000
+@@ -84,6 +84,8 @@
+ int qpi_io_memory;
+ uint32_t kqemu_comm_base; /* physical address of the QPI communication page */
+
++extern int enable_gl;
++
+ #define cpuid(index, eax, ebx, ecx, edx) \
+ asm volatile ("cpuid" \
+ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
+@@ -867,6 +869,22 @@
+ else
+ env->hflags &= ~HF_OSFXSR_MASK;
+
++ /* OPENGL Stuff */
++ if (enable_gl && ((env->hflags & HF_CPL_MASK) == 3)) {
++ int index = (env->eip >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
++ if (env->segs[R_CS].base != 0)
++ fprintf(stderr, "env->segs[R_CS].base != 0 !\n");
++ else if (__builtin_expect(env->tlb_table[1][index].addr_code !=
++ (env->eip & TARGET_PAGE_MASK), 0))
++ ldub_code(env->eip);
++
++ if (env->tlb_table[1][index].addend) {
++ unsigned char *ptr = env->eip + env->tlb_table[1][index].addend;
++ if (ptr[0] == 0xCD && ptr[1] == 0x99)
++ helper_opengl();
++ }
++ }
++
+ #ifdef DEBUG
+ if (loglevel & CPU_LOG_INT) {
+ fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
+Index: trunk/sdl.c
+===================================================================
+--- trunk.orig/sdl.c 2009-01-19 23:00:33.000000000 +0000
++++ trunk/sdl.c 2009-01-19 23:28:22.000000000 +0000
+@@ -26,6 +26,7 @@
+ #include "sysemu.h"
+
+ #include <SDL.h>
++#include <SDL_syswm.h>
+
+ #ifndef _WIN32
+ #include <signal.h>
+@@ -50,6 +51,10 @@
+ static int guest_x, guest_y;
+ static SDL_Cursor *guest_sprite = 0;
+
++#ifdef TARGET_OPENGL_OK
++extern void opengl_exec_set_parent_window(Display* _dpy, Window _parent_window);
++#endif
++
+ static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
+ {
+ // printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
+@@ -58,6 +63,7 @@
+
+ static void sdl_resize(DisplayState *ds, int w, int h)
+ {
++ SDL_SysWMinfo info;
+ int flags;
+
+ // printf("resizing to %d %d\n", w, h);
+@@ -72,6 +78,17 @@
+ height = h;
+
+ again:
++ if (ds->data != NULL) {
++ SDL_VERSION(&info.version);
++ SDL_GetWMInfo(&info);
++#ifdef TARGET_OPENGL_OK
++ if (info.subsystem == SDL_SYSWM_X11 && info.info.x11.display)
++ opengl_exec_set_parent_window(info.info.x11.display,
++ RootWindow(info.info.x11.display,
++ DefaultScreen(info.info.x11.display)));
++#endif
++ }
++
+ screen = SDL_SetVideoMode(w, h, 0, flags);
+ if (!screen) {
+ fprintf(stderr, "Could not open SDL display\n");
+@@ -86,6 +103,13 @@
+ fprintf(stderr, "Could not open SDL display\n");
+ exit(1);
+ }
++
++ SDL_VERSION(&info.version);
++ SDL_GetWMInfo(&info);
++#ifdef TARGET_OPENGL_OK
++ opengl_exec_set_parent_window(info.info.x11.display, info.info.x11.window);
++#endif
++
+ ds->data = screen->pixels;
+ ds->linesize = screen->pitch;
+ ds->depth = screen->format->BitsPerPixel;
+@@ -574,6 +598,10 @@
+ line = image;
+ for (x = 0; x < width; x ++, dst ++) {
+ switch (bpp) {
++ case 32:
++ src = *(line ++); src |= *(line ++);
++ src = *(line ++); src |= *(line ++);
++ break;
+ case 24:
+ src = *(line ++); src |= *(line ++); src |= *(line ++);
+ break;
+@@ -643,6 +671,7 @@
+ ds->dpy_fill = sdl_fill;
+ ds->mouse_set = sdl_mouse_warp;
+ ds->cursor_define = sdl_mouse_define;
++ ds->data = NULL;
+
+ sdl_resize(ds, 640, 400);
+ sdl_update_caption();
+Index: trunk/target-i386/beginend_funcs.sh
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ trunk/target-i386/beginend_funcs.sh 2009-01-19 23:06:08.000000000 +0000
+@@ -0,0 +1,23 @@
++#! /bin/sh
++# Copyright 2008 (C) Intel Corporation
++#
++# echo names of functions that are legal between a glBegin and glEnd pair.
++echo -e MAGIC_MACRO\(glVertex{2,3,4}{s,i,f,d}{,v}\)\\n
++echo -e MAGIC_MACRO\(glTexCoord{1,2,3,4}{s,i,f,d}{,v}\)\\n
++echo -e MAGIC_MACRO\(glMultiTexCoord{1,2,3,4}{s,i,f,d}{,v}\)\\n
++echo -e MAGIC_MACRO\(glNormal3{b,s,i,f,d}{,v}\)\\n
++echo -e MAGIC_MACRO\(glFogCoord{f,d}{,v}\)\\n
++echo -e MAGIC_MACRO\(glColor{3,4}{b,s,i,f,d,ub,us,ui}{,v}\)\\n
++echo -e MAGIC_MACRO\(glSecondaryColor3{b,s,i,f,d,ub,us,ui}{,v}\)\\n
++echo -e MAGIC_MACRO\(glIndex{s,i,f,d,ub}{,v}\)\\n
++echo -e MAGIC_MACRO\(glVertexAttrib{1,2,3,4}{s,f,d}{,v}\)\\n
++echo -e MAGIC_MACRO\(glVertexAttrib4{b,i,ub,us,ui}v\)\\n
++echo -e MAGIC_MACRO\(glVertexAttrib4Nub\)\\n
++echo -e MAGIC_MACRO\(glVertexAttrib4N{b,s,i,ub,us,ui}v\)\\n
++echo -e MAGIC_MACRO\(glArrayElement\)\\n
++echo -e MAGIC_MACRO\(glEvalCoord{1,2}{f,d}{,v}\)\\n
++echo -e MAGIC_MACRO\(glEvalPoint{1,2}\)\\n
++echo -e MAGIC_MACRO\(glMaterial{i,f}{,v}\)\\n
++echo -e MAGIC_MACRO\(glCallList\)\\n
++echo -e MAGIC_MACRO\(glCallLists\)\\n
++echo -e MAGIC_MACRO\(glEdgeFlag{,v}\)\\n
+Index: trunk/target-i386/ghash.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ trunk/target-i386/ghash.c 2009-01-19 23:06:08.000000000 +0000
+@@ -0,0 +1,347 @@
++/* This is a modified and simplified version of original ghash.c */
++
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++
++#include <stdlib.h>
++
++#include "ghash.h"
++
++#define HASH_TABLE_MIN_SIZE 11
++#define HASH_TABLE_MAX_SIZE 13845163
++
++#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
++
++
++typedef struct _SimpleHashNode SimpleHashNode;
++
++struct _SimpleHashNode
++{
++ int key;
++ void* value;
++ SimpleHashNode *next;
++};
++
++struct _SimpleHashTable
++{
++ int size;
++ int nnodes;
++ SimpleHashNode **nodes;
++ SimpleDestroyNotify value_destroy_func;
++};
++
++static const unsigned int simple_primes[] =
++{
++ 11,
++ 19,
++ 37,
++ 73,
++ 109,
++ 163,
++ 251,
++ 367,
++ 557,
++ 823,
++ 1237,
++ 1861,
++ 2777,
++ 4177,
++ 6247,
++ 9371,
++ 14057,
++ 21089,
++ 31627,
++ 47431,
++ 71143,
++ 106721,
++ 160073,
++ 240101,
++ 360163,
++ 540217,
++ 810343,
++ 1215497,
++ 1823231,
++ 2734867,
++ 4102283,
++ 6153409,
++ 9230113,
++ 13845163,
++};
++
++static const unsigned int simple_nprimes = sizeof (simple_primes) / sizeof (simple_primes[0]);
++
++unsigned int simple_spaced_primes_closest (unsigned int num)
++{
++ int i;
++
++ for (i = 0; i < simple_nprimes; i++)
++ if (simple_primes[i] > num)
++ return simple_primes[i];
++
++ return simple_primes[simple_nprimes - 1];
++}
++
++#define HASH_TABLE_RESIZE(hash_table) \
++ do { \
++ if ((hash_table->size >= 3 * hash_table->nnodes && \
++ hash_table->size > HASH_TABLE_MIN_SIZE) || \
++ (3 * hash_table->size <= hash_table->nnodes && \
++ hash_table->size < HASH_TABLE_MAX_SIZE)) \
++ simple_hash_table_resize (hash_table); \
++ } while(0)
++
++static void simple_hash_table_resize (SimpleHashTable *hash_table);
++static SimpleHashNode** simple_hash_table_lookup_node (SimpleHashTable *hash_table,
++ int key);
++static SimpleHashNode* simple_hash_node_new (int key,
++ void* value);
++static void simple_hash_nodes_destroy (SimpleHashNode *hash_node,
++ SimpleDestroyNotify value_destroy_func);
++
++
++#define alloc0(type, n) (type*)calloc(n, sizeof(type))
++
++SimpleHashTable*
++simple_hash_table_new (SimpleDestroyNotify value_destroy_func)
++{
++ SimpleHashTable *hash_table;
++
++ hash_table = alloc0(SimpleHashTable, 1);
++ hash_table->size = HASH_TABLE_MIN_SIZE;
++ hash_table->nnodes = 0;
++ hash_table->value_destroy_func = value_destroy_func;
++ hash_table->nodes = alloc0 (SimpleHashNode*, hash_table->size);
++
++ return hash_table;
++}
++
++SimpleHashTable* simple_hash_table_clone(SimpleHashTable *hash_table,
++ SimpleCloneValue clone_value_func)
++{
++ SimpleHashTable *hash_table_new;
++ SimpleHashNode *new_node;
++ SimpleHashNode *node;
++ int i;
++
++ hash_table_new = alloc0 (SimpleHashTable, 1);
++ hash_table_new->size = hash_table->size;
++ hash_table_new->nnodes = hash_table->nnodes;
++ hash_table_new->value_destroy_func = hash_table->value_destroy_func;
++ hash_table_new->nodes = alloc0 (SimpleHashNode*, hash_table_new->size);
++ for (i = 0; i < hash_table->size; i++)
++ {
++ node = hash_table->nodes[i];
++ while(node)
++ {
++ SimpleHashNode *next = hash_table_new->nodes[i];
++ new_node = simple_hash_node_new(node->key,
++ (clone_value_func)? clone_value_func(node->value) : node->value);
++ new_node->next = next;
++ hash_table_new->nodes[i] = new_node;
++ node = node->next;
++ }
++ }
++ return hash_table_new;
++}
++
++void
++simple_hash_table_destroy (SimpleHashTable *hash_table)
++{
++ int i;
++
++ for (i = 0; i < hash_table->size; i++)
++ {
++ simple_hash_nodes_destroy (hash_table->nodes[i],
++ hash_table->value_destroy_func);
++ hash_table->nodes[i] = NULL;
++ }
++ free (hash_table->nodes);
++ free (hash_table);
++}
++
++static inline SimpleHashNode**
++simple_hash_table_lookup_node (SimpleHashTable *hash_table,
++ int key)
++{
++ SimpleHashNode **node;
++
++ node = &hash_table->nodes[(unsigned int)key % hash_table->size];
++ while (*node && (*node)->key != key)
++ node = &(*node)->next;
++
++ return node;
++}
++
++void*
++simple_hash_table_lookup (SimpleHashTable *hash_table, int key)
++{
++ SimpleHashNode *node;
++
++ node = *simple_hash_table_lookup_node (hash_table, key);
++
++ return node ? node->value : NULL;
++}
++
++void**
++simple_hash_table_lookup_pointer (SimpleHashTable *hash_table, int key)
++{
++ SimpleHashNode *node;
++
++ node = *simple_hash_table_lookup_node (hash_table, key);
++
++ return node ? &node->value : NULL;
++}
++
++
++void
++simple_hash_table_insert (SimpleHashTable *hash_table,
++ int key,
++ void* value)
++{
++ SimpleHashNode **node;
++
++ node = simple_hash_table_lookup_node (hash_table, key);
++
++ if (*node)
++ {
++ /* do not reset node->key in this place, keeping
++ * the old key is the intended behaviour.
++ * simple_hash_table_replace() can be used instead.
++ */
++ if (hash_table->value_destroy_func)
++ hash_table->value_destroy_func ((*node)->value);
++
++ (*node)->value = value;
++ }
++ else
++ {
++ *node = simple_hash_node_new (key, value);
++ hash_table->nnodes++;
++ HASH_TABLE_RESIZE (hash_table);
++ }
++}
++int
++simple_hash_table_remove (SimpleHashTable *hash_table,
++ int key)
++{
++ SimpleHashNode **node, *dest;
++
++ node = simple_hash_table_lookup_node (hash_table, key);
++ if (*node)
++ {
++ dest = *node;
++ (*node) = dest->next;
++ if (hash_table->value_destroy_func)
++ hash_table->value_destroy_func (dest->value);
++ free (dest);
++ hash_table->nnodes--;
++
++ HASH_TABLE_RESIZE (hash_table);
++
++ return 1;
++ }
++
++ return 0;
++}
++
++
++void
++simple_hash_table_foreach (SimpleHashTable *hash_table,
++ SimpleHFunc func,
++ void* user_data)
++{
++ SimpleHashNode *node;
++ int i;
++
++ for (i = 0; i < hash_table->size; i++)
++ for (node = hash_table->nodes[i]; node; node = node->next)
++ (* func) (node->key, node->value, user_data);
++}
++
++unsigned int
++simple_hash_table_size (SimpleHashTable *hash_table)
++{
++ return hash_table->nnodes;
++}
++
++static void
++simple_hash_table_resize (SimpleHashTable *hash_table)
++{
++ SimpleHashNode **new_nodes;
++ SimpleHashNode *node;
++ SimpleHashNode *next;
++ unsigned int hash_val;
++ int new_size;
++ int i;
++
++ new_size = simple_spaced_primes_closest (hash_table->nnodes);
++ new_size = CLAMP (new_size, HASH_TABLE_MIN_SIZE, HASH_TABLE_MAX_SIZE);
++
++ new_nodes = alloc0 (SimpleHashNode*, new_size);
++
++ for (i = 0; i < hash_table->size; i++)
++ for (node = hash_table->nodes[i]; node; node = next)
++ {
++ next = node->next;
++
++ hash_val = (unsigned int)(node->key) % new_size;
++
++ node->next = new_nodes[hash_val];
++ new_nodes[hash_val] = node;
++ }
++
++ free (hash_table->nodes);
++ hash_table->nodes = new_nodes;
++ hash_table->size = new_size;
++}
++
++static SimpleHashNode*
++simple_hash_node_new (int key,
++ void* value)
++{
++ SimpleHashNode *hash_node = alloc0 (SimpleHashNode, 1);
++
++ hash_node->key = key;
++ hash_node->value = value;
++ hash_node->next = NULL;
++
++ return hash_node;
++}
++
++static void
++simple_hash_nodes_destroy (SimpleHashNode *hash_node,
++ SimpleDestroyNotify value_destroy_func)
++{
++ while (hash_node)
++ {
++ SimpleHashNode *next = hash_node->next;
++ if (value_destroy_func)
++ value_destroy_func (hash_node->value);
++ free (hash_node);
++ hash_node = next;
++ }
++}
+Index: trunk/target-i386/ghash.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ trunk/target-i386/ghash.h 2009-01-19 23:06:08.000000000 +0000
+@@ -0,0 +1,59 @@
++/* This is a modified and simplified version of original ghash.h */
++
++
++/* GLIB - Library of useful routines for C programming
++ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*
++ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
++ * file for a list of people on the GLib Team. See the ChangeLog
++ * files for a list of changes. These files are distributed with
++ * GLib at ftp://ftp.gtk.org/pub/gtk/.
++ */
++
++#ifndef __SIMPLE_HASH_H__
++#define __SIMPLE_HASH_H__
++
++typedef struct _SimpleHashTable SimpleHashTable;
++
++typedef void (*SimpleDestroyNotify)(void*);
++typedef void (*SimpleHFunc)(int key, void* value, void* user_data);
++typedef void* (*SimpleCloneValue)(void* value);
++
++/* Hash tables
++ */
++SimpleHashTable* simple_hash_table_new (SimpleDestroyNotify value_destroy_func);
++SimpleHashTable* simple_hash_table_clone(SimpleHashTable *hash_table,
++ SimpleCloneValue clone_value_func);
++void simple_hash_table_destroy (SimpleHashTable *hash_table);
++void simple_hash_table_insert (SimpleHashTable *hash_table,
++ int key,
++ void* value);
++int simple_hash_table_remove (SimpleHashTable *hash_table,
++ int key);
++void* simple_hash_table_lookup (SimpleHashTable *hash_table,
++ int key);
++void** simple_hash_table_lookup_pointer (SimpleHashTable *hash_table, int key);
++void simple_hash_table_foreach (SimpleHashTable *hash_table,
++ SimpleHFunc func,
++ void* user_data);
++unsigned int simple_hash_table_size (SimpleHashTable *hash_table);
++
++#endif /* __SIMPLE_HASH_H__ */
++
+Index: trunk/target-i386/gl_func_perso.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ trunk/target-i386/gl_func_perso.h 2009-01-19 23:06:08.000000000 +0000
+@@ -0,0 +1,135 @@
++/*
++ * Hand-implemented GL/GLX API
++ *
++ * Copyright (c) 2006,2007 Even Rouault
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++ * THE SOFTWARE.
++ */
++
++MAGIC_MACRO(_init32),
++MAGIC_MACRO(_init64),
++MAGIC_MACRO(_synchronize),
++MAGIC_MACRO(_serialized_calls),
++MAGIC_MACRO(_exit_process),
++MAGIC_MACRO(_moveResizeWindow),
++MAGIC_MACRO(_changeWindowState),
++MAGIC_MACRO(_send_cursor),
++
++/* When you add a glX call here, you HAVE TO update IS_GLX_CALL */
++MAGIC_MACRO(glXChooseVisual),
++MAGIC_MACRO(glXQueryExtensionsString),
++MAGIC_MACRO(glXQueryServerString),
++MAGIC_MACRO(glXCreateContext),
++MAGIC_MACRO(glXCopyContext),
++MAGIC_MACRO(glXDestroyContext),
++MAGIC_MACRO(glXGetClientString),
++MAGIC_MACRO(glXQueryVersion),
++MAGIC_MACRO(glXMakeCurrent),
++MAGIC_MACRO(glXGetConfig),
++MAGIC_MACRO(glXGetConfig_extended),
++MAGIC_MACRO(glXWaitGL),
++MAGIC_MACRO(glXWaitX),
++MAGIC_MACRO(glXGetFBConfigAttrib_extended),
++MAGIC_MACRO(glXChooseFBConfig),
++MAGIC_MACRO(glXChooseFBConfigSGIX),
++MAGIC_MACRO(glXGetFBConfigs),
++MAGIC_MACRO(glXCreatePbuffer),
++MAGIC_MACRO(glXCreateGLXPbufferSGIX),
++MAGIC_MACRO(glXDestroyPbuffer),
++MAGIC_MACRO(glXDestroyGLXPbufferSGIX),
++MAGIC_MACRO(glXCreateNewContext),
++MAGIC_MACRO(glXCreateContextWithConfigSGIX),
++MAGIC_MACRO(glXGetVisualFromFBConfig),
++MAGIC_MACRO(glXGetFBConfigAttrib),
++MAGIC_MACRO(glXGetFBConfigAttribSGIX),
++MAGIC_MACRO(glXQueryContext),
++MAGIC_MACRO(glXQueryDrawable),
++MAGIC_MACRO(glXQueryGLXPbufferSGIX),
++MAGIC_MACRO(glXUseXFont),
++MAGIC_MACRO(glXIsDirect),
++MAGIC_MACRO(glXGetProcAddress_fake),
++MAGIC_MACRO(glXGetProcAddress_global_fake),
++MAGIC_MACRO(glXSwapBuffers),
++MAGIC_MACRO(glXQueryExtension),
++MAGIC_MACRO(glXGetScreenDriver),
++MAGIC_MACRO(glXGetDriverConfig),
++MAGIC_MACRO(glXSwapIntervalSGI),
++MAGIC_MACRO(glXBindTexImageATI),
++MAGIC_MACRO(glXReleaseTexImageATI),
++MAGIC_MACRO(glXBindTexImageARB),
++MAGIC_MACRO(glXReleaseTexImageARB),
++
++MAGIC_MACRO(glGetString),
++
++MAGIC_MACRO(glShaderSourceARB_fake),
++MAGIC_MACRO(glShaderSource_fake),
++MAGIC_MACRO(glVertexPointer_fake),
++MAGIC_MACRO(glNormalPointer_fake),
++MAGIC_MACRO(glColorPointer_fake),
++MAGIC_MACRO(glSecondaryColorPointer_fake),
++MAGIC_MACRO(glIndexPointer_fake),
++MAGIC_MACRO(glTexCoordPointer_fake),
++MAGIC_MACRO(glEdgeFlagPointer_fake),
++MAGIC_MACRO(glVertexAttribPointerARB_fake),
++MAGIC_MACRO(glVertexAttribPointerNV_fake),
++MAGIC_MACRO(glWeightPointerARB_fake),
++MAGIC_MACRO(glMatrixIndexPointerARB_fake),
++MAGIC_MACRO(glFogCoordPointer_fake),
++MAGIC_MACRO(glVariantPointerEXT_fake),
++MAGIC_MACRO(glInterleavedArrays_fake),
++MAGIC_MACRO(glElementPointerATI_fake),
++MAGIC_MACRO(glTuxRacerDrawElements_fake),
++MAGIC_MACRO(glVertexAndNormalPointer_fake),
++MAGIC_MACRO(glTexCoordPointer01_fake),
++MAGIC_MACRO(glTexCoordPointer012_fake),
++MAGIC_MACRO(glVertexNormalPointerInterlaced_fake),
++MAGIC_MACRO(glVertexNormalColorPointerInterlaced_fake),
++MAGIC_MACRO(glVertexColorTexCoord0PointerInterlaced_fake),
++MAGIC_MACRO(glVertexNormalTexCoord0PointerInterlaced_fake),
++MAGIC_MACRO(glVertexNormalTexCoord01PointerInterlaced_fake),
++MAGIC_MACRO(glVertexNormalTexCoord012PointerInterlaced_fake),
++MAGIC_MACRO(glVertexNormalColorTexCoord0PointerInterlaced_fake),
++MAGIC_MACRO(glVertexNormalColorTexCoord01PointerInterlaced_fake),
++MAGIC_MACRO(glVertexNormalColorTexCoord012PointerInterlaced_fake),
++MAGIC_MACRO(glGenTextures_fake),
++MAGIC_MACRO(glGenBuffersARB_fake),
++MAGIC_MACRO(glGenLists_fake),
++MAGIC_MACRO(_glDrawElements_buffer),
++MAGIC_MACRO(_glDrawRangeElements_buffer),
++MAGIC_MACRO(_glMultiDrawElements_buffer),
++MAGIC_MACRO(_glVertexPointer_buffer),
++MAGIC_MACRO(_glNormalPointer_buffer),
++MAGIC_MACRO(_glColorPointer_buffer),
++MAGIC_MACRO(_glSecondaryColorPointer_buffer),
++MAGIC_MACRO(_glIndexPointer_buffer),
++MAGIC_MACRO(_glTexCoordPointer_buffer),
++MAGIC_MACRO(_glEdgeFlagPointer_buffer),
++MAGIC_MACRO(_glVertexAttribPointerARB_buffer),
++MAGIC_MACRO(_glWeightPointerARB_buffer),
++MAGIC_MACRO(_glMatrixIndexPointerARB_buffer),
++MAGIC_MACRO(_glFogCoordPointer_buffer),
++MAGIC_MACRO(_glVariantPointerEXT_buffer),
++MAGIC_MACRO(_glGetError_fake),
++MAGIC_MACRO(_glReadPixels_pbo),
++MAGIC_MACRO(_glDrawPixels_pbo),
++MAGIC_MACRO(_glMapBufferARB_fake),
++MAGIC_MACRO(_glSelectBuffer_fake),
++MAGIC_MACRO(_glGetSelectBuffer_fake),
++MAGIC_MACRO(_glFeedbackBuffer_fake),
++MAGIC_MACRO(_glGetFeedbackBuffer_fake),
+Index: trunk/target-i386/helper.h
+===================================================================
+--- trunk.orig/target-i386/helper.h 2009-01-05 11:10:06.000000000 +0000
++++ trunk/target-i386/helper.h 2009-01-19 23:06:08.000000000 +0000
+@@ -214,4 +214,6 @@
+ DEF_HELPER_2(rcrq, tl, tl, tl)
+ #endif
+
++DEF_HELPER_0(opengl, void)
++
+ #include "def-helper.h"
+Index: trunk/target-i386/helper_opengl.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ trunk/target-i386/helper_opengl.c 2009-01-19 23:06:08.000000000 +0000
+@@ -0,0 +1,979 @@
++/*
++ * Host-side implementation of GL/GLX API
++ *
++ * Copyright (c) 2006,2007 Even Rouault
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
++ * THE SOFTWARE.
++ */
++#define _XOPEN_SOURCE 600
++#include <string.h>
++#include <stdlib.h>
++#include <assert.h>
++
++#include <X11/Xlib.h>
++#include <X11/Xutil.h>
++
++#include "exec.h"
++
++#if defined(CONFIG_USER_ONLY)
++void helper_opengl(void)
++{
++ /* TODO */
++}
++#else
++
++#include "opengl_func.h"
++
++#define ENABLE_GL_LOG
++
++extern FILE *stderr;
++
++extern void init_process_tab(void);
++extern int do_function_call(int func_number, arg_t *args, char *ret_string);
++
++extern void sdl_set_opengl_window(int x, int y, int width, int height);
++
++static int last_process_id = 0;
++static int must_save = 0;
++
++static inline void *get_phys_mem_addr(const CPUState *env, target_ulong addr)
++{
++ int is_user, index;
++
++ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
++ is_user = ((env->hflags & HF_CPL_MASK) == 3);
++ if (is_user == 0) {
++ fprintf(stderr, "not in userland !!!\n");
++ return NULL;
++ }
++ if (__builtin_expect
++ (env->tlb_table[is_user][index].addr_code !=
++ (addr & TARGET_PAGE_MASK), 0)) {
++ target_ulong ret = cpu_get_phys_page_debug((CPUState *) env, addr);
++
++ if (ret == -1) {
++ fprintf(stderr,
++ "cpu_get_phys_page_debug(env, " TARGET_FMT_lx ") == "
++ TARGET_FMT_lx "\n", addr, ret);
++ fprintf(stderr,
++ "not in phys mem " TARGET_FMT_lx "(" TARGET_FMT_lx " "
++ TARGET_FMT_lx ")\n", addr,
++ env->tlb_table[is_user][index].addr_code,
++ addr & TARGET_PAGE_MASK);
++ fprintf(stderr, "cpu_x86_handle_mmu_fault = %d\n",
++ cpu_x86_handle_mmu_fault((CPUState *) env, addr, 0, 1, 1));
++ return NULL;
++ } else {
++ if (ret + TARGET_PAGE_SIZE <= phys_ram_size) {
++ return phys_ram_base + ret +
++ (((target_ulong) addr) & (TARGET_PAGE_SIZE - 1));
++ } else {
++ fprintf(stderr,
++ "cpu_get_phys_page_debug(env, " TARGET_FMT_lx ") == "
++ TARGET_FMT_lx "p\n", addr, ret);
++ fprintf(stderr,
++ "ret=" TARGET_FMT_lx " phys_ram_size= " TARGET_FMT_lx
++ "\n", ret, (target_ulong) phys_ram_size);
++ return NULL;
++ }
++ }
++ } else
++ return (void *) (addr + env->tlb_table[is_user][index].addend);
++}
++
++#ifndef MIN
++#define MIN(a, b) (((a) < (b)) ? (a) : (b))
++#endif
++
++enum {
++ NOT_MAPPED,
++ MAPPED_CONTIGUOUS,
++ MAPPED_NOT_CONTIGUOUS
++};
++
++#define TARGET_ADDR_LOW_ALIGN(x) ((target_ulong)(x) & ~(TARGET_PAGE_SIZE - 1))
++
++/* Return NOT_MAPPED if a page is not mapped into target physical memory */
++/* MAPPED_CONTIGUOUS if all pages are mapped into target physical memory and contiguous */
++/* MAPPED_NOT_CONTIGUOUS if all pages are mapped into target physical memory but not contiguous */
++static int get_target_mem_state(const CPUState *env,
++ target_ulong target_addr, int len)
++{
++ target_ulong aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr);
++ int to_end_page =
++ (long) aligned_target_addr + TARGET_PAGE_SIZE - (long) target_addr;
++ int ret = MAPPED_CONTIGUOUS;
++
++ if (aligned_target_addr != target_addr) {
++ void *phys_addr = get_phys_mem_addr(env, aligned_target_addr);
++ void *last_phys_addr = phys_addr;
++
++ if (phys_addr == 0) {
++ return NOT_MAPPED;
++ }
++ if (len > to_end_page) {
++ len -= to_end_page;
++ aligned_target_addr += TARGET_PAGE_SIZE;
++ int i;
++
++ for (i = 0; i < len; i += TARGET_PAGE_SIZE) {
++ void *phys_addr =
++ get_phys_mem_addr(env, aligned_target_addr + i);
++ if (phys_addr == 0) {
++ return NOT_MAPPED;
++ }
++ if (phys_addr != last_phys_addr + TARGET_PAGE_SIZE)
++ ret = MAPPED_NOT_CONTIGUOUS;
++ last_phys_addr = phys_addr;
++ }
++ }
++ } else {
++ void *last_phys_addr = NULL;
++ int i;
++
++ for (i = 0; i < len; i += TARGET_PAGE_SIZE) {
++ void *phys_addr = get_phys_mem_addr(env, target_addr + i);
++
++ if (phys_addr == 0) {
++ return NOT_MAPPED;
++ }
++ if (i != 0 && phys_addr != last_phys_addr + TARGET_PAGE_SIZE)
++ ret = MAPPED_NOT_CONTIGUOUS;
++ last_phys_addr = phys_addr;
++ }
++ }
++ return ret;
++}
++
++/* copy len bytes from host memory at addr host_addr to target memory at logical addr target_addr */
++/* Returns 1 if successfull, 0 if some target pages are not mapped into target physical memory */
++static int memcpy_host_to_target(const CPUState *env,
++ target_ulong target_addr,
++ const void *host_addr, int len)
++{
++ int i;
++ target_ulong aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr);
++ int to_end_page =
++ (long) aligned_target_addr + TARGET_PAGE_SIZE - (long) target_addr;
++ int ret = get_target_mem_state(env, target_addr, len);
++
++ if (ret == NOT_MAPPED) {
++ return 0;
++ }
++
++ if (ret == MAPPED_CONTIGUOUS) {
++ void *phys_addr = get_phys_mem_addr(env, target_addr);
++
++ memcpy(phys_addr, host_addr, len);
++ } else {
++ if (aligned_target_addr != target_addr) {
++ void *phys_addr = get_phys_mem_addr(env, target_addr);
++
++ memcpy(phys_addr, host_addr, MIN(len, to_end_page));
++ if (len <= to_end_page) {
++ return 1;
++ }
++ len -= to_end_page;
++ host_addr += to_end_page;
++ target_addr = aligned_target_addr + TARGET_PAGE_SIZE;
++ }
++ for (i = 0; i < len; i += TARGET_PAGE_SIZE) {
++ void *phys_addr = get_phys_mem_addr(env, target_a