diff options
Diffstat (limited to 'meta/packages')
| -rw-r--r-- | meta/packages/qemu/qemu-0.9.1+svnr6190/qemu-add-gl-host-code.patch | 33906 | ||||
| -rw-r--r-- | meta/packages/qemu/qemu_svn.bb | 6 |
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 |
