Browse Source

Merge branch 'master' of git+ssh://openadk.org/git/openadk

Waldemar Brodkorb 15 years ago
parent
commit
3b76e79f14
100 changed files with 16192 additions and 1290 deletions
  1. 1 0
      .gitignore
  2. 37 0
      Config.in
  3. 1 0
      README
  4. 21 12
      mk/build.mk
  5. 15 2
      mk/image.mk
  6. 3 12
      mk/kernel-build.mk
  7. 0 2
      mk/kernel.mk
  8. 1 1
      mk/mirrors.mk
  9. 47 5
      mk/modules.mk
  10. 2 2
      mk/package.mk
  11. 2 2
      mk/vars.mk
  12. 23 0
      package/Config.in
  13. 55 0
      package/DirectFB/Makefile
  14. 1 0
      package/DirectFB/files/DirectFB.conffiles
  15. 4 0
      package/DirectFB/files/directfbrc
  16. 35 7
      package/MesaLib/Makefile
  17. 14774 0
      package/MesaLib/patches/000-mesalib-xdemos.patch
  18. 12 0
      package/MesaLib/patches/patch-include_GL_internal_sarea_h
  19. 3 6
      package/adkinstall/Makefile
  20. 127 28
      package/adkinstall/src/adkinstall
  21. 2 2
      package/aircrack-ng/Makefile
  22. 35 0
      package/alix-switch/Makefile
  23. 19 0
      package/alix-switch/files/alix-switch
  24. 27 0
      package/alix-switch/files/alix-switch.init
  25. 3 0
      package/alix-switch/files/alix-switch.postinst
  26. 108 0
      package/alix-switch/src/alix-switchd.c
  27. 16 1
      package/alsa-utils/Makefile
  28. 5 5
      package/apr-util/Makefile
  29. 0 19
      package/apr-util/patches/patch-uri_Makefile_in
  30. 0 21
      package/apr-util/patches/uri_delim.patch
  31. 8 19
      package/apr/Makefile
  32. 16 0
      package/apr/patches/patch-include_apr_want_h
  33. 8 4
      package/asterisk/Makefile
  34. 0 13
      package/asterisk/patches/patch-Makefile
  35. 0 26
      package/asterisk/patches/patch-apps_app_followme_c
  36. 26 0
      package/b43-firmware/Makefile
  37. 10 8
      package/base-files/Makefile
  38. 1 1
      package/base-files/src/etc/ipkg.conf
  39. 17 7
      package/base-files/src/etc/network/if-pre-up.d/04-wireless
  40. 0 1
      package/base-files/src/etc/profile
  41. 1 2
      package/base-files/src/etc/shadow
  42. 2 1
      package/base-files/src/init
  43. 3 0
      package/base-files/src/sbin/adkupdate
  44. 12 6
      package/busybox/Makefile
  45. 1 0
      package/busybox/config/archival/Config.in
  46. 0 1
      package/busybox/config/editors/Config.in
  47. 0 665
      package/busybox/files/busybox.config
  48. 1 1
      package/busybox/files/crond.init
  49. 119 103
      package/busybox/patches/001-ipkg.patch
  50. 1 1
      package/cfgfs/Makefile
  51. 2 2
      package/collectd/Makefile
  52. 56 0
      package/collectd/patches/patch-configure
  53. 3 3
      package/collectd/patches/patch-src_libcollectdclient_Makefile_in
  54. 1 1
      package/conntrack-tools/Makefile
  55. 27 0
      package/coreutils/Makefile
  56. 2 2
      package/cpio/Makefile
  57. 8 0
      package/cpio/patches/patch-src_filetypes_h
  58. 2 2
      package/curl/Makefile
  59. 9 9
      package/davfs2/Makefile
  60. 0 11
      package/davfs2/patches/patch-src_cache_c
  61. 0 11
      package/davfs2/patches/patch-src_dav_coda2_c
  62. 0 11
      package/davfs2/patches/patch-src_dav_coda3_c
  63. 0 11
      package/davfs2/patches/patch-src_dav_fuse5_c
  64. 0 11
      package/davfs2/patches/patch-src_dav_fuse7_c
  65. 0 31
      package/davfs2/patches/patch-src_kernel_interface_c
  66. 22 40
      package/davfs2/patches/patch-src_mount_davfs_c
  67. 5 6
      package/davfs2/patches/patch-src_umount_davfs_c
  68. 21 41
      package/davfs2/patches/patch-src_webdav_c
  69. 31 0
      package/dillo/Makefile
  70. 7 1
      package/dropbear/Makefile
  71. 3 3
      package/e2fsprogs/Makefile
  72. 1 1
      package/fetchmail/Makefile
  73. 4 4
      package/ffmpeg/Makefile
  74. 0 63
      package/ffmpeg/patches/patch-configure
  75. 10 7
      package/firefox/Makefile
  76. 11 0
      package/firefox/patches/patch-content_media_nsAudioStream_cpp
  77. 27 0
      package/fltk/Makefile
  78. 11 0
      package/fltk/patches/patch-makeinclude_in
  79. 11 0
      package/fltk/patches/patch-makeinclude_in.orig
  80. 40 0
      package/fluxbox/Makefile
  81. 2 0
      package/font-misc-misc/Makefile
  82. 11 0
      package/font-misc-misc/patches/patch-configure
  83. 11 1
      package/font-util/Makefile
  84. 23 0
      package/freeglut/Makefile
  85. 2 2
      package/git/Makefile
  86. 28 0
      package/gpm/files/gpm.init
  87. 4 0
      package/gpm/files/gpm.postinst
  88. 6 6
      package/grub-bin/Makefile
  89. 4 5
      package/grub/Makefile
  90. 11 0
      package/grub/patches/patch-conf_common_mk
  91. 11 0
      package/grub/patches/patch-include_grub_i18n_h
  92. 3 3
      package/grub/patches/patch-include_grub_misc_h
  93. 10 16
      package/grub/patches/patch-kern_misc_c
  94. 26 0
      package/grub/patches/patch-kern_misc_c.orig
  95. 29 0
      package/grub/patches/patch-lib_libgcrypt-grub_cipher_camellia_c
  96. 21 0
      package/grub/patches/patch-lib_libgcrypt-grub_cipher_camellia_c.orig
  97. 11 0
      package/grub/patches/patch-lib_libgcrypt-grub_cipher_des_c
  98. 29 0
      package/grub/patches/patch-lib_libgcrypt-grub_cipher_dsa_c
  99. 20 0
      package/grub/patches/patch-lib_libgcrypt-grub_cipher_elgamal_c
  100. 11 0
      package/grub/patches/patch-lib_libgcrypt-grub_cipher_md4_c

+ 1 - 0
.gitignore

@@ -17,6 +17,7 @@ toolchain_build_*/
 .prereq_done
 .config*
 .busyboxcfg
+.bbrebuild
 .defconfig
 all.config
 .cfg_*/

+ 37 - 0
Config.in

@@ -17,13 +17,27 @@ config ADK_HAVE_DOT_CONFIG
 
 menu "ADK settings"
 
+config ADK_VENDOR
+	string "vendor name"
+	default "openadk"
+	help
+	  Vendor string is used for toolchain.
+
+config ADK_HOST
+	string "webserver for packages and distfiles"
+	default "www.openadk.org"
+	help
+	  Configure host for IPKG package management.
+
 config ADK_DEVELSYSTEM
 	bool "Compile a ADK development system"
 	default n
 	select BUSYBOX_CMP
 	select BUSYBOX_EXPR
+	select BUSYBOX_INSTALL
 	select BUSYBOX_MKTEMP
 	select BUSYBOX_UNZIP
+	select BUSYBOX_TAC
 	select BUSYBOX_TEE
 	select ADK_PACKAGE_AUTOCONF
 	select ADK_PACKAGE_AUTOMAKE
@@ -47,8 +61,10 @@ config ADK_DEVELSYSTEM
 	select ADK_PACKAGE_MAKE
 	select ADK_PACKAGE_MKSH
 	select ADK_PACKAGE_PATCH
+	select ADK_PACKAGE_PKG_CONFIG
 	select ADK_PACKAGE_MICROPERL
 	select ADK_PACKAGE_TAR
+	select ADK_PACKAGE_TSORT
 	select ADK_PACKAGE_WGET
 	select ADK_PACKAGE_ZLIB
 	select ADK_PACKAGE_ZLIB_DEV
@@ -119,6 +135,10 @@ config ADK_HOST_NETBSD
 	prompt "NetBSD"
 	boolean
 
+config ADK_HOST_DARWIN
+	prompt "Darwin"
+	boolean
+
 config ADK_HOST_CYGWIN
 	prompt "Cygwin"
 	boolean
@@ -128,4 +148,21 @@ endchoice
 endmenu
 
 source "target/Config.in"
+
+menu "Runtime configuration"
+config ADK_SSH_PUBKEY
+	string "SSH public key (root user only)"
+	default ""
+	help
+	  Paste your generated SSH public key here and it will be embedded into
+	  the built image, so you can use it to login instantly.
+
+config ADK_PASSWORD
+	string "root password for the embedded system"
+	default "linux123"
+	help
+	  Predefine the root password enabled in the built image.
+
+endmenu
+
 source "package/Config.in"

+ 1 - 0
README

@@ -36,3 +36,4 @@ buildsystem will download all sources, build the toolchain, the kernel and all
 applications.
 
 Sunshine!
+

+ 21 - 12
mk/build.mk

@@ -20,7 +20,6 @@ DEFCONFIG=		ADK_DEVELSYSTEM=n \
 			ADK_PACKAGE_XORG_SERVER_WITH_DRI=n \
 			ADK_PACKAGE_AUFS2_UTIL=n \
 			ADK_PACKAGE_BASE_FILES=y \
-			ADK_PACKAGE_GCC=n \
 			ADK_PACKAGE_MGETTY=n \
 			ADK_COMPILE_HEIMDAL=n \
 			ADK_PACKAGE_HEIMDAL_PKINIT=n \
@@ -65,8 +64,9 @@ noconfig_targets:=	menuconfig \
 
 POSTCONFIG=		-@ \
 	if [ -f .config.old ];then \
-		if [ -f .busyboxcfg ];then \
-			rm .busyboxcfg; \
+		if [ "$$(grep ^BUSYBOX .config|md5sum)" != "$$(grep ^BUSYBOX .config.old|md5sum)" ];then \
+			touch .bbrebuild; \
+			cp .config .config.old; \
 		fi; \
 	fi
 
@@ -90,12 +90,12 @@ ${TOPDIR}/package/Depends.mk: ${TOPDIR}/.config $(wildcard ${TOPDIR}/package/*/M
 world: $(DISTDIR) $(BUILD_DIR) $(TARGET_DIR) $(PACKAGE_DIR) ${TOPDIR}/.ADK_HAVE_DOT_CONFIG
 	${BASH} ${TOPDIR}/scripts/scan-pkgs.sh
 ifeq ($(ADK_NATIVE),y)
-	$(MAKE) -f mk/build.mk toolchain/kernel-headers-prepare target/config-prepare target/compile package/compile root_clean package/install package_index target/install
+	$(MAKE) -f mk/build.mk toolchain/kernel-headers-prepare tools/install target/config-prepare target/compile package/compile root_clean package/install package_index target/install
 else
 ifeq ($(ADK_TOOLCHAIN_ONLY),y)
-	$(MAKE) -f mk/build.mk toolchain/install package/compile
+	$(MAKE) -f mk/build.mk toolchain/install tools/install package/compile
 else
-	$(MAKE) -f mk/build.mk toolchain/install target/config-prepare target/compile package/compile root_clean package/install package_index target/install
+	$(MAKE) -f mk/build.mk toolchain/install tools/install target/config-prepare target/compile package/compile root_clean package/install target/install package_index
 endif
 endif
 
@@ -136,6 +136,9 @@ target/%: ${TOPDIR}/.ADK_HAVE_DOT_CONFIG
 toolchain/%: ${STAGING_DIR}
 	$(MAKE) -C toolchain $(patsubst toolchain/%,%,$@)
 
+tools/%:
+	$(MAKE) -C tools $(patsubst tools/%,%,$@)
+
 image:
 	$(MAKE) -C target image
 
@@ -272,6 +275,9 @@ endif
 ifeq (${OStype},NetBSD)
 	@echo ADK_HOST_NETBSD=y > $(TOPDIR)/.defconfig
 endif
+ifeq (${OStype},Darwin)
+	@echo ADK_HOST_DARWIN=y > $(TOPDIR)/.defconfig
+endif
 ifneq (,$(filter CYGWIN%,${OStype}))
 	@echo ADK_HOST_CYGWIN=y > $(TOPDIR)/.defconfig
 endif
@@ -280,10 +286,10 @@ endif
 			|grep -i "$(TARGET)"\$$ \
 			|sed -e "s#^config \(.*\)#\1=y#" \
 			 >> $(TOPDIR)/.defconfig; \
-		for symbol in ${DEFCONFIG}; do \
-			echo $$symbol >> $(TOPDIR)/.defconfig; \
-		done; \
 	fi
+	@for symbol in ${DEFCONFIG}; do \
+		echo $$symbol >> $(TOPDIR)/.defconfig; \
+	done
 	@if [ ! -z "$(FS)" ];then \
 		grep "^config" target/Config.in \
 			|grep -i "$(FS)" \
@@ -340,6 +346,9 @@ endif
 ifeq (${OStype},NetBSD)
 	@echo ADK_HOST_NETBSD=y > $(TOPDIR)/all.config
 endif
+ifeq (${OStype},Darwin)
+	@echo ADK_HOST_DARWIN=y > $(TOPDIR)/all.config
+endif
 ifneq (,$(filter CYGWIN%,${OStype}))
 	@echo ADK_HOST_CYGWIN=y > $(TOPDIR)/all.config
 endif
@@ -348,10 +357,10 @@ endif
 			|grep -i "$(TARGET)"\$$ \
 			|sed -e "s#^config \(.*\)#\1=y#" \
 			>> $(TOPDIR)/all.config; \
-		for symbol in ${DEFCONFIG}; do \
-			echo $$symbol >> $(TOPDIR)/all.config; \
-		done; \
 	fi
+	@for symbol in ${DEFCONFIG}; do \
+		echo $$symbol >> $(TOPDIR)/all.config; \
+	done
 	@if [ ! -z "$(FS)" ];then \
 		grep "^config" target/Config.in \
 			|grep -i "$(FS)" \

+ 15 - 2
mk/image.mk

@@ -1,7 +1,7 @@
 # This file is part of the OpenADK project. OpenADK is copyrighted
 # material, please see the LICENCE file in the top-level directory.
 
-imageprepare: kernel-install image-prepare-post extra-install
+imageprepare: image-prepare-post extra-install
 
 # if an extra directory exist in TOPDIR, copy all content over the 
 # root directory, do the same if make extra=/dir/to/extra is used
@@ -52,13 +52,26 @@ image-prepare-post:
 		done; \
 	fi
 
+KERNEL_PKGDIR:=$(LINUX_BUILD_DIR)/kernel-pkg
+KERNEL_PKG:=$(PACKAGE_DIR)/kernel_$(ADK_TARGET)-$(KERNEL_VERSION)_$(CPU_ARCH).$(PKG_SUFFIX)
+
+kernel-package: $(LINUX_DIR)/vmlinux
+	$(TRACE) target/$(ADK_TARGET)-create-kernel-package
+	rm -rf $(KERNEL_PKGDIR)
+	@mkdir -p $(KERNEL_PKGDIR)/boot
+	cp $(KERNEL) $(KERNEL_PKGDIR)/boot/vmlinuz-adk
+	${BASH} ${SCRIPT_DIR}/make-ipkg-dir.sh ${KERNEL_PKGDIR} \
+	    ../linux/kernel.control ${ADK_TARGET}-${KERNEL_VERSION} ${CPU_ARCH}
+	$(PKG_BUILD) $(KERNEL_PKGDIR) $(PACKAGE_DIR)
+	$(PKG_INSTALL) $(KERNEL_PKG)
+
 INITRAMFS=		${ADK_TARGET}-${ADK_LIBC}-${FS}
 ROOTFSSQUASHFS=		${ADK_TARGET}-${ADK_LIBC}-${FS}.img
 ROOTFSTARBALL=		${ADK_TARGET}-${ADK_LIBC}-${FS}+kernel.tar.gz
 ROOTFSUSERTARBALL=	${ADK_TARGET}-${ADK_LIBC}-${FS}.tar.gz
 INITRAMFS_PIGGYBACK=	${ADK_TARGET}-${ADK_LIBC}-${FS}.cpio
 
-${BIN_DIR}/${ROOTFSTARBALL}: ${TARGET_DIR}
+${BIN_DIR}/${ROOTFSTARBALL}: ${TARGET_DIR} kernel-package
 	cd ${TARGET_DIR}; tar -cf - --owner=0 --group=0 . | gzip -n9 >$@
 
 ${BIN_DIR}/${ROOTFSUSERTARBALL}: ${TARGET_DIR}

+ 3 - 12
mk/kernel-build.mk

@@ -3,11 +3,8 @@
 
 include $(TOPDIR)/rules.mk
 include $(TOPDIR)/mk/linux.mk
-#include ${TOPDIR}/mk/buildhlp.mk
 include ${TOPDIR}/mk/kernel-vars.mk
 
-KERNEL_PKGDIR:=$(LINUX_BUILD_DIR)/kernel-pkg
-
 $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/linux-$(KERNEL_VERSION)/.patched:
 	$(TRACE) target/$(ADK_TARGET)-kernel-patch
 	$(PATCH) $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/linux-$(KERNEL_VERSION) ../linux/patches/$(KERNEL_VERSION) *.patch $(MAKE_TRACE)
@@ -37,17 +34,11 @@ $(LINUX_DIR)/vmlinux: $(LINUX_DIR)/.config
 		INSTALL_MOD_PATH=$(LINUX_BUILD_DIR)/modules \
 		modules_install $(MAKE_TRACE)
 	$(TRACE) target/$(ADK_TARGET)-create-packages
-	$(MAKE) $(KERNEL_PKG) $(TARGETS) 
+ifneq ($(strip $(TARGETS)),)
+	$(MAKE) $(TARGETS)
+endif
 	touch -c $(LINUX_DIR)/vmlinux
 
-$(KERNEL_PKG):
-	$(TRACE) target/$(ADK_TARGET)-create-kernel-package
-	rm -rf $(KERNEL_PKGDIR)
-	@mkdir -p $(KERNEL_PKGDIR)/etc
-	${BASH} ${SCRIPT_DIR}/make-ipkg-dir.sh ${KERNEL_PKGDIR} \
-	    ../linux/kernel.control ${ADK_TARGET}-${KERNEL_VERSION} ${CPU_ARCH}
-	$(PKG_BUILD) $(KERNEL_PKGDIR) $(PACKAGE_DIR) $(MAKE_TRACE)
-
 prepare:
 compile: $(LINUX_DIR)/vmlinux
 install: compile

+ 0 - 2
mk/kernel.mk

@@ -1,7 +1,6 @@
 # This file is part of the OpenADK project. OpenADK is copyrighted
 # material, please see the LICENCE file in the top-level directory.
 
-
 LINUX_KMOD_SUFFIX=ko
 MODULES_SUBDIR := lib/modules/$(KERNEL_VERSION)
 LINUX_BUILD_DIR := $(BUILD_DIR)/linux-$(ARCH)-$(ADK_TARGET)
@@ -9,7 +8,6 @@ KMOD_BUILD_DIR := $(LINUX_BUILD_DIR)/linux-modules
 MODULES_DIR := $(LINUX_BUILD_DIR)/modules/$(MODULES_SUBDIR)
 TARGET_MODULES_DIR := $(LINUX_TARGET_DIR)/$(MODULES_SUBDIR)
 
-KERNEL_PKG:=$(PACKAGE_DIR)/kernel_$(ADK_TARGET)-$(KERNEL_VERSION)_$(CPU_ARCH).$(PKG_SUFFIX)
 INSTALL_TARGETS:= $(KERNEL_PKG)
 NOINSTALL_TARGETS:=
 TARGETS:=

+ 1 - 1
mk/mirrors.mk

@@ -1,7 +1,7 @@
 # This file is part of the OpenADK project. OpenADK is copyrighted
 # material, please see the LICENCE file in the top-level directory.
 
-MASTER_SITE_BACKUP?=	${MASTER_SITE_OPENADK}
+MASTER_SITE_BACKUP?=	http://${ADK_HOST}/distfiles/
 
 MASTER_SITE_OPENADK?=	\
 	http://www.openadk.org/distfiles/ \

+ 47 - 5
mk/modules.mk

@@ -4,6 +4,7 @@
 #
 # Virtualization
 #
+
 $(eval $(call KMOD_template,KVM,kvm,\
 	$(MODULES_DIR)/kernel/arch/${ARCH}/kvm/kvm \
 ,90))
@@ -16,10 +17,10 @@ $(eval $(call KMOD_template,KVM_INTEL,kvm-intel,\
 	$(MODULES_DIR)/kernel/arch/${ARCH}/kvm/kvm-intel \
 ,95))
 
-
 #
 # Serial ATA devices
 #
+
 $(eval $(call KMOD_template,SATA_AHCI,sata-ahci,\
 	$(MODULES_DIR)/kernel/drivers/ata/ahci \
 ,10))
@@ -27,6 +28,7 @@ $(eval $(call KMOD_template,SATA_AHCI,sata-ahci,\
 #
 # Ethernet network devices
 # 
+
 $(eval $(call KMOD_template,NE2K_PCI,ne2k-pci,\
 	$(MODULES_DIR)/kernel/drivers/net/8390 \
 	$(MODULES_DIR)/kernel/drivers/net/ne2k-pci \
@@ -52,10 +54,10 @@ $(eval $(call KMOD_template,SKY2,sky2,\
 	$(MODULES_DIR)/kernel/drivers/net/sky2 \
 ,20))
 
-
 # 
 # Wireless network devices
 #
+
 $(eval $(call KMOD_template,MAC80211,mac80211,\
 	$(MODULES_DIR)/kernel/net/wireless/cfg80211 \
 	$(MODULES_DIR)/kernel/net/mac80211/mac80211 \
@@ -70,6 +72,14 @@ $(eval $(call KMOD_template,P54_COMMON,p54-common,\
 	$(MODULES_DIR)/kernel/drivers/net/wireless/p54/p54common \
 ,68))
 
+$(eval $(call KMOD_template,RTL8187B,rtl8187b,\
+	$(MODULES_DIR)/kernel/drivers/net/wireless/rtl8187b/rtl8187b \
+,70))
+
+$(eval $(call KMOD_template,B43,b43,\
+	$(MODULES_DIR)/kernel/drivers/net/wireless/b43/b43 \
+,70))
+
 $(eval $(call KMOD_template,P54_USB,p54-usb,\
 	$(MODULES_DIR)/kernel/drivers/net/wireless/p54/p54usb \
 ,70))
@@ -94,6 +104,7 @@ $(eval $(call KMOD_template,RT61PCI,rt61pci,\
 #
 # Networking
 #
+
 $(eval $(call KMOD_template,ATM,atm,\
 	$(MODULES_DIR)/kernel/net/atm/atm \
 ,50))
@@ -162,6 +173,7 @@ $(eval $(call KMOD_template,BONDING,bonding,\
 #
 # Traffic scheduling
 #
+
 $(eval $(call KMOD_template,NET_SCH_CBQ,net-sch-cbq,\
 	$(MODULES_DIR)/kernel/net/sched/sch_cbq \
 ,40))
@@ -214,6 +226,7 @@ $(eval $(call KMOD_template,NET_SCH_INGRESS,net-sch-ingress,\
 #
 # classifications
 #
+
 $(eval $(call KMOD_template,NET_CLS_BASIC,net-cls-basic,\
 	$(MODULES_DIR)/kernel/net/sched/cls_basic \
 ,40))
@@ -237,6 +250,7 @@ $(eval $(call KMOD_template,NET_CLS_U32,net-cls-u32,\
 #
 # actions
 #
+
 $(eval $(call KMOD_template,NET_ACT_POLICE,net-act-police,\
 	$(MODULES_DIR)/kernel/net/sched/act_police \
 ,45))
@@ -260,6 +274,7 @@ $(eval $(call KMOD_template,NET_ACT_PEDIT,net-act-pedit,\
 #
 # IPsec 
 #
+
 $(eval $(call KMOD_template,NET_KEY,net-key,\
 	$(MODULES_DIR)/kernel/net/key/af_key \
 ,60))
@@ -292,9 +307,11 @@ $(eval $(call KMOD_template,INET_XFRM_MODE_BEET,inet-xfrm-mode-beet,\
 ##
 ## Filtering / Firewalling
 ##
+
 #
 # Ethernet Bridging firewall
 #
+
 $(eval $(call KMOD_template,BRIDGE_NF_EBTABLES,bridge-nf-ebtables,\
 	$(MODULES_DIR)/kernel/net/bridge/netfilter/ebtables \
 ,55))
@@ -334,6 +351,7 @@ $(eval $(call KMOD_template,BRIDGE_EBT_REDIRECT,bridge-ebt-redirect,\
 #
 # Netfilter Core
 #
+
 $(eval $(call KMOD_template,NETFILTER_XT_TARGET_CLASSIFY,netfiler-xt-target-classify,\
 	$(MODULES_DIR)/kernel/net/netfilter/xt_CLASSIFY \
 ,50))
@@ -361,6 +379,7 @@ $(eval $(call KMOD_template,NETFILTER_XT_TARGET_NOTRACK,netfilter-xt-target-notr
 #
 # IP: Netfilter
 #
+
 $(eval $(call KMOD_template,NF_CONNTRACK,nf-conntrack,\
 	$(MODULES_DIR)/kernel/net/netfilter/nf_conntrack \
 ,45))
@@ -472,6 +491,7 @@ $(eval $(call KMOD_template,IP_NF_MATCH_MULTIPORT,ip-nf-match-multiport,\
 #
 # Filtering
 #
+
 $(eval $(call KMOD_template,IP_NF_FILTER,ip-nf-filter,\
 	$(MODULES_DIR)/kernel/net/ipv4/netfilter/iptable_filter \
 ,55))
@@ -507,6 +527,7 @@ $(eval $(call KMOD_template,IP_NF_TARGET_NETMAP,ip-nf-target-netmap,\
 #
 # Mangle
 #
+
 $(eval $(call KMOD_template,IP_NF_MANGLE,ip-nf-mangle,\
 	$(MODULES_DIR)/kernel/net/ipv4/netfilter/iptable_mangle \
 ,60))
@@ -526,6 +547,7 @@ $(eval $(call KMOD_template,IP_NF_TARGET_TTL,ip-nf-target-ttl,\
 #
 # IPv6: Netfilter
 #
+
 $(eval $(call KMOD_template,NF_CONNTRACK_IPV6,nf-conntrack-ipv6,\
 	$(MODULES_DIR)/kernel/net/ipv6/netfilter/nf_conntrack_ipv6 \
 ,50))
@@ -569,6 +591,7 @@ $(eval $(call KMOD_template,IP6_NF_TARGET_LOG,ip6-nf-target-log,\
 #
 # IPv6: Filtering
 #
+
 $(eval $(call KMOD_template,IP6_NF_FILTER,ip6-nf-filter,\
 	$(MODULES_DIR)/kernel/net/ipv6/netfilter/ip6table_filter \
 ,55))
@@ -580,6 +603,7 @@ $(eval $(call KMOD_template,IP6_NF_TARGET_REJECT,ip6-nf-target-reject,\
 #
 # IPv6: Mangle
 #
+
 $(eval $(call KMOD_template,IP6_NF_MANGLE,ip6-nf-mangle,\
 	$(MODULES_DIR)/kernel/net/ipv6/netfilter/ip6table_mangle \
 ,60))
@@ -641,6 +665,7 @@ $(eval $(call KMOD_template,IP_VS_FTP,ip-vs-ftp,\
 #
 # Block devices
 #
+
 $(eval $(call KMOD_template,BLK_DEV_LOOP,blk-dev-loop,\
     $(MODULES_DIR)/kernel/drivers/block/loop \
 ,20))
@@ -666,6 +691,7 @@ $(eval $(call KMOD_template,BLK_DEV_SR,blk-dev-sr,\
 #
 # RAID
 #
+
 $(eval $(call KMOD_template,BLK_DEV_MD,blk-dev-md,\
     $(MODULES_DIR)/kernel/drivers/md/md-mod \
 ,30))
@@ -691,6 +717,7 @@ $(eval $(call KMOD_template,MD_RAID456,md-raid456,\
 #
 # Device Mapper
 #
+
 $(eval $(call KMOD_template,BLK_DEV_DM,blk-dev-dm,\
     $(MODULES_DIR)/kernel/drivers/md/dm-mod \
 ,35))
@@ -709,7 +736,6 @@ $(eval $(call KMOD_template,DM_SNAPSHOT,dm-snapshot,\
     $(MODULES_DIR)/kernel/drivers/md/dm-snapshot \
 ,40))
 
-
 #
 # Crypto
 #
@@ -894,6 +920,7 @@ $(eval $(call KMOD_template,OCF_TALITOS,ocf-talitos,\
 #
 # Filesystems
 #
+
 $(eval $(call KMOD_template,AUFS_FS,aufs-fs,\
 	$(MODULES_DIR)/kernel/fs/aufs/aufs \
 ,30))
@@ -993,6 +1020,7 @@ $(eval $(call KMOD_template,UDF_FS,udf-fs,\
 #
 # Multimedia
 #
+
 $(eval $(call KMOD_template,SOUND,sound,\
 	$(MODULES_DIR)/kernel/sound/soundcore \
 ,30))
@@ -1032,10 +1060,16 @@ $(eval $(call KMOD_template,SND_CS5535AUDIO,sound-cs5535audio,\
 	$(MODULES_DIR)/kernel/sound/pci/cs5535audio/snd-cs5535audio \
 ,55))
 
-$(eval $(call KMOD_template,VIDEODEV,videodev,\
+$(eval $(call KMOD_template,VIDEO_DEV,video-dev,\
+	$(MODULES_DIR)/kernel/drivers/media/video/v4l1-compat \
+	$(MODULES_DIR)/kernel/drivers/media/video/v4l2-compat-ioctl32 \
 	$(MODULES_DIR)/kernel/drivers/media/video/videodev \
 ,65))
 
+$(eval $(call KMOD_template,USB_VIDEO_CLASS,usb-video-class,\
+	$(MODULES_DIR)/kernel/drivers/media/video/uvc/uvcvideo \
+,70))
+
 $(eval $(call KMOD_template,PWC,pwc,\
 	$(MODULES_DIR)/kernel/drivers/usb/pwc \
 ,70))
@@ -1043,6 +1077,7 @@ $(eval $(call KMOD_template,PWC,pwc,\
 #
 # PCMCIA/CardBus
 #
+
 $(eval $(call KMOD_template,PCCARD,pccard,\
 	$(MODULES_DIR)/kernel/drivers/pcmcia/pcmcia_core \
 ,40))
@@ -1219,10 +1254,10 @@ $(eval $(call KMOD_template,NETFILTER_XT_TARGET_LED,netfilter-xt-target-led,\
 	$(MODULES_DIR)/kernel/net/netfilter/xt_LED \
 ,90))
 
-
 #
 # NLS
 #
+
 $(eval $(call KMOD_template,NLS,nls,\
 	$(MODULES_DIR)/kernel/fs/nls/nls_base \
 ,10))
@@ -1389,7 +1424,10 @@ $(eval $(call KMOD_template,NLS_UTF8,nls-utf8, \
 	$(MODULES_DIR)/kernel/fs/nls/nls_utf8 \
 ,20))
 
+#
 # ISDN
+#
+
 ISDN_MODULES=drivers/isdn/i4l/isdn
 
 $(eval $(call KMOD_template,ISDN,isdn, \
@@ -1446,7 +1484,10 @@ $(eval $(call KMOD_template,MISDN_SPEEDFAX,misdn-speedfax, \
 	$(MODULES_DIR)/kernel/drivers/isdn/hardware/mISDN/sedlfax \
 ,80))
 
+#
 # Library modules
+#
+
 $(eval $(call KMOD_template,CRC_CCITT,crc-ccitt, \
 	$(MODULES_DIR)/kernel/lib/crc-ccitt \
 ,01))
@@ -1469,6 +1510,7 @@ $(eval $(call KMOD_template,LIBCRC32C,libcrc32c, \
 
 #
 # parallel port support
+#
 
 $(eval $(call KMOD_template,LP,lp,\
 	$(MODULES_DIR)/kernel/drivers/char/lp \

+ 2 - 2
mk/package.mk

@@ -160,7 +160,7 @@ IDEPEND_$(1):=	$$(strip $(4))
 _ALL_CONTROLS+=	$$(IDIR_$(1))/CONTROL/control
 ICONTROL_$(1)?=	$(WRKDIR)/.$(2).control
 $$(IDIR_$(1))/CONTROL/control: ${_PATCH_COOKIE}
-	@echo "Package: $(2)" > $(WRKDIR)/.$(2).control
+	@echo "Package: $$(shell echo $(2) | tr '_' '-')" > $(WRKDIR)/.$(2).control
 	@echo "Section: $(6)" >> $(WRKDIR)/.$(2).control
 	@echo "Description: $(5)" >> $(WRKDIR)/.$(2).control
 	${BASH} ${SCRIPT_DIR}/make-ipkg-dir.sh $${IDIR_$(1)} $${ICONTROL_$(1)} $(3) ${CPU_ARCH}
@@ -177,7 +177,7 @@ $$(IDIR_$(1))/CONTROL/control: ${_PATCH_COOKIE}
 			comma=", "; \
 			last=$$$$dep; \
 		done; \
-		echo "Depends: $$$$deps" >>$${IDIR_$(1)}/CONTROL/control; \
+		echo "Depends: $$$$deps" | tr '_' '-' >>$${IDIR_$(1)}/CONTROL/control; \
 	fi
 	@for file in conffiles preinst postinst prerm postrm; do \
 		[ ! -f ./files/$(2).$$$$file ] || cp ./files/$(2).$$$$file $$(IDIR_$(1))/CONTROL/$$$$file; \

+ 2 - 2
mk/vars.mk

@@ -37,8 +37,8 @@ PACKAGE_DIR:=		$(BIN_DIR)/packages
 TARGET_DIR:=		$(BASE_DIR)/root_${ADK_TARGET}_${ADK_LIBC}
 TARGET_DIR_PFX:=	$(BASE_DIR)/root_*
 TARGET_PATH=		${SCRIPT_DIR}:${STAGING_TOOLS}/bin:${STAGING_DIR}/scripts:${_PATH}
-REAL_GNU_TARGET_NAME=	$(CPU_ARCH)-openadk-linux-$(ADK_TARGET_SUFFIX)
-GNU_TARGET_NAME=	$(CPU_ARCH)-openadk-linux
+REAL_GNU_TARGET_NAME=	$(CPU_ARCH)-$(ADK_VENDOR)-linux-$(ADK_TARGET_SUFFIX)
+GNU_TARGET_NAME=	$(CPU_ARCH)-$(ADK_VENDOR)-linux
 TOOLCHAIN_SYSROOT:=	$(TOOLCHAIN_BUILD_DIR)/libc_dev
 ifeq ($(ADK_NATIVE),y) 
 TARGET_CROSS:=		

+ 23 - 0
package/Config.in

@@ -16,6 +16,7 @@ config ADK_ENABLE_IPV6
 	  exception proves the rule. ;)
 
 menu "Basesystem"
+source "package/alix-switch/Config.in"
 source "package/adkinstall/Config.in"
 source "package/base-files/Config.in"
 source "package/base-files/Config.in.manual"
@@ -29,6 +30,7 @@ source "package/libc/Config.in.manual"
 source "package/grub/Config.in"
 source "package/grub-bin/Config.in"
 source "package/rpm/Config.in"
+source "package/uvd/Config.in"
 endmenu
 
 menu "Bluetooth"
@@ -174,13 +176,19 @@ source "package/cxxtools/Config.in"
 source "package/dbus/Config.in"
 source "package/dbus-glib/Config.in"
 source "package/dbus-glib/Config.in.lib"
+source "package/DirectFB/Config.in"
+source "package/DirectFB/Config.in.lib"
 source "package/e2fsprogs/Config.in.lib"
+source "package/fltk/Config.in"
+source "package/fltk/Config.in.lib"
 source "package/fontconfig/Config.in"
+source "package/freeglut/Config.in"
 source "package/gettext/Config.in"
 source "package/glib/Config.in"
 source "package/gtk+/Config.in"
 source "package/heimdal/Config.in.lib"
 source "package/id3lib/Config.in"
+source "package/imlib2/Config.in"
 source "package/libao/Config.in"
 source "package/libao/Config.in.lib"
 source "package/libaudiofile/Config.in"
@@ -536,6 +544,7 @@ source "package/make/Config.in"
 source "package/microperl/Config.in"
 source "package/perl/Config.in"
 source "package/php/Config.in"
+source "package/pkg-config/Config.in"
 source "package/python/Config.in"
 source "package/python2/Config.in"
 source "package/ruby/Config.in"
@@ -572,6 +581,7 @@ endmenu
 menu "Utilities"
 source "package/bc/Config.in"
 source "package/comgt/Config.in"
+source "package/coreutils/Config.in"
 source "package/cpufrequtils/Config.in"
 source "package/fbset/Config.in"
 source "package/file/Config.in"
@@ -593,6 +603,7 @@ endmenu
 
 menu "Wireless"
 source "package/aircrack-ng/Config.in"
+source "package/b43-firmware/Config.in"
 source "package/chillispot/Config.in"
 source "package/hostapd/Config.in"
 source "package/iw/Config.in"
@@ -601,6 +612,7 @@ source "package/olsrd/Config.in"
 source "package/p54-firmware/Config.in"
 source "package/rt61-firmware/Config.in"
 source "package/wifidog/Config.in"
+source "package/wireless-tools/Config.in"
 source "package/wpa_supplicant/Config.in"
 endmenu
 
@@ -617,12 +629,19 @@ source "package/xf86-input-evtouch/Config.in"
 endmenu
 
 menu "X applications"
+source "package/dillo/Config.in"
 source "package/evilwm/Config.in"
 source "package/firefox/Config.in"
+source "package/fluxbox/Config.in"
 source "package/font-util/Config.in"
+source "package/qingy/Config.in"
 source "package/rxvt-unicode/Config.in"
+source "package/twm/Config.in"
 source "package/xauth/Config.in"
+source "package/xinit/Config.in"
 source "package/xlsfonts/Config.in"
+source "package/xterm/Config.in"
+source "package/xvinfo/Config.in"
 endmenu
 
 menu "X fonts"
@@ -672,12 +691,16 @@ source "package/libXdamage/Config.in"
 source "package/libXdamage/Config.in.lib"
 source "package/libXfixes/Config.in"
 source "package/libXfixes/Config.in.lib"
+source "package/libXi/Config.in"
+source "package/libXi/Config.in.lib"
 source "package/libXmu/Config.in"
 source "package/libXmu/Config.in.lib"
 source "package/libXpm/Config.in"
 source "package/libXpm/Config.in.lib"
 source "package/libXrender/Config.in"
 source "package/libXrender/Config.in.lib"
+source "package/libXScrnSaver/Config.in"
+source "package/libXScrnSaver/Config.in.lib"
 source "package/libXt/Config.in"
 source "package/libXt/Config.in.lib"
 source "package/libXft/Config.in"

+ 55 - 0
package/DirectFB/Makefile

@@ -0,0 +1,55 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=		DirectFB
+PKG_VERSION:=		1.4.3
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		223e036da906ceb4bd44708026839ff1
+PKG_DESCR:=		Thin library on top of the Linux framebuffer devices
+PKG_SECTION:=		libs
+PKG_BUILDDEP:=		libpng
+PKG_DEPENDS:=		libpng
+PKG_URL:=		http://www.directfb.org/
+PKG_SITES:=		http://directfb.org/downloads/Core/DirectFB-1.4/
+
+include $(TOPDIR)/mk/package.mk
+
+$(eval $(call PKG_template,DIRECTFB,directfb,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+
+CONFIGURE_ARGS+=	--with-inputdrivers=linuxinput,keyboard,ps2mouse \
+			--with-gfxdrivers=none \
+			--disable-osx
+
+# This is to overcome libtool fuckup - when building without,
+# libtool calls (the correct) ld directly without parameters,
+# which then chooses the wrong default emulation (which is
+# probably the real problem here). LDEMULATION overrides ld's
+# wrong choice.
+ifeq (${ADK_LINUX_MIPS64_LEMOTE},y)
+XAKE_FLAGS+=		LDEMULATION=elf64ltsmip
+endif
+
+post-install:
+	${INSTALL_DIR} ${IDIR_DIRECTFB}/etc
+	${INSTALL_DATA} ./files/directfbrc ${IDIR_DIRECTFB}/etc/
+	$(INSTALL_DIR) $(IDIR_DIRECTFB)/usr/lib/directfb-1.4-0/{inputdrivers,systems,wm}
+	${CP} $(WRKINST)/usr/lib/lib{direct,fusion}*.so* \
+		$(IDIR_DIRECTFB)/usr/lib/
+	${CP} ${WRKINST}/usr/lib/directfb-1.4-0/inputdrivers/libdirectfb_linux_input.so \
+		${IDIR_DIRECTFB}/usr/lib/directfb-1.4-0/inputdrivers/
+	${CP} ${WRKINST}/usr/lib/directfb-1.4-0/systems/*.so \
+		${IDIR_DIRECTFB}/usr/lib/directfb-1.4-0/systems/
+	${CP} ${WRKINST}/usr/lib/directfb-1.4-0/wm/*.so \
+		${IDIR_DIRECTFB}/usr/lib/directfb-1.4-0/wm/
+	$(INSTALL_DIR) $(IDIR_DIRECTFB)/usr/lib/directfb-1.4-0/interfaces/IDirectFB{Font,ImageProvider,VideoProvider}
+	${CP} ${WRKINST}/usr/lib/directfb-1.4-0/interfaces/IDirectFBFont/*.so \
+		${IDIR_DIRECTFB}/usr/lib/directfb-1.4-0/interfaces/IDirectFBFont/
+	${CP} ${WRKINST}/usr/lib/directfb-1.4-0/interfaces/IDirectFBImageProvider/*.so \
+		${IDIR_DIRECTFB}/usr/lib/directfb-1.4-0/interfaces/IDirectFBImageProvider/
+	${CP} ${WRKINST}/usr/lib/directfb-1.4-0/interfaces/IDirectFBVideoProvider/*.so \
+		${IDIR_DIRECTFB}/usr/lib/directfb-1.4-0/interfaces/IDirectFBVideoProvider/
+
+
+include ${TOPDIR}/mk/pkg-bottom.mk

+ 1 - 0
package/DirectFB/files/DirectFB.conffiles

@@ -0,0 +1 @@
+/etc/directfbrc

+ 4 - 0
package/DirectFB/files/directfbrc

@@ -0,0 +1,4 @@
+#mode=1024x600
+#depth=16
+mouse-protocol=IMPS/2
+mouse-source=/dev/psaux

+ 35 - 7
package/MesaLib/Makefile

@@ -15,21 +15,40 @@ PKG_BUILDDEP+=		dri2proto glproto expat
 PKG_URL:=		http://www.mesa3d.org/
 PKG_SITES:=		ftp://ftp.freedesktop.org/pub/mesa/7.8.1/
 
+PKG_DESCR_GLXINFO:=	Display various GLX information
+PKG_SECT_GLXINFO:=	x11
+PKG_DESCR_GLXGEARS:=	Nice little OpenGL demo application
+PKG_SECT_GLXGEARS:=	x11
+
 WRKDIST=		${WRKDIR}/Mesa-${PKG_VERSION}
 
-PKG_TARGET_DEPENDS:=  	ibmx40
+PKG_TARGET_DEPENDS:=  	ibmx40 lemote
 
 include $(TOPDIR)/mk/package.mk
 
 $(eval $(call PKG_template,MESALIB,mesalib,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+$(eval $(call PKG_template,GLXINFO,glxinfo,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR_GLXINFO},${PKG_SECT_GLXINFO}))
+$(eval $(call PKG_template,GLXGEARS,glxgears,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR_GLXGEARS},${PKG_SECT_GLXGEARS}))
+
+ifeq (${ADK_LINUX_X86_IBMX40},y)
+DRI_DRIVERS:=i810
+endif
+
+# Lemote's SMI712 is not directly supported by Mesa,
+# and at least some SIS driver fails to build when
+# keeping the driver auto-selection intact.
+ifeq (${ADK_LINUX_MIPS64_LEMOTE},y)
+DRI_DRIVERS:=swrast
+endif
 
 CONFIGURE_ARGS+=	--disable-static \
 			--disable-gallium \
 			--disable-glw \
 			--with-driver=dri \
-			--without-demos
+			--with-dri-drivers=${DRI_DRIVERS} \
+			--with-demos=xdemos
 
-XAKE_FLAGS+=		APP_CC=${HOSTCC} HOST_CC=${HOSTCC}
+XAKE_FLAGS+=		HOST_CC=${HOSTCC}
 
 pre-configure:
 	(cd ${WRKBUILD}; rm -rf config.{cache,status}; \
@@ -38,17 +57,26 @@ pre-configure:
 		--disable-glw \
 		--disable-gallium \
 		--with-driver=xlib \
-		--without-demos \
 	);
 	${MAKE} -C ${WRKBUILD}/src/glsl
 	${MAKE} -C ${WRKBUILD}/src/glsl/apps
-	cp ${WRKBUILD}/src/glsl/apps/compile \
+	${CP} ${WRKBUILD}/src/glsl/apps/compile \
 		${STAGING_TOOLS}/bin
 	${MAKE} -C ${WRKBUILD}/src/glsl clean
 
 post-install:
-	$(INSTALL_DIR) $(IDIR_MESALIB)/usr/lib
-	$(INSTALL_BIN) $(WRKINST)/usr/lib/libGL*.so* \
+	$(INSTALL_DIR) $(IDIR_MESALIB)/usr/lib/dri
+	$(CP) $(WRKINST)/usr/lib/libGL*.so* \
 		$(IDIR_MESALIB)/usr/lib
+ifeq (${ADK_LINUX_MIPS64_LEMOTE},y)
+	${CP} $(WRKINST)/usr/lib/dri/swrast_dri.so \
+		${IDIR_MESALIB}/usr/lib/dri/
+endif
+	${INSTALL_DIR} ${IDIR_GLXINFO}/usr/bin
+	${INSTALL_BIN} ${WRKBUILD}/progs/xdemos/glxinfo \
+		${IDIR_GLXINFO}/usr/bin/
+	${INSTALL_DIR} ${IDIR_GLXGEARS}/usr/bin
+	${INSTALL_BIN} ${WRKBUILD}/progs/xdemos/glxgears \
+		${IDIR_GLXGEARS}/usr/bin/
 
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 14774 - 0
package/MesaLib/patches/000-mesalib-xdemos.patch

@@ -0,0 +1,14774 @@
+diff -Naurp Mesa-7.8.1/progs/xdemos/corender.c Mesa-7.8.1.patched/progs/xdemos/corender.c
+--- Mesa-7.8.1/progs/xdemos/corender.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/corender.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,400 @@
++/**
++ * Example of cooperative rendering into one window by two processes.
++ * The first instance of the program creates the GLX window.
++ * The second instance of the program gets the window ID from the first
++ * and draws into it.
++ * Socket IPC is used for synchronization.
++ *
++ * Usage:
++ * 1. run 'corender &'
++ * 2. run 'corender 2'  (any arg will do)
++ *
++ * Brian Paul
++ * 11 Oct 2007
++ */
++
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <assert.h>
++#include <math.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <X11/keysym.h>
++#include <unistd.h>
++#include "ipc.h"
++
++
++#ifndef M_PI
++#define M_PI 3.14159265358979323846
++#endif
++
++static int MyID = 0;  /* 0 or 1 */
++static int WindowID = 0;
++static GLXContext Context = 0;
++static int Width = 700, Height = 350;
++static int Rot = 0;
++static int Sock = 0;
++
++static GLfloat Red[4] = {1.0, 0.2, 0.2, 1.0};
++static GLfloat Blue[4] = {0.2, 0.2, 1.0, 1.0};
++
++static int Sync = 1;  /** synchronized rendering? */
++
++
++static void
++setup_ipc(void)
++{
++   int k, port = 10001;
++
++   if (MyID == 0) {
++      /* I'm the first one, wait for connection from second */
++      k = CreatePort(&port);
++      assert(k != -1);
++
++      printf("Waiting for connection from another 'corender'\n");
++      Sock = AcceptConnection(k);
++      assert(Sock != -1);
++
++      printf("Got connection, sending windowID\n");
++
++      /* send windowID */
++      SendData(Sock, &WindowID, sizeof(WindowID));
++   }
++   else {
++      /* I'm the second one, connect to first */
++      char hostname[1000];
++
++      MyHostName(hostname, 1000);
++      Sock = Connect(hostname, port);
++      assert(Sock != -1);
++
++      /* get windowID */
++      ReceiveData(Sock, &WindowID, sizeof(WindowID));
++      printf("Contacted first 'corender', getting WindowID\n");
++   }
++}
++
++
++
++/** from GLUT */
++static void
++doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
++{
++  int i, j;
++  GLfloat theta, phi, theta1;
++  GLfloat cosTheta, sinTheta;
++  GLfloat cosTheta1, sinTheta1;
++  GLfloat ringDelta, sideDelta;
++
++  ringDelta = 2.0 * M_PI / rings;
++  sideDelta = 2.0 * M_PI / nsides;
++
++  theta = 0.0;
++  cosTheta = 1.0;
++  sinTheta = 0.0;
++  for (i = rings - 1; i >= 0; i--) {
++    theta1 = theta + ringDelta;
++    cosTheta1 = cos(theta1);
++    sinTheta1 = sin(theta1);
++    glBegin(GL_QUAD_STRIP);
++    phi = 0.0;
++    for (j = nsides; j >= 0; j--) {
++      GLfloat cosPhi, sinPhi, dist;
++
++      phi += sideDelta;
++      cosPhi = cos(phi);
++      sinPhi = sin(phi);
++      dist = R + r * cosPhi;
++
++      glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
++      glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
++      glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
++      glVertex3f(cosTheta * dist, -sinTheta * dist,  r * sinPhi);
++    }
++    glEnd();
++    theta = theta1;
++    cosTheta = cosTheta1;
++    sinTheta = sinTheta1;
++  }
++}
++
++
++static void
++redraw(Display *dpy)
++{
++   int dbg = 0;
++
++   glXMakeCurrent(dpy, WindowID, Context);
++   glEnable(GL_LIGHTING);
++   glEnable(GL_LIGHT0);
++   glEnable(GL_DEPTH_TEST);
++   glClearColor(0.5, 0.5, 0.5, 0.0);
++
++   if (MyID == 0) {
++      /* First process */
++
++      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++      glPushMatrix();
++      glTranslatef(-1, 0, 0);
++      glRotatef(Rot, 1, 0, 0);
++      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Red);
++      doughnut(0.5, 2.0, 20, 30);
++      glPopMatrix();
++
++      glFinish();
++      if (!Sync) {
++         usleep(1000*10);
++      }
++
++      /* signal second process to render */
++      if (Sync) {
++         int code = 1;
++         if (dbg) printf("0: send signal\n");
++         SendData(Sock, &code, sizeof(code));
++         SendData(Sock, &Rot, sizeof(Rot));
++      }
++
++      /* wait for second process to finish rendering */
++      if (Sync) {
++         int code = 0;
++         if (dbg) printf("0: wait signal\n");
++         ReceiveData(Sock, &code, sizeof(code));
++         if (dbg) printf("0: got signal\n");
++         assert(code == 2);
++      }
++
++   }
++   else {
++      /* Second process */
++
++      /* wait for first process's signal for me to render */
++      if (Sync) {
++         int code = 0;
++         if (dbg) printf("1: wait signal\n");
++         ReceiveData(Sock, &code, sizeof(code));
++         ReceiveData(Sock, &Rot, sizeof(Rot));
++
++         if (dbg) printf("1: got signal\n");
++         assert(code == 1);
++      }
++
++      /* XXX this clear should not be here, but for some reason, it
++       * makes things _mostly_ work correctly w/ NVIDIA's driver.
++       * There's only occasional glitches.
++       * Without this glClear(), depth buffer for the second process
++       * is pretty much broken.
++       */
++      /* glClear(GL_DEPTH_BUFFER_BIT); */
++
++      glPushMatrix();
++      glTranslatef(1, 0, 0);
++      glRotatef(Rot + 90 , 1, 0, 0);
++      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Blue);
++      doughnut(0.5, 2.0, 20, 30);
++      glPopMatrix();
++      glFinish();
++
++      glXSwapBuffers(dpy, WindowID);
++      usleep(1000*10);
++
++      /* signal first process that I'm done rendering */
++      if (Sync) {
++         int code = 2;
++         if (dbg) printf("1: send signal\n");
++         SendData(Sock, &code, sizeof(code));
++      }
++   }
++}
++
++
++static void
++resize(Display *dpy, int width, int height)
++{
++   float ar = (float) width / height;
++
++   glXMakeCurrent(dpy, WindowID, Context);
++
++   glViewport(0, 0, width, height);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glFrustum(-ar, ar, 1.0, -1.0, 5.0, 200.0);
++   glMatrixMode(GL_MODELVIEW);
++   glLoadIdentity();
++   glTranslatef(0, 0, -15);
++
++   Width = width;
++   Height = height;
++}
++
++
++
++static void
++set_window_title(Display *dpy, Window win, const char *title)
++{
++   XSizeHints sizehints;
++   sizehints.flags = 0;
++   XSetStandardProperties(dpy, win, title, title,
++                          None, (char **)NULL, 0, &sizehints);
++}
++
++
++static Window
++make_gl_window(Display *dpy, XVisualInfo *visinfo, int width, int height)
++{
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   int x = 0, y = 0;
++   char *name = NULL;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, x, y, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   return win;
++}
++
++
++static void
++set_event_mask(Display *dpy, Window win)
++{
++   XSetWindowAttributes attr;
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   XChangeWindowAttributes(dpy, win, CWEventMask, &attr);
++}
++
++
++static void
++event_loop(Display *dpy)
++{
++   while (1) {
++      while (XPending(dpy) > 0) {
++         XEvent event;
++         XNextEvent(dpy, &event);
++
++         switch (event.type) {
++         case Expose:
++            redraw(dpy);
++            break;
++         case ConfigureNotify:
++            resize(dpy, event.xconfigure.width, event.xconfigure.height);
++            break;
++         case KeyPress:
++            {
++               char buffer[10];
++               int r, code;
++               code = XLookupKeysym(&event.xkey, 0);
++               if (code == XK_Left) {
++               }
++               else {
++                  r = XLookupString(&event.xkey, buffer, sizeof(buffer),
++                                    NULL, NULL);
++                  if (buffer[0] == 27) {
++                     exit(0);
++                  }
++               }
++            }
++         default:
++            /* nothing */
++            ;
++         }
++      }
++
++      if (MyID == 0 || !Sync)
++         Rot += 1;
++      redraw(dpy);
++   }
++}
++
++
++static XVisualInfo *
++choose_visual(Display *dpy)
++{
++   int attribs[] = { GLX_RGBA,
++                     GLX_RED_SIZE, 1,
++                     GLX_GREEN_SIZE, 1,
++                     GLX_BLUE_SIZE, 1,
++                     GLX_DOUBLEBUFFER,
++                     GLX_DEPTH_SIZE, 1,
++                     None };
++   int scrnum = DefaultScreen( dpy );
++   return glXChooseVisual(dpy, scrnum, attribs);
++}
++
++
++static void
++parse_opts(int argc, char *argv[])
++{
++   if (argc > 1) {
++      MyID = 1;
++   }
++}
++
++
++int
++main( int argc, char *argv[] )
++{
++   Display *dpy;
++   XVisualInfo *visinfo;
++
++   parse_opts(argc, argv);
++
++   dpy = XOpenDisplay(NULL);
++
++   visinfo = choose_visual(dpy);
++
++   Context = glXCreateContext( dpy, visinfo, NULL, True );
++   if (!Context) {
++      printf("Error: glXCreateContext failed\n");
++      exit(1);
++   }
++
++   if (MyID == 0) {
++      WindowID = make_gl_window(dpy, visinfo, Width, Height);
++      set_window_title(dpy, WindowID, "corender");
++      XMapWindow(dpy, WindowID);
++      /*printf("WindowID 0x%x\n", (int) WindowID);*/
++   }
++
++   /* do ipc hand-shake here */
++   setup_ipc();
++   assert(Sock);
++   assert(WindowID);
++
++   if (MyID == 1) {
++      set_event_mask(dpy, WindowID);
++   }
++
++   resize(dpy, Width, Height);
++
++   event_loop(dpy);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glsync.c Mesa-7.8.1.patched/progs/xdemos/glsync.c
+--- Mesa-7.8.1/progs/xdemos/glsync.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glsync.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,295 @@
++/*
++ * Copyright © 2007 Intel Corporation
++ *
++ * 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 (including the next
++ * paragraph) 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.
++ *
++ * Authors:
++ *    Jesse Barnes <jesse.barnes@intel.com>
++ *
++ */
++
++/** @file glsync.c
++ * The program is simple:  it paints a window alternating colors (red &
++ * white) either as fast as possible or synchronized to vblank events
++ *
++ * If run normally, the program should display a window that exhibits
++ * significant tearing between red and white colors (e.g. you might get
++ * a "waterfall" effect of red and white horizontal bars).
++ *
++ * If run with the '-s b' option, the program should synchronize the
++ * window color changes with the vertical blank period, resulting in a
++ * window that looks orangish with a high frequency flicker (which may
++ * be invisible).  If the window is moved to another screen, this
++ * property should be preserved.  If the window spans two screens, it
++ * shouldn't tear on whichever screen most of the window is on; the
++ * portion on the other screen may show some tearing (like the
++ * waterfall effect above).
++ *
++ * Other options include '-w <width>' and '-h <height' to set the
++ * window size.
++ */
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <GL/gl.h>
++#include <GL/glu.h>
++#include <GL/glx.h>
++#include <GL/glxext.h>
++#include <X11/X.h>
++#include <X11/Xlib.h>
++#include <X11/Xutil.h>
++
++void (*video_sync_get)();
++void (*video_sync)();
++void (*swap_interval)();
++
++static int GLXExtensionSupported(Display *dpy, const char *extension)
++{
++	const char *extensionsString, *pos;
++
++	extensionsString = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
++
++	pos = strstr(extensionsString, extension);
++
++	if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') &&
++	    (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0'))
++		return 1;
++
++	return 0;
++}
++
++extern char *optarg;
++extern int optind, opterr, optopt;
++static char optstr[] = "w:h:s:vi:";
++
++enum sync_type {
++	none = 0,
++	sgi_video_sync,
++	buffer_swap
++};
++
++static void usage(char *name)
++{
++	printf("usage: %s [-w <width>] [-h <height>] [-s<sync method>] "
++	       "[-v]\n", name);
++	printf("\t-s<sync method>:\n");
++	printf("\t\tn: none\n");
++	printf("\t\ts: SGI video sync extension\n");
++	printf("\t\tb: buffer swap\n");
++	printf("\t-i<swap interval>\n");
++	printf("\t-v: verbose (print count)\n");
++	exit(-1);
++}
++
++int main(int argc, char *argv[])
++{
++	Display *disp;
++	XVisualInfo *pvi;
++	XSetWindowAttributes swa;
++	GLint last_val = -1, count = 0;
++	Window winGL;
++	GLXContext context;
++	int dummy;
++	Atom wmDelete;
++	enum sync_type waitforsync = none;
++	int width = 500, height = 500, verbose = 0, interval = 1;
++	int c, i = 1;
++	int ret;
++	int attribs[] = { GLX_RGBA,
++                     GLX_RED_SIZE, 1,
++                     GLX_GREEN_SIZE, 1,
++                     GLX_BLUE_SIZE, 1,
++                     None };
++	int db_attribs[] = { GLX_RGBA,
++                     GLX_RED_SIZE, 1,
++                     GLX_GREEN_SIZE, 1,
++                     GLX_BLUE_SIZE, 1,
++                     GLX_DOUBLEBUFFER,
++                     GLX_DEPTH_SIZE, 1,
++                     None };
++	XSizeHints sizehints;
++
++	opterr = 0;
++	while ((c = getopt(argc, argv, optstr)) != -1) {
++		switch (c) {
++		case 'w':
++			width = atoi(optarg);
++			break;
++		case 'h':
++			height = atoi(optarg);
++			break;
++		case 's':
++			switch (optarg[0]) {
++			case 'n':
++				waitforsync = none;
++				break;
++			case 's':
++				waitforsync = sgi_video_sync;
++				break;
++			case 'b':
++				waitforsync = buffer_swap;
++				break;
++			default:
++				usage(argv[0]);
++				break;
++			}
++			break;
++		case 'v':
++			verbose = 1;
++			break;
++		case 'i':
++			interval = atoi(optarg);
++			break;
++		default:
++			usage(argv[0]);
++			break;
++		}
++	}
++
++	disp = XOpenDisplay(NULL);
++	if (!disp) {
++		fprintf(stderr, "failed to open display\n");
++		return -1;
++	}
++
++	if (!glXQueryExtension(disp, &dummy, &dummy)) {
++		fprintf(stderr, "glXQueryExtension failed\n");
++		return -1;
++	}
++
++	if (!GLXExtensionSupported(disp, "GLX_SGI_video_sync")) {
++		fprintf(stderr, "GLX_SGI_video_sync not supported, exiting\n");
++		return -1;
++	}
++
++	if (waitforsync != buffer_swap) {
++		pvi = glXChooseVisual(disp, DefaultScreen(disp), attribs);
++	} else {
++		pvi = glXChooseVisual(disp, DefaultScreen(disp), db_attribs);
++	}
++
++	if (!pvi) {
++		fprintf(stderr, "failed to choose visual, exiting\n");
++		return -1;
++	}
++
++	pvi->screen = DefaultScreen(disp);
++
++	swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen),
++				       pvi->visual, AllocNone);
++	swa.border_pixel = 0;
++	swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
++		StructureNotifyMask;
++	winGL = XCreateWindow(disp, RootWindow(disp, pvi->screen),
++			      0, 0,
++			      width, height,
++			      0, pvi->depth, InputOutput, pvi->visual,
++			      CWBorderPixel | CWColormap | CWEventMask, &swa);
++	if (!winGL) {
++		fprintf(stderr, "window creation failed\n");
++		return -1;
++	}
++        wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True);
++        XSetWMProtocols(disp, winGL, &wmDelete, 1);
++
++	sizehints.x = 0;
++	sizehints.y = 0;
++	sizehints.width  = width;
++	sizehints.height = height;
++	sizehints.flags = USSize | USPosition;
++
++	XSetNormalHints(disp, winGL, &sizehints);
++	XSetStandardProperties(disp, winGL, "glsync test", "glsync text",
++			       None, NULL, 0, &sizehints);
++
++	context = glXCreateContext(disp, pvi, NULL, GL_TRUE);
++	if (!context) {
++		fprintf(stderr, "failed to create glx context\n");
++		return -1;
++	}
++
++	XMapWindow(disp, winGL);
++	ret = glXMakeCurrent(disp, winGL, context);
++	if (!ret) {
++		fprintf(stderr, "failed to make context current: %d\n", ret);
++	}
++
++	video_sync_get = glXGetProcAddress((unsigned char *)"glXGetVideoSyncSGI");
++	video_sync = glXGetProcAddress((unsigned char *)"glXWaitVideoSyncSGI");
++
++	swap_interval = glXGetProcAddress((unsigned char *)"glXSwapIntervalSGI");
++
++	if (!video_sync_get || !video_sync || !swap_interval) {
++		fprintf(stderr, "failed to get sync functions\n");
++		return -1;
++	}
++
++	if (waitforsync == buffer_swap) {
++		swap_interval(interval);
++		fprintf(stderr, "set swap interval to %d\n", interval);
++	}
++	video_sync_get(&count);
++	count++;
++	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++	while (i++) {
++		/* Alternate colors to make tearing obvious */
++		if (i & 1) {
++			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
++			glColor3f(1.0f, 1.0f, 1.0f);
++		} else {
++			glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
++			glColor3f(1.0f, 0.0f, 0.0f);
++		}
++
++		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++		glRectf(0, 0, width, height);
++
++		/* Wait for vsync */
++		if (waitforsync == sgi_video_sync) {
++			if (verbose)
++				fprintf(stderr, "waiting on count %d\n", count);
++			video_sync(2, (count + 1) % 2, &count);
++			if (count < last_val)
++				fprintf(stderr, "error:  vblank count went backwards: %d -> %d\n", last_val, count);
++			if (count == last_val)
++				fprintf(stderr, "error:  count didn't change: %d\n", count);
++			last_val = count;
++			glFlush();
++		} else if (waitforsync == buffer_swap) {
++			glXSwapBuffers(disp, winGL);
++		} else {
++			video_sync_get(&count);
++			sleep(1);
++			glFinish();
++		}
++
++		if (verbose) {
++			video_sync_get(&count);
++			fprintf(stderr, "current count: %d\n", count);
++		}
++	}
++
++	XDestroyWindow(disp, winGL);
++	glXDestroyContext(disp, context);
++	XCloseDisplay(disp);
++
++	return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glthreads.c Mesa-7.8.1.patched/progs/xdemos/glthreads.c
+--- Mesa-7.8.1/progs/xdemos/glthreads.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glthreads.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,716 @@
++/*
++ * Copyright (C) 2000  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++/*
++ * This program tests GLX thread safety.
++ * Command line options:
++ *  -p                       Open a display connection for each thread
++ *  -l                       Enable application-side locking
++ *  -n <num threads>         Number of threads to create (default is 2)
++ *  -display <display name>  Specify X display (default is $DISPLAY)
++ *  -t                       Use texture mapping
++ *
++ * Brian Paul  20 July 2000
++ */
++
++
++/*
++ * Notes:
++ * - Each thread gets its own GLX context.
++ *
++ * - The GLX contexts share texture objects.
++ *
++ * - When 't' is pressed to update the texture image, the window/thread which
++ *   has input focus is signalled to change the texture.  The other threads
++ *   should see the updated texture the next time they call glBindTexture.
++ */
++
++
++#if defined(PTHREADS)   /* defined by Mesa on Linux and other platforms */
++
++#include <assert.h>
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <math.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <pthread.h>
++
++
++/*
++ * Each window/thread/context:
++ */
++struct winthread {
++   Display *Dpy;
++   int Index;
++   pthread_t Thread;
++   Window Win;
++   GLXContext Context;
++   float Angle;
++   int WinWidth, WinHeight;
++   GLboolean NewSize;
++   GLboolean Initialized;
++   GLboolean MakeNewTexture;
++};
++
++
++#define MAX_WINTHREADS 100
++static struct winthread WinThreads[MAX_WINTHREADS];
++static int NumWinThreads = 0;
++static volatile GLboolean ExitFlag = GL_FALSE;
++
++static GLboolean MultiDisplays = 0;
++static GLboolean Locking = 0;
++static GLboolean Texture = GL_FALSE;
++static GLuint TexObj = 12;
++static GLboolean Animate = GL_TRUE;
++
++static pthread_mutex_t Mutex;
++static pthread_cond_t CondVar;
++static pthread_mutex_t CondMutex;
++
++
++static void
++Error(const char *msg)
++{
++   fprintf(stderr, "Error: %s\n", msg);
++   exit(1);
++}
++
++
++static void
++signal_redraw(void)
++{
++   pthread_mutex_lock(&CondMutex);
++   pthread_cond_broadcast(&CondVar);
++   pthread_mutex_unlock(&CondMutex);
++}
++
++
++static void
++MakeNewTexture(struct winthread *wt)
++{
++#define TEX_SIZE 128
++   static float step = 0.0;
++   GLfloat image[TEX_SIZE][TEX_SIZE][4];
++   GLint width;
++   int i, j;
++
++   for (j = 0; j < TEX_SIZE; j++) {
++      for (i = 0; i < TEX_SIZE; i++) {
++         float dt = 5.0 * (j - 0.5 * TEX_SIZE) / TEX_SIZE;
++         float ds = 5.0 * (i - 0.5 * TEX_SIZE) / TEX_SIZE;
++         float r = dt * dt + ds * ds + step;
++         image[j][i][0] = 
++         image[j][i][1] = 
++         image[j][i][2] = 0.75 + 0.25 * cos(r);
++         image[j][i][3] = 1.0;
++      }
++   }
++
++   step += 0.5;
++
++   glBindTexture(GL_TEXTURE_2D, TexObj);
++
++   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
++   if (width) {
++      assert(width == TEX_SIZE);
++      /* sub-tex replace */
++      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEX_SIZE, TEX_SIZE,
++                   GL_RGBA, GL_FLOAT, image);
++   }
++   else {
++      /* create new */
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++
++      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, 
++                   GL_RGBA, GL_FLOAT, image);
++   }
++}
++
++
++
++/* draw a colored cube */
++static void
++draw_object(void)
++{
++   glPushMatrix();
++   glScalef(0.75, 0.75, 0.75);
++
++   glColor3f(1, 0, 0);
++
++   if (Texture) {
++      glBindTexture(GL_TEXTURE_2D, TexObj);
++      glEnable(GL_TEXTURE_2D);
++   }
++   else {
++      glDisable(GL_TEXTURE_2D);
++   }
++
++   glBegin(GL_QUADS);
++
++   /* -X */
++   glColor3f(0, 1, 1);
++   glTexCoord2f(0, 0);  glVertex3f(-1, -1, -1);
++   glTexCoord2f(1, 0);  glVertex3f(-1,  1, -1);
++   glTexCoord2f(1, 1);  glVertex3f(-1,  1,  1);
++   glTexCoord2f(0, 1);  glVertex3f(-1, -1,  1);
++
++   /* +X */
++   glColor3f(1, 0, 0);
++   glTexCoord2f(0, 0);  glVertex3f(1, -1, -1);
++   glTexCoord2f(1, 0);  glVertex3f(1,  1, -1);
++   glTexCoord2f(1, 1);  glVertex3f(1,  1,  1);
++   glTexCoord2f(0, 1);  glVertex3f(1, -1,  1);
++
++   /* -Y */
++   glColor3f(1, 0, 1);
++   glTexCoord2f(0, 0);  glVertex3f(-1, -1, -1);
++   glTexCoord2f(1, 0);  glVertex3f( 1, -1, -1);
++   glTexCoord2f(1, 1);  glVertex3f( 1, -1,  1);
++   glTexCoord2f(0, 1);  glVertex3f(-1, -1,  1);
++
++   /* +Y */
++   glColor3f(0, 1, 0);
++   glTexCoord2f(0, 0);  glVertex3f(-1, 1, -1);
++   glTexCoord2f(1, 0);  glVertex3f( 1, 1, -1);
++   glTexCoord2f(1, 1);  glVertex3f( 1, 1,  1);
++   glTexCoord2f(0, 1);  glVertex3f(-1, 1,  1);
++
++   /* -Z */
++   glColor3f(1, 1, 0);
++   glTexCoord2f(0, 0);  glVertex3f(-1, -1, -1);
++   glTexCoord2f(1, 0);  glVertex3f( 1, -1, -1);
++   glTexCoord2f(1, 1);  glVertex3f( 1,  1, -1);
++   glTexCoord2f(0, 1);  glVertex3f(-1,  1, -1);
++
++   /* +Y */
++   glColor3f(0, 0, 1);
++   glTexCoord2f(0, 0);  glVertex3f(-1, -1, 1);
++   glTexCoord2f(1, 0);  glVertex3f( 1, -1, 1);
++   glTexCoord2f(1, 1);  glVertex3f( 1,  1, 1);
++   glTexCoord2f(0, 1);  glVertex3f(-1,  1, 1);
++
++   glEnd();
++
++   glPopMatrix();
++}
++
++
++/* signal resize of given window */
++static void
++resize(struct winthread *wt, int w, int h)
++{
++   wt->NewSize = GL_TRUE;
++   wt->WinWidth = w;
++   wt->WinHeight = h;
++   if (!Animate)
++      signal_redraw();
++}
++
++
++/*
++ * We have an instance of this for each thread.
++ */
++static void
++draw_loop(struct winthread *wt)
++{
++   while (!ExitFlag) {
++
++      if (Locking)
++         pthread_mutex_lock(&Mutex);
++
++      glXMakeCurrent(wt->Dpy, wt->Win, wt->Context);
++      if (!wt->Initialized) {
++         printf("glthreads: %d: GL_RENDERER = %s\n", wt->Index,
++                (char *) glGetString(GL_RENDERER));
++         if (Texture /*&& wt->Index == 0*/) {
++            MakeNewTexture(wt);
++         }
++         wt->Initialized = GL_TRUE;
++      }
++
++      if (Locking)
++         pthread_mutex_unlock(&Mutex);
++
++      glEnable(GL_DEPTH_TEST);
++
++      if (wt->NewSize) {
++         GLfloat w = (float) wt->WinWidth / (float) wt->WinHeight;
++         glViewport(0, 0, wt->WinWidth, wt->WinHeight);
++         glMatrixMode(GL_PROJECTION);
++         glLoadIdentity();
++         glFrustum(-w, w, -1.0, 1.0, 1.5, 10);
++         glMatrixMode(GL_MODELVIEW);
++         glLoadIdentity();
++         glTranslatef(0, 0, -2.5);
++         wt->NewSize = GL_FALSE;
++      }
++
++      if (wt->MakeNewTexture) {
++         MakeNewTexture(wt);
++         wt->MakeNewTexture = GL_FALSE;
++      }
++
++      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++      glPushMatrix();
++         glRotatef(wt->Angle, 0, 1, 0);
++         glRotatef(wt->Angle, 1, 0, 0);
++         glScalef(0.7, 0.7, 0.7);
++         draw_object();
++      glPopMatrix();
++
++      if (Locking)
++         pthread_mutex_lock(&Mutex);
++
++      glXSwapBuffers(wt->Dpy, wt->Win);
++
++      if (Locking)
++         pthread_mutex_unlock(&Mutex);
++
++      if (Animate) {
++         usleep(5000);
++      }
++      else {
++         /* wait for signal to draw */
++         pthread_mutex_lock(&CondMutex);
++         pthread_cond_wait(&CondVar, &CondMutex);
++         pthread_mutex_unlock(&CondMutex);
++      }
++      wt->Angle += 1.0;
++   }
++}
++
++
++static void
++keypress(XEvent *event, struct winthread *wt)
++{
++   char buf[100];
++   KeySym keySym;
++   XComposeStatus stat;
++
++   XLookupString(&event->xkey, buf, sizeof(buf), &keySym, &stat);
++
++   switch (keySym) {
++   case XK_Escape:
++      /* tell all threads to exit */
++      if (!Animate) {
++         signal_redraw();
++      }
++      ExitFlag = GL_TRUE;
++      /*printf("exit draw_loop %d\n", wt->Index);*/
++      return;
++   case XK_t:
++   case XK_T:
++      if (Texture) {
++         wt->MakeNewTexture = GL_TRUE;
++         if (!Animate)
++            signal_redraw();
++      }
++      break;
++   case XK_a:
++   case XK_A:
++      Animate = !Animate;
++      if (Animate)  /* yes, prev Animate state! */
++         signal_redraw();
++      break;
++   case XK_s:
++   case XK_S:
++      if (!Animate)
++         signal_redraw();
++      break;
++   default:
++      ; /* nop */
++   }
++}
++
++
++/*
++ * The main process thread runs this loop.
++ * Single display connection for all threads.
++ */
++static void
++event_loop(Display *dpy)
++{
++   XEvent event;
++   int i;
++
++   assert(!MultiDisplays);
++
++   while (!ExitFlag) {
++
++      if (Locking) {
++         while (1) {
++            int k;
++            pthread_mutex_lock(&Mutex);
++            k = XPending(dpy);
++            if (k) {
++               XNextEvent(dpy, &event);
++               pthread_mutex_unlock(&Mutex);
++               break;
++            }
++            pthread_mutex_unlock(&Mutex);
++            usleep(5000);
++         }
++      }
++      else {
++         XNextEvent(dpy, &event);
++      }
++
++      switch (event.type) {
++         case ConfigureNotify:
++            /* Find winthread for this event's window */
++            for (i = 0; i < NumWinThreads; i++) {
++               struct winthread *wt = &WinThreads[i];
++               if (event.xconfigure.window == wt->Win) {
++                  resize(wt, event.xconfigure.width,
++                         event.xconfigure.height);
++                  break;
++               }
++            }
++            break;
++         case KeyPress:
++            for (i = 0; i < NumWinThreads; i++) {
++               struct winthread *wt = &WinThreads[i];
++               if (event.xkey.window == wt->Win) {
++                  keypress(&event, wt);
++                  break;
++               }
++            }
++            break;
++         default:
++            /*no-op*/ ;
++      }
++   }
++}
++
++
++/*
++ * Separate display connection for each thread.
++ */
++static void
++event_loop_multi(void)
++{
++   XEvent event;
++   int w = 0;
++
++   assert(MultiDisplays);
++
++   while (!ExitFlag) {
++      struct winthread *wt = &WinThreads[w];
++      if (XPending(wt->Dpy)) {
++         XNextEvent(wt->Dpy, &event);
++         switch (event.type) {
++         case ConfigureNotify:
++            resize(wt, event.xconfigure.width, event.xconfigure.height);
++            break;
++         case KeyPress:
++            keypress(&event, wt);
++            break;
++         default:
++            ; /* nop */
++         }
++      }
++      w = (w + 1) % NumWinThreads;
++      usleep(5000);
++   }
++}
++
++
++
++/*
++ * we'll call this once for each thread, before the threads are created.
++ */
++static void
++create_window(struct winthread *wt, GLXContext shareCtx)
++{
++   Window win;
++   GLXContext ctx;
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++                    GLX_DEPTH_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   XVisualInfo *visinfo;
++   int width = 160, height = 160;
++   int xpos = (wt->Index % 8) * (width + 10);
++   int ypos = (wt->Index / 8) * (width + 20);
++
++   scrnum = DefaultScreen(wt->Dpy);
++   root = RootWindow(wt->Dpy, scrnum);
++
++   visinfo = glXChooseVisual(wt->Dpy, scrnum, attrib);
++   if (!visinfo) {
++      Error("Unable to find RGB, Z, double-buffered visual");
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap(wt->Dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow(wt->Dpy, root, xpos, ypos, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr);
++   if (!win) {
++      Error("Couldn't create window");
++   }
++
++   {
++      XSizeHints sizehints;
++      sizehints.x = xpos;
++      sizehints.y = ypos;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(wt->Dpy, win, &sizehints);
++      XSetStandardProperties(wt->Dpy, win, "glthreads", "glthreads",
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++
++   ctx = glXCreateContext(wt->Dpy, visinfo, shareCtx, True);
++   if (!ctx) {
++      Error("Couldn't create GLX context");
++   }
++
++   XMapWindow(wt->Dpy, win);
++   XSync(wt->Dpy, 0);
++
++   /* save the info for this window/context */
++   wt->Win = win;
++   wt->Context = ctx;
++   wt->Angle = 0.0;
++   wt->WinWidth = width;
++   wt->WinHeight = height;
++   wt->NewSize = GL_TRUE;
++}
++
++
++/*
++ * Called by pthread_create()
++ */
++static void *
++thread_function(void *p)
++{
++   struct winthread *wt = (struct winthread *) p;
++   draw_loop(wt);
++   return NULL;
++}
++
++
++/*
++ * called before exit to wait for all threads to finish
++ */
++static void
++clean_up(void)
++{
++   int i;
++
++   /* wait for threads to finish */
++   for (i = 0; i < NumWinThreads; i++) {
++      pthread_join(WinThreads[i].Thread, NULL);
++   }
++
++   for (i = 0; i < NumWinThreads; i++) {
++      glXDestroyContext(WinThreads[i].Dpy, WinThreads[i].Context);
++      XDestroyWindow(WinThreads[i].Dpy, WinThreads[i].Win);
++   }
++}
++
++
++static void
++usage(void)
++{
++   printf("glthreads: test of GL thread safety (any key = exit)\n");
++   printf("Usage:\n");
++   printf("  glthreads [options]\n");
++   printf("Options:\n");
++   printf("   -display DISPLAYNAME  Specify display string\n");
++   printf("   -n NUMTHREADS  Number of threads to create\n");
++   printf("   -p  Use a separate display connection for each thread\n");
++   printf("   -l  Use application-side locking\n");
++   printf("   -t  Enable texturing\n");
++   printf("Keyboard:\n");
++   printf("   Esc  Exit\n");
++   printf("   t    Change texture image (requires -t option)\n");
++   printf("   a    Toggle animation\n");
++   printf("   s    Step rotation (when not animating)\n");
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   char *displayName = NULL;
++   int numThreads = 2;
++   Display *dpy = NULL;
++   int i;
++   Status threadStat;
++
++   if (argc == 1) {
++      usage();
++   }
++   else {
++      int i;
++      for (i = 1; i < argc; i++) {
++         if (strcmp(argv[i], "-display") == 0 && i + 1 < argc) {
++            displayName = argv[i + 1];
++            i++;
++         }
++         else if (strcmp(argv[i], "-p") == 0) {
++            MultiDisplays = 1;
++         }
++         else if (strcmp(argv[i], "-l") == 0) {
++            Locking = 1;
++         }
++         else if (strcmp(argv[i], "-t") == 0) {
++            Texture = 1;
++         }
++         else if (strcmp(argv[i], "-n") == 0 && i + 1 < argc) {
++            numThreads = atoi(argv[i + 1]);
++            if (numThreads < 1)
++               numThreads = 1;
++            else if (numThreads > MAX_WINTHREADS)
++               numThreads = MAX_WINTHREADS;
++            i++;
++         }
++         else {
++            usage();
++            exit(1);
++         }
++      }
++   }
++   
++   if (Locking)
++      printf("glthreads: Using explicit locks around Xlib calls.\n");
++   else
++      printf("glthreads: No explict locking.\n");
++
++   if (MultiDisplays)
++      printf("glthreads: Per-thread display connections.\n");
++   else
++      printf("glthreads: Single display connection.\n");
++
++   /*
++    * VERY IMPORTANT: call XInitThreads() before any other Xlib functions.
++    */
++   if (!MultiDisplays) {
++      if (!Locking) {
++         threadStat = XInitThreads();
++      if (threadStat) {
++         printf("XInitThreads() returned %d (success)\n", (int) threadStat);
++      }
++      else {
++         printf("XInitThreads() returned 0 (failure- this program may fail)\n");
++      }
++      }
++
++      dpy = XOpenDisplay(displayName);
++      if (!dpy) {
++         fprintf(stderr, "Unable to open display %s\n", XDisplayName(displayName));
++         return -1;
++      }
++   }
++
++   pthread_mutex_init(&Mutex, NULL);
++   pthread_mutex_init(&CondMutex, NULL);
++   pthread_cond_init(&CondVar, NULL);
++
++   printf("glthreads: creating windows\n");
++
++   NumWinThreads = numThreads;
++
++   /* Create the GLX windows and contexts */
++   for (i = 0; i < numThreads; i++) {
++      GLXContext share;
++
++      if (MultiDisplays) {
++         WinThreads[i].Dpy = XOpenDisplay(displayName);
++         assert(WinThreads[i].Dpy);
++      }
++      else {
++         WinThreads[i].Dpy = dpy;
++      }
++      WinThreads[i].Index = i;
++      WinThreads[i].Initialized = GL_FALSE;
++
++      share = (Texture && i > 0) ? WinThreads[0].Context : 0;
++
++      create_window(&WinThreads[i], share);
++   }
++
++   printf("glthreads: creating threads\n");
++
++   /* Create the threads */
++   for (i = 0; i < numThreads; i++) {
++      pthread_create(&WinThreads[i].Thread, NULL, thread_function,
++                     (void*) &WinThreads[i]);
++      printf("glthreads: Created thread %p\n", (void *) WinThreads[i].Thread);
++   }
++
++   if (MultiDisplays)
++      event_loop_multi();
++   else
++      event_loop(dpy);
++
++   clean_up();
++
++   if (MultiDisplays) {
++      for (i = 0; i < numThreads; i++) {
++         XCloseDisplay(WinThreads[i].Dpy);
++      }
++   }
++   else {
++      XCloseDisplay(dpy);
++   }
++
++   return 0;
++}
++
++
++#else /* PTHREADS */
++
++
++#include <stdio.h>
++
++int
++main(int argc, char *argv[])
++{
++   printf("Sorry, this program wasn't compiled with PTHREADS defined.\n");
++   return 0;
++}
++
++
++#endif /* PTHREADS */
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxcontexts.c Mesa-7.8.1.patched/progs/xdemos/glxcontexts.c
+--- Mesa-7.8.1/progs/xdemos/glxcontexts.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxcontexts.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,548 @@
++/*
++ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++/*
++ * Version of glxgears that creates/destroys the rendering context for each
++ * frame.  Also periodically destroy/recreate the window.
++ * Good for finding memory leaks, etc.
++ *
++ * Command line options:
++ *    -info      print GL implementation information
++ *
++ */
++
++
++#include <assert.h>
++#include <math.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <X11/Xlib.h>
++#include <X11/keysym.h>
++#include <GL/gl.h>
++#include <GL/glx.h>
++
++
++#define BENCHMARK
++
++#ifdef BENCHMARK
++
++/* XXX this probably isn't very portable */
++
++#include <sys/time.h>
++#include <unistd.h>
++
++/* return current time (in seconds) */
++static double
++current_time(void)
++{
++   struct timeval tv;
++#ifdef __VMS
++   (void) gettimeofday(&tv, NULL );
++#else
++   struct timezone tz;
++   (void) gettimeofday(&tv, &tz);
++#endif
++   return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
++}
++
++#else /*BENCHMARK*/
++
++/* dummy */
++static double
++current_time(void)
++{
++   /* update this function for other platforms! */
++   static double t = 0.0;
++   static int warn = 1;
++   if (warn) {
++      fprintf(stderr, "Warning: current_time() not implemented!!\n");
++      warn = 0;
++   }
++   return t += 1.0;
++}
++
++#endif /*BENCHMARK*/
++
++
++
++#ifndef M_PI
++#define M_PI 3.14159265
++#endif
++
++
++static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
++static GLint gear1, gear2, gear3;
++static GLfloat angle = 0.0;
++
++static XVisualInfo *visinfo = NULL;
++static int WinWidth = 300, WinHeight = 300;
++
++
++/*
++ *
++ *  Draw a gear wheel.  You'll probably want to call this function when
++ *  building a display list since we do a lot of trig here.
++ * 
++ *  Input:  inner_radius - radius of hole at center
++ *          outer_radius - radius at center of teeth
++ *          width - width of gear
++ *          teeth - number of teeth
++ *          tooth_depth - depth of tooth
++ */
++static void
++gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
++     GLint teeth, GLfloat tooth_depth)
++{
++   GLint i;
++   GLfloat r0, r1, r2;
++   GLfloat angle, da;
++   GLfloat u, v, len;
++
++   r0 = inner_radius;
++   r1 = outer_radius - tooth_depth / 2.0;
++   r2 = outer_radius + tooth_depth / 2.0;
++
++   da = 2.0 * M_PI / teeth / 4.0;
++
++   glShadeModel(GL_FLAT);
++
++   glNormal3f(0.0, 0.0, 1.0);
++
++   /* draw front face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw front sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++   }
++   glEnd();
++
++   glNormal3f(0.0, 0.0, -1.0);
++
++   /* draw back face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    -width * 0.5);
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw back sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++   }
++   glEnd();
++
++   /* draw outward faces of teeth */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      u = r2 * cos(angle + da) - r1 * cos(angle);
++      v = r2 * sin(angle + da) - r1 * sin(angle);
++      len = sqrt(u * u + v * v);
++      u /= len;
++      v /= len;
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
++      v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++   }
++
++   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
++   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
++
++   glEnd();
++
++   glShadeModel(GL_SMOOTH);
++
++   /* draw inside radius cylinder */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glNormal3f(-cos(angle), -sin(angle), 0.0);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++   }
++   glEnd();
++}
++
++
++static void
++do_draw(void)
++{
++   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++   glPushMatrix();
++   glRotatef(view_rotx, 1.0, 0.0, 0.0);
++   glRotatef(view_roty, 0.0, 1.0, 0.0);
++   glRotatef(view_rotz, 0.0, 0.0, 1.0);
++
++   glPushMatrix();
++   glTranslatef(-3.0, -2.0, 0.0);
++   glRotatef(angle, 0.0, 0.0, 1.0);
++   glCallList(gear1);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(3.1, -2.0, 0.0);
++   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
++   glCallList(gear2);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(-3.1, 4.2, 0.0);
++   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
++   glCallList(gear3);
++   glPopMatrix();
++
++   glPopMatrix();
++}
++
++
++/* new window size or exposure */
++static void
++reshape(int width, int height)
++{
++   glViewport(0, 0, (GLint) width, (GLint) height);
++
++   {
++      GLfloat h = (GLfloat) height / (GLfloat) width;
++
++      glMatrixMode(GL_PROJECTION);
++      glLoadIdentity();
++      glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
++   }
++   
++   glMatrixMode(GL_MODELVIEW);
++   glLoadIdentity();
++   glTranslatef(0.0, 0.0, -40.0);
++}
++
++
++static void
++init(void)
++{
++   static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
++   static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
++   static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
++   static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
++
++   glLightfv(GL_LIGHT0, GL_POSITION, pos);
++   glEnable(GL_CULL_FACE);
++   glEnable(GL_LIGHTING);
++   glEnable(GL_LIGHT0);
++   glEnable(GL_DEPTH_TEST);
++
++   /* make the gears */
++   gear1 = glGenLists(1);
++   glNewList(gear1, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
++   gear(1.0, 4.0, 1.0, 20, 0.7);
++   glEndList();
++
++   gear2 = glGenLists(1);
++   glNewList(gear2, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
++   gear(0.5, 2.0, 2.0, 10, 0.7);
++   glEndList();
++
++   gear3 = glGenLists(1);
++   glNewList(gear3, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
++   gear(1.3, 2.0, 0.5, 10, 0.7);
++   glEndList();
++
++   glEnable(GL_NORMALIZE);
++}
++   
++
++static void
++draw( Display *dpy, Window win )
++{
++   GLXContext ctx;
++
++   ctx = glXCreateContext( dpy, visinfo, NULL, True );
++   if (!ctx) {
++      printf("Error: glXCreateContext failed\n");
++      exit(1);
++   }
++
++   glXMakeCurrent(dpy, win, ctx);
++
++   init();
++
++   reshape(WinWidth, WinHeight);
++
++   do_draw();
++
++   glDeleteLists(gear1, 1);
++   glDeleteLists(gear2, 1);
++   glDeleteLists(gear3, 1);
++
++   glXSwapBuffers(dpy, win);
++   glXDestroyContext(dpy, ctx);
++}
++
++
++/*
++ * Create an RGB, double-buffered window.
++ * Return the window and context handles.
++ */
++static void
++make_window( Display *dpy, const char *name,
++             int x, int y, int width, int height,
++             Window *winRet)
++{
++   int attribs[] = { GLX_RGBA,
++                     GLX_RED_SIZE, 1,
++                     GLX_GREEN_SIZE, 1,
++                     GLX_BLUE_SIZE, 1,
++                     GLX_DOUBLEBUFFER,
++                     GLX_DEPTH_SIZE, 1,
++                     None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   if (visinfo)
++	   XFree(visinfo);
++
++   visinfo = glXChooseVisual( dpy, scrnum, attribs );
++   if (!visinfo) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   attr.override_redirect = 0;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect;
++
++   win = XCreateWindow( dpy, root, x, y, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   *winRet = win;
++}
++
++
++static void
++event_loop(Display *dpy)
++{
++   Window win;
++   make_window(dpy, "glxgears", 0, 0, WinWidth, WinHeight, &win);
++   XMapWindow(dpy, win);
++
++   while (1) {
++      while (XPending(dpy) > 0) {
++         XEvent event;
++         XNextEvent(dpy, &event);
++         switch (event.type) {
++	 case Expose:
++            /* we'll redraw below */
++	    break;
++	 case ConfigureNotify:
++            WinWidth = event.xconfigure.width;
++            WinHeight = event.xconfigure.height;
++	    break;
++         case KeyPress:
++            {
++               char buffer[10];
++               int r, code;
++               code = XLookupKeysym(&event.xkey, 0);
++               if (code == XK_Left) {
++                  view_roty += 5.0;
++               }
++               else if (code == XK_Right) {
++                  view_roty -= 5.0;
++               }
++               else if (code == XK_Up) {
++                  view_rotx += 5.0;
++               }
++               else if (code == XK_Down) {
++                  view_rotx -= 5.0;
++               }
++               else {
++                  r = XLookupString(&event.xkey, buffer, sizeof(buffer),
++                                    NULL, NULL);
++                  if (buffer[0] == 27) {
++                     /* escape */
++                     return;
++                  }
++               }
++            }
++         }
++      }
++
++      {
++         static int frames = 0;
++         static double tRot0 = -1.0, tRate0 = -1.0;
++         double dt, t = current_time();
++         if (tRot0 < 0.0)
++            tRot0 = t;
++         dt = t - tRot0;
++         tRot0 = t;
++
++         /* advance rotation for next frame */
++         angle += 70.0 * dt;  /* 70 degrees per second */
++         if (angle > 3600.0)
++	    angle -= 3600.0;
++
++         draw( dpy, win );
++
++         frames++;
++
++         if (tRate0 < 0.0)
++            tRate0 = t;
++
++         if (t - tRate0 >= 1.0) {
++            GLfloat seconds = t - tRate0;
++            GLfloat fps = frames / seconds;
++            printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
++                   fps);
++            tRate0 = t;
++
++            /* Destroy window and create new one */	    
++	    XDestroyWindow(dpy, win);
++	    make_window(dpy, "glxgears",
++                        (int)(fps * 100) % 100, (int)(fps * 100) % 100, /* x,y */
++                        WinWidth, WinHeight, &win);
++	    XMapWindow(dpy, win);
++
++            frames = 0;
++         }
++      }
++   }
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   Display *dpy;
++   char *dpyName = NULL;
++   GLboolean printInfo = GL_FALSE;
++   int i;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0) {
++         dpyName = argv[i+1];
++         i++;
++      }
++      else if (strcmp(argv[i], "-info") == 0) {
++         printInfo = GL_TRUE;
++      }
++      else
++	 printf("Warrning: unknown parameter: %s\n", argv[i]);
++   }
++
++   dpy = XOpenDisplay(dpyName);
++   if (!dpy) {
++      fprintf(stderr, "Error: couldn't open display %s\n",
++	      XDisplayName(dpyName));
++      return -1;
++   }
++
++   if (printInfo) {
++      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
++      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
++      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
++      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
++   }
++
++   event_loop(dpy);
++
++   XCloseDisplay(dpy);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxdemo.c Mesa-7.8.1.patched/progs/xdemos/glxdemo.c
+--- Mesa-7.8.1/progs/xdemos/glxdemo.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxdemo.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,127 @@
++
++
++/*
++ * A demonstration of using the GLX functions.  This program is in the
++ * public domain.
++ *
++ * Brian Paul
++ */
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <stdio.h>
++#include <stdlib.h>
++
++
++
++static void redraw( Display *dpy, Window w )
++{
++   printf("Redraw event\n");
++
++   glClear( GL_COLOR_BUFFER_BIT );
++
++   glColor3f( 1.0, 1.0, 0.0 );
++   glRectf( -0.8, -0.8, 0.8, 0.8 );
++
++   glXSwapBuffers( dpy, w );
++}
++
++
++
++static void resize( unsigned int width, unsigned int height )
++{
++   printf("Resize event\n");
++   glViewport( 0, 0, width, height );
++   glMatrixMode( GL_PROJECTION );
++   glLoadIdentity();
++   glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
++}
++
++
++
++static Window make_rgb_db_window( Display *dpy,
++				  unsigned int width, unsigned int height )
++{
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   GLXContext ctx;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   visinfo = glXChooseVisual( dpy, scrnum, attrib );
++   if (!visinfo) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   ctx = glXCreateContext( dpy, visinfo, NULL, True );
++   if (!ctx) {
++      printf("Error: glXCreateContext failed\n");
++      exit(1);
++   }
++
++   glXMakeCurrent( dpy, win, ctx );
++
++   return win;
++}
++
++
++static void event_loop( Display *dpy )
++{
++   XEvent event;
++
++   while (1) {
++      XNextEvent( dpy, &event );
++
++      switch (event.type) {
++	 case Expose:
++	    redraw( dpy, event.xany.window );
++	    break;
++	 case ConfigureNotify:
++	    resize( event.xconfigure.width, event.xconfigure.height );
++	    break;
++      }
++   }
++}
++
++
++
++int main( int argc, char *argv[] )
++{
++   Display *dpy;
++   Window win;
++
++   dpy = XOpenDisplay(NULL);
++
++   win = make_rgb_db_window( dpy, 300, 300 );
++
++   glShadeModel( GL_FLAT );
++   glClearColor( 0.5, 0.5, 0.5, 1.0 );
++
++   XMapWindow( dpy, win );
++
++   event_loop( dpy );
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxgears.c Mesa-7.8.1.patched/progs/xdemos/glxgears.c
+--- Mesa-7.8.1/progs/xdemos/glxgears.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxgears.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,787 @@
++/*
++ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++/*
++ * This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
++ * Port by Brian Paul  23 March 2001
++ *
++ * See usage() below for command line options.
++ */
++
++
++#include <math.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <X11/Xlib.h>
++#include <X11/keysym.h>
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <GL/glxext.h>
++
++#ifndef GLX_MESA_swap_control
++#define GLX_MESA_swap_control 1
++typedef int (*PFNGLXGETSWAPINTERVALMESAPROC)(void);
++#endif
++
++
++#define BENCHMARK
++
++#ifdef BENCHMARK
++
++/* XXX this probably isn't very portable */
++
++#include <sys/time.h>
++#include <unistd.h>
++
++/* return current time (in seconds) */
++static double
++current_time(void)
++{
++   struct timeval tv;
++#ifdef __VMS
++   (void) gettimeofday(&tv, NULL );
++#else
++   struct timezone tz;
++   (void) gettimeofday(&tv, &tz);
++#endif
++   return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
++}
++
++#else /*BENCHMARK*/
++
++/* dummy */
++static double
++current_time(void)
++{
++   /* update this function for other platforms! */
++   static double t = 0.0;
++   static int warn = 1;
++   if (warn) {
++      fprintf(stderr, "Warning: current_time() not implemented!!\n");
++      warn = 0;
++   }
++   return t += 1.0;
++}
++
++#endif /*BENCHMARK*/
++
++
++
++#ifndef M_PI
++#define M_PI 3.14159265
++#endif
++
++
++/** Event handler results: */
++#define NOP 0
++#define EXIT 1
++#define DRAW 2
++
++static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
++static GLint gear1, gear2, gear3;
++static GLfloat angle = 0.0;
++
++static GLboolean fullscreen = GL_FALSE;	/* Create a single fullscreen window */
++static GLboolean stereo = GL_FALSE;	/* Enable stereo.  */
++static GLboolean animate = GL_TRUE;	/* Animation */
++static GLfloat eyesep = 5.0;		/* Eye separation. */
++static GLfloat fix_point = 40.0;	/* Fixation point distance.  */
++static GLfloat left, right, asp;	/* Stereo frustum params.  */
++
++
++/*
++ *
++ *  Draw a gear wheel.  You'll probably want to call this function when
++ *  building a display list since we do a lot of trig here.
++ * 
++ *  Input:  inner_radius - radius of hole at center
++ *          outer_radius - radius at center of teeth
++ *          width - width of gear
++ *          teeth - number of teeth
++ *          tooth_depth - depth of tooth
++ */
++static void
++gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
++     GLint teeth, GLfloat tooth_depth)
++{
++   GLint i;
++   GLfloat r0, r1, r2;
++   GLfloat angle, da;
++   GLfloat u, v, len;
++
++   r0 = inner_radius;
++   r1 = outer_radius - tooth_depth / 2.0;
++   r2 = outer_radius + tooth_depth / 2.0;
++
++   da = 2.0 * M_PI / teeth / 4.0;
++
++   glShadeModel(GL_FLAT);
++
++   glNormal3f(0.0, 0.0, 1.0);
++
++   /* draw front face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw front sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++   }
++   glEnd();
++
++   glNormal3f(0.0, 0.0, -1.0);
++
++   /* draw back face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    -width * 0.5);
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw back sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++   }
++   glEnd();
++
++   /* draw outward faces of teeth */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      u = r2 * cos(angle + da) - r1 * cos(angle);
++      v = r2 * sin(angle + da) - r1 * sin(angle);
++      len = sqrt(u * u + v * v);
++      u /= len;
++      v /= len;
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
++      v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++   }
++
++   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
++   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
++
++   glEnd();
++
++   glShadeModel(GL_SMOOTH);
++
++   /* draw inside radius cylinder */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glNormal3f(-cos(angle), -sin(angle), 0.0);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++   }
++   glEnd();
++}
++
++
++static void
++draw(void)
++{
++   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++   glPushMatrix();
++   glRotatef(view_rotx, 1.0, 0.0, 0.0);
++   glRotatef(view_roty, 0.0, 1.0, 0.0);
++   glRotatef(view_rotz, 0.0, 0.0, 1.0);
++
++   glPushMatrix();
++   glTranslatef(-3.0, -2.0, 0.0);
++   glRotatef(angle, 0.0, 0.0, 1.0);
++   glCallList(gear1);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(3.1, -2.0, 0.0);
++   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
++   glCallList(gear2);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(-3.1, 4.2, 0.0);
++   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
++   glCallList(gear3);
++   glPopMatrix();
++
++   glPopMatrix();
++}
++
++
++static void
++draw_gears(void)
++{
++   if (stereo) {
++      /* First left eye.  */
++      glDrawBuffer(GL_BACK_LEFT);
++
++      glMatrixMode(GL_PROJECTION);
++      glLoadIdentity();
++      glFrustum(left, right, -asp, asp, 5.0, 60.0);
++
++      glMatrixMode(GL_MODELVIEW);
++
++      glPushMatrix();
++      glTranslated(+0.5 * eyesep, 0.0, 0.0);
++      draw();
++      glPopMatrix();
++
++      /* Then right eye.  */
++      glDrawBuffer(GL_BACK_RIGHT);
++
++      glMatrixMode(GL_PROJECTION);
++      glLoadIdentity();
++      glFrustum(-right, -left, -asp, asp, 5.0, 60.0);
++
++      glMatrixMode(GL_MODELVIEW);
++
++      glPushMatrix();
++      glTranslated(-0.5 * eyesep, 0.0, 0.0);
++      draw();
++      glPopMatrix();
++   }
++   else {
++      draw();
++   }
++}
++
++
++/** Draw single frame, do SwapBuffers, compute FPS */
++static void
++draw_frame(Display *dpy, Window win)
++{
++   static int frames = 0;
++   static double tRot0 = -1.0, tRate0 = -1.0;
++   double dt, t = current_time();
++
++   if (tRot0 < 0.0)
++      tRot0 = t;
++   dt = t - tRot0;
++   tRot0 = t;
++
++   if (animate) {
++      /* advance rotation for next frame */
++      angle += 70.0 * dt;  /* 70 degrees per second */
++      if (angle > 3600.0)
++         angle -= 3600.0;
++   }
++
++   draw_gears();
++   glXSwapBuffers(dpy, win);
++
++   frames++;
++   
++   if (tRate0 < 0.0)
++      tRate0 = t;
++   if (t - tRate0 >= 5.0) {
++      GLfloat seconds = t - tRate0;
++      GLfloat fps = frames / seconds;
++      printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
++             fps);
++      tRate0 = t;
++      frames = 0;
++   }
++}
++
++
++/* new window size or exposure */
++static void
++reshape(int width, int height)
++{
++   glViewport(0, 0, (GLint) width, (GLint) height);
++
++   if (stereo) {
++      GLfloat w;
++
++      asp = (GLfloat) height / (GLfloat) width;
++      w = fix_point * (1.0 / 5.0);
++
++      left = -5.0 * ((w - 0.5 * eyesep) / fix_point);
++      right = 5.0 * ((w + 0.5 * eyesep) / fix_point);
++   }
++   else {
++      GLfloat h = (GLfloat) height / (GLfloat) width;
++
++      glMatrixMode(GL_PROJECTION);
++      glLoadIdentity();
++      glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
++   }
++   
++   glMatrixMode(GL_MODELVIEW);
++   glLoadIdentity();
++   glTranslatef(0.0, 0.0, -40.0);
++}
++   
++
++
++static void
++init(void)
++{
++   static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
++   static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
++   static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
++   static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
++
++   glLightfv(GL_LIGHT0, GL_POSITION, pos);
++   glEnable(GL_CULL_FACE);
++   glEnable(GL_LIGHTING);
++   glEnable(GL_LIGHT0);
++   glEnable(GL_DEPTH_TEST);
++
++   /* make the gears */
++   gear1 = glGenLists(1);
++   glNewList(gear1, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
++   gear(1.0, 4.0, 1.0, 20, 0.7);
++   glEndList();
++
++   gear2 = glGenLists(1);
++   glNewList(gear2, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
++   gear(0.5, 2.0, 2.0, 10, 0.7);
++   glEndList();
++
++   gear3 = glGenLists(1);
++   glNewList(gear3, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
++   gear(1.3, 2.0, 0.5, 10, 0.7);
++   glEndList();
++
++   glEnable(GL_NORMALIZE);
++}
++
++
++/**
++ * Remove window border/decorations.
++ */
++static void
++no_border( Display *dpy, Window w)
++{
++   static const unsigned MWM_HINTS_DECORATIONS = (1 << 1);
++   static const int PROP_MOTIF_WM_HINTS_ELEMENTS = 5;
++
++   typedef struct
++   {
++      unsigned long       flags;
++      unsigned long       functions;
++      unsigned long       decorations;
++      long                inputMode;
++      unsigned long       status;
++   } PropMotifWmHints;
++
++   PropMotifWmHints motif_hints;
++   Atom prop, proptype;
++   unsigned long flags = 0;
++
++   /* setup the property */
++   motif_hints.flags = MWM_HINTS_DECORATIONS;
++   motif_hints.decorations = flags;
++
++   /* get the atom for the property */
++   prop = XInternAtom( dpy, "_MOTIF_WM_HINTS", True );
++   if (!prop) {
++      /* something went wrong! */
++      return;
++   }
++
++   /* not sure this is correct, seems to work, XA_WM_HINTS didn't work */
++   proptype = prop;
++
++   XChangeProperty( dpy, w,                         /* display, window */
++                    prop, proptype,                 /* property, type */
++                    32,                             /* format: 32-bit datums */
++                    PropModeReplace,                /* mode */
++                    (unsigned char *) &motif_hints, /* data */
++                    PROP_MOTIF_WM_HINTS_ELEMENTS    /* nelements */
++                  );
++}
++
++
++/*
++ * Create an RGB, double-buffered window.
++ * Return the window and context handles.
++ */
++static void
++make_window( Display *dpy, const char *name,
++             int x, int y, int width, int height,
++             Window *winRet, GLXContext *ctxRet)
++{
++   int attribs[] = { GLX_RGBA,
++                     GLX_RED_SIZE, 1,
++                     GLX_GREEN_SIZE, 1,
++                     GLX_BLUE_SIZE, 1,
++                     GLX_DOUBLEBUFFER,
++                     GLX_DEPTH_SIZE, 1,
++                     None };
++   int stereoAttribs[] = { GLX_RGBA,
++                           GLX_RED_SIZE, 1,
++                           GLX_GREEN_SIZE, 1,
++                           GLX_BLUE_SIZE, 1,
++                           GLX_DOUBLEBUFFER,
++                           GLX_DEPTH_SIZE, 1,
++                           GLX_STEREO,
++                           None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   GLXContext ctx;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   if (fullscreen) {
++      x = 0; y = 0;
++      width = DisplayWidth( dpy, scrnum );
++      height = DisplayHeight( dpy, scrnum );
++   }
++
++   if (stereo)
++      visinfo = glXChooseVisual( dpy, scrnum, stereoAttribs );
++   else
++      visinfo = glXChooseVisual( dpy, scrnum, attribs );
++   if (!visinfo) {
++      if (stereo) {
++         printf("Error: couldn't get an RGB, "
++                "Double-buffered, Stereo visual\n");
++      } else
++         printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   /* XXX this is a bad way to get a borderless window! */
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, x, y, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   if (fullscreen)
++      no_border(dpy, win);
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   ctx = glXCreateContext( dpy, visinfo, NULL, True );
++   if (!ctx) {
++      printf("Error: glXCreateContext failed\n");
++      exit(1);
++   }
++
++   XFree(visinfo);
++
++   *winRet = win;
++   *ctxRet = ctx;
++}
++
++
++/**
++ * Determine whether or not a GLX extension is supported.
++ */
++static int
++is_glx_extension_supported(Display *dpy, const char *query)
++{
++   const int scrnum = DefaultScreen(dpy);
++   const char *glx_extensions = NULL;
++   const size_t len = strlen(query);
++   const char *ptr;
++
++   if (glx_extensions == NULL) {
++      glx_extensions = glXQueryExtensionsString(dpy, scrnum);
++   }
++
++   ptr = strstr(glx_extensions, query);
++   return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0')));
++}
++
++
++/**
++ * Attempt to determine whether or not the display is synched to vblank.
++ */
++static void
++query_vsync(Display *dpy, GLXDrawable drawable)
++{
++   int interval = 0;
++
++#if defined(GLX_EXT_swap_control)
++   if (is_glx_extension_supported(dpy, "GLX_EXT_swap_control")) {
++       unsigned int tmp = -1;
++       glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &tmp);
++       interval = tmp;
++   } else
++#endif
++   if (is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) {
++      PFNGLXGETSWAPINTERVALMESAPROC pglXGetSwapIntervalMESA =
++          (PFNGLXGETSWAPINTERVALMESAPROC)
++          glXGetProcAddressARB((const GLubyte *) "glXGetSwapIntervalMESA");
++
++      interval = (*pglXGetSwapIntervalMESA)();
++   } else if (is_glx_extension_supported(dpy, "GLX_SGI_swap_control")) {
++      /* The default swap interval with this extension is 1.  Assume that it
++       * is set to the default.
++       *
++       * Many Mesa-based drivers default to 0, but all of these drivers also
++       * export GLX_MESA_swap_control.  In that case, this branch will never
++       * be taken, and the correct result should be reported.
++       */
++      interval = 1;
++   }
++
++
++   if (interval > 0) {
++      printf("Running synchronized to the vertical refresh.  The framerate should be\n");
++      if (interval == 1) {
++         printf("approximately the same as the monitor refresh rate.\n");
++      } else if (interval > 1) {
++         printf("approximately 1/%d the monitor refresh rate.\n",
++                interval);
++      }
++   }
++}
++
++/**
++ * Handle one X event.
++ * \return NOP, EXIT or DRAW
++ */
++static int
++handle_event(Display *dpy, Window win, XEvent *event)
++{
++   (void) dpy;
++   (void) win;
++
++   switch (event->type) {
++   case Expose:
++      return DRAW;
++   case ConfigureNotify:
++      reshape(event->xconfigure.width, event->xconfigure.height);
++      break;
++   case KeyPress:
++      {
++         char buffer[10];
++         int r, code;
++         code = XLookupKeysym(&event->xkey, 0);
++         if (code == XK_Left) {
++            view_roty += 5.0;
++         }
++         else if (code == XK_Right) {
++            view_roty -= 5.0;
++         }
++         else if (code == XK_Up) {
++            view_rotx += 5.0;
++         }
++         else if (code == XK_Down) {
++            view_rotx -= 5.0;
++         }
++         else {
++            r = XLookupString(&event->xkey, buffer, sizeof(buffer),
++                              NULL, NULL);
++            if (buffer[0] == 27) {
++               /* escape */
++               return EXIT;
++            }
++            else if (buffer[0] == 'a' || buffer[0] == 'A') {
++               animate = !animate;
++            }
++         }
++         return DRAW;
++      }
++   }
++   return NOP;
++}
++
++
++static void
++event_loop(Display *dpy, Window win)
++{
++   while (1) {
++      int op;
++      while (!animate || XPending(dpy) > 0) {
++         XEvent event;
++         XNextEvent(dpy, &event);
++         op = handle_event(dpy, win, &event);
++         if (op == EXIT)
++            return;
++         else if (op == DRAW)
++            break;
++      }
++
++      draw_frame(dpy, win);
++   }
++}
++
++
++static void
++usage(void)
++{
++   printf("Usage:\n");
++   printf("  -display <displayname>  set the display to run on\n");
++   printf("  -stereo                 run in stereo mode\n");
++   printf("  -fullscreen             run in fullscreen mode\n");
++   printf("  -info                   display OpenGL renderer info\n");
++   printf("  -geometry WxH+X+Y       window geometry\n");
++}
++ 
++
++int
++main(int argc, char *argv[])
++{
++   unsigned int winWidth = 300, winHeight = 300;
++   int x = 0, y = 0;
++   Display *dpy;
++   Window win;
++   GLXContext ctx;
++   char *dpyName = NULL;
++   GLboolean printInfo = GL_FALSE;
++   int i;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0) {
++         dpyName = argv[i+1];
++         i++;
++      }
++      else if (strcmp(argv[i], "-info") == 0) {
++         printInfo = GL_TRUE;
++      }
++      else if (strcmp(argv[i], "-stereo") == 0) {
++         stereo = GL_TRUE;
++      }
++      else if (strcmp(argv[i], "-fullscreen") == 0) {
++         fullscreen = GL_TRUE;
++      }
++      else if (i < argc-1 && strcmp(argv[i], "-geometry") == 0) {
++         XParseGeometry(argv[i+1], &x, &y, &winWidth, &winHeight);
++         i++;
++      }
++      else {
++         usage();
++         return -1;
++      }
++   }
++
++   dpy = XOpenDisplay(dpyName);
++   if (!dpy) {
++      printf("Error: couldn't open display %s\n",
++	     dpyName ? dpyName : getenv("DISPLAY"));
++      return -1;
++   }
++
++   make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx);
++   XMapWindow(dpy, win);
++   glXMakeCurrent(dpy, win, ctx);
++   query_vsync(dpy, win);
++
++   if (printInfo) {
++      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
++      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
++      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
++      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
++   }
++
++   init();
++
++   /* Set initial projection/viewing transformation.
++    * We can't be sure we'll get a ConfigureNotify event when the window
++    * first appears.
++    */
++   reshape(winWidth, winHeight);
++
++   event_loop(dpy, win);
++
++   glDeleteLists(gear1, 1);
++   glDeleteLists(gear2, 1);
++   glDeleteLists(gear3, 1);
++   glXMakeCurrent(dpy, None, NULL);
++   glXDestroyContext(dpy, ctx);
++   XDestroyWindow(dpy, win);
++   XCloseDisplay(dpy);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxgears_fbconfig.c Mesa-7.8.1.patched/progs/xdemos/glxgears_fbconfig.c
+--- Mesa-7.8.1/progs/xdemos/glxgears_fbconfig.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxgears_fbconfig.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,632 @@
++/*
++ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++/**
++ * \file glxgears_fbconfig.c
++ * Yet-another-version of gears.  Originally ported to GLX by Brian Paul on
++ * 23 March 2001.  Modified to use fbconfigs by Ian Romanick on 10 Feb 2004.
++ *
++ * Command line options:
++ *    -info      print GL implementation information
++ *
++ * \author Brian Paul
++ * \author Ian Romanick <idr@us.ibm.com>
++ */
++
++
++#define GLX_GLXEXT_PROTOTYPES
++
++#include <math.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <X11/Xlib.h>
++#include <X11/keysym.h>
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <GL/glxext.h>
++#include <assert.h>
++#include "pbutil.h"
++
++static PFNGLXCHOOSEFBCONFIGPROC choose_fbconfig = NULL;
++static PFNGLXGETVISUALFROMFBCONFIGPROC get_visual_from_fbconfig = NULL;
++static PFNGLXCREATENEWCONTEXTPROC create_new_context = NULL;
++static PFNGLXCREATEWINDOWPROC create_window = NULL;
++static PFNGLXDESTROYWINDOWPROC destroy_window = NULL;
++
++#define BENCHMARK
++
++#ifdef BENCHMARK
++
++/* XXX this probably isn't very portable */
++
++#include <sys/time.h>
++#include <unistd.h>
++
++/* return current time (in seconds) */
++static int
++current_time(void)
++{
++   struct timeval tv;
++#ifdef __VMS
++   (void) gettimeofday(&tv, NULL );
++#else
++   struct timezone tz;
++   (void) gettimeofday(&tv, &tz);
++#endif
++   return (int) tv.tv_sec;
++}
++
++#else /*BENCHMARK*/
++
++/* dummy */
++static int
++current_time(void)
++{
++   return 0;
++}
++
++#endif /*BENCHMARK*/
++
++
++
++#ifndef M_PI
++#define M_PI 3.14159265
++#endif
++
++
++static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
++static GLint gear1, gear2, gear3;
++static GLfloat angle = 0.0;
++
++
++/*
++ *
++ *  Draw a gear wheel.  You'll probably want to call this function when
++ *  building a display list since we do a lot of trig here.
++ * 
++ *  Input:  inner_radius - radius of hole at center
++ *          outer_radius - radius at center of teeth
++ *          width - width of gear
++ *          teeth - number of teeth
++ *          tooth_depth - depth of tooth
++ */
++static void
++gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
++     GLint teeth, GLfloat tooth_depth)
++{
++   GLint i;
++   GLfloat r0, r1, r2;
++   GLfloat angle, da;
++   GLfloat u, v, len;
++
++   r0 = inner_radius;
++   r1 = outer_radius - tooth_depth / 2.0;
++   r2 = outer_radius + tooth_depth / 2.0;
++
++   da = 2.0 * M_PI / teeth / 4.0;
++
++   glShadeModel(GL_FLAT);
++
++   glNormal3f(0.0, 0.0, 1.0);
++
++   /* draw front face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw front sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++   }
++   glEnd();
++
++   glNormal3f(0.0, 0.0, -1.0);
++
++   /* draw back face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    -width * 0.5);
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw back sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++   }
++   glEnd();
++
++   /* draw outward faces of teeth */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      u = r2 * cos(angle + da) - r1 * cos(angle);
++      v = r2 * sin(angle + da) - r1 * sin(angle);
++      len = sqrt(u * u + v * v);
++      u /= len;
++      v /= len;
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
++      v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++   }
++
++   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
++   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
++
++   glEnd();
++
++   glShadeModel(GL_SMOOTH);
++
++   /* draw inside radius cylinder */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glNormal3f(-cos(angle), -sin(angle), 0.0);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++   }
++   glEnd();
++}
++
++
++static void
++draw(void)
++{
++   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++   glPushMatrix();
++   glRotatef(view_rotx, 1.0, 0.0, 0.0);
++   glRotatef(view_roty, 0.0, 1.0, 0.0);
++   glRotatef(view_rotz, 0.0, 0.0, 1.0);
++
++   glPushMatrix();
++   glTranslatef(-3.0, -2.0, 0.0);
++   glRotatef(angle, 0.0, 0.0, 1.0);
++   glCallList(gear1);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(3.1, -2.0, 0.0);
++   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
++   glCallList(gear2);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(-3.1, 4.2, 0.0);
++   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
++   glCallList(gear3);
++   glPopMatrix();
++
++   glPopMatrix();
++}
++
++
++/* new window size or exposure */
++static void
++reshape(int width, int height)
++{
++   GLfloat h = (GLfloat) height / (GLfloat) width;
++
++   glViewport(0, 0, (GLint) width, (GLint) height);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
++   glMatrixMode(GL_MODELVIEW);
++   glLoadIdentity();
++   glTranslatef(0.0, 0.0, -40.0);
++}
++
++
++static void
++init(void)
++{
++   static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
++   static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
++   static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
++   static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
++
++   glLightfv(GL_LIGHT0, GL_POSITION, pos);
++   glEnable(GL_CULL_FACE);
++   glEnable(GL_LIGHTING);
++   glEnable(GL_LIGHT0);
++   glEnable(GL_DEPTH_TEST);
++
++   /* make the gears */
++   gear1 = glGenLists(1);
++   glNewList(gear1, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
++   gear(1.0, 4.0, 1.0, 20, 0.7);
++   glEndList();
++
++   gear2 = glGenLists(1);
++   glNewList(gear2, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
++   gear(0.5, 2.0, 2.0, 10, 0.7);
++   glEndList();
++
++   gear3 = glGenLists(1);
++   glNewList(gear3, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
++   gear(1.3, 2.0, 0.5, 10, 0.7);
++   glEndList();
++
++   glEnable(GL_NORMALIZE);
++}
++
++
++static GLXWindow
++dummy_create_window(Display *dpy, GLXFBConfig config, Window win,
++                   const int *attrib_list)
++{
++   (void) dpy;
++   (void) config;
++   (void) attrib_list;
++
++   return (GLXWindow) win;
++}
++
++
++static void
++dummy_destroy_window(Display *dpy, GLXWindow win)
++{
++   (void) dpy;
++   (void) win;
++}
++
++
++/**
++ * Initialize fbconfig related function pointers.
++ */
++static void
++init_fbconfig_functions(Display *dpy, int scrnum)
++{
++   const char * glx_extensions;
++   const char * match;
++   static const char ext_name[] = "GLX_SGIX_fbconfig";
++   const size_t len = strlen( ext_name );
++   int major;
++   int minor;
++   GLboolean ext_version_supported;
++   GLboolean glx_1_3_supported;
++
++
++   /* Determine if GLX 1.3 or greater is supported.
++    */
++   glXQueryVersion(dpy, & major, & minor);
++   glx_1_3_supported = (major == 1) && (minor >= 3);
++
++   /* Determine if GLX_SGIX_fbconfig is supported.
++    */
++   glx_extensions = glXQueryExtensionsString(dpy, scrnum);
++   match = strstr( glx_extensions, ext_name );
++
++   ext_version_supported = (match != NULL)
++       && ((match[len] == '\0') || (match[len] == ' '));
++
++   printf( "GLX 1.3 is %ssupported.\n",
++	   (glx_1_3_supported) ? "" : "not " );
++   printf( "%s is %ssupported.\n",
++	   ext_name, (ext_version_supported) ? "" : "not " );
++
++   if ( glx_1_3_supported ) {
++      choose_fbconfig = (PFNGLXCHOOSEFBCONFIGPROC)
++	 glXGetProcAddressARB((GLubyte *) "glXChooseFBConfig");
++      get_visual_from_fbconfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
++	 glXGetProcAddressARB((GLubyte *) "glXGetVisualFromFBConfig");
++      create_new_context = (PFNGLXCREATENEWCONTEXTPROC)
++	 glXGetProcAddressARB((GLubyte *) "glXCreateNewContext");
++      create_window = (PFNGLXCREATEWINDOWPROC)
++	 glXGetProcAddressARB((GLubyte *) "glXCreateWindow");
++      destroy_window = (PFNGLXDESTROYWINDOWPROC)
++	 glXGetProcAddressARB((GLubyte *) "glXDestroyWindow");
++   }
++   else if ( ext_version_supported ) {
++      choose_fbconfig = (PFNGLXCHOOSEFBCONFIGPROC)
++	 glXGetProcAddressARB((GLubyte *) "glXChooseFBConfigSGIX");
++      get_visual_from_fbconfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
++	 glXGetProcAddressARB((GLubyte *) "glXGetVisualFromFBConfigSGIX");
++      create_new_context = (PFNGLXCREATENEWCONTEXTPROC)
++	 glXGetProcAddressARB((GLubyte *) "glXCreateContextWithConfigSGIX");
++      create_window = dummy_create_window;
++      destroy_window = dummy_destroy_window;
++   }
++   else {
++      printf( "This demo requires either GLX 1.3 or %s be supported.\n",
++	      ext_name );
++      exit(1);
++   }
++
++   if ( choose_fbconfig == NULL ) {
++      printf( "glXChooseFBConfig not found!\n" );
++      exit(1);
++   }
++
++   if ( get_visual_from_fbconfig == NULL ) {
++      printf( "glXGetVisualFromFBConfig not found!\n" );
++      exit(1);
++   }
++
++   if ( create_new_context == NULL ) {
++      printf( "glXCreateNewContext not found!\n" );
++      exit(1);
++   }
++}
++
++
++/*
++ * Create an RGB, double-buffered window.
++ * Return the window and context handles.
++ */
++static void
++make_window( Display *dpy, const char *name,
++             int x, int y, int width, int height,
++             Window *winRet, GLXWindow *glxWinRet, GLXContext *ctxRet)
++{
++   int attrib[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
++		    GLX_RENDER_TYPE,   GLX_RGBA_BIT,
++		    GLX_RED_SIZE,      1,
++		    GLX_GREEN_SIZE,    1,
++		    GLX_BLUE_SIZE,     1,
++		    GLX_DOUBLEBUFFER,  GL_TRUE,
++		    GLX_DEPTH_SIZE,    1,
++		    None };
++   GLXFBConfig * fbconfig;
++   int num_configs;
++   int scrnum;
++   int i;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   GLXWindow glxWin;
++   GLXContext ctx;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   init_fbconfig_functions(dpy, scrnum);
++   fbconfig = (*choose_fbconfig)(dpy, scrnum, attrib, & num_configs);
++   if (fbconfig == NULL) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   printf("\nThe following fbconfigs meet the requirements.  The first one "
++	  "will be used.\n\n");
++   for ( i = 0 ; i < num_configs ; i++ ) {
++      PrintFBConfigInfo(dpy, scrnum, fbconfig[i], GL_TRUE);
++   }
++
++   /* window attributes */
++   visinfo = (*get_visual_from_fbconfig)(dpy, fbconfig[0]);
++   assert(visinfo != NULL);
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   glxWin = (*create_window)(dpy, fbconfig[0], win, NULL);
++
++   ctx = (*create_new_context)(dpy, fbconfig[0], GLX_RGBA_TYPE, NULL, GL_TRUE);
++   if (!ctx) {
++      printf("Error: glXCreateNewContext failed\n");
++      exit(1);
++   }
++
++   XFree(fbconfig);
++
++   *glxWinRet = glxWin;
++   *winRet = win;
++   *ctxRet = ctx;
++}
++
++
++static void
++event_loop(Display *dpy, GLXWindow win)
++{
++   while (1) {
++      while (XPending(dpy) > 0) {
++         XEvent event;
++         XNextEvent(dpy, &event);
++         switch (event.type) {
++	 case Expose:
++            /* we'll redraw below */
++	    break;
++	 case ConfigureNotify:
++	    reshape(event.xconfigure.width, event.xconfigure.height);
++	    break;
++         case KeyPress:
++            {
++               char buffer[10];
++               int r, code;
++               code = XLookupKeysym(&event.xkey, 0);
++               if (code == XK_Left) {
++                  view_roty += 5.0;
++               }
++               else if (code == XK_Right) {
++                  view_roty -= 5.0;
++               }
++               else if (code == XK_Up) {
++                  view_rotx += 5.0;
++               }
++               else if (code == XK_Down) {
++                  view_rotx -= 5.0;
++               }
++               else {
++                  r = XLookupString(&event.xkey, buffer, sizeof(buffer),
++                                    NULL, NULL);
++                  if (buffer[0] == 27) {
++                     /* escape */
++                     return;
++                  }
++               }
++            }
++         }
++      }
++
++      /* next frame */
++      angle += 2.0;
++
++      draw();
++      glXSwapBuffers(dpy, win);
++
++      /* calc framerate */
++      {
++         static int t0 = -1;
++         static int frames = 0;
++         int t = current_time();
++
++         if (t0 < 0)
++            t0 = t;
++
++         frames++;
++
++         if (t - t0 >= 5.0) {
++            GLfloat seconds = t - t0;
++            GLfloat fps = frames / seconds;
++            printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
++                   fps);
++            t0 = t;
++            frames = 0;
++         }
++      }
++   }
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   Display *dpy;
++   Window win;
++   GLXWindow glxWin;
++   GLXContext ctx;
++   const char *dpyName = NULL;
++   GLboolean printInfo = GL_FALSE;
++   int i;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0) {
++         dpyName = argv[i+1];
++         i++;
++      }
++      else if (strcmp(argv[i], "-info") == 0) {
++         printInfo = GL_TRUE;
++      }
++   }
++
++   dpy = XOpenDisplay(dpyName);
++   if (!dpy) {
++      printf("Error: couldn't open display %s\n", XDisplayName(dpyName));
++      return -1;
++   }
++
++   make_window(dpy, "glxgears", 0, 0, 300, 300, &win, &glxWin, &ctx);
++   XMapWindow(dpy, win);
++   glXMakeCurrent(dpy, glxWin, ctx);
++
++   if (printInfo) {
++      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
++      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
++      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
++      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
++   }
++
++   init();
++
++   event_loop(dpy, glxWin);
++
++   glXDestroyContext(dpy, ctx);
++   destroy_window(dpy, glxWin);
++   XDestroyWindow(dpy, win);
++   XCloseDisplay(dpy);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxgears_pixmap.c Mesa-7.8.1.patched/progs/xdemos/glxgears_pixmap.c
+--- Mesa-7.8.1/progs/xdemos/glxgears_pixmap.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxgears_pixmap.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,547 @@
++/*
++ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
++ * Copyright (C) 2008  Red Hat, Inc   All Rights Reserved.
++ *
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++/**
++ * \file glxgears_pixmap.c
++ * Yet-another-version of gears.  Originally ported to GLX by Brian Paul on
++ * 23 March 2001.  Modified to use fbconfigs by Ian Romanick on 10 Feb 2004.
++ *
++ * Command line options:
++ *    -info      print GL implementation information
++ *
++ * \author Brian Paul
++ * \author Ian Romanick <idr@us.ibm.com>
++ * \author Kristian Hoegsberg <krh@redhat.com>
++ */
++
++
++#define GLX_GLXEXT_PROTOTYPES
++
++#include <math.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <X11/Xlib.h>
++#include <X11/keysym.h>
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <GL/glxext.h>
++#include <assert.h>
++#include "pbutil.h"
++
++#define BENCHMARK
++
++#ifdef BENCHMARK
++
++/* XXX this probably isn't very portable */
++
++#include <sys/time.h>
++#include <unistd.h>
++
++/* return current time (in seconds) */
++static int
++current_time(void)
++{
++   struct timeval tv;
++#ifdef __VMS
++   (void) gettimeofday(&tv, NULL );
++#else
++   struct timezone tz;
++   (void) gettimeofday(&tv, &tz);
++#endif
++   return (int) tv.tv_sec;
++}
++
++#else /*BENCHMARK*/
++
++/* dummy */
++static int
++current_time(void)
++{
++   return 0;
++}
++
++#endif /*BENCHMARK*/
++
++
++
++#ifndef M_PI
++#define M_PI 3.14159265
++#endif
++
++
++static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
++static GLint gear1, gear2, gear3;
++static GLfloat angle = 0.0;
++
++
++/*
++ *
++ *  Draw a gear wheel.  You'll probably want to call this function when
++ *  building a display list since we do a lot of trig here.
++ * 
++ *  Input:  inner_radius - radius of hole at center
++ *          outer_radius - radius at center of teeth
++ *          width - width of gear
++ *          teeth - number of teeth
++ *          tooth_depth - depth of tooth
++ */
++static void
++gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
++     GLint teeth, GLfloat tooth_depth)
++{
++   GLint i;
++   GLfloat r0, r1, r2;
++   GLfloat angle, da;
++   GLfloat u, v, len;
++
++   r0 = inner_radius;
++   r1 = outer_radius - tooth_depth / 2.0;
++   r2 = outer_radius + tooth_depth / 2.0;
++
++   da = 2.0 * M_PI / teeth / 4.0;
++
++   glShadeModel(GL_FLAT);
++
++   glNormal3f(0.0, 0.0, 1.0);
++
++   /* draw front face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw front sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++   }
++   glEnd();
++
++   glNormal3f(0.0, 0.0, -1.0);
++
++   /* draw back face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    -width * 0.5);
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw back sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++   }
++   glEnd();
++
++   /* draw outward faces of teeth */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      u = r2 * cos(angle + da) - r1 * cos(angle);
++      v = r2 * sin(angle + da) - r1 * sin(angle);
++      len = sqrt(u * u + v * v);
++      u /= len;
++      v /= len;
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
++      v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++   }
++
++   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
++   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
++
++   glEnd();
++
++   glShadeModel(GL_SMOOTH);
++
++   /* draw inside radius cylinder */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glNormal3f(-cos(angle), -sin(angle), 0.0);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++   }
++   glEnd();
++}
++
++
++static void
++draw(void)
++{
++   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++   glPushMatrix();
++   glRotatef(view_rotx, 1.0, 0.0, 0.0);
++   glRotatef(view_roty, 0.0, 1.0, 0.0);
++   glRotatef(view_rotz, 0.0, 0.0, 1.0);
++
++   glPushMatrix();
++   glTranslatef(-3.0, -2.0, 0.0);
++   glRotatef(angle, 0.0, 0.0, 1.0);
++   glCallList(gear1);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(3.1, -2.0, 0.0);
++   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
++   glCallList(gear2);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(-3.1, 4.2, 0.0);
++   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
++   glCallList(gear3);
++   glPopMatrix();
++
++   glPopMatrix();
++}
++
++
++struct gears {
++   Window win;
++   GLXContext ctx;
++   Pixmap pixmap;
++   GLXPixmap glxpixmap;
++   GC gc;
++   int width, height;
++};
++
++
++/* new window size or exposure */
++static void
++reshape(struct gears *gears, int width, int height)
++{
++   gears->width = width;
++   gears->height = height;
++}
++
++
++static void
++init(int width, int height)
++{
++   static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
++   static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
++   static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
++   static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
++   GLfloat h = (GLfloat) height / (GLfloat) width;
++
++   glLightfv(GL_LIGHT0, GL_POSITION, pos);
++   glEnable(GL_CULL_FACE);
++   glEnable(GL_LIGHTING);
++   glEnable(GL_LIGHT0);
++   glEnable(GL_DEPTH_TEST);
++
++   /* make the gears */
++   gear1 = glGenLists(1);
++   glNewList(gear1, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
++   gear(1.0, 4.0, 1.0, 20, 0.7);
++   glEndList();
++
++   gear2 = glGenLists(1);
++   glNewList(gear2, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
++   gear(0.5, 2.0, 2.0, 10, 0.7);
++   glEndList();
++
++   gear3 = glGenLists(1);
++   glNewList(gear3, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
++   gear(1.3, 2.0, 0.5, 10, 0.7);
++   glEndList();
++
++   glEnable(GL_NORMALIZE);
++
++   glViewport(0, 0, (GLint) width, (GLint) height);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
++   glMatrixMode(GL_MODELVIEW);
++   glLoadIdentity();
++   glTranslatef(0.0, 0.0, -40.0);
++}
++
++/*
++ * Create an RGB, double-buffered window.
++ * Return the window and context handles.
++ */
++static void
++make_window( Display *dpy, const char *name,
++             int x, int y, int width, int height, struct gears *gears)
++{
++   int attrib[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
++		    GLX_RENDER_TYPE,   GLX_RGBA_BIT,
++		    GLX_RED_SIZE,      1,
++		    GLX_GREEN_SIZE,    1,
++		    GLX_BLUE_SIZE,     1,
++		    GLX_DOUBLEBUFFER,  GL_FALSE,
++		    GLX_DEPTH_SIZE,    1,
++		    None };
++   GLXFBConfig * fbconfig;
++   int num_configs;
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   XVisualInfo *visinfo;
++
++   gears->width = width;
++   gears->height = height;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   fbconfig = glXChooseFBConfig(dpy, scrnum, attrib, & num_configs);
++   if (fbconfig == NULL) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   /* window attributes */
++   visinfo = glXGetVisualFromFBConfig(dpy, fbconfig[0]);
++   assert(visinfo != NULL);
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   gears->win = XCreateWindow( dpy, root, 0, 0, width, height,
++			       0, visinfo->depth, InputOutput,
++			       visinfo->visual, mask, &attr );
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, gears->win, &sizehints);
++      XSetStandardProperties(dpy, gears->win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   gears->gc = XCreateGC(dpy, gears->win, 0, NULL);
++
++   gears->pixmap = XCreatePixmap(dpy, gears->win,
++				 width, height, visinfo->depth);
++   if (!gears->pixmap) {
++      printf("Error: XCreatePixmap failed\n");
++      exit(-1);
++   }
++
++   gears->glxpixmap = glXCreatePixmap(dpy, fbconfig[0], gears->pixmap, NULL);
++   if (!gears->glxpixmap) {
++      printf("Error: glXCreatePixmap failed\n");
++      exit(-1);
++   }
++
++   gears->ctx = glXCreateNewContext(dpy, fbconfig[0],
++				    GLX_RGBA_TYPE, NULL, GL_TRUE);
++   if (!gears->ctx) {
++      printf("Error: glXCreateNewContext failed\n");
++      exit(1);
++   }
++
++   XFree(fbconfig);
++}
++
++
++static void
++event_loop(Display *dpy, struct gears *gears)
++{
++   int x, y;
++
++   while (1) {
++      while (XPending(dpy) > 0) {
++         XEvent event;
++         XNextEvent(dpy, &event);
++         switch (event.type) {
++	 case Expose:
++            /* we'll redraw below */
++	    break;
++	 case ConfigureNotify:
++	    reshape(gears, event.xconfigure.width, event.xconfigure.height);
++	    break;
++         case KeyPress:
++            {
++               char buffer[10];
++               int r, code;
++               code = XLookupKeysym(&event.xkey, 0);
++               if (code == XK_Left) {
++                  view_roty += 5.0;
++               }
++               else if (code == XK_Right) {
++                  view_roty -= 5.0;
++               }
++               else if (code == XK_Up) {
++                  view_rotx += 5.0;
++               }
++               else if (code == XK_Down) {
++                  view_rotx -= 5.0;
++               }
++               else {
++                  r = XLookupString(&event.xkey, buffer, sizeof(buffer),
++                                    NULL, NULL);
++                  if (buffer[0] == 27) {
++                     /* escape */
++                     return;
++                  }
++               }
++            }
++         }
++      }
++
++      /* next frame */
++      angle += 2.0;
++
++      draw();
++      glFinish();
++
++      for (x = 0; x < gears->width; x += 100)
++         for (y = 0; y < gears->width; y += 100)
++            XCopyArea(dpy, gears->pixmap, gears->win, gears->gc,
++		      50, 50, 100, 100, x, y);
++
++      /* calc framerate */
++      {
++         static int t0 = -1;
++         static int frames = 0;
++         int t = current_time();
++
++         if (t0 < 0)
++            t0 = t;
++
++         frames++;
++
++         if (t - t0 >= 5.0) {
++            GLfloat seconds = t - t0;
++            GLfloat fps = frames / seconds;
++            printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
++                   fps);
++            t0 = t;
++            frames = 0;
++         }
++      }
++   }
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   Display *dpy;
++   const char *dpyName = NULL;
++   GLboolean printInfo = GL_FALSE;
++   struct gears gears;
++   int i, width = 200, height = 200;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0) {
++         dpyName = argv[i+1];
++         i++;
++      }
++      else if (strcmp(argv[i], "-info") == 0) {
++         printInfo = GL_TRUE;
++      }
++   }
++
++   dpy = XOpenDisplay(dpyName);
++   if (!dpy) {
++      printf("Error: couldn't open display %s\n", XDisplayName(dpyName));
++      return -1;
++   }
++
++   make_window(dpy, "glxgears", 0, 0, width, height, &gears);
++   XMapWindow(dpy, gears.win);
++   glXMakeCurrent(dpy, gears.glxpixmap, gears.ctx);
++
++   if (printInfo) {
++      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
++      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
++      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
++      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
++   }
++
++   init(width, height);
++
++   event_loop(dpy, &gears);
++
++   glXDestroyContext(dpy, gears.ctx);
++   XDestroyWindow(dpy, gears.win);
++   glXDestroyPixmap(dpy, gears.pixmap);
++   XFreePixmap(dpy, gears.pixmap);
++   XCloseDisplay(dpy);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxheads.c Mesa-7.8.1.patched/progs/xdemos/glxheads.c
+--- Mesa-7.8.1/progs/xdemos/glxheads.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxheads.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,313 @@
++
++/*
++ * Exercise multiple GLX connections on multiple X displays.
++ * Direct GLX contexts are attempted first, then indirect.
++ * Each window will display a spinning green triangle.
++ *
++ * Copyright (C) 2000  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++
++
++/*
++ * Each display/window/context:
++ */
++struct head {
++   char DisplayName[1000];
++   Display *Dpy;
++   Window Win;
++   GLXContext Context;
++   float Angle;
++   char Renderer[1000];
++   char Vendor[1000];
++   char Version[1000];
++};
++
++
++#define MAX_HEADS 20
++static struct head Heads[MAX_HEADS];
++static int NumHeads = 0;
++
++
++static void
++Error(const char *display, const char *msg)
++{
++   fprintf(stderr, "Error on display %s - %s\n", XDisplayName(display), msg);
++   exit(1);
++}
++
++
++static struct head *
++AddHead(const char *displayName)
++{
++   Display *dpy;
++   Window win;
++   GLXContext ctx;
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   XVisualInfo *visinfo;
++   int width = 300, height = 300;
++   int xpos = 10, ypos = 10;
++
++   if (NumHeads >= MAX_HEADS)
++      return NULL;
++
++   dpy = XOpenDisplay(displayName);
++   if (!dpy) {
++      Error(displayName, "Unable to open display");
++      return NULL;
++   }
++
++   scrnum = DefaultScreen(dpy);
++   root = RootWindow(dpy, scrnum);
++
++   visinfo = glXChooseVisual(dpy, scrnum, attrib);
++   if (!visinfo) {
++      Error(displayName, "Unable to find RGB, double-buffered visual");
++      return NULL;
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow(dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr);
++   if (!win) {
++      Error(displayName, "Couldn't create window");
++      return NULL;
++   }
++
++   {
++      XSizeHints sizehints;
++      sizehints.x = xpos;
++      sizehints.y = ypos;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, displayName, displayName,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++
++   ctx = glXCreateContext(dpy, visinfo, NULL, True);
++   if (!ctx) {
++      Error(displayName, "Couldn't create GLX context");
++      return NULL;
++   }
++
++   XMapWindow(dpy, win);
++
++   if (!glXMakeCurrent(dpy, win, ctx)) {
++      Error(displayName, "glXMakeCurrent failed");
++      printf("glXMakeCurrent failed in Redraw()\n");
++      return NULL;
++   }
++
++   /* save the info for this head */
++   {
++      struct head *h = &Heads[NumHeads];
++      const char * tmp;
++
++      if (strlen(displayName) + 1 > sizeof(h->DisplayName)) {
++         Error(displayName, "displayName string length overflow");
++         return NULL;
++      }
++      strcpy(h->DisplayName, displayName);
++
++      h->Dpy = dpy;
++      h->Win = win;
++      h->Context = ctx;
++      h->Angle = 0.0;
++
++      tmp = (char *) glGetString(GL_VERSION);
++      if (strlen(tmp) + 1 > sizeof(h->Version)) {
++         Error(displayName, "GL_VERSION string length overflow");
++         return NULL;
++      }
++      strcpy(h->Version, tmp);
++
++      tmp = (char *) glGetString(GL_VENDOR);
++      if (strlen(tmp) + 1 > sizeof(h->Vendor)) {
++         Error(displayName, "GL_VENDOR string length overflow");
++         return NULL;
++      }
++      strcpy(h->Vendor, tmp);
++
++      tmp = (char *) glGetString(GL_RENDERER);
++      if (strlen(tmp) + 1 > sizeof(h->Renderer)) {
++         Error(displayName, "GL_RENDERER string length overflow");
++         return NULL;
++      }
++      strcpy(h->Renderer, tmp);
++
++      NumHeads++;
++      return &Heads[NumHeads-1];
++   }
++
++}
++
++
++static void
++Redraw(struct head *h)
++{
++   if (!glXMakeCurrent(h->Dpy, h->Win, h->Context)) {
++      Error(h->DisplayName, "glXMakeCurrent failed");
++      printf("glXMakeCurrent failed in Redraw()\n");
++      return;
++   }
++
++   h->Angle += 1.0;
++
++   glShadeModel(GL_FLAT);
++   glClearColor(0.5, 0.5, 0.5, 1.0);
++   glClear(GL_COLOR_BUFFER_BIT);
++
++   /* draw green triangle */
++   glColor3f(0.0, 1.0, 0.0);
++   glPushMatrix();
++   glRotatef(h->Angle, 0, 0, 1);
++   glBegin(GL_TRIANGLES);
++   glVertex2f(0, 0.8);
++   glVertex2f(-0.8, -0.7);
++   glVertex2f(0.8, -0.7);
++   glEnd();
++   glPopMatrix();
++
++   glXSwapBuffers(h->Dpy, h->Win);
++}
++
++
++
++static void
++Resize(const struct head *h, unsigned int width, unsigned int height)
++{
++   if (!glXMakeCurrent(h->Dpy, h->Win, h->Context)) {
++      Error(h->DisplayName, "glXMakeCurrent failed in Resize()");
++      return;
++   }
++   glFlush();
++   glViewport(0, 0, width, height);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
++}
++
++
++
++static void
++EventLoop(void)
++{
++   while (1) {
++      int i;
++      for (i = 0; i < NumHeads; i++) {
++         struct head *h = &Heads[i];
++         while (XPending(h->Dpy) > 0) {
++            XEvent event;
++            XNextEvent(h->Dpy, &event);
++            if (event.xany.window == h->Win) {
++               switch (event.type) {
++                  case Expose:
++                     Redraw(h);
++                     break;
++                  case ConfigureNotify:
++                     Resize(h, event.xconfigure.width, event.xconfigure.height);
++                     break;
++                  case KeyPress:
++                     return;
++                  default:
++                     /*no-op*/ ;
++               }
++            }
++            else {
++               printf("window mismatch\n");
++            }
++         }
++         Redraw(h);
++      }
++      usleep(1);
++   }
++}
++
++
++
++static void
++PrintInfo(const struct head *h)
++{
++   printf("Name: %s\n", h->DisplayName);
++   printf("  Display:     %p\n", (void *) h->Dpy);
++   printf("  Window:      0x%x\n", (int) h->Win);
++   printf("  Context:     0x%lx\n", (long) h->Context);
++   printf("  GL_VERSION:  %s\n", h->Version);
++   printf("  GL_VENDOR:   %s\n", h->Vendor);
++   printf("  GL_RENDERER: %s\n", h->Renderer);
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   int i;
++   if (argc == 1) {
++      struct head *h;
++      printf("glxheads: exercise multiple GLX connections (any key = exit)\n");
++      printf("Usage:\n");
++      printf("  glxheads xdisplayname ...\n");
++      printf("Example:\n");
++      printf("  glxheads :0 mars:0 venus:1\n");
++
++      h = AddHead(XDisplayName(NULL));
++      if (h)
++         PrintInfo(h);
++   }
++   else {
++      for (i = 1; i < argc; i++) {
++         const char *name = argv[i];
++         struct head *h = AddHead(name);
++         if (h) {
++            PrintInfo(h);
++         }
++      }
++   }
++
++   EventLoop();
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxinfo.c Mesa-7.8.1.patched/progs/xdemos/glxinfo.c
+--- Mesa-7.8.1/progs/xdemos/glxinfo.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxinfo.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,1195 @@
++/*
++ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++/*
++ * This program is a work-alike of the IRIX glxinfo program.
++ * Command line options:
++ *  -t                     print wide table
++ *  -v                     print verbose information
++ *  -display DisplayName   specify the X display to interogate
++ *  -b                     only print ID of "best" visual on screen 0
++ *  -i                     use indirect rendering connection only
++ *  -l                     print interesting OpenGL limits (added 5 Sep 2002)
++ *
++ * Brian Paul  26 January 2000
++ */
++
++#define GLX_GLXEXT_PROTOTYPES
++
++#include <X11/Xlib.h>
++#include <X11/Xutil.h>
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++
++
++#ifndef GLX_NONE_EXT
++#define GLX_NONE_EXT  0x8000
++#endif
++
++#ifndef GLX_TRANSPARENT_RGB
++#define GLX_TRANSPARENT_RGB 0x8008
++#endif
++
++#ifndef GLX_RGBA_BIT
++#define GLX_RGBA_BIT			0x00000001
++#endif
++
++#ifndef GLX_COLOR_INDEX_BIT
++#define GLX_COLOR_INDEX_BIT		0x00000002
++#endif
++
++typedef enum
++{
++   Normal,
++   Wide,
++   Verbose
++} InfoMode;
++
++
++struct visual_attribs
++{
++   /* X visual attribs */
++   int id;
++   int klass;
++   int depth;
++   int redMask, greenMask, blueMask;
++   int colormapSize;
++   int bitsPerRGB;
++
++   /* GL visual attribs */
++   int supportsGL;
++   int transparentType;
++   int transparentRedValue;
++   int transparentGreenValue;
++   int transparentBlueValue;
++   int transparentAlphaValue;
++   int transparentIndexValue;
++   int bufferSize;
++   int level;
++   int render_type;
++   int doubleBuffer;
++   int stereo;
++   int auxBuffers;
++   int redSize, greenSize, blueSize, alphaSize;
++   int depthSize;
++   int stencilSize;
++   int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize;
++   int numSamples, numMultisample;
++   int visualCaveat;
++};
++
++   
++/*
++ * Print a list of extensions, with word-wrapping.
++ */
++static void
++print_extension_list(const char *ext)
++{
++   const char *indentString = "    ";
++   const int indent = 4;
++   const int max = 79;
++   int width, i, j;
++
++   if (!ext || !ext[0])
++      return;
++
++   width = indent;
++   printf("%s", indentString);
++   i = j = 0;
++   while (1) {
++      if (ext[j] == ' ' || ext[j] == 0) {
++         /* found end of an extension name */
++         const int len = j - i;
++         if (width + len > max) {
++            /* start a new line */
++            printf("\n");
++            width = indent;
++            printf("%s", indentString);
++         }
++         /* print the extension name between ext[i] and ext[j] */
++         while (i < j) {
++            printf("%c", ext[i]);
++            i++;
++         }
++         /* either we're all done, or we'll continue with next extension */
++         width += len + 1;
++         if (ext[j] == 0) {
++            break;
++         }
++         else {
++            i++;
++            j++;
++            if (ext[j] == 0)
++               break;
++            printf(", ");
++            width += 2;
++         }
++      }
++      j++;
++   }
++   printf("\n");
++}
++
++
++static void
++print_display_info(Display *dpy)
++{
++   printf("name of display: %s\n", DisplayString(dpy));
++}
++
++
++/**
++ * Print interesting limits for vertex/fragment programs.
++ */
++static void
++print_program_limits(GLenum target)
++{
++#if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program)
++   struct token_name {
++      GLenum token;
++      const char *name;
++   };
++   static const struct token_name common_limits[] = {
++      { GL_MAX_PROGRAM_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_INSTRUCTIONS_ARB" },
++      { GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" },
++      { GL_MAX_PROGRAM_TEMPORARIES_ARB, "GL_MAX_PROGRAM_TEMPORARIES_ARB" },
++      { GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, "GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB" },
++      { GL_MAX_PROGRAM_PARAMETERS_ARB, "GL_MAX_PROGRAM_PARAMETERS_ARB" },
++      { GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, "GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB" },
++      { GL_MAX_PROGRAM_ATTRIBS_ARB, "GL_MAX_PROGRAM_ATTRIBS_ARB" },
++      { GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, "GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB" },
++      { GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB, "GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB" },
++      { GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" },
++      { GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB" },
++      { GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB" },
++      { (GLenum) 0, NULL }
++   };
++   static const struct token_name fragment_limits[] = {
++      { GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB" },
++      { GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB" },
++      { GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB" },
++      { GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB" },
++      { GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB" },
++      { GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" },
++      { (GLenum) 0, NULL }
++   };
++
++   PFNGLGETPROGRAMIVARBPROC GetProgramivARB_func = (PFNGLGETPROGRAMIVARBPROC)
++      glXGetProcAddressARB((GLubyte *) "glGetProgramivARB");
++
++   GLint max[1];
++   int i;
++
++   if (target == GL_VERTEX_PROGRAM_ARB) {
++      printf("    GL_VERTEX_PROGRAM_ARB:\n");
++   }
++   else if (target == GL_FRAGMENT_PROGRAM_ARB) {
++      printf("    GL_FRAGMENT_PROGRAM_ARB:\n");
++   }
++   else {
++      return; /* something's wrong */
++   }
++
++   for (i = 0; common_limits[i].token; i++) {
++      GetProgramivARB_func(target, common_limits[i].token, max);
++      if (glGetError() == GL_NO_ERROR) {
++         printf("        %s = %d\n", common_limits[i].name, max[0]);
++      }
++   }
++   if (target == GL_FRAGMENT_PROGRAM_ARB) {
++      for (i = 0; fragment_limits[i].token; i++) {
++         GetProgramivARB_func(target, fragment_limits[i].token, max);
++         if (glGetError() == GL_NO_ERROR) {
++            printf("        %s = %d\n", fragment_limits[i].name, max[0]);
++         }
++      }
++   }
++#endif /* GL_ARB_vertex_program / GL_ARB_fragment_program */
++}
++
++
++/**
++ * Print interesting limits for vertex/fragment shaders.
++ */
++static void
++print_shader_limits(GLenum target)
++{
++   struct token_name {
++      GLenum token;
++      const char *name;
++   };
++#if defined(GL_ARB_vertex_shader)
++   static const struct token_name vertex_limits[] = {
++      { GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB" },
++      { GL_MAX_VARYING_FLOATS_ARB, "GL_MAX_VARYING_FLOATS_ARB" },
++      { GL_MAX_VERTEX_ATTRIBS_ARB, "GL_MAX_VERTEX_ATTRIBS_ARB" },
++      { GL_MAX_TEXTURE_IMAGE_UNITS_ARB, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" },
++      { GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB" },
++      { GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB" },
++      { GL_MAX_TEXTURE_COORDS_ARB, "GL_MAX_TEXTURE_COORDS_ARB" },
++      { (GLenum) 0, NULL }
++   };
++#endif
++#if defined(GL_ARB_fragment_shader)
++   static const struct token_name fragment_limits[] = {
++      { GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB" },
++      { GL_MAX_TEXTURE_COORDS_ARB, "GL_MAX_TEXTURE_COORDS_ARB" },
++      { GL_MAX_TEXTURE_IMAGE_UNITS_ARB, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" },
++      { (GLenum) 0, NULL }
++   };
++#endif
++   GLint max[1];
++   int i;
++
++#if defined(GL_ARB_vertex_shader)
++   if (target == GL_VERTEX_SHADER_ARB) {
++      printf("    GL_VERTEX_SHADER_ARB:\n");
++      for (i = 0; vertex_limits[i].token; i++) {
++         glGetIntegerv(vertex_limits[i].token, max);
++         if (glGetError() == GL_NO_ERROR) {
++            printf("        %s = %d\n", vertex_limits[i].name, max[0]);
++         }
++      }
++   }
++#endif
++#if defined(GL_ARB_fragment_shader)
++   if (target == GL_FRAGMENT_SHADER_ARB) {
++      printf("    GL_FRAGMENT_SHADER_ARB:\n");
++      for (i = 0; fragment_limits[i].token; i++) {
++         glGetIntegerv(fragment_limits[i].token, max);
++         if (glGetError() == GL_NO_ERROR) {
++            printf("        %s = %d\n", fragment_limits[i].name, max[0]);
++         }
++      }
++   }
++#endif
++}
++
++
++/**
++ * Print interesting OpenGL implementation limits.
++ */
++static void
++print_limits(const char *extensions)
++{
++   struct token_name {
++      GLuint count;
++      GLenum token;
++      const char *name;
++   };
++   static const struct token_name limits[] = {
++      { 1, GL_MAX_ATTRIB_STACK_DEPTH, "GL_MAX_ATTRIB_STACK_DEPTH" },
++      { 1, GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH" },
++      { 1, GL_MAX_CLIP_PLANES, "GL_MAX_CLIP_PLANES" },
++      { 1, GL_MAX_COLOR_MATRIX_STACK_DEPTH, "GL_MAX_COLOR_MATRIX_STACK_DEPTH" },
++      { 1, GL_MAX_ELEMENTS_VERTICES, "GL_MAX_ELEMENTS_VERTICES" },
++      { 1, GL_MAX_ELEMENTS_INDICES, "GL_MAX_ELEMENTS_INDICES" },
++      { 1, GL_MAX_EVAL_ORDER, "GL_MAX_EVAL_ORDER" },
++      { 1, GL_MAX_LIGHTS, "GL_MAX_LIGHTS" },
++      { 1, GL_MAX_LIST_NESTING, "GL_MAX_LIST_NESTING" },
++      { 1, GL_MAX_MODELVIEW_STACK_DEPTH, "GL_MAX_MODELVIEW_STACK_DEPTH" },
++      { 1, GL_MAX_NAME_STACK_DEPTH, "GL_MAX_NAME_STACK_DEPTH" },
++      { 1, GL_MAX_PIXEL_MAP_TABLE, "GL_MAX_PIXEL_MAP_TABLE" },
++      { 1, GL_MAX_PROJECTION_STACK_DEPTH, "GL_MAX_PROJECTION_STACK_DEPTH" },
++      { 1, GL_MAX_TEXTURE_STACK_DEPTH, "GL_MAX_TEXTURE_STACK_DEPTH" },
++      { 1, GL_MAX_TEXTURE_SIZE, "GL_MAX_TEXTURE_SIZE" },
++      { 1, GL_MAX_3D_TEXTURE_SIZE, "GL_MAX_3D_TEXTURE_SIZE" },
++      { 2, GL_MAX_VIEWPORT_DIMS, "GL_MAX_VIEWPORT_DIMS" },
++      { 2, GL_ALIASED_LINE_WIDTH_RANGE, "GL_ALIASED_LINE_WIDTH_RANGE" },
++      { 2, GL_SMOOTH_LINE_WIDTH_RANGE, "GL_SMOOTH_LINE_WIDTH_RANGE" },
++      { 2, GL_ALIASED_POINT_SIZE_RANGE, "GL_ALIASED_POINT_SIZE_RANGE" },
++      { 2, GL_SMOOTH_POINT_SIZE_RANGE, "GL_SMOOTH_POINT_SIZE_RANGE" },
++#if defined(GL_ARB_texture_cube_map)
++      { 1, GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB" },
++#endif
++#if defined(GLX_NV_texture_rectangle)
++      { 1, GL_MAX_RECTANGLE_TEXTURE_SIZE_NV, "GL_MAX_RECTANGLE_TEXTURE_SIZE_NV" },
++#endif
++#if defined(GL_ARB_texture_compression)
++      { 1, GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, "GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB" },
++#endif
++#if defined(GL_ARB_multitexture)
++      { 1, GL_MAX_TEXTURE_UNITS_ARB, "GL_MAX_TEXTURE_UNITS_ARB" },
++#endif
++#if defined(GL_EXT_texture_lod_bias)
++      { 1, GL_MAX_TEXTURE_LOD_BIAS_EXT, "GL_MAX_TEXTURE_LOD_BIAS_EXT" },
++#endif
++#if defined(GL_EXT_texture_filter_anisotropic)
++      { 1, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT" },
++#endif
++#if defined(GL_ARB_draw_buffers)
++      { 1, GL_MAX_DRAW_BUFFERS_ARB, "GL_MAX_DRAW_BUFFERS_ARB" },
++#endif
++      { 0, (GLenum) 0, NULL }
++   };
++   GLint i, max[2];
++
++   printf("OpenGL limits:\n");
++   for (i = 0; limits[i].count; i++) {
++      glGetIntegerv(limits[i].token, max);
++      if (glGetError() == GL_NO_ERROR) {
++         if (limits[i].count == 1)
++            printf("    %s = %d\n", limits[i].name, max[0]);
++         else /* XXX fix if we ever query something with more than 2 values */
++            printf("    %s = %d, %d\n", limits[i].name, max[0], max[1]);
++      }
++   }
++
++   /* these don't fit into the above mechanism, unfortunately */
++   glGetConvolutionParameteriv(GL_CONVOLUTION_2D, GL_MAX_CONVOLUTION_WIDTH, max);
++   glGetConvolutionParameteriv(GL_CONVOLUTION_2D, GL_MAX_CONVOLUTION_HEIGHT, max+1);
++   if (glGetError() == GL_NONE) {
++      printf("    GL_MAX_CONVOLUTION_WIDTH/HEIGHT = %d, %d\n", max[0], max[1]);
++   }
++
++#if defined(GL_ARB_vertex_program)
++   if (strstr(extensions, "GL_ARB_vertex_program")) {
++      print_program_limits(GL_VERTEX_PROGRAM_ARB);
++   }
++#endif
++#if defined(GL_ARB_fragment_program)
++   if (strstr(extensions, "GL_ARB_fragment_program")) {
++      print_program_limits(GL_FRAGMENT_PROGRAM_ARB);
++   }
++#endif
++#if defined(GL_ARB_vertex_shader)
++   if (strstr(extensions, "GL_ARB_vertex_shader")) {
++      print_shader_limits(GL_VERTEX_SHADER_ARB);
++   }
++#endif
++#if defined(GL_ARB_fragment_shader)
++   if (strstr(extensions, "GL_ARB_fragment_shader")) {
++      print_shader_limits(GL_FRAGMENT_SHADER_ARB);
++   }
++#endif
++}
++
++
++static void
++print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits)
++{
++   Window win;
++   int attribSingle[] = {
++      GLX_RGBA,
++      GLX_RED_SIZE, 1,
++      GLX_GREEN_SIZE, 1,
++      GLX_BLUE_SIZE, 1,
++      None };
++   int attribDouble[] = {
++      GLX_RGBA,
++      GLX_RED_SIZE, 1,
++      GLX_GREEN_SIZE, 1,
++      GLX_BLUE_SIZE, 1,
++      GLX_DOUBLEBUFFER,
++      None };
++
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   GLXContext ctx = NULL;
++   XVisualInfo *visinfo;
++   int width = 100, height = 100;
++
++   root = RootWindow(dpy, scrnum);
++
++   /*
++    * Find a basic GLX visual.  We'll then create a rendering context and
++    * query various info strings.
++    */
++   visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
++   if (!visinfo)
++      visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
++
++   if (visinfo)
++      ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );
++
++#ifdef GLX_VERSION_1_3
++   /* Try glXChooseFBConfig() if glXChooseVisual didn't work.
++    * XXX when would that happen?
++    */
++   if (!visinfo) {
++      int fbAttribSingle[] = {
++	 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
++	 GLX_RED_SIZE,      1,
++	 GLX_GREEN_SIZE,    1,
++	 GLX_BLUE_SIZE,     1,
++	 GLX_DOUBLEBUFFER,  GL_FALSE,
++	 None };
++      int fbAttribDouble[] = {
++	 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
++	 GLX_RED_SIZE,      1,
++	 GLX_GREEN_SIZE,    1,
++	 GLX_BLUE_SIZE,     1,
++	 GLX_DOUBLEBUFFER,  GL_TRUE,
++	 None };
++      GLXFBConfig *configs = NULL;
++      int nConfigs;
++
++      configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs);
++      if (!configs)
++	 configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs);
++
++      if (configs) {
++	 visinfo = glXGetVisualFromFBConfig(dpy, configs[0]);
++	 ctx = glXCreateNewContext(dpy, configs[0], GLX_RGBA_TYPE, NULL, allowDirect);
++	 XFree(configs);
++      }
++   }
++#endif
++
++   if (!visinfo) {
++      fprintf(stderr, "Error: couldn't find RGB GLX visual or fbconfig\n");
++      return;
++   }
++
++   if (!ctx) {
++      fprintf(stderr, "Error: glXCreateContext failed\n");
++      XFree(visinfo);
++      return;
++   }
++
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++   win = XCreateWindow(dpy, root, 0, 0, width, height,
++		       0, visinfo->depth, InputOutput,
++		       visinfo->visual, mask, &attr);
++
++   if (glXMakeCurrent(dpy, win, ctx)) {
++      const char *serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR);
++      const char *serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION);
++      const char *serverExtensions = glXQueryServerString(dpy, scrnum, GLX_EXTENSIONS);
++      const char *clientVendor = glXGetClientString(dpy, GLX_VENDOR);
++      const char *clientVersion = glXGetClientString(dpy, GLX_VERSION);
++      const char *clientExtensions = glXGetClientString(dpy, GLX_EXTENSIONS);
++      const char *glxExtensions = glXQueryExtensionsString(dpy, scrnum);
++      const char *glVendor = (const char *) glGetString(GL_VENDOR);
++      const char *glRenderer = (const char *) glGetString(GL_RENDERER);
++      const char *glVersion = (const char *) glGetString(GL_VERSION);
++      const char *glExtensions = (const char *) glGetString(GL_EXTENSIONS);
++      int glxVersionMajor;
++      int glxVersionMinor;
++      char *displayName = NULL;
++      char *colon = NULL, *period = NULL;
++      
++      if (! glXQueryVersion( dpy, & glxVersionMajor, & glxVersionMinor )) {
++         fprintf(stderr, "Error: glXQueryVersion failed\n");
++         exit(1);
++      }
++
++      /* Strip the screen number from the display name, if present. */
++      if (!(displayName = (char *) malloc(strlen(DisplayString(dpy)) + 1))) {
++         fprintf(stderr, "Error: malloc() failed\n");
++         exit(1);
++      }
++      strcpy(displayName, DisplayString(dpy));
++      colon = strrchr(displayName, ':');
++      if (colon) {
++         period = strchr(colon, '.');
++         if (period)
++            *period = '\0';
++      }
++      printf("display: %s  screen: %d\n", displayName, scrnum);
++      free(displayName);
++      printf("direct rendering: ");
++      if (glXIsDirect(dpy, ctx)) {
++         printf("Yes\n");
++      } else {
++         if (!allowDirect) {
++            printf("No (-i specified)\n");
++         } else if (getenv("LIBGL_ALWAYS_INDIRECT")) {
++            printf("No (LIBGL_ALWAYS_INDIRECT set)\n");
++         } else {
++            printf("No (If you want to find out why, try setting "
++                   "LIBGL_DEBUG=verbose)\n");
++         }
++      }
++      printf("server glx vendor string: %s\n", serverVendor);
++      printf("server glx version string: %s\n", serverVersion);
++      printf("server glx extensions:\n");
++      print_extension_list(serverExtensions);
++      printf("client glx vendor string: %s\n", clientVendor);
++      printf("client glx version string: %s\n", clientVersion);
++      printf("client glx extensions:\n");
++      print_extension_list(clientExtensions);
++      printf("GLX version: %u.%u\n", glxVersionMajor, glxVersionMinor);
++      printf("GLX extensions:\n");
++      print_extension_list(glxExtensions);
++      printf("OpenGL vendor string: %s\n", glVendor);
++      printf("OpenGL renderer string: %s\n", glRenderer);
++      printf("OpenGL version string: %s\n", glVersion);
++#ifdef GL_VERSION_2_0
++      if (glVersion[0] >= '2' && glVersion[1] == '.') {
++         char *v = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
++         printf("OpenGL shading language version string: %s\n", v);
++      }
++#endif
++
++      printf("OpenGL extensions:\n");
++      print_extension_list(glExtensions);
++      if (limits)
++         print_limits(glExtensions);
++   }
++   else {
++      fprintf(stderr, "Error: glXMakeCurrent failed\n");
++   }
++
++   glXDestroyContext(dpy, ctx);
++   XFree(visinfo);
++   XDestroyWindow(dpy, win);
++}
++
++
++static const char *
++visual_class_name(int cls)
++{
++   switch (cls) {
++      case StaticColor:
++         return "StaticColor";
++      case PseudoColor:
++         return "PseudoColor";
++      case StaticGray:
++         return "StaticGray";
++      case GrayScale:
++         return "GrayScale";
++      case TrueColor:
++         return "TrueColor";
++      case DirectColor:
++         return "DirectColor";
++      default:
++         return "";
++   }
++}
++
++
++static const char *
++visual_class_abbrev(int cls)
++{
++   switch (cls) {
++      case StaticColor:
++         return "sc";
++      case PseudoColor:
++         return "pc";
++      case StaticGray:
++         return "sg";
++      case GrayScale:
++         return "gs";
++      case TrueColor:
++         return "tc";
++      case DirectColor:
++         return "dc";
++      default:
++         return "";
++   }
++}
++
++static const char *
++visual_render_type_name(int type)
++{
++   switch (type) {
++      case GLX_RGBA_BIT:
++         return "rgba";
++      case GLX_COLOR_INDEX_BIT:
++         return "ci";
++      case GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT:
++         return "rgba|ci";
++      default:
++         return "";
++      }
++}
++
++static GLboolean
++get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
++                   struct visual_attribs *attribs)
++{
++   const char *ext = glXQueryExtensionsString(dpy, vInfo->screen);
++   int rgba;
++
++   memset(attribs, 0, sizeof(struct visual_attribs));
++
++   attribs->id = vInfo->visualid;
++#if defined(__cplusplus) || defined(c_plusplus)
++   attribs->klass = vInfo->c_class;
++#else
++   attribs->klass = vInfo->class;
++#endif
++   attribs->depth = vInfo->depth;
++   attribs->redMask = vInfo->red_mask;
++   attribs->greenMask = vInfo->green_mask;
++   attribs->blueMask = vInfo->blue_mask;
++   attribs->colormapSize = vInfo->colormap_size;
++   attribs->bitsPerRGB = vInfo->bits_per_rgb;
++
++   if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0 ||
++       !attribs->supportsGL)
++      return GL_FALSE;
++   glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize);
++   glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level);
++   glXGetConfig(dpy, vInfo, GLX_RGBA, &rgba);
++   if (rgba)
++      attribs->render_type = GLX_RGBA_BIT;
++   else
++      attribs->render_type = GLX_COLOR_INDEX_BIT;
++   
++   glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
++   glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo);
++   glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers);
++   glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize);
++   glXGetConfig(dpy, vInfo, GLX_GREEN_SIZE, &attribs->greenSize);
++   glXGetConfig(dpy, vInfo, GLX_BLUE_SIZE, &attribs->blueSize);
++   glXGetConfig(dpy, vInfo, GLX_ALPHA_SIZE, &attribs->alphaSize);
++   glXGetConfig(dpy, vInfo, GLX_DEPTH_SIZE, &attribs->depthSize);
++   glXGetConfig(dpy, vInfo, GLX_STENCIL_SIZE, &attribs->stencilSize);
++   glXGetConfig(dpy, vInfo, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
++   glXGetConfig(dpy, vInfo, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
++   glXGetConfig(dpy, vInfo, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
++   glXGetConfig(dpy, vInfo, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);
++
++   /* get transparent pixel stuff */
++   glXGetConfig(dpy, vInfo,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
++   if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
++     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
++     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
++     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
++     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
++   }
++   else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
++     glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
++   }
++
++   /* multisample attribs */
++#ifdef GLX_ARB_multisample
++   if (ext && strstr(ext, "GLX_ARB_multisample")) {
++      glXGetConfig(dpy, vInfo, GLX_SAMPLE_BUFFERS_ARB, &attribs->numMultisample);
++      glXGetConfig(dpy, vInfo, GLX_SAMPLES_ARB, &attribs->numSamples);
++   }
++#endif
++   else {
++      attribs->numSamples = 0;
++      attribs->numMultisample = 0;
++   }
++
++#if defined(GLX_EXT_visual_rating)
++   if (ext && strstr(ext, "GLX_EXT_visual_rating")) {
++      glXGetConfig(dpy, vInfo, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat);
++   }
++   else {
++      attribs->visualCaveat = GLX_NONE_EXT;
++   }
++#else
++   attribs->visualCaveat = 0;
++#endif
++
++   return GL_TRUE;
++}
++
++#ifdef GLX_VERSION_1_3
++
++static int
++glx_token_to_visual_class(int visual_type)
++{
++   switch (visual_type) {
++   case GLX_TRUE_COLOR:
++      return TrueColor;
++   case GLX_DIRECT_COLOR:
++      return DirectColor;
++   case GLX_PSEUDO_COLOR:
++      return PseudoColor;
++   case GLX_STATIC_COLOR:
++      return StaticColor;
++   case GLX_GRAY_SCALE:
++      return GrayScale;
++   case GLX_STATIC_GRAY:
++      return StaticGray;
++   case GLX_NONE:
++   default:
++      return None;
++   }
++}
++
++static GLboolean
++get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
++		     struct visual_attribs *attribs)
++{
++   int visual_type;
++
++   memset(attribs, 0, sizeof(struct visual_attribs));
++
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_FBCONFIG_ID, &attribs->id);
++
++#if 0
++   attribs->depth = vInfo->depth;
++   attribs->redMask = vInfo->red_mask;
++   attribs->greenMask = vInfo->green_mask;
++   attribs->blueMask = vInfo->blue_mask;
++   attribs->colormapSize = vInfo->colormap_size;
++   attribs->bitsPerRGB = vInfo->bits_per_rgb;
++#endif
++
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_X_VISUAL_TYPE, &visual_type);
++   attribs->klass = glx_token_to_visual_class(visual_type);
++
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_BUFFER_SIZE, &attribs->bufferSize);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_LEVEL, &attribs->level);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &attribs->render_type);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_STEREO, &attribs->stereo);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_AUX_BUFFERS, &attribs->auxBuffers);
++
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_RED_SIZE, &attribs->redSize);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_GREEN_SIZE, &attribs->greenSize);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_BLUE_SIZE, &attribs->blueSize);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_ALPHA_SIZE, &attribs->alphaSize);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_DEPTH_SIZE, &attribs->depthSize);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_STENCIL_SIZE, &attribs->stencilSize);
++
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);
++
++   /* get transparent pixel stuff */
++   glXGetFBConfigAttrib(dpy, fbconfig,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
++   if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
++     glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
++     glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
++     glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
++     glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
++   }
++   else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
++     glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
++   }
++
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLE_BUFFERS, &attribs->numMultisample);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLES, &attribs->numSamples);
++   glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &attribs->visualCaveat);
++
++   return GL_TRUE;
++}
++
++#endif
++
++
++
++static void
++print_visual_attribs_verbose(const struct visual_attribs *attribs)
++{
++   printf("Visual ID: %x  depth=%d  class=%s\n",
++          attribs->id, attribs->depth, visual_class_name(attribs->klass));
++   printf("    bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n",
++          attribs->bufferSize, attribs->level,
++	  visual_render_type_name(attribs->render_type),
++          attribs->doubleBuffer, attribs->stereo);
++   printf("    rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n",
++          attribs->redSize, attribs->greenSize,
++          attribs->blueSize, attribs->alphaSize);
++   printf("    auxBuffers=%d depthSize=%d stencilSize=%d\n",
++          attribs->auxBuffers, attribs->depthSize, attribs->stencilSize);
++   printf("    accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n",
++          attribs->accumRedSize, attribs->accumGreenSize,
++          attribs->accumBlueSize, attribs->accumAlphaSize);
++   printf("    multiSample=%d  multiSampleBuffers=%d\n",
++          attribs->numSamples, attribs->numMultisample);
++#ifdef GLX_EXT_visual_rating
++   if (attribs->visualCaveat == GLX_NONE_EXT || attribs->visualCaveat == 0)
++      printf("    visualCaveat=None\n");
++   else if (attribs->visualCaveat == GLX_SLOW_VISUAL_EXT)
++      printf("    visualCaveat=Slow\n");
++   else if (attribs->visualCaveat == GLX_NON_CONFORMANT_VISUAL_EXT)
++      printf("    visualCaveat=Nonconformant\n");
++#endif
++   if (attribs->transparentType == GLX_NONE) {
++     printf("    Opaque.\n");
++   }
++   else if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
++     printf("    Transparent RGB: Red=%d Green=%d Blue=%d Alpha=%d\n",attribs->transparentRedValue,attribs->transparentGreenValue,attribs->transparentBlueValue,attribs->transparentAlphaValue);
++   }
++   else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
++     printf("    Transparent index=%d\n",attribs->transparentIndexValue);
++   }
++}
++
++
++static void
++print_visual_attribs_short_header(void)
++{
++ printf("   visual  x  bf lv rg d st colorbuffer ax dp st accumbuffer  ms  cav\n");
++ printf(" id dep cl sp sz l  ci b ro  r  g  b  a bf th cl  r  g  b  a ns b eat\n");
++ printf("----------------------------------------------------------------------\n");
++}
++
++
++static void
++print_visual_attribs_short(const struct visual_attribs *attribs)
++{
++   char *caveat = NULL;
++#ifdef GLX_EXT_visual_rating
++   if (attribs->visualCaveat == GLX_NONE_EXT || attribs->visualCaveat == 0)
++      caveat = "None";
++   else if (attribs->visualCaveat == GLX_SLOW_VISUAL_EXT)
++      caveat = "Slow";
++   else if (attribs->visualCaveat == GLX_NON_CONFORMANT_VISUAL_EXT)
++      caveat = "Ncon";
++   else
++      caveat = "None";
++#else
++   caveat = "None";
++#endif 
++
++   printf("0x%02x %2d %2s %2d %2d %2d %c%c %c  %c %2d %2d %2d %2d %2d %2d %2d",
++          attribs->id,
++          attribs->depth,
++          visual_class_abbrev(attribs->klass),
++          attribs->transparentType != GLX_NONE,
++          attribs->bufferSize,
++          attribs->level,
++          (attribs->render_type & GLX_RGBA_BIT) ? 'r' : ' ',
++          (attribs->render_type & GLX_COLOR_INDEX_BIT) ? 'c' : ' ',
++          attribs->doubleBuffer ? 'y' : '.',
++          attribs->stereo ? 'y' : '.',
++          attribs->redSize, attribs->greenSize,
++          attribs->blueSize, attribs->alphaSize,
++          attribs->auxBuffers,
++          attribs->depthSize,
++          attribs->stencilSize
++          );
++
++   printf(" %2d %2d %2d %2d %2d %1d %s\n",
++          attribs->accumRedSize, attribs->accumGreenSize,
++          attribs->accumBlueSize, attribs->accumAlphaSize,
++          attribs->numSamples, attribs->numMultisample,
++          caveat
++          );
++}
++
++
++static void
++print_visual_attribs_long_header(void)
++{
++ printf("Vis  Vis   Visual Trans  buff lev render DB ste  r   g   b   a  aux dep ste  accum buffers  MS   MS\n");
++ printf(" ID Depth   Type  parent size el   type     reo sz  sz  sz  sz  buf th  ncl  r   g   b   a  num bufs\n");
++ printf("----------------------------------------------------------------------------------------------------\n");
++}
++
++
++static void
++print_visual_attribs_long(const struct visual_attribs *attribs)
++{
++   printf("0x%2x %2d %-11s %2d     %2d %2d  %4s %3d %3d %3d %3d %3d %3d",
++          attribs->id,
++          attribs->depth,
++          visual_class_name(attribs->klass),
++          attribs->transparentType != GLX_NONE,
++          attribs->bufferSize,
++          attribs->level,
++          visual_render_type_name(attribs->render_type),
++          attribs->doubleBuffer,
++          attribs->stereo,
++          attribs->redSize, attribs->greenSize,
++          attribs->blueSize, attribs->alphaSize
++          );
++
++   printf(" %3d %4d %2d %3d %3d %3d %3d  %2d  %2d\n",
++          attribs->auxBuffers,
++          attribs->depthSize,
++          attribs->stencilSize,
++          attribs->accumRedSize, attribs->accumGreenSize,
++          attribs->accumBlueSize, attribs->accumAlphaSize,
++          attribs->numSamples, attribs->numMultisample
++          );
++}
++
++
++static void
++print_visual_info(Display *dpy, int scrnum, InfoMode mode)
++{
++   XVisualInfo theTemplate;
++   XVisualInfo *visuals;
++   int numVisuals, numGlxVisuals;
++   long mask;
++   int i;
++   struct visual_attribs attribs;
++
++   /* get list of all visuals on this screen */
++   theTemplate.screen = scrnum;
++   mask = VisualScreenMask;
++   visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals);
++
++   numGlxVisuals = 0;
++   for (i = 0; i < numVisuals; i++) {
++      if (get_visual_attribs(dpy, &visuals[i], &attribs))
++	 numGlxVisuals++;
++   }
++
++   if (numGlxVisuals == 0)
++      return;
++
++   printf("%d GLX Visuals\n", numGlxVisuals);
++
++   if (mode == Normal)
++      print_visual_attribs_short_header();
++   else if (mode == Wide)
++      print_visual_attribs_long_header();
++
++   for (i = 0; i < numVisuals; i++) {
++      if (!get_visual_attribs(dpy, &visuals[i], &attribs))
++	 continue;
++
++      if (mode == Verbose)
++	 print_visual_attribs_verbose(&attribs);
++      else if (mode == Normal)
++         print_visual_attribs_short(&attribs);
++      else if (mode == Wide) 
++         print_visual_attribs_long(&attribs);
++   }
++   printf("\n");
++
++   XFree(visuals);
++}
++
++#ifdef GLX_VERSION_1_3
++
++static void
++print_fbconfig_info(Display *dpy, int scrnum, InfoMode mode)
++{
++   int numFBConfigs = 0;
++   struct visual_attribs attribs;
++   GLXFBConfig *fbconfigs;
++   int i;
++
++   /* get list of all fbconfigs on this screen */
++   fbconfigs = glXGetFBConfigs(dpy, scrnum, &numFBConfigs);
++
++   if (numFBConfigs == 0) {
++      XFree(fbconfigs);
++      return;
++   }
++
++   printf("%d GLXFBConfigs:\n", numFBConfigs);
++   if (mode == Normal)
++      print_visual_attribs_short_header();
++   else if (mode == Wide)
++      print_visual_attribs_long_header();
++
++   for (i = 0; i < numFBConfigs; i++) {
++      get_fbconfig_attribs(dpy, fbconfigs[i], &attribs);
++
++      if (mode == Verbose) 
++         print_visual_attribs_verbose(&attribs);
++      else if (mode == Normal)
++	 print_visual_attribs_short(&attribs);
++      else if (mode == Wide)
++         print_visual_attribs_long(&attribs);
++   }
++   printf("\n");
++
++   XFree(fbconfigs);
++}
++
++#endif
++
++/*
++ * Stand-alone Mesa doesn't really implement the GLX protocol so it
++ * doesn't really know the GLX attributes associated with an X visual.
++ * The first time a visual is presented to Mesa's pseudo-GLX it
++ * attaches ancilliary buffers to it (like depth and stencil).
++ * But that usually only works if glXChooseVisual is used.
++ * This function calls glXChooseVisual() to sort of "prime the pump"
++ * for Mesa's GLX so that the visuals that get reported actually
++ * reflect what applications will see.
++ * This has no effect when using true GLX.
++ */
++static void
++mesa_hack(Display *dpy, int scrnum)
++{
++   static int attribs[] = {
++      GLX_RGBA,
++      GLX_RED_SIZE, 1,
++      GLX_GREEN_SIZE, 1,
++      GLX_BLUE_SIZE, 1,
++      GLX_DEPTH_SIZE, 1,
++      GLX_STENCIL_SIZE, 1,
++      GLX_ACCUM_RED_SIZE, 1,
++      GLX_ACCUM_GREEN_SIZE, 1,
++      GLX_ACCUM_BLUE_SIZE, 1,
++      GLX_ACCUM_ALPHA_SIZE, 1,
++      GLX_DOUBLEBUFFER,
++      None
++   };
++   XVisualInfo *visinfo;
++
++   visinfo = glXChooseVisual(dpy, scrnum, attribs);
++   if (visinfo)
++      XFree(visinfo);
++}
++
++
++/*
++ * Examine all visuals to find the so-called best one.
++ * We prefer deepest RGBA buffer with depth, stencil and accum
++ * that has no caveats.
++ */
++static int
++find_best_visual(Display *dpy, int scrnum)
++{
++   XVisualInfo theTemplate;
++   XVisualInfo *visuals;
++   int numVisuals;
++   long mask;
++   int i;
++   struct visual_attribs bestVis;
++
++   /* get list of all visuals on this screen */
++   theTemplate.screen = scrnum;
++   mask = VisualScreenMask;
++   visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals);
++
++   /* init bestVis with first visual info */
++   get_visual_attribs(dpy, &visuals[0], &bestVis);
++
++   /* try to find a "better" visual */
++   for (i = 1; i < numVisuals; i++) {
++      struct visual_attribs vis;
++
++      get_visual_attribs(dpy, &visuals[i], &vis);
++
++      /* always skip visuals with caveats */
++      if (vis.visualCaveat != GLX_NONE_EXT)
++         continue;
++
++      /* see if this vis is better than bestVis */
++      if ((!bestVis.supportsGL && vis.supportsGL) ||
++          (bestVis.visualCaveat != GLX_NONE_EXT) ||
++          (!(bestVis.render_type & GLX_RGBA_BIT) && (vis.render_type & GLX_RGBA_BIT)) ||
++          (!bestVis.doubleBuffer && vis.doubleBuffer) ||
++          (bestVis.redSize < vis.redSize) ||
++          (bestVis.greenSize < vis.greenSize) ||
++          (bestVis.blueSize < vis.blueSize) ||
++          (bestVis.alphaSize < vis.alphaSize) ||
++          (bestVis.depthSize < vis.depthSize) ||
++          (bestVis.stencilSize < vis.stencilSize) ||
++          (bestVis.accumRedSize < vis.accumRedSize)) {
++         /* found a better visual */
++         bestVis = vis;
++      }
++   }
++
++   XFree(visuals);
++
++   return bestVis.id;
++}
++
++
++static void
++usage(void)
++{
++   printf("Usage: glxinfo [-v] [-t] [-h] [-i] [-b] [-display <dname>]\n");
++   printf("\t-v: Print visuals info in verbose form.\n");
++   printf("\t-t: Print verbose table.\n");
++   printf("\t-display <dname>: Print GLX visuals on specified server.\n");
++   printf("\t-h: This information.\n");
++   printf("\t-i: Force an indirect rendering context.\n");
++   printf("\t-b: Find the 'best' visual and print its number.\n");
++   printf("\t-l: Print interesting OpenGL limits.\n");
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   char *displayName = NULL;
++   Display *dpy;
++   int numScreens, scrnum;
++   InfoMode mode = Normal;
++   GLboolean findBest = GL_FALSE;
++   GLboolean limits = GL_FALSE;
++   Bool allowDirect = True;
++   int i;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0 && i + 1 < argc) {
++         displayName = argv[i + 1];
++         i++;
++      }
++      else if (strcmp(argv[i], "-t") == 0) {
++         mode = Wide;
++      }
++      else if (strcmp(argv[i], "-v") == 0) {
++         mode = Verbose;
++      }
++      else if (strcmp(argv[i], "-b") == 0) {
++         findBest = GL_TRUE;
++      }
++      else if (strcmp(argv[i], "-i") == 0) {
++         allowDirect = False;
++      }
++      else if (strcmp(argv[i], "-l") == 0) {
++         limits = GL_TRUE;
++      }
++      else if (strcmp(argv[i], "-h") == 0) {
++         usage();
++         return 0;
++      }
++      else {
++         printf("Unknown option `%s'\n", argv[i]);
++         usage();
++         return 0;
++      }
++   }
++
++   dpy = XOpenDisplay(displayName);
++   if (!dpy) {
++      fprintf(stderr, "Error: unable to open display %s\n", XDisplayName(displayName));
++      return -1;
++   }
++
++   if (findBest) {
++      int b;
++      mesa_hack(dpy, 0);
++      b = find_best_visual(dpy, 0);
++      printf("%d\n", b);
++   }
++   else {
++      numScreens = ScreenCount(dpy);
++      print_display_info(dpy);
++      for (scrnum = 0; scrnum < numScreens; scrnum++) {
++         mesa_hack(dpy, scrnum);
++         print_screen_info(dpy, scrnum, allowDirect, limits);
++         printf("\n");
++         print_visual_info(dpy, scrnum, mode);
++#ifdef GLX_VERSION_1_3
++         print_fbconfig_info(dpy, scrnum, mode);
++#endif
++         if (scrnum + 1 < numScreens)
++            printf("\n\n");
++      }
++   }
++
++   XCloseDisplay(dpy);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxpbdemo.c Mesa-7.8.1.patched/progs/xdemos/glxpbdemo.c
+--- Mesa-7.8.1/progs/xdemos/glxpbdemo.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxpbdemo.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,431 @@
++
++/*
++ * This program demonstrates how to do "off-screen" rendering using
++ * the GLX pixel buffer extension.
++ *
++ * Written by Brian Paul for the "OpenGL and Window System Integration"
++ * course presented at SIGGRAPH '97.  Updated on 5 October 2002.
++ *
++ * Updated on 31 January 2004 to use native GLX by
++ * Andrew P. Lentvorski, Jr. <bsder@allcaps.org>
++ *
++ * Usage:
++ *   glxpbdemo width height imgfile
++ * Where:
++ *   width is the width, in pixels, of the image to generate.
++ *   height is the height, in pixels, of the image to generate.
++ *   imgfile is the name of the PPM image file to write.
++ *
++ *
++ * This demo draws 3-D boxes with random orientation.
++ *
++ * On machines such as the SGI Indigo you may have to reconfigure your
++ * display/X server to enable pbuffers.  Look in the /usr/gfx/ucode/MGRAS/vof/
++ * directory for display configurations with the _pbuf suffix.  Use
++ * setmon -x <vof> to configure your X server and display for pbuffers.
++ *
++ * O2 systems seem to support pbuffers well.
++ *
++ */
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <X11/Xlib.h>
++#include <GL/glx.h>
++
++/* Some ugly global vars */
++static GLXFBConfig gFBconfig = 0;
++static Display *gDpy = NULL;
++static int gScreen = 0;
++static GLXPbuffer gPBuffer = 0;
++static int gWidth, gHeight;
++
++
++/*
++ * Test for appropriate version of GLX to run this program
++ * Input:  dpy - the X display
++ *         screen - screen number
++ * Return:  0 = GLX not available.
++ *          1 = GLX available.
++ */
++static int
++RuntimeQueryGLXVersion(Display *dpy, int screen)
++{
++#if defined(GLX_VERSION_1_3) || defined(GLX_VERSION_1_4)
++   char *glxversion;
++ 
++   glxversion = (char *) glXGetClientString(dpy, GLX_VERSION);
++   if (!(strstr(glxversion, "1.3") || strstr(glxversion, "1.4")))
++      return 0;
++
++   glxversion = (char *) glXQueryServerString(dpy, screen, GLX_VERSION);
++   if (!(strstr(glxversion, "1.3") || strstr(glxversion, "1.4")))
++      return 0;
++
++   return 1;
++#else
++   return 0;
++#endif
++}
++
++
++
++/*
++ * Create the pbuffer and return a GLXPbuffer handle.
++ */
++static GLXPbuffer
++MakePbuffer( Display *dpy, int screen, int width, int height )
++{
++   GLXFBConfig *fbConfigs;
++   GLXFBConfig chosenFBConfig;
++   GLXPbuffer pBuffer = None;
++
++   int nConfigs;
++   int fbconfigid;
++
++   int fbAttribs[] = {
++      GLX_RENDER_TYPE, GLX_RGBA_BIT,
++      GLX_DEPTH_SIZE, 1,
++      GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT | GLX_PBUFFER_BIT,
++      None
++   };
++
++   int pbAttribs[] = {
++      GLX_PBUFFER_WIDTH, 0,
++      GLX_PBUFFER_HEIGHT, 0,
++      GLX_LARGEST_PBUFFER, False,
++      GLX_PRESERVED_CONTENTS, False,
++      None
++   };
++
++   pbAttribs[1] = width;
++   pbAttribs[3] = height;
++
++   fbConfigs = glXChooseFBConfig(dpy, screen, fbAttribs, &nConfigs);
++
++   if (0 == nConfigs || !fbConfigs) {
++      printf("Error: glxChooseFBConfig failed\n");
++      XFree(fbConfigs);
++      XCloseDisplay(dpy);
++      return 0;
++   }
++
++   chosenFBConfig = fbConfigs[0];
++
++   glXGetFBConfigAttrib(dpy, chosenFBConfig, GLX_FBCONFIG_ID, &fbconfigid);
++   printf("Chose 0x%x as fbconfigid\n", fbconfigid);
++
++   /* Create the pbuffer using first fbConfig in the list that works. */
++   pBuffer = glXCreatePbuffer(dpy, chosenFBConfig, pbAttribs);
++
++   if (pBuffer) {
++      gFBconfig = chosenFBConfig;
++      gWidth = width;
++      gHeight = height;
++   }
++
++   XFree(fbConfigs);
++
++   return pBuffer;
++}
++
++
++
++/*
++ * Do all the X / GLX setup stuff.
++ */
++static int
++Setup(int width, int height)
++{
++#if defined(GLX_VERSION_1_3) || defined(GLX_VERSION_1_4)
++   GLXContext glCtx;
++
++   /* Open the X display */
++   gDpy = XOpenDisplay(NULL);
++   if (!gDpy) {
++      printf("Error: couldn't open default X display.\n");
++      return 0;
++   }
++
++   /* Get default screen */
++   gScreen = DefaultScreen(gDpy);
++
++   /* Test that GLX is available */
++   if (!RuntimeQueryGLXVersion(gDpy, gScreen)) {
++     printf("Error: GLX 1.3 or 1.4 not available\n");
++     XCloseDisplay(gDpy);
++     return 0;
++   }
++
++   /* Create Pbuffer */
++   gPBuffer = MakePbuffer( gDpy, gScreen, width, height );
++   if (gPBuffer==None) {
++      printf("Error: couldn't create pbuffer\n");
++      XCloseDisplay(gDpy);
++      return 0;
++   }
++
++   /* Create GLX context */
++   glCtx = glXCreateNewContext(gDpy, gFBconfig, GLX_RGBA_TYPE, NULL, True);
++   if (glCtx) {
++      if (!glXIsDirect(gDpy, glCtx)) {
++         printf("Warning: using indirect GLXContext\n");
++      }
++   }
++   else {
++      printf("Error: Couldn't create GLXContext\n");
++      XCloseDisplay(gDpy);
++      return 0;
++   }
++
++   /* Bind context to pbuffer */
++   if (!glXMakeCurrent(gDpy, gPBuffer, glCtx)) {
++      printf("Error: glXMakeCurrent failed\n");
++      XCloseDisplay(gDpy);
++      return 0;
++   }
++
++   return 1;  /* Success!! */
++#else
++   printf("Error: GLX version 1.3 or 1.4 not available at compile time\n");
++   return 0;
++#endif
++}
++
++
++
++/* One-time GL setup */
++static void
++InitGL(void)
++{
++   static GLfloat pos[4] = {0.0, 0.0, 10.0, 0.0};
++   glEnable(GL_LIGHTING);
++   glEnable(GL_LIGHT0);
++   glLightfv(GL_LIGHT0, GL_POSITION, pos);
++   glEnable(GL_NORMALIZE);
++   glEnable(GL_DEPTH_TEST);
++   glEnable(GL_CULL_FACE);
++
++   glViewport(0, 0, gWidth, gHeight);
++   glMatrixMode( GL_PROJECTION );
++   glLoadIdentity();
++   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
++   glMatrixMode( GL_MODELVIEW );
++   glLoadIdentity();
++   glTranslatef( 0.0, 0.0, -15.0 );
++
++}
++
++
++/* Return random float in [0,1] */
++static float
++Random(void)
++{
++   int i = rand();
++   return (float) (i % 1000) / 1000.0;
++}
++
++
++static void
++RandomColor(void)
++{
++   GLfloat c[4];
++   c[0] = Random();
++   c[1] = Random();
++   c[2] = Random();
++   c[3] = 1.0;
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c);
++}
++
++
++/* This function borrowed from Mark Kilgard's GLUT */
++static void
++drawBox(GLfloat x0, GLfloat x1, GLfloat y0, GLfloat y1,
++        GLfloat z0, GLfloat z1, GLenum type)
++{
++  static GLfloat n[6][3] =
++  {
++    {-1.0, 0.0, 0.0},
++    {0.0, 1.0, 0.0},
++    {1.0, 0.0, 0.0},
++    {0.0, -1.0, 0.0},
++    {0.0, 0.0, 1.0},
++    {0.0, 0.0, -1.0}
++  };
++  static GLint faces[6][4] =
++  {
++    {0, 1, 2, 3},
++    {3, 2, 6, 7},
++    {7, 6, 5, 4},
++    {4, 5, 1, 0},
++    {5, 6, 2, 1},
++    {7, 4, 0, 3}
++  };
++  GLfloat v[8][3], tmp;
++  GLint i;
++
++  if (x0 > x1) {
++    tmp = x0;
++    x0 = x1;
++    x1 = tmp;
++  }
++  if (y0 > y1) {
++    tmp = y0;
++    y0 = y1;
++    y1 = tmp;
++  }
++  if (z0 > z1) {
++    tmp = z0;
++    z0 = z1;
++    z1 = tmp;
++  }
++  v[0][0] = v[1][0] = v[2][0] = v[3][0] = x0;
++  v[4][0] = v[5][0] = v[6][0] = v[7][0] = x1;
++  v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0;
++  v[2][1] = v[3][1] = v[6][1] = v[7][1] = y1;
++  v[0][2] = v[3][2] = v[4][2] = v[7][2] = z0;
++  v[1][2] = v[2][2] = v[5][2] = v[6][2] = z1;
++
++  for (i = 0; i < 6; i++) {
++    glBegin(type);
++    glNormal3fv(&n[i][0]);
++    glVertex3fv(&v[faces[i][0]][0]);
++    glVertex3fv(&v[faces[i][1]][0]);
++    glVertex3fv(&v[faces[i][2]][0]);
++    glVertex3fv(&v[faces[i][3]][0]);
++    glEnd();
++  }
++}
++
++
++
++/* Render a scene */
++static void
++Render(void)
++{
++   int NumBoxes = 100;
++   int i;
++
++   InitGL();
++   glClearColor(0.2, 0.2, 0.9, 0.0);
++   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++   for (i=0;i<NumBoxes;i++) {
++      float tx = -2.0 + 4.0 * Random();
++      float ty = -2.0 + 4.0 * Random();
++      float tz =  4.0 - 16.0 * Random();
++      float sx = 0.1 + Random() * 0.4;
++      float sy = 0.1 + Random() * 0.4;
++      float sz = 0.1 + Random() * 0.4;
++      float rx = Random();
++      float ry = Random();
++      float rz = Random();
++      float ra = Random() * 360.0;
++      glPushMatrix();
++      glTranslatef(tx, ty, tz);
++      glRotatef(ra, rx, ry, rz);
++      glScalef(sx, sy, sz);
++      RandomColor();
++      drawBox(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, GL_POLYGON);
++      glPopMatrix();
++   }
++
++   glFinish();
++}
++
++
++
++static void
++WriteFile(const char *filename)
++{
++   FILE *f;
++   GLubyte *image;
++   int i;
++
++   image = malloc(gWidth * gHeight * 3 * sizeof(GLubyte));
++   if (!image) {
++      printf("Error: couldn't allocate image buffer\n");
++      return;
++   }
++
++   glPixelStorei(GL_PACK_ALIGNMENT, 1);
++   glReadPixels(0, 0, gWidth, gHeight, GL_RGB, GL_UNSIGNED_BYTE, image);
++
++   f = fopen(filename, "w");
++   if (!f) {
++      printf("Couldn't open image file: %s\n", filename);
++      return;
++   }
++   fprintf(f,"P6\n");
++   fprintf(f,"# ppm-file created by %s\n", "trdemo2");
++   fprintf(f,"%i %i\n", gWidth, gHeight);
++   fprintf(f,"255\n");
++   fclose(f);
++   f = fopen(filename, "ab");  /* now append binary data */
++   if (!f) {
++      printf("Couldn't append to image file: %s\n", filename);
++      return;
++   }
++
++   for (i=0;i<gHeight;i++) {
++      GLubyte *rowPtr;
++      /* Remember, OpenGL images are bottom to top.  Have to reverse. */
++      rowPtr = image + (gHeight-1-i) * gWidth*3;
++      fwrite(rowPtr, 1, gWidth*3, f);
++   }
++
++   fclose(f);
++   free(image);
++
++   printf("Wrote %d by %d image file: %s\n", gWidth, gHeight, filename);
++}
++
++
++
++/*
++ * Print message describing command line parameters.
++ */
++static void
++Usage(const char *appName)
++{
++   printf("Usage:\n");
++   printf("  %s width height imgfile\n", appName);
++   printf("Where imgfile is a ppm file\n");
++}
++
++
++
++int
++main(int argc, char *argv[])
++{
++   if (argc!=4) {
++      Usage(argv[0]);
++   }
++   else {
++      int width = atoi(argv[1]);
++      int height = atoi(argv[2]);
++      char *fileName = argv[3];
++      if (width<=0) {
++         printf("Error: width parameter must be at least 1.\n");
++         return 1;
++      }
++      if (height<=0) {
++         printf("Error: height parameter must be at least 1.\n");
++         return 1;
++      }
++      if (!Setup(width, height)) {
++         return 1;
++      }
++
++      printf("Setup completed\n");
++      Render();
++      printf("Render completed.\n");
++      WriteFile(fileName);
++      printf("File write completed.\n");
++
++      glXDestroyPbuffer( gDpy, gPBuffer );
++   }
++   return 0;
++}
++
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxpixmap.c Mesa-7.8.1.patched/progs/xdemos/glxpixmap.c
+--- Mesa-7.8.1/progs/xdemos/glxpixmap.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxpixmap.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,187 @@
++
++
++/*
++ * A demonstration of using the GLXPixmap functions.  This program is in
++ * the public domain.
++ *
++ * Brian Paul
++ */
++
++
++#include <GL/gl.h>
++#define GLX_GLXEXT_PROTOTYPES
++#include <GL/glx.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++
++static GLXContext ctx;
++static XVisualInfo *visinfo;
++static GC gc;
++
++
++
++static Window make_rgb_window( Display *dpy,
++				  unsigned int width, unsigned int height )
++{
++   const int sbAttrib[] = { GLX_RGBA,
++                            GLX_RED_SIZE, 1,
++                            GLX_GREEN_SIZE, 1,
++                            GLX_BLUE_SIZE, 1,
++                            None };
++   const int dbAttrib[] = { GLX_RGBA,
++                            GLX_RED_SIZE, 1,
++                            GLX_GREEN_SIZE, 1,
++                            GLX_BLUE_SIZE, 1,
++                            GLX_DOUBLEBUFFER,
++                            None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   visinfo = glXChooseVisual( dpy, scrnum, (int *) sbAttrib );
++   if (!visinfo) {
++      visinfo = glXChooseVisual( dpy, scrnum, (int *) dbAttrib );
++      if (!visinfo) {
++         printf("Error: couldn't get an RGB visual\n");
++         exit(1);
++      }
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   /* TODO: share root colormap if possible */
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   /* make an X GC so we can do XCopyArea later */
++   gc = XCreateGC( dpy, win, 0, NULL );
++
++   /* need indirect context */
++   ctx = glXCreateContext( dpy, visinfo, NULL, False );
++   if (!ctx) {
++      printf("Error: glXCreateContext failed\n");
++      exit(-1);
++   }
++
++   printf("Direct rendering: %s\n", glXIsDirect(dpy, ctx) ? "Yes" : "No");
++
++   return win;
++}
++
++
++static GLXPixmap make_pixmap( Display *dpy, Window win,
++			       unsigned int width, unsigned int height,
++                               Pixmap *pixmap)
++{
++   Pixmap pm;
++   GLXPixmap glxpm;
++   XWindowAttributes attr;
++
++   pm = XCreatePixmap( dpy, win, width, height, visinfo->depth );
++   if (!pm) {
++      printf("Error: XCreatePixmap failed\n");
++      exit(-1);
++   }
++
++   XGetWindowAttributes( dpy, win, &attr );
++
++   /*
++    * IMPORTANT:
++    *   Use the glXCreateGLXPixmapMESA funtion when using Mesa because
++    *   Mesa needs to know the colormap associated with a pixmap in order
++    *   to render correctly.  This is because Mesa allows RGB rendering
++    *   into any kind of visual, not just TrueColor or DirectColor.
++    */
++#ifdef GLX_MESA_pixmap_colormap
++   if (strstr(glXQueryExtensionsString(dpy, 0), "GLX_MESA_pixmap_colormap")) {
++      /* stand-alone Mesa, specify the colormap */
++      glxpm = glXCreateGLXPixmapMESA( dpy, visinfo, pm, attr.colormap );
++   }
++   else {
++      glxpm = glXCreateGLXPixmap( dpy, visinfo, pm );
++   }
++#else
++   /* This will work with Mesa too if the visual is TrueColor or DirectColor */
++   glxpm = glXCreateGLXPixmap( dpy, visinfo, pm );
++#endif
++
++   if (!glxpm) {
++      printf("Error: GLXCreateGLXPixmap failed\n");
++      exit(-1);
++   }
++
++   *pixmap = pm;
++
++   return glxpm;
++}
++
++
++
++static void event_loop( Display *dpy, GLXPixmap pm )
++{
++   XEvent event;
++
++   while (1) {
++      XNextEvent( dpy, &event );
++
++      switch (event.type) {
++	 case Expose:
++	    printf("Redraw\n");
++	    /* copy the image from GLXPixmap to window */
++	    XCopyArea( dpy, pm, event.xany.window,  /* src, dest */
++		       gc, 0, 0, 300, 300,          /* gc, src pos, size */
++		       0, 0 );                      /* dest pos */
++	    break;
++	 case ConfigureNotify:
++	    /* nothing */
++	    break;
++      }
++   }
++}
++
++
++
++int main( int argc, char *argv[] )
++{
++   Display *dpy;
++   Window win;
++   Pixmap pm;
++   GLXPixmap glxpm;
++
++   dpy = XOpenDisplay(NULL);
++
++   win = make_rgb_window( dpy, 300, 300 );
++   glxpm = make_pixmap( dpy, win, 300, 300, &pm );
++
++   glXMakeCurrent( dpy, glxpm, ctx );
++   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
++
++   /* Render an image into the pixmap */
++   glShadeModel( GL_FLAT );
++   glClearColor( 0.5, 0.5, 0.5, 1.0 );
++   glClear( GL_COLOR_BUFFER_BIT );
++   glViewport( 0, 0, 300, 300 );
++   glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
++   glColor3f( 0.0, 1.0, 1.0 );
++   glRectf( -0.75, -0.75, 0.75, 0.75 );
++   glFlush();
++   glXWaitGL();
++
++   XMapWindow( dpy, win );
++
++   event_loop( dpy, pm );
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxsnoop.c Mesa-7.8.1.patched/progs/xdemos/glxsnoop.c
+--- Mesa-7.8.1/progs/xdemos/glxsnoop.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxsnoop.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,377 @@
++/**
++ * Display/snoop the z/stencil/back/front buffers of another app's window.
++ * Also, an example of the need for shared ancillary renderbuffers.
++ *
++ * Hint: use 'xwininfo' to get a window's ID.
++ *
++ * Brian Paul
++ * 11 Oct 2007
++ */
++
++#define GL_GLEXT_PROTOTYPES
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <X11/keysym.h>
++
++
++#define Z_BUFFER 1
++#define STENCIL_BUFFER 2
++#define BACK_BUFFER 3
++#define FRONT_BUFFER 4
++
++
++static int Buffer = BACK_BUFFER;
++static int WindowID = 0;
++static const char *DisplayName = NULL;
++static GLXContext Context = 0;
++static int Width, Height;
++
++
++/**
++ * Grab the z/stencil/back/front image from the srcWin and display it
++ * (possibly converted to grayscale) in the dstWin.
++ */
++static void
++redraw(Display *dpy, Window srcWin, Window dstWin )
++{
++   GLubyte *image = malloc(Width * Height * 4);
++
++   glXMakeCurrent(dpy, srcWin, Context);
++   glPixelStorei(GL_PACK_ALIGNMENT, 1);
++   if (Buffer == BACK_BUFFER) {
++      glReadBuffer(GL_BACK);
++      glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, image);
++   }
++   else if (Buffer == FRONT_BUFFER) {
++      glReadBuffer(GL_FRONT);
++      glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, image);
++   }
++   else if (Buffer == Z_BUFFER) {
++      GLfloat *z = malloc(Width * Height * sizeof(GLfloat));
++      int i;
++      glReadPixels(0, 0, Width, Height, GL_DEPTH_COMPONENT, GL_FLOAT, z);
++      for (i = 0; i < Width * Height; i++) {
++         image[i*4+0] =
++         image[i*4+1] =
++         image[i*4+2] = (GLint) (255.0 * z[i]);
++         image[i*4+3] = 255;
++      }
++      free(z);
++   }
++   else if (Buffer == STENCIL_BUFFER) {
++      GLubyte *sten = malloc(Width * Height * sizeof(GLubyte));
++      int i, min = 100, max = -1;
++      float step;
++      int sz;
++      glGetIntegerv(GL_STENCIL_BITS, &sz);
++      glReadPixels(0, 0, Width, Height,
++                   GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, sten);
++      /* find min/max for converting stencil to grayscale */
++      for (i = 0; i < Width * Height; i++) {
++         if (sten[i] < min)
++            min = sten[i];
++         if (sten[i] > max)
++            max = sten[i];
++      }
++      if (min == max)
++         step = 0;
++      else
++         step = 255.0 / (float) (max - min);
++      for (i = 0; i < Width * Height; i++) {
++         image[i*4+0] =
++         image[i*4+1] =
++         image[i*4+2] = (GLint) ((sten[i] - min) * step);
++         image[i*4+3] = 255;
++      }
++      free(sten);
++   }
++
++   glXMakeCurrent(dpy, dstWin, Context);
++   glWindowPos2iARB(0, 0);
++   glDrawBuffer(GL_FRONT);
++   glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, image);
++   glFlush();
++
++   free(image);
++}
++
++
++static void
++set_window_title(Display *dpy, Window win, const char *title)
++{
++   XSizeHints sizehints;
++   sizehints.flags = 0;
++   XSetStandardProperties(dpy, win, title, title,
++                          None, (char **)NULL, 0, &sizehints);
++}
++
++
++static Window
++make_gl_window(Display *dpy, XVisualInfo *visinfo, int width, int height)
++{
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   int x = 0, y = 0;
++   char *name = NULL;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, x, y, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   return win;
++}
++
++
++static void
++update_window_title(Display *dpy, Window win)
++{
++   char title[1000], *buf;
++
++   switch (Buffer) {
++   case Z_BUFFER:
++      buf = "Z";
++      break;
++   case STENCIL_BUFFER:
++      buf = "Stencil";
++      break;
++   case BACK_BUFFER:
++      buf = "Back";
++      break;
++   case FRONT_BUFFER:
++      buf = "Front";
++      break;
++   default:
++      buf = "";
++   }
++
++   sprintf(title, "glxsnoop window 0x%x (%s buffer)", (int) WindowID, buf);
++
++   set_window_title(dpy, win, title);
++}
++
++
++static void
++keypress(Display *dpy, Window win, char key)
++{
++   switch (key) {
++   case 27:
++      /* escape */
++      exit(0);
++      break;
++   case 's':
++      Buffer = STENCIL_BUFFER;
++      break;
++   case 'z':
++      Buffer = Z_BUFFER;
++      break;
++   case 'f':
++      Buffer = FRONT_BUFFER;
++      break;
++   case 'b':
++      Buffer = BACK_BUFFER;
++      break;
++   default:
++      return;
++   }
++
++   update_window_title(dpy, win);
++   redraw(dpy, WindowID, win);
++}
++
++
++static void
++event_loop(Display *dpy, Window win)
++{
++   XEvent event;
++
++   while (1) {
++      XNextEvent( dpy, &event );
++
++      switch (event.type) {
++      case Expose:
++         redraw(dpy, WindowID, win);
++         break;
++      case ConfigureNotify:
++         /*resize( event.xconfigure.width, event.xconfigure.height );*/
++         break;
++      case KeyPress:
++         {
++            char buffer[10];
++            int r, code;
++            code = XLookupKeysym(&event.xkey, 0);
++            if (code == XK_Left) {
++            }
++            else {
++               r = XLookupString(&event.xkey, buffer, sizeof(buffer),
++                                 NULL, NULL);
++               keypress(dpy, win, buffer[0]);
++            }
++         }
++      default:
++         /* nothing */
++         ;
++      }
++   }
++}
++
++
++static VisualID
++get_window_visualid(Display *dpy, Window win)
++{
++   XWindowAttributes attr;
++
++   if (XGetWindowAttributes(dpy, win, &attr)) {
++      return attr.visual->visualid;
++   }
++   else {
++      return 0;
++   }
++}
++
++
++static void
++get_window_size(Display *dpy, Window win, int *w, int *h)
++{
++   XWindowAttributes attr;
++
++   if (XGetWindowAttributes(dpy, win, &attr)) {
++      *w = attr.width;
++      *h = attr.height;
++   }
++   else {
++      *w = *h = 0;
++   }
++}
++
++
++static XVisualInfo *
++visualid_to_visualinfo(Display *dpy, VisualID vid)
++{
++   XVisualInfo *vinfo, templ;
++   long mask;
++   int n;
++
++   templ.visualid = vid;
++   mask = VisualIDMask;
++
++   vinfo = XGetVisualInfo(dpy, mask, &templ, &n);
++   return vinfo;
++}
++
++
++static void
++key_usage(void)
++{
++   printf("Keyboard:\n");
++   printf("  z - display Z buffer\n");
++   printf("  s - display stencil buffer\n");
++   printf("  f - display front color buffer\n");
++   printf("  b - display back buffer\n");
++}
++
++
++static void
++usage(void)
++{
++   printf("Usage: glxsnoop [-display dpy] windowID\n");
++   key_usage();
++}
++
++
++static void
++parse_opts(int argc, char *argv[])
++{
++   int i;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-h") == 0) {
++         usage();
++         exit(0);
++      }
++      else if (strcmp(argv[i], "-display") == 0) {
++         DisplayName = argv[i + 1];
++         i++;
++      }
++      else {
++         if (argv[i][0] == '0' && argv[i][1] == 'x') {
++            /* hex */
++            WindowID = strtol(argv[i], NULL, 16);
++         }
++         else {
++            WindowID = atoi(argv[i]);
++         }
++         break;
++      }
++   }
++
++   if (!WindowID) {
++      usage();
++      exit(0);
++   }
++}
++
++
++int
++main( int argc, char *argv[] )
++{
++   Display *dpy;
++   VisualID vid;
++   XVisualInfo *visinfo;
++   Window win;
++
++   parse_opts(argc, argv);
++
++   key_usage();
++
++   dpy = XOpenDisplay(DisplayName);
++
++   /* find the VisualID for the named window */
++   vid = get_window_visualid(dpy, WindowID);
++   get_window_size(dpy, WindowID, &Width, &Height);
++
++   visinfo = visualid_to_visualinfo(dpy, vid);
++
++   Context = glXCreateContext( dpy, visinfo, NULL, True );
++   if (!Context) {
++      printf("Error: glXCreateContext failed\n");
++      exit(1);
++   }
++
++   win = make_gl_window(dpy, visinfo, Width, Height);
++   XMapWindow(dpy, win);
++   update_window_title(dpy, win);
++
++   event_loop( dpy, win );
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/glxswapcontrol.c Mesa-7.8.1.patched/progs/xdemos/glxswapcontrol.c
+--- Mesa-7.8.1/progs/xdemos/glxswapcontrol.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/glxswapcontrol.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,893 @@
++/*
++ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++/*
++ * This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
++ * Port by Brian Paul  23 March 2001
++ *
++ * Modified by Ian Romanick <idr@us.ibm.com> 09 April 2003 to support
++ * GLX_{MESA,SGI}_swap_control and GLX_OML_sync_control.
++ *
++ * Command line options:
++ *    -display       Name of the display to use.
++ *    -info          print GL implementation information
++ *    -swap N        Attempt to set the swap interval to 1/N second
++ *    -forcegetrate  Get the display refresh rate even if the required GLX
++ *                   extension is not supported.
++ */
++
++
++#include <math.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <X11/Xlib.h>
++#include <X11/keysym.h>
++#ifndef __VMS
++/*# include <stdint.h>*/
++#endif
++# define GLX_GLXEXT_PROTOTYPES
++#include <GL/gl.h>
++#include <GL/glx.h>
++
++#ifndef GLX_MESA_swap_control
++typedef GLint ( * PFNGLXSWAPINTERVALMESAPROC) (unsigned interval);
++typedef GLint ( * PFNGLXGETSWAPINTERVALMESAPROC) ( void );
++#endif
++
++#if !defined( GLX_OML_sync_control ) && defined( _STDINT_H )
++#define GLX_OML_sync_control 1
++typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
++#endif
++
++#ifndef GLX_MESA_swap_frame_usage
++#define GLX_MESA_swap_frame_usage 1
++typedef int ( * PFNGLXGETFRAMEUSAGEMESAPROC) (Display *dpy, GLXDrawable drawable, float * usage );
++#endif
++
++#define BENCHMARK
++
++PFNGLXGETFRAMEUSAGEMESAPROC get_frame_usage = NULL;
++
++#ifdef BENCHMARK
++
++/* XXX this probably isn't very portable */
++
++#include <sys/time.h>
++#include <unistd.h>
++
++#define NUL '\0'
++
++/* return current time (in seconds) */
++static int
++current_time(void)
++{
++   struct timeval tv;
++#ifdef __VMS
++   (void) gettimeofday(&tv, NULL );
++#else
++   struct timezone tz;
++   (void) gettimeofday(&tv, &tz);
++#endif
++   return (int) tv.tv_sec;
++}
++
++#else /*BENCHMARK*/
++
++/* dummy */
++static int
++current_time(void)
++{
++   return 0;
++}
++
++#endif /*BENCHMARK*/
++
++
++
++#ifndef M_PI
++#define M_PI 3.14159265
++#endif
++
++
++static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
++static GLint gear1, gear2, gear3;
++static GLfloat angle = 0.0;
++
++static GLboolean has_OML_sync_control = GL_FALSE;
++static GLboolean has_SGI_swap_control = GL_FALSE;
++static GLboolean has_MESA_swap_control = GL_FALSE;
++static GLboolean has_MESA_swap_frame_usage = GL_FALSE;
++
++static char ** extension_table = NULL;
++static unsigned num_extensions;
++
++static GLboolean use_ztrick = GL_FALSE;
++static GLfloat aspectX = 1.0f, aspectY = 1.0f;
++
++/*
++ *
++ *  Draw a gear wheel.  You'll probably want to call this function when
++ *  building a display list since we do a lot of trig here.
++ * 
++ *  Input:  inner_radius - radius of hole at center
++ *          outer_radius - radius at center of teeth
++ *          width - width of gear
++ *          teeth - number of teeth
++ *          tooth_depth - depth of tooth
++ */
++static void
++gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
++     GLint teeth, GLfloat tooth_depth)
++{
++   GLint i;
++   GLfloat r0, r1, r2;
++   GLfloat angle, da;
++   GLfloat u, v, len;
++
++   r0 = inner_radius;
++   r1 = outer_radius - tooth_depth / 2.0;
++   r2 = outer_radius + tooth_depth / 2.0;
++
++   da = 2.0 * M_PI / teeth / 4.0;
++
++   glShadeModel(GL_FLAT);
++
++   glNormal3f(0.0, 0.0, 1.0);
++
++   /* draw front face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw front sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++   }
++   glEnd();
++
++   glNormal3f(0.0, 0.0, -1.0);
++
++   /* draw back face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    -width * 0.5);
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw back sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++   }
++   glEnd();
++
++   /* draw outward faces of teeth */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      u = r2 * cos(angle + da) - r1 * cos(angle);
++      v = r2 * sin(angle + da) - r1 * sin(angle);
++      len = sqrt(u * u + v * v);
++      u /= len;
++      v /= len;
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
++      v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++   }
++
++   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
++   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
++
++   glEnd();
++
++   glShadeModel(GL_SMOOTH);
++
++   /* draw inside radius cylinder */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glNormal3f(-cos(angle), -sin(angle), 0.0);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++   }
++   glEnd();
++}
++
++
++static void
++draw(void)
++{
++   if ( use_ztrick ) {
++      static GLboolean flip = GL_FALSE;
++      static const GLfloat vert[4][3] = {
++	 { -1, -1, -0.999 },
++	 {  1, -1, -0.999 },
++	 {  1,  1, -0.999 },
++	 { -1,  1, -0.999 }
++      };
++      static const GLfloat col[4][3] = {
++	 { 1.0, 0.6, 0.0 },
++	 { 1.0, 0.6, 0.0 },
++	 { 0.0, 0.0, 0.0 },
++	 { 0.0, 0.0, 0.0 },
++      };
++      
++      if ( flip ) {
++	 glDepthRange(0, 0.5);
++	 glDepthFunc(GL_LEQUAL);
++      }
++      else {
++	 glDepthRange(1.0, 0.4999);
++	 glDepthFunc(GL_GEQUAL);
++      }
++
++      flip = !flip;
++
++      /* The famous Quake "Z trick" only works when the whole screen is
++       * re-drawn each frame.
++       */
++
++      glMatrixMode(GL_MODELVIEW);
++      glLoadIdentity();
++      glMatrixMode(GL_PROJECTION);
++      glLoadIdentity();
++      glOrtho(-1, 1, -1, 1, -1, 1);
++      glDisable(GL_LIGHTING);
++      glShadeModel(GL_SMOOTH);
++
++      glEnableClientState( GL_VERTEX_ARRAY );
++      glEnableClientState( GL_COLOR_ARRAY );
++      glVertexPointer( 3, GL_FLOAT, 0, vert );
++      glColorPointer( 3, GL_FLOAT, 0, col );
++      glDrawArrays( GL_POLYGON, 0, 4 );
++      glDisableClientState( GL_COLOR_ARRAY );
++      glDisableClientState( GL_VERTEX_ARRAY );
++
++      glMatrixMode(GL_PROJECTION);
++      glLoadIdentity();
++      glFrustum(-aspectX, aspectX, -aspectY, aspectY, 5.0, 60.0);
++
++      glEnable(GL_LIGHTING);
++
++      glMatrixMode(GL_MODELVIEW);
++      glLoadIdentity();
++      glTranslatef(0.0, 0.0, -45.0);
++   }
++   else {
++      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++   }
++
++   glPushMatrix();
++   glRotatef(view_rotx, 1.0, 0.0, 0.0);
++   glRotatef(view_roty, 0.0, 1.0, 0.0);
++   glRotatef(view_rotz, 0.0, 0.0, 1.0);
++
++   glPushMatrix();
++   glTranslatef(-3.0, -2.0, 0.0);
++   glRotatef(angle, 0.0, 0.0, 1.0);
++   glCallList(gear1);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(3.1, -2.0, 0.0);
++   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
++   glCallList(gear2);
++   glPopMatrix();
++
++   glPushMatrix();
++   glTranslatef(-3.1, 4.2, 0.0);
++   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
++   glCallList(gear3);
++   glPopMatrix();
++
++   glPopMatrix();
++}
++
++
++/* new window size or exposure */
++static void
++reshape(int width, int height)
++{
++   if (width > height) {
++      aspectX = (GLfloat) width / (GLfloat) height;
++      aspectY = 1.0;
++   }
++   else {
++      aspectX = 1.0;
++      aspectY = (GLfloat) height / (GLfloat) width;
++   }
++
++   glViewport(0, 0, (GLint) width, (GLint) height);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++
++   glFrustum(-aspectX, aspectX, -aspectY, aspectY, 5.0, 60.0);
++   glMatrixMode(GL_MODELVIEW);
++   glLoadIdentity();
++   glTranslatef(0.0, 0.0, -45.0);
++}
++
++
++static void
++init(void)
++{
++   static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
++   static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
++   static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
++   static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
++
++   glLightfv(GL_LIGHT0, GL_POSITION, pos);
++   glEnable(GL_CULL_FACE);
++   glEnable(GL_LIGHTING);
++   glEnable(GL_LIGHT0);
++   glEnable(GL_DEPTH_TEST);
++
++   /* make the gears */
++   gear1 = glGenLists(1);
++   glNewList(gear1, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
++   gear(1.0, 4.0, 1.0, 20, 0.7);
++   glEndList();
++
++   gear2 = glGenLists(1);
++   glNewList(gear2, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
++   gear(0.5, 2.0, 2.0, 10, 0.7);
++   glEndList();
++
++   gear3 = glGenLists(1);
++   glNewList(gear3, GL_COMPILE);
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
++   gear(1.3, 2.0, 0.5, 10, 0.7);
++   glEndList();
++
++   glEnable(GL_NORMALIZE);
++}
++
++
++/**
++ * Remove window border/decorations.
++ */
++static void
++no_border( Display *dpy, Window w)
++{
++   static const unsigned MWM_HINTS_DECORATIONS = (1 << 1);
++   static const int PROP_MOTIF_WM_HINTS_ELEMENTS = 5;
++
++   typedef struct
++   {
++      unsigned long       flags;
++      unsigned long       functions;
++      unsigned long       decorations;
++      long                inputMode;
++      unsigned long       status;
++   } PropMotifWmHints;
++
++   PropMotifWmHints motif_hints;
++   Atom prop, proptype;
++   unsigned long flags = 0;
++
++   /* setup the property */
++   motif_hints.flags = MWM_HINTS_DECORATIONS;
++   motif_hints.decorations = flags;
++
++   /* get the atom for the property */
++   prop = XInternAtom( dpy, "_MOTIF_WM_HINTS", True );
++   if (!prop) {
++      /* something went wrong! */
++      return;
++   }
++
++   /* not sure this is correct, seems to work, XA_WM_HINTS didn't work */
++   proptype = prop;
++
++   XChangeProperty( dpy, w,                         /* display, window */
++                    prop, proptype,                 /* property, type */
++                    32,                             /* format: 32-bit datums */
++                    PropModeReplace,                /* mode */
++                    (unsigned char *) &motif_hints, /* data */
++                    PROP_MOTIF_WM_HINTS_ELEMENTS    /* nelements */
++                  );
++}
++
++
++/*
++ * Create an RGB, double-buffered window.
++ * Return the window and context handles.
++ */
++static void
++make_window( Display *dpy, const char *name,
++             int x, int y, int width, int height, GLboolean fullscreen,
++             Window *winRet, GLXContext *ctxRet)
++{
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    GLX_DEPTH_SIZE, 1,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   GLXContext ctx;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   if (fullscreen) {
++      x = y = 0;
++      width = DisplayWidth( dpy, scrnum );
++      height = DisplayHeight( dpy, scrnum );
++   }
++
++   visinfo = glXChooseVisual( dpy, scrnum, attrib );
++   if (!visinfo) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   if (fullscreen)
++      no_border(dpy, win);
++
++   ctx = glXCreateContext( dpy, visinfo, NULL, True );
++   if (!ctx) {
++      printf("Error: glXCreateContext failed\n");
++      exit(1);
++   }
++
++   XFree(visinfo);
++
++   *winRet = win;
++   *ctxRet = ctx;
++}
++
++
++static void
++event_loop(Display *dpy, Window win)
++{
++   float  frame_usage = 0.0;
++
++   while (1) {
++      while (XPending(dpy) > 0) {
++         XEvent event;
++         XNextEvent(dpy, &event);
++         switch (event.type) {
++	 case Expose:
++            /* we'll redraw below */
++	    break;
++	 case ConfigureNotify:
++	    reshape(event.xconfigure.width, event.xconfigure.height);
++	    break;
++         case KeyPress:
++            {
++               char buffer[10];
++               int r, code;
++               code = XLookupKeysym(&event.xkey, 0);
++               if (code == XK_Left) {
++                  view_roty += 5.0;
++               }
++               else if (code == XK_Right) {
++                  view_roty -= 5.0;
++               }
++               else if (code == XK_Up) {
++                  view_rotx += 5.0;
++               }
++               else if (code == XK_Down) {
++                  view_rotx -= 5.0;
++               }
++               else {
++                  r = XLookupString(&event.xkey, buffer, sizeof(buffer),
++                                    NULL, NULL);
++                  if (buffer[0] == 27) {
++                     /* escape */
++                     return;
++                  }
++               }
++            }
++         }
++      }
++
++      /* next frame */
++      angle += 2.0;
++
++      draw();
++
++      glXSwapBuffers(dpy, win);
++
++      if ( get_frame_usage != NULL ) {
++	 GLfloat   temp;
++	 
++	 (*get_frame_usage)( dpy, win, & temp );
++	 frame_usage += temp;
++      }
++
++      /* calc framerate */
++      {
++         static int t0 = -1;
++         static int frames = 0;
++         int t = current_time();
++
++         if (t0 < 0)
++            t0 = t;
++
++         frames++;
++
++         if (t - t0 >= 5.0) {
++            GLfloat seconds = t - t0;
++            GLfloat fps = frames / seconds;
++	    if ( get_frame_usage != NULL ) {
++	       printf("%d frames in %3.1f seconds = %6.3f FPS (%3.1f%% usage)\n",
++		      frames, seconds, fps,
++		      (frame_usage * 100.0) / (float) frames );
++	    }
++	    else {
++	       printf("%d frames in %3.1f seconds = %6.3f FPS\n",
++		      frames, seconds, fps);
++	    }
++
++            t0 = t;
++            frames = 0;
++	    frame_usage = 0.0;
++         }
++      }
++   }
++}
++
++
++/**
++ * Display the refresh rate of the display using the GLX_OML_sync_control
++ * extension.
++ */
++static void
++show_refresh_rate( Display * dpy )
++{
++#if defined(GLX_OML_sync_control) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
++   PFNGLXGETMSCRATEOMLPROC  get_msc_rate;
++   int32_t  n;
++   int32_t  d;
++
++   get_msc_rate = (PFNGLXGETMSCRATEOMLPROC) glXGetProcAddressARB( (const GLubyte *) "glXGetMscRateOML" );
++   if ( get_msc_rate != NULL ) {
++      (*get_msc_rate)( dpy, glXGetCurrentDrawable(), &n, &d );
++      printf( "refresh rate: %.1fHz\n", (float) n / d );
++      return;
++   }
++#endif
++   printf( "glXGetMscRateOML not supported.\n" );
++}
++
++
++/**
++ * Fill in the table of extension strings from a supplied extensions string
++ * (as returned by glXQueryExtensionsString).
++ *
++ * \param string   String of GLX extensions.
++ * \sa is_extension_supported
++ */
++static void
++make_extension_table( const char * string )
++{
++   char ** string_tab;
++   unsigned  num_strings;
++   unsigned  base;
++   unsigned  idx;
++   unsigned  i;
++      
++   /* Count the number of spaces in the string.  That gives a base-line
++    * figure for the number of extension in the string.
++    */
++   
++   num_strings = 1;
++   for ( i = 0 ; string[i] != NUL ; i++ ) {
++      if ( string[i] == ' ' ) {
++	 num_strings++;
++      }
++   }
++   
++   string_tab = (char **) malloc( sizeof( char * ) * num_strings );
++   if ( string_tab == NULL ) {
++      return;
++   }
++
++   base = 0;
++   idx = 0;
++
++   while ( string[ base ] != NUL ) {
++      /* Determine the length of the next extension string.
++       */
++
++      for ( i = 0 
++	    ; (string[ base + i ] != NUL) && (string[ base + i ] != ' ')
++	    ; i++ ) {
++	 /* empty */ ;
++      }
++
++      if ( i > 0 ) {
++	 /* If the string was non-zero length, add it to the table.  We
++	  * can get zero length strings if there is a space at the end of
++	  * the string or if there are two (or more) spaces next to each
++	  * other in the string.
++	  */
++
++	 string_tab[ idx ] = malloc( sizeof( char ) * (i + 1) );
++	 if ( string_tab[ idx ] == NULL ) {
++	    return;
++	 }
++
++	 (void) memcpy( string_tab[ idx ], & string[ base ], i );
++	 string_tab[ idx ][i] = NUL;
++	 idx++;
++      }
++
++
++      /* Skip to the start of the next extension string.
++       */
++
++      for ( base += i
++	    ; (string[ base ] == ' ') && (string[ base ] != NUL) 
++	    ; base++ ) {
++	 /* empty */ ;
++      }
++   }
++
++   extension_table = string_tab;
++   num_extensions = idx;
++}
++
++    
++/**
++ * Determine of an extension is supported.  The extension string table
++ * must have already be initialized by calling \c make_extension_table.
++ * 
++ * \praram ext  Extension to be tested.
++ * \return GL_TRUE of the extension is supported, GL_FALSE otherwise.
++ * \sa make_extension_table
++ */
++static GLboolean
++is_extension_supported( const char * ext )
++{
++   unsigned   i;
++   
++   for ( i = 0 ; i < num_extensions ; i++ ) {
++      if ( strcmp( ext, extension_table[i] ) == 0 ) {
++	 return GL_TRUE;
++      }
++   }
++   
++   return GL_FALSE;
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   Display *dpy;
++   Window win;
++   GLXContext ctx;
++   char *dpyName = NULL;
++   int swap_interval = 1;
++   GLboolean do_swap_interval = GL_FALSE;
++   GLboolean force_get_rate = GL_FALSE;
++   GLboolean fullscreen = GL_FALSE;
++   GLboolean printInfo = GL_FALSE;
++   int i;
++   PFNGLXSWAPINTERVALMESAPROC set_swap_interval = NULL;
++   PFNGLXGETSWAPINTERVALMESAPROC get_swap_interval = NULL;
++   int width = 300, height = 300;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0 && i + 1 < argc) {
++         dpyName = argv[i+1];
++         i++;
++      }
++      else if (strcmp(argv[i], "-info") == 0) {
++         printInfo = GL_TRUE;
++      }
++      else if (strcmp(argv[i], "-swap") == 0 && i + 1 < argc) {
++	 swap_interval = atoi( argv[i+1] );
++	 do_swap_interval = GL_TRUE;
++	 i++;
++      }
++      else if (strcmp(argv[i], "-forcegetrate") == 0) {
++	 /* This option was put in because some DRI drivers don't support the
++	  * full GLX_OML_sync_control extension, but they do support
++	  * glXGetMscRateOML.
++	  */
++	 force_get_rate = GL_TRUE;
++      }
++      else if (strcmp(argv[i], "-fullscreen") == 0) {
++         fullscreen = GL_TRUE;
++      }
++      else if (strcmp(argv[i], "-ztrick") == 0) {
++	 use_ztrick = GL_TRUE;
++      }
++      else if (strcmp(argv[i], "-help") == 0) {
++         printf("Usage:\n");
++         printf("  gears [options]\n");
++         printf("Options:\n");
++         printf("  -help                   Print this information\n");
++         printf("  -display displayName    Specify X display\n");
++         printf("  -info                   Display GL information\n");
++         printf("  -swap N                 Swap no more than once per N vertical refreshes\n");
++         printf("  -forcegetrate           Try to use glXGetMscRateOML function\n");
++         printf("  -fullscreen             Full-screen window\n");
++         return 0;
++      }
++   }
++
++   dpy = XOpenDisplay(dpyName);
++   if (!dpy) {
++      printf("Error: couldn't open display %s\n", XDisplayName(dpyName));
++      return -1;
++   }
++
++   make_window(dpy, "glxgears", 0, 0, width, height, fullscreen, &win, &ctx);
++   XMapWindow(dpy, win);
++   glXMakeCurrent(dpy, win, ctx);
++
++   make_extension_table( (char *) glXQueryExtensionsString(dpy,DefaultScreen(dpy)) );
++   has_OML_sync_control = is_extension_supported( "GLX_OML_sync_control" );
++   has_SGI_swap_control = is_extension_supported( "GLX_SGI_swap_control" );
++   has_MESA_swap_control = is_extension_supported( "GLX_MESA_swap_control" );
++   has_MESA_swap_frame_usage = is_extension_supported( "GLX_MESA_swap_frame_usage" );
++
++   if ( has_MESA_swap_control ) {
++      set_swap_interval = (PFNGLXSWAPINTERVALMESAPROC) glXGetProcAddressARB( (const GLubyte *) "glXSwapIntervalMESA" );
++      get_swap_interval = (PFNGLXGETSWAPINTERVALMESAPROC) glXGetProcAddressARB( (const GLubyte *) "glXGetSwapIntervalMESA" );
++   }
++   else if ( has_SGI_swap_control ) {
++      set_swap_interval = (PFNGLXSWAPINTERVALMESAPROC) glXGetProcAddressARB( (const GLubyte *) "glXSwapIntervalSGI" );
++   }
++
++
++   if ( has_MESA_swap_frame_usage ) {
++      get_frame_usage = (PFNGLXGETFRAMEUSAGEMESAPROC)  glXGetProcAddressARB( (const GLubyte *) "glXGetFrameUsageMESA" );
++   }
++      
++
++   if (printInfo) {
++      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
++      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
++      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
++      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
++      if ( has_OML_sync_control || force_get_rate ) {
++	 show_refresh_rate( dpy );
++      }
++
++      if ( get_swap_interval != NULL ) {
++	 printf("Default swap interval = %d\n", (*get_swap_interval)() );
++      }
++   }
++
++   if ( do_swap_interval ) {
++      if ( set_swap_interval != NULL ) {
++	 if ( ((swap_interval == 0) && !has_MESA_swap_control)
++	      || (swap_interval < 0) ) {
++	    printf( "Swap interval must be non-negative or greater than zero "
++		    "if GLX_MESA_swap_control is not supported.\n" );
++	 }
++	 else {
++	    (*set_swap_interval)( swap_interval );
++	 }
++
++	 if ( printInfo && (get_swap_interval != NULL) ) {
++	    printf("Current swap interval = %d\n", (*get_swap_interval)() );
++	 }
++      }
++      else {
++	 printf("Unable to set swap-interval.  Neither GLX_SGI_swap_control "
++		"nor GLX_MESA_swap_control are supported.\n" );
++      }
++   }
++
++   init();
++
++   /* Set initial projection/viewing transformation.
++    * same as glxgears.c
++    */
++   reshape(width, height);
++
++   event_loop(dpy, win);
++
++   glXDestroyContext(dpy, ctx);
++   XDestroyWindow(dpy, win);
++   XCloseDisplay(dpy);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/ipc.c Mesa-7.8.1.patched/progs/xdemos/ipc.c
+--- Mesa-7.8.1/progs/xdemos/ipc.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/ipc.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,264 @@
++/* Copyright (c) 2003 Tungsten Graphics, Inc.
++ * 
++ * 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, the Tungsten
++ * Graphics splash screen, 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.
++ */
++
++/*
++ * Simple IPC API
++ * Brian Paul
++ */
++
++
++#include <assert.h>
++#include <stdio.h>
++#include <string.h>
++#include <sys/types.h>
++#include <netinet/in.h>
++#include <netinet/tcp.h>
++#include <arpa/inet.h>
++#include <netdb.h>
++#include <unistd.h>
++#include <sys/socket.h>
++#include "ipc.h"
++
++#if defined(IRIX) || defined(irix)
++typedef int socklen_t;
++#endif
++
++#define NO_DELAY 1
++
++#define DEFAULT_MASTER_PORT 7011
++
++
++/*
++ * Return my hostname in <nameOut>.
++ * Return 1 for success, 0 for error.
++ */
++int
++MyHostName(char *nameOut, int maxNameLength)
++{
++    int k = gethostname(nameOut, maxNameLength);
++    return k==0;
++}
++
++
++/*
++ * Create a socket attached to a port.  Later, we can call AcceptConnection
++ * on the socket returned from this function.
++ * Return the new socket number or -1 if error.
++ */
++int
++CreatePort(int *port)
++{
++    char hostname[1000];
++    struct sockaddr_in servaddr;
++    struct hostent *hp;
++    int so_reuseaddr = 1;
++    int tcp_nodelay = 1;
++    int sock, k;
++
++    /* create socket */
++    sock = socket(AF_INET, SOCK_STREAM, 0);
++    assert(sock > 2);
++
++    /* get my host name */
++    k = gethostname(hostname, 1000);
++    assert(k == 0);
++
++    /* get hostent info */
++    hp = gethostbyname(hostname);
++    assert(hp);
++
++    /* initialize the servaddr struct */
++    memset(&servaddr, 0, sizeof(servaddr) );
++    servaddr.sin_family = AF_INET;
++    servaddr.sin_port = htons((unsigned short) (*port));
++    memcpy((char *) &servaddr.sin_addr, hp->h_addr,
++	   sizeof(servaddr.sin_addr));
++
++    /* deallocate when we exit */
++    k = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
++		   (char *) &so_reuseaddr, sizeof(so_reuseaddr));
++    assert(k==0);
++
++    /* send packets immediately */
++#if NO_DELAY
++    k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
++		   (char *) &tcp_nodelay, sizeof(tcp_nodelay));
++    assert(k==0);
++#endif
++
++    if (*port == 0)
++        *port = DEFAULT_MASTER_PORT;
++
++    k = 1;
++    while (k && (*port < 65534)) {
++    	/* bind our address to the socket */
++    	servaddr.sin_port = htons((unsigned short) (*port));
++    	k = bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
++        if (k)
++           *port = *port + 1;
++    }
++
++#if 0
++    printf("###### Real Port: %d\n", *port);
++#endif
++
++    /* listen for connections */
++    k = listen(sock, 100);
++    assert(k == 0);
++
++    return sock;
++}
++
++
++/*
++ * Accept a connection on the named socket.
++ * Return a new socket for the new connection, or -1 if error.
++ */
++int
++AcceptConnection(int socket)
++{
++    struct sockaddr addr;
++    socklen_t addrLen;
++    int newSock;
++
++    addrLen = sizeof(addr);
++    newSock = accept(socket, &addr, &addrLen);
++    if (newSock == 1)
++	return -1;
++    else
++	return newSock;
++}
++
++
++/*
++ * Contact the server running on the given host on the named port.
++ * Return socket number or -1 if error.
++ */
++int
++Connect(const char *hostname, int port)
++{
++    struct sockaddr_in servaddr;
++    struct hostent *hp;
++    int sock, k;
++    int tcp_nodelay = 1;
++
++    assert(port);
++
++    sock = socket(AF_INET, SOCK_STREAM, 0);
++    assert(sock >= 0);
++
++    hp = gethostbyname(hostname);
++    assert(hp);
++
++    memset(&servaddr, 0, sizeof(servaddr));
++    servaddr.sin_family = AF_INET;
++    servaddr.sin_port = htons((unsigned short) port);
++    memcpy((char *) &servaddr.sin_addr, hp->h_addr, sizeof(servaddr.sin_addr));
++
++    k = connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
++    if (k != 0) {
++       perror("Connect:");
++       return -1;
++    }
++
++#if NO_DELAY
++    /* send packets immediately */
++    k = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
++		   (char *) &tcp_nodelay, sizeof(tcp_nodelay));
++    assert(k==0);
++#endif
++
++    return sock;
++}
++
++
++void
++CloseSocket(int socket)
++{
++    close(socket);
++}
++
++
++int
++SendData(int socket, const void *data, int bytes)
++{
++    int sent = 0;
++    int b;
++
++    while (sent < bytes) {
++        b = write(socket, (char *) data + sent, bytes - sent);
++        if (b <= 0)
++            return -1; /* something broke */
++        sent += b;
++    }
++    return sent;
++}
++
++
++int
++ReceiveData(int socket, void *data, int bytes)
++{
++    int received = 0, b;
++
++    while (received < bytes) {
++        b = read(socket, (char *) data + received, bytes - received);
++        if (b <= 0)
++            return -1;
++        received += b;
++    }
++    return received;
++}
++
++
++int
++SendString(int socket, const char *str)
++{
++    const int len = strlen(str);
++    int sent, b;
++
++    /* first, send a 4-byte length indicator */
++    b = write(socket, &len, sizeof(len));
++    if (b <= 0)
++	return -1;
++
++    sent = SendData(socket, str, len);
++    assert(sent == len);
++    return sent;
++}
++
++
++int
++ReceiveString(int socket, char *str, int maxLen)
++{
++    int len, received, b;
++
++    /* first, read 4 bytes to see how long of string to receive */
++    b = read(socket, &len, sizeof(len));
++    if (b <= 0)
++	return -1;
++
++    assert(len <= maxLen);  /* XXX fix someday */
++    assert(len >= 0);
++    received = ReceiveData(socket, str, len);
++    assert(received != -1);
++    assert(received == len);
++    str[len] = 0;
++    return received;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/ipc.h Mesa-7.8.1.patched/progs/xdemos/ipc.h
+--- Mesa-7.8.1/progs/xdemos/ipc.h	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/ipc.h	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,16 @@
++#ifndef IPC_H
++#define IPC_H
++
++
++extern int MyHostName(char *nameOut, int maxNameLength);
++extern int CreatePort(int *port);
++extern int AcceptConnection(int socket);
++extern int Connect(const char *hostname, int port);
++extern void CloseSocket(int socket);
++extern int SendData(int socket, const void *data, int bytes);
++extern int ReceiveData(int socket, void *data, int bytes);
++extern int SendString(int socket, const char *str);
++extern int ReceiveString(int socket, char *str, int maxLen);
++
++
++#endif /* IPC_H */
+diff -Naurp Mesa-7.8.1/progs/xdemos/Makefile Mesa-7.8.1.patched/progs/xdemos/Makefile
+--- Mesa-7.8.1/progs/xdemos/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/Makefile	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,103 @@
++# progs/xdemos/Makefile
++
++TOP = ../..
++include $(TOP)/configs/current
++
++
++INCDIR = $(TOP)/include
++
++LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
++
++# Add X11 and pthread libs to satisfy GNU gold.
++APP_LIB_DEPS += -lX11 -lpthread
++
++LIBS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) -L$(libdir) $(APP_LIB_DEPS)
++
++PROGS = \
++	corender \
++	glsync \
++	glthreads \
++	glxdemo \
++	glxgears \
++	glxgears_fbconfig \
++	glxgears_pixmap \
++	glxcontexts \
++	glxheads \
++	glxinfo \
++	glxpixmap \
++	glxpbdemo \
++	glxsnoop \
++	glxswapcontrol \
++	manywin \
++	msctest \
++	multictx \
++	offset \
++	omlsync \
++	overlay \
++	pbinfo \
++	pbdemo \
++	sharedtex \
++        sharedtex_mt \
++	texture_from_pixmap \
++	wincopy \
++	xfont \
++	xrotfontdemo
++
++# Don't build these by default because of extra library dependencies
++EXTRA_PROGS = \
++	shape \
++	yuvrect_client \
++	xdemo
++
++
++
++##### RULES #####
++
++.o: $(LIB_DEP)
++	$(APP_CC) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
++
++.c.o:
++	$(APP_CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) $< -c -o $@
++
++
++##### TARGETS #####
++
++default: $(PROGS)
++
++$(PROGS): $(PROGS:%=%.o)
++
++extra: $(EXTRA_PROGS)
++
++
++clean:
++	-rm -f $(PROGS) $(EXTRA_PROGS)
++	-rm -f *.o *~
++
++
++# special cases
++pbutil.o: pbutil.h
++pbinfo.o: pbutil.h
++pbinfo: pbinfo.o pbutil.o
++	$(APP_CC) $(CFLAGS) $(LDFLAGS) pbinfo.o pbutil.o $(LIBS) -o $@
++
++pbdemo.o: pbutil.h
++pbdemo: pbdemo.o pbutil.o
++	$(APP_CC) $(CFLAGS) $(LDFLAGS) pbdemo.o pbutil.o $(LIBS) -o $@
++
++glxgears_fbconfig.o: pbutil.h
++glxgears_fbconfig: glxgears_fbconfig.o pbutil.o
++	$(APP_CC) $(CFLAGS) $(LDFLAGS) glxgears_fbconfig.o pbutil.o $(LIBS) -o $@
++
++xuserotfont.o: xuserotfont.h
++xrotfontdemo.o: xuserotfont.h
++xrotfontdemo: xrotfontdemo.o xuserotfont.o
++	$(APP_CC) $(CFLAGS) $(LDFLAGS) xrotfontdemo.o xuserotfont.o $(LIBS) -o $@
++
++ipc.o: ipc.h
++corender.o: ipc.h
++corender: corender.o ipc.o
++	$(APP_CC) $(CFLAGS) $(LDFLAGS) corender.o ipc.o $(LIBS) -o $@
++
++yuvrect_client: yuvrect_client.o
++	$(APP_CC) $(CFLAGS) $< $(LDFLAGS) $(LIBS) -l$(GLU_LIB) -o $@
++
+diff -Naurp Mesa-7.8.1/progs/xdemos/manywin.c Mesa-7.8.1.patched/progs/xdemos/manywin.c
+--- Mesa-7.8.1/progs/xdemos/manywin.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/manywin.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,421 @@
++/*
++ * Create N GLX windows/contexts and render to them in round-robin order.
++ * Also, have the contexts share all texture objects.
++ * Press 'd' to delete a texture, 'u' to unbind it.
++ *
++ * Copyright (C) 2000  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <assert.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <X11/keysym.h>
++
++
++/*
++ * Each display/window/context:
++ */
++struct head {
++   char DisplayName[1000];
++   Display *Dpy;
++   Window Win;
++   GLXContext Context;
++   float Angle;
++   char Renderer[1000];
++   char Vendor[1000];
++   char Version[1000];
++};
++
++
++#define MAX_HEADS 200
++static struct head Heads[MAX_HEADS];
++static int NumHeads = 0;
++static GLboolean SwapSeparate = GL_TRUE;
++static GLuint TexObj = 0;
++
++
++static void
++Error(const char *display, const char *msg)
++{
++   fprintf(stderr, "Error on display %s - %s\n", XDisplayName(display), msg);
++   exit(1);
++}
++
++
++static struct head *
++AddHead(const char *displayName, const char *name)
++{
++   Display *dpy;
++   Window win;
++   GLXContext ctx;
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   XVisualInfo *visinfo;
++   int width = 90, height = 90;
++   int xpos = 0, ypos = 0;
++
++   if (NumHeads >= MAX_HEADS)
++      return NULL;
++
++   dpy = XOpenDisplay(displayName);
++   if (!dpy) {
++      Error(displayName, "Unable to open display");
++      return NULL;
++   }
++
++   scrnum = DefaultScreen(dpy);
++   root = RootWindow(dpy, scrnum);
++
++   visinfo = glXChooseVisual(dpy, scrnum, attrib);
++   if (!visinfo) {
++      Error(displayName, "Unable to find RGB, double-buffered visual");
++      return NULL;
++   }
++
++   /* window attributes */
++   xpos = (NumHeads % 10) * 100;
++   ypos = (NumHeads / 10) * 100;
++   printf("%d, %d\n", xpos, ypos);
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow(dpy, root, xpos, ypos, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr);
++   if (!win) {
++      Error(displayName, "Couldn't create window");
++      return NULL;
++   }
++
++   {
++      XSizeHints sizehints;
++      sizehints.x = xpos;
++      sizehints.y = ypos;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   if (NumHeads == 0) {
++      ctx = glXCreateContext(dpy, visinfo, NULL, True);
++   }
++   else {
++      /* share textures & dlists with 0th context */
++      printf("sharing\n");
++      ctx = glXCreateContext(dpy, visinfo, Heads[0].Context, True);
++   }
++   if (!ctx) {
++      Error(displayName, "Couldn't create GLX context");
++      return NULL;
++   }
++
++   XMapWindow(dpy, win);
++
++   if (!glXMakeCurrent(dpy, win, ctx)) {
++      Error(displayName, "glXMakeCurrent failed");
++      printf("glXMakeCurrent failed in Redraw()\n");
++      return NULL;
++   }
++
++   if (NumHeads == 0) {
++      /* create texture object now */
++      static const GLubyte checker[2][2][4] = {
++         { {255, 255, 255, 255}, {  0,   0,   0, 255} },
++         { {  0,   0,   0,   0}, {255, 255, 255, 255} }
++      };
++      glGenTextures(1, &TexObj);
++      assert(TexObj);
++      glBindTexture(GL_TEXTURE_2D, TexObj);
++      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGB,
++                   GL_UNSIGNED_BYTE, checker);
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
++   }
++   else {
++      /* bind 0th context's texture in this context too */
++      assert(TexObj);
++      glBindTexture(GL_TEXTURE_2D, TexObj);
++   }
++   glEnable(GL_TEXTURE_2D);
++
++   /* save the info for this head */
++   {
++      struct head *h = &Heads[NumHeads];
++      const char * tmp;
++
++      if (strlen(name) + 1 > sizeof(h->DisplayName)) {
++         Error(displayName, "name string overflow");
++         return NULL;
++      }
++      strcpy(h->DisplayName, name);
++
++      h->Dpy = dpy;
++      h->Win = win;
++      h->Context = ctx;
++      h->Angle = 0.0;
++
++      tmp = (char *) glGetString(GL_VERSION);
++      if (strlen(tmp) + 1 > sizeof(h->Version)) {
++         Error(displayName, "GL_VERSION string overflow");
++         return NULL;
++      }
++      strcpy(h->Version, tmp);
++
++      tmp = (char *) glGetString(GL_VENDOR);
++      if (strlen(tmp) + 1 > sizeof(h->Vendor)) {
++         Error(displayName, "GL_VENDOR string overflow");
++         return NULL;
++      }
++      strcpy(h->Vendor, tmp);
++
++      tmp = (char *) glGetString(GL_RENDERER);
++      if (strlen(tmp) + 1 > sizeof(h->Renderer)) {
++         Error(displayName, "GL_RENDERER string overflow");
++         return NULL;
++      }
++      strcpy(h->Renderer, tmp);
++
++      NumHeads++;
++      return &Heads[NumHeads-1];
++   }
++
++}
++
++
++static void
++DestroyHeads(void)
++{
++   int i;
++   for (i = 0; i < NumHeads; i++) {
++      XDestroyWindow(Heads[i].Dpy, Heads[i].Win);
++      glXDestroyContext(Heads[i].Dpy, Heads[i].Context);
++      XCloseDisplay(Heads[i].Dpy);
++   }
++}
++
++
++static void
++Redraw(struct head *h)
++{
++   if (!glXMakeCurrent(h->Dpy, h->Win, h->Context)) {
++      Error(h->DisplayName, "glXMakeCurrent failed");
++      printf("glXMakeCurrent failed in Redraw()\n");
++      return;
++   }
++
++   h->Angle += 1.0;
++
++   glShadeModel(GL_FLAT);
++   glClearColor(0.5, 0.5, 0.5, 1.0);
++   glClear(GL_COLOR_BUFFER_BIT);
++
++   /* draw green triangle */
++   glColor3f(0.0, 1.0, 0.0);
++   glPushMatrix();
++   glRotatef(h->Angle, 0, 0, 1);
++   glBegin(GL_TRIANGLES);
++   glTexCoord2f(0.5, 1.0);   glVertex2f(0, 0.8);
++   glTexCoord2f(0.0, 0.0);   glVertex2f(-0.8, -0.7);
++   glTexCoord2f(1.0, 0.0);   glVertex2f(0.8, -0.7);
++   glEnd();
++   glPopMatrix();
++
++   if (!SwapSeparate)
++      glXSwapBuffers(h->Dpy, h->Win);
++}
++
++
++static void
++Swap(struct head *h)
++{
++   glXSwapBuffers(h->Dpy, h->Win);
++}
++
++
++static void
++Resize(const struct head *h, unsigned int width, unsigned int height)
++{
++   if (!glXMakeCurrent(h->Dpy, h->Win, h->Context)) {
++      Error(h->DisplayName, "glXMakeCurrent failed in Resize()");
++      return;
++   }
++   glFlush();
++   glViewport(0, 0, width, height);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
++}
++
++
++
++static void
++EventLoop(void)
++{
++   while (1) {
++      int i;
++      for (i = 0; i < NumHeads; i++) {
++         struct head *h = &Heads[i];
++         while (XPending(h->Dpy) > 0) {
++            XEvent event;
++            XNextEvent(h->Dpy, &event);
++            if (event.xany.window == h->Win) {
++               switch (event.type) {
++                  case Expose:
++                     Redraw(h);
++                     if (SwapSeparate)
++                        Swap(h);
++                     break;
++                  case ConfigureNotify:
++                     Resize(h, event.xconfigure.width, event.xconfigure.height);
++                     break;
++                  case KeyPress:
++                     {
++                        char buf[100];
++                        KeySym keySym;
++                        XComposeStatus stat;
++                        XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
++                        switch (keySym) {
++                           case XK_Escape:
++                              return;
++                              break;
++                           case XK_d:
++                           case XK_D:
++                              printf("Delete Texture in window %d\n", i);
++                              glXMakeCurrent(h->Dpy, h->Win, h->Context);
++                              glDeleteTextures(1, &TexObj);
++                              break;
++                           case XK_u:
++                           case XK_U:
++                              printf("Unbind Texture in window %d\n", i);
++                              glXMakeCurrent(h->Dpy, h->Win, h->Context);
++                              glBindTexture(GL_TEXTURE_2D, 0);
++                              break;
++                        }
++                     }
++                     break;
++                  default:
++                     /*no-op*/ ;
++               }
++            }
++            else {
++               printf("window mismatch\n");
++            }
++         }
++      }
++
++      /* redraw all windows */
++      for (i = 0; i < NumHeads; i++) {
++         Redraw(&Heads[i]);
++      }
++      /* swapbuffers on all windows, if not already done */
++      if (SwapSeparate) {
++         for (i = 0; i < NumHeads; i++) {
++            Swap(&Heads[i]);
++         }
++      }
++      usleep(1);
++   }
++}
++
++
++
++static void
++PrintInfo(const struct head *h)
++{
++   printf("Name: %s\n", h->DisplayName);
++   printf("  Display:     %p\n", (void *) h->Dpy);
++   printf("  Window:      0x%x\n", (int) h->Win);
++   printf("  Context:     0x%lx\n", (long) h->Context);
++   printf("  GL_VERSION:  %s\n", h->Version);
++   printf("  GL_VENDOR:   %s\n", h->Vendor);
++   printf("  GL_RENDERER: %s\n", h->Renderer);
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   char *dpyName = NULL;
++   int i;
++
++   if (argc == 1) {
++      printf("manywin: open N simultaneous glx windows\n");
++      printf("Usage:\n");
++      printf("  manywin [-s] numWindows\n");
++      printf("Options:\n");
++      printf("  -s = swap immediately after drawing (see src code)\n");
++      printf("Example:\n");
++      printf("  manywin 10\n");
++      return 0;
++   }
++   else {
++      int n = 3;
++      for (i = 1; i < argc; i++) {
++         if (strcmp(argv[i], "-s") == 0) {
++            SwapSeparate = GL_FALSE;
++         }
++         else if (strcmp(argv[i], "-display") == 0 && i < argc) {
++            dpyName = argv[i+1];
++            i++;
++         }
++         else {
++            n = atoi(argv[i]);
++         }
++      }
++      if (n < 1)
++         n = 1;
++      if (n > MAX_HEADS)
++         n = MAX_HEADS;
++
++      printf("%d windows\n", n);
++      for (i = 0; i < n; i++) {
++         char name[100];
++         struct head *h;
++         sprintf(name, "%d", i);
++         h = AddHead(dpyName, name);
++         if (h) {
++            PrintInfo(h);
++         }
++      }
++   }
++
++   EventLoop();
++   DestroyHeads();
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/msctest.c Mesa-7.8.1.patched/progs/xdemos/msctest.c
+--- Mesa-7.8.1/progs/xdemos/msctest.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/msctest.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,195 @@
++/*
++ * Copyright © 2009 Intel Corporation
++ *
++ * 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 (including the next
++ * paragraph) 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.
++ *
++ * Authors:
++ *    Jesse Barnes <jesse.barnes@intel.com>
++ *
++ */
++
++/** @file msctest.c
++ * Simple test for MSC functionality.
++ */
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <GL/gl.h>
++#include <GL/glu.h>
++#include <GL/glx.h>
++#include <GL/glxext.h>
++#include <X11/X.h>
++#include <X11/Xlib.h>
++#include <X11/Xutil.h>
++
++void (*get_sync_values)(Display *dpy, Window winGL, int64_t *ust, int64_t *msc, int64_t *sbc);
++void (*wait_sync)(Display *dpy, Window winGL, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
++
++static int GLXExtensionSupported(Display *dpy, const char *extension)
++{
++	const char *extensionsString, *pos;
++
++	extensionsString = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
++
++	pos = strstr(extensionsString, extension);
++
++	if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') &&
++	    (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0'))
++		return 1;
++
++	return 0;
++}
++
++extern char *optarg;
++extern int optind, opterr, optopt;
++static char optstr[] = "v";
++
++static void usage(char *name)
++{
++	printf("usage: %s\n", name);
++	exit(-1);
++}
++
++int main(int argc, char *argv[])
++{
++	Display *disp;
++	XVisualInfo *pvi;
++	XSetWindowAttributes swa;
++	int attrib[14];
++	Window winGL;
++	GLXContext context;
++	int dummy;
++	Atom wmDelete;
++	int verbose = 0, width = 200, height = 200;
++	int c, i = 1;
++	int64_t ust, msc, sbc;
++
++	opterr = 0;
++	while ((c = getopt(argc, argv, optstr)) != -1) {
++		switch (c) {
++		case 'v':
++			verbose = 1;
++			break;
++		default:
++			usage(argv[0]);
++			break;
++		}
++	}
++
++	disp = XOpenDisplay(NULL);
++	if (!disp) {
++		fprintf(stderr, "failed to open display\n");
++		return -1;
++	}
++
++	if (!glXQueryExtension(disp, &dummy, &dummy)) {
++		fprintf(stderr, "glXQueryExtension failed\n");
++		return -1;
++	}
++
++	if (!GLXExtensionSupported(disp, "GLX_OML_sync_control")) {
++		fprintf(stderr, "GLX_OML_sync_control not supported, exiting\n");
++		return -1;
++	}
++
++	attrib[0] = GLX_RGBA;
++	attrib[1] = 1;
++	attrib[2] = GLX_RED_SIZE;
++	attrib[3] = 1;
++	attrib[4] = GLX_GREEN_SIZE;
++	attrib[5] = 1;
++	attrib[6] = GLX_BLUE_SIZE;
++	attrib[7] = 1;
++	attrib[8] = GLX_DOUBLEBUFFER;
++	attrib[9] = 1;
++	attrib[10] = None;
++
++	pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib);
++	if (!pvi) {
++		fprintf(stderr, "failed to choose visual, exiting\n");
++		return -1;
++	}
++
++	context = glXCreateContext(disp, pvi, None, GL_TRUE);
++	if (!context) {
++		fprintf(stderr, "failed to create glx context\n");
++		return -1;
++	}
++
++	pvi->screen = DefaultScreen(disp);
++
++	swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen),
++				       pvi->visual, AllocNone);
++	swa.border_pixel = 0;
++	swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
++		StructureNotifyMask;
++	winGL = XCreateWindow(disp, RootWindow(disp, pvi->screen),
++			      0, 0,
++			      width, height,
++			      0, pvi->depth, InputOutput, pvi->visual,
++			      CWBorderPixel | CWColormap | CWEventMask, &swa);
++	if (!winGL) {
++		fprintf(stderr, "window creation failed\n");
++		return -1;
++	}
++        wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True);
++        XSetWMProtocols(disp, winGL, &wmDelete, 1);
++
++	XSetStandardProperties(disp, winGL, "msc test", "msc text",
++			       None, NULL, 0, NULL);
++
++	XMapRaised(disp, winGL);
++
++	glXMakeCurrent(disp, winGL, context);
++
++	get_sync_values = (void *)glXGetProcAddress((unsigned char *)"glXGetSyncValuesOML");
++	wait_sync = (void *)glXGetProcAddress((unsigned char *)"glXWaitForMscOML");
++
++	if (!get_sync_values || !wait_sync) {
++		fprintf(stderr, "failed to get sync values function\n");
++		return -1;
++	}
++
++	while (i++) {
++		get_sync_values(disp, winGL, &ust, &msc, &sbc);
++		fprintf(stderr, "ust: %llu, msc: %llu, sbc: %llu\n", ust, msc,
++			sbc);
++
++		/* Alternate colors to make tearing obvious */
++		if (i & 1)
++			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
++		else
++			glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
++		glClear(GL_COLOR_BUFFER_BIT);
++		glXSwapBuffers(disp, winGL);
++		wait_sync(disp, winGL, 0, 60, 0, &ust, &msc, &sbc);
++		fprintf(stderr,
++			"wait returned ust: %llu, msc: %llu, sbc: %llu\n",
++			ust, msc, sbc);
++		sleep(1);
++	}
++
++	XDestroyWindow(disp, winGL);
++	glXDestroyContext(disp, context);
++	XCloseDisplay(disp);
++
++	return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/multictx.c Mesa-7.8.1.patched/progs/xdemos/multictx.c
+--- Mesa-7.8.1/progs/xdemos/multictx.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/multictx.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,585 @@
++/*
++ * Copyright (C) 2009  VMware, Inc.   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++/*
++ * Test rendering with two contexts into one window.
++ * Setup different rendering state for each context to check that
++ * context switching is handled properly.
++ *
++ * Brian Paul
++ * 6 Aug 2009
++ */
++
++
++#include <math.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <sys/time.h>
++#include <unistd.h>
++#include <X11/Xlib.h>
++#include <X11/keysym.h>
++#include <GL/gl.h>
++#include <GL/glx.h>
++
++
++
++#ifndef M_PI
++#define M_PI 3.14159265
++#endif
++
++
++/** Event handler results: */
++#define NOP 0
++#define EXIT 1
++#define DRAW 2
++
++static GLfloat view_rotx = 0.0, view_roty = 210.0, view_rotz = 0.0;
++static GLint gear1, gear2;
++static GLfloat angle = 0.0;
++
++static GLboolean animate = GL_TRUE;	/* Animation */
++
++
++static double
++current_time(void)
++{
++   struct timeval tv;
++#ifdef __VMS
++   (void) gettimeofday(&tv, NULL );
++#else
++   struct timezone tz;
++   (void) gettimeofday(&tv, &tz);
++#endif
++   return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
++}
++
++
++/*
++ *
++ *  Draw a gear wheel.  You'll probably want to call this function when
++ *  building a display list since we do a lot of trig here.
++ * 
++ *  Input:  inner_radius - radius of hole at center
++ *          outer_radius - radius at center of teeth
++ *          width - width of gear
++ *          teeth - number of teeth
++ *          tooth_depth - depth of tooth
++ */
++static void
++gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
++     GLint teeth, GLfloat tooth_depth)
++{
++   GLint i;
++   GLfloat r0, r1, r2;
++   GLfloat angle, da;
++   GLfloat u, v, len;
++
++   r0 = inner_radius;
++   r1 = outer_radius - tooth_depth / 2.0;
++   r2 = outer_radius + tooth_depth / 2.0;
++
++   da = 2.0 * M_PI / teeth / 4.0;
++
++   glShadeModel(GL_FLAT);
++
++   glNormal3f(0.0, 0.0, 1.0);
++
++   /* draw front face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw front sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++   }
++   glEnd();
++
++   glNormal3f(0.0, 0.0, -1.0);
++
++   /* draw back face */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      if (i < teeth) {
++	 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		    -width * 0.5);
++	 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      }
++   }
++   glEnd();
++
++   /* draw back sides of teeth */
++   glBegin(GL_QUADS);
++   da = 2.0 * M_PI / teeth / 4.0;
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++   }
++   glEnd();
++
++   /* draw outward faces of teeth */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i < teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
++      glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
++      u = r2 * cos(angle + da) - r1 * cos(angle);
++      v = r2 * sin(angle + da) - r1 * sin(angle);
++      len = sqrt(u * u + v * v);
++      u /= len;
++      v /= len;
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
++      glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 width * 0.5);
++      glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
++		 -width * 0.5);
++      u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
++      v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
++      glNormal3f(v, -u, 0.0);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 width * 0.5);
++      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
++		 -width * 0.5);
++      glNormal3f(cos(angle), sin(angle), 0.0);
++   }
++
++   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
++   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
++
++   glEnd();
++
++   glShadeModel(GL_SMOOTH);
++
++   /* draw inside radius cylinder */
++   glBegin(GL_QUAD_STRIP);
++   for (i = 0; i <= teeth; i++) {
++      angle = i * 2.0 * M_PI / teeth;
++      glNormal3f(-cos(angle), -sin(angle), 0.0);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
++      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
++   }
++   glEnd();
++}
++
++
++static void
++draw(int ctx)
++{
++   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++   glPushMatrix();
++   glRotatef(view_rotx, 1.0, 0.0, 0.0);
++   glRotatef(view_roty + angle, 0.0, 1.0, 0.0);
++   glRotatef(view_rotz, 0.0, 0.0, 1.0);
++
++   if (ctx == 0) {
++      glDisable(GL_CULL_FACE);
++      glPushMatrix();
++      glRotatef(angle, 0.0, 0.0, 1.0);
++      glCallList(gear1);
++      glPopMatrix();
++      /* This should not effect the other context's rendering */
++      glEnable(GL_CULL_FACE);
++      glCullFace(GL_FRONT_AND_BACK);
++   }
++   else {
++      glPushMatrix();
++      glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
++      glCallList(gear2);
++      glPopMatrix();
++   }
++
++   glPopMatrix();
++
++   /* this flush is important since we'll be switching contexts next */
++   glFlush();
++}
++
++
++
++static void
++draw_frame(Display *dpy, Window win, GLXContext ctx1, GLXContext ctx2)
++{
++   static double tRot0 = -1.0;
++   double dt, t = current_time();
++
++   if (tRot0 < 0.0)
++      tRot0 = t;
++   dt = t - tRot0;
++   tRot0 = t;
++
++   if (animate) {
++      /* advance rotation for next frame */
++      angle += 70.0 * dt;  /* 70 degrees per second */
++      if (angle > 3600.0)
++         angle -= 3600.0;
++   }
++
++   glXMakeCurrent(dpy, (GLXDrawable) win, ctx1);
++   draw(0);
++
++   glXMakeCurrent(dpy, (GLXDrawable) win, ctx2);
++   draw(1);
++
++   glXSwapBuffers(dpy, win);
++}
++
++
++/* new window size or exposure */
++static void
++reshape(Display *dpy, Window win,
++        GLXContext ctx1, GLXContext ctx2, int width, int height)
++{
++   int i;
++
++   width /= 2;
++
++   /* loop: left half of window, right half of window */
++   for (i = 0; i < 2; i++) {
++      if (i == 0)
++         glXMakeCurrent(dpy, win, ctx1);
++      else
++         glXMakeCurrent(dpy, win, ctx2);
++
++      glViewport(width * i, 0, width, height);
++      glScissor(width * i, 0, width, height);
++
++      {
++         GLfloat h = (GLfloat) height / (GLfloat) width;
++
++         glMatrixMode(GL_PROJECTION);
++         glLoadIdentity();
++         glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
++      }
++
++      glMatrixMode(GL_MODELVIEW);
++      glLoadIdentity();
++      glTranslatef(0.0, 0.0, -30.0);
++   }
++}
++   
++
++
++static void
++init(Display *dpy, Window win, GLXContext ctx1, GLXContext ctx2)
++{
++   static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
++   static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
++   static GLfloat green[4] = { 0.0, 0.8, 0.2, 0.5 };
++   /*static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };*/
++
++   /* first ctx */
++   {
++      static GLuint stipple[32] = {
++         0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
++         0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
++
++         0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00,
++         0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00,
++
++         0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
++         0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
++
++         0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00,
++         0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00
++      };
++
++      glXMakeCurrent(dpy, win, ctx1);
++
++      glLightfv(GL_LIGHT0, GL_POSITION, pos);
++      glEnable(GL_LIGHTING);
++      glEnable(GL_LIGHT0);
++      glEnable(GL_DEPTH_TEST);
++
++      gear1 = glGenLists(1);
++      glNewList(gear1, GL_COMPILE);
++      glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
++      gear(1.0, 4.0, 1.0, 20, 0.7);
++      glEndList();
++
++      glEnable(GL_NORMALIZE);
++      glEnable(GL_SCISSOR_TEST);
++      glClearColor(0.4, 0.4, 0.4, 1.0);
++
++      glPolygonStipple((GLubyte *) stipple);
++      glEnable(GL_POLYGON_STIPPLE);
++   }
++
++   /* second ctx */
++   {
++      glXMakeCurrent(dpy, win, ctx2);
++
++      glLightfv(GL_LIGHT0, GL_POSITION, pos);
++      glEnable(GL_LIGHTING);
++      glEnable(GL_LIGHT0);
++      glEnable(GL_DEPTH_TEST);
++
++      gear2 = glGenLists(1);
++      glNewList(gear2, GL_COMPILE);
++      glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
++      gear(1.5, 3.0, 1.5, 16, 0.7);
++      glEndList();
++
++      glEnable(GL_NORMALIZE);
++      glEnable(GL_SCISSOR_TEST);
++      glClearColor(0.6, 0.6, 0.6, 1.0);
++
++      glEnable(GL_BLEND);
++      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
++   }
++}
++
++
++/**
++ * Create an RGB, double-buffered window.
++ * Return the window and two context handles.
++ */
++static void
++make_window_and_contexts( Display *dpy, const char *name,
++                          int x, int y, int width, int height,
++                          Window *winRet,
++                          GLXContext *ctxRet1,
++                          GLXContext *ctxRet2)
++{
++   int attribs[] = { GLX_RGBA,
++                     GLX_RED_SIZE, 1,
++                     GLX_GREEN_SIZE, 1,
++                     GLX_BLUE_SIZE, 1,
++                     GLX_DOUBLEBUFFER,
++                     GLX_DEPTH_SIZE, 1,
++                     None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   visinfo = glXChooseVisual( dpy, scrnum, attribs );
++   if (!visinfo) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, x, y, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   *winRet = win;
++   *ctxRet1 = glXCreateContext( dpy, visinfo, NULL, True );
++   *ctxRet2 = glXCreateContext( dpy, visinfo, NULL, True );
++
++   if (!*ctxRet1 || !*ctxRet2) {
++      printf("Error: glXCreateContext failed\n");
++      exit(1);
++   }
++
++   XFree(visinfo);
++}
++
++
++/**
++ * Handle one X event.
++ * \return NOP, EXIT or DRAW
++ */
++static int
++handle_event(Display *dpy, Window win, GLXContext ctx1, GLXContext ctx2,
++             XEvent *event)
++{
++   (void) dpy;
++   (void) win;
++
++   switch (event->type) {
++   case Expose:
++      return DRAW;
++   case ConfigureNotify:
++      reshape(dpy, win, ctx1, ctx2,
++              event->xconfigure.width, event->xconfigure.height);
++      break;
++   case KeyPress:
++      {
++         char buffer[10];
++         int r, code;
++         code = XLookupKeysym(&event->xkey, 0);
++         if (code == XK_Left) {
++            view_roty += 5.0;
++         }
++         else if (code == XK_Right) {
++            view_roty -= 5.0;
++         }
++         else if (code == XK_Up) {
++            view_rotx += 5.0;
++         }
++         else if (code == XK_Down) {
++            view_rotx -= 5.0;
++         }
++         else {
++            r = XLookupString(&event->xkey, buffer, sizeof(buffer),
++                              NULL, NULL);
++            if (buffer[0] == 27) {
++               /* escape */
++               return EXIT;
++            }
++            else if (buffer[0] == 'a' || buffer[0] == 'A') {
++               animate = !animate;
++            }
++         }
++         return DRAW;
++      }
++   }
++   return NOP;
++}
++
++
++static void
++event_loop(Display *dpy, Window win, GLXContext ctx1, GLXContext ctx2)
++{
++   while (1) {
++      int op;
++      while (!animate || XPending(dpy) > 0) {
++         XEvent event;
++         XNextEvent(dpy, &event);
++         op = handle_event(dpy, win, ctx1, ctx2, &event);
++         if (op == EXIT)
++            return;
++         else if (op == DRAW)
++            break;
++      }
++
++      draw_frame(dpy, win, ctx1, ctx2);
++   }
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   unsigned int winWidth = 800, winHeight = 400;
++   int x = 0, y = 0;
++   Display *dpy;
++   Window win;
++   GLXContext ctx1, ctx2;
++   char *dpyName = NULL;
++   GLboolean printInfo = GL_FALSE;
++   int i;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0) {
++         dpyName = argv[i+1];
++         i++;
++      }
++      else {
++         return 1;
++      }
++   }
++
++   dpy = XOpenDisplay(dpyName);
++   if (!dpy) {
++      printf("Error: couldn't open display %s\n",
++	     dpyName ? dpyName : getenv("DISPLAY"));
++      return -1;
++   }
++
++   make_window_and_contexts(dpy, "multictx", x, y, winWidth, winHeight,
++                            &win, &ctx1, &ctx2);
++   XMapWindow(dpy, win);
++
++   if (printInfo) {
++      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
++      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
++      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
++      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
++   }
++
++   init(dpy, win, ctx1, ctx2);
++
++   /* Set initial projection/viewing transformation.
++    * We can't be sure we'll get a ConfigureNotify event when the window
++    * first appears.
++    */
++   reshape(dpy, win, ctx1, ctx2, winWidth, winHeight);
++
++   event_loop(dpy, win, ctx1, ctx2);
++
++   glDeleteLists(gear1, 1);
++   glDeleteLists(gear2, 1);
++   glXDestroyContext(dpy, ctx1);
++   glXDestroyContext(dpy, ctx2);
++   XDestroyWindow(dpy, win);
++   XCloseDisplay(dpy);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/offset.c Mesa-7.8.1.patched/progs/xdemos/offset.c
+--- Mesa-7.8.1/progs/xdemos/offset.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/offset.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,343 @@
++/****************************************************************************
++Copyright 1995 by Silicon Graphics Incorporated, Mountain View, California.
++
++                        All Rights Reserved
++
++Permission to use, copy, modify, and distribute this software and its 
++documentation for any purpose and without fee is hereby granted, 
++provided that the above copyright notice appear in all copies and that
++both that copyright notice and this permission notice appear in 
++supporting documentation, and that the name of Silicon Graphics not be
++used in advertising or publicity pertaining to distribution of the
++software without specific, written prior permission.  
++
++SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
++USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
++OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++PERFORMANCE OF THIS SOFTWARE.
++
++****************************************************************************/
++
++/*
++ * Derived from code written by Kurt Akeley, November 1992
++ *
++ *	Uses PolygonOffset to draw hidden-line images.  PolygonOffset
++ *	    shifts the z values of polygons an amount that is
++ *	    proportional to their slope in screen z.  This keeps
++ *	    the lines, which are drawn without displacement, from
++ *	    interacting with their respective polygons, and
++ *	    thus eliminates line dropouts.
++ *
++ *	The left image shows an ordinary antialiased wireframe image.
++ *	The center image shows an antialiased hidden-line image without
++ *	    PolygonOffset.
++ *	The right image shows an antialiased hidden-line image using
++ *	    PolygonOffset to reduce artifacts.
++ *
++ *	Drag with a mouse button pressed to rotate the models.
++ *	Press the escape key to exit.
++ */
++
++/*
++ * Modified for OpenGL 1.1 glPolygonOffset() conventions
++ */
++
++
++#include <GL/glx.h>
++#include <X11/keysym.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++
++#undef GL_EXT_polygon_offset  /* use GL 1.1 version instead of extension */
++
++
++#ifndef EXIT_FAILURE
++#  define EXIT_FAILURE    1
++#endif
++#ifndef EXIT_SUCCESS
++#  define EXIT_SUCCESS    0
++#endif
++
++#define MAXQUAD 6
++
++typedef float Vertex[3];
++
++typedef Vertex Quad[4];
++
++/* data to define the six faces of a unit cube */
++Quad quads[MAXQUAD] = {
++   { {0,0,0}, {0,0,1}, {0,1,1}, {0,1,0} }, /* x = 0 */
++   { {0,0,0}, {1,0,0}, {1,0,1}, {0,0,1} }, /* y = 0 */
++   { {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0} }, /* z = 0 */
++   { {1,0,0}, {1,0,1}, {1,1,1}, {1,1,0} }, /* x = 1 */
++   { {0,1,0}, {1,1,0}, {1,1,1}, {0,1,1} }, /* y = 1 */
++   { {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1} }  /* z = 1 */
++};
++
++#define WIREFRAME	0
++#define HIDDEN_LINE	1
++
++static void error(const char* prog, const char* msg);
++static void cubes(int mx, int my, int mode);
++static void fill(Quad quad);
++static void outline(Quad quad);
++static void draw_hidden(Quad quad, int mode, int face);
++static void process_input(Display *dpy, Window win);
++static int query_extension(char* extName);
++
++static int attributeList[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
++    GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None };
++
++static int dimension = 3;
++
++static float Scale = 1.0;
++
++
++int main(int argc, char** argv) {
++    Display *dpy;
++    XVisualInfo *vi;
++    XSetWindowAttributes swa;
++    Window win;
++    GLXContext cx;
++    GLint z;
++
++    dpy = XOpenDisplay(0);
++    if (!dpy) error(argv[0], "can't open display");
++
++    vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList);
++    if (!vi) error(argv[0], "no suitable visual");
++
++    cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
++
++    swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
++                                   vi->visual, AllocNone);
++
++    swa.border_pixel = 0;
++    swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask |
++	ButtonPressMask | ButtonMotionMask;
++    win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 900, 300,
++			0, vi->depth, InputOutput, vi->visual,
++			CWBorderPixel|CWColormap|CWEventMask, &swa);
++    XStoreName(dpy, win, "hiddenline");
++    XMapWindow(dpy, win);
++
++    glXMakeCurrent(dpy, win, cx);
++
++    /* check for the polygon offset extension */
++#ifndef GL_VERSION_1_1
++    if (!query_extension("GL_EXT_polygon_offset"))
++        error(argv[0], "polygon_offset extension is not available");
++#else
++   (void) query_extension;
++#endif
++
++    /* set up viewing parameters */
++    glMatrixMode(GL_PROJECTION);
++    glFrustum(-1, 1, -1, 1, 6, 20);
++    glMatrixMode(GL_MODELVIEW);
++    glTranslatef(0, 0, -15);
++
++    /* set other relevant state information */
++    glEnable(GL_DEPTH_TEST);
++
++    glGetIntegerv(GL_DEPTH_BITS, &z);
++    printf("GL_DEPTH_BITS = %d\n", z);
++
++#ifdef GL_EXT_polygon_offset
++    printf("using 1.0 offset extension\n");
++    glPolygonOffsetEXT( 1.0, 0.00001 );
++#else
++    printf("using 1.1 offset\n");
++    glPolygonOffset( 1.0, 0.5 );
++#endif
++
++    glShadeModel( GL_FLAT );
++    glDisable( GL_DITHER );
++
++    /* process events until the user presses ESC */
++    while (1) process_input(dpy, win);
++
++    return 0;
++}
++
++static void
++draw_scene(int mx, int my) {
++   glClearColor(0.25, 0.25, 0.25, 0);
++    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++    glPushMatrix();
++    glTranslatef(-1.7, 0.0, 0.0);
++    cubes(mx, my, WIREFRAME);
++    glPopMatrix();
++
++    glPushMatrix();
++    cubes(mx, my, HIDDEN_LINE);
++    glPopMatrix();
++
++    glPushMatrix();
++    glTranslatef(1.7, 0.0, 0.0);
++#ifdef GL_EXT_polygon_offset
++    glEnable(GL_POLYGON_OFFSET_EXT);
++#else
++    glEnable(GL_POLYGON_OFFSET_FILL);
++#endif
++    glScalef(Scale, Scale, Scale);
++    cubes(mx, my, HIDDEN_LINE);
++#ifdef GL_EXT_polygon_offset
++    glDisable(GL_POLYGON_OFFSET_EXT);
++#else
++    glDisable(GL_POLYGON_OFFSET_FILL);
++#endif
++    glPopMatrix();
++}
++
++
++static void
++cubes(int mx, int my, int mode) {
++    int x, y, z, i;
++
++    /* track the mouse */
++    glRotatef(mx / 2.0, 0, 1, 0);
++    glRotatef(my / 2.0, 1, 0, 0);
++
++    /* draw the lines as hidden polygons */
++    glTranslatef(-0.5, -0.5, -0.5);
++    glScalef(1.0/dimension, 1.0/dimension, 1.0/dimension);
++    for (z = 0; z < dimension; z++) {
++	for (y = 0; y < dimension; y++) {
++	    for (x = 0; x < dimension; x++) {
++		glPushMatrix();
++		glTranslatef(x, y, z);
++		glScalef(0.8, 0.8, 0.8);
++		for (i = 0; i < MAXQUAD; i++)
++                    draw_hidden(quads[i], mode, i);
++		glPopMatrix();
++	    }
++	}
++    }
++}
++
++static void
++fill(Quad quad) {
++    /* draw a filled polygon */
++    glBegin(GL_QUADS);
++    glVertex3fv(quad[0]);
++    glVertex3fv(quad[1]);
++    glVertex3fv(quad[2]);
++    glVertex3fv(quad[3]);
++    glEnd();
++}
++
++static void
++outline(Quad quad) {
++    /* draw an outlined polygon */
++    glBegin(GL_LINE_LOOP);
++    glVertex3fv(quad[0]);
++    glVertex3fv(quad[1]);
++    glVertex3fv(quad[2]);
++    glVertex3fv(quad[3]);
++    glEnd();
++}
++
++static void
++draw_hidden(Quad quad, int mode, int face) {
++    static const GLfloat colors[3][3] = {
++        {0.5, 0.5, 0.0},
++        {0.8, 0.5, 0.0},
++        {0.0, 0.5, 0.8}
++    };
++    if (mode == HIDDEN_LINE) {
++        glColor3fv(colors[face % 3]);
++	fill(quad);
++    }
++
++    /* draw the outline using white */
++    glColor3f(1, 1, 1);
++    outline(quad);
++}
++
++static void
++process_input(Display *dpy, Window win) {
++    XEvent event;
++    static int prevx, prevy;
++    static int deltax = 90, deltay = 40;
++
++    do {
++	char buf[31];
++	KeySym keysym;
++
++	XNextEvent(dpy, &event);
++	switch(event.type) {
++	case Expose:
++	    break;
++	case ConfigureNotify: {
++	    /* this approach preserves a 1:1 viewport aspect ratio */
++	    int vX, vY, vW, vH;
++	    int eW = event.xconfigure.width, eH = event.xconfigure.height;
++	    if (eW >= eH) {
++		vX = 0;
++		vY = (eH - eW) >> 1;
++		vW = vH = eW;
++	    } else {
++		vX = (eW - eH) >> 1;
++		vY = 0;
++		vW = vH = eH;
++	    }
++	    glViewport(vX, vY, vW, vH);
++	    }
++	    break;
++	case KeyPress:
++	    (void) XLookupString(&event.xkey, buf, sizeof(buf), &keysym, NULL);
++	    switch (keysym) {
++            case 'Z':
++               Scale *= 1.1;
++               break;
++            case 'z':
++               Scale *= 0.9;
++               break;
++	    case XK_Escape:
++		exit(EXIT_SUCCESS);
++	    default:
++		break;
++	    }
++	    break;
++	case ButtonPress:
++	    prevx = event.xbutton.x;
++	    prevy = event.xbutton.y;
++	    break;
++	case MotionNotify:
++	    deltax += (event.xbutton.x - prevx); prevx = event.xbutton.x;
++	    deltay += (event.xbutton.y - prevy); prevy = event.xbutton.y;
++	    break;
++	default:
++	    break;
++	}
++    } while (XPending(dpy));
++
++    draw_scene(deltax, deltay);
++    glXSwapBuffers(dpy, win);
++}
++
++static void
++error(const char *prog, const char *msg) {
++    fprintf(stderr, "%s: %s\n", prog, msg);
++    exit(EXIT_FAILURE);
++}
++
++static int
++query_extension(char* extName) {
++    char *p = (char *) glGetString(GL_EXTENSIONS);
++    char *end = p + strlen(p);
++    while (p < end) {
++        int n = strcspn(p, " ");
++        if ((strlen(extName) == n) && (strncmp(extName, p, n) == 0))
++            return GL_TRUE;
++        p += (n + 1);
++    }
++    return GL_FALSE;
++}
++
+diff -Naurp Mesa-7.8.1/progs/xdemos/omlsync.c Mesa-7.8.1.patched/progs/xdemos/omlsync.c
+--- Mesa-7.8.1/progs/xdemos/omlsync.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/omlsync.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,265 @@
++/*
++ * Copyright © 2007-2010 Intel Corporation
++ *
++ * 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 (including the next
++ * paragraph) 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.
++ *
++ * Authors:
++ *    Jesse Barnes <jesse.barnes@intel.com>
++ *
++ */
++
++/** @file omlsync.c
++ * The program is simple:  it paints a window alternating colors (red &
++ * white) either as fast as possible or synchronized to vblank events
++ *
++ * If run normally, the program should display a window that exhibits
++ * significant tearing between red and white colors (e.g. you might get
++ * a "waterfall" effect of red and white horizontal bars).
++ *
++ * If run with the '-s b' option, the program should synchronize the
++ * window color changes with the vertical blank period, resulting in a
++ * window that looks orangish with a high frequency flicker (which may
++ * be invisible).  If the window is moved to another screen, this
++ * property should be preserved.  If the window spans two screens, it
++ * shouldn't tear on whichever screen most of the window is on; the
++ * portion on the other screen may show some tearing (like the
++ * waterfall effect above).
++ *
++ * Other options include '-w <width>' and '-h <height>' to set the
++ * window size.
++ */
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <GL/gl.h>
++#include <GL/glu.h>
++#include <GL/glx.h>
++#include <GL/glxext.h>
++#include <X11/X.h>
++#include <X11/Xlib.h>
++#include <X11/Xutil.h>
++
++Bool (*glXGetSyncValuesOML)(Display *dpy, GLXDrawable drawable,
++			    int64_t *ust, int64_t *msc, int64_t *sbc);
++Bool (*glXGetMscRateOML)(Display *dpy, GLXDrawable drawable, int32_t *numerator,
++			 int32_t *denominator);
++int64_t (*glXSwapBuffersMscOML)(Display *dpy, GLXDrawable drawable,
++				int64_t target_msc, int64_t divisor,
++				int64_t remainder);
++Bool (*glXWaitForMscOML)(Display *dpy, GLXDrawable drawable, int64_t target_msc,
++			 int64_t divisor, int64_t remainder, int64_t *ust,
++			 int64_t *msc, int64_t *sbc);
++Bool (*glXWaitForSbcOML)(Display *dpy, GLXDrawable drawable, int64_t target_sbc,
++			 int64_t *ust, int64_t *msc, int64_t *sbc);
++int (*glXSwapInterval)(int interval);
++
++static int GLXExtensionSupported(Display *dpy, const char *extension)
++{
++	const char *extensionsString, *pos;
++
++	extensionsString = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
++
++	pos = strstr(extensionsString, extension);
++
++	if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') &&
++	    (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0'))
++		return 1;
++
++	return 0;
++}
++
++extern char *optarg;
++extern int optind, opterr, optopt;
++static char optstr[] = "w:h:vd:r:n:i:";
++
++static void usage(char *name)
++{
++	printf("usage: %s [-w <width>] [-h <height>] ...\n", name);
++	printf("\t-d<divisor> - divisor for OML swap\n");
++	printf("\t-r<remainder> - remainder for OML swap\n");
++	printf("\t-n<interval> - wait interval for OML WaitMSC\n");
++	printf("\t-i<swap interval> - swap at most once every n frames\n");
++	printf("\t-v: verbose (print count)\n");
++	exit(-1);
++}
++
++int main(int argc, char *argv[])
++{
++	Display *disp;
++	XVisualInfo *pvi;
++	XSetWindowAttributes swa;
++	Window winGL;
++	GLXContext context;
++	int dummy;
++	Atom wmDelete;
++	int64_t ust, msc, sbc;
++	int width = 500, height = 500, verbose = 0, divisor = 0, remainder = 0,
++		wait_interval = 0, swap_interval = 1;
++	int c, i = 1;
++	int ret;
++	int db_attribs[] = { GLX_RGBA,
++                     GLX_RED_SIZE, 1,
++                     GLX_GREEN_SIZE, 1,
++                     GLX_BLUE_SIZE, 1,
++                     GLX_DOUBLEBUFFER,
++                     GLX_DEPTH_SIZE, 1,
++                     None };
++	XSizeHints sizehints;
++
++	opterr = 0;
++	while ((c = getopt(argc, argv, optstr)) != -1) {
++		switch (c) {
++		case 'w':
++			width = atoi(optarg);
++			break;
++		case 'h':
++			height = atoi(optarg);
++			break;
++		case 'v':
++			verbose = 1;
++			break;
++		case 'd':
++			divisor = atoi(optarg);
++			break;
++		case 'r':
++			remainder = atoi(optarg);
++			break;
++		case 'n':
++			wait_interval = atoi(optarg);
++			break;
++		case 'i':
++			swap_interval = atoi(optarg);
++			break;
++		default:
++			usage(argv[0]);
++			break;
++		}
++	}
++
++	disp = XOpenDisplay(NULL);
++	if (!disp) {
++		fprintf(stderr, "failed to open display\n");
++		return -1;
++	}
++
++	if (!glXQueryExtension(disp, &dummy, &dummy)) {
++		fprintf(stderr, "glXQueryExtension failed\n");
++		return -1;
++	}
++
++	if (!GLXExtensionSupported(disp, "GLX_OML_sync_control")) {
++		fprintf(stderr, "GLX_OML_sync_control not supported\n");
++		return -1;
++	}
++
++	if (!GLXExtensionSupported(disp, "GLX_MESA_swap_control")) {
++		fprintf(stderr, "GLX_MESA_swap_control not supported\n");
++		return -1;
++	}
++
++	pvi = glXChooseVisual(disp, DefaultScreen(disp), db_attribs);
++
++	if (!pvi) {
++		fprintf(stderr, "failed to choose visual, exiting\n");
++		return -1;
++	}
++
++	pvi->screen = DefaultScreen(disp);
++
++	swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen),
++				       pvi->visual, AllocNone);
++	swa.border_pixel = 0;
++	swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
++		StructureNotifyMask;
++	winGL = XCreateWindow(disp, RootWindow(disp, pvi->screen),
++			      0, 0,
++			      width, height,
++			      0, pvi->depth, InputOutput, pvi->visual,
++			      CWBorderPixel | CWColormap | CWEventMask, &swa);
++	if (!winGL) {
++		fprintf(stderr, "window creation failed\n");
++		return -1;
++	}
++        wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True);
++        XSetWMProtocols(disp, winGL, &wmDelete, 1);
++
++	sizehints.x = 0;
++	sizehints.y = 0;
++	sizehints.width  = width;
++	sizehints.height = height;
++	sizehints.flags = USSize | USPosition;
++
++	XSetNormalHints(disp, winGL, &sizehints);
++	XSetStandardProperties(disp, winGL, "glsync test", "glsync text",
++			       None, NULL, 0, &sizehints);
++
++	context = glXCreateContext(disp, pvi, NULL, GL_TRUE);
++	if (!context) {
++		fprintf(stderr, "failed to create glx context\n");
++		return -1;
++	}
++
++	XMapWindow(disp, winGL);
++	ret = glXMakeCurrent(disp, winGL, context);
++	if (!ret) {
++		fprintf(stderr, "failed to make context current: %d\n", ret);
++	}
++
++	glXGetSyncValuesOML = (void *)glXGetProcAddress((unsigned char *)"glXGetSyncValuesOML");
++	glXGetMscRateOML = (void *)glXGetProcAddress((unsigned char *)"glXGetMscRateOML");
++	glXSwapBuffersMscOML = (void *)glXGetProcAddress((unsigned char *)"glXSwapBuffersMscOML");
++	glXWaitForMscOML = (void *)glXGetProcAddress((unsigned char *)"glXWaitForMscOML");
++	glXWaitForSbcOML = (void *)glXGetProcAddress((unsigned char *)"glXWaitForSbcOML");
++	glXSwapInterval = (void *)glXGetProcAddress((unsigned char *)"glXSwapIntervalMESA");
++
++	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++	glXSwapInterval(swap_interval);
++	fprintf(stderr, "set swap interval to %d\n", swap_interval);
++
++	glXGetSyncValuesOML(disp, winGL, &ust, &msc, &sbc);
++	while (i++) {
++		/* Alternate colors to make tearing obvious */
++		if (i & 1) {
++			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
++			glColor3f(1.0f, 1.0f, 1.0f);
++		} else {
++			glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
++			glColor3f(1.0f, 0.0f, 0.0f);
++		}
++
++		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++		glRectf(0, 0, width, height);
++
++		glXSwapBuffersMscOML(disp, winGL, 0, divisor, remainder);
++
++		if (wait_interval) {
++			glXWaitForMscOML(disp, winGL, msc + wait_interval,
++					 0, 0, &ust, &msc, &sbc);
++		}
++	}
++
++	XDestroyWindow(disp, winGL);
++	glXDestroyContext(disp, context);
++	XCloseDisplay(disp);
++
++	return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/opencloseopen.c Mesa-7.8.1.patched/progs/xdemos/opencloseopen.c
+--- Mesa-7.8.1/progs/xdemos/opencloseopen.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/opencloseopen.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,189 @@
++/*
++ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
++ * (C) Copyright IBM Corporation 2003
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <unistd.h>
++#include <string.h>
++#include <X11/Xlib.h>
++#include <GL/gl.h>
++#include <GL/glx.h>
++
++/** \file opencloseopen.c
++ * Simple test for Mesa bug #508473.  Create a window and rendering context.
++ * Draw a single frame.  Close the window, destroy the context, and close
++ * the display.  Re-open the display, create a new window and context.  This
++ * should work, but, at least as of Mesa 5.1, it segfaults.  See the bug
++ * report for more details.
++ * 
++ * Most of the code here was lifed from various other Mesa xdemos.
++ */
++
++static void
++draw(void)
++{
++   glViewport(0, 0, 300, 300);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
++   glMatrixMode(GL_MODELVIEW);
++
++   glShadeModel(GL_FLAT);
++   glClearColor(0.5, 0.5, 0.5, 1.0);
++   glClear(GL_COLOR_BUFFER_BIT);
++
++   /* draw blue quad */
++   glLoadIdentity();
++   glColor3f(0.3, 0.3, 1.0);
++   glPushMatrix();
++   glRotatef(0, 0, 0, 1);
++   glBegin(GL_POLYGON);
++   glVertex2f(-0.5, -0.25);
++   glVertex2f( 0.5, -0.25);
++   glVertex2f( 0.5, 0.25);
++   glVertex2f(-0.5, 0.25);
++   glEnd();
++   glPopMatrix();}
++
++
++/*
++ * Create an RGB, double-buffered window.
++ * Return the window and context handles.
++ */
++static void
++make_window( const char * dpyName, const char *name,
++             int x, int y, int width, int height,
++	     Display **dpyRet, Window *winRet, GLXContext *ctxRet)
++{
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   GLXContext ctx;
++   XVisualInfo *visinfo;
++   Display *dpy;
++
++   dpy = XOpenDisplay(dpyName);
++   if (!dpy) {
++      printf("Error: couldn't open display %s\n", XDisplayName(dpyName));
++      exit(1);
++   }
++
++   *dpyRet = dpy;
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   visinfo = glXChooseVisual( dpy, scrnum, attrib );
++   if (!visinfo) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   ctx = glXCreateContext( dpy, visinfo, NULL, True );
++   if (!ctx) {
++      printf("Error: glXCreateContext failed\n");
++      exit(1);
++   }
++
++   XFree(visinfo);
++
++   *winRet = win;
++   *ctxRet = ctx;
++}
++
++
++static void
++destroy_window( Display *dpy, Window win, GLXContext ctx )
++{
++   glXMakeCurrent(dpy, None, NULL);
++   glXDestroyContext(dpy, ctx);
++   XDestroyWindow(dpy, win);
++   XCloseDisplay(dpy);
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   Display *dpy;
++   Window win;
++   GLXContext ctx;
++   char *dpyName = NULL;
++   int i;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0) {
++         dpyName = argv[i+1];
++         i++;
++      }
++   }
++
++   printf("If this program segfaults, then Mesa bug #508473 is probably "
++	  "back.\n");
++   make_window(dpyName, "Open-close-open", 0, 0, 300, 300, &dpy, &win, &ctx);
++   XMapWindow(dpy, win);
++   glXMakeCurrent(dpy, win, ctx);
++
++   draw();
++   glXSwapBuffers(dpy, win);
++   sleep(2);
++
++   destroy_window(dpy, win, ctx);
++
++   make_window(dpyName, "Open-close-open", 0, 0, 300, 300, &dpy, &win, &ctx);
++   XMapWindow(dpy, win);
++   glXMakeCurrent(dpy, win, ctx);
++   destroy_window(dpy, win, ctx);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/overlay.c Mesa-7.8.1.patched/progs/xdemos/overlay.c
+--- Mesa-7.8.1/progs/xdemos/overlay.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/overlay.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,246 @@
++/*
++ * GLX overlay test/demo.
++ *
++ * Brian Paul
++ * 18 July 2005
++ */
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <X11/keysym.h>
++#include <assert.h>
++#include <stdio.h>
++#include <stdlib.h>
++
++static int WinWidth = 300, WinHeight = 300;
++static Window NormalWindow = 0;
++static Window OverlayWindow = 0;
++static GLXContext NormalContext = 0;
++static GLXContext OverlayContext = 0;
++static GLboolean RGBOverlay = GL_FALSE;
++static GLfloat Angle = 0.0;
++
++
++static void
++RedrawNormal(Display *dpy)
++{
++   glXMakeCurrent(dpy, NormalWindow, NormalContext);
++   glViewport(0, 0, WinWidth, WinHeight);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
++   glMatrixMode(GL_MODELVIEW);
++   glClearColor(0.5, 0.5, 0.5, 1.0);
++   glClear(GL_COLOR_BUFFER_BIT);
++   glColor3f(1.0, 1.0, 0.0);
++   glPushMatrix();
++   glRotatef(Angle, 0, 0, 1);
++   glRectf(-0.8, -0.8, 0.8, 0.8);
++   glPopMatrix();
++   glXSwapBuffers(dpy, NormalWindow);
++}
++
++
++static void
++RedrawOverlay(Display *dpy)
++{
++   glXMakeCurrent(dpy, OverlayWindow, OverlayContext);
++   glViewport(0, 0, WinWidth, WinHeight);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
++   glMatrixMode(GL_MODELVIEW);
++   glClear(GL_COLOR_BUFFER_BIT);
++   if (RGBOverlay) {
++      glColor3f(0.0, 1.0, 1.0);
++   }
++   else {
++      glIndexi(2);
++   }
++   glBegin(GL_LINES);
++   glVertex2f(-1, -1);
++   glVertex2f(1, 1);
++   glVertex2f(1, -1);
++   glVertex2f(-1, 1);
++   glEnd();
++   glXSwapBuffers(dpy, OverlayWindow);
++}
++
++
++static Window
++MakeWindow(Display *dpy, XVisualInfo *visinfo, Window parent,
++             unsigned int width, unsigned int height)
++{
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++
++   scrnum = DefaultScreen(dpy);
++   root = RootWindow(dpy, scrnum);
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow(dpy, parent, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr);
++   return win;
++}
++
++
++static void
++MakeNormalWindow(Display *dpy)
++{
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int scrnum;
++   Window root;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen(dpy);
++   root = RootWindow(dpy, scrnum);
++
++   visinfo = glXChooseVisual(dpy, scrnum, attrib);
++   if (!visinfo) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   NormalWindow = MakeWindow(dpy, visinfo, root, WinWidth, WinHeight);
++   assert(NormalWindow);
++
++   NormalContext = glXCreateContext(dpy, visinfo, NULL, True);
++   assert(NormalContext);
++}
++
++
++static void
++MakeOverlayWindow(Display *dpy)
++{
++   int rgbAttribs[] = {
++      GLX_RGBA,
++      GLX_RED_SIZE, 1,
++      GLX_GREEN_SIZE, 1,
++      GLX_BLUE_SIZE, 1,
++      GLX_DOUBLEBUFFER,
++      GLX_LEVEL, 1,
++      None
++   };
++   int indexAttribs[] = {
++      /*GLX_RGBA, leave this out */
++      GLX_RED_SIZE, 1,
++      GLX_GREEN_SIZE, 1,
++      GLX_BLUE_SIZE, 1,
++      GLX_DOUBLEBUFFER,
++      GLX_LEVEL, 1,
++      None
++   };
++   int scrnum;
++   Window root;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen(dpy);
++   root = RootWindow(dpy, scrnum);
++
++   visinfo = glXChooseVisual(dpy, scrnum, rgbAttribs);
++   if (visinfo) {
++      printf("Found RGB overlay visual 0x%x\n", (int) visinfo->visualid);
++      RGBOverlay = GL_TRUE;
++   }
++   else {
++      visinfo = glXChooseVisual(dpy, scrnum, indexAttribs);
++      if (visinfo) {
++         printf("Found Color Index overlay visual 0x%x\n",
++                (int) visinfo->visualid);
++         /* XXX setup the colormap entries! */
++      }
++      else {
++         printf("Couldn't get an overlay visual.\n");
++         printf("Your hardware probably doesn't support framebuffer overlay planes.\n");
++         exit(1);
++      }
++   }
++
++   OverlayWindow = MakeWindow(dpy, visinfo, NormalWindow, WinWidth, WinHeight);
++   assert(OverlayWindow);
++
++   OverlayContext = glXCreateContext(dpy, visinfo, NULL, True);
++   assert(OverlayContext);
++}
++
++
++static void
++EventLoop(Display *dpy)
++{
++   XEvent event;
++
++   while (1) {
++      XNextEvent(dpy, &event);
++
++      switch (event.type) {
++	 case Expose:
++	    RedrawNormal(dpy);
++	    RedrawOverlay(dpy);
++	    break;
++	 case ConfigureNotify:
++            WinWidth = event.xconfigure.width;
++            WinHeight = event.xconfigure.height;
++            if (event.xconfigure.window == NormalWindow)
++               XResizeWindow(dpy, OverlayWindow, WinWidth, WinHeight);
++	    break;
++         case KeyPress:
++            {
++               char buffer[10];
++               int r, code;
++               code = XLookupKeysym(&event.xkey, 0);
++	       r = XLookupString(&event.xkey, buffer, sizeof(buffer),
++				 NULL, NULL);
++	       if (buffer[0] == 27) {
++                  /* escape */
++                  return;
++               }
++               else if (buffer[0] == ' ') {
++                  Angle += 5.0;
++                  RedrawNormal(dpy);
++               }
++            }
++            break;
++         default:
++            ; /* nothing */
++      }
++   }
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   Display *dpy = XOpenDisplay(NULL);
++
++   assert(dpy);
++
++   MakeNormalWindow(dpy);
++   MakeOverlayWindow(dpy);
++
++   XMapWindow(dpy, NormalWindow);
++   XMapWindow(dpy, OverlayWindow);
++
++   EventLoop(dpy);
++
++   glXDestroyContext(dpy, OverlayContext);
++   glXDestroyContext(dpy, NormalContext);
++   XDestroyWindow(dpy, OverlayWindow);
++   XDestroyWindow(dpy, NormalWindow);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/pbdemo.c Mesa-7.8.1.patched/progs/xdemos/pbdemo.c
+--- Mesa-7.8.1/progs/xdemos/pbdemo.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/pbdemo.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,493 @@
++
++/*
++ * This program demonstrates how to do "off-screen" rendering using
++ * the GLX pixel buffer extension.
++ *
++ * Written by Brian Paul for the "OpenGL and Window System Integration"
++ * course presented at SIGGRAPH '97.  Updated on 5 October 2002.
++ *
++ * Usage:
++ *   pbuffers width height imgfile
++ * Where:
++ *   width is the width, in pixels, of the image to generate.
++ *   height is the height, in pixels, of the image to generate.
++ *   imgfile is the name of the PPM image file to write.
++ *
++ *
++ * This demo draws 3-D boxes with random orientation.  A pbuffer with
++ * a depth (Z) buffer is prefered but if such a pbuffer can't be created
++ * we use a non-depth-buffered config.
++ *
++ * On machines such as the SGI Indigo you may have to reconfigure your
++ * display/X server to enable pbuffers.  Look in the /usr/gfx/ucode/MGRAS/vof/
++ * directory for display configurationswith the _pbuf suffix.  Use
++ * setmon -x <vof> to configure your X server and display for pbuffers.
++ *
++ * O2 systems seem to support pbuffers well.
++ *
++ * IR systems (at least 1RM systems) don't have single-buffered, RGBA,
++ * Z-buffered pbuffer configs.  BUT, they DO have DOUBLE-buffered, RGBA,
++ * Z-buffered pbuffers.  Note how we try four different fbconfig attribute
++ * lists below!
++ */
++
++
++#include <assert.h>
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <X11/Xlib.h>
++#include "pbutil.h"
++
++
++/* Some ugly global vars */
++static Display *gDpy = NULL;
++static int gScreen = 0;
++static FBCONFIG gFBconfig = 0;
++static PBUFFER gPBuffer = 0;
++static int gWidth, gHeight;
++static GLXContext glCtx;
++
++
++
++/*
++ * Create the pbuffer and return a GLXPbuffer handle.
++ *
++ * We loop over a list of fbconfigs trying to create
++ * a pixel buffer.  We return the first pixel buffer which we successfully
++ * create.
++ */
++static PBUFFER
++MakePbuffer( Display *dpy, int screen, int width, int height )
++{
++#define NUM_FB_CONFIGS 4
++   const char fbString[NUM_FB_CONFIGS][100] = {
++      "Single Buffered, depth buffer",
++      "Double Buffered, depth buffer",
++      "Single Buffered, no depth buffer",
++      "Double Buffered, no depth buffer"
++   };
++   int fbAttribs[NUM_FB_CONFIGS][100] = {
++      {
++         /* Single buffered, with depth buffer */
++         GLX_RENDER_TYPE, GLX_RGBA_BIT,
++         GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
++         GLX_RED_SIZE, 1,
++         GLX_GREEN_SIZE, 1,
++         GLX_BLUE_SIZE, 1,
++         GLX_DEPTH_SIZE, 1,
++         GLX_DOUBLEBUFFER, 0,
++         GLX_STENCIL_SIZE, 0,
++         None
++      },
++      {
++         /* Double buffered, with depth buffer */
++         GLX_RENDER_TYPE, GLX_RGBA_BIT,
++         GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
++         GLX_RED_SIZE, 1,
++         GLX_GREEN_SIZE, 1,
++         GLX_BLUE_SIZE, 1,
++         GLX_DEPTH_SIZE, 1,
++         GLX_DOUBLEBUFFER, 1,
++         GLX_STENCIL_SIZE, 0,
++         None
++      },
++      {
++         /* Single buffered, without depth buffer */
++         GLX_RENDER_TYPE, GLX_RGBA_BIT,
++         GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
++         GLX_RED_SIZE, 1,
++         GLX_GREEN_SIZE, 1,
++         GLX_BLUE_SIZE, 1,
++         GLX_DEPTH_SIZE, 0,
++         GLX_DOUBLEBUFFER, 0,
++         GLX_STENCIL_SIZE, 0,
++         None
++      },
++      {
++         /* Double buffered, without depth buffer */
++         GLX_RENDER_TYPE, GLX_RGBA_BIT,
++         GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
++         GLX_RED_SIZE, 1,
++         GLX_GREEN_SIZE, 1,
++         GLX_BLUE_SIZE, 1,
++         GLX_DEPTH_SIZE, 0,
++         GLX_DOUBLEBUFFER, 1,
++         GLX_STENCIL_SIZE, 0,
++         None
++      }
++   };
++   Bool largest = True;
++   Bool preserve = False;
++   FBCONFIG *fbConfigs;
++   PBUFFER pBuffer = None;
++   int nConfigs;
++   int i;
++   int attempt;
++
++   for (attempt=0; attempt<NUM_FB_CONFIGS; attempt++) {
++
++      /* Get list of possible frame buffer configurations */
++      fbConfigs = ChooseFBConfig(dpy, screen, fbAttribs[attempt], &nConfigs);
++      if (nConfigs==0 || !fbConfigs) {
++         printf("Note: glXChooseFBConfig(%s) failed\n", fbString[attempt]);
++         XFree(fbConfigs);
++         continue;
++      }
++
++#if 0 /*DEBUG*/
++      for (i=0;i<nConfigs;i++) {
++         printf("Config %d\n", i);
++         PrintFBConfigInfo(dpy, screen, fbConfigs[i], 0);
++      }
++#endif
++
++      /* Create the pbuffer using first fbConfig in the list that works. */
++      for (i=0;i<nConfigs;i++) {
++         pBuffer = CreatePbuffer(dpy, screen, fbConfigs[i], width, height, largest, preserve);
++         if (pBuffer) {
++            gFBconfig = fbConfigs[i];
++            gWidth = width;
++            gHeight = height;
++            break;
++         }
++      }
++
++      if (pBuffer!=None) {
++         break;
++      }
++   }
++
++   if (pBuffer) {
++      printf("Using: %s\n", fbString[attempt]);
++   }
++
++   XFree(fbConfigs);
++
++   return pBuffer;
++#undef NUM_FB_CONFIGS
++}
++
++
++
++/*
++ * Do all the X / GLX setup stuff.
++ */
++static int
++Setup(int width, int height)
++{
++   int pbSupport;
++   XVisualInfo *visInfo;
++
++   /* Open the X display */
++   gDpy = XOpenDisplay(NULL);
++   if (!gDpy) {
++      printf("Error: couldn't open default X display.\n");
++      return 0;
++   }
++
++   /* Get default screen */
++   gScreen = DefaultScreen(gDpy);
++
++   /* Test that pbuffers are available */
++   pbSupport = QueryPbuffers(gDpy, gScreen);
++   if (pbSupport == 1) {
++      printf("Using GLX 1.3 Pbuffers\n");
++   }
++   else if (pbSupport == 2) {
++      printf("Using SGIX Pbuffers\n");
++   }
++   else {
++      printf("Error: pbuffers not available on this screen\n");
++      XCloseDisplay(gDpy);
++      return 0;
++   }
++
++   /* Create Pbuffer */
++   gPBuffer = MakePbuffer( gDpy, gScreen, width, height );
++   if (gPBuffer==None) {
++      printf("Error: couldn't create pbuffer\n");
++      XCloseDisplay(gDpy);
++      return 0;
++   }
++
++   /* Test drawable queries */
++   {
++      unsigned int v;
++      glXQueryDrawable( gDpy, gPBuffer, GLX_WIDTH, &v);
++      printf("GLX_WIDTH = %u\n", v);
++      glXQueryDrawable( gDpy, gPBuffer, GLX_HEIGHT, &v);
++      printf("GLX_HEIGHT = %u\n", v);
++      glXQueryDrawable( gDpy, gPBuffer, GLX_PRESERVED_CONTENTS, &v);
++      printf("GLX_PRESERVED_CONTENTS = %u\n", v);
++      glXQueryDrawable( gDpy, gPBuffer, GLX_LARGEST_PBUFFER, &v);
++      printf("GLX_LARGEST_PBUFFER = %u\n", v);
++      glXQueryDrawable( gDpy, gPBuffer, GLX_FBCONFIG_ID, &v);
++      printf("GLX_FBCONFIG_ID = %u\n", v);
++   }
++
++   /* Get corresponding XVisualInfo */
++   visInfo = GetVisualFromFBConfig(gDpy, gScreen, gFBconfig);
++   if (!visInfo) {
++      printf("Error: can't get XVisualInfo from FBconfig\n");
++      XCloseDisplay(gDpy);
++      return 0;
++   }
++
++   /* Create GLX context */
++   glCtx = glXCreateContext(gDpy, visInfo, NULL, True);
++   if (!glCtx) {
++      /* try indirect */
++      glCtx = glXCreateContext(gDpy, visInfo, NULL, False);
++      if (!glCtx) {
++         printf("Error: Couldn't create GLXContext\n");
++         XFree(visInfo);
++         XCloseDisplay(gDpy);
++         return 0;
++      }
++      else {
++         printf("Warning: using indirect GLXContext\n");
++      }
++   }
++
++   /* Bind context to pbuffer */
++   if (!glXMakeCurrent(gDpy, gPBuffer, glCtx)) {
++      printf("Error: glXMakeCurrent failed\n");
++      XFree(visInfo);
++      XCloseDisplay(gDpy);
++      return 0;
++   }
++
++   return 1;  /* Success!! */
++}
++
++
++
++/* One-time GL setup */
++static void
++InitGL(void)
++{
++   static GLfloat pos[4] = {0.0, 0.0, 10.0, 0.0};
++   glEnable(GL_LIGHTING);
++   glEnable(GL_LIGHT0);
++   glLightfv(GL_LIGHT0, GL_POSITION, pos);
++   glEnable(GL_NORMALIZE);
++   glEnable(GL_DEPTH_TEST);
++   glEnable(GL_CULL_FACE);
++
++   glViewport(0, 0, gWidth, gHeight);
++   glMatrixMode( GL_PROJECTION );
++   glLoadIdentity();
++   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
++   glMatrixMode( GL_MODELVIEW );
++   glLoadIdentity();
++   glTranslatef( 0.0, 0.0, -15.0 );
++}
++
++
++/* Return random float in [0,1] */
++static float
++Random(void)
++{
++   int i = rand();
++   return (float) (i % 1000) / 1000.0;
++}
++
++
++static void
++RandomColor(void)
++{
++   GLfloat c[4];
++   c[0] = Random();
++   c[1] = Random();
++   c[2] = Random();
++   c[3] = 1.0;
++   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c);
++}
++
++
++/* This function borrowed from Mark Kilgard's GLUT */
++static void
++drawBox(GLfloat x0, GLfloat x1, GLfloat y0, GLfloat y1,
++  GLfloat z0, GLfloat z1, GLenum type)
++{
++  static GLfloat n[6][3] =
++  {
++    {-1.0, 0.0, 0.0},
++    {0.0, 1.0, 0.0},
++    {1.0, 0.0, 0.0},
++    {0.0, -1.0, 0.0},
++    {0.0, 0.0, 1.0},
++    {0.0, 0.0, -1.0}
++  };
++  static GLint faces[6][4] =
++  {
++    {0, 1, 2, 3},
++    {3, 2, 6, 7},
++    {7, 6, 5, 4},
++    {4, 5, 1, 0},
++    {5, 6, 2, 1},
++    {7, 4, 0, 3}
++  };
++  GLfloat v[8][3], tmp;
++  GLint i;
++
++  if (x0 > x1) {
++    tmp = x0;
++    x0 = x1;
++    x1 = tmp;
++  }
++  if (y0 > y1) {
++    tmp = y0;
++    y0 = y1;
++    y1 = tmp;
++  }
++  if (z0 > z1) {
++    tmp = z0;
++    z0 = z1;
++    z1 = tmp;
++  }
++  v[0][0] = v[1][0] = v[2][0] = v[3][0] = x0;
++  v[4][0] = v[5][0] = v[6][0] = v[7][0] = x1;
++  v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0;
++  v[2][1] = v[3][1] = v[6][1] = v[7][1] = y1;
++  v[0][2] = v[3][2] = v[4][2] = v[7][2] = z0;
++  v[1][2] = v[2][2] = v[5][2] = v[6][2] = z1;
++
++  for (i = 0; i < 6; i++) {
++    glBegin(type);
++    glNormal3fv(&n[i][0]);
++    glVertex3fv(&v[faces[i][0]][0]);
++    glVertex3fv(&v[faces[i][1]][0]);
++    glVertex3fv(&v[faces[i][2]][0]);
++    glVertex3fv(&v[faces[i][3]][0]);
++    glEnd();
++  }
++}
++
++
++
++/* Render a scene */
++static void
++Render(void)
++{
++   int NumBoxes = 100;
++   int i;
++
++   glClearColor(0.2, 0.2, 0.9, 0.0);
++   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++   for (i=0;i<NumBoxes;i++) {
++      float tx = -2.0 + 4.0 * Random();
++      float ty = -2.0 + 4.0 * Random();
++      float tz =  4.0 - 16.0 * Random();
++      float sx = 0.1 + Random() * 0.4;
++      float sy = 0.1 + Random() * 0.4;
++      float sz = 0.1 + Random() * 0.4;
++      float rx = Random();
++      float ry = Random();
++      float rz = Random();
++      float ra = Random() * 360.0;
++      glPushMatrix();
++      glTranslatef(tx, ty, tz);
++      glRotatef(ra, rx, ry, rz);
++      glScalef(sx, sy, sz);
++      RandomColor();
++      drawBox(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, GL_POLYGON);
++      glPopMatrix();
++   }
++
++   glFinish();
++}
++
++
++
++static void
++WriteFile(const char *filename)
++{
++   FILE *f;
++   GLubyte *image;
++   int i;
++
++   image = malloc(gWidth * gHeight * 3 * sizeof(GLubyte));
++   if (!image) {
++      printf("Error: couldn't allocate image buffer\n");
++      return;
++   }
++
++   glPixelStorei(GL_PACK_ALIGNMENT, 1);
++   glReadPixels(0, 0, gWidth, gHeight, GL_RGB, GL_UNSIGNED_BYTE, image);
++
++   f = fopen(filename, "w");
++   if (!f) {
++      printf("Couldn't open image file: %s\n", filename);
++      return;
++   }
++   fprintf(f,"P6\n");
++   fprintf(f,"# ppm-file created by %s\n", "trdemo2");
++   fprintf(f,"%i %i\n", gWidth, gHeight);
++   fprintf(f,"255\n");
++   fclose(f);
++   f = fopen(filename, "ab");  /* now append binary data */
++   if (!f) {
++      printf("Couldn't append to image file: %s\n", filename);
++      return;
++   }
++
++   for (i=0;i<gHeight;i++) {
++      GLubyte *rowPtr;
++      /* Remember, OpenGL images are bottom to top.  Have to reverse. */
++      rowPtr = image + (gHeight-1-i) * gWidth*3;
++      fwrite(rowPtr, 1, gWidth*3, f);
++   }
++
++   fclose(f);
++   free(image);
++
++   printf("Wrote %d by %d image file: %s\n", gWidth, gHeight, filename);
++}
++
++
++
++/*
++ * Print message describing command line parameters.
++ */
++static void
++Usage(const char *appName)
++{
++   printf("Usage:\n");
++   printf("  %s width height imgfile\n", appName);
++   printf("Where imgfile is a ppm file\n");
++}
++
++
++
++int
++main(int argc, char *argv[])
++{
++   if (argc!=4) {
++      Usage(argv[0]);
++   }
++   else {
++      int width = atoi(argv[1]);
++      int height = atoi(argv[2]);
++      char *fileName = argv[3];
++      if (width<=0) {
++         printf("Error: width parameter must be at least 1.\n");
++         return 1;
++      }
++      if (height<=0) {
++         printf("Error: height parameter must be at least 1.\n");
++         return 1;
++      }
++      if (!Setup(width, height)) {
++         return 1;
++      }
++      InitGL();
++      Render();
++      WriteFile(fileName);
++      DestroyPbuffer(gDpy, gScreen, gPBuffer);
++   }
++   return 0;
++}
++
+diff -Naurp Mesa-7.8.1/progs/xdemos/pbinfo.c Mesa-7.8.1.patched/progs/xdemos/pbinfo.c
+--- Mesa-7.8.1/progs/xdemos/pbinfo.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/pbinfo.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,107 @@
++
++/*
++ * Print list of fbconfigs and test each to see if a pbuffer can be created
++ * for that config.
++ *
++ * Brian Paul
++ * April 1997
++ * Updated on 5 October 2002.
++ */
++
++
++#include <X11/Xlib.h>
++#include <stdio.h>
++#include <string.h>
++#include "pbutil.h"
++
++
++
++
++static void
++PrintConfigs(Display *dpy, int screen, Bool horizFormat)
++{
++   FBCONFIG *fbConfigs;
++   int nConfigs;
++   int i;
++
++   fbConfigs = GetAllFBConfigs(dpy, screen, &nConfigs);
++   if (!nConfigs || !fbConfigs) {
++      printf("Error: glxGetFBConfigs failed\n");
++      XFree(fbConfigs);
++      return;
++   }
++
++   printf("Number of fbconfigs: %d\n", nConfigs);
++
++   if (horizFormat) {
++      printf("  ID        VisualType  Depth Lvl RGB CI DB Stereo  R  G  B  A");
++      printf("   Z  S  AR AG AB AA  MSbufs MSnum  Pbuffer  Float\n");
++   }
++
++   /* Print config info */
++   for (i = 0; i < nConfigs; i++) {
++      PrintFBConfigInfo(dpy, screen, fbConfigs[i], horizFormat);
++   }
++
++   /* free the list */
++   XFree(fbConfigs);
++}
++
++
++
++static void
++PrintUsage(void)
++{
++   printf("Options:\n");
++   printf("  -display <display-name>  specify X display name\n");
++   printf("  -t                       print in tabular format\n");
++   printf("  -v                       print in verbose format\n");
++   printf("  -help                    print this information\n");
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   Display *dpy;
++   int scrn;
++   char *dpyName = NULL;
++   Bool horizFormat = True;
++   int i;
++
++   for (i=1; i<argc; i++) {
++      if (strcmp(argv[i],"-display")==0) {
++	 if (i+1<argc) {
++	    dpyName = argv[i+1];
++	    i++;
++	 }
++      }
++      else if (strcmp(argv[i],"-t")==0) {
++	 /* tabular format */
++	 horizFormat = True;
++      }
++      else if (strcmp(argv[i],"-v")==0) {
++	 /* verbose format */
++	 horizFormat = False;
++      }
++      else if (strcmp(argv[i],"-help")==0) {
++	 PrintUsage();
++	 return 0;
++      }
++      else {
++	 printf("Unknown option: %s\n", argv[i]);
++      }
++   }
++
++   dpy = XOpenDisplay(dpyName);
++
++   if (!dpy) {
++      printf("Error: couldn't open display %s\n", XDisplayName(dpyName));
++      return 1;
++   }
++
++   scrn = DefaultScreen(dpy);
++   PrintConfigs(dpy, scrn, horizFormat);
++   XCloseDisplay(dpy);
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/pbutil.c Mesa-7.8.1.patched/progs/xdemos/pbutil.c
+--- Mesa-7.8.1/progs/xdemos/pbutil.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/pbutil.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,446 @@
++
++/*
++ * OpenGL pbuffers utility functions.
++ *
++ * Brian Paul
++ * Original code: April 1997
++ * Updated on 5 October 2002
++ * Updated again on 3 January 2005 to use GLX 1.3 functions in preference
++ * to the GLX_SGIX_fbconfig/pbuffer extensions.
++ */
++
++#include <stdio.h>
++#include <string.h>
++#include "pbutil.h"
++
++
++/**
++ * Test if we pixel buffers are available for a particular X screen.
++ * Input:  dpy - the X display
++ *         screen - screen number
++ * Return:  0 = fbconfigs not available.
++ *          1 = fbconfigs are available via GLX 1.3.
++ *          2 = fbconfigs and pbuffers are available via GLX_SGIX_fbconfig
++ */
++int
++QueryFBConfig(Display *dpy, int screen)
++{
++#if defined(GLX_VERSION_1_3)
++   {
++      /* GLX 1.3 supports pbuffers */
++      int glxVersionMajor, glxVersionMinor;
++      if (!glXQueryVersion(dpy, &glxVersionMajor, &glxVersionMinor)) {
++         /* GLX not available! */
++         return 0;
++      }
++      if (glxVersionMajor * 100 + glxVersionMinor >= 103) {
++         return 1;
++      }
++      /* fall-through */
++   }
++#endif
++
++   /* Try the SGIX extensions */
++   {
++      char *extensions;
++      extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
++      if (extensions && strstr(extensions,"GLX_SGIX_fbconfig")) {
++	 return 2;
++      }
++   }
++
++   return 0;
++}
++
++/**
++ * Test if we pixel buffers are available for a particular X screen.
++ * Input:  dpy - the X display
++ *         screen - screen number
++ * Return:  0 = pixel buffers not available.
++ *          1 = pixel buffers are available via GLX 1.3.
++ *          2 = pixel buffers are available via GLX_SGIX_fbconfig/pbuffer.
++ */
++int
++QueryPbuffers(Display *dpy, int screen)
++{
++   int ret;
++
++   ret = QueryFBConfig(dpy, screen);
++   if (ret == 2) {
++      char *extensions;
++      extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
++      if (extensions && strstr(extensions, "GLX_SGIX_pbuffer"))
++	 return 2;
++      else
++	 return 0;
++   }
++   else
++      return ret;
++}
++
++FBCONFIG *
++ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs)
++{
++   int fbcSupport = QueryPbuffers(dpy, screen);
++#if defined(GLX_VERSION_1_3)
++   if (fbcSupport == 1) {
++      return glXChooseFBConfig(dpy, screen, attribs, nConfigs);
++   }
++#endif
++#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
++   if (fbcSupport == 2) {
++      return glXChooseFBConfigSGIX(dpy, screen, (int *) attribs, nConfigs);
++   }
++#endif
++   return NULL;
++}
++
++
++FBCONFIG *
++GetAllFBConfigs(Display *dpy, int screen, int *nConfigs)
++{
++   int fbcSupport = QueryFBConfig(dpy, screen);
++#if defined(GLX_VERSION_1_3)
++   if (fbcSupport == 1) {
++      return glXGetFBConfigs(dpy, screen, nConfigs);
++   }
++#endif
++#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
++   if (fbcSupport == 2) {
++      /* The GLX_SGIX_fbconfig extensions says to pass NULL to get list
++       * of all available configurations.
++       */
++      return glXChooseFBConfigSGIX(dpy, screen, NULL, nConfigs);
++   }
++#endif
++   return NULL;
++}
++
++
++XVisualInfo *
++GetVisualFromFBConfig(Display *dpy, int screen, FBCONFIG config)
++{
++   int fbcSupport = QueryFBConfig(dpy, screen);
++#if defined(GLX_VERSION_1_3)
++   if (fbcSupport == 1) {
++      return glXGetVisualFromFBConfig(dpy, config);
++   }
++#endif
++#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
++   if (fbcSupport == 2) {
++      return glXGetVisualFromFBConfigSGIX(dpy, config);
++   }
++#endif
++   return NULL;
++}
++
++
++/**
++ * Either use glXGetFBConfigAttrib() or glXGetFBConfigAttribSGIX()
++ * to query an fbconfig attribute.
++ */
++static int
++GetFBConfigAttrib(Display *dpy, int screen,
++#if defined(GLX_VERSION_1_3)
++                  const GLXFBConfig config,
++#elif defined(GLX_SGIX_fbconfig)
++                  const GLXFBConfigSGIX config,
++#endif
++                  int attrib
++                  )
++{
++   int fbcSupport = QueryFBConfig(dpy, screen);
++   int value = 0;
++
++#if defined(GLX_VERSION_1_3)
++   if (fbcSupport == 1) {
++      /* ok */
++      if (glXGetFBConfigAttrib(dpy, config, attrib, &value) != 0) {
++         value = 0;
++      }
++      return value;
++   }
++   /* fall-through */
++#endif
++
++#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
++   if (fbcSupport == 2) {
++      if (glXGetFBConfigAttribSGIX(dpy, config, attrib, &value) != 0) {
++         value = 0;
++      }
++      return value;
++   }
++#endif
++   
++   return value;
++}
++
++
++
++/**
++ * Print parameters for a GLXFBConfig to stdout.
++ * Input:  dpy - the X display
++ *         screen - the X screen number
++ *         fbConfig - the fbconfig handle
++ *         horizFormat - if true, print in horizontal format
++ */
++void
++PrintFBConfigInfo(Display *dpy, int screen, FBCONFIG config, Bool horizFormat)
++{
++   PBUFFER pBuffer;
++   int width=2, height=2;
++   int bufferSize, level, doubleBuffer, stereo, auxBuffers;
++   int redSize, greenSize, blueSize, alphaSize;
++   int depthSize, stencilSize;
++   int accumRedSize, accumBlueSize, accumGreenSize, accumAlphaSize;
++   int sampleBuffers, samples;
++   int drawableType, renderType, xRenderable, xVisual, id;
++   int maxWidth, maxHeight, maxPixels;
++   int optWidth, optHeight;
++   int floatComponents = 0;
++
++   /* do queries using the GLX 1.3 tokens (same as the SGIX tokens) */
++   bufferSize     = GetFBConfigAttrib(dpy, screen, config, GLX_BUFFER_SIZE);
++   level          = GetFBConfigAttrib(dpy, screen, config, GLX_LEVEL);
++   doubleBuffer   = GetFBConfigAttrib(dpy, screen, config, GLX_DOUBLEBUFFER);
++   stereo         = GetFBConfigAttrib(dpy, screen, config, GLX_STEREO);
++   auxBuffers     = GetFBConfigAttrib(dpy, screen, config, GLX_AUX_BUFFERS);
++   redSize        = GetFBConfigAttrib(dpy, screen, config, GLX_RED_SIZE);
++   greenSize      = GetFBConfigAttrib(dpy, screen, config, GLX_GREEN_SIZE);
++   blueSize       = GetFBConfigAttrib(dpy, screen, config, GLX_BLUE_SIZE);
++   alphaSize      = GetFBConfigAttrib(dpy, screen, config, GLX_ALPHA_SIZE);
++   depthSize      = GetFBConfigAttrib(dpy, screen, config, GLX_DEPTH_SIZE);
++   stencilSize    = GetFBConfigAttrib(dpy, screen, config, GLX_STENCIL_SIZE);
++   accumRedSize   = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_RED_SIZE);
++   accumGreenSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_GREEN_SIZE);
++   accumBlueSize  = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_BLUE_SIZE);
++   accumAlphaSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_ALPHA_SIZE);
++   sampleBuffers  = GetFBConfigAttrib(dpy, screen, config, GLX_SAMPLE_BUFFERS);
++   samples        = GetFBConfigAttrib(dpy, screen, config, GLX_SAMPLES);
++   drawableType   = GetFBConfigAttrib(dpy, screen, config, GLX_DRAWABLE_TYPE);
++   renderType     = GetFBConfigAttrib(dpy, screen, config, GLX_RENDER_TYPE);
++   xRenderable    = GetFBConfigAttrib(dpy, screen, config, GLX_X_RENDERABLE);
++   xVisual        = GetFBConfigAttrib(dpy, screen, config, GLX_X_VISUAL_TYPE);
++   if (!xRenderable || !(drawableType & GLX_WINDOW_BIT_SGIX))
++      xVisual = -1;
++
++   id        = GetFBConfigAttrib(dpy, screen, config, GLX_FBCONFIG_ID);
++   maxWidth  = GetFBConfigAttrib(dpy, screen, config, GLX_MAX_PBUFFER_WIDTH);
++   maxHeight = GetFBConfigAttrib(dpy, screen, config, GLX_MAX_PBUFFER_HEIGHT);
++   maxPixels = GetFBConfigAttrib(dpy, screen, config, GLX_MAX_PBUFFER_PIXELS);
++#if defined(GLX_SGIX_pbuffer)
++   optWidth  = GetFBConfigAttrib(dpy, screen, config, GLX_OPTIMAL_PBUFFER_WIDTH_SGIX);
++   optHeight = GetFBConfigAttrib(dpy, screen, config, GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX);
++#else
++   optWidth = optHeight = 0;
++#endif
++#if defined(GLX_NV_float_buffer)
++   floatComponents = GetFBConfigAttrib(dpy, screen, config, GLX_FLOAT_COMPONENTS_NV);
++#endif
++
++   /* See if we can create a pbuffer with this config */
++   pBuffer = CreatePbuffer(dpy, screen, config, width, height, False, False);
++
++   if (horizFormat) {
++      printf("0x%-9x ", id);
++      if (xVisual==GLX_STATIC_GRAY)        printf("StaticGray  ");
++      else if (xVisual==GLX_GRAY_SCALE)    printf("GrayScale   ");
++      else if (xVisual==GLX_STATIC_COLOR)  printf("StaticColor ");
++      else if (xVisual==GLX_PSEUDO_COLOR)  printf("PseudoColor ");
++      else if (xVisual==GLX_TRUE_COLOR)    printf("TrueColor   ");
++      else if (xVisual==GLX_DIRECT_COLOR)  printf("DirectColor ");
++      else                            printf("  -none-    ");
++      printf(" %3d %3d   %s   %s  %s   %2s   ", bufferSize, level,
++	     (renderType & GLX_RGBA_BIT_SGIX) ? "y" : ".",
++	     (renderType & GLX_COLOR_INDEX_BIT_SGIX) ? "y" : ".",
++	     doubleBuffer ? "y" : ".",
++	     stereo ? "y" : ".");
++      printf("%2d %2d %2d %2d  ", redSize, greenSize, blueSize, alphaSize);
++      printf("%2d %2d  ", depthSize, stencilSize);
++      printf("%2d %2d %2d %2d", accumRedSize, accumGreenSize, accumBlueSize,
++	     accumAlphaSize);
++      printf("    %2d    %2d", sampleBuffers, samples);
++      printf("       %s       %c", pBuffer ? "y" : ".",
++             ".y"[floatComponents]);
++      printf("\n");
++   }
++   else {
++      printf("Id 0x%x\n", id);
++      printf("  Buffer Size: %d\n", bufferSize);
++      printf("  Level: %d\n", level);
++      printf("  Double Buffer: %s\n", doubleBuffer ? "yes" : "no");
++      printf("  Stereo: %s\n", stereo ? "yes" : "no");
++      printf("  Aux Buffers: %d\n", auxBuffers);
++      printf("  Red Size: %d\n", redSize);
++      printf("  Green Size: %d\n", greenSize);
++      printf("  Blue Size: %d\n", blueSize);
++      printf("  Alpha Size: %d\n", alphaSize);
++      printf("  Depth Size: %d\n", depthSize);
++      printf("  Stencil Size: %d\n", stencilSize);
++      printf("  Accum Red Size: %d\n", accumRedSize);
++      printf("  Accum Green Size: %d\n", accumGreenSize);
++      printf("  Accum Blue Size: %d\n", accumBlueSize);
++      printf("  Accum Alpha Size: %d\n", accumAlphaSize);
++      printf("  Sample Buffers: %d\n", sampleBuffers);
++      printf("  Samples/Pixel: %d\n", samples);
++      printf("  Drawable Types: ");
++      if (drawableType & GLX_WINDOW_BIT)  printf("Window ");
++      if (drawableType & GLX_PIXMAP_BIT)  printf("Pixmap ");
++      if (drawableType & GLX_PBUFFER_BIT)  printf("PBuffer");
++      printf("\n");
++      printf("  Render Types: ");
++      if (renderType & GLX_RGBA_BIT_SGIX)  printf("RGBA ");
++      if (renderType & GLX_COLOR_INDEX_BIT_SGIX)  printf("CI ");
++      printf("\n");
++      printf("  X Renderable: %s\n", xRenderable ? "yes" : "no");
++
++      printf("  Pbuffer: %s\n", pBuffer ? "yes" : "no");
++      printf("  Max Pbuffer width: %d\n", maxWidth);
++      printf("  Max Pbuffer height: %d\n", maxHeight);
++      printf("  Max Pbuffer pixels: %d\n", maxPixels);
++      printf("  Optimum Pbuffer width: %d\n", optWidth);
++      printf("  Optimum Pbuffer height: %d\n", optHeight);
++
++      printf("  Float Components: %s\n", floatComponents ? "yes" : "no");
++   }
++
++   if (pBuffer) {
++      DestroyPbuffer(dpy, screen, pBuffer);
++   }
++}
++
++
++
++GLXContext
++CreateContext(Display *dpy, int screen, FBCONFIG config)
++{
++   int fbcSupport = QueryFBConfig(dpy, screen);
++#if defined(GLX_VERSION_1_3)
++   if (fbcSupport == 1) {
++      /* GLX 1.3 */
++      GLXContext c;
++      c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, True);
++      if (!c) {
++         /* try indirect */
++         c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, False);
++      }
++      return c;
++   }
++#endif
++#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
++   if (fbcSupport == 2) {
++      GLXContext c;
++      c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, True);
++      if (!c) {
++         c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, False);
++      }
++      return c;
++   }
++#endif
++   return 0;
++}
++
++
++void
++DestroyContext(Display *dpy, GLXContext ctx)
++{
++   glXDestroyContext(dpy, ctx);
++}
++
++
++/* This is only used by CreatePbuffer() */
++static int XErrorFlag = 0;
++static int HandleXError(Display *dpy, XErrorEvent *event)
++{
++    XErrorFlag = 1;
++    return 0;
++}
++
++
++/**
++ * Create a Pbuffer.  Use an X error handler to deal with potential
++ * BadAlloc errors.
++ *
++ * Input:  dpy - the X display
++ *         fbConfig - an FBConfig as returned by glXChooseFBConfigSGIX().
++ *         width, height - size of pixel buffer to request, in pixels.
++ *         pbAttribs - list of optional pixel buffer attributes
++ * Return:  a Pbuffer or None.
++ */
++PBUFFER
++CreatePbuffer(Display *dpy, int screen, FBCONFIG config,
++              int width, int height, Bool largest, Bool preserve)
++{
++   int (*oldHandler)(Display *, XErrorEvent *);
++   PBUFFER pBuffer = None;
++   int pbSupport = QueryPbuffers(dpy, screen);
++
++   /* Catch X protocol errors with our own error handler */
++   oldHandler = XSetErrorHandler(HandleXError);
++   XErrorFlag = 0;
++
++#if defined(GLX_VERSION_1_3)
++   if (pbSupport == 1) {
++      /* GLX 1.3 */
++      int attribs[100], i = 0;
++      attribs[i++] = GLX_PBUFFER_WIDTH;
++      attribs[i++] = width;
++      attribs[i++] = GLX_PBUFFER_HEIGHT;
++      attribs[i++] = height;
++      attribs[i++] = GLX_PRESERVED_CONTENTS;
++      attribs[i++] = preserve;
++      attribs[i++] = GLX_LARGEST_PBUFFER;
++      attribs[i++] = largest;
++      attribs[i++] = 0;
++      pBuffer = glXCreatePbuffer(dpy, config, attribs);
++   }
++   else
++#endif
++#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
++   if (pbSupport == 2) {
++      int attribs[100], i = 0;
++      attribs[i++] = GLX_PRESERVED_CONTENTS;
++      attribs[i++] = preserve;
++      attribs[i++] = GLX_LARGEST_PBUFFER;
++      attribs[i++] = largest;
++      attribs[i++] = 0;
++      pBuffer = glXCreateGLXPbufferSGIX(dpy, config, width, height, attribs);
++   }
++   else
++#endif
++   {
++      pBuffer = None;
++   }
++
++   XSync(dpy, False);
++   /* Restore original X error handler */
++   (void) XSetErrorHandler(oldHandler);
++
++   /* Return pbuffer (may be None) */
++   if (!XErrorFlag && pBuffer != None) {
++      /*printf("config %d worked!\n", i);*/
++      return pBuffer;
++   }
++   else {
++      return None;
++   }
++}
++
++
++void
++DestroyPbuffer(Display *dpy, int screen, PBUFFER pbuffer)
++{
++   int pbSupport = QueryPbuffers(dpy, screen);
++#if defined(GLX_VERSION_1_3)
++   if (pbSupport == 1) {
++      glXDestroyPbuffer(dpy, pbuffer);
++      return;
++   }
++#endif
++#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
++   if (pbSupport == 2) {
++      glXDestroyGLXPbufferSGIX(dpy, pbuffer);
++      return;
++   }
++#endif
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/pbutil.h Mesa-7.8.1.patched/progs/xdemos/pbutil.h
+--- Mesa-7.8.1/progs/xdemos/pbutil.h	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/pbutil.h	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,69 @@
++/*
++ * OpenGL pbuffers utility functions.
++ *
++ * Brian Paul
++ * April 1997
++ */
++
++
++#ifndef PBUTIL_H
++#define PBUTIL_H
++
++
++#define GLX_GLXEXT_PROTOTYPES
++#include <GL/glx.h>
++
++
++#if defined(GLX_VERSION_1_3)
++#define PBUFFER GLXPbuffer
++#define FBCONFIG GLXFBConfig
++#elif defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
++#define PBUFFER GLXPbufferSGIX
++#define FBCONFIG GLXFBConfigSGIX
++#else
++#define PBUFFER int
++#define FBCONFIG int
++#endif
++
++
++extern int
++QueryFBConfig(Display *dpy, int screen);
++
++extern int
++QueryPbuffers(Display *dpy, int screen);
++
++
++extern void
++PrintFBConfigInfo(Display *dpy, int screen, FBCONFIG config, Bool horizFormat);
++
++
++extern FBCONFIG *
++ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs);
++
++
++extern FBCONFIG *
++GetAllFBConfigs(Display *dpy, int screen, int *nConfigs);
++
++
++extern XVisualInfo *
++GetVisualFromFBConfig(Display *dpy, int screen, FBCONFIG config);
++
++
++extern GLXContext
++CreateContext(Display *dpy, int screen, FBCONFIG config);
++
++
++extern void
++DestroyContext(Display *dpy, GLXContext ctx);
++
++
++extern PBUFFER
++CreatePbuffer(Display *dpy, int screen, FBCONFIG config,
++	      int width, int height, Bool preserve, Bool largest);
++
++
++extern void
++DestroyPbuffer(Display *dpy, int screen, PBUFFER pbuffer);
++
++
++#endif  /*PBUTIL_H*/
+diff -Naurp Mesa-7.8.1/progs/xdemos/shape.c Mesa-7.8.1.patched/progs/xdemos/shape.c
+--- Mesa-7.8.1/progs/xdemos/shape.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/shape.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,393 @@
++
++/*
++ * Example of using the X "shape" extension with OpenGL:  render a spinning
++ * cube inside of a non-rectangular window.
++ *
++ * Press ESC to exit.  Press up/down to change window shape.
++ *
++ * To compile add "shape" to the PROGS list in Makefile.
++ *
++ * Brian Paul
++ * June 16, 1997
++ *
++ * This program is in the public domain.
++ */
++
++
++#include <math.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <sys/time.h>
++#include <time.h>
++#include <unistd.h>
++#include <X11/Xlib.h>
++#include <X11/Xutil.h>
++#include <X11/keysym.h>
++#include <X11/extensions/shape.h>
++#include <GL/glx.h>
++
++#ifndef PI
++#define PI 3.1415926
++#endif
++
++
++static int Width=500, Height=500;
++
++static float Xangle = 0.0, Yangle = 0.0;
++static int Sides = 5;
++static int MinSides = 3;
++static int MaxSides = 20;
++
++
++/* return current time (in seconds) */
++static double
++current_time(void)
++{
++   struct timeval tv;
++#ifdef __VMS
++   (void) gettimeofday(&tv, NULL );
++#else
++   struct timezone tz;
++   (void) gettimeofday(&tv, &tz);
++#endif
++   return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
++}
++
++
++/*
++ * Draw the OpenGL stuff and do a SwapBuffers.
++ */
++static void display(Display *dpy, Window win)
++{
++   float scale = 1.7;
++
++   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++   glPushMatrix();
++
++   glScalef(scale, scale, scale);
++   glRotatef(Xangle, 1.0, 0.0, 0.0);
++   glRotatef(Yangle, 0.0, 1.0, 0.0);
++
++   /*
++    * wireframe box
++    */
++   glColor3f(1.0, 1.0, 1.0);
++   glBegin(GL_LINE_LOOP);
++   glVertex3f(-1.0, -1.0, -1.0);
++   glVertex3f( 1.0, -1.0, -1.0);
++   glVertex3f( 1.0,  1.0, -1.0);
++   glVertex3f(-1.0,  1.0, -1.0);
++   glEnd();
++
++   glBegin(GL_LINE_LOOP);
++   glVertex3f(-1.0, -1.0, 1.0);
++   glVertex3f( 1.0, -1.0, 1.0);
++   glVertex3f( 1.0,  1.0, 1.0);
++   glVertex3f(-1.0,  1.0, 1.0);
++   glEnd();
++
++   glBegin(GL_LINES);
++   glVertex3f(-1.0, -1.0, -1.0);   glVertex3f(-1.0, -1.0, 1.0);
++   glVertex3f( 1.0, -1.0, -1.0);   glVertex3f( 1.0, -1.0, 1.0);
++   glVertex3f( 1.0,  1.0, -1.0);   glVertex3f( 1.0,  1.0, 1.0);
++   glVertex3f(-1.0,  1.0, -1.0);   glVertex3f(-1.0,  1.0, 1.0);
++   glEnd();
++
++   /*
++    * Solid box
++    */
++   glPushMatrix();
++   glScalef(0.75, 0.75, 0.75);
++
++   glColor3f(1, 0, 0);
++   glBegin(GL_POLYGON);
++   glVertex3f(1, -1, -1);
++   glVertex3f(1,  1, -1);
++   glVertex3f(1,  1,  1);
++   glVertex3f(1, -1,  1);
++   glEnd();
++
++   glColor3f(0, 1, 1);
++   glBegin(GL_POLYGON);
++   glVertex3f(-1, -1, -1);
++   glVertex3f(-1,  1, -1);
++   glVertex3f(-1,  1,  1);
++   glVertex3f(-1, -1,  1);
++   glEnd();
++
++   glColor3f(0, 1, 0);
++   glBegin(GL_POLYGON);
++   glVertex3f(-1, 1, -1);
++   glVertex3f( 1, 1, -1);
++   glVertex3f( 1, 1,  1);
++   glVertex3f(-1, 1,  1);
++   glEnd();
++
++   glColor3f(1, 0, 1);
++   glBegin(GL_POLYGON);
++   glVertex3f(-1, -1, -1);
++   glVertex3f( 1, -1, -1);
++   glVertex3f( 1, -1,  1);
++   glVertex3f(-1, -1,  1);
++   glEnd();
++
++   glColor3f(0, 0, 1);
++   glBegin(GL_POLYGON);
++   glVertex3f(-1, -1, 1);
++   glVertex3f( 1, -1, 1);
++   glVertex3f( 1,  1, 1);
++   glVertex3f(-1,  1, 1);
++   glEnd();
++
++   glColor3f(1, 1, 0);
++   glBegin(GL_POLYGON);
++   glVertex3f(-1, -1, -1);
++   glVertex3f( 1, -1, -1);
++   glVertex3f( 1,  1, -1);
++   glVertex3f(-1,  1, -1);
++   glEnd();
++   glPopMatrix();
++
++
++   glPopMatrix();
++
++   glXSwapBuffers(dpy, win);
++}
++
++
++/*
++ * This is called when we have to recompute the window shape bitmask.
++ * We just generate an n-sided regular polygon here but any other shape
++ * would be possible.
++ */
++static void make_shape_mask(Display *dpy, Window win, int width, int height,
++                            int sides)
++{
++   Pixmap shapeMask;
++   XGCValues xgcv;
++   GC gc;
++
++   /* allocate 1-bit deep pixmap and a GC */
++   shapeMask = XCreatePixmap(dpy, win, width, height, 1);
++   gc = XCreateGC(dpy, shapeMask, 0, &xgcv);
++
++   /* clear shapeMask to zeros */
++   XSetForeground(dpy, gc, 0);
++   XFillRectangle(dpy, shapeMask, gc, 0, 0, width, height);
++
++   /* draw mask */
++   XSetForeground(dpy, gc, 1);
++   {
++      int cx = width / 2;
++      int cy = height / 2;
++      float angle = 0.0;
++      float step = 2.0 * PI / sides;
++      float radius = width / 2;
++      int i;
++      XPoint points[100];
++      for (i=0;i<sides;i++) {
++         int x = cx + radius * sin(angle);
++         int y = cy - radius * cos(angle);
++         points[i].x = x;
++         points[i].y = y;
++         angle += step;
++      }
++      XFillPolygon(dpy, shapeMask, gc, points, sides, Convex, CoordModeOrigin);
++   }
++
++   /* This is the only SHAPE extension call- simple! */
++   XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, shapeMask, ShapeSet);
++
++   XFreeGC(dpy, gc);
++   XFreePixmap(dpy, shapeMask);
++}
++
++
++/*
++ * Called when window is resized.  Do OpenGL viewport and projection stuff.
++ */
++static void reshape(int width, int height)
++{
++   glViewport(0, 0, width, height);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glFrustum(-1.0, 1.0, -1.0, 1.0, 3.0, 20.0);
++   glMatrixMode(GL_MODELVIEW);
++   glLoadIdentity();
++   glTranslatef(0.0, 0.0, -10.0);
++
++   glEnable(GL_DEPTH_TEST);
++}
++
++
++/*
++ * Process X events.
++ */
++static void event_loop(Display *dpy, Window win)
++{
++   while (1) {
++      XEvent event;
++      if (XPending(dpy)) {
++         XNextEvent(dpy, &event);
++         switch (event.type) {
++            case Expose:
++               display(dpy, event.xexpose.window);
++               break;
++            case ConfigureNotify:
++               Width = event.xconfigure.width;
++               Height = event.xconfigure.height,
++               make_shape_mask(dpy, win, Width, Height, Sides);
++               reshape(Width, Height);
++               break;
++            case KeyPress:
++               {
++                  char buf[100];
++                  KeySym keySym;
++                  XComposeStatus stat;
++                  XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
++                  switch (keySym) {
++                     case XK_Escape:
++                        exit(0);
++                        break;
++                     case XK_Up:
++                        Sides++;
++                        if (Sides>MaxSides) Sides = MaxSides;
++                        make_shape_mask(dpy, win, Width, Height, Sides);
++                        break;
++                     case XK_Down:
++                        Sides--;
++                        if (Sides<MinSides) Sides = MinSides;
++                        make_shape_mask(dpy, win, Width, Height, Sides);
++                        break;
++                  }
++               }
++               break;
++            default:
++               ;;
++         }
++      }
++      else {
++         static double t0 = -1.0;
++         double dt, t = current_time();
++         if (t0 < 0.0)
++            t0 = t;
++         dt = t - t0;
++         Xangle += 90.0 * dt;  /* 90 degrees per second */
++         Yangle += 70.0 * dt;
++         t0 = t;
++         display(dpy, win);
++      }
++   }
++}
++
++
++/*
++ * Allocate a "nice" colormap.  This could be better (HP-CR support, etc).
++ */
++static Colormap alloc_colormap(Display *dpy, Window parent, Visual *vis)
++{
++   Screen *scr = DefaultScreenOfDisplay(dpy);
++   int scrnum = DefaultScreen(dpy);
++
++   if (MaxCmapsOfScreen(scr)==1 && vis==DefaultVisual(dpy, scrnum)) {
++      /* The window and root are of the same visual type so */
++      /* share the root colormap. */
++      return DefaultColormap(dpy, scrnum);
++   }
++   else {
++      return XCreateColormap(dpy, parent, vis, AllocNone);
++   }
++}
++
++
++int main(int argc, char *argv[])
++{
++   static int glAttribs[] = {
++      GLX_DOUBLEBUFFER,
++      GLX_RGBA,
++      GLX_DEPTH_SIZE, 1,
++      None
++   };
++   Display *dpy;
++   XVisualInfo *visInfo;
++   int scrn;
++   Window root;
++   Colormap cmap;
++   Window win;
++   XSetWindowAttributes winAttribs;
++   unsigned long winAttribsMask;
++   GLXContext glCtx;
++   int ignore;
++   const char *name = "OpenGL in a Shaped Window";
++
++   dpy = XOpenDisplay(NULL);
++   if (!dpy) {
++      fprintf(stderr, "Couldn't open default display\n");
++      return 1;
++   }
++
++   /* check that we can use the shape extension */
++   if (!XQueryExtension(dpy, "SHAPE", &ignore, &ignore, &ignore )) {
++      fprintf(stderr, "Display doesn't support shape extension\n");
++      return 1;
++   }
++
++   scrn = DefaultScreen(dpy);
++
++   root = RootWindow(dpy, scrn);
++
++   visInfo = glXChooseVisual(dpy, scrn, glAttribs);
++   if (!visInfo) {
++      fprintf(stderr, "Couldn't get RGB, DB, Z visual\n");
++      return 1;
++   }
++
++   glCtx = glXCreateContext(dpy, visInfo, 0, True);
++   if (!glCtx) {
++      fprintf(stderr, "Couldn't create GL context\n");
++      return 1;
++   }
++
++   cmap = alloc_colormap(dpy, root, visInfo->visual);
++   if (!cmap) {
++      fprintf(stderr, "Couln't create colormap\n");
++      return 1;
++   }
++
++   winAttribs.border_pixel = 0;
++   winAttribs.colormap = cmap;
++   winAttribs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   winAttribsMask = CWBorderPixel | CWColormap | CWEventMask;
++   win = XCreateWindow(dpy, root, 0, 0, Width, Height, 0,
++                       visInfo->depth, InputOutput,
++                       visInfo->visual,
++                       winAttribsMask, &winAttribs);
++
++   {
++      XSizeHints sizehints;
++      /*
++      sizehints.x = xpos;
++      sizehints.y = ypos;
++      sizehints.width  = width;
++      sizehints.height = height;
++      */
++      sizehints.flags = 0;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++
++   XMapWindow(dpy, win);
++
++   glXMakeCurrent(dpy, win, glCtx);
++
++   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
++   printf("Press ESC to exit.\n");
++   printf("Press up/down to change window shape.\n");
++
++   event_loop(dpy, win);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/sharedtex.c Mesa-7.8.1.patched/progs/xdemos/sharedtex.c
+--- Mesa-7.8.1/progs/xdemos/sharedtex.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/sharedtex.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,324 @@
++/*
++ * Test sharing of texture objects by two rendering contexts.
++ * In particular, test that changing a texture object in one context
++ * effects the texture in the second context.
++ *
++ * Brian Paul
++ * 30 Apr 2008
++ *
++ * Copyright (C) 2008  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <assert.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <X11/keysym.h>
++
++
++#define MAX_CONTEXTS 2
++
++#define TEX_SIZE 32
++
++static const char *DisplayName = NULL;
++static Display *Dpy;
++static XVisualInfo *VisInfo;
++static Window Win;
++static GLXContext Contexts[MAX_CONTEXTS];
++static int WinWidth = 300, WinHeight = 300;
++
++static int DrawContext = 0, TexContext = 1;
++
++static GLuint TexObj = 0;
++static GLboolean NewTexture = GL_FALSE;
++
++
++static void
++Error(const char *msg)
++{
++   fprintf(stderr, "sharedtex error: %s\n", msg);
++   exit(1);
++}
++
++
++static void
++CreateWindow(const char *name)
++{
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   int xpos = 0, ypos = 0;
++   static int n = 0;
++
++   scrnum = DefaultScreen(Dpy);
++   root = RootWindow(Dpy, scrnum);
++
++   VisInfo = glXChooseVisual(Dpy, scrnum, attrib);
++   if (!VisInfo) {
++      Error("Unable to find RGB, double-buffered visual");
++   }
++
++   /* window attributes */
++   xpos = (n % 10) * 100;
++   ypos = (n / 10) * 100;
++   n++;
++
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap(Dpy, root, VisInfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   Win = XCreateWindow(Dpy, root, xpos, ypos, WinWidth, WinHeight,
++		        0, VisInfo->depth, InputOutput,
++		        VisInfo->visual, mask, &attr);
++   if (!Win) {
++      Error("Couldn't create window");
++   }
++
++   {
++      XSizeHints sizehints;
++      sizehints.x = xpos;
++      sizehints.y = ypos;
++      sizehints.width  = WinWidth;
++      sizehints.height = WinHeight;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(Dpy, Win, &sizehints);
++      XSetStandardProperties(Dpy, Win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   XMapWindow(Dpy, Win);
++}
++
++
++/**
++ * Change texture image, using TexContext
++ */
++static void
++ModifyTexture(void)
++{
++   GLuint tex[TEX_SIZE][TEX_SIZE];
++   GLuint c0, c1;
++   int i, j;
++
++   if (Win && !glXMakeCurrent(Dpy, Win, Contexts[TexContext])) {
++      Error("glXMakeCurrent failed");
++   }
++
++   /* choose two random colors */
++   c0 = rand() & 0xffffffff;
++   c1 = rand() & 0xffffffff;
++
++   for (i = 0; i < TEX_SIZE; i++) {
++      for (j = 0; j < TEX_SIZE; j++) {
++         if (((i / 4) ^ (j / 4)) & 1) {
++            tex[i][j] = c0;
++         }
++         else {
++            tex[i][j] = c1;
++         }
++      }
++   }
++
++   glBindTexture(GL_TEXTURE_2D, TexObj);
++   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0,
++                GL_RGBA, GL_UNSIGNED_BYTE, tex);
++
++   NewTexture = GL_TRUE;
++}
++
++
++static void
++InitContext(void)
++{
++   glGenTextures(1, &TexObj);
++   assert(TexObj);
++   glBindTexture(GL_TEXTURE_2D, TexObj);
++   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++   glEnable(GL_TEXTURE_2D);
++
++   printf("GL_RENDERER = %s\n", (char*) glGetString(GL_RENDERER));
++}
++
++
++static void
++Setup(void)
++{
++   int i;
++
++   Dpy = XOpenDisplay(DisplayName);
++   if (!Dpy) {
++      Error("Unable to open display");
++   }
++
++   CreateWindow("sharedtex");
++
++   for (i = 0; i < MAX_CONTEXTS; i++) {
++      GLXContext share = i > 0 ? Contexts[0] : 0;
++
++      Contexts[i] = glXCreateContext(Dpy, VisInfo, share, True);
++      if (!Contexts[i]) {
++         Error("Unable to create GLX context");
++      }
++
++      if (!glXMakeCurrent(Dpy, Win, Contexts[i])) {
++         Error("glXMakeCurrent failed");
++      }
++
++      InitContext();
++   }
++
++   ModifyTexture();
++}
++
++
++/**
++ * Redraw window, using DrawContext
++ */
++static void
++Redraw(void)
++{
++   static float rot = 0.0;
++   float ar;
++
++   rot += 1.0;
++
++   if (Win && !glXMakeCurrent(Dpy, Win, Contexts[DrawContext])) {
++      Error("glXMakeCurrent failed");
++   }
++
++   glViewport(0, 0, WinWidth, WinHeight);
++   ar = (float) WinWidth / (float) WinHeight;
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glOrtho(-ar, ar, -1.0, 1.0, -1.0, 1.0);
++   glMatrixMode(GL_MODELVIEW);
++
++   glShadeModel(GL_FLAT);
++   glClearColor(0.5, 0.5, 0.5, 1.0);
++   glClear(GL_COLOR_BUFFER_BIT);
++
++   glPushMatrix();
++   glRotatef(rot, 0, 0, 1);
++   glScalef(0.7, 0.7, 0.7);
++
++   if (NewTexture) {
++      /* rebind to get new contents */
++      glBindTexture(GL_TEXTURE_2D, TexObj);
++      NewTexture = GL_FALSE;
++   }
++
++   /* draw textured quad */
++   glBegin(GL_POLYGON);
++   glTexCoord2f( 0.0, 0.0 );   glVertex2f( -1.0, -1.0 );
++   glTexCoord2f( 1.0, 0.0 );   glVertex2f(  1.0, -1.0 );
++   glTexCoord2f( 1.0, 1.0 );   glVertex2f(  1.0,  1.0 );
++   glTexCoord2f( 0.0, 1.0 );   glVertex2f( -1.0,  1.0 );
++   glEnd();
++
++   glPopMatrix();
++
++   if (Win)
++      glXSwapBuffers(Dpy, Win);
++}
++
++
++static void
++EventLoop(void)
++{
++   while (1) {
++      while (XPending(Dpy) > 0) {
++         XEvent event;
++         XNextEvent(Dpy, &event);
++
++         switch (event.type) {
++         case Expose:
++            Redraw();
++            break;
++         case ConfigureNotify:
++            WinWidth = event.xconfigure.width;
++            WinHeight = event.xconfigure.height;
++            break;
++         case KeyPress:
++            {
++               char buf[100];
++               KeySym keySym;
++               XComposeStatus stat;
++               XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
++               switch (keySym) {
++               case XK_Escape:
++                  exit(0);
++                  break;
++               case XK_t:
++               case XK_T:
++                  ModifyTexture();
++                  break;
++               default:
++                  ;
++               }
++            }
++            Redraw();
++            break;
++         default:
++            /*no-op*/ ;
++         }
++      }
++
++      Redraw();
++      usleep(10000);
++   }
++}
++
++
++
++
++int
++main(int argc, char *argv[])
++{
++   int i;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0 && i < argc) {
++         DisplayName = argv[i+1];
++         i++;
++      }
++   }
++
++   Setup();
++
++   printf("Press 't' to change texture image/colors\n");
++
++   EventLoop();
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/sharedtex_mt.c Mesa-7.8.1.patched/progs/xdemos/sharedtex_mt.c
+--- Mesa-7.8.1/progs/xdemos/sharedtex_mt.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/sharedtex_mt.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,490 @@
++/* $Id: sharedtex.c,v 1.2 2002/01/16 14:32:46 joukj Exp $ */
++
++/*
++ * Test sharing of display lists and texture objects between GLX contests.
++ * Brian Paul
++ * Summer 2000
++ *
++ *
++ * Copyright (C) 2000  Brian Paul   All Rights Reserved.
++ *
++ * 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
++ * BRIAN PAUL 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.
++ *
++ *
++ * Modified 2009 for multithreading by Thomas Hellstrom.
++ */
++
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <pthread.h>
++#include <X11/X.h>
++
++struct thread_init_arg {
++   int id;
++};
++
++struct window {
++   pthread_mutex_t drawMutex;
++   char DisplayName[1000];
++   Display *Dpy;
++   Window Win;
++   GLXContext Context;
++   float Angle;
++   int Id;
++   XVisualInfo *visInfo;
++};
++
++
++#define MAX_WINDOWS 20
++static struct window Windows[MAX_WINDOWS];
++static int NumWindows = 0;
++static int terminate = 0;
++static GLXContext gCtx;
++static Display *gDpy;
++static GLuint Textures[3];
++
++
++
++static void
++Error(const char *display, const char *msg)
++{
++   fprintf(stderr, "Error on display %s - %s\n", display, msg);
++   exit(1);
++}
++
++
++static int
++initMainthread(Display *dpy, const char *displayName)
++{
++   int scrnum;
++   XVisualInfo *visinfo;
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++                    GLX_DEPTH_SIZE, 1,
++		    None };
++
++   scrnum = DefaultScreen(dpy);
++   visinfo = glXChooseVisual(dpy, scrnum, attrib);
++   if (!visinfo) {
++      Error(displayName, "Unable to find RGB, double-buffered visual");
++      return -1;
++   }
++   gCtx = glXCreateContext(dpy, visinfo, NULL, True);
++   if (!gCtx) {
++      Error(displayName, "Couldn't create GLX context");
++      return -1;
++   }
++   return 0;
++}
++
++static struct window *
++AddWindow(Display *dpy, const char *displayName, int xpos, int ypos,
++          GLXContext sCtx)
++{
++   Window win;
++   GLXContext ctx;
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++                    GLX_DEPTH_SIZE, 1,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   XVisualInfo *visinfo;
++   int width = 300, height = 300;
++
++   if (NumWindows >= MAX_WINDOWS)
++      return NULL;
++
++   scrnum = DefaultScreen(dpy);
++   root = RootWindow(dpy, scrnum);
++
++   visinfo = glXChooseVisual(dpy, scrnum, attrib);
++   if (!visinfo) {
++      Error(displayName, "Unable to find RGB, double-buffered visual");
++      return NULL;
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow(dpy, root, xpos, ypos, width, height,
++		       0, visinfo->depth, InputOutput,
++		       visinfo->visual, mask, &attr);
++   if (!win) {
++      Error(displayName, "Couldn't create window");
++      return NULL;
++   }
++
++   {
++      XSizeHints sizehints;
++      sizehints.x = xpos;
++      sizehints.y = ypos;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, displayName, displayName,
++			     None, (char **)NULL, 0, &sizehints);
++   }
++
++
++   ctx = glXCreateContext(dpy, visinfo,
++                          sCtx ? sCtx : NULL, True);
++
++   if (!ctx) {
++      Error(displayName, "Couldn't create GLX context");
++      return NULL;
++   }
++
++   XMapWindow(dpy, win);
++
++   /* save the info for this window */
++   {
++      static int id = 0;
++      struct window *h = &Windows[NumWindows];
++      if (strlen(displayName) + 1 > sizeof(h->DisplayName)) {
++         Error(displayName, "string overflow");
++         return NULL;
++      }
++      strcpy(h->DisplayName, displayName);
++      h->Dpy = dpy;
++      h->Win = win;
++      h->Context = ctx;
++      h->Angle = 0.0;
++      h->Id = id++;
++      h->visInfo = visinfo;
++      pthread_mutex_init(&h->drawMutex, NULL);
++      NumWindows++;
++      return &Windows[NumWindows-1];
++   }
++}
++
++
++static void
++InitGLstuff(void)
++
++{
++   glGenTextures(3, Textures);
++
++   /* setup first texture object */
++   {
++      GLubyte image[16][16][4];
++      GLint i, j;
++      glBindTexture(GL_TEXTURE_2D, Textures[0]);
++
++      /* red/white checkerboard */
++      for (i = 0; i < 16; i++) {
++         for (j = 0; j < 16; j++) {
++            if ((i ^ j) & 1) {
++               image[i][j][0] = 255;
++               image[i][j][1] = 255;
++               image[i][j][2] = 255;
++               image[i][j][3] = 255;
++            }
++            else {
++               image[i][j][0] = 255;
++               image[i][j][1] = 0;
++               image[i][j][2] = 0;
++               image[i][j][3] = 255;
++            }
++         }
++      }
++
++      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
++                   GL_UNSIGNED_BYTE, image);
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
++   }
++
++   /* setup second texture object */
++   {
++      GLubyte image[8][8][3];
++      GLint i, j;
++      glBindTexture(GL_TEXTURE_2D, Textures[1]);
++
++      /* green/yellow checkerboard */
++      for (i = 0; i < 8; i++) {
++         for (j = 0; j < 8; j++) {
++            if ((i ^ j) & 1) {
++               image[i][j][0] = 0;
++               image[i][j][1] = 255;
++               image[i][j][2] = 0;
++            }
++            else {
++               image[i][j][0] = 255;
++               image[i][j][1] = 255;
++               image[i][j][2] = 0;
++            }
++         }
++      }
++
++      glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
++      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB,
++                   GL_UNSIGNED_BYTE, image);
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
++   }
++
++   /* setup second texture object */
++   {
++      GLubyte image[4][4][3];
++      GLint i, j;
++      glBindTexture(GL_TEXTURE_2D, Textures[2]);
++
++      /* blue/gray checkerboard */
++      for (i = 0; i < 4; i++) {
++         for (j = 0; j < 4; j++) {
++            if ((i ^ j) & 1) {
++               image[i][j][0] = 0;
++               image[i][j][1] = 0;
++               image[i][j][2] = 255;
++            }
++            else {
++               image[i][j][0] = 200;
++               image[i][j][1] = 200;
++               image[i][j][2] = 200;
++            }
++         }
++      }
++
++      glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
++      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 4, 4, 0, GL_RGB,
++                   GL_UNSIGNED_BYTE, image);
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
++   }
++
++   /* Now make the cube object display list */
++
++   printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
++   printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
++   printf("GL_VENDOR: %s\n", (char *) glGetString(GL_VENDOR));
++}
++
++static void
++Redraw(struct window *h)
++{
++   pthread_mutex_lock(&h->drawMutex);
++   if (!glXMakeCurrent(h->Dpy, h->Win, h->Context)) {
++      Error(h->DisplayName, "glXMakeCurrent failed in Redraw");
++      pthread_mutex_unlock(&h->drawMutex);
++      return;
++   }
++
++   h->Angle += 1.0;
++
++   glShadeModel(GL_FLAT);
++   glClearColor(0.25, 0.25, 0.25, 1.0);
++   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
++
++   glEnable(GL_TEXTURE_2D);
++   glEnable(GL_DEPTH_TEST);
++   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
++
++   glColor3f(1, 1, 1);
++
++   glPushMatrix();
++   if (h->Id == 0)
++      glRotatef(h->Angle, 0, 1, -1);
++   else if (h->Id == 1)
++      glRotatef(-(h->Angle), 0, 1, -1);
++   else if (h->Id == 2)
++      glRotatef(h->Angle, 0, 1, 1);
++   else if (h->Id == 3)
++      glRotatef(-(h->Angle), 0, 1, 1);
++   glBindTexture(GL_TEXTURE_2D, Textures[0]);
++   glBegin(GL_POLYGON);
++   glTexCoord2f(0, 0);  glVertex3f(-1, -1, -1);
++   glTexCoord2f(1, 0);  glVertex3f(-1,  1, -1);
++   glTexCoord2f(1, 1);  glVertex3f(-1,  1,  1);
++   glTexCoord2f(0, 1);  glVertex3f(-1, -1,  1);
++   glEnd();
++   glBegin(GL_POLYGON);
++   glTexCoord2f(0, 0);  glVertex3f(1, -1, -1);
++   glTexCoord2f(1, 0);  glVertex3f(1,  1, -1);
++   glTexCoord2f(1, 1);  glVertex3f(1,  1,  1);
++   glTexCoord2f(0, 1);  glVertex3f(1, -1,  1);
++   glEnd();
++
++   glBindTexture(GL_TEXTURE_2D, Textures[1]);
++   glBegin(GL_POLYGON);
++   glTexCoord2f(0, 0);  glVertex3f(-1, -1, -1);
++   glTexCoord2f(1, 0);  glVertex3f( 1, -1, -1);
++   glTexCoord2f(1, 1);  glVertex3f( 1, -1,  1);
++   glTexCoord2f(0, 1);  glVertex3f(-1, -1,  1);
++   glEnd();
++   glBegin(GL_POLYGON);
++   glTexCoord2f(0, 0);  glVertex3f(-1, 1, -1);
++   glTexCoord2f(1, 0);  glVertex3f( 1, 1, -1);
++   glTexCoord2f(1, 1);  glVertex3f( 1, 1,  1);
++   glTexCoord2f(0, 1);  glVertex3f(-1, 1,  1);
++   glEnd();
++
++   glBindTexture(GL_TEXTURE_2D, Textures[2]);
++   glBegin(GL_POLYGON);
++   glTexCoord2f(0, 0);  glVertex3f(-1, -1, -1);
++   glTexCoord2f(1, 0);  glVertex3f( 1, -1, -1);
++   glTexCoord2f(1, 1);  glVertex3f( 1,  1, -1);
++   glTexCoord2f(0, 1);  glVertex3f(-1,  1, -1);
++   glEnd();
++   glBegin(GL_POLYGON);
++   glTexCoord2f(0, 0);  glVertex3f(-1, -1, 1);
++   glTexCoord2f(1, 0);  glVertex3f( 1, -1, 1);
++   glTexCoord2f(1, 1);  glVertex3f( 1,  1, 1);
++   glTexCoord2f(0, 1);  glVertex3f(-1,  1, 1);
++   glEnd();
++
++   glPopMatrix();
++
++   glXSwapBuffers(h->Dpy, h->Win);
++
++   if (!glXMakeCurrent(h->Dpy, None, NULL)) {
++      Error(h->DisplayName, "glXMakeCurrent failed in Redraw");
++   }
++   pthread_mutex_unlock(&h->drawMutex);
++}
++
++static void *threadRunner (void *arg)
++{
++   struct thread_init_arg *tia = (struct thread_init_arg *) arg;
++   struct window *win;
++
++   win = &Windows[tia->id];
++
++   while(!terminate) {
++      usleep(1000);
++      Redraw(win);
++   }
++
++   return NULL;
++}
++
++static void
++Resize(struct window *h, unsigned int width, unsigned int height)
++{
++   pthread_mutex_lock(&h->drawMutex);
++
++   if (!glXMakeCurrent(h->Dpy, h->Win, h->Context)) {
++      Error(h->DisplayName, "glXMakeCurrent failed in Resize()");
++      pthread_mutex_unlock(&h->drawMutex);
++      return;
++   }
++
++   glViewport(0, 0, width, height);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glFrustum(-1, 1, -1, 1, 2, 10);
++   glMatrixMode(GL_MODELVIEW);
++   glLoadIdentity();
++   glTranslatef(0, 0, -4.5);
++   if (!glXMakeCurrent(h->Dpy, None, NULL)) {
++      Error(h->DisplayName, "glXMakeCurrent failed in Resize()");
++   }
++   pthread_mutex_unlock(&h->drawMutex);
++}
++
++
++static void
++EventLoop(void)
++{
++   while (1) {
++      int i;
++      XEvent event;
++      XNextEvent(gDpy, &event);
++      for (i = 0; i < NumWindows; i++) {
++	 struct window *h = &Windows[i];
++	 if (event.xany.window == h->Win) {
++	    switch (event.type) {
++	    case Expose:
++	       Redraw(h);
++	       break;
++	    case ConfigureNotify:
++	       Resize(h, event.xconfigure.width, event.xconfigure.height);
++	       break;
++	    case KeyPress:
++	       terminate = 1;
++	       return;
++	    default:
++	       /*no-op*/ ;
++	    }
++	 }
++      }
++   }
++}
++
++int
++main(int argc, char *argv[])
++{
++   const char *dpyName = XDisplayName(NULL);
++   pthread_t t0, t1, t2, t3;
++   struct thread_init_arg tia0, tia1, tia2, tia3;
++   struct window *h0;
++
++   XInitThreads();
++
++   gDpy = XOpenDisplay(dpyName);
++   if (!gDpy) {
++      Error(dpyName, "Unable to open display");
++      return -1;
++   }
++
++   if (initMainthread(gDpy, dpyName))
++      return -1;
++
++   /* four windows and contexts sharing display lists and texture objects */
++   h0 = AddWindow(gDpy, dpyName,  10,  10, gCtx);
++   (void) AddWindow(gDpy, dpyName, 330,  10, gCtx);
++   (void) AddWindow(gDpy, dpyName,  10, 350, gCtx);
++   (void) AddWindow(gDpy, dpyName, 330, 350, gCtx);
++
++   if (!glXMakeCurrent(gDpy, h0->Win, gCtx)) {
++      Error(dpyName, "glXMakeCurrent failed for init thread.");
++      return -1;
++   }
++
++   InitGLstuff();
++
++   tia0.id = 0;
++   pthread_create(&t0, NULL, threadRunner, &tia0);
++   tia1.id = 1;
++   pthread_create(&t1, NULL, threadRunner, &tia1);
++   tia2.id = 2;
++   pthread_create(&t2, NULL, threadRunner, &tia2);
++   tia3.id = 3;
++   pthread_create(&t3, NULL, threadRunner, &tia3);
++   EventLoop();
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/texture_from_pixmap.c Mesa-7.8.1.patched/progs/xdemos/texture_from_pixmap.c
+--- Mesa-7.8.1/progs/xdemos/texture_from_pixmap.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/texture_from_pixmap.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,396 @@
++/*
++ * Mesa 3-D graphics library
++ * Version:  7.1
++ * 
++ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++/*
++ * Test the GLX_EXT_texture_from_pixmap extension
++ * Brian Paul
++ * 19 May 2007
++ */
++
++
++#define GL_GLEXT_PROTOTYPES
++#define GLX_GLXEXT_PROTOTYPES
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <X11/keysym.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++
++static float top, bottom;
++
++static PFNGLXBINDTEXIMAGEEXTPROC glXBindTexImageEXT_func = NULL;
++static PFNGLXRELEASETEXIMAGEEXTPROC glXReleaseTexImageEXT_func = NULL;
++
++
++static Display *
++OpenDisplay(void)
++{
++   int screen;
++   Display *dpy;
++   const char *ext;
++
++   dpy = XOpenDisplay(NULL);
++   if (!dpy) {
++      printf("Couldn't open default display!\n");
++      exit(1);
++   }
++
++   screen = DefaultScreen(dpy);
++   ext = glXQueryExtensionsString(dpy, screen);
++   if (!strstr(ext, "GLX_EXT_texture_from_pixmap")) {
++      fprintf(stderr, "GLX_EXT_texture_from_pixmap not supported.\n");
++      exit(1);
++   }
++
++   glXBindTexImageEXT_func = (PFNGLXBINDTEXIMAGEEXTPROC)
++      glXGetProcAddress((GLubyte *) "glXBindTexImageEXT");
++   glXReleaseTexImageEXT_func = (PFNGLXRELEASETEXIMAGEEXTPROC)
++      glXGetProcAddress((GLubyte*) "glXReleaseTexImageEXT");
++
++   if (!glXBindTexImageEXT_func || !glXReleaseTexImageEXT_func) {
++      fprintf(stderr, "glXGetProcAddress failed!\n");
++      exit(1);
++   }
++      
++   return dpy;
++}
++
++
++static GLXFBConfig
++ChoosePixmapFBConfig(Display *display)
++{
++   int screen = DefaultScreen(display);
++   GLXFBConfig *fbconfigs;
++   int i, nfbconfigs = 0, value;
++
++   fbconfigs = glXGetFBConfigs(display, screen, &nfbconfigs);
++   for (i = 0; i < nfbconfigs; i++) {
++
++      glXGetFBConfigAttrib(display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
++      if (!(value & GLX_PIXMAP_BIT))
++         continue;
++
++      glXGetFBConfigAttrib(display, fbconfigs[i],
++                           GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value);
++      if (!(value & GLX_TEXTURE_2D_BIT_EXT))
++         continue;
++
++      glXGetFBConfigAttrib(display, fbconfigs[i],
++                           GLX_BIND_TO_TEXTURE_RGBA_EXT, &value);
++      if (value == False) {
++         glXGetFBConfigAttrib(display, fbconfigs[i],
++                              GLX_BIND_TO_TEXTURE_RGB_EXT, &value);
++         if (value == False)
++            continue;
++      }
++
++      glXGetFBConfigAttrib(display, fbconfigs[i],
++                           GLX_Y_INVERTED_EXT, &value);
++      if (value == True) {
++         top = 0.0f;
++         bottom = 1.0f;
++      }
++      else {
++         top = 1.0f;
++         bottom = 0.0f;
++      }
++
++      break;
++   }
++
++   if (i == nfbconfigs) {
++      printf("Unable to find FBconfig for texturing\n");
++      exit(1);
++   }
++
++   return fbconfigs[i];
++}
++
++
++static GLXPixmap
++CreatePixmap(Display *dpy, GLXFBConfig config, int w, int h, Pixmap *p)
++{
++   GLXPixmap gp;
++   const int pixmapAttribs[] = {
++      GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
++      GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
++      None
++   };
++   Window root = RootWindow(dpy, 0);
++
++   *p = XCreatePixmap(dpy, root, w, h, 24);
++   XSync(dpy, 0);
++   gp = glXCreatePixmap(dpy, config, *p, pixmapAttribs);
++   XSync(dpy, 0);
++
++   return gp;
++}
++
++
++static void
++DrawPixmapImage(Display *dpy, Pixmap pm, int w, int h)
++{
++   XGCValues gcvals;
++   GC gc;
++
++   gcvals.background = 0;
++   gc = XCreateGC(dpy, pm, GCBackground, &gcvals);
++
++   XSetForeground(dpy, gc, 0x0);
++   XFillRectangle(dpy, pm, gc, 0, 0, w, h);
++
++   XSetForeground(dpy, gc, 0xff0000);
++   XFillRectangle(dpy, pm, gc, 0, 0, 50, 50);
++
++   XSetForeground(dpy, gc, 0x00ff00);
++   XFillRectangle(dpy, pm, gc, w - 50, 0, 50, 50);
++
++   XSetForeground(dpy, gc, 0x0000ff);
++   XFillRectangle(dpy, pm, gc, 0, h - 50, 50, 50);
++
++   XSetForeground(dpy, gc, 0xffffff);
++   XFillRectangle(dpy, pm, gc, h - 50, h - 50, 50, 50);
++
++   XSetForeground(dpy, gc, 0xffff00);
++   XSetLineAttributes(dpy, gc, 3, LineSolid, CapButt, JoinBevel);
++   XDrawLine(dpy, pm, gc, 0, 0, w, h);
++   XDrawLine(dpy, pm, gc, 0, h, w, 0);
++
++   XFreeGC(dpy, gc);
++}
++
++
++static XVisualInfo *
++ChooseWindowVisual(Display *dpy)
++{
++   int screen = DefaultScreen(dpy);
++   XVisualInfo *visinfo;
++   int attribs[] = {
++      GLX_RGBA,
++      GLX_RED_SIZE, 1,
++      GLX_GREEN_SIZE, 1,
++      GLX_BLUE_SIZE, 1,
++      GLX_DOUBLEBUFFER,
++      None
++   };
++
++   visinfo = glXChooseVisual(dpy, screen, attribs);
++   if (!visinfo) {
++      printf("Unable to find RGB, double-buffered visual\n");
++      exit(1);
++   }
++
++   return visinfo;
++}
++
++
++static Window
++CreateWindow(Display *dpy, XVisualInfo *visinfo,
++             int width, int height, const char *name)
++{
++   int screen = DefaultScreen(dpy);
++   Window win;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++
++   root = RootWindow(dpy, screen);
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow(dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr);
++   if (win) {
++      XSizeHints sizehints;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++
++      XMapWindow(dpy, win);
++   }
++   return win;
++}
++
++
++static void
++BindPixmapTexture(Display *dpy, GLXPixmap gp)
++{
++   GLuint texture;
++
++   glGenTextures(1, &texture);
++   glBindTexture(GL_TEXTURE_2D, texture);
++
++   glXBindTexImageEXT_func(dpy, gp, GLX_FRONT_LEFT_EXT, NULL);
++
++   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++
++   glEnable(GL_TEXTURE_2D);
++   /*
++     glXReleaseTexImageEXT_func(display, glxpixmap, GLX_FRONT_LEFT_EXT);
++   */
++}
++
++
++static void
++Resize(Window win, unsigned int width, unsigned int height)
++{
++   float sz = 1.5;
++   glViewport(0, 0, width, height);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glOrtho(-sz, sz, -sz, sz, -1.0, 1.0);
++   glMatrixMode(GL_MODELVIEW);
++}
++
++
++static void
++Redraw(Display *dpy, Window win, float rot)
++{
++   glClearColor(0.25, 0.25, 0.25, 0.0);
++   glClear(GL_COLOR_BUFFER_BIT);
++   glPushMatrix();
++   glRotatef(rot, 0, 0, 1);
++   glRotatef(2.0 * rot, 1, 0, 0);
++
++   glBegin(GL_QUADS);
++   glTexCoord2d(0.0, bottom);
++   glVertex2f(-1, -1);
++   glTexCoord2d(1.0, bottom);
++   glVertex2f( 1, -1);
++   glTexCoord2d(1.0, top);
++   glVertex2d(1.0, 1.0);
++   glTexCoord2d(0.0, top);
++   glVertex2f(-1.0, 1.0);
++   glEnd();
++
++   glPopMatrix();
++
++   glXSwapBuffers(dpy, win);
++}
++
++
++static void
++EventLoop(Display *dpy, Window win)
++{
++   GLfloat rot = 0.0;
++   int anim = 0;
++ 
++   while (1) {
++      if (!anim || XPending(dpy) > 0) {
++         XEvent event;
++         XNextEvent(dpy, &event);
++
++         switch (event.type) {
++         case Expose:
++            Redraw(dpy, win, rot);
++            break;
++         case ConfigureNotify:
++            Resize(event.xany.window,
++                   event.xconfigure.width,
++                   event.xconfigure.height);
++            break;
++         case KeyPress:
++            {
++               char buf[100];
++               KeySym keySym;
++               XComposeStatus stat;
++               XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
++               if (keySym == XK_Escape) {
++                  return; /* exit */
++               }
++               else if (keySym == XK_r) {
++                  rot += 1.0;
++                  Redraw(dpy, win, rot);
++               }
++               else if (keySym == XK_a) {
++                  anim = !anim;
++               }
++               else if (keySym == XK_R) {
++                  rot -= 1.0;
++                  Redraw(dpy, win, rot);
++               }
++            }
++            break;
++         default:
++            ; /*no-op*/
++         }
++      }
++      else {
++         /* animate */
++         rot += 1.0;
++         Redraw(dpy, win, rot);
++      }
++   }
++}
++
++
++
++int
++main(int argc, char *argv[])
++{
++   Display *dpy;
++   GLXFBConfig pixmapConfig;
++   XVisualInfo *windowVis;
++   GLXPixmap gp;
++   Window win;
++   GLXContext ctx;
++   Pixmap p;
++
++   dpy = OpenDisplay();
++
++   pixmapConfig = ChoosePixmapFBConfig(dpy);
++   windowVis = ChooseWindowVisual(dpy);
++   win = CreateWindow(dpy, windowVis, 500, 500, "Texture From Pixmap");
++
++   gp = CreatePixmap(dpy, pixmapConfig, 512, 512, &p);
++   DrawPixmapImage(dpy, p, 512, 512);
++
++   ctx = glXCreateContext(dpy, windowVis, NULL, True);
++   if (!ctx) {
++      printf("Couldn't create GLX context\n");
++      exit(1);
++   }
++
++   glXMakeCurrent(dpy, win, ctx);
++
++   BindPixmapTexture(dpy, gp);
++
++   EventLoop(dpy, win);
++
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/wincopy.c Mesa-7.8.1.patched/progs/xdemos/wincopy.c
+--- Mesa-7.8.1/progs/xdemos/wincopy.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/wincopy.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,328 @@
++/*
++ * Mesa 3-D graphics library
++ * Version:  6.5.2
++ * 
++ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++/*
++ * This program opens two GLX windows, renders into one and uses
++ * glCopyPixels to copy the image from the first window into the
++ * second by means of the GLX 1.3 function glxMakeContextCurrent().
++ * This function works just like the glXMakeCurrentReadSGI() function
++ * in the GLX_SGI_make_current_read extension.
++ */
++
++
++#define GL_GLEXT_PROTOTYPES
++#define GLX_GLXEXT_PROTOTYPES
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <X11/keysym.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++
++#ifdef GLX_VERSION_1_3
++
++
++static Display *Dpy;
++static int ScrNum;
++static GLXContext Context;
++static Window Win[2];  /* Win[0] = source,  Win[1] = dest */
++static GLint Width[2], Height[2];
++static GLboolean TestClipping = GL_FALSE;
++static GLfloat Angle = 0.0;
++
++static GLboolean DrawFront = GL_FALSE;
++
++PFNGLXMAKECURRENTREADSGIPROC make_context_current = NULL;
++
++static Window
++CreateWindow(Display *dpy, int scrnum, XVisualInfo *visinfo,
++             int xpos, int ypos, int width, int height,
++             const char *name)
++{
++   Window win;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++
++   root = RootWindow(dpy, scrnum);
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow(dpy, root, xpos, ypos, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr);
++   if (win) {
++      XSizeHints sizehints;
++      sizehints.x = xpos;
++      sizehints.y = ypos;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++
++      XMapWindow(dpy, win);
++   }
++   return win;
++}
++
++
++static void
++Redraw(void)
++{
++   /* make the first window the current one */
++   if (! (*make_context_current)(Dpy, Win[0], Win[0], Context)) {
++      printf("glXMakeContextCurrent failed in Redraw()\n");
++      return;
++   }
++
++   Angle += 1.0;
++
++   if (DrawFront) {
++      glDrawBuffer(GL_FRONT);
++      glReadBuffer(GL_FRONT);
++   }
++   else {
++      glDrawBuffer(GL_BACK);
++      glReadBuffer(GL_BACK);
++   }
++
++   glViewport(0, 0, Width[0], Height[0]);
++   glMatrixMode(GL_PROJECTION);
++   glLoadIdentity();
++   glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
++   glMatrixMode(GL_MODELVIEW);
++
++   glShadeModel(GL_FLAT);
++   glClearColor(0.5, 0.5, 0.5, 0.0);
++   glClear(GL_COLOR_BUFFER_BIT);
++
++   /* draw blue quad */
++   glColor3f(0.3, 0.3, 1.0);
++   glPushMatrix();
++   glRotatef(Angle, 0, 0, 1);
++   glBegin(GL_POLYGON);
++   glVertex2f(-0.5, -0.25);
++   glVertex2f( 0.5, -0.25);
++   glVertex2f( 0.5, 0.25);
++   glVertex2f(-0.5, 0.25);
++   glEnd();
++   glPopMatrix();
++
++   if (DrawFront)
++      glFinish();
++   else
++      glXSwapBuffers(Dpy, Win[0]);
++
++
++   /* copy image from window 0 to window 1 */
++   if (!(*make_context_current)(Dpy, Win[1], Win[0], Context)) {
++      printf("glXMakeContextCurrent failed in Redraw()\n");
++      return;
++   }
++
++   /* copy the image between windows */
++   glClearColor(0.0, 0.0, 0.0, 0.0);
++   glClear(GL_COLOR_BUFFER_BIT);
++
++   if (TestClipping) {
++      glWindowPos2iARB(-2, -2);
++      glCopyPixels(-2, -2, Width[0] + 4, Height[0] + 4, GL_COLOR);
++   }
++   else {
++      glWindowPos2iARB(0, 0);
++      glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR);
++   }
++
++   if (DrawFront)
++      glFinish();
++   else
++      glXSwapBuffers(Dpy, Win[1]);
++}
++
++
++
++static void
++Resize(Window win, unsigned int width, unsigned int height)
++{
++   int i;
++   if (win == Win[0]) {
++      i = 0;
++   }
++   else {
++      i = 1;
++   }
++   Width[i] = width;
++   Height[i] = height;
++   if (!glXMakeCurrent(Dpy, Win[i], Context)) {
++      printf("glXMakeCurrent failed in Resize()\n");
++      return;
++   }
++}
++
++
++
++static void
++EventLoop(void)
++{
++   XEvent event;
++   while (1) {
++      if (XPending(Dpy) > 0) {
++         XNextEvent( Dpy, &event );
++         switch (event.type) {
++            case Expose:
++               Redraw();
++               break;
++            case ConfigureNotify:
++               Resize(event.xany.window, event.xconfigure.width, event.xconfigure.height);
++               break;
++            case KeyPress:
++               {
++                  char buf[100];
++                  KeySym keySym;
++                  XComposeStatus stat;
++                  XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
++                  if (keySym == XK_Escape) {
++                        /* exit */
++                        return;
++                  }
++                  else if (buf[0] == 'f') {
++                     DrawFront = !DrawFront;
++                     printf("Drawing to %s buffer\n",
++                            DrawFront ? "GL_FRONT" : "GL_BACK");
++                  }
++               }
++               break;
++            default:
++               /*no-op*/ ;
++         }
++      }
++      else {
++         /* animate */
++         Redraw();
++      }
++   }
++}
++
++
++static void
++Init(void)
++{
++   XVisualInfo *visinfo;
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int major, minor;
++
++   Dpy = XOpenDisplay(NULL);
++   if (!Dpy) {
++      printf("Couldn't open default display!\n");
++      exit(1);
++   }
++
++   ScrNum = DefaultScreen(Dpy);
++
++   glXQueryVersion(Dpy, &major, &minor);
++
++   if (major * 100 + minor >= 103) {
++      make_context_current = (PFNGLXMAKECURRENTREADSGIPROC)
++	  glXGetProcAddressARB( (GLubyte *) "glXMakeContextCurrent" );
++   }
++   else {
++      const char * const glxExtensions = glXQueryExtensionsString(Dpy, ScrNum);
++      const char * ext = strstr( glxExtensions, "GLX_SGI_make_current_read" );
++      const size_t len = strlen( "GLX_SGI_make_current_read" );
++      
++      if ( (ext != NULL) 
++	   && ((ext[len] == ' ') || (ext[len] == '\0')) ) {
++	 make_context_current = (PFNGLXMAKECURRENTREADSGIPROC) 
++	     glXGetProcAddressARB( (GLubyte *) "glXMakeCurrentReadSGI" );
++      }
++   }
++
++   if (make_context_current == NULL) {
++      fprintf(stderr, "Sorry, this program requires either GLX 1.3 "
++	      "or GLX_SGI_make_current_read.\n");
++      exit(1);
++   }
++
++   visinfo = glXChooseVisual(Dpy, ScrNum, attrib);
++   if (!visinfo) {
++      printf("Unable to find RGB, double-buffered visual\n");
++      exit(1);
++   }
++
++   Context = glXCreateContext(Dpy, visinfo, NULL, True);
++   if (!Context) {
++      printf("Couldn't create GLX context\n");
++      exit(1);
++   }
++
++
++   Win[0] = CreateWindow(Dpy, ScrNum, visinfo,
++                         0, 0, 300, 300, "source window");
++
++   Win[1] = CreateWindow(Dpy, ScrNum, visinfo,
++                         350, 0, 300, 300, "dest window");
++
++   printf("Press Esc to exit\n");
++   printf("Press 'f' to toggle front/back buffer drawing\n");
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   if (argc > 1 && strcmp(argv[1], "-clip") == 0)
++      TestClipping = GL_TRUE;
++   Init();
++   EventLoop();
++   return 0;
++}
++
++
++#else
++
++
++int
++main(int argc, char *argv[])
++{
++   printf("This program requires GLX 1.3!\n");
++   return 0;
++}
++
++
++#endif /* GLX_VERSION_1_3 */
+diff -Naurp Mesa-7.8.1/progs/xdemos/xdemo.c Mesa-7.8.1.patched/progs/xdemos/xdemo.c
+--- Mesa-7.8.1/progs/xdemos/xdemo.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/xdemo.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,334 @@
++
++/*
++ * Very simple demo of how to use the Mesa/X11 interface instead of the
++ * glx, tk or aux toolkits.  I highly recommend using the GLX interface
++ * instead of the X/Mesa interface, however.
++ *
++ * This program is in the public domain.
++ *
++ * Brian Paul
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <X11/Xlib.h>
++#include <X11/Xutil.h>
++#include "GL/xmesa.h"
++#include "GL/gl.h"
++
++
++
++static GLint Black, Red, Green, Blue;
++
++
++
++static void make_window( char *title, int color_flag )
++{
++   int x = 10, y = 10, width = 400, height = 300;
++   Display *dpy;
++   int scr;
++   Window root, win;
++   Colormap cmap;
++   XColor xcolor;
++   int attr_flags;
++   XVisualInfo *visinfo;
++   XSetWindowAttributes attr;
++   XTextProperty tp;
++   XSizeHints sh;
++   XEvent e;
++   XMesaContext context;
++   XMesaVisual visual;
++   XMesaBuffer buffer;
++
++
++   /*
++    * Do the usual X things to make a window.
++    */
++
++   dpy = XOpenDisplay(NULL);
++   if (!dpy) {
++      printf("Couldn't open default display!\n");
++      exit(1);
++   }
++
++   scr = DefaultScreen(dpy);
++   root = RootWindow(dpy, scr);
++
++   /* alloc visinfo struct */
++   visinfo = (XVisualInfo *) malloc( sizeof(XVisualInfo) );
++
++   /* Get a visual and colormap */
++   if (color_flag) {
++      /* Open TrueColor window */
++
++/*
++      if (!XMatchVisualInfo( dpy, scr, 24, TrueColor, visinfo )) {
++	 printf("Couldn't get 24-bit TrueColor visual!\n");
++	 exit(1);
++      }
++*/
++      if (!XMatchVisualInfo( dpy, scr, 8, PseudoColor, visinfo )) {
++	 printf("Couldn't get 8-bit PseudoColor visual!\n");
++	 exit(1);
++      }
++
++      cmap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
++      Black = Red = Green = Blue = 0;
++   }
++   else {
++      /* Open color index window */
++
++      if (!XMatchVisualInfo( dpy, scr, 8, PseudoColor, visinfo )) {
++	 printf("Couldn't get 8-bit PseudoColor visual\n");
++	 exit(1);
++      }
++
++      cmap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
++
++      /* Allocate colors */
++      xcolor.red   = 0x0;
++      xcolor.green = 0x0;
++      xcolor.blue  = 0x0;
++      xcolor.flags = DoRed | DoGreen | DoBlue;
++      if (!XAllocColor( dpy, cmap, &xcolor )) {
++	 printf("Couldn't allocate black!\n");
++	 exit(1);
++      }
++      Black = xcolor.pixel;
++
++      xcolor.red   = 0xffff;
++      xcolor.green = 0x0;
++      xcolor.blue  = 0x0;
++      xcolor.flags = DoRed | DoGreen | DoBlue;
++      if (!XAllocColor( dpy, cmap, &xcolor )) {
++	 printf("Couldn't allocate red!\n");
++	 exit(1);
++      }
++      Red = xcolor.pixel;
++
++      xcolor.red   = 0x0;
++      xcolor.green = 0xffff;
++      xcolor.blue  = 0x0;
++      xcolor.flags = DoRed | DoGreen | DoBlue;
++      if (!XAllocColor( dpy, cmap, &xcolor )) {
++	 printf("Couldn't allocate green!\n");
++	 exit(1);
++      }
++      Green = xcolor.pixel;
++
++      xcolor.red   = 0x0;
++      xcolor.green = 0x0;
++      xcolor.blue  = 0xffff;
++      xcolor.flags = DoRed | DoGreen | DoBlue;
++      if (!XAllocColor( dpy, cmap, &xcolor )) {
++	 printf("Couldn't allocate blue!\n");
++	 exit(1);
++      }
++      Blue = xcolor.pixel;
++   }
++
++   /* set window attributes */
++   attr.colormap = cmap;
++   attr.event_mask = ExposureMask | StructureNotifyMask;
++   attr.border_pixel = BlackPixel( dpy, scr );
++   attr.background_pixel = BlackPixel( dpy, scr );
++   attr_flags = CWColormap | CWEventMask | CWBorderPixel | CWBackPixel;
++
++   /* Create the window */
++   win = XCreateWindow( dpy, root, x,y, width, height, 0,
++			    visinfo->depth, InputOutput,
++			    visinfo->visual,
++			    attr_flags, &attr);
++   if (!win) {
++      printf("Couldn't open window!\n");
++      exit(1);
++   }
++
++   XStringListToTextProperty(&title, 1, &tp);
++   sh.flags = USPosition | USSize;
++   XSetWMProperties(dpy, win, &tp, &tp, 0, 0, &sh, 0, 0);
++   XMapWindow(dpy, win);
++   while (1) {
++      XNextEvent( dpy, &e );
++      if (e.type == MapNotify && e.xmap.window == win) {
++	 break;
++      }
++   }
++
++
++   /*
++    * Now do the special Mesa/Xlib stuff!
++    */
++
++   visual = XMesaCreateVisual( dpy, visinfo,
++                              (GLboolean) color_flag,
++                               GL_FALSE,  /* alpha_flag */
++                               GL_FALSE,  /* db_flag */
++                               GL_FALSE,  /* stereo flag */
++                               GL_FALSE,  /* ximage_flag */
++                               0,         /* depth size */
++                               0,         /* stencil size */
++                               0,0,0,0,   /* accum_size */
++                               0,         /* num samples */
++                               0,         /* level */
++                               0          /* caveat */
++                              );
++   if (!visual) {
++      printf("Couldn't create Mesa/X visual!\n");
++      exit(1);
++   }
++
++   /* Create a Mesa rendering context */
++   context = XMesaCreateContext( visual,
++                                 NULL       /* share_list */
++                               );
++   if (!context) {
++      printf("Couldn't create Mesa/X context!\n");
++      exit(1);
++   }
++
++   buffer = XMesaCreateWindowBuffer( visual, win );
++   if (!buffer) {
++      printf("Couldn't create Mesa/X buffer!\n");
++      exit(1);
++   }
++
++
++   XMesaMakeCurrent( context, buffer );
++
++   /* Ready to render! */
++}
++
++
++
++static void draw_cube( void )
++{
++   /* X faces */
++   glIndexi( Red );
++   glColor3f( 1.0, 0.0, 0.0 );
++   glBegin( GL_POLYGON );
++   glVertex3f( 1.0, 1.0, 1.0 );
++   glVertex3f( 1.0, -1.0, 1.0 );
++   glVertex3f( 1.0, -1.0, -1.0 );
++   glVertex3f( 1.0, 1.0, -1.0 );
++   glEnd();
++
++   glBegin( GL_POLYGON );
++   glVertex3f( -1.0, 1.0, 1.0 );
++   glVertex3f( -1.0, 1.0, -1.0 );
++   glVertex3f( -1.0, -1.0, -1.0 );
++   glVertex3f( -1.0, -1.0, 1.0 );
++   glEnd();
++
++   /* Y faces */
++   glIndexi( Green );
++   glColor3f( 0.0, 1.0, 0.0 );
++   glBegin( GL_POLYGON );
++   glVertex3f(  1.0, 1.0,  1.0 );
++   glVertex3f(  1.0, 1.0, -1.0 );
++   glVertex3f( -1.0, 1.0, -1.0 );
++   glVertex3f( -1.0, 1.0,  1.0 );
++   glEnd();
++
++   glBegin( GL_POLYGON );
++   glVertex3f(  1.0, -1.0,  1.0 );
++   glVertex3f( -1.0, -1.0,  1.0 );
++   glVertex3f( -1.0, -1.0, -1.0 );
++   glVertex3f(  1.0, -1.0, -1.0 );
++   glEnd();
++
++   /* Z faces */
++   glIndexi( Blue );
++   glColor3f( 0.0, 0.0, 1.0 );
++   glBegin( GL_POLYGON );
++   glVertex3f(  1.0,  1.0,  1.0 );
++   glVertex3f( -1.0,  1.0,  1.0 );
++   glVertex3f( -1.0, -1.0,  1.0 );
++   glVertex3f(  1.0, -1.0,  1.0 );
++   glEnd();
++
++   glBegin( GL_POLYGON );
++   glVertex3f(  1.0, 1.0, -1.0 );
++   glVertex3f(  1.0,-1.0, -1.0 );
++   glVertex3f( -1.0,-1.0, -1.0 );
++   glVertex3f( -1.0, 1.0, -1.0 );
++   glEnd();
++}
++
++
++
++
++static void display_loop( void )
++{
++   GLfloat xrot, yrot, zrot;
++
++   xrot = yrot = zrot = 0.0;
++
++   glClearColor( 0.0, 0.0, 0.0, 0.0 );
++   glClearIndex( Black );
++
++   glMatrixMode( GL_PROJECTION );
++   glLoadIdentity();
++   glFrustum( -1.0, 1.0,  -1.0, 1.0,  1.0, 10.0 );
++   glTranslatef( 0.0, 0.0, -5.0 );
++
++   glMatrixMode( GL_MODELVIEW );
++   glLoadIdentity();
++
++   glCullFace( GL_BACK );
++   glEnable( GL_CULL_FACE );
++
++   glShadeModel( GL_FLAT );
++
++   while (1) {
++      glClear( GL_COLOR_BUFFER_BIT );
++      glPushMatrix();
++      glRotatef( xrot, 1.0, 0.0, 0.0 );
++      glRotatef( yrot, 0.0, 1.0, 0.0 );
++      glRotatef( zrot, 0.0, 0.0, 1.0 );
++
++      draw_cube();
++
++      glPopMatrix();
++      glFinish();
++
++      xrot += 10.0;
++      yrot += 7.0;
++      zrot -= 3.0;
++   }
++
++}
++
++
++
++
++int main( int argc, char *argv[] )
++{
++   int mode = 0;
++
++   if (argc >= 2)
++   {
++        if (strcmp(argv[1],"-ci")==0)
++           mode = 0;
++        else if (strcmp(argv[1],"-rgb")==0)
++           mode = 1;
++        else
++        {
++           printf("Bad flag: %s\n", argv[1]);
++           printf("Specify -ci for 8-bit color index or -rgb for RGB mode\n");
++           exit(1);
++        }
++   }
++   else
++   {
++        printf("Specify -ci for 8-bit color index or -rgb for RGB mode\n");
++        printf("Defaulting to  8-bit color index\n");
++   }
++
++   make_window( argv[0], mode );
++
++   display_loop();
++   return 0;
++}
++
+diff -Naurp Mesa-7.8.1/progs/xdemos/xfont.c Mesa-7.8.1.patched/progs/xdemos/xfont.c
+--- Mesa-7.8.1/progs/xdemos/xfont.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/xfont.c	2010-06-13 13:45:06.788792936 +0200
+@@ -0,0 +1,206 @@
++
++/*
++ * Mesa 3-D graphics library
++ * 
++ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++/*
++ * Example of using glXUseXFont().
++ * 5 November 1999
++ * Brian Paul
++ */
++
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++
++static const char *ProgramName = "xfont";
++
++static const char *FontName = "fixed";
++
++static GLuint FontBase = 0;
++
++
++
++static void redraw( Display *dpy, Window w )
++{
++   static const char *text = "This is glXUseXFont()";
++
++   glClear( GL_COLOR_BUFFER_BIT );
++
++   /* triangle */
++   glColor3f( 0.2, 0.2, 1.0 );
++   glBegin(GL_TRIANGLES);
++   glVertex2f( 0, 0.8 );
++   glVertex2f( -0.8, -0.7 );
++   glVertex2f( 0.8, -0.7 );
++   glEnd();
++
++   /* text */
++   glColor3f( 1, 1, 1 );
++   glRasterPos2f(-0.8, 0); 
++   glListBase(FontBase);
++   glCallLists(strlen(text), GL_UNSIGNED_BYTE, (GLubyte *) text);
++
++   glXSwapBuffers( dpy, w );
++}
++
++
++
++static void resize( unsigned int width, unsigned int height )
++{
++   glViewport( 0, 0, width, height );
++   glMatrixMode( GL_PROJECTION );
++   glLoadIdentity();
++   glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
++}
++
++
++
++static void setup_font( Display *dpy )
++{
++    XFontStruct *fontInfo;
++    Font id;
++    unsigned int first, last;
++
++    fontInfo = XLoadQueryFont(dpy, FontName);
++    if (!fontInfo) {
++        printf("Error: font %s not found\n", FontName);
++	exit(0);
++    }
++
++    id = fontInfo->fid;
++    first = fontInfo->min_char_or_byte2;
++    last = fontInfo->max_char_or_byte2;
++
++    FontBase = glGenLists((GLuint) last + 1);
++    if (!FontBase) {
++        printf("Error: unable to allocate display lists\n");
++	exit(0);
++    }
++    glXUseXFont(id, first, last - first + 1, FontBase + first);
++}
++
++static Window make_rgb_db_window( Display *dpy, int xpos, int ypos,
++				  unsigned int width, unsigned int height )
++{
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   GLXContext ctx;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   visinfo = glXChooseVisual( dpy, scrnum, attrib );
++   if (!visinfo) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   {
++      XSizeHints sizehints;
++      sizehints.x = xpos;
++      sizehints.y = ypos;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, ProgramName, ProgramName,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++
++   ctx = glXCreateContext( dpy, visinfo, NULL, True );
++
++   glXMakeCurrent( dpy, win, ctx );
++
++   return win;
++}
++
++
++static void event_loop( Display *dpy )
++{
++   XEvent event;
++
++   while (1) {
++      XNextEvent( dpy, &event );
++
++      switch (event.type) {
++	 case Expose:
++	    redraw( dpy, event.xany.window );
++	    break;
++	 case ConfigureNotify:
++	    resize( event.xconfigure.width, event.xconfigure.height );
++	    break;
++         case KeyPress:
++            exit(0);
++         default:
++            ;  /* no-op */
++      }
++   }
++}
++
++
++
++int main( int argc, char *argv[] )
++{
++   Display *dpy;
++   Window win;
++
++   dpy = XOpenDisplay(NULL);
++
++   win = make_rgb_db_window( dpy, 0, 0, 300, 300 );
++   setup_font( dpy );
++
++   glShadeModel( GL_FLAT );
++   glClearColor( 0.5, 0.5, 1.0, 1.0 );
++
++   XMapWindow( dpy, win );
++
++   event_loop( dpy );
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/xrotfontdemo.c Mesa-7.8.1.patched/progs/xdemos/xrotfontdemo.c
+--- Mesa-7.8.1/progs/xdemos/xrotfontdemo.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/xrotfontdemo.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,220 @@
++/*
++ * Mesa 3-D graphics library
++ * 
++ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
++ * 
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++/*
++ * Example of using glXUseRotatedXFontMESA().
++ * 24 Jan 2004
++ * Brian Paul
++ */
++
++
++#include <GL/gl.h>
++#include <GL/glx.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include "xuserotfont.h"
++
++
++static const char *ProgramName = "xfont";
++
++static const char *FontName = "fixed";
++
++static GLuint FontBase[4];
++
++
++static void redraw( Display *dpy, Window w )
++{
++   static const char *text = "  Rotated bitmap text";
++   int i;
++
++   glClear( GL_COLOR_BUFFER_BIT );
++
++   /* triangle */
++   glColor3f( 0.2, 0.2, 1.0 );
++   glBegin(GL_TRIANGLES);
++   glVertex2f( -0.8,  0.7 );
++   glVertex2f( -0.8, -0.7 );
++   glVertex2f(  0.8,  0.0 );
++   glEnd();
++
++   /* marker */
++   glColor3f( 0, 1, 0 );
++   glBegin(GL_POINTS);
++   glVertex2f(0, 0);
++   glEnd();
++
++   /* text */
++   glColor3f( 1, 1, 1 );
++
++   for (i = 0; i < 4; i++) {
++      glRasterPos2f(0, 0); 
++      glListBase(FontBase[i]);
++      glCallLists(strlen(text), GL_UNSIGNED_BYTE, (GLubyte *) text);
++   }
++
++   glXSwapBuffers( dpy, w );
++}
++
++
++
++static void resize( unsigned int width, unsigned int height )
++{
++   glViewport( 0, 0, width, height );
++   glMatrixMode( GL_PROJECTION );
++   glLoadIdentity();
++   glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
++}
++
++
++
++static void setup_font( Display *dpy )
++{
++    XFontStruct *fontInfo;
++    Font id;
++    unsigned int first, last;
++    int i;
++
++    fontInfo = XLoadQueryFont(dpy, FontName);
++    if (!fontInfo) {
++        printf("Error: font %s not found\n", FontName);
++	exit(0);
++    }
++
++    id = fontInfo->fid;
++    first = fontInfo->min_char_or_byte2;
++    last = fontInfo->max_char_or_byte2;
++
++    for (i = 0; i < 4; i++) {
++       FontBase[i] = glGenLists((GLuint) last + 1);
++       if (!FontBase[i]) {
++          printf("Error: unable to allocate display lists\n");
++          exit(0);
++       }
++       glXUseRotatedXFontMESA(id, first, last - first + 1, FontBase[i] + first,
++                              i * 90);
++    }
++}
++
++
++static Window make_rgb_db_window( Display *dpy, int xpos, int ypos,
++				  unsigned int width, unsigned int height )
++{
++   int attrib[] = { GLX_RGBA,
++		    GLX_RED_SIZE, 1,
++		    GLX_GREEN_SIZE, 1,
++		    GLX_BLUE_SIZE, 1,
++		    GLX_DOUBLEBUFFER,
++		    None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   GLXContext ctx;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++
++   visinfo = glXChooseVisual( dpy, scrnum, attrib );
++   if (!visinfo) {
++      printf("Error: couldn't get an RGB, Double-buffered visual\n");
++      exit(1);
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
++
++   win = XCreateWindow( dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   {
++      XSizeHints sizehints;
++      sizehints.x = xpos;
++      sizehints.y = ypos;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, ProgramName, ProgramName,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++
++   ctx = glXCreateContext( dpy, visinfo, NULL, True );
++
++   glXMakeCurrent( dpy, win, ctx );
++
++   return win;
++}
++
++
++static void event_loop( Display *dpy )
++{
++   XEvent event;
++
++   while (1) {
++      XNextEvent( dpy, &event );
++
++      switch (event.type) {
++	 case Expose:
++	    redraw( dpy, event.xany.window );
++	    break;
++	 case ConfigureNotify:
++	    resize( event.xconfigure.width, event.xconfigure.height );
++	    break;
++         case KeyPress:
++            exit(0);
++         default:
++            ;  /* no-op */
++      }
++   }
++}
++
++
++
++int main( int argc, char *argv[] )
++{
++   Display *dpy;
++   Window win;
++
++   dpy = XOpenDisplay(NULL);
++
++   win = make_rgb_db_window( dpy, 0, 0, 300, 300 );
++   setup_font( dpy );
++
++   glShadeModel( GL_FLAT );
++   glClearColor( 0.5, 0.5, 1.0, 1.0 );
++
++   XMapWindow( dpy, win );
++
++   event_loop( dpy );
++   return 0;
++}
+diff -Naurp Mesa-7.8.1/progs/xdemos/xuserotfont.c Mesa-7.8.1.patched/progs/xdemos/xuserotfont.c
+--- Mesa-7.8.1/progs/xdemos/xuserotfont.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/xuserotfont.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,399 @@
++/*
++ * Mesa 3-D graphics library
++ * Version:  6.1
++ *
++ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
++ *
++ * 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
++ * BRIAN PAUL 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.
++ */
++
++
++/* \file xuserotfont.c
++ *
++ * A function like glXUseXFont() but takes a 0, 90, 180 or 270 degree
++ * rotation angle for rotated text display.
++ *
++ * Based on Mesa's glXUseXFont implementation written by Thorsten Ohl.
++ */
++
++#include <assert.h>
++#include <stdlib.h>
++#include <string.h>
++#include <GL/glx.h>
++#include "xuserotfont.h"
++
++
++/**
++ * Generate OpenGL-compatible bitmap by drawing an X character glyph
++ * to an off-screen pixmap, then getting the image and testing pixels.
++ * \param width  bitmap width in pixels
++ * \param height  bitmap height in pixels
++ */
++static void
++fill_bitmap(Display *dpy, Pixmap pixmap, GC gc,
++	    unsigned int bitmapWidth, unsigned int bitmapHeight,
++            unsigned int charWidth, unsigned int charHeight,
++	    int xPos, int yPos, unsigned int c, GLubyte * bitmap,
++            int rotation)
++{
++   const int bytesPerRow = (bitmapWidth + 7) / 8;
++   XImage *image;
++   XChar2b char2b;
++
++   /* clear pixmap to 0 */
++   XSetForeground(dpy, gc, 0);
++   XFillRectangle(dpy, pixmap, gc, 0, 0, charWidth, charHeight);
++
++   /* The glyph is drawn snug up against the left/top edges of the pixmap */
++   XSetForeground(dpy, gc, 1);
++   char2b.byte1 = (c >> 8) & 0xff;
++   char2b.byte2 = (c & 0xff);
++   XDrawString16(dpy, pixmap, gc, xPos, yPos, &char2b, 1);
++
++   /* initialize GL bitmap */
++   memset(bitmap, 0, bytesPerRow * bitmapHeight);
++
++   image = XGetImage(dpy, pixmap, 0, 0, charWidth, charHeight, 1, XYPixmap);
++   if (image) {
++      /* Set appropriate bits in the GL bitmap.
++       * Note: X11 and OpenGL are upside down wrt each other).
++       */
++      unsigned int x, y;
++      if (rotation == 0) {
++         for (y = 0; y < charHeight; y++) {
++            for (x = 0; x < charWidth; x++) {
++               if (XGetPixel(image, x, y)) {
++                  int y2 = bitmapHeight - y - 1;
++                  bitmap[bytesPerRow * y2 + x / 8] |= (1 << (7 - (x % 8)));
++               }
++            }
++         }
++      }
++      else if (rotation == 90) {
++         for (y = 0; y < charHeight; y++) {
++            for (x = 0; x < charWidth; x++) {
++               if (XGetPixel(image, x, y)) {
++                  int x2 = y;
++                  int y2 = x;
++                  bitmap[bytesPerRow * y2 + x2 / 8] |= (1 << (7 - (x2 % 8)));
++               }
++            }
++         }
++      }
++      else if (rotation == 180) {
++         for (y = 0; y < charHeight; y++) {
++            for (x = 0; x < charWidth; x++) {
++               if (XGetPixel(image, x, y)) {
++                  int x2 = charWidth - x - 1;
++                  bitmap[bytesPerRow * y + x2 / 8] |= (1 << (7 - (x2 % 8)));
++               }
++            }
++         }
++      }
++      else {
++         assert(rotation == 270);
++         for (y = 0; y < charHeight; y++) {
++            for (x = 0; x < charWidth; x++) {
++               if (XGetPixel(image, x, y)) {
++                  int x2 = charHeight - y - 1;
++                  int y2 = charWidth - x - 1;
++                  bitmap[bytesPerRow * y2 + x2 / 8] |= (1 << (7 - (x2 % 8)));
++               }
++            }
++         }
++      }
++      XDestroyImage(image);
++   }
++}
++
++
++/*
++ * Determine if a given glyph is valid and return the
++ * corresponding XCharStruct.
++ */
++static const XCharStruct *
++isvalid(const XFontStruct * fs, unsigned int which)
++{
++   unsigned int rows, pages;
++   unsigned int byte1 = 0, byte2 = 0;
++   int i, valid = 1;
++
++   rows = fs->max_byte1 - fs->min_byte1 + 1;
++   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
++
++   if (rows == 1) {
++      /* "linear" fonts */
++      if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which))
++	 valid = 0;
++   }
++   else {
++      /* "matrix" fonts */
++      byte2 = which & 0xff;
++      byte1 = which >> 8;
++      if ((fs->min_char_or_byte2 > byte2) ||
++	  (fs->max_char_or_byte2 < byte2) ||
++	  (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1))
++	 valid = 0;
++   }
++
++   if (valid) {
++      if (fs->per_char) {
++	 if (rows == 1) {
++	    /* "linear" fonts */
++	    return fs->per_char + (which - fs->min_char_or_byte2);
++	 }
++	 else {
++	    /* "matrix" fonts */
++	    i = ((byte1 - fs->min_byte1) * pages) +
++	       (byte2 - fs->min_char_or_byte2);
++	    return fs->per_char + i;
++	 }
++      }
++      else {
++	 return &fs->min_bounds;
++      }
++   }
++   return NULL;
++}
++
++
++void
++glXUseRotatedXFontMESA(Font font, int first, int count, int listbase,
++                       int rotation)
++{
++   Display *dpy;
++   Window win;
++   Pixmap pixmap;
++   GC gc;
++   XFontStruct *fs;
++   GLint swapbytes, lsbfirst, rowlength;
++   GLint skiprows, skippixels, alignment;
++   unsigned int maxCharWidth, maxCharHeight;
++   GLubyte *bm;
++   int i;
++
++   if (rotation != 0 &&
++       rotation != 90 &&
++       rotation != 180 &&
++       rotation != 270)
++      return;
++
++   dpy = glXGetCurrentDisplay();
++   if (!dpy)
++      return;			/* I guess glXMakeCurrent wasn't called */
++   win = RootWindow(dpy, DefaultScreen(dpy));
++
++   fs = XQueryFont(dpy, font);
++   if (!fs) {
++      /*
++      _mesa_error(NULL, GL_INVALID_VALUE,
++		  "Couldn't get font structure information");
++      */
++      return;
++   }
++
++   /* Allocate a GL bitmap that can fit any character */
++   maxCharWidth = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
++   maxCharHeight = fs->max_bounds.ascent + fs->max_bounds.descent;
++   /* use max, in case we're rotating */
++   if (rotation == 90 || rotation == 270) {
++      /* swap width/height */
++      bm = (GLubyte *) malloc((maxCharHeight + 7) / 8 * maxCharWidth);
++   }
++   else {
++      /* normal or upside down */
++      bm = (GLubyte *) malloc((maxCharWidth + 7) / 8 * maxCharHeight);
++   }
++   if (!bm) {
++      XFreeFontInfo(NULL, fs, 1);
++      /*
++      _mesa_error(NULL, GL_OUT_OF_MEMORY,
++		  "Couldn't allocate bitmap in glXUseXFont()");
++      */
++      return;
++   }
++
++#if 0
++   /* get the page info */
++   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
++   firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
++   lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
++   rows = fs->max_byte1 - fs->min_byte1 + 1;
++   unsigned int first_char, last_char, pages, rows;
++#endif
++
++   /* Save the current packing mode for bitmaps.  */
++   glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
++   glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
++   glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
++   glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
++   glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
++   glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
++
++   /* Enforce a standard packing mode which is compatible with
++      fill_bitmap() from above.  This is actually the default mode,
++      except for the (non)alignment.  */
++   glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
++   glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
++   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
++   glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
++   glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
++   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++
++   /* Create pixmap and GC */
++   pixmap = XCreatePixmap(dpy, win, maxCharWidth, maxCharHeight, 1);
++   {
++      XGCValues values;
++      unsigned long valuemask;
++      values.foreground = BlackPixel(dpy, DefaultScreen(dpy));
++      values.background = WhitePixel(dpy, DefaultScreen(dpy));
++      values.font = fs->fid;
++      valuemask = GCForeground | GCBackground | GCFont;
++      gc = XCreateGC(dpy, pixmap, valuemask, &values);
++   }
++
++#ifdef DEBUG_XROT
++   if (debug_xfonts)
++      dump_font_struct(fs);
++#endif
++
++   for (i = 0; i < count; i++) {
++      const unsigned int c = first + i;
++      const int list = listbase + i;
++      unsigned int charWidth, charHeight;
++      unsigned int bitmapWidth = 0, bitmapHeight = 0;
++      GLfloat xOrig, yOrig, xStep, yStep, dtemp;
++      const XCharStruct *ch;
++      int xPos, yPos;
++      int valid;
++
++      /* check on index validity and get the bounds */
++      ch = isvalid(fs, c);
++      if (!ch) {
++	 ch = &fs->max_bounds;
++	 valid = 0;
++      }
++      else {
++	 valid = 1;
++      }
++
++#ifdef DEBUG_XROT
++      if (debug_xfonts) {
++	 char s[7];
++	 sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c);
++	 dump_char_struct(ch, s);
++      }
++#endif
++
++      /* glBitmap()' parameters:
++         straight from the glXUseXFont(3) manpage.  */
++      charWidth = ch->rbearing - ch->lbearing;
++      charHeight = ch->ascent + ch->descent;
++      xOrig = -ch->lbearing;
++      yOrig = ch->descent;
++      xStep = ch->width;
++      yStep = 0;
++
++      /* X11's starting point.  */
++      xPos = -ch->lbearing;
++      yPos = ch->ascent;
++
++      /* Apply rotation */
++      switch (rotation) {
++      case 0:
++         /* nothing */
++         bitmapWidth = charWidth;
++         bitmapHeight = charHeight;
++         break;
++      case 90:
++         /* xStep, yStep */
++         dtemp = xStep;
++         xStep = -yStep;
++         yStep = dtemp;
++         /* xOrig, yOrig */
++         yOrig = xOrig;
++         xOrig = charHeight - (charHeight - yPos);
++         /* width, height */
++         bitmapWidth = charHeight;
++         bitmapHeight = charWidth;
++         break;
++      case 180:
++         /* xStep, yStep */
++         xStep = -xStep;
++         yStep = -yStep;
++         /* xOrig, yOrig */
++         xOrig = charWidth - xOrig - 1;
++         yOrig = charHeight - yOrig - 1;
++         bitmapWidth = charWidth;
++         bitmapHeight = charHeight;
++         break;
++      case 270:
++         /* xStep, yStep */
++         dtemp = xStep;
++         xStep = yStep;
++         yStep = -dtemp;
++         /* xOrig, yOrig */
++         dtemp = yOrig;
++         yOrig = charWidth - xOrig;
++         xOrig = dtemp;
++         /* width, height */
++         bitmapWidth = charHeight;
++         bitmapHeight = charWidth;
++         break;
++      default:
++         /* should never get here */
++         ;
++      }
++
++      glNewList(list, GL_COMPILE);
++      if (valid && bitmapWidth > 0 && bitmapHeight > 0) {
++
++	 fill_bitmap(dpy, pixmap, gc, bitmapWidth, bitmapHeight,
++                     charWidth, charHeight,
++                     xPos, yPos, c, bm, rotation);
++
++	 glBitmap(bitmapWidth, bitmapHeight, xOrig, yOrig, xStep, yStep, bm);
++
++#ifdef DEBUG_XROT
++	 if (debug_xfonts) {
++	    printf("width/height = %u/%u\n", bitmapWidth, bitmapHeight);
++	    dump_bitmap(bitmapWidth, bitmapHeight, bm);
++	 }
++#endif
++      }
++      else {
++	 glBitmap(0, 0, 0.0, 0.0, xStep, yStep, NULL);
++      }
++      glEndList();
++   }
++
++   free(bm);
++   XFreeFontInfo(NULL, fs, 1);
++   XFreePixmap(dpy, pixmap);
++   XFreeGC(dpy, gc);
++
++   /* Restore saved packing modes.  */
++   glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
++   glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
++   glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
++   glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
++   glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
++   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
++}
++
++
+diff -Naurp Mesa-7.8.1/progs/xdemos/xuserotfont.h Mesa-7.8.1.patched/progs/xdemos/xuserotfont.h
+--- Mesa-7.8.1/progs/xdemos/xuserotfont.h	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/xuserotfont.h	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,12 @@
++#ifndef XUSEROTFONT_H
++#define XUSEROTFONT_H
++
++#include <X11/Xlib.h>
++
++
++extern void
++glXUseRotatedXFontMESA(Font font, int first, int count, int listbase,
++                       int rotation);
++
++
++#endif
+diff -Naurp Mesa-7.8.1/progs/xdemos/yuvrect_client.c Mesa-7.8.1.patched/progs/xdemos/yuvrect_client.c
+--- Mesa-7.8.1/progs/xdemos/yuvrect_client.c	1970-01-01 01:00:00.000000000 +0100
++++ Mesa-7.8.1.patched/progs/xdemos/yuvrect_client.c	2010-06-13 13:45:06.789793146 +0200
+@@ -0,0 +1,326 @@
++/*
++ * Test the GL_NV_texture_rectangle and GL_MESA_ycrcb_texture extensions and GLX_MESA_allocate-memory
++ *
++ * Dave Airlie - Feb 2005
++ */
++
++#include <assert.h>
++#include <math.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <X11/Xlib.h>
++#include <X11/keysym.h>
++#define GL_GLEXT_PROTOTYPES
++#include <GL/glx.h>
++
++#include "../util/readtex.c"   /* I know, this is a hack. */
++
++#define TEXTURE_FILE "../images/girl2.rgb"
++
++static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
++static GLint ImgWidth, ImgHeight;
++static GLushort *ImageYUV = NULL;
++static void *glx_memory;
++
++static void DrawObject(void)
++{
++   glBegin(GL_QUADS);
++
++   glTexCoord2f(0, 0);
++   glVertex2f(-1.0, -1.0);
++
++   glTexCoord2f(ImgWidth, 0);
++   glVertex2f(1.0, -1.0);
++
++   glTexCoord2f(ImgWidth, ImgHeight);
++   glVertex2f(1.0, 1.0);
++
++   glTexCoord2f(0, ImgHeight);
++   glVertex2f(-1.0, 1.0);
++
++   glEnd();
++}
++
++
++static void scr_Display( void )
++{
++   glClear( GL_COLOR_BUFFER_BIT );
++
++   glPushMatrix();
++      glRotatef(Xrot, 1.0, 0.0, 0.0);
++      glRotatef(Yrot, 0.0, 1.0, 0.0);
++      glRotatef(Zrot, 0.0, 0.0, 1.0);
++      DrawObject();
++   glPopMatrix();
++
++}
++
++
++static void Reshape( int width, int height )
++{
++   glViewport( 0, 0, width, height );
++   glMatrixMode( GL_PROJECTION );
++   glLoadIdentity();
++   glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
++   glMatrixMode( GL_MODELVIEW );
++   glLoadIdentity();
++   glTranslatef( 0.0, 0.0, -15.0 );
++}
++
++static int queryClient(Display *dpy, int screen)
++{
++#ifdef GLX_MESA_allocate_memory
++  char *extensions;
++
++  extensions = (char *)glXQueryExtensionsString(dpy, screen);
++  if (!extensions || !strstr(extensions,"GLX_MESA_allocate_memory")) {
++    return 0;
++  }
++
++  return 1;
++#else
++  return 0;
++#endif
++}
++
++static int
++query_extension(char* extName) {
++    char *p = (char *) glGetString(GL_EXTENSIONS);
++    char *end = p + strlen(p);
++    while (p < end) {
++        int n = strcspn(p, " ");
++        if ((strlen(extName) == n) && (strncmp(extName, p, n) == 0))
++            return GL_TRUE;
++        p += (n + 1);
++    }
++    return GL_FALSE;
++}
++
++static void Init( int argc, char *argv[] , Display *dpy, int screen, Window win)
++{
++   GLuint texObj = 100;
++   const char *file;
++   void *glx_memory;
++
++   if (!query_extension("GL_NV_texture_rectangle")) {
++      printf("Sorry, GL_NV_texture_rectangle is required\n");
++      exit(0);
++   }
++
++   if (!query_extension("GL_MESA_ycbcr_texture")) {
++      printf("Sorry, GL_MESA_ycbcr_texture is required\n");
++      exit(0);
++   }
++
++   if (!queryClient(dpy, screen)) {
++     printf("Sorry, GLX_MESA_allocate_memory is required\n");
++     exit(0);
++   }
++
++   glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1);
++   glBindTexture(GL_TEXTURE_RECTANGLE_NV, texObj);
++#ifdef LINEAR_FILTER
++   /* linear filtering looks much nicer but is much slower for Mesa */
++   glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++   glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++#else
++   glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++   glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
++#endif
++
++   if (argc > 1)
++      file = argv[1];
++   else
++      file = TEXTURE_FILE;
++
++   ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight);
++   if (!ImageYUV) {
++      printf("Couldn't read %s\n", TEXTURE_FILE);
++      exit(0);
++   }
++   
++   glx_memory = glXAllocateMemoryMESA(dpy, screen, ImgWidth * ImgHeight * 2, 0, 0 ,0);
++   if (!glx_memory)
++   {
++     fprintf(stderr,"Failed to allocate MESA memory\n");
++     exit(-1);
++   }
++   
++   memcpy(glx_memory, ImageYUV, ImgWidth * ImgHeight * 2);
++   
++   printf("Image: %dx%d\n", ImgWidth, ImgHeight);
++
++   glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0,
++                GL_YCBCR_MESA, ImgWidth, ImgHeight, 0,
++                GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_APPLE, glx_memory);
++
++   assert(glGetError() == GL_NO_ERROR);
++
++   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
++
++   glEnable(GL_TEXTURE_RECTANGLE_NV);
++
++   glShadeModel(GL_FLAT);
++   glClearColor(0.3, 0.3, 0.4, 1.0);
++
++}
++
++/*
++ * Create an RGB, double-buffered window.
++ * Return the window and context handles.
++ */
++static void
++make_window( Display *dpy, const char *name,
++             int x, int y, int width, int height,
++             Window *winRet, GLXContext *ctxRet)
++{
++   int attribs[] = { GLX_RGBA,
++                     GLX_RED_SIZE, 1,
++                     GLX_GREEN_SIZE, 1,
++                     GLX_BLUE_SIZE, 1,
++                     GLX_DOUBLEBUFFER,
++                     GLX_DEPTH_SIZE, 1,
++                     None };
++   int scrnum;
++   XSetWindowAttributes attr;
++   unsigned long mask;
++   Window root;
++   Window win;
++   GLXContext ctx;
++   XVisualInfo *visinfo;
++
++   scrnum = DefaultScreen( dpy );
++   root = RootWindow( dpy, scrnum );
++   
++   visinfo = glXChooseVisual( dpy, scrnum, attribs );
++   if (!visinfo) {
++     printf("Error: couldn't get an RGB, Double-buffered visual\n");
++     exit(1);
++   }
++
++   /* window attributes */
++   attr.background_pixel = 0;
++   attr.border_pixel = 0;
++   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
++   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
++   attr.override_redirect = 0;
++   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect;
++
++   win = XCreateWindow( dpy, root, 0, 0, width, height,
++		        0, visinfo->depth, InputOutput,
++		        visinfo->visual, mask, &attr );
++
++   /* set hints and properties */
++   {
++      XSizeHints sizehints;
++      sizehints.x = x;
++      sizehints.y = y;
++      sizehints.width  = width;
++      sizehints.height = height;
++      sizehints.flags = USSize | USPosition;
++      XSetNormalHints(dpy, win, &sizehints);
++      XSetStandardProperties(dpy, win, name, name,
++                              None, (char **)NULL, 0, &sizehints);
++   }
++
++   ctx = glXCreateContext( dpy, visinfo, NULL, True );
++   if (!ctx) {
++      printf("Error: glXCreateContext failed\n");
++      exit(1);
++   }
++
++   XFree(visinfo);
++
++   *winRet = win;
++   *ctxRet = ctx;
++}
++
++
++static void
++event_loop(Display *dpy, Window win)
++{
++   while (1) {
++      while (XPending(dpy) > 0) {
++         XEvent event;
++         XNextEvent(dpy, &event);
++         switch (event.type) {
++	 case Expose:
++            /* we'll redraw below */
++	    break;
++	 case ConfigureNotify:
++	   Reshape(event.xconfigure.width, event.xconfigure.height);
++	    break;
++         case KeyPress:
++            {
++               char buffer[10];
++               int r, code;
++               code = XLookupKeysym(&event.xkey, 0);
++	       r = XLookupString(&event.xkey, buffer, sizeof(buffer),
++				 NULL, NULL);
++	       if (buffer[0] == 27) {
++		 /* escape */
++		 return;
++                 
++               }
++            }
++         }
++      }
++
++   }
++}
++
++
++int
++main(int argc, char *argv[])
++{
++   Display *dpy;
++   Window win;
++   GLXContext ctx;
++   char *dpyName = NULL;
++   GLboolean printInfo = GL_FALSE;
++   int i;
++
++   for (i = 1; i < argc; i++) {
++      if (strcmp(argv[i], "-display") == 0) {
++         dpyName = argv[i+1];
++         i++;
++      }
++      else if (strcmp(argv[i], "-info") == 0) {
++         printInfo = GL_TRUE;
++      }
++      else
++	 printf("Warrning: unknown parameter: %s\n", argv[i]);
++   }
++
++   dpy = XOpenDisplay(dpyName);
++   if (!dpy) {
++      printf("Error: couldn't open display %s\n",
++	     XDisplayName(dpyName));
++      return -1;
++   }
++
++   make_window(dpy, "yuvrect_client", 0, 0, 300, 300, &win, &ctx);
++   XMapWindow(dpy, win);
++   glXMakeCurrent(dpy, win, ctx);
++
++   if (printInfo) {
++      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
++      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
++      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
++      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
++   }
++
++   Init(argc, argv, dpy, DefaultScreen(dpy), win);
++
++   scr_Display();			       
++   glXSwapBuffers(dpy, win);
++   event_loop(dpy, win);
++
++   glXFreeMemoryMESA(dpy, DefaultScreen(dpy), glx_memory);
++   glXDestroyContext(dpy, ctx);
++   XDestroyWindow(dpy, win);
++   XCloseDisplay(dpy);
++
++   return 0;
++}

+ 12 - 0
package/MesaLib/patches/patch-include_GL_internal_sarea_h

@@ -0,0 +1,12 @@
+	fix for loongson
+--- Mesa-7.8.1.orig/include/GL/internal/sarea.h	2010-02-05 01:10:39.000000000 +0100
++++ Mesa-7.8.1/include/GL/internal/sarea.h	2010-06-12 19:13:41.417809541 +0200
+@@ -42,6 +42,8 @@
+ /* SAREA area needs to be at least a page */
+ #if defined(__alpha__)
+ #define SAREA_MAX 			0x2000
++#elif defined(__mips__)
++#define SAREA_MAX			0x4000
+ #elif defined(__ia64__)
+ #define SAREA_MAX			0x10000		/* 64kB */
+ #else

+ 3 - 6
package/adkinstall/Makefile

@@ -5,7 +5,7 @@ include ${TOPDIR}/rules.mk
 
 PKG_NAME:=		adkinstall
 PKG_VERSION:=		1.0
-PKG_RELEASE:=		4
+PKG_RELEASE:=		5
 PKG_DESCR:=		installer for cf, mmc, sd or mtd devices
 PKG_SECTION:=		base
 PKG_DEPENDS:=		parted sfdisk e2fsprogs
@@ -31,13 +31,10 @@ do-install:
 ifeq ($(ADK_LINUX_MIPS_RB532),y)
 	${INSTALL_BIN} ./src/adkinstall.rb532 \
 		$(IDIR_ADKINSTALL)/sbin/adkinstall
-else ifeq ($(ADK_LINUX_ARM_FOXBOARD),y)
+else ifeq ($(ADK_LINUX_ARM_FOXG20),y)
 	${INSTALL_BIN} ./src/adkinstall.foxg20 \
 		$(IDIR_ADKINSTALL)/sbin/adkinstall
-else ifeq ($(ADK_LINUX_MIPS_RB433),y)
-	${INSTALL_BIN} ./src/adkinstall.rb4xx \
-		$(IDIR_ADKINSTALL)/sbin/adkinstall
-else ifeq ($(ADK_LINUX_MIPS_RB411),y)
+else ifeq ($(ADK_LINUX_MIPS_RB4XX),y)
 	${INSTALL_BIN} ./src/adkinstall.rb4xx \
 		$(IDIR_ADKINSTALL)/sbin/adkinstall
 else

+ 127 - 28
package/adkinstall/src/adkinstall

@@ -1,38 +1,140 @@
 #!/bin/sh
 # installs a rootfs tar archive from OpenADK onto a Compact Flash disk
 
+check_exit() {
+        if [ $? -ne 0 ];then
+                echo "Installation failed."
+                exit 1
+        fi
+}
+
+rescue=0
+while getopts "r" option
+do
+	case $option in
+		r)
+			rescue=1
+			;;
+		*)
+			printf "Option not recognized\n"
+			exit 1
+			;;
+	esac
+done
+shift $(($OPTIND - 1))
+
 if [ -z $1 ];then
         printf "Please give your root tar archive as parameter\n"
         exit 1
 fi
-# create empty partition table
+
+if [ $rescue -eq 1 ];then
+	if [ -z $2 ];then
+		printf "Please give your rescue kernel image as second parameter\n"
+		exit 2
+	fi
+	if [ ! -f $2 ];then
+		printf "$2 is not a file, Exiting.\n"
+		exit 1
+	fi
+fi
+
+printf "Creating partitions ...\n"
 parted -s /dev/sda mklabel msdos
+check_exit
 sleep 2
 maxsize=$(env LC_ALL=C parted /dev/sda -s unit cyl print |awk '/^Disk/ { print $3 }'|sed -e 's/cyl//')
 rootsize=$(($maxsize-2))
-parted -s /dev/sda unit cyl mkpartfs primary ext2 0 $rootsize
-parted -s /dev/sda unit cyl mkpart primary fat32 $rootsize $maxsize
-parted -s /dev/sda set 1 boot on
-sfdisk --change-id /dev/sda 2 88 >/dev/null 2>&1
-if [ $? -eq 0 ];then
-        printf "Successfully created partition ${rootpart}\n"
-else
-        printf "Partition creation failed, Exiting.\n"
-        exit 1
+start=0
+rootp=1
+cfgfsp=2
+if [ $rescue -eq 1 ];then
+	rootp=3
+	cfgfsp=4
+	start=2
+	parted -s /dev/sda unit cyl mkpartfs primary ext2 0 1
+	parted -s /dev/sda unit cyl mkpartfs primary ext2 1 2
+	check_exit
 fi
-mount -t ext2 /dev/sda1 /mnt
-printf "Extracting install archive\n"
+parted -s /dev/sda unit cyl mkpartfs primary ext2 $start $rootsize
+check_exit
+parted -s /dev/sda unit cyl mkpart primary fat32 $rootsize $maxsize
+check_exit
+parted -s /dev/sda set $rootp boot on
+check_exit
+sfdisk --change-id /dev/sda $cfgfsp 88 >/dev/null 2>&1
+check_exit
+# settle down
+sleep 2
+mount -t ext2 /dev/sda$rootp /mnt
+check_exit
+printf "Extracting install archive ...\n"
 tar -C /mnt -xzpf $1
+check_exit
 chmod 1777 /mnt/tmp
 chmod 4755 /mnt/bin/busybox
+if [ $rescue -eq 1 ];then
+	mkdir /mnt/boot/grub
+fi
 
 speed=$(awk -F \, '/console=ttyS0/ { print $2 }' /proc/cmdline|sed -e "s/ .*$//")
 
-printf "Install bootloader\n"
+if [ $rescue -eq 1 ];then
+	umount /mnt
+	mount /dev/sda2 /mnt
+	cp $2 /mnt/rescue
+fi
+printf "Installing bootloader ...\n"
 mkdir -p /mnt/boot/grub
-mount -o bind /dev /mnt/dev
-chroot /mnt mount -t proc /proc /proc
-chroot /mnt mount -t sysfs /sys /sys
+if [ $rescue -eq 1 ];then
+mount /dev/sda1 /mnt/boot/grub
+cat << EOF > /mnt/boot/grub/grub.cfg
+set timeout=1
+serial --unit=0 --speed=$speed
+terminal_output serial 
+terminal_input serial 
+
+if [ -s \$prefix/grubenv ]; then
+  load_env
+fi
+
+set default="\${saved_entry}"
+
+if [ \${prev_saved_entry} ]; then
+  set saved_entry=\${prev_saved_entry}
+  save_env saved_entry
+  set prev_saved_entry=
+  save_env prev_saved_entry
+  set boot_once=true
+fi
+
+function savedefault {
+  if [ -z \${boot_once} ]; then
+    saved_entry=\${chosen}
+    save_env saved_entry
+  fi
+}
+
+function recordfail {
+  set recordfail=1
+  if [ -n \${have_grubenv} ]; then if [ -z \${boot_once} ]; then save_env recordfail; fi; fi
+}
+
+menuentry "GNU/Linux (OpenADK)" {
+	recordfail
+        insmod ext2
+        set root=(hd0,3)
+        linux /boot/vmlinuz-adk root=/dev/sda$rootp ro init=/init panic=10
+}
+
+menuentry "GNU/Linux (OpenADK) Rescue Mode" {
+	recordfail
+        insmod ext2
+        set root=(hd0,2)
+        linux /rescue ro init=/init panic=10
+}
+EOF
+else
 cat << EOF > /mnt/boot/grub/grub.cfg
 set default=0
 set timeout=1
@@ -43,19 +145,16 @@ terminal_input serial
 menuentry "GNU/Linux (OpenADK)" {
         insmod ext2
         set root=(hd0,1)
-        linux /boot/vmlinuz-adk root=/dev/sda1 ro init=/init panic=10
+        linux /boot/vmlinuz-adk root=/dev/sda$rootp ro init=/init panic=10
 }
 EOF
-chroot /mnt grub-install /dev/sda >/dev/null 2>&1
-umount /mnt/proc
-umount /mnt/sys
-umount /mnt/dev
-
-printf "Creating device nodes\n"
-mknod -m 666 /mnt/dev/null c 1 3
-mknod -m 622 /mnt/dev/console c 5 1
-mknod -m 666 /mnt/dev/tty c 5 0
-
+fi
+grub-install --root-directory=/mnt /dev/sda 
+check_exit
+if [ $rescue -eq 1 ];then
+	grub-set-default --root-directory=/mnt 0
+	umount /mnt/boot/grub
+fi
 umount /mnt
-printf "Successfully installed.\n"
+printf "Successfully installed. You can reboot now.\n"
 exit 0

+ 2 - 2
package/aircrack-ng/Makefile

@@ -4,9 +4,9 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=		aircrack-ng
-PKG_VERSION:=		1.0
+PKG_VERSION:=		1.1
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		dafbfaf944ca9d523fde4bae86f0c067
+PKG_MD5SUM:=		f7a24ed8fad122c4187d06bfd6f998b4
 PKG_DESCR:=		set of tools for auditing wireless networks
 PKG_SECTION:=		net
 PKG_DEPENDS:=		libpthread libopenssl libpcap

+ 35 - 0
package/alix-switch/Makefile

@@ -0,0 +1,35 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include ${TOPDIR}/rules.mk
+
+PKG_NAME:=		alix-switch
+PKG_VERSION:=		1.0
+PKG_RELEASE:=		1
+PKG_DESCR:=		simple daemon listening on button events
+PKG_SECTION:=		base
+
+PKG_TARGET_DEPENDS:=	alix
+
+NO_DISTFILES:=		1
+
+include ${TOPDIR}/mk/package.mk
+
+$(eval $(call PKG_template,ALIX_SWITCH,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+
+PKGDFLT_ALIX_SWITCH=	y
+
+CONFIG_STYLE:=		manual
+BUILD_STYLE:=		manual
+INSTALL_STYLE:=		manual
+
+do-build:
+	${TARGET_CC} -Wall ${TCPPFLAGS} ${TCFLAGS} \
+		-o ${WRKBUILD}/alix-switchd ${WRKBUILD}/alix-switchd.c
+
+do-install:
+	${INSTALL_DIR} ${IDIR_ALIX_SWITCH}/usr/sbin ${IDIR_ALIX_SWITCH}/etc
+	${INSTALL_BIN} ${WRKBUILD}/alix-switchd ${IDIR_ALIX_SWITCH}/usr/sbin
+	${INSTALL_BIN} ./files/alix-switch ${IDIR_ALIX_SWITCH}/etc
+
+include ${TOPDIR}/mk/pkg-bottom.mk

+ 19 - 0
package/alix-switch/files/alix-switch

@@ -0,0 +1,19 @@
+#!/bin/sh
+# launched by alix-switchd in case of button event
+# f.e. boot rescue system once
+case "$1" in
+  on)
+    echo "alix-switch: on"
+    mount /dev/sda1 /boot/grub
+    grub-reboot 1
+    umount /boot/grub
+    reboot
+    ;;
+  off)
+    echo "alix-switch: off"
+    ;;
+  *)
+    echo "Usage: $0 {on|off}"
+    ;;
+esac
+exit $?

+ 27 - 0
package/alix-switch/files/alix-switch.init

@@ -0,0 +1,27 @@
+#!/bin/sh
+#PKG alix-switch
+#INIT 10
+
+. /etc/rc.conf
+
+case $1 in
+autostop) ;;
+autostart)
+	test x"${alix_switch:-NO}" = x"NO" && exit 0
+	exec sh $0 start
+	;;
+start)
+	alix-switchd -d
+	;;
+stop)
+	pkill alix-switchd
+	;;
+restart)
+	sh $0 stop
+	sh $0 start
+	;;
+*)
+	echo "usage: $0 (start|stop|restart)"
+	exit 1
+esac
+exit $?

+ 3 - 0
package/alix-switch/files/alix-switch.postinst

@@ -0,0 +1,3 @@
+#!/bin/sh
+. $IPKG_INSTROOT/etc/functions.sh
+add_rcconf alix_switch alix_switch YES

+ 108 - 0
package/alix-switch/src/alix-switchd.c

@@ -0,0 +1,108 @@
+/*
+* alix-switchd.c
+*
+* 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.
+*/
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/io.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#define SCRIPT		"/etc/alix-switch"
+#define GPIOBASE	0x6100
+
+typedef void (*sighandler_t)(int);
+
+static sighandler_t handle_signal (int sig_nr, sighandler_t signalhandler) {
+
+	struct sigaction neu_sig, alt_sig;
+
+	neu_sig.sa_handler = signalhandler;
+	sigemptyset(&neu_sig.sa_mask);
+	neu_sig.sa_flags = SA_RESTART;
+	if (sigaction (sig_nr, &neu_sig, &alt_sig) < 0)
+		return SIG_ERR;
+
+	return alt_sig.sa_handler;
+}
+
+static void start_daemon (void) {
+
+	int i;
+	pid_t pid, sid;
+
+	handle_signal(SIGHUP, SIG_IGN);
+	if ((pid = fork ()) != 0)
+		exit(EXIT_FAILURE);
+	umask(0);
+	if ((sid = setsid()) < 0)
+		exit(EXIT_FAILURE);
+	chdir("/");
+	for (i = sysconf(_SC_OPEN_MAX); i > 0; i--)
+		close(i);
+}
+
+
+int main(int argc, char *argv[]) {
+
+	int i;
+	unsigned long bPort = 0;
+	struct timespec sleep;
+	int bDaemon = 0, bSwitch = 0, bState = 0;
+ 
+	for(i = 1; i < argc; i++) {
+		if (!strcasecmp(argv[i], "-d") || !strcasecmp(argv[i], "--daemon")) {
+			bDaemon = 1;
+		} else {
+			printf( "\nusage: %s [-d | --daemon]\n", argv[0]);
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	if (iopl(3)) {
+		fprintf( stderr, "Could not set I/O permissions to level 3\n");
+		exit(EXIT_FAILURE);
+	}
+   
+	if (bDaemon)
+		start_daemon();
+
+	sleep.tv_sec = 0;
+	sleep.tv_nsec = 50000000;
+
+	while(1) {
+		bPort = inl(GPIOBASE + 0xB0);
+		if ((bPort & 0x100) == 0)
+			bState = 1;
+		else
+			bState = 0;
+      
+		if (bState && !bSwitch)
+     			system(SCRIPT " on");
+
+		bSwitch = bState;
+		nanosleep(&sleep, NULL);
+	}
+
+	if (iopl(0)) {
+      		fprintf(stderr, "Could not set I/O permissions to level 0");
+		exit(EXIT_FAILURE);
+	}
+
+	return EXIT_SUCCESS;
+}

+ 16 - 1
package/alsa-utils/Makefile

@@ -11,20 +11,35 @@ PKG_DESCR:=		ALSA mixer utility
 PKG_SECTION:=		utils
 PKG_DEPENDS:=		alsa-lib libpthread
 PKG_BUILDDEP+=		alsa-lib
+ifeq (${ADK_PACKAGE_ALSA_UTILS_WITH_ALSAMIXER},y)
+PKG_BUILDDEP+=		libncurses
+endif
 PKG_URL:=		http://www.alsa-project.org
 PKG_SITES:=		ftp://ftp.task.gda.pl/pub/linux/misc/alsa/utils/ \
 			ftp://ftp.alsa-project.org/pub/utils/
 
+PKG_FLAVOURS:=		WITH_ALSAMIXER
+PKGFS_WITH_ALSAMIXER:=	libncurses
+PKGFD_WITH_ALSAMIXER:=	include alsamixer ncurses applet
+
 DISTFILES:=             ${PKG_NAME}-${PKG_VERSION}.tar.bz2
 
 include ${TOPDIR}/mk/package.mk
 
 $(eval $(call PKG_template,ALSA_UTILS,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
 
+ifeq (${ADK_PACKAGE_ALSA_UTILS_WITH_ALSAMIXER},y)
+CONFIGURE_ARGS+=	--enable-alsamixer
+else
 CONFIGURE_ARGS+=	--disable-alsamixer
+endif
 
 post-install:
-	${INSTALL_DIR} ${IDIR_ALSA_UTILS}/usr/bin 
+	${INSTALL_DIR} ${IDIR_ALSA_UTILS}/usr/bin/
 	${CP} ${WRKINST}/usr/bin/amixer ${IDIR_ALSA_UTILS}/usr/bin/
+ifeq (${ADK_PACKAGE_ALSA_UTILS_WITH_ALSAMIXER},y)
+	${INSTALL_BIN} ${WRKINST}/usr/bin/alsamixer \
+		${IDIR_ALSA_UTILS}/usr/bin/
+endif
 
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 5 - 5
package/apr-util/Makefile

@@ -4,9 +4,9 @@
 include ${TOPDIR}/rules.mk
 
 PKG_NAME:=              apr-util
-PKG_VERSION:=           0.9.15
+PKG_VERSION:=           1.3.9
 PKG_RELEASE:=           1
-PKG_MD5SUM:=            dc772ae295f49ddb8ee8e69a9716c53b
+PKG_MD5SUM:=            cc2ec0ba4f01d88375f1170f762518fa
 PKG_DESCR:=		Apache Portable Runtime utility library
 PKG_SECTION:=		libs
 PKG_DEPENDS:=		libexpat apr
@@ -21,11 +21,11 @@ $(eval $(call PKG_template,APR_UTIL,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${
 CONFIGURE_ARGS+=	--without-berkeley-db
 CONFIGURE_ARGS+=	--with-apr=${STAGING_DIR}/usr
 CONFIGURE_ARGS+=	--with-expat=${STAGING_DIR}/usr
-XAKE_FLAGS+=		apr_builddir=${STAGING_DIR}/usr/share/build \
-			apr_builders=${STAGING_DIR}/usr/share/build
+XAKE_FLAGS+=		apr_builddir=${STAGING_DIR}/usr/share/build-1 \
+			apr_builders=${STAGING_DIR}/usr/share/build-1
 
 post-install:
 	${INSTALL_DIR} ${IDIR_APR_UTIL}/usr/lib
-	${CP} ${WRKINST}/usr/lib/libaprutil-0.so* ${IDIR_APR_UTIL}/usr/lib/
+	${CP} ${WRKINST}/usr/lib/libaprutil-1.so* ${IDIR_APR_UTIL}/usr/lib/
 
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 0 - 19
package/apr-util/patches/patch-uri_Makefile_in

@@ -1,19 +0,0 @@
-$Id$
---- apr-util-0.9.13.orig/uri/Makefile.in	2004-11-25 00:45:40.000000000 +0100
-+++ apr-util-0.9.13/uri/Makefile.in	2007-02-07 12:55:37.000000000 +0100
-@@ -3,7 +3,7 @@ VPATH = @srcdir@
- INCLUDES = @APRUTIL_PRIV_INCLUDES@ @APR_INCLUDES@ @APRUTIL_INCLUDES@ -I.
- 
- TARGETS = uri_delims.h apr_uri.lo
--CLEAN_TARGETS = gen_uri_delims uri_delims.h
-+CLEAN_TARGETS = gen_uri_delims
- 
- # bring in rules.mk for standard functionality
- @INCLUDE_RULES@
-@@ -13,6 +13,3 @@ gen_uri_delims: $(gen_uri_delims_OBJECTS
- 	$(LINK) $(EXTRA_LDFLAGS) $(gen_uri_delims_OBJECTS) $(EXTRA_LIBS)
- 
- apr_uri.lo: uri_delims.h apr_uri.c
--
--uri_delims.h: gen_uri_delims
--	./gen_uri_delims > uri_delims.h

+ 0 - 21
package/apr-util/patches/uri_delim.patch

@@ -1,21 +0,0 @@
-diff -Nur apr-util-0.9.13/uri/uri_delims.h build_mipsel/w-apr-util-0.9.13-1/apr-util-0.9.13/uri/uri_delims.h
---- apr-util-0.9.13/uri/uri_delims.h    1970-01-01 01:00:00.000000000 +0100
-+++ build_mipsel/w-apr-util-0.9.13-1/apr-util-0.9.13/uri/uri_delims.h   2007-02-07 13:06:56.000000000 +0100
-@@ -0,0 +1,16 @@
-+/* this file is automatically generated by gen_uri_delims, do not edit */
-+static const unsigned char uri_delims[256] = {
-+    T_NUL,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,T_HASH,0,0,0,0,
-+    0,0,0,0,0,0,0,T_SLASH,0,0,0,0,0,0,0,0,0,0,T_COLON,0,
-+    0,0,0,T_QUESTION,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-+};
-

+ 8 - 19
package/apr/Makefile

@@ -4,22 +4,15 @@
 include ${TOPDIR}/rules.mk
 
 PKG_NAME:=		apr
-PKG_VERSION:=		0.9.17
+PKG_VERSION:=		1.4.2
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		ca1e22d98081a03a33c2a0b8684eb192
+PKG_MD5SUM:=		fc80cb54f158c2674f9eeb47a1f672cd
 PKG_DESCR:=		Apache Portable Runtime library
 PKG_SECTION:=		libs
-ifeq ($(ADK_PACKAGE_APR_THREADING),y)
 PKG_DEPENDS:=		libpthread
-PKG_BUILDDEP+=		libpthread
-endif
 PKG_URL:=		http://apr.apache.org
 PKG_SITES:=		http://gd.tuwien.ac.at/infosys/servers/http/apache/dist/${PKG_NAME}/
 
-PKG_FLAVOURS=		THREADING
-PKGFD_FULL=		Enable threading support
-
-
 include ${TOPDIR}/mk/package.mk
 
 $(eval $(call PKG_template,APR,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
@@ -31,23 +24,19 @@ CONFIGURE_ENV+=		ac_cv_sizeof_ssize_t=4
 CONFIGURE_ENV+=		ac_cv_file__dev_zero=yes
 CONFIGURE_ENV+=		apr_cv_process_shared_works=no
 CONFIGURE_ENV+=		ac_cv_lib_nsl_gethostbyname=no
+CONFIGURE_ENV+=		apr_cv_tcp_nodelay_with_cork=no
 CONFIGURE_ARGS+=	--with-devrandom=/dev/urandom
-
-ifeq (${ADK_PACKAGE_APR_THREADING},y)
 CONFIGURE_ARGS+=	--enable-threads
-else
-CONFIGURE_ARGS+=	--disable-threads
-endif
 
 post-install:
 	${INSTALL_DIR} ${IDIR_APR}/usr/lib
-	${CP} ${WRKINST}/usr/lib/libapr-0.so* ${IDIR_APR}/usr/lib/
-	${INSTALL_DIR} ${STAGING_DIR}/usr/share/build
-	${CP} ${WRKINST}/usr/share/build/* ${STAGING_DIR}/usr/share/build/
+	${CP} ${WRKINST}/usr/lib/libapr-1.so* ${IDIR_APR}/usr/lib/
+	${INSTALL_DIR} ${STAGING_DIR}/usr/share/build-1
+	${CP} ${WRKINST}/usr/share/build-1/* ${STAGING_DIR}/usr/share/build-1/
 	# we need to patch paths to get apr-util compiling
 	$(SED) "s,\(^installbuilddir=\"\)\(.*\),\1${STAGING_DIR}\2," \
-		${WRKINST}/usr/bin/apr-config
+		${WRKINST}/usr/bin/apr-1-config
 	$(SED) "s,\(^datadir=\"\)\(.*\),\1${STAGING_DIR}\2," \
-		${WRKINST}/usr/bin/apr-config
+		${WRKINST}/usr/bin/apr-1-config
 
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 16 - 0
package/apr/patches/patch-include_apr_want_h

@@ -0,0 +1,16 @@
+--- apr-1.4.2.orig/include/apr_want.h	2010-01-06 12:36:50.000000000 +0100
++++ apr-1.4.2/include/apr_want.h	2010-05-29 17:56:14.201613974 +0200
+@@ -89,11 +89,13 @@
+ 
+ #else
+ 
++/*
+ struct iovec
+ {
+     void *iov_base;
+     size_t iov_len;
+ };
++*/
+ 
+ #endif
+ 

+ 8 - 4
package/asterisk/Makefile

@@ -4,9 +4,9 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=		asterisk
-PKG_VERSION:=		1.6.2.5
+PKG_VERSION:=		1.6.2.7
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		9d1f7bcf6833605ced4b2740d14bd576
+PKG_MD5SUM:=		861f57ba43bfe05dc645e0679a260e41
 PKG_DESCR:=		Open Source PBX
 PKG_SECTION:=		net
 PKG_MULTI:=		1
@@ -174,6 +174,7 @@ do-install: ${SUB_INSTALLS-m} ${SUB_INSTALLS-y}
 		rm -f gtalk.conf ; \
 		rm -f skinny.conf ; \
 		rm -f dundi.conf ; \
+		$(SED) '#^astdatadir = /var/#/usr/#' asterisk.conf ; \
 	)
 	${INSTALL_DATA} ./files/modules.conf $(IDIR_ASTERISK)/etc/asterisk/
 	$(SED) 's|/var/lib/asterisk|/usr/lib/asterisk|g' \
@@ -191,8 +192,11 @@ asterisk-sounds-install:
 	${INSTALL_DIR} $(IDIR_ASTERISK_SOUNDS)/usr/lib/asterisk/sounds
 	$(CP) $(WRKBUILD)/sounds/* \
 		$(IDIR_ASTERISK_SOUNDS)/usr/lib/asterisk/sounds/
-	rm -f $(IDIR_ASTERISK_SOUNDS)/usr/lib/asterisk/sounds/*.mp3
-	rm -f $(IDIR_ASTERISK_SOUNDS)/usr/lib/asterisk/sounds/vm-*
+	(cd $(IDIR_ASTERISK_SOUNDS)/usr/lib/asterisk/sounds; \
+		rm -f *.mp3 vm-*; \
+		rm -f CHANGES* CREDITS* LICENSE* *.txt ; \
+		rm -f *.tar.gz Makefile ; \
+	)
 
 asterisk-voicemail-install:
 	${INSTALL_DIR} $(IDIR_ASTERISK_VOICEMAIL)/etc/asterisk

+ 0 - 13
package/asterisk/patches/patch-Makefile

@@ -1,13 +0,0 @@
---- asterisk-1.6.2.1.orig/Makefile	2009-12-10 22:04:20.000000000 +0100
-+++ asterisk-1.6.2.1/Makefile	2010-02-05 21:05:41.313084404 +0100
-@@ -366,8 +366,8 @@ makeopts: configure
- 	@exit 1
- 
- menuselect.makeopts: menuselect/menuselect menuselect-tree makeopts build_tools/menuselect-deps $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS)
--	menuselect/menuselect --check-deps $@
--	menuselect/menuselect --check-deps $@ $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS)
-+	./menuselect/menuselect --check-deps $@
-+	./menuselect/menuselect --check-deps $@ $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS)
- 
- $(MOD_SUBDIRS_EMBED_LDSCRIPT):
- 	+@echo "EMBED_LDSCRIPTS+="`$(SILENTMAKE) -C $(@:-embed-ldscript=) SUBDIR=$(@:-embed-ldscript=) __embed_ldscript` >> makeopts.embed_rules

+ 0 - 26
package/asterisk/patches/patch-apps_app_followme_c

@@ -1,26 +0,0 @@
---- asterisk-1.6.2.1.orig/apps/app_followme.c	2009-09-15 18:06:24.000000000 +0200
-+++ asterisk-1.6.2.1/apps/app_followme.c	2010-02-14 10:33:51.540422962 +0100
-@@ -172,7 +172,9 @@ static int ynlongest = 0;
- 
- static const char *featuredigittostr;
- static int featuredigittimeout = 5000;		/*!< Feature Digit Timeout */
--static const char *defaultmoh = "default";    	/*!< Default Music-On-Hold Class */
-+static const char *defaultmoh;		    	/*!< Default Music-On-Hold Class */
-+
-+
- 
- static char takecall[20] = "1", nextindp[20] = "2";
- static char callfromprompt[PATH_MAX] = "followme/call-from";
-@@ -236,6 +238,7 @@ static struct call_followme *alloc_profi
- 
- static void init_profile(struct call_followme *f)
- {
-+	defaultmoh = "default";
- 	f->active = 1;
- 	ast_copy_string(f->moh, defaultmoh, sizeof(f->moh));
- }
-@@ -1195,3 +1198,4 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MO
- 		.unload = unload_module,
- 		.reload = reload,
- 	       );
-+

+ 26 - 0
package/b43-firmware/Makefile

@@ -0,0 +1,26 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include ${TOPDIR}/rules.mk
+
+PKG_NAME:=		b43-firmware
+PKG_VERSION:=		1.0
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		37c8d2c029a7e5b82f4433a6fa1e2ee5
+PKG_DESCR:=		firmware for b43 wireless cards
+PKG_SECTION:=		sys
+PKG_SITES:=		http://openadk.org/distfiles/
+
+include ${TOPDIR}/mk/package.mk
+
+$(eval $(call PKG_template,B43_FIRMWARE,b43-firmware,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+
+CONFIG_STYLE:=          manual
+BUILD_STYLE:=           manual
+INSTALL_STYLE:=         manual
+
+do-install:
+	${INSTALL_DIR} ${IDIR_B43_FIRMWARE}/lib/firmware
+	${CP} ${WRKBUILD}/* ${IDIR_B43_FIRMWARE}/lib/firmware/
+
+include ${TOPDIR}/mk/pkg-bottom.mk

+ 10 - 8
package/base-files/Makefile

@@ -6,9 +6,9 @@ include $(TOPDIR)/mk/rootfs.mk
 
 PKG_NAME:=		base-files
 PKG_VERSION:=		1.0
-PKG_RELEASE:=		10
-PKG_DESCR:=		basic filesystem structure and scripts
+PKG_RELEASE:=		17
 PKG_SECTION:=		base
+PKG_DESCR:=		basic filesystem structure and scripts
 
 WRKDIST=		${WRKDIR}/base-files
 NO_DISTFILES:=		1
@@ -31,12 +31,10 @@ do-install:
 ifeq (${ADK_TARGET_ROOTFS_NFSROOT},y)
 	@-rm $(IDIR_BASE_FILES)/etc/network/interfaces
 endif
-ifeq (${ADK_TARGET_PACKAGE_IPKG},y)
 	$(SED) 's,@TARGET@,$(ADK_TARGET),g' $(IDIR_BASE_FILES)/etc/ipkg.conf
-	$(SED) 's,@VERSION@,$(ADK_VERSION),g' $(IDIR_BASE_FILES)/etc/ipkg.conf
-else
-	@-rm $(IDIR_BASE_FILES)/etc/ipkg.conf
-endif
+	$(SED) 's,@HOST@,$(ADK_HOST),g' $(IDIR_BASE_FILES)/etc/ipkg.conf
+	$(SED) 's,@LIBC@,$(ADK_LIBC),g' $(IDIR_BASE_FILES)/etc/ipkg.conf
+	$(SED) 's,@VENDOR@,$(ADK_VENDOR),g' $(IDIR_BASE_FILES)/etc/ipkg.conf
 	echo /bin/sh >${IDIR_BASE_FILES}/etc/shells
 	echo /bin/ash >>${IDIR_BASE_FILES}/etc/shells
 ifneq (${ADK_PACKAGE_BASH},)
@@ -64,10 +62,14 @@ endif
 	mkdir -p $(IDIR_BASE_FILES)/usr/bin
 	chmod 755 $(IDIR_BASE_FILES)/lib/mdev/init
 	chmod 600 $(IDIR_BASE_FILES)/etc/shadow
-	ln -sf ../tmp/resolv.conf $(IDIR_BASE_FILES)/etc/resolv.conf
 	ln -sf ../proc/mounts $(IDIR_BASE_FILES)/etc/mtab
 	rm -rf $(IDIR_BASE_FILES)/var
 	ln -sf tmp $(IDIR_BASE_FILES)/var
+	test -z $(ADK_PASSWORD) || \
+	    $(SED) 's,\*NP\*,'"$$(${STAGING_TOOLS}/bin/mkcrypt \
+	    ${ADK_PASSWORD}),g" $(IDIR_BASE_FILES)/etc/shadow
+	git log -1|head -1|sed -e 's#commit ##' \
+		> $(IDIR_BASE_FILES)/etc/adkversion
 ifneq (${ADK_PACKAGE_CONFIG_IN_ETC},)
 	gzip -9c ${TOPDIR}/.config >$(IDIR_BASE_FILES)/etc/adkconfig.gz
 endif

+ 1 - 1
package/base-files/src/etc/ipkg.conf

@@ -1,3 +1,3 @@
-src openadk http://www.openadk.org/packages/@TARGET@
+src @VENDOR@ http://@HOST@/@TARGET@_@LIBC@/packages
 dest root /
 dest ram /tmp

+ 17 - 7
package/base-files/src/etc/network/if-pre-up.d/04-wireless

@@ -74,13 +74,23 @@ case "$IF_WIRELESS_MODE" in
 		}
 		;;
 	sta)
-		[ -x /usr/sbin/iw ] || {
-			logger -t wireless "No iw utility found"
-			exit 1
-		}
 		ip link set up dev ${IFACE}
-		iw dev ${IFACE} set channel $IF_WIRELESS_CHANNEL
-		iw dev ${IFACE} connect $IF_WIRELESS_SSID
+		[ $IF_WIRELESS_EXTENSION -eq 1 ] && {
+			[ -x /usr/sbin/iwconfig ] || {
+				logger -t wireless "No wireless-tools found"	
+				exit 1
+			}
+			driver=wext
+			iwconfig ${IFACE} essid $IF_WIRELESS_SSID
+		} || {
+			[ -x /usr/sbin/iw ] || {
+				logger -t wireless "No iw utility found"
+				exit 1
+			}
+			driver=nl80211
+			iw dev ${IFACE} set channel $IF_WIRELESS_CHANNEL
+			iw dev ${IFACE} connect $IF_WIRELESS_SSID
+		}
 		[ $wpa2 -eq 1 ] && {
 			[ -x /usr/sbin/wpa_supplicant ] || {
 				logger -t wireless "No wpa_supplicant found"
@@ -93,7 +103,7 @@ case "$IF_WIRELESS_MODE" in
 		 	echo " psk=\"$IF_WIRELESS_PASSPHRASE\"" >> /tmp/wpa_supplicant.conf
 			echo " priority=5" >> /tmp/wpa_supplicant.conf
 			echo "}"  >> /tmp/wpa_supplicant.conf
-			wpa_supplicant -B -Dnl80211 -i${IFACE} -c/tmp/wpa_supplicant.conf
+			wpa_supplicant -B -D${driver} -i${IFACE} -c/tmp/wpa_supplicant.conf
 		}
 		;;
 	*)

+ 0 - 1
package/base-files/src/etc/profile

@@ -4,7 +4,6 @@ if [[ $(id -u) = 0 ]]; then
 	export PS1='# '
 else
 	export PS1='$ '
-	export HOME=/tmp
 fi
 cat /etc/banner 2>&-
 [ -x /usr/bin/vim ] && alias vi=vim || alias vim=vi

+ 1 - 2
package/base-files/src/etc/shadow

@@ -1,3 +1,2 @@
-root:$1$8sJkb6fV$46vEIu5ntmbUuljmr55zY/:14191:0:::::
-admin:$1$8sJkb6fV$46vEIu5ntmbUuljmr55zY/:14191:0:::::
+root:*NP*:14191:0:::::
 nobody:*:9797:0:::::

+ 2 - 1
package/base-files/src/init

@@ -4,7 +4,8 @@ export PATH=/bin:/sbin:/usr/bin:/usr/sbin
 mount -nt proc proc /proc
 mount -o nosuid,nodev,noexec -t sysfs sysfs /sys
 [ ! -f /etc/notmpfs ] && {
-	size=$(awk '/MemTotal:/ { if ($2 > 16000) { print 4096 } else { print 2048 }}' /proc/meminfo)
+	size=2048
+	size=$(cat /etc/tmpfs 2>/dev/null)
 	mount none /tmp -t tmpfs -o size=${size}k
 	mount none /tmp -t tmpfs -o remount,nosuid,nodev,mode=1777
 }

+ 3 - 0
package/base-files/src/sbin/adkupdate

@@ -29,9 +29,12 @@ check_exit() {
 prepare() {
 	cd /
 	if [ -x /sbin/cfgfs ];then
+		pkill crond
 		umount -f /etc
+		check_exit
 	fi
 	mount -o remount,rw /
+	check_exit
 	if [ "$system" == "RB532" ];then
 		mount -t yaffs2 /dev/mtdblock0 /boot
 	elif [ "$system" == "AR7130" ];then

+ 12 - 6
package/busybox/Makefile

@@ -5,11 +5,11 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=		busybox
 PKG_VERSION:=		1.16.1
-PKG_RELEASE:=		1
+PKG_RELEASE:=		4
 PKG_MD5SUM:=		319486ec65078d07fde26eb620fecde7
 PKG_DESCR:=		Core utilities for embedded Linux systems
 PKG_SECTION:=		base
-PKG_URL:=		http://www.busybox.net
+PKG_URL:=		http://www.busybox.net/
 PKG_SITES:=		http://www.busybox.net/downloads/
 
 DISTFILES:=		${PKG_NAME}-${PKG_VERSION}.tar.bz2
@@ -30,6 +30,12 @@ CONFIG_STYLE:=		manual
 BUILD_STYLE:=		manual
 INSTALL_STYLE:=		manual
 
+bbrebuild:
+	@if [ -f ${TOPDIR}/.bbrebuild ];then \
+		rm ${WRKBUILD}/.build_done; \
+		rm ${TOPDIR}/.bbrebuild; \
+	fi
+
 ${TOPDIR}/.busyboxcfg: ${TOPDIR}/.config
 	grep BUSYBOX_ $(TOPDIR)/.config|sed -e 's/BUSYBOX_/CONFIG_/' > \
 		${TOPDIR}/.busyboxcfg
@@ -38,7 +44,7 @@ ${WRKBUILD}/.config: ${TOPDIR}/.busyboxcfg
 	cp $(TOPDIR)/.busyboxcfg ${WRKBUILD}/.config
 	$(SED) 's;@IDIR@;${WRKINST};' ${WRKBUILD}/.config
 	
-do-configure: $(TOPDIR)/.busyboxcfg ${WRKBUILD}/.config
+do-configure: ${WRKBUILD}/.config
 ifeq ($(ADK_NATIVE),y)
 	yes '' | \
 	$(MAKE) V=1 \
@@ -51,7 +57,7 @@ else
 	    ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) oldconfig $(MAKE_TRACE)
 endif
 
-do-build: $(TOPDIR)/.busyboxcfg ${WRKBUILD}/.config
+do-build: do-configure
 ifeq ($(ADK_NATIVE),y)
 	$(MAKE) V=1 \
 	    IPKG_ARCH="$(CPU_ARCH)" ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) busybox
@@ -60,7 +66,7 @@ else
 	    IPKG_ARCH="$(CPU_ARCH)" ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) busybox
 endif
 
-do-install: $(TOPDIR)/.busyboxcfg ${WRKBUILD}/.config ${SUB_INSTALLS-m} ${SUB_INSTALLS-y}
+do-install: ${WRKBUILD}/.config ${SUB_INSTALLS-m} ${SUB_INSTALLS-y}
 ifeq ($(ADK_NATIVE),y)
 	$(MAKE) V=1 \
 	    IPKG_ARCH="$(CPU_ARCH)" ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) install $(MAKE_TRACE)
@@ -78,6 +84,6 @@ udhcpd-install:
 	${INSTALL_DIR} ${IDIR_UDHCPD}/etc/
 	${INSTALL_DATA} ./files/udhcpd.conf ${IDIR_UDHCPD}/etc/
 
-fake:	$(TOPDIR)/.busyboxcfg do-configure do-install
+fake: bbrebuild
 
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 1 - 0
package/busybox/config/archival/Config.in

@@ -32,6 +32,7 @@ config BUSYBOX_FEATURE_SEAMLESS_Z
 config BUSYBOX_AR
 	bool "ar"
 	default n
+	depends on !ADK_PACKAGE_BINUTILS
 	help
 	  ar is an archival utility program used to create, modify, and
 	  extract contents from archives. An archive is a single file holding

+ 0 - 1
package/busybox/config/editors/Config.in

@@ -76,7 +76,6 @@ config BUSYBOX_SED
 
 config BUSYBOX_VI
 	bool "vi"
-	depends on !ADK_PACKAGE_VIM
 	default y
 	help
 	  'vi' is a text editor. More specifically, it is the One True

+ 0 - 665
package/busybox/files/busybox.config

@@ -1,665 +0,0 @@
-# Busybox version: 1.4.2
-#
-CONFIG_HAVE_DOT_CONFIG=y
-
-#
-# Busybox Settings
-#
-
-#
-# General Configuration
-#
-CONFIG_NITPICK=y
-# CONFIG_DESKTOP is not set
-CONFIG_FEATURE_BUFFERS_USE_MALLOC=y
-# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
-# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
-CONFIG_SHOW_USAGE=y
-CONFIG_FEATURE_VERBOSE_USAGE=y
-# CONFIG_FEATURE_COMPRESS_USAGE is not set
-# CONFIG_FEATURE_INSTALLER is not set
-# CONFIG_LOCALE_SUPPORT is not set
-CONFIG_GETOPT_LONG=y
-CONFIG_FEATURE_DEVPTS=y
-# CONFIG_FEATURE_CLEAN_UP is not set
-CONFIG_FEATURE_SUID=y
-CONFIG_FEATURE_SYSLOG=y
-# CONFIG_FEATURE_SUID_CONFIG is not set
-# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set
-CONFIG_FEATURE_HAVE_RPC=y
-# CONFIG_SELINUX is not set
-CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
-
-#
-# Build Options
-#
-# CONFIG_STATIC is not set
-# CONFIG_BUILD_LIBBUSYBOX is not set
-# CONFIG_FEATURE_FULL_LIBBUSYBOX is not set
-# CONFIG_FEATURE_SHARED_BUSYBOX is not set
-CONFIG_LFS=y
-# CONFIG_BUILD_AT_ONCE is not set
-
-#
-# Debugging Options
-#
-# CONFIG_DEBUG is not set
-# CONFIG_DEBUG_PESSIMIZE is not set
-# CONFIG_NO_DEBUG_LIB is not set
-# CONFIG_DMALLOC is not set
-# CONFIG_EFENCE is not set
-CONFIG_INCLUDE_SUSv2=y
-
-#
-# Installation Options
-#
-# CONFIG_INSTALL_NO_USR is not set
-CONFIG_INSTALL_APPLET_SYMLINKS=y
-# CONFIG_INSTALL_APPLET_HARDLINKS is not set
-# CONFIG_INSTALL_APPLET_DONT is not set
-CONFIG_PREFIX="@IDIR@"
-
-#
-# Busybox Library Tuning
-#
-CONFIG_PASSWORD_MINLEN=6
-CONFIG_MD5_SIZE_VS_SPEED=1
-
-#
-# Applets
-#
-
-#
-# Archival Utilities
-#
-# CONFIG_AR is not set
-# CONFIG_FEATURE_AR_LONG_FILENAMES is not set
-# CONFIG_BUNZIP2 is not set
-# CONFIG_CPIO is not set
-# CONFIG_DPKG is not set
-# CONFIG_DPKG_DEB is not set
-# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set
-CONFIG_GUNZIP=y
-CONFIG_FEATURE_GUNZIP_UNCOMPRESS=y
-CONFIG_GZIP=y
-CONFIG_IPKG=y
-# CONFIG_RPM2CPIO is not set
-# CONFIG_RPM is not set
-CONFIG_TAR=y
-CONFIG_FEATURE_TAR_CREATE=y
-# CONFIG_FEATURE_TAR_BZIP2 is not set
-# CONFIG_FEATURE_TAR_LZMA is not set
-CONFIG_FEATURE_TAR_FROM=y
-CONFIG_FEATURE_TAR_GZIP=y
-# CONFIG_FEATURE_TAR_COMPRESS is not set
-# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set
-CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y
-# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set
-# CONFIG_UNCOMPRESS is not set
-# CONFIG_UNLZMA is not set
-# CONFIG_FEATURE_LZMA_FAST is not set
-# CONFIG_UNZIP is not set
-
-#
-# Common options for cpio and tar
-#
-# CONFIG_FEATURE_UNARCHIVE_TAPE is not set
-# CONFIG_FEATURE_DEB_TAR_GZ is not set
-# CONFIG_FEATURE_DEB_TAR_BZ2 is not set
-# CONFIG_FEATURE_DEB_TAR_LZMA is not set
-
-#
-# Coreutils
-#
-CONFIG_BASENAME=y
-# CONFIG_CAL is not set
-CONFIG_CAT=y
-# CONFIG_CATV is not set
-CONFIG_CHGRP=y
-CONFIG_CHMOD=y
-CONFIG_CHOWN=y
-CONFIG_CHROOT=y
-CONFIG_CKSUM=y
-CONFIG_CMP=y
-CONFIG_COMM=y
-CONFIG_CP=y
-CONFIG_CUT=y
-CONFIG_DATE=y
-CONFIG_FEATURE_DATE_ISOFMT=y
-CONFIG_DD=y
-CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
-CONFIG_FEATURE_DD_IBS_OBS=y
-CONFIG_DF=y
-# CONFIG_DIFF is not set
-# CONFIG_FEATURE_DIFF_BINARY is not set
-# CONFIG_FEATURE_DIFF_DIR is not set
-# CONFIG_FEATURE_DIFF_MINIMAL is not set
-CONFIG_DIRNAME=y
-# CONFIG_DOS2UNIX is not set
-# CONFIG_UNIX2DOS is not set
-CONFIG_DU=y
-# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set
-CONFIG_ECHO=y
-CONFIG_FEATURE_FANCY_ECHO=y
-CONFIG_ENV=y
-# CONFIG_FEATURE_ENV_LONG_OPTIONS is not set
-CONFIG_EXPR=y
-# CONFIG_EXPR_MATH_SUPPORT_64 is not set
-CONFIG_FALSE=y
-# CONFIG_FOLD is not set
-CONFIG_HEAD=y
-CONFIG_FEATURE_FANCY_HEAD=y
-CONFIG_HOSTID=y
-CONFIG_ID=y
-CONFIG_INSTALL=y
-# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
-CONFIG_LENGTH=y
-CONFIG_LN=y
-# CONFIG_LOGNAME is not set
-CONFIG_LS=y
-CONFIG_FEATURE_LS_FILETYPES=y
-CONFIG_FEATURE_LS_FOLLOWLINKS=y
-CONFIG_FEATURE_LS_RECURSIVE=y
-CONFIG_FEATURE_LS_SORTFILES=y
-CONFIG_FEATURE_LS_TIMESTAMPS=y
-CONFIG_FEATURE_LS_USERNAME=y
-CONFIG_FEATURE_LS_COLOR=y
-# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
-CONFIG_MD5SUM=y
-CONFIG_MKDIR=y
-# CONFIG_FEATURE_MKDIR_LONG_OPTIONS is not set
-CONFIG_MKFIFO=y
-CONFIG_MKNOD=y
-CONFIG_MV=y
-# CONFIG_FEATURE_MV_LONG_OPTIONS is not set
-# CONFIG_NICE is not set
-CONFIG_NOHUP=y
-# CONFIG_OD is not set
-# CONFIG_PRINTENV is not set
-CONFIG_PRINTF=y
-CONFIG_PWD=y
-# CONFIG_REALPATH is not set
-CONFIG_RM=y
-CONFIG_RMDIR=y
-CONFIG_SEQ=y
-# CONFIG_SHA1SUM is not set
-CONFIG_SLEEP=y
-CONFIG_FEATURE_FANCY_SLEEP=y
-CONFIG_SORT=y
-CONFIG_FEATURE_SORT_BIG=y
-CONFIG_STAT=y
-CONFIG_FEATURE_STAT_FORMAT=y
-CONFIG_STTY=y
-# CONFIG_SUM is not set
-CONFIG_SYNC=y
-CONFIG_TAIL=y
-CONFIG_FEATURE_FANCY_TAIL=y
-CONFIG_TEE=y
-CONFIG_FEATURE_TEE_USE_BLOCK_IO=y
-CONFIG_TEST=y
-# CONFIG_FEATURE_TEST_64 is not set
-CONFIG_TOUCH=y
-CONFIG_TR=y
-CONFIG_FEATURE_TR_CLASSES=y
-# CONFIG_FEATURE_TR_EQUIV is not set
-CONFIG_TRUE=y
-# CONFIG_TTY is not set
-CONFIG_UNAME=y
-CONFIG_UNIQ=y
-# CONFIG_USLEEP is not set
-# CONFIG_UUDECODE is not set
-# CONFIG_UUENCODE is not set
-CONFIG_WATCH=y
-CONFIG_WC=y
-# CONFIG_FEATURE_WC_LARGE is not set
-CONFIG_WHO=y
-# CONFIG_WHOAMI is not set
-CONFIG_YES=y
-
-#
-# Common options for cp and mv
-#
-CONFIG_FEATURE_PRESERVE_HARDLINKS=y
-
-#
-# Common options for ls, more and telnet
-#
-CONFIG_FEATURE_AUTOWIDTH=y
-
-#
-# Common options for df, du, ls
-#
-CONFIG_FEATURE_HUMAN_READABLE=y
-
-#
-# Common options for md5sum, sha1sum
-#
-CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y
-
-#
-# Console Utilities
-#
-# CONFIG_CHVT is not set
-CONFIG_CLEAR=y
-# CONFIG_DEALLOCVT is not set
-# CONFIG_DUMPKMAP is not set
-# CONFIG_LOADFONT is not set
-# CONFIG_LOADKMAP is not set
-# CONFIG_OPENVT is not set
-CONFIG_RESET=y
-# CONFIG_RESIZE is not set
-# CONFIG_FEATURE_RESIZE_PRINT is not set
-# CONFIG_SETCONSOLE is not set
-# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
-# CONFIG_SETKEYCODES is not set
-# CONFIG_SETLOGCONS is not set
-
-#
-# Debian Utilities
-#
-CONFIG_MKTEMP=y
-# CONFIG_PIPE_PROGRESS is not set
-CONFIG_READLINK=y
-CONFIG_FEATURE_READLINK_FOLLOW=y
-CONFIG_RUN_PARTS=y
-# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
-# CONFIG_START_STOP_DAEMON is not set
-# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set
-# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set
-CONFIG_WHICH=y
-
-#
-# Editors
-#
-CONFIG_AWK=y
-CONFIG_FEATURE_AWK_MATH=y
-CONFIG_ED=y
-# CONFIG_PATCH is not set
-CONFIG_SED=y
-CONFIG_VI=y
-CONFIG_FEATURE_VI_COLON=y
-CONFIG_FEATURE_VI_YANKMARK=y
-CONFIG_FEATURE_VI_SEARCH=y
-CONFIG_FEATURE_VI_USE_SIGNALS=y
-CONFIG_FEATURE_VI_DOT_CMD=y
-CONFIG_FEATURE_VI_READONLY=y
-CONFIG_FEATURE_VI_SETOPTS=y
-CONFIG_FEATURE_VI_SET=y
-CONFIG_FEATURE_VI_WIN_RESIZE=y
-CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y
-CONFIG_FEATURE_ALLOW_EXEC=y
-
-#
-# Finding Utilities
-#
-CONFIG_FIND=y
-CONFIG_FEATURE_FIND_PRINT0=y
-CONFIG_FEATURE_FIND_MTIME=y
-CONFIG_FEATURE_FIND_MMIN=y
-CONFIG_FEATURE_FIND_PERM=y
-CONFIG_FEATURE_FIND_TYPE=y
-CONFIG_FEATURE_FIND_XDEV=y
-CONFIG_FEATURE_FIND_NEWER=y
-CONFIG_FEATURE_FIND_INUM=y
-CONFIG_FEATURE_FIND_EXEC=y
-CONFIG_GREP=y
-CONFIG_FEATURE_GREP_EGREP_ALIAS=y
-CONFIG_FEATURE_GREP_FGREP_ALIAS=y
-CONFIG_FEATURE_GREP_CONTEXT=y
-CONFIG_XARGS=y
-CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y
-CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y
-CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y
-CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
-
-#
-# Init Utilities
-#
-CONFIG_INIT=y
-# CONFIG_DEBUG_INIT is not set
-CONFIG_FEATURE_USE_INITTAB=y
-# CONFIG_FEATURE_INIT_SCTTY is not set
-# CONFIG_FEATURE_EXTRA_QUIET is not set
-# CONFIG_FEATURE_INIT_COREDUMPS is not set
-# CONFIG_FEATURE_INITRD is not set
-CONFIG_HALT=y
-CONFIG_MESG=y
-
-#
-# Login/Password Management Utilities
-#
-CONFIG_FEATURE_SHADOWPASSWDS=y
-CONFIG_USE_BB_SHADOW=y
-CONFIG_USE_BB_PWD_GRP=y
-# CONFIG_ADDGROUP is not set
-# CONFIG_DELGROUP is not set
-# CONFIG_ADDUSER is not set
-# CONFIG_DELUSER is not set
-# CONFIG_GETTY is not set
-CONFIG_FEATURE_UTMP=y
-# CONFIG_FEATURE_WTMP is not set
-# CONFIG_LOGIN is not set
-# CONFIG_LOGIN_SCRIPTS is not set
-# CONFIG_FEATURE_SECURETTY is not set
-CONFIG_PASSWD=y
-CONFIG_FEATURE_PASSWD_WEAK_CHECK=y
-CONFIG_SU=y
-CONFIG_FEATURE_SU_SYSLOG=y
-CONFIG_FEATURE_SU_CHECKS_SHELLS=y
-# CONFIG_SULOGIN is not set
-# CONFIG_VLOCK is not set
-
-#
-# Linux Ext2 FS Progs
-#
-# CONFIG_CHATTR is not set
-CONFIG_FSCK=y
-# CONFIG_LSATTR is not set
-
-#
-# Linux Module Utilities
-#
-CONFIG_INSMOD=y
-# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
-# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
-# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
-# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
-# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
-CONFIG_RMMOD=y
-CONFIG_LSMOD=y
-CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y
-CONFIG_MODPROBE=y
-# CONFIG_FEATURE_MODPROBE_MULTIPLE_OPTIONS is not set
-# CONFIG_FEATURE_MODPROBE_FANCY_ALIAS is not set
-
-#
-# Options common to multiple modutils
-#
-# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set
-# CONFIG_FEATURE_2_4_MODULES is not set
-CONFIG_FEATURE_2_6_MODULES=y
-# CONFIG_FEATURE_QUERY_MODULE_INTERFACE is not set
-
-#
-# Linux System Utilities
-#
-CONFIG_DMESG=y
-CONFIG_FEATURE_DMESG_PRETTY=y
-# CONFIG_FBSET is not set
-# CONFIG_FEATURE_FBSET_FANCY is not set
-# CONFIG_FEATURE_FBSET_READMODE is not set
-# CONFIG_FDFLUSH is not set
-# CONFIG_FDFORMAT is not set
-CONFIG_FDISK=y
-CONFIG_FDISK_SUPPORT_LARGE_DISKS=y
-CONFIG_FEATURE_FDISK_WRITABLE=y
-# CONFIG_FEATURE_AIX_LABEL is not set
-# CONFIG_FEATURE_SGI_LABEL is not set
-# CONFIG_FEATURE_SUN_LABEL is not set
-# CONFIG_FEATURE_OSF_LABEL is not set
-# CONFIG_FEATURE_FDISK_ADVANCED is not set
-# CONFIG_FREERAMDISK is not set
-# CONFIG_FSCK_MINIX is not set
-# CONFIG_MKFS_MINIX is not set
-# CONFIG_FEATURE_MINIX2 is not set
-# CONFIG_GETOPT is not set
-CONFIG_HEXDUMP=y
-CONFIG_HWCLOCK=y
-CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS=y
-# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set
-CONFIG_IPCRM=y 
-CONFIG_IPCS=y
-CONFIG_LOSETUP=y
-CONFIG_MDEV=y
-CONFIG_FEATURE_MDEV_CONF=y
-CONFIG_FEATURE_MDEV_EXEC=y
-CONFIG_MKSWAP=y
-# CONFIG_FEATURE_MKSWAP_V0 is not set
-CONFIG_MORE=y
-CONFIG_FEATURE_USE_TERMIOS=y
-CONFIG_MOUNT=y
-CONFIG_FEATURE_MOUNT_NFS=y
-CONFIG_FEATURE_MOUNT_CIFS=y
-CONFIG_FEATURE_MOUNT_FLAGS=y
-CONFIG_FEATURE_MOUNT_FSTAB=y
-CONFIG_PIVOT_ROOT=y
-# CONFIG_RDATE is not set
-# CONFIG_READPROFILE is not set
-# CONFIG_SETARCH is not set
-CONFIG_SWAPONOFF=y
-CONFIG_SWITCH_ROOT=y
-CONFIG_UMOUNT=y
-CONFIG_FEATURE_UMOUNT_ALL=y
-
-#
-# Common options for mount/umount
-#
-CONFIG_FEATURE_MOUNT_LOOP=y
-# CONFIG_FEATURE_MTAB_SUPPORT is not set
-
-#
-# Miscellaneous Utilities
-#
-# CONFIG_ADJTIMEX is not set
-# CONFIG_BBCONFIG is not set
-CONFIG_CROND=y
-# CONFIG_DEBUG_CROND_OPTION is not set
-# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
-CONFIG_CRONTAB=y
-# CONFIG_DC is not set
-# CONFIG_DEVFSD is not set
-# CONFIG_DEVFSD_MODLOAD is not set
-# CONFIG_DEVFSD_FG_NP is not set
-# CONFIG_DEVFSD_VERBOSE is not set
-# CONFIG_FEATURE_DEVFS is not set
-# CONFIG_EJECT is not set
-# CONFIG_LAST is not set
-# CONFIG_LESS is not set
-# CONFIG_FEATURE_LESS_MAXLINES is not set
-# CONFIG_FEATURE_LESS_BRACKETS is not set
-# CONFIG_FEATURE_LESS_FLAGS is not set
-# CONFIG_FEATURE_LESS_FLAGCS is not set
-# CONFIG_FEATURE_LESS_MARKS is not set
-# CONFIG_FEATURE_LESS_REGEXP is not set
-# CONFIG_HDPARM is not set
-# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set
-# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set
-# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set
-# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
-# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
-# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
-# CONFIG_MAKEDEVS is not set
-# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
-# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
-# CONFIG_MOUNTPOINT is not set
-# CONFIG_MT is not set
-# CONFIG_NMETER is not set
-# CONFIG_RAIDAUTORUN is not set
-# CONFIG_READAHEAD is not set
-# CONFIG_RUNLEVEL is not set
-CONFIG_RX=y
-CONFIG_STRINGS=y
-# CONFIG_SETSID is not set
-# CONFIG_TASKSET is not set
-# CONFIG_FEATURE_TASKSET_FANCY is not set
-# CONFIG_TIME is not set
-CONFIG_WATCHDOG=y
-
-#
-# Networking Utilities
-#
-CONFIG_FEATURE_IPV6=y
-CONFIG_ARP=y
-CONFIG_ARPING=y
-# CONFIG_DNSD is not set
-CONFIG_ETHER_WAKE=y
-# CONFIG_FAKEIDENTD is not set
-# CONFIG_FTPGET is not set
-# CONFIG_FTPPUT is not set
-# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
-CONFIG_HOSTNAME=y
-# CONFIG_HTTPD is not set
-# CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP is not set
-# CONFIG_FEATURE_HTTPD_SETUID is not set
-# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set
-# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set
-# CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES is not set
-# CONFIG_FEATURE_HTTPD_CGI is not set
-# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set
-# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set
-# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set
-CONFIG_IFCONFIG=y
-CONFIG_FEATURE_IFCONFIG_STATUS=y
-# CONFIG_FEATURE_IFCONFIG_SLIP is not set
-# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
-CONFIG_FEATURE_IFCONFIG_HW=y
-CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y
-CONFIG_IFUPDOWN=y
-CONFIG_FEATURE_IFUPDOWN_IP=y
-CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y
-# CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set
-CONFIG_FEATURE_IFUPDOWN_IPV4=y
-CONFIG_FEATURE_IFUPDOWN_IPV6=y
-# CONFIG_FEATURE_IFUPDOWN_IPX is not set
-# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set
-CONFIG_INETD=y
-CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO=y
-CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD=y
-CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME=y
-CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME=y
-CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN=y
-CONFIG_FEATURE_INETD_RPC=y
-CONFIG_IP=y
-CONFIG_FEATURE_IP_ADDRESS=y
-CONFIG_FEATURE_IP_LINK=y
-CONFIG_FEATURE_IP_ROUTE=y
-CONFIG_FEATURE_IP_TUNNEL=y
-CONFIG_FEATURE_IP_RULE=y
-# CONFIG_FEATURE_IP_SHORT_FORMS is not set
-# CONFIG_IPADDR is not set
-# CONFIG_IPLINK is not set
-# CONFIG_IPROUTE is not set
-# CONFIG_IPTUNNEL is not set
-# CONFIG_IPRULE is not set
-# CONFIG_IPCALC is not set
-# CONFIG_FEATURE_IPCALC_FANCY is not set
-# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
-# CONFIG_NAMEIF is not set
-CONFIG_NC=y
-CONFIG_NC_SERVER=y
-CONFIG_NC_EXTRA=y
-CONFIG_NETSTAT=y
-CONFIG_NSLOOKUP=y
-CONFIG_PING=y
-CONFIG_FEATURE_FANCY_PING=y
-CONFIG_PING6=y
-CONFIG_FEATURE_FANCY_PING6=y
-CONFIG_ROUTE=y
-CONFIG_TELNET=y
-CONFIG_FEATURE_TELNET_TTYPE=y
-# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set
-CONFIG_TELNETD=y
-CONFIG_FEATURE_TELNETD_STANDALONE=y
-CONFIG_TFTP=y
-CONFIG_FEATURE_TFTP_GET=y
-CONFIG_FEATURE_TFTP_PUT=y
-CONFIG_FEATURE_TFTP_BLOCKSIZE=y
-CONFIG_DEBUG_TFTP=y
-CONFIG_TRACEROUTE=y
-CONFIG_FEATURE_TRACEROUTE_VERBOSE=y
-CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y
-CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y
-# CONFIG_APP_UDHCPD is not set
-# CONFIG_APP_DHCPRELAY is not set
-# CONFIG_APP_DUMPLEASES is not set
-CONFIG_APP_UDHCPC=y
-# CONFIG_FEATURE_UDHCP_SYSLOG is not set
-# CONFIG_FEATURE_UDHCP_DEBUG is not set
-# CONFIG_VCONFIG is not set
-CONFIG_WGET=y
-CONFIG_FEATURE_WGET_STATUSBAR=y
-CONFIG_FEATURE_WGET_AUTHENTICATION=y
-CONFIG_FEATURE_WGET_IP6_LITERAL=y
-CONFIG_FEATURE_WGET_LONG_OPTIONS=y
-# CONFIG_ZCIP is not set
-
-#
-# Process Utilities
-#
-CONFIG_FREE=y
-CONFIG_FUSER=y
-CONFIG_KILL=y
-CONFIG_KILLALL=y
-CONFIG_KILLALL5=y
-CONFIG_PIDOF=y
-CONFIG_FEATURE_PIDOF_SINGLE=y
-CONFIG_FEATURE_PIDOF_OMIT=y
-CONFIG_PS=y
-CONFIG_FEATURE_PS_WIDE=y
-CONFIG_RENICE=y
-CONFIG_BB_SYSCTL=y
-CONFIG_TOP=y
-CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y
-CONFIG_UPTIME=y
-
-#
-# Shells
-#
-# CONFIG_FEATURE_SH_IS_ASH is not set
-# CONFIG_FEATURE_SH_IS_HUSH is not set
-# CONFIG_FEATURE_SH_IS_LASH is not set
-# CONFIG_FEATURE_SH_IS_MSH is not set
-CONFIG_FEATURE_SH_IS_NONE=y
-# CONFIG_ASH is not set
-# CONFIG_ASH_JOB_CONTROL is not set
-# CONFIG_ASH_READ_NCHARS is not set
-# CONFIG_ASH_READ_TIMEOUT is not set
-# CONFIG_ASH_ALIAS is not set
-# CONFIG_ASH_MATH_SUPPORT is not set
-# CONFIG_ASH_MATH_SUPPORT_64 is not set
-# CONFIG_ASH_GETOPTS is not set
-# CONFIG_ASH_BUILTIN_ECHO is not set
-# CONFIG_ASH_BUILTIN_TEST is not set
-# CONFIG_ASH_CMDCMD is not set
-# CONFIG_ASH_MAIL is not set
-# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_ASH_RANDOM_SUPPORT is not set
-# CONFIG_ASH_EXPAND_PRMT is not set
-# CONFIG_HUSH is not set
-# CONFIG_LASH is not set
-# CONFIG_MSH is not set
-# CONFIG_FEATURE_SH_EXTRA_QUIET is not set
-# CONFIG_FEATURE_SH_STANDALONE_SHELL is not set
-# CONFIG_FEATURE_COMMAND_EDITING is not set
-# CONFIG_FEATURE_COMMAND_EDITING_VI is not set
-# CONFIG_FEATURE_COMMAND_HISTORY is not set
-# CONFIG_FEATURE_COMMAND_SAVEHISTORY is not set
-# CONFIG_FEATURE_COMMAND_TAB_COMPLETION is not set
-# CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION is not set
-# CONFIG_FEATURE_SH_FANCY_PROMPT is not set
-
-#
-# System Logging Utilities
-#
-CONFIG_SYSLOGD=y
-CONFIG_FEATURE_ROTATE_LOGFILE=y
-CONFIG_FEATURE_REMOTE_LOG=y
-CONFIG_FEATURE_IPC_SYSLOG=y
-CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16
-CONFIG_LOGREAD=y
-CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y
-CONFIG_KLOGD=y
-CONFIG_LOGGER=y
-
-#
-# Runit Utilities
-#
-# CONFIG_RUNSV is not set
-# CONFIG_RUNSVDIR is not set
-# CONFIG_SV is not set
-# CONFIG_SVLOGD is not set
-# CONFIG_CHPST is not set
-# CONFIG_SETUIDGID is not set
-# CONFIG_ENVUIDGID is not set
-# CONFIG_ENVDIR is not set
-# CONFIG_SOFTLIMIT is not set

+ 1 - 1
package/busybox/files/crond.init

@@ -14,7 +14,7 @@ start)
 	crond -c /etc/crontabs
 	;;
 stop)
-	kill $(pidof crond|cut -d ' ' -f 3)
+	pkill crond
 	;;
 restart)
 	sh $0 stop

+ 119 - 103
package/busybox/patches/001-ipkg.patch

@@ -1,6 +1,6 @@
 diff -Nur busybox-1.16.1.orig/archival/Config.in busybox-1.16.1/archival/Config.in
 --- busybox-1.16.1.orig/archival/Config.in	2010-03-28 19:43:35.000000000 +0200
-+++ busybox-1.16.1/archival/Config.in	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/Config.in	2010-06-29 17:31:21.805863709 +0200
 @@ -187,6 +187,14 @@
  	  are actually slower than gzip at equivalent compression ratios
  	  and take up 3.2K of code.
@@ -18,7 +18,7 @@ diff -Nur busybox-1.16.1.orig/archival/Config.in busybox-1.16.1/archival/Config.
  	default n
 diff -Nur busybox-1.16.1.orig/archival/ipkg.c busybox-1.16.1/archival/ipkg.c
 --- busybox-1.16.1.orig/archival/ipkg.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/ipkg.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/ipkg.c	2010-06-29 17:31:21.827118101 +0200
 @@ -0,0 +1,28 @@
 +/* ipkg.c - the itsy package management system
 +
@@ -50,7 +50,7 @@ diff -Nur busybox-1.16.1.orig/archival/ipkg.c busybox-1.16.1/archival/ipkg.c
 +}
 diff -Nur busybox-1.16.1.orig/archival/Kbuild busybox-1.16.1/archival/Kbuild
 --- busybox-1.16.1.orig/archival/Kbuild	2010-03-20 03:58:07.000000000 +0100
-+++ busybox-1.16.1/archival/Kbuild	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/Kbuild	2010-06-29 17:31:21.865866986 +0200
 @@ -16,6 +16,7 @@
  lib-$(CONFIG_DPKG_DEB)		+= dpkg_deb.o
  lib-$(CONFIG_GUNZIP)		+= bbunzip.o
@@ -61,7 +61,7 @@ diff -Nur busybox-1.16.1.orig/archival/Kbuild busybox-1.16.1/archival/Kbuild
  lib-$(CONFIG_RPM2CPIO)		+= rpm2cpio.o
 diff -Nur busybox-1.16.1.orig/archival/libipkg/args.c busybox-1.16.1/archival/libipkg/args.c
 --- busybox-1.16.1.orig/archival/libipkg/args.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/args.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/args.c	2010-06-29 17:31:21.905863813 +0200
 @@ -0,0 +1,242 @@
 +/* args.c - parse command-line args
 + 
@@ -307,7 +307,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/args.c busybox-1.16.1/archival/li
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/args.h busybox-1.16.1/archival/libipkg/args.h
 --- busybox-1.16.1.orig/archival/libipkg/args.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/args.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/args.h	2010-06-29 17:31:21.945866019 +0200
 @@ -0,0 +1,72 @@
 +/* args.h - parse command-line args
 +
@@ -383,7 +383,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/args.h busybox-1.16.1/archival/li
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/conffile.c busybox-1.16.1/archival/libipkg/conffile.c
 --- busybox-1.16.1.orig/archival/libipkg/conffile.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/conffile.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/conffile.c	2010-06-29 17:31:21.987118040 +0200
 @@ -0,0 +1,65 @@
 +/* conffile.c - the itsy package management system
 +
@@ -452,7 +452,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/conffile.c busybox-1.16.1/archiva
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/conffile.h busybox-1.16.1/archival/libipkg/conffile.h
 --- busybox-1.16.1.orig/archival/libipkg/conffile.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/conffile.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/conffile.h	2010-06-29 17:31:22.018368070 +0200
 @@ -0,0 +1,30 @@
 +/* conffile.h - the itsy package management system
 +
@@ -486,7 +486,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/conffile.h busybox-1.16.1/archiva
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/conffile_list.c busybox-1.16.1/archival/libipkg/conffile_list.c
 --- busybox-1.16.1.orig/archival/libipkg/conffile_list.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/conffile_list.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/conffile_list.c	2010-06-29 17:31:22.055873481 +0200
 @@ -0,0 +1,47 @@
 +/* conffile_list.c - the itsy package management system
 +
@@ -537,7 +537,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/conffile_list.c busybox-1.16.1/ar
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/conffile_list.h busybox-1.16.1/archival/libipkg/conffile_list.h
 --- busybox-1.16.1.orig/archival/libipkg/conffile_list.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/conffile_list.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/conffile_list.h	2010-06-29 17:31:22.089612450 +0200
 @@ -0,0 +1,36 @@
 +/* conffile_list.h - the itsy package management system
 +
@@ -577,7 +577,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/conffile_list.h busybox-1.16.1/ar
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/file_util.c busybox-1.16.1/archival/libipkg/file_util.c
 --- busybox-1.16.1.orig/archival/libipkg/file_util.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/file_util.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/file_util.c	2010-06-29 17:31:22.137606321 +0200
 @@ -0,0 +1,186 @@
 +/* file_util.c - convenience routines for common stat operations
 +
@@ -767,7 +767,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/file_util.c busybox-1.16.1/archiv
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/file_util.h busybox-1.16.1/archival/libipkg/file_util.h
 --- busybox-1.16.1.orig/archival/libipkg/file_util.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/file_util.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/file_util.h	2010-06-29 17:31:22.220596553 +0200
 @@ -0,0 +1,29 @@
 +/* file_util.h - convenience routines for common file operations
 +
@@ -800,7 +800,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/file_util.h busybox-1.16.1/archiv
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/hash_table.c busybox-1.16.1/archival/libipkg/hash_table.c
 --- busybox-1.16.1.orig/archival/libipkg/hash_table.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/hash_table.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/hash_table.c	2010-06-29 17:31:22.257056261 +0200
 @@ -0,0 +1,155 @@
 +/* hash.c - hash tables for ipkg
 +
@@ -959,7 +959,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/hash_table.c busybox-1.16.1/archi
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/hash_table.h busybox-1.16.1/archival/libipkg/hash_table.h
 --- busybox-1.16.1.orig/archival/libipkg/hash_table.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/hash_table.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/hash_table.h	2010-06-29 17:31:22.305858166 +0200
 @@ -0,0 +1,44 @@
 +/* hash.h - hash tables for ipkg
 +
@@ -1007,8 +1007,8 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/hash_table.h busybox-1.16.1/archi
 +#endif /* _HASH_TABLE_H_ */
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_cmd.c busybox-1.16.1/archival/libipkg/ipkg_cmd.c
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_cmd.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_cmd.c	2010-04-22 19:18:12.000000000 +0200
-@@ -0,0 +1,1386 @@
++++ busybox-1.16.1/archival/libipkg/ipkg_cmd.c	2010-06-29 19:19:50.699618181 +0200
+@@ -0,0 +1,1366 @@
 +/* ipkg_cmd.c - the itsy package management system
 +
 +   Carl D. Worth
@@ -2023,30 +2023,10 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_cmd.c busybox-1.16.1/archiva
 +     installed_files = pkg_get_installed_files(pkg);
 +     pkg_version = pkg_version_str_alloc(pkg);
 +
-+     if (buff) {
-+     try_again:
-+	  used_len = snprintf(buff, buff_len, "Package %s (%s) is installed on %s and has the following files:\n",
-+			      pkg->name, pkg_version, pkg->dest->name) + 1;
-+	  if (used_len > buff_len) {
-+	       buff_len *= 2;
-+	       buff = realloc (buff, buff_len);
-+	       goto try_again;
-+	  }
-+	  for (iter = installed_files->head; iter; iter = iter->next) {
-+	       used_len += strlen (iter->data) + 1;
-+	       while (buff_len <= used_len) {
-+		    buff_len *= 2;
-+		    buff = realloc (buff, buff_len);
-+	       }
-+	       strncat(buff, iter->data, buff_len);
-+	       strncat(buff, "\n", buff_len);
-+	  } 
-+	  if (ipkg_cb_list) ipkg_cb_list(pkg->name,
-+					 buff,
-+					 pkg_version_str_alloc(pkg),
-+					 pkg->state_status,
-+					 p_userdata);
-+	  free(buff);
++     printf("Package %s (%s) is installed on %s and has the following files:\n",
++            pkg->name, pkg_version, pkg->dest->name);
++     for (iter = installed_files->head; iter; iter = iter->next) {
++          puts(iter->data);
 +     }
 +
 +     free(pkg_version);
@@ -2397,7 +2377,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_cmd.c busybox-1.16.1/archiva
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_cmd.h busybox-1.16.1/archival/libipkg/ipkg_cmd.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_cmd.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_cmd.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_cmd.h	2010-06-29 17:31:22.398358961 +0200
 @@ -0,0 +1,41 @@
 +/* ipkg_cmd.h - the itsy package management system
 +
@@ -2442,7 +2422,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_cmd.h busybox-1.16.1/archiva
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_conf.c busybox-1.16.1/archival/libipkg/ipkg_conf.c
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_conf.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_conf.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_conf.c	2010-06-29 17:31:22.425857952 +0200
 @@ -0,0 +1,711 @@
 +/* ipkg_conf.c - the itsy package management system
 +
@@ -3157,7 +3137,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_conf.c busybox-1.16.1/archiv
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_conf.h busybox-1.16.1/archival/libipkg/ipkg_conf.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_conf.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_conf.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_conf.h	2010-06-29 17:31:22.458368131 +0200
 @@ -0,0 +1,107 @@
 +/* ipkg_conf.h - the itsy package management system
 +
@@ -3268,7 +3248,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_conf.h busybox-1.16.1/archiv
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_configure.c busybox-1.16.1/archival/libipkg/ipkg_configure.c
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_configure.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_configure.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_configure.c	2010-06-29 17:31:22.488368061 +0200
 @@ -0,0 +1,40 @@
 +/* ipkg_configure.c - the itsy package management system
 +
@@ -3312,7 +3292,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_configure.c busybox-1.16.1/a
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_configure.h busybox-1.16.1/archival/libipkg/ipkg_configure.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_configure.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_configure.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_configure.h	2010-06-29 17:31:22.527882534 +0200
 @@ -0,0 +1,25 @@
 +/* ipkg_configure.h - the itsy package management system
 +
@@ -3341,7 +3321,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_configure.h busybox-1.16.1/a
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_download.c busybox-1.16.1/archival/libipkg/ipkg_download.c
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_download.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_download.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_download.c	2010-06-29 17:31:22.569385415 +0200
 @@ -0,0 +1,195 @@
 +/* ipkg_download.c - the itsy package management system
 +
@@ -3540,7 +3520,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_download.c busybox-1.16.1/ar
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_download.h busybox-1.16.1/archival/libipkg/ipkg_download.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_download.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_download.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_download.h	2010-06-29 17:31:22.608368046 +0200
 @@ -0,0 +1,30 @@
 +/* ipkg_download.h - the itsy package management system
 +
@@ -3574,7 +3554,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_download.h busybox-1.16.1/ar
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg.h busybox-1.16.1/archival/libipkg/ipkg.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg.h	2010-06-29 17:31:22.647281522 +0200
 @@ -0,0 +1,68 @@
 +/* ipkg.h - the itsy package management system
 +
@@ -3646,8 +3626,8 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg.h busybox-1.16.1/archival/li
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_includes.h busybox-1.16.1/archival/libipkg/ipkg_includes.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_includes.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_includes.h	2010-04-22 19:18:12.000000000 +0200
-@@ -0,0 +1,79 @@
++++ busybox-1.16.1/archival/libipkg/ipkg_includes.h	2010-06-29 17:32:10.339618090 +0200
+@@ -0,0 +1,81 @@
 +#ifndef IPKG_INCLUDES_H
 +#define IPKG_INCLUDES_H
 +
@@ -3726,10 +3706,12 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_includes.h busybox-1.16.1/ar
 +# include <unistd.h>
 +#endif
 +
++#include <sys/mount.h> 
++
 +#endif /* IPKG_INCLUDES_H */
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_install.c busybox-1.16.1/archival/libipkg/ipkg_install.c
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_install.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_install.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_install.c	2010-06-29 17:31:22.727172508 +0200
 @@ -0,0 +1,1982 @@
 +/* ipkg_install.c - the itsy package management system
 +
@@ -5715,7 +5697,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_install.c busybox-1.16.1/arc
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_install.h busybox-1.16.1/archival/libipkg/ipkg_install.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_install.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_install.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_install.h	2010-06-29 17:31:22.768368136 +0200
 @@ -0,0 +1,35 @@
 +/* ipkg_install.h - the itsy package management system
 +
@@ -5754,7 +5736,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_install.h busybox-1.16.1/arc
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_message.c busybox-1.16.1/archival/libipkg/ipkg_message.c
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_message.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_message.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_message.c	2010-06-29 17:31:22.798368009 +0200
 @@ -0,0 +1,35 @@
 +/* ipkg_message.c - the itsy package management system
 +
@@ -5793,7 +5775,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_message.c busybox-1.16.1/arc
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_message.h busybox-1.16.1/archival/libipkg/ipkg_message.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_message.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_message.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_message.h	2010-06-29 17:31:22.839937503 +0200
 @@ -0,0 +1,32 @@
 +/* ipkg_message.h - the itsy package management system
 +
@@ -5829,7 +5811,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_message.h busybox-1.16.1/arc
 +#endif /* _IPKG_MESSAGE_H_ */
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_remove.c busybox-1.16.1/archival/libipkg/ipkg_remove.c
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_remove.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_remove.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_remove.c	2010-06-29 17:31:22.876628032 +0200
 @@ -0,0 +1,385 @@
 +/* ipkg_remove.c - the itsy package management system
 +
@@ -6218,7 +6200,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_remove.c busybox-1.16.1/arch
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_remove.h busybox-1.16.1/archival/libipkg/ipkg_remove.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_remove.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_remove.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_remove.h	2010-06-29 17:31:22.918368225 +0200
 @@ -0,0 +1,33 @@
 +/* ipkg_remove.h - the itsy package management system
 +
@@ -6255,7 +6237,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_remove.h busybox-1.16.1/arch
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_upgrade.c busybox-1.16.1/archival/libipkg/ipkg_upgrade.c
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_upgrade.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_upgrade.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_upgrade.c	2010-06-29 17:31:22.976264794 +0200
 @@ -0,0 +1,79 @@
 +/* ipkg_upgrade.c - the itsy package management system
 +
@@ -6338,7 +6320,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_upgrade.c busybox-1.16.1/arc
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_upgrade.h busybox-1.16.1/archival/libipkg/ipkg_upgrade.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_upgrade.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_upgrade.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_upgrade.h	2010-06-29 17:31:23.015873328 +0200
 @@ -0,0 +1,18 @@
 +/* ipkg_upgrade.c - the itsy package management system
 +
@@ -6360,7 +6342,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_upgrade.h busybox-1.16.1/arc
 +int ipkg_upgrade_pkg(ipkg_conf_t *conf, pkg_t *old);
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_utils.c busybox-1.16.1/archival/libipkg/ipkg_utils.c
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_utils.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_utils.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_utils.c	2010-06-29 17:31:23.067592883 +0200
 @@ -0,0 +1,185 @@
 +/* ipkg_utils.c - the itsy package management system
 +
@@ -6549,7 +6531,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_utils.c busybox-1.16.1/archi
 +       
 diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_utils.h busybox-1.16.1/archival/libipkg/ipkg_utils.h
 --- busybox-1.16.1.orig/archival/libipkg/ipkg_utils.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/ipkg_utils.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/ipkg_utils.h	2010-06-29 17:31:23.105873432 +0200
 @@ -0,0 +1,29 @@
 +/* ipkg_utils.h - the itsy package management system
 +
@@ -6582,7 +6564,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/ipkg_utils.h busybox-1.16.1/archi
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/Kbuild busybox-1.16.1/archival/libipkg/Kbuild
 --- busybox-1.16.1.orig/archival/libipkg/Kbuild	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/Kbuild	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/Kbuild	2010-06-29 17:31:23.145868229 +0200
 @@ -0,0 +1,60 @@
 +# Makefile for busybox
 +#
@@ -6646,8 +6628,8 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/Kbuild busybox-1.16.1/archival/li
 +CFLAGS += -DIPKGLIBDIR="\"/usr/lib\"" -DHOST_CPU_STR="\"$(IPKG_ARCH)\""
 diff -Nur busybox-1.16.1.orig/archival/libipkg/libipkg.c busybox-1.16.1/archival/libipkg/libipkg.c
 --- busybox-1.16.1.orig/archival/libipkg/libipkg.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/libipkg.c	2010-04-22 19:18:12.000000000 +0200
-@@ -0,0 +1,525 @@
++++ busybox-1.16.1/archival/libipkg/libipkg.c	2010-06-29 19:58:50.069617923 +0200
+@@ -0,0 +1,550 @@
 +/* ipkglib.c - the itsy package management system
 +
 +   Florina Boor
@@ -7101,6 +7083,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/libipkg.c busybox-1.16.1/archival
 +	ipkg_conf_t ipkg_conf;
 +	const char *message = "ipkg must have one sub-command argument";
 +
++
 +	args_init (&args);
 +
 +	optind_ = args_parse (&args, argc, argv);
@@ -7135,6 +7118,18 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/libipkg.c busybox-1.16.1/archival
 +           args.noreadfeedsfile = 1;
 +
 +
++        if ( !strcmp(cmd_name,"install") ||
++             !strcmp(cmd_name,"update") ||
++             !strcmp(cmd_name,"upgrade") ||
++             !strcmp(cmd_name,"flag") ||
++             !strcmp(cmd_name,"configure") ||
++             !strcmp(cmd_name,"remove") ) {
++		/* mount rootfs read-write */
++		if (mount("","/",0,MS_REMOUNT,0)<0)
++			fprintf (stderr, "Mounting rootfs read-write failed\n");
++	}
++	
++
 +	err = ipkg_conf_init (&ipkg_conf, &args);
 +	if (err)
 +	{
@@ -7171,11 +7166,23 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/libipkg.c busybox-1.16.1/archival
 +
 +	ipkg_conf_deinit (&ipkg_conf);
 +
++        if ( !strcmp(cmd_name,"install") ||
++             !strcmp(cmd_name,"update") ||
++             !strcmp(cmd_name,"upgrade") ||
++             !strcmp(cmd_name,"flag") ||
++             !strcmp(cmd_name,"configure") ||
++             !strcmp(cmd_name,"remove") ) {
++		sync();
++		/* mount rootfs read-only */
++		if (mount("","/",0,MS_REMOUNT|MS_RDONLY,0)<0)
++			fprintf (stderr, "Mounting rootfs read-only failed\n");
++	}
++
 +	return err;
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/libipkg.h busybox-1.16.1/archival/libipkg/libipkg.h
 --- busybox-1.16.1.orig/archival/libipkg/libipkg.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/libipkg.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/libipkg.h	2010-06-29 17:31:24.283460019 +0200
 @@ -0,0 +1,78 @@
 +/* ipkglib.h - the itsy package management system
 +
@@ -7257,7 +7264,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/libipkg.h busybox-1.16.1/archival
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/nv_pair.c busybox-1.16.1/archival/libipkg/nv_pair.c
 --- busybox-1.16.1.orig/archival/libipkg/nv_pair.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/nv_pair.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/nv_pair.c	2010-06-29 17:31:24.316180264 +0200
 @@ -0,0 +1,40 @@
 +/* nv_pair.c - the itsy package management system
 +
@@ -7301,7 +7308,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/nv_pair.c busybox-1.16.1/archival
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/nv_pair.h busybox-1.16.1/archival/libipkg/nv_pair.h
 --- busybox-1.16.1.orig/archival/libipkg/nv_pair.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/nv_pair.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/nv_pair.h	2010-06-29 17:31:24.358376170 +0200
 @@ -0,0 +1,32 @@
 +/* nv_pair.h - the itsy package management system
 +
@@ -7337,7 +7344,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/nv_pair.h busybox-1.16.1/archival
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/nv_pair_list.c busybox-1.16.1/archival/libipkg/nv_pair_list.c
 --- busybox-1.16.1.orig/archival/libipkg/nv_pair_list.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/nv_pair_list.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/nv_pair_list.c	2010-06-29 17:31:24.395873641 +0200
 @@ -0,0 +1,98 @@
 +/* nv_pair_list.c - the itsy package management system
 +
@@ -7439,7 +7446,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/nv_pair_list.c busybox-1.16.1/arc
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/nv_pair_list.h busybox-1.16.1/archival/libipkg/nv_pair_list.h
 --- busybox-1.16.1.orig/archival/libipkg/nv_pair_list.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/nv_pair_list.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/nv_pair_list.h	2010-06-29 17:31:24.439618049 +0200
 @@ -0,0 +1,60 @@
 +/* nv_pair_list.h - the itsy package management system
 +
@@ -7503,7 +7510,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/nv_pair_list.h busybox-1.16.1/arc
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg.c busybox-1.16.1/archival/libipkg/pkg.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg.c	2010-06-29 17:31:24.502860549 +0200
 @@ -0,0 +1,1757 @@
 +/* pkg.c - the itsy package management system
 +
@@ -9264,7 +9271,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg.c busybox-1.16.1/archival/lib
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_depends.c busybox-1.16.1/archival/libipkg/pkg_depends.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg_depends.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_depends.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_depends.c	2010-06-29 17:31:24.548368104 +0200
 @@ -0,0 +1,1032 @@
 +/* pkg_depends.c - the itsy package management system
 +
@@ -10300,7 +10307,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_depends.c busybox-1.16.1/arch
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_depends.h busybox-1.16.1/archival/libipkg/pkg_depends.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg_depends.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_depends.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_depends.h	2010-06-29 17:31:24.588368223 +0200
 @@ -0,0 +1,105 @@
 +/* pkg_depends.h - the itsy package management system
 +
@@ -10409,7 +10416,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_depends.h busybox-1.16.1/arch
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_dest.c busybox-1.16.1/archival/libipkg/pkg_dest.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg_dest.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_dest.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_dest.c	2010-06-29 17:31:24.625873289 +0200
 @@ -0,0 +1,92 @@
 +/* pkg_dest.c - the itsy package management system
 +
@@ -10505,7 +10512,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_dest.c busybox-1.16.1/archiva
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_dest.h busybox-1.16.1/archival/libipkg/pkg_dest.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg_dest.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_dest.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_dest.h	2010-06-29 17:31:24.669618111 +0200
 @@ -0,0 +1,38 @@
 +/* pkg_dest.h - the itsy package management system
 +
@@ -10547,7 +10554,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_dest.h busybox-1.16.1/archiva
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_dest_list.c busybox-1.16.1/archival/libipkg/pkg_dest_list.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg_dest_list.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_dest_list.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_dest_list.c	2010-06-29 17:31:24.715868178 +0200
 @@ -0,0 +1,85 @@
 +/* pkg_dest_list.c - the itsy package management system
 +
@@ -10636,7 +10643,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_dest_list.c busybox-1.16.1/ar
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_dest_list.h busybox-1.16.1/archival/libipkg/pkg_dest_list.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg_dest_list.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_dest_list.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_dest_list.h	2010-06-29 17:31:24.760275316 +0200
 @@ -0,0 +1,50 @@
 +/* pkg_dest_list.h - the itsy package management system
 +
@@ -10690,7 +10697,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_dest_list.h busybox-1.16.1/ar
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_extract.c busybox-1.16.1/archival/libipkg/pkg_extract.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg_extract.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_extract.c	2010-04-22 19:33:49.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_extract.c	2010-06-29 17:31:24.818364193 +0200
 @@ -0,0 +1,255 @@
 +/* pkg_extract.c - the itsy package management system
 +
@@ -10949,7 +10956,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_extract.c busybox-1.16.1/arch
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_extract.h busybox-1.16.1/archival/libipkg/pkg_extract.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg_extract.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_extract.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_extract.h	2010-06-29 17:31:24.858368110 +0200
 @@ -0,0 +1,32 @@
 +/* pkg_extract.c - the itsy package management system
 +
@@ -10985,7 +10992,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_extract.h busybox-1.16.1/arch
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg.h busybox-1.16.1/archival/libipkg/pkg.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg.h	2010-06-29 17:31:24.897965989 +0200
 @@ -0,0 +1,229 @@
 +/* pkg.h - the itsy package management system
 +
@@ -11218,7 +11225,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg.h busybox-1.16.1/archival/lib
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_hash.c busybox-1.16.1/archival/libipkg/pkg_hash.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg_hash.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_hash.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_hash.c	2010-06-29 17:31:24.956062867 +0200
 @@ -0,0 +1,623 @@
 +/* ipkg_hash.c - the itsy package management system
 +
@@ -11845,7 +11852,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_hash.c busybox-1.16.1/archiva
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_hash.h busybox-1.16.1/archival/libipkg/pkg_hash.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg_hash.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_hash.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_hash.h	2010-06-29 17:31:25.005861391 +0200
 @@ -0,0 +1,61 @@
 +/* pkg_hash.h - the itsy package management system
 +
@@ -11910,7 +11917,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_hash.h busybox-1.16.1/archiva
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_parse.c busybox-1.16.1/archival/libipkg/pkg_parse.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg_parse.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_parse.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_parse.c	2010-06-29 17:31:25.059133294 +0200
 @@ -0,0 +1,368 @@
 +/* pkg_parse.c - the itsy package management system
 +
@@ -12282,7 +12289,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_parse.c busybox-1.16.1/archiv
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_parse.h busybox-1.16.1/archival/libipkg/pkg_parse.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg_parse.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_parse.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_parse.h	2010-06-29 17:31:25.098367969 +0200
 @@ -0,0 +1,31 @@
 +/* pkg_parse.h - the itsy package management system
 +
@@ -12317,7 +12324,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_parse.h busybox-1.16.1/archiv
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_src.c busybox-1.16.1/archival/libipkg/pkg_src.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg_src.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_src.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_src.c	2010-06-29 17:31:25.135873346 +0200
 @@ -0,0 +1,43 @@
 +/* pkg_src.c - the itsy package management system
 +
@@ -12364,7 +12371,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_src.c busybox-1.16.1/archival
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_src.h busybox-1.16.1/archival/libipkg/pkg_src.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg_src.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_src.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_src.h	2010-06-29 17:31:25.195873136 +0200
 @@ -0,0 +1,34 @@
 +/* pkg_src.h - the itsy package management system
 +
@@ -12402,7 +12409,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_src.h busybox-1.16.1/archival
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_src_list.c busybox-1.16.1/archival/libipkg/pkg_src_list.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg_src_list.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_src_list.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_src_list.c	2010-06-29 17:31:25.238287396 +0200
 @@ -0,0 +1,75 @@
 +/* pkg_src_list.c - the itsy package management system
 +
@@ -12481,7 +12488,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_src_list.c busybox-1.16.1/arc
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_src_list.h busybox-1.16.1/archival/libipkg/pkg_src_list.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg_src_list.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_src_list.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_src_list.h	2010-06-29 17:31:25.278367968 +0200
 @@ -0,0 +1,57 @@
 +/* pkg_src_list.h - the itsy package management system
 +
@@ -12542,7 +12549,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_src_list.h busybox-1.16.1/arc
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_vec.c busybox-1.16.1/archival/libipkg/pkg_vec.c
 --- busybox-1.16.1.orig/archival/libipkg/pkg_vec.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_vec.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_vec.c	2010-06-29 17:31:25.319617983 +0200
 @@ -0,0 +1,231 @@
 +/* pkg_vec.c - the itsy package management system
 +
@@ -12777,7 +12784,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_vec.c busybox-1.16.1/archival
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_vec.h busybox-1.16.1/archival/libipkg/pkg_vec.h
 --- busybox-1.16.1.orig/archival/libipkg/pkg_vec.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/pkg_vec.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/pkg_vec.h	2010-06-29 17:31:25.358368186 +0200
 @@ -0,0 +1,62 @@
 +/* pkg_vec.h - the itsy package management system
 +
@@ -12843,7 +12850,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/pkg_vec.h busybox-1.16.1/archival
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/sprintf_alloc.h busybox-1.16.1/archival/libipkg/sprintf_alloc.h
 --- busybox-1.16.1.orig/archival/libipkg/sprintf_alloc.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/sprintf_alloc.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/sprintf_alloc.h	2010-06-29 17:31:25.395865857 +0200
 @@ -0,0 +1,25 @@
 +/* sprintf_alloca.c -- like sprintf with memory allocation
 +
@@ -12872,7 +12879,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/sprintf_alloc.h busybox-1.16.1/ar
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/str_list.c busybox-1.16.1/archival/libipkg/str_list.c
 --- busybox-1.16.1.orig/archival/libipkg/str_list.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/str_list.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/str_list.c	2010-06-29 17:31:25.437577685 +0200
 @@ -0,0 +1,76 @@
 +/* str_list.c - the itsy package management system
 +
@@ -12952,7 +12959,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/str_list.c busybox-1.16.1/archiva
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/str_list.h busybox-1.16.1/archival/libipkg/str_list.h
 --- busybox-1.16.1.orig/archival/libipkg/str_list.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/str_list.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/str_list.h	2010-06-29 17:31:25.487410851 +0200
 @@ -0,0 +1,51 @@
 +/* str_list.h - the itsy package management system
 +
@@ -13007,7 +13014,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/str_list.h busybox-1.16.1/archiva
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/str_util.c busybox-1.16.1/archival/libipkg/str_util.c
 --- busybox-1.16.1.orig/archival/libipkg/str_util.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/str_util.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/str_util.c	2010-06-29 17:31:25.540714295 +0200
 @@ -0,0 +1,69 @@
 +/* str_utils.c - the itsy package management system
 +
@@ -13080,7 +13087,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/str_util.c busybox-1.16.1/archiva
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/str_util.h busybox-1.16.1/archival/libipkg/str_util.h
 --- busybox-1.16.1.orig/archival/libipkg/str_util.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/str_util.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/str_util.h	2010-06-29 17:31:25.578749246 +0200
 @@ -0,0 +1,27 @@
 +/* str_utils.h - the itsy package management system
 +
@@ -13111,7 +13118,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/str_util.h busybox-1.16.1/archiva
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/user.c busybox-1.16.1/archival/libipkg/user.c
 --- busybox-1.16.1.orig/archival/libipkg/user.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/user.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/user.c	2010-06-29 17:31:25.628536327 +0200
 @@ -0,0 +1,49 @@
 +/* user.c - the itsy package management system
 +
@@ -13164,7 +13171,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/user.c busybox-1.16.1/archival/li
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/user.h busybox-1.16.1/archival/libipkg/user.h
 --- busybox-1.16.1.orig/archival/libipkg/user.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/user.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/user.h	2010-06-29 17:31:25.678337891 +0200
 @@ -0,0 +1,23 @@
 +/* user.c - the itsy package management system
 +
@@ -13191,7 +13198,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/user.h busybox-1.16.1/archival/li
 +
 diff -Nur busybox-1.16.1.orig/archival/libipkg/void_list.c busybox-1.16.1/archival/libipkg/void_list.c
 --- busybox-1.16.1.orig/archival/libipkg/void_list.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/void_list.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/void_list.c	2010-06-29 17:31:25.715873105 +0200
 @@ -0,0 +1,194 @@
 +/* void_list.c - the itsy package management system
 +
@@ -13389,7 +13396,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/void_list.c busybox-1.16.1/archiv
 +}
 diff -Nur busybox-1.16.1.orig/archival/libipkg/void_list.h busybox-1.16.1/archival/libipkg/void_list.h
 --- busybox-1.16.1.orig/archival/libipkg/void_list.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/void_list.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/void_list.h	2010-06-29 17:31:25.758368030 +0200
 @@ -0,0 +1,59 @@
 +/* void_list.h - the itsy package management system
 +
@@ -13452,7 +13459,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/void_list.h busybox-1.16.1/archiv
 +#endif
 diff -Nur busybox-1.16.1.orig/archival/libipkg/xsystem.c busybox-1.16.1/archival/libipkg/xsystem.c
 --- busybox-1.16.1.orig/archival/libipkg/xsystem.c	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/xsystem.c	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/xsystem.c	2010-06-29 17:31:25.799781135 +0200
 @@ -0,0 +1,64 @@
 +/* xsystem.c - system(3) with error messages
 +
@@ -13520,7 +13527,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/xsystem.c busybox-1.16.1/archival
 +	 
 diff -Nur busybox-1.16.1.orig/archival/libipkg/xsystem.h busybox-1.16.1/archival/libipkg/xsystem.h
 --- busybox-1.16.1.orig/archival/libipkg/xsystem.h	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.16.1/archival/libipkg/xsystem.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libipkg/xsystem.h	2010-06-29 17:31:25.855865061 +0200
 @@ -0,0 +1,34 @@
 +/* xsystem.h - system(3) with error messages
 +
@@ -13558,7 +13565,7 @@ diff -Nur busybox-1.16.1.orig/archival/libipkg/xsystem.h busybox-1.16.1/archival
 +	 
 diff -Nur busybox-1.16.1.orig/archival/libunarchive/Kbuild busybox-1.16.1/archival/libunarchive/Kbuild
 --- busybox-1.16.1.orig/archival/libunarchive/Kbuild	2010-03-20 03:58:07.000000000 +0100
-+++ busybox-1.16.1/archival/libunarchive/Kbuild	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/archival/libunarchive/Kbuild	2010-06-29 17:31:25.898368046 +0200
 @@ -40,6 +40,7 @@
  lib-$(CONFIG_DPKG)                      += $(DPKG_FILES)
  lib-$(CONFIG_DPKG_DEB)                  += $(DPKG_FILES)
@@ -13569,7 +13576,7 @@ diff -Nur busybox-1.16.1.orig/archival/libunarchive/Kbuild busybox-1.16.1/archiv
  lib-$(CONFIG_TAR)                       += get_header_tar.o
 diff -Nur busybox-1.16.1.orig/include/applets.h busybox-1.16.1/include/applets.h
 --- busybox-1.16.1.orig/include/applets.h	2010-03-28 19:43:35.000000000 +0200
-+++ busybox-1.16.1/include/applets.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/include/applets.h	2010-06-29 17:31:25.938368064 +0200
 @@ -214,6 +214,7 @@
  IF_IPCALC(APPLET(ipcalc, _BB_DIR_BIN, _BB_SUID_DROP))
  IF_IPCRM(APPLET(ipcrm, _BB_DIR_USR_BIN, _BB_SUID_REQUIRE))
@@ -13580,7 +13587,16 @@ diff -Nur busybox-1.16.1.orig/include/applets.h busybox-1.16.1/include/applets.h
  IF_IPRULE(APPLET(iprule, _BB_DIR_BIN, _BB_SUID_DROP))
 diff -Nur busybox-1.16.1.orig/include/unarchive.h busybox-1.16.1/include/unarchive.h
 --- busybox-1.16.1.orig/include/unarchive.h	2010-03-28 19:43:35.000000000 +0200
-+++ busybox-1.16.1/include/unarchive.h	2010-04-22 19:21:25.000000000 +0200
++++ busybox-1.16.1/include/unarchive.h	2010-06-29 17:31:25.978368044 +0200
+@@ -53,7 +53,7 @@
+ 	off_t offset;
+ 
+ 	/* Archiver specific. Can make it a union if it ever gets big */
+-#if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB
++#if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB || ENABLE_IPKG
+ 	smallint tar__end;
+ # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
+ 	char* tar__longname;
 @@ -65,7 +65,7 @@
  	struct hardlinks_t *cpio__hardlinks_to_create;
  	struct hardlinks_t *cpio__created_hardlinks;
@@ -13592,7 +13608,7 @@ diff -Nur busybox-1.16.1.orig/include/unarchive.h busybox-1.16.1/include/unarchi
  	/* How to process any sub archive, e.g. get_header_tar_gz */
 diff -Nur busybox-1.16.1.orig/include/usage.h busybox-1.16.1/include/usage.h
 --- busybox-1.16.1.orig/include/usage.h	2010-03-28 19:44:04.000000000 +0200
-+++ busybox-1.16.1/include/usage.h	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/include/usage.h	2010-06-29 17:31:26.018367985 +0200
 @@ -1592,6 +1592,82 @@
         "$ ls -la /tmp/busybox*\n" \
         "-rw-rw-r--    1 andersen andersen   554058 Apr 14 17:49 /tmp/busybox.tar.gz\n"
@@ -13678,7 +13694,7 @@ diff -Nur busybox-1.16.1.orig/include/usage.h busybox-1.16.1/include/usage.h
  #define halt_full_usage "\n\n" \
 diff -Nur busybox-1.16.1.orig/Makefile busybox-1.16.1/Makefile
 --- busybox-1.16.1.orig/Makefile	2010-03-28 19:44:09.000000000 +0200
-+++ busybox-1.16.1/Makefile	2010-04-22 19:18:12.000000000 +0200
++++ busybox-1.16.1/Makefile	2010-06-29 17:31:26.058368031 +0200
 @@ -454,6 +454,7 @@
  
  libs-y		:= \

+ 1 - 1
package/cfgfs/Makefile

@@ -14,7 +14,7 @@ PKG_TARGET_DEPENDS:=	alix wrap foxboard ag241 foxg20 routerboard
 WRKDIST=		${WRKDIR}/${PKG_NAME}-${PKG_VERSION}
 NO_DISTFILES:=		1
 
-CFLINE_CFGFS:= 		select BUSYBOX_COMM\n\tselect BUSYBOX_MD5SUM\n\tselect BUSYBOX_XARGS\n\tselect BUSYBOX_FEATURE_SORT_BIG\n\tselect BUSYBOX_DIFF\n\tdepends on !ADK_TARGET_ROOTFS_NFSROOT
+CFLINE_CFGFS:= 		select BUSYBOX_COMM\n\tselect BUSYBOX_MD5SUM\n\tselect BUSYBOX_XARGS\n\tselect BUSYBOX_FEATURE_SORT_BIG\n\tselect BUSYBOX_DIFF\n\tdepends on !ADK_TARGET_ROOTFS_NFSROOT && !ADK_TARGET_ROOTFS_INITRAMFS_PIGGYBACK && !ADK_TARGET_ROOTFS_INITRAMFS
 
 include ${TOPDIR}/mk/package.mk
 

+ 2 - 2
package/collectd/Makefile

@@ -4,9 +4,9 @@
 include ${TOPDIR}/rules.mk
 
 PKG_NAME:=		collectd
-PKG_VERSION:=		4.9.1
+PKG_VERSION:=		4.10.0
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		31a63d8e3a796dee247024f70426ed1c
+PKG_MD5SUM:=		c473cf8e9f22f5a9f7ef4c5be1b0c436
 PKG_DESCR:=		System statistics collection daemon
 PKG_SECTION:=		console
 PKG_DEPENDS:=		libpthread

+ 56 - 0
package/collectd/patches/patch-configure

@@ -0,0 +1,56 @@
+--- collectd-4.10.0.orig/configure	2010-05-01 11:16:01.000000000 +0200
++++ collectd-4.10.0/configure	2010-06-14 15:51:32.263465769 +0200
+@@ -16636,53 +16636,6 @@ $as_echo "#define HAVE_GEN_GETMNTENT 1" 
+ 
+ fi
+ 
+-# Check for htonll
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if have htonll defined" >&5
+-$as_echo_n "checking if have htonll defined... " >&6; }
+-
+-    have_htonll="no"
+-    if test "$cross_compiling" = yes; then :
+-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error "cannot run test program while cross compiling
+-See \`config.log' for more details." "$LINENO" 5; }
+-else
+-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h.  */
+-
+-
+-#include <sys/types.h>
+-#include <netinet/in.h>
+-#if HAVE_INTTYPES_H
+-# include <inttypes.h>
+-#endif
+-
+-int
+-main ()
+-{
+-
+-          return htonll(0);
+-
+-  ;
+-  return 0;
+-}
+-
+-_ACEOF
+-if ac_fn_c_try_run "$LINENO"; then :
+-
+-      have_htonll="yes"
+-
+-$as_echo "#define HAVE_HTONLL 1" >>confdefs.h
+-
+-
+-fi
+-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+-  conftest.$ac_objext conftest.beam conftest.$ac_ext
+-fi
+-
+-
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_htonll" >&5
+-$as_echo "$have_htonll" >&6; }
+ 
+ # Check for structures
+ ac_fn_c_check_member "$LINENO" "struct if_data" "ifi_ibytes" "ac_cv_member_struct_if_data_ifi_ibytes" "

+ 3 - 3
package/collectd/patches/patch-src_libcollectdclient_Makefile_in

@@ -1,7 +1,7 @@
 $Id: update-patches 24 2008-08-31 14:56:13Z wbx $
---- collectd-4.6.2.orig/src/libcollectdclient/Makefile.in	2009-03-18 11:56:40.000000000 +0100
-+++ collectd-4.6.2/src/libcollectdclient/Makefile.in	2009-05-09 16:29:33.000000000 +0200
-@@ -251,7 +251,7 @@ top_build_prefix = @top_build_prefix@
+--- collectd-4.10.0.orig/src/libcollectdclient/Makefile.in	2010-05-01 11:16:00.000000000 +0200
++++ collectd-4.10.0/src/libcollectdclient/Makefile.in	2010-06-14 15:49:28.563473998 +0200
+@@ -327,7 +327,7 @@ top_build_prefix = @top_build_prefix@
  top_builddir = @top_builddir@
  top_srcdir = @top_srcdir@
  AUTOMAKE_OPTIONS = foreign no-dependencies

+ 1 - 1
package/conntrack-tools/Makefile

@@ -9,7 +9,7 @@ PKG_RELEASE:=		1
 PKG_MD5SUM:=		35b0ab9cde069b4ec8a493daae82d67b
 PKG_DESCR:=		Connection tracking userspace tools
 PKG_SECTION:=		firewall
-PKG_DEPENDS:=		libnetfilter_conntrack
+PKG_DEPENDS:=		libnetfilter-conntrack
 PKG_BUILDDEP+=		libnetfilter_conntrack
 PKG_URL:=		http://conntrack-tools.netfilter.org
 PKG_SITES:=		http://www.netfilter.org/projects/conntrack-tools/files/

+ 27 - 0
package/coreutils/Makefile

@@ -0,0 +1,27 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=		coreutils
+PKG_VERSION:=		8.5
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		c1ffe586d001e87d66cd80c4536ee823
+PKG_DESCR:=		basic file, shell and text manipulation utilities
+PKG_SECTION:=		base
+PKG_URL:=		http://www.gnu.org/software/coreutils/
+PKG_SITES:=		http://ftp.gnu.org/gnu/coreutils/
+
+PKG_DESCR_TSORT:=	topological sort utility
+
+include $(TOPDIR)/mk/package.mk
+
+#$(eval $(call PKG_template,COREUTILS,$(PKG_NAME),$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+$(eval $(call PKG_template,TSORT,tsort,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR_TSORT},${PKG_SECTION}))
+
+post-install:
+	$(INSTALL_DIR) $(IDIR_TSORT)/usr/bin
+	$(INSTALL_BIN) $(WRKINST)/usr/bin/tsort \
+		$(IDIR_TSORT)/usr/bin
+
+include ${TOPDIR}/mk/pkg-bottom.mk

+ 2 - 2
package/cpio/Makefile

@@ -4,9 +4,9 @@
 include ${TOPDIR}/rules.mk
 
 PKG_NAME:=		cpio
-PKG_VERSION:=		2.10
+PKG_VERSION:=		2.11
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		351ab3d38d8949913e478cc23b9d6ad4
+PKG_MD5SUM:=		1112bb6c45863468b5496ba128792f6c
 PKG_DESCR:=		copies files into or out of a cpio archive
 PKG_SECTION:=		net
 PKG_URL:=		http://www.gnu.org/software/cpio/

+ 8 - 0
package/cpio/patches/patch-src_filetypes_h

@@ -0,0 +1,8 @@
+--- cpio-2.11.orig/src/filetypes.h	2010-02-12 11:19:23.000000000 +0100
++++ cpio-2.11/src/filetypes.h	2010-06-08 18:26:43.633473938 +0200
+@@ -82,4 +82,4 @@
+ #define lstat stat
+ #endif
+ int lstat ();
+-int stat ();
++//int stat ();

+ 2 - 2
package/curl/Makefile

@@ -4,9 +4,9 @@
 include ${TOPDIR}/rules.mk
 
 PKG_NAME:=		curl
-PKG_VERSION:=		7.19.7
+PKG_VERSION:=		7.20.1
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		ecb2e37e45c9933e2a963cabe03670ab
+PKG_MD5SUM:=		d7df0507db48546661b155b612cac19c
 PKG_DESCR:=		a client-side URL transfer tool
 PKG_SECTION:=		net
 PKG_DEPENDS:=		libcurl

+ 9 - 9
package/davfs2/Makefile

@@ -3,25 +3,25 @@
 
 include ${TOPDIR}/rules.mk
 
-PKG_NAME=		davfs2
-PKG_VERSION=		1.3.3
-PKG_RELEASE=		1
-PKG_MD5SUM=		57def26e4d6d63527e01612d10fd0515
+PKG_NAME:=		davfs2
+PKG_VERSION:=		1.4.6
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		c9e8aeb15daeba4b6283b40bb640e908
 PKG_DESCR:=		WebDAV filesystem
 PKG_SECTION:=		admin
 PKG_BUILDDEP+=		libiconv neon
 ifneq (${ADK_PACKAGE_DAVFS2_FUSE}${ADK_PACKAGE_DAVFS2_BOTH},)
 PKG_BUILDDEP+=		fuse
 endif
-PKG_URL:=		http://savannah.nongnu.org/projects/davfs2
-PKG_SITES=		${MASTER_SITE_SOURCEFORGE:=dav/}
+PKG_URL:=		http://savannah.nongnu.org/projects/davfs2		
+PKG_SITES:=		http://www.very-clever.com/download/nongnu/davfs2/
 
 ifeq (${ADK_PACKAGE_DAVFS2_FUSE},y)
-PKG_DEPENDS:=			fuse-utils kmod-fuse-fs libiconv neon
+PKG_DEPENDS:=		fuse-utils kmod-fuse-fs libiconv neon
 else ifeq (${ADK_PACKAGE_DAVFS2_CODA},y)
-PKG_DEPENDS:=			kmod-coda-fs libiconv neon
+PKG_DEPENDS:=		kmod-coda-fs libiconv neon
 else
-PKG_DEPENDS:=			kmod-coda-fs fuse-utils kmod-fuse-fs libiconv neon
+PKG_DEPENDS:=		kmod-coda-fs fuse-utils kmod-fuse-fs libiconv neon
 endif
 
 include ${TOPDIR}/mk/package.mk

+ 0 - 11
package/davfs2/patches/patch-src_cache_c

@@ -1,11 +0,0 @@
-$Id: update-patches 24 2008-08-31 14:56:13Z wbx $
---- davfs2-1.3.3.orig/src/cache.c	2008-06-24 21:32:50.000000000 +0200
-+++ davfs2-1.3.3/src/cache.c	2008-12-08 00:06:51.000000000 +0100
-@@ -23,7 +23,6 @@
- 
- #include "config.h"
- 
--#include <argz.h>
- #include <dirent.h>
- #include <errno.h>
- #include <error.h>

+ 0 - 11
package/davfs2/patches/patch-src_dav_coda2_c

@@ -1,11 +0,0 @@
-$Id: update-patches 24 2008-08-31 14:56:13Z wbx $
---- davfs2-1.3.3.orig/src/dav_coda2.c	2008-02-02 23:23:45.000000000 +0100
-+++ davfs2-1.3.3/src/dav_coda2.c	2008-12-08 00:07:35.000000000 +0100
-@@ -23,7 +23,6 @@
- 
- #include "config.h"
- 
--#include <argz.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <limits.h>

+ 0 - 11
package/davfs2/patches/patch-src_dav_coda3_c

@@ -1,11 +0,0 @@
-$Id: update-patches 24 2008-08-31 14:56:13Z wbx $
---- davfs2-1.3.3.orig/src/dav_coda3.c	2008-02-02 23:24:10.000000000 +0100
-+++ davfs2-1.3.3/src/dav_coda3.c	2008-12-08 00:08:00.000000000 +0100
-@@ -23,7 +23,6 @@
- 
- #include "config.h"
- 
--#include <argz.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <limits.h>

+ 0 - 11
package/davfs2/patches/patch-src_dav_fuse5_c

@@ -1,11 +0,0 @@
-$Id: update-patches 24 2008-08-31 14:56:13Z wbx $
---- davfs2-1.3.3.orig/src/dav_fuse5.c	2008-04-05 20:36:06.000000000 +0200
-+++ davfs2-1.3.3/src/dav_fuse5.c	2008-12-08 00:08:26.000000000 +0100
-@@ -23,7 +23,6 @@
- 
- #include "config.h"
- 
--#include <argz.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <stddef.h>

+ 0 - 11
package/davfs2/patches/patch-src_dav_fuse7_c

@@ -1,11 +0,0 @@
-$Id: update-patches 24 2008-08-31 14:56:13Z wbx $
---- davfs2-1.3.3.orig/src/dav_fuse7.c	2008-04-09 21:43:34.000000000 +0200
-+++ davfs2-1.3.3/src/dav_fuse7.c	2008-12-08 00:08:32.000000000 +0100
-@@ -23,7 +23,6 @@
- 
- #include "config.h"
- 
--#include <argz.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <stddef.h>

+ 0 - 31
package/davfs2/patches/patch-src_kernel_interface_c

@@ -1,31 +0,0 @@
-$Id$
---- davfs2-1.3.3.orig/src/kernel_interface.c	2008-04-05 20:43:04.000000000 +0200
-+++ davfs2-1.3.3/src/kernel_interface.c	2008-12-08 00:09:01.000000000 +0100
-@@ -23,7 +23,6 @@
- 
- #include "config.h"
- 
--#include <argz.h>
- #include <errno.h>
- #include <error.h>
- #include <fcntl.h>
-@@ -173,7 +172,8 @@ static int init_coda(int *dev, dav_run_m
-     }
- 
-     if (*dev <= 0) {
--        system("/sbin/modprobe coda &>/dev/null");
-+        system("/sbin/insmod coda");
-+	sleep(1);
-         minor = 0;
-         while (*dev <= 0 && minor < MAX_CODADEVS) {
-             char *path;
-@@ -240,7 +240,8 @@ static int init_fuse(int *dev, dav_run_m
- 
-     *dev = open(path, O_RDWR | O_NONBLOCK);
-     if (*dev <= 0) {
--        system("/sbin/modprobe fuse &>/dev/null");
-+        system("/sbin/insmod fuse");
-+	sleep(1);
-         *dev = open(path, O_RDWR | O_NONBLOCK);
-     }
-     if (*dev <= 0) {

+ 22 - 40
package/davfs2/patches/patch-src_mount_davfs_c

@@ -1,40 +1,22 @@
-$Id$
---- davfs2-1.3.3.orig/src/mount_davfs.c	2008-06-30 20:29:42.000000000 +0200
-+++ davfs2-1.3.3/src/mount_davfs.c	2008-12-08 00:20:01.000000000 +0100
-@@ -23,12 +23,10 @@
- 
- #include "config.h"
- 
--#include <argz.h>
- #include <ctype.h>
- #include <errno.h>
- #include <error.h>
+--- davfs2-1.4.6.orig/src/mount_davfs.c	2010-01-21 19:50:15.000000000 +0100
++++ davfs2-1.4.6/src/mount_davfs.c	2010-05-29 21:10:23.041613426 +0200
+@@ -29,7 +29,6 @@
+ #ifdef HAVE_FCNTL_H
  #include <fcntl.h>
+ #endif
 -#include <fstab.h>
  #include <getopt.h>
  #include <grp.h>
- #include <limits.h>
-@@ -602,15 +600,18 @@ static char *check_double_mounts(dav_arg
-    free to choose them. They should be configured in davfs2.conf anyway. */
- static void check_fstab(const dav_args *args) {
- 
+ #ifdef HAVE_LIBINTL_H
+@@ -677,6 +676,7 @@ check_double_mounts(dav_args *args)
+ static void
+ check_fstab(const dav_args *args)
+ {
 +#if 0
      dav_args *n_args = new_args();
      n_args->mopts = DAV_USER_MOPTS;
  
-     setfsent();
-     struct fstab *ft = getfsfile(mpoint);
-     if (ft == NULL)
-+#endif
-         error(EXIT_FAILURE, 0, _("no entry for %s found in %s"), url,
--              _PATH_FSTAB);
-+              "/etc/fstab");
- 
-+#if 0
-     if (strcmp(url, ft->fs_spec) != 0) {
-         char *fstab_url = decode_octal(ft->fs_spec);
-         if (strcmp(url, fstab_url) != 0)
-@@ -642,6 +643,7 @@ static void check_fstab(const dav_args *
+@@ -733,6 +733,7 @@ check_fstab(const dav_args *args)
  
      endfsent();
      delete_args(n_args);
@@ -42,28 +24,28 @@ $Id$
  }
  
  
-@@ -661,7 +663,7 @@ static void check_mountpoint(dav_args *a
+@@ -754,7 +755,7 @@ check_mountpoint(dav_args *args)
      struct passwd *pw;
  
      if (*mpoint != '/') {
 -        char *mp = canonicalize_file_name(mpoint);
 +        char *mp = realpath(mpoint, NULL);
-         if (mp == NULL)
+         if (!mp)
              error(EXIT_FAILURE, 0,
                    _("can't evaluate path of mount point %s"), mpoint);
-@@ -1754,6 +1756,7 @@ static dav_args *new_args(void) {
- 
- static void log_dbg_config(char *argv[], dav_args *args) {
- 
+@@ -1824,6 +1825,7 @@ new_args(void)
+ static void
+ log_dbg_cmdline(char *argv[])
+ {
 +    /*
      size_t len;
-     char * cmdline;
+     char *cmdline;
      if (argz_create(argv, &cmdline, &len) == 0) {
-@@ -1761,6 +1764,7 @@ static void log_dbg_config(char *argv[],
+@@ -1831,6 +1833,7 @@ log_dbg_cmdline(char *argv[])
          syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), cmdline);
          free(cmdline);
      }
 +    */
-     
-     syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
-            "Configuration:");
+ }
+ 
+ 

+ 5 - 6
package/davfs2/patches/patch-src_umount_davfs_c

@@ -1,12 +1,11 @@
-$Id: update-patches 24 2008-08-31 14:56:13Z wbx $
---- davfs2-1.3.3.orig/src/umount_davfs.c	2008-01-11 22:40:18.000000000 +0100
-+++ davfs2-1.3.3/src/umount_davfs.c	2008-12-08 00:38:43.000000000 +0100
-@@ -114,7 +114,7 @@ int main(int argc, char *argv[]) {
+--- davfs2-1.4.6.orig/src/umount_davfs.c	2009-06-04 20:30:32.000000000 +0200
++++ davfs2-1.4.6/src/umount_davfs.c	2010-05-30 09:53:14.681613660 +0200
+@@ -120,7 +120,7 @@ main(int argc, char *argv[])
      if (optind < (argc - 1))
          error(EXIT_FAILURE, 0, _("too many arguments"));
  
 -    char *mpoint = canonicalize_file_name(argv[optind]);
 +    char *mpoint = realpath(argv[optind], NULL);
-     if (mpoint == NULL)
+     if (!mpoint)
          mpoint = argv[optind];
-     if (mpoint == NULL || *mpoint != '/')
+     if (!mpoint || *mpoint != '/')

+ 21 - 41
package/davfs2/patches/patch-src_webdav_c

@@ -1,55 +1,35 @@
-$Id$
-
-	cf. http://sourceforge.net/tracker/index.php?func=detail&aid=1594808&group_id=26275&atid=386747
-
---- davfs2-1.3.3.orig/src/webdav.c	2008-06-28 19:20:07.000000000 +0200
-+++ davfs2-1.3.3/src/webdav.c	2008-12-08 00:37:23.000000000 +0100
-@@ -23,7 +23,6 @@
+--- davfs2-1.4.6.orig/src/webdav.c	2010-02-16 20:29:59.000000000 +0100
++++ davfs2-1.4.6/src/webdav.c	2010-05-30 09:52:01.161613627 +0200
+@@ -52,6 +52,8 @@
+ #include <sys/stat.h>
+ #endif
  
- #include "config.h"
- 
--#include <argz.h>
- #include <errno.h>
- #include <error.h>
- #include <fcntl.h>
-@@ -34,6 +33,7 @@
- #include <stdlib.h>
- #include <string.h>
- #include <syslog.h>
 +#include <regex.h>
- #include <time.h>
- #include <unistd.h>
- 
-@@ -406,6 +406,11 @@ void dav_init_webdav(const char *scheme,
-     suri = (ne_uri *) ne_calloc(sizeof(ne_uri));
-     ne_fill_server_uri(session, suri);
- 
-+    /* begin of GMX hack */
-+    ne_server_capabilities caps;
-+    ne_options(session, "/", &caps);
-+    /* end of GMX hack */
 +
-     if (use_locks) {
-         locks = ne_lockstore_create();
-         if (lock_owner == NULL) {
-@@ -1859,13 +1864,18 @@ static int ssl_verify(void *userdata, in
-                      "or there might be a man-in-the-middle-attack.\n"));
-             printf(_("Accept certificate for this session? [y,N] "));
-             char *s = NULL;
-+            regex_t *re;
-             size_t n = 0;
-             ssize_t len = 0;
+ #include <ne_alloc.h>
+ #include <ne_auth.h>
+ #include <ne_basic.h>
+@@ -1918,6 +1920,7 @@ quota_result(void *userdata, const ne_ur
+ static int
+ ssl_verify(void *userdata, int failures, const ne_ssl_certificate *cert)
+ {
++    regex_t *re;
+     char *issuer = ne_ssl_readable_dname(ne_ssl_cert_issuer(cert));
+     char *subject = ne_ssl_readable_dname(ne_ssl_cert_subject(cert));
+     char *digest = ne_calloc(NE_SSL_DIGESTLEN);
+@@ -1964,8 +1967,13 @@ ssl_verify(void *userdata, int failures,
              len = getline(&s, &n, stdin);
              if (len < 0)
                  abort();
--            if (rpmatch(s) < 1)
--                ret = -1;
+-            if (rpmatch(s) > 0)
+-                ret = 0;
 +	    if (regcomp(&re, "^[yY]", REG_EXTENDED) != 0) {
 +		if (regexec(&re, s, (size_t)0, NULL, 0) < 1) {
 +		        regfree(&re);
 +			ret = -1;
 +		}
++		ret = 0;
 +	    }
              free(s);
-         }
      } 
+ 

+ 31 - 0
package/dillo/Makefile

@@ -0,0 +1,31 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=		dillo
+PKG_VERSION:=		2.2
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		f8bcd62093f178bed81e46cc54e73f42
+PKG_DESCR:=		small graphical web browser
+PKG_SECTION:=		x11
+PKG_DEPENDS:=		libfltk libxi libiconv libpng zlib libjpeg
+PKG_DEPENDS+=		libstdcxx
+PKG_BUILDDEP+=		fltk libXi libiconv jpeg libpng zlib
+PKG_URL:=		http://www.dillo.org/
+PKG_SITES:=		http://www.dillo.org/download/
+
+DISTFILES:=             ${PKG_NAME}-${PKG_VERSION}.tar.bz2
+
+include $(TOPDIR)/mk/package.mk
+
+$(eval $(call PKG_template,DILLO,$(PKG_NAME),$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+
+TLDFLAGS+=		-liconv
+
+post-install:
+	$(INSTALL_DIR) $(IDIR_DILLO)/usr/bin
+	$(INSTALL_BIN) $(WRKINST)/usr/bin/dillo \
+		$(IDIR_DILLO)/usr/bin
+
+include ${TOPDIR}/mk/pkg-bottom.mk

+ 7 - 1
package/dropbear/Makefile

@@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=		dropbear
 PKG_VERSION:=		0.52
-PKG_RELEASE:=		2
+PKG_RELEASE:=		3
 PKG_MD5SUM:=		1c69ec674481d7745452f68f2ea5597e
 PKG_DESCR:=		SSH 2 server/client designed for embedded systems 
 PKG_SECTION:=		net
@@ -62,5 +62,11 @@ do-install:
 	$(INSTALL_DIR) $(IDIR_DBCONVERT)/usr/bin
 	$(INSTALL_BIN) $(WRKBUILD)/dropbearconvert \
 		$(IDIR_DBCONVERT)/usr/bin/dropbearconvert
+	# ssh pubkey
+	test -z $(ADK_SSH_PUBKEY) || ( \
+		mkdir -p $(IDIR_DROPBEAR)/etc/dropbear; \
+		echo $(ADK_SSH_PUBKEY) \
+		>$(IDIR_DROPBEAR)/etc/dropbear/authorized_keys; \
+        )
 
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 3 - 3
package/e2fsprogs/Makefile

@@ -4,9 +4,9 @@
 include ${TOPDIR}/rules.mk
 
 PKG_NAME:=		e2fsprogs
-PKG_VERSION:=		1.41.9
-PKG_RELEASE:=		3
-PKG_MD5SUM:=		52f60a9e19a02f142f5546f1b5681927
+PKG_VERSION:=		1.41.12
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		1b24a21fc0c2381ef420961cbfec733f
 PKG_DESCR:=		Ext2/3/4 filesystem utilities
 PKG_SECTION:=		admin
 PKG_DEPENDS:=		libcom-err libuuid libblkid libpthread

+ 1 - 1
package/fetchmail/Makefile

@@ -10,7 +10,6 @@ PKG_MD5SUM:=		72c20ad2b9629f1a109668b05a84d823
 PKG_DESCR:=		fetch mail from a POP or IMAP server
 PKG_SECTION:=		text
 ifeq (${ADK_PACKAGE_FETCHMAIL_SSL},y)
-PKG_DEPENDS:=		libopenssl
 PKG_BUILDDEP+=		openssl
 endif
 PKG_URL:=		http://fetchmail.berlios.de/
@@ -20,6 +19,7 @@ DISTFILES:=             ${PKG_NAME}-${PKG_VERSION}.tar.bz2
 
 PKG_FLAVOURS:=		SSL
 PKGFD_SSL:=		enable SSL support
+PKGFS_SSL:=		libopenssl
 
 include ${TOPDIR}/mk/package.mk
 

+ 4 - 4
package/ffmpeg/Makefile

@@ -4,9 +4,9 @@
 include ${TOPDIR}/rules.mk
 
 PKG_NAME:=		ffmpeg
-PKG_VERSION:=		0.5
-PKG_RELEASE:=		2
-PKG_MD5SUM:=		be8503f15c3b81ba00eb8379ca8dcf33
+PKG_VERSION:=		0.6
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		d6142a9a5821d6a6262a6edb903faa24
 PKG_DESCR:=		solution to record, convert and stream audio and video
 PKG_SECTION:=		sound
 PKG_DEPENDS:=		libfaad2
@@ -25,6 +25,7 @@ CONFIG_STYLE:=		minimal
 include ${TOPDIR}/mk/cpu.mk
 
 CONFIGURE_ARGS:=	--prefix=/usr \
+			--target-os=linux \
 			--arch=${CPU_ARCH} \
 			--enable-cross-compile \
 			--source-path=${WRKSRC} \
@@ -39,7 +40,6 @@ CONFIGURE_ARGS:=	--prefix=/usr \
 			--disable-ffmpeg \
 			--disable-ffplay \
 			--disable-ffserver \
-			--disable-vhook \
 			--enable-gpl \
 			--enable-swscale \
 			--enable-postproc \

+ 0 - 63
package/ffmpeg/patches/patch-configure

@@ -1,63 +0,0 @@
---- ffmpeg-0.5.orig/configure	2009-03-01 18:57:14.000000000 +0100
-+++ ffmpeg-0.5/configure	2010-01-06 20:34:48.343750000 +0100
-@@ -1167,7 +1167,7 @@ arch=`uname -m`
- cpu="generic"
- 
- # OS
--target_os=$(tolower $(uname -s))
-+target_os=linux
- 
- # configurable options
- enable debug
-@@ -2486,51 +2486,6 @@ cmp -s $TMPH config.h &&
- 
- rm -f $TMPC $TMPE $TMPH $TMPO $TMPS $TMPSH
- 
--# build tree in object directory if source path is different from current one
--if enabled source_path_used; then
--    DIRS="\
--        doc               \
--        libavcodec        \
--        libavcodec/alpha  \
--        libavcodec/arm    \
--        libavcodec/bfin   \
--        libavcodec/mlib   \
--        libavcodec/ppc    \
--        libavcodec/sh4    \
--        libavcodec/sparc  \
--        libavcodec/x86    \
--        libavdevice       \
--        libavfilter       \
--        libavformat       \
--        libavutil         \
--        libpostproc       \
--        libswscale        \
--        tests             \
--        tools             \
--        vhook             \
--        "
--    FILES="\
--        Makefile             \
--        common.mak           \
--        subdir.mak           \
--        doc/texi2pod.pl      \
--        libavcodec/Makefile  \
--        libavdevice/Makefile \
--        libavfilter/Makefile \
--        libavformat/Makefile \
--        libavutil/Makefile   \
--        libpostproc/Makefile \
--        libswscale/Makefile  \
--        "
--    for dir in $DIRS ; do
--        mkdir -p $dir
--    done
--    for f in $FILES ; do
--        $ln_s "$source_path/$f" $f
--    done
--fi
--
--
- # build pkg-config files
- 
- pkgconfig_generate(){

+ 10 - 7
package/firefox/Makefile

@@ -4,23 +4,23 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=		firefox
-PKG_VERSION:=		3.6.3
+PKG_VERSION:=		3.6.6
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		5e4541ab23084b7b14ba228291ce2688
+PKG_MD5SUM:=		c9a071b31bb90d05edfb93117d0a7537
 PKG_DESCR:=		graphical webbrowser
 PKG_SECTION:=		x11
-PKG_DEPENDS:=		libpthread alsa-lib dbus-glib glib gtk+ libnotify libidl
+PKG_DEPENDS:=		libpthread alsa-lib dbus-glib glib libgtk+ libnotify libidl
 PKG_DEPENDS+=		nspr nss libjpeg atk pango cairo libxt libx11 libstdcxx
 PKG_DEPENDS+=		libxdamage libxfixes
 PKG_BUILDDEP+=		alsa-lib dbus-glib glib gtk+ libnotify libIDL libX11 libXt
 PKG_BUILDDEP+=		nspr nss jpeg
 PKG_URL:=		http://www.mozilla.org/
-PKG_SITES:=		http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/source/
+PKG_SITES:=		http://releases.mozilla.org/pub/mozilla.org/firefox/releases/${PKG_VERSION}/source/
 
 DISTFILES:=             ${PKG_NAME}-${PKG_VERSION}.source.tar.bz2
 
 WRKDIST=		${WRKDIR}/mozilla-1.9.2
-PKG_TARGET_DEPENDS:=	alix1c x86_qemu x86_64_qemu shuttle ibmx40
+PKG_TARGET_DEPENDS:=	alix1c x86_qemu x86_64_qemu shuttle ibmx40 lemote
 
 include $(TOPDIR)/mk/package.mk
 
@@ -28,7 +28,8 @@ $(eval $(call PKG_template,FIREFOX,$(PKG_NAME),$(PKG_VERSION)-${PKG_RELEASE},${P
 
 CONFIGURE_ENV+=		CROSS_COMPILE=1 HOST_CC="${HOSTCC}" HOST_CFLAGS="${HOSTCFLAGS}" \
 			HOST_CXX="${HOSTCXX}" HOST_CXXFLAGS="${HOSTCXXFLAGS}" \
-			HOST_LIBIDL_CONFIG="/usr/bin/libIDL-config-2"
+			HOST_LIBIDL_CONFIG="/usr/bin/libIDL-config-2" \
+			ac_cv_thread_keyword=no
 CONFIGURE_ARGS+=	--enable-application=browser \
 			--with-system-zlib \
 			--with-system-jpeg \
@@ -41,12 +42,14 @@ CONFIGURE_ARGS+=	--enable-application=browser \
 			--disable-gnomevfs \
 			--disable-optimize \
 			--disable-necko-wifi \
+			--disable-svg \
+			--disable-mathml \
 			--disable-crashreporter
 
 post-install:
 	$(INSTALL_DIR) $(IDIR_FIREFOX)/usr/bin
 	$(INSTALL_DIR) $(IDIR_FIREFOX)/usr/lib
-	$(CP) $(WRKINST)/usr/lib/firefox-3.6.3 \
+	$(CP) $(WRKINST)/usr/lib/firefox-${PKG_VERSION} \
 		$(IDIR_FIREFOX)/usr/lib/
 	$(CP) $(WRKINST)/usr/bin/firefox \
 		$(IDIR_FIREFOX)/usr/bin

+ 11 - 0
package/firefox/patches/patch-content_media_nsAudioStream_cpp

@@ -0,0 +1,11 @@
+--- mozilla-1.9.2.orig/content/media/nsAudioStream.cpp	2010-04-02 18:02:19.000000000 +0200
++++ mozilla-1.9.2/content/media/nsAudioStream.cpp	2010-06-11 21:28:33.522214080 +0200
+@@ -246,7 +246,7 @@ float nsAudioStream::GetPosition()
+ #if defined(XP_WIN)
+   positionType = SA_POSITION_WRITE_HARDWARE;
+ #endif
+-  PRInt64 position = 0;
++  int64_t position = 0;
+   if (sa_stream_get_position(static_cast<sa_stream_t*>(mAudioHandle),
+                              positionType, &position) == SA_SUCCESS) {
+     return (position / float(mRate) / mChannels / sizeof(short));

+ 27 - 0
package/fltk/Makefile

@@ -0,0 +1,27 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=		fltk
+PKG_VERSION:=		2.0
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		557544badbacca4ee1ebb2448f6e1f8a
+PKG_DESCR:=		fast light toolkit
+PKG_SECTION:=		libs
+PKG_BUILDDEP+=		libX11 libXi MesaLib freeglut
+PKG_URL:=		http://www.fltk.org/
+PKG_SITES:=		http://ftp.funet.fi/pub/mirrors/ftp.easysw.com/pub/fltk/snapshots/
+
+DISTFILES:=             ${PKG_NAME}-${PKG_VERSION}.x-r7513.tar.bz2
+WRKDIST=		${WRKDIR}/${PKG_NAME}-2.0.x-r7513
+
+include $(TOPDIR)/mk/package.mk
+
+$(eval $(call PKG_template,LIBFLTK,libfltk,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+
+post-install:
+	$(INSTALL_DIR) $(IDIR_LIBFLTK)/usr/lib
+	$(CP) ${WRKINST}/usr/lib/libfltk*.so* $(IDIR_LIBFLTK)/usr/lib
+
+include ${TOPDIR}/mk/pkg-bottom.mk

+ 11 - 0
package/fltk/patches/patch-makeinclude_in

@@ -0,0 +1,11 @@
+--- fltk-2.0.x-r7513.orig/makeinclude.in	2006-04-11 00:06:06.000000000 +0200
++++ fltk-2.0.x-r7513/makeinclude.in	2010-06-13 17:18:11.503473158 +0200
+@@ -45,7 +45,7 @@ NROFF		= @NROFF@
+ RM		= rm -f
+ RMDIR		= rm -rf
+ SHELL		= /bin/sh
+-STRIP		= strip
++STRIP		= echo
+ 
+ # compiler names:
+ CC		= @CC@

+ 11 - 0
package/fltk/patches/patch-makeinclude_in.orig

@@ -0,0 +1,11 @@
+--- fltk-2.0.x-r7513.orig/makeinclude.in	2006-04-11 00:06:06.000000000 +0200
++++ fltk-2.0.x-r7513/makeinclude.in	2010-06-13 17:15:29.633155678 +0200
+@@ -45,7 +45,7 @@ NROFF		= @NROFF@
+ RM		= rm -f
+ RMDIR		= rm -rf
+ SHELL		= /bin/sh
+-STRIP		= strip
++STRIP		= 
+ 
+ # compiler names:
+ CC		= @CC@

+ 40 - 0
package/fluxbox/Makefile

@@ -0,0 +1,40 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=		fluxbox
+PKG_VERSION:=		1.1.1
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		e0be927617be4ffc1ddc79513f4eb0f9
+PKG_DESCR:=		Fluxbox is an X11 window manager featuring tabs and an iconbar
+PKG_SECTION:=		x11
+PKG_DEPENDS:=		libstdcxx
+PKG_BUILDDEP:=		libXpm
+ifeq (${ADK_PACKAGE_FLUXBOX_WITH_IMLIB2},y)
+PKG_BUILDDEP+=		imlib2
+endif
+PKG_URL:=		http://www.fluxbox.org
+PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=fluxbox/}
+
+PKG_FLAVOURS:=		WITH_IMLIB2
+PKGFD_WITH_IMLIB2:=	enable imlib2 support
+PKGFS_WITH_IMLIB2:=	imlib2
+
+include $(TOPDIR)/mk/package.mk
+
+$(eval $(call PKG_template,FLUXBOX,$(PKG_NAME),$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+
+ifeq (${ADK_PACKAGE_FLUXBOX_WITH_IMLIB2},y)
+CONFIGURE_ARGS+=	--enable-imlib2
+else
+CONFIGURE_ARGS+=	--disable-imlib2
+endif
+
+post-install:
+	$(INSTALL_DIR) $(IDIR_FLUXBOX)/usr/{bin,share}
+	$(INSTALL_BIN) $(WRKINST)/usr/bin/* \
+		$(IDIR_FLUXBOX)/usr/bin
+	${CP} ${WRKINST}/usr/share/fluxbox ${IDIR_FLUXBOX}/usr/share/
+
+include ${TOPDIR}/mk/pkg-bottom.mk

+ 2 - 0
package/font-misc-misc/Makefile

@@ -19,6 +19,8 @@ include $(TOPDIR)/mk/package.mk
 
 $(eval $(call PKG_template,FONT_MISC_MISC,$(PKG_NAME),$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
 
+CONFIGURE_ENV+=		MAPFILES_PATH=${STAGING_DIR}/usr/share/fonts/X11/util
+
 post-install:
 	$(INSTALL_DIR) $(IDIR_FONT_MISC_MISC)/usr/share/fonts/X11/misc
 	$(CP) ${WRKINST}/usr/share/fonts/X11/misc/* \

+ 11 - 0
package/font-misc-misc/patches/patch-configure

@@ -0,0 +1,11 @@
+--- font-misc-misc-1.1.0.orig/configure	2009-10-11 03:23:03.000000000 +0200
++++ font-misc-misc-1.1.0/configure	2010-06-15 00:35:59.189800221 +0200
+@@ -5544,7 +5544,7 @@ $as_echo "yes" >&6; }
+ fi
+ 	{ $as_echo "$as_me:$LINENO: checking for ucs2any encoding data files" >&5
+ $as_echo_n "checking for ucs2any encoding data files... " >&6; }
+-	MAPFILES_PATH=`pkg-config --variable=mapdir fontutil`
++#	MAPFILES_PATH=`pkg-config --variable=mapdir fontutil`
+ 
+ 	{ $as_echo "$as_me:$LINENO: result: ${MAPFILES_PATH}" >&5
+ $as_echo "${MAPFILES_PATH}" >&6; }

+ 11 - 1
package/font-util/Makefile

@@ -16,7 +16,17 @@ include ${TOPDIR}/mk/package.mk
 
 $(eval $(call PKG_template,FONT_UTIL,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION},${PKG_OPTS}))
 
-post-install:
+# XXX: Push the mapping files to a place where we can find them
+# again when compiling the actual fonts. This is ugly as hell,
+# especially as all font packages still need patching to avoid
+# calling pkg-config (which we don't provide) in order to
+# automatically find the mappings.
+fonts-hack:
+	${INSTALL_DIR} ${STAGING_DIR}/usr/share/fonts/X11/util
+	${CP} ${WRKINST}/usr/share/fonts/X11/util/* \
+		${STAGING_DIR}/usr/share/fonts/X11/util
+
+post-install: fonts-hack
 	${INSTALL_DIR} ${IDIR_FONT_UTIL}/usr/share/fonts/X11/util
 	${CP} ${WRKINST}/usr/share/fonts/X11/util/* \
 		${IDIR_FONT_UTIL}/usr/share/fonts/X11/util

+ 23 - 0
package/freeglut/Makefile

@@ -0,0 +1,23 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=		freeglut
+PKG_VERSION:=		2.6.0
+PKG_RELEASE:=		1
+PKG_MD5SUM:=		39f0f2de89f399529d2b981188082218
+PKG_DESCR:=		OpenGL Utility Toolkit
+PKG_SECTION:=		libs
+PKG_URL:=		http://www.freeglut.org/
+PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=freeglut/}
+
+include $(TOPDIR)/mk/package.mk
+
+$(eval $(call PKG_template,FREEGLUT,$(PKG_NAME),$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+
+post-install:
+	$(INSTALL_DIR) $(IDIR_FREEGLUT)/usr/lib
+	$(CP) ${WRKINST}/usr/lib/libglut.so* $(IDIR_FREEGLUT)/usr/lib
+
+include ${TOPDIR}/mk/pkg-bottom.mk

+ 2 - 2
package/git/Makefile

@@ -4,9 +4,9 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=		git
-PKG_VERSION:=		1.7.0.1
+PKG_VERSION:=		1.7.1
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		05485caf5c503ce378a87759bc3a0509
+PKG_MD5SUM:=		d2fefae2b787a19601c09d89975ce5fb
 PKG_DESCR:=		fast version control system
 PKG_SECTION:=		scm
 PKG_DEPENDS:=		libopenssl libcurl libexpat libpthread

+ 28 - 0
package/gpm/files/gpm.init

@@ -0,0 +1,28 @@
+#!/bin/sh
+#PKG gpm
+#INIT 80
+
+. /etc/rc.conf
+
+case $1 in
+autostop) ;;
+autostart)
+	test x"${gpm:-NO}" = x"NO" && exit 0
+	exec sh $0 start
+	;;
+start)
+	/usr/sbin/gpm $gpm_flags
+	;;
+stop)
+	pkill gpm
+	;;
+restart)
+	sh $0 stop
+	sh $0 start
+	;;
+*)
+	echo "Usage: $0 {start | stop | restart}"
+	exit 1
+	;;
+esac
+exit $?

+ 4 - 0
package/gpm/files/gpm.postinst

@@ -0,0 +1,4 @@
+#!/bin/sh
+. $IPKG_INSTROOT/etc/functions.sh
+add_rcconf 'options passed to gpm' gpm_flags "-m /dev/psaux -t ps2"
+add_rcconf gpm gpm NO

+ 6 - 6
package/grub-bin/Makefile

@@ -4,17 +4,17 @@
 include ${TOPDIR}/rules.mk
 
 # compiled with i486 toolchain, statically linked with uClibc
-# cross-compile on amd64 does not work, so provide a binary package
+# cross-compiling is difficult, so provide a binary package
 PKG_NAME:=		grub-bin
-PKG_VERSION:=		1.97.1
+PKG_VERSION:=		1.98
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		24961a39e63d8ec16d765aad3a301cda
-PKG_DESCR:=		GRUB bootloader
-PKG_SECTION:=		sys
+PKG_MD5SUM:=		958f9fd415a0bd52fe115176afbf19d9
+PKG_DESCR:=		GRUB2 bootloader (binary package)
+PKG_SECTION:=		base
 PKG_SITES:=		http://openadk.org/distfiles/
 
 PKG_TARGET_DEPENDS:=	x86 x86_64
-CFLINE_GRUB_BIN:=	select BUSYBOX_FEATURE_STAT_FORMAT
+CFLINE_GRUB_BIN:=	select BUSYBOX_FEATURE_STAT_FORMAT\n\tdepends on !ADK_TARGET_ROOTFS_INITRAMFS_PIGGYBACK && !ADK_TARGET_ROOTFS_INITRAMFS
 
 include ${TOPDIR}/mk/package.mk
 

+ 4 - 5
package/grub/Makefile

@@ -4,10 +4,10 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=		grub
-PKG_VERSION:=		1.97.1
+PKG_VERSION:=		1.98
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		66fe18cd9318e3d67a34d7b7a8e7b1f6
-PKG_DESCR:=		GRand Unified Bootloader
+PKG_MD5SUM:=		c0bcf60e524739bb64e3a2d4e3732a59
+PKG_DESCR:=		GRUB2 bootloader (source package)
 PKG_SECTION:=		base
 PKG_URL:=		http://www.gnu.org/software/grub
 PKG_SITES:=		ftp://alpha.gnu.org/gnu/grub/
@@ -19,8 +19,7 @@ include $(TOPDIR)/mk/package.mk
 
 $(eval $(call PKG_template,GRUB,${PKG_NAME},$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
 
-CONFIGURE_ARGS+=	--disable-grub-emu \
-			--disable-efiemu \
+CONFIGURE_ARGS+=	--disable-efiemu \
 			--disable-grub-mkfont \
 			--disable-grub-fstest
 

+ 11 - 0
package/grub/patches/patch-conf_common_mk

@@ -0,0 +1,11 @@
+--- grub-1.98.orig/conf/common.mk	2010-03-06 21:52:26.000000000 +0100
++++ grub-1.98/conf/common.mk	2010-06-26 18:20:29.307157138 +0200
+@@ -11159,7 +11159,7 @@ trigtables.c: gentrigtables
+ 	./gentrigtables > $@
+ DISTCLEANFILES += trigtables.c
+ gentrigtables: gentrigtables.c
+-	$(CC) -o $@ $^ $(CPPFLAGS) -lm
++	$(HOSTCC) -o $@ $^ $(CPPFLAGS) -lm
+ DISTCLEANFILES += gentrigtables
+ 
+ pkglib_MODULES += setjmp.mod

+ 11 - 0
package/grub/patches/patch-include_grub_i18n_h

@@ -0,0 +1,11 @@
+--- grub-1.98.orig/include/grub/i18n.h	2010-03-06 21:51:37.000000000 +0100
++++ grub-1.98/include/grub/i18n.h	2010-06-26 15:31:22.860562533 +0200
+@@ -25,7 +25,7 @@
+ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s);
+ 
+ /* NLS can be disabled through the configure --disable-nls option.  */
+-#if ENABLE_NLS
++#if defined(ENABLE_NLS)
+ 
+ # ifdef GRUB_UTIL
+ 

+ 3 - 3
package/grub/patches/patch-include_grub_misc_h

@@ -1,6 +1,6 @@
---- grub-1.97.1.orig/include/grub/misc.h	2009-11-09 16:48:16.000000000 +0100
-+++ grub-1.97.1/include/grub/misc.h	2009-11-29 12:07:10.920475755 +0100
-@@ -74,14 +74,6 @@ grub_strncat (char *dest, const char *sr
+--- grub-1.98.orig/include/grub/misc.h	2010-03-06 21:51:37.000000000 +0100
++++ grub-1.98/include/grub/misc.h	2010-06-26 18:54:44.075171713 +0200
+@@ -91,14 +91,6 @@ grub_strncat (char *dest, const char *sr
    return dest;
  }
  

+ 10 - 16
package/grub/patches/patch-kern_misc_c

@@ -1,6 +1,6 @@
---- grub-1.97.1.orig/kern/misc.c	2009-11-09 16:48:16.000000000 +0100
-+++ grub-1.97.1/kern/misc.c	2009-11-29 11:48:55.492463135 +0100
-@@ -51,23 +51,6 @@ grub_memmove (void *dest, const void *sr
+--- grub-1.98.orig/kern/misc.c	2010-03-06 21:51:37.000000000 +0100
++++ grub-1.98/kern/misc.c	2010-06-26 20:12:26.711214130 +0200
+@@ -64,23 +64,6 @@ grub_memmove (void *dest, const void *sr
    return dest;
  }
  
@@ -24,29 +24,23 @@
  char *
  grub_strcpy (char *dest, const char *src)
  {
-@@ -182,10 +165,6 @@ grub_memcmp (const void *s1, const void 
- 
-   return 0;
- }
--#ifndef APPLE_CC
--int memcmp (const void *s1, const void *s2, grub_size_t n)
--  __attribute__ ((alias ("grub_memcmp")));
--#endif
- 
- int
- grub_strcmp (const char *s1, const char *s2)
-@@ -467,10 +446,6 @@ grub_memset (void *s, int c, grub_size_t
+@@ -516,15 +499,6 @@ grub_memset (void *s, int c, grub_size_t
  
    return s;
  }
 -#ifndef APPLE_CC
 -void *memset (void *s, int c, grub_size_t n)
 -  __attribute__ ((alias ("grub_memset")));
+-#else
+-void *memset (void *s, int c, grub_size_t n)
+-{
+-  return grub_memset (s, c, n);
+-}
 -#endif
  
  grub_size_t
  grub_strlen (const char *s)
-@@ -1002,11 +977,6 @@ grub_abort (void)
+@@ -1053,11 +1027,6 @@ grub_abort (void)
    grub_exit ();
  }
  

+ 26 - 0
package/grub/patches/patch-kern_misc_c.orig

@@ -0,0 +1,26 @@
+--- grub-1.98.orig/kern/misc.c	2010-03-06 21:51:37.000000000 +0100
++++ grub-1.98/kern/misc.c	2010-06-26 19:44:00.999168677 +0200
+@@ -64,23 +64,6 @@ grub_memmove (void *dest, const void *sr
+   return dest;
+ }
+ 
+-#ifndef APPLE_CC
+-void *memmove (void *dest, const void *src, grub_size_t n)
+-  __attribute__ ((alias ("grub_memmove")));
+-/* GCC emits references to memcpy() for struct copies etc.  */
+-void *memcpy (void *dest, const void *src, grub_size_t n)
+-  __attribute__ ((alias ("grub_memmove")));
+-#else
+-void *memcpy (void *dest, const void *src, grub_size_t n)
+-{
+-	return grub_memmove (dest, src, n);
+-}
+-void *memmove (void *dest, const void *src, grub_size_t n)
+-{
+-	return grub_memmove (dest, src, n);
+-}
+-#endif
+-
+ char *
+ grub_strcpy (char *dest, const char *src)
+ {

+ 29 - 0
package/grub/patches/patch-lib_libgcrypt-grub_cipher_camellia_c

@@ -0,0 +1,29 @@
+--- grub-1.98.orig/lib/libgcrypt-grub/cipher/camellia.c	2010-03-06 21:52:26.000000000 +0100
++++ grub-1.98/lib/libgcrypt-grub/cipher/camellia.c	2010-06-26 20:49:20.915278106 +0200
+@@ -26,6 +26,7 @@
+  */
+ 
+ 
++#include <grub/misc.h>
+ #include "camellia.h"
+ 
+ /* u32 must be 32bit word */
+@@ -946,13 +947,13 @@ void camellia_setup192(const unsigned ch
+     unsigned char kk[32];
+     u32 krll, krlr, krrl,krrr;
+ 
+-    memcpy(kk, key, 24);
+-    memcpy((unsigned char *)&krll, key+16,4);
+-    memcpy((unsigned char *)&krlr, key+20,4);
++    grub_memcpy(kk, key, 24);
++    grub_memcpy((unsigned char *)&krll, key+16,4);
++    grub_memcpy((unsigned char *)&krlr, key+20,4);
+     krrl = ~krll;
+     krrr = ~krlr;
+-    memcpy(kk+24, (unsigned char *)&krrl, 4);
+-    memcpy(kk+28, (unsigned char *)&krrr, 4);
++    grub_memcpy(kk+24, (unsigned char *)&krrl, 4);
++    grub_memcpy(kk+28, (unsigned char *)&krrr, 4);
+     camellia_setup256(kk, subkey);
+     return;
+ }

+ 21 - 0
package/grub/patches/patch-lib_libgcrypt-grub_cipher_camellia_c.orig

@@ -0,0 +1,21 @@
+--- grub-1.98.orig/lib/libgcrypt-grub/cipher/camellia.c	2010-03-06 21:52:26.000000000 +0100
++++ grub-1.98/lib/libgcrypt-grub/cipher/camellia.c	2010-06-26 20:41:39.651169327 +0200
+@@ -946,13 +946,13 @@ void camellia_setup192(const unsigned ch
+     unsigned char kk[32];
+     u32 krll, krlr, krrl,krrr;
+ 
+-    memcpy(kk, key, 24);
+-    memcpy((unsigned char *)&krll, key+16,4);
+-    memcpy((unsigned char *)&krlr, key+20,4);
++    grub_memcpy(kk, key, 24);
++    grub_memcpy((unsigned char *)&krll, key+16,4);
++    grub_memcpy((unsigned char *)&krlr, key+20,4);
+     krrl = ~krll;
+     krrr = ~krlr;
+-    memcpy(kk+24, (unsigned char *)&krrl, 4);
+-    memcpy(kk+28, (unsigned char *)&krrr, 4);
++    grub_memcpy(kk+24, (unsigned char *)&krrl, 4);
++    grub_memcpy(kk+28, (unsigned char *)&krrr, 4);
+     camellia_setup256(kk, subkey);
+     return;
+ }

+ 11 - 0
package/grub/patches/patch-lib_libgcrypt-grub_cipher_des_c

@@ -0,0 +1,11 @@
+--- grub-1.98.orig/lib/libgcrypt-grub/cipher/des.c	2010-03-06 21:52:26.000000000 +0100
++++ grub-1.98/lib/libgcrypt-grub/cipher/des.c	2010-06-26 20:35:49.335279651 +0200
+@@ -119,7 +119,7 @@
+ #include "cipher.h"
+ 
+ #if defined(__GNUC__) && defined(__GNU_LIBRARY__)
+-#define working_memcmp memcmp
++#define working_memcmp grub_memcmp
+ #else
+ /*
+  * According to the SunOS man page, memcmp returns indeterminate sign

+ 29 - 0
package/grub/patches/patch-lib_libgcrypt-grub_cipher_dsa_c

@@ -0,0 +1,29 @@
+--- grub-1.98.orig/lib/libgcrypt-grub/cipher/dsa.c	2010-03-06 21:52:26.000000000 +0100
++++ grub-1.98/lib/libgcrypt-grub/cipher/dsa.c	2010-06-26 20:41:13.511279436 +0200
+@@ -157,7 +157,7 @@ gen_k( gcry_mpi_t q )
+ 	     to get_random_bytes() and use this the here maybe it is
+ 	     easier to do this directly in random.c. */
+           char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
+-          memcpy( rndbuf,pp, 4 );
++          grub_memcpy( rndbuf,pp, 4 );
+           gcry_free(pp);
+ 	}
+       _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
+@@ -337,7 +337,7 @@ generate (DSA_secret_key *sk, unsigned i
+       else 
+         { /* Change only some of the higher bits (= 2 bytes)*/
+           char *r = gcry_random_bytes_secure (2, random_level);
+-          memcpy(rndbuf, r, 2 );
++          grub_memcpy(rndbuf, r, 2 );
+           gcry_free(r);
+         }
+ 
+@@ -713,7 +713,7 @@ dsa_generate_ext (int algo, unsigned int
+               gcry_sexp_release (l1);
+               return GPG_ERR_INV_OBJ; /* No value or value too large.  */
+             }
+-          memcpy (buf, s, n);
++          grub_memcpy (buf, s, n);
+           buf[n] = 0;
+           qbits = (unsigned int)strtoul (buf, NULL, 0);
+           gcry_sexp_release (l1);

+ 20 - 0
package/grub/patches/patch-lib_libgcrypt-grub_cipher_elgamal_c

@@ -0,0 +1,20 @@
+--- grub-1.98.orig/lib/libgcrypt-grub/cipher/elgamal.c	2010-03-06 21:52:26.000000000 +0100
++++ grub-1.98/lib/libgcrypt-grub/cipher/elgamal.c	2010-06-26 20:40:56.115156639 +0200
+@@ -212,7 +212,7 @@ gen_k( gcry_mpi_t p, int small_k )
+              easier to do this directly in random.c Anyway, it is
+              highly inlikely that we will ever reach this code. */
+           char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
+-          memcpy( rndbuf, pp, 4 );
++          grub_memcpy( rndbuf, pp, 4 );
+           gcry_free(pp);
+ 	}
+       _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
+@@ -308,7 +308,7 @@ generate ( ELG_secret_key *sk, unsigned 
+             {
+               char *r = gcry_random_bytes_secure( 2,
+                                                   GCRY_VERY_STRONG_RANDOM );
+-              memcpy(rndbuf, r, 2 );
++              grub_memcpy(rndbuf, r, 2 );
+               gcry_free(r);
+             }
+ 	}

+ 11 - 0
package/grub/patches/patch-lib_libgcrypt-grub_cipher_md4_c

@@ -0,0 +1,11 @@
+--- grub-1.98.orig/lib/libgcrypt-grub/cipher/md4.c	2010-03-06 21:52:26.000000000 +0100
++++ grub-1.98/lib/libgcrypt-grub/cipher/md4.c	2010-06-26 20:24:28.691278909 +0200
+@@ -109,7 +109,7 @@ transform ( MD4_CONTEXT *ctx, const unsi
+       }
+   }
+ #else
+-  memcpy (in, data, 64);
++  grub_memcpy (in, data, 64);
+ #endif
+ 
+   /* Round 1.  */

Some files were not shown because too many files changed in this diff