Просмотр исходного кода

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

Waldemar Brodkorb 15 лет назад
Родитель
Сommit
7907e3ee73
100 измененных файлов с 16272 добавлено и 1294 удалено
  1. 3 0
      .gitignore
  2. 64 5
      Config.in
  3. 1 0
      README
  4. 4 2
      TODO
  5. 22 6
      mk/build.mk
  6. 0 20
      mk/cpu.mk
  7. 16 33
      mk/image.mk
  8. 3 12
      mk/kernel-build.mk
  9. 0 2
      mk/kernel.mk
  10. 1 1
      mk/mirrors.mk
  11. 83 6
      mk/modules.mk
  12. 3 2
      mk/package.mk
  13. 3 3
      mk/vars.mk
  14. 1 1
      package/6tunnel/Makefile
  15. 0 712
      package/Config.in
  16. 55 0
      package/DirectFB/Makefile
  17. 1 0
      package/DirectFB/files/DirectFB.conffiles
  18. 4 0
      package/DirectFB/files/directfbrc
  19. 2 1
      package/Makefile
  20. 35 7
      package/MesaLib/Makefile
  21. 14774 0
      package/MesaLib/patches/000-mesalib-xdemos.patch
  22. 12 0
      package/MesaLib/patches/patch-include_GL_internal_sarea_h
  23. 4 7
      package/adkinstall/Makefile
  24. 127 28
      package/adkinstall/src/adkinstall
  25. 1 1
      package/aiccu/Makefile
  26. 1 1
      package/aircrack-ng/Makefile
  27. 35 0
      package/alix-switch/Makefile
  28. 19 0
      package/alix-switch/files/alix-switch
  29. 27 0
      package/alix-switch/files/alix-switch.init
  30. 3 0
      package/alix-switch/files/alix-switch.postinst
  31. 108 0
      package/alix-switch/src/alix-switchd.c
  32. 18 3
      package/alsa-utils/Makefile
  33. 2 2
      package/alsa-utils/files/alsa-utils.postinst
  34. 7 3
      package/alsa-utils/files/amixer.init
  35. 1 1
      package/arpd/Makefile
  36. 1 1
      package/arpwatch/Makefile
  37. 10 4
      package/asterisk/Makefile
  38. 1 1
      package/atftp/Makefile
  39. 1 1
      package/aufs2-util/Makefile
  40. 1 1
      package/autoconf/Makefile
  41. 1 1
      package/automake/Makefile
  42. 1 1
      package/autossh/Makefile
  43. 3 3
      package/avahi/Makefile
  44. 1 1
      package/axtls/Makefile
  45. 1 1
      package/b43-firmware/Makefile
  46. 15 1
      package/base-files/Config.in.manual
  47. 24 11
      package/base-files/Makefile
  48. 1 1
      package/base-files/src/etc/ipkg.conf
  49. 2 2
      package/base-files/src/etc/network/if-pre-up.d/04-wireless
  50. 2 2
      package/base-files/src/etc/profile
  51. 1 2
      package/base-files/src/etc/shadow
  52. 2 1
      package/base-files/src/init
  53. 3 0
      package/base-files/src/sbin/adkupdate
  54. 1 1
      package/base-files/src/usr/share/udhcpc/default.script
  55. 4 4
      package/bind/Makefile
  56. 16 14
      package/binutils/Makefile
  57. 1 1
      package/bison/Makefile
  58. 1 1
      package/bitlbee/Makefile
  59. 1 1
      package/bridge-utils/Makefile
  60. 1 1
      package/busybox/Config.in.manual
  61. 16 10
      package/busybox/Makefile
  62. 1 1
      package/busybox/config/Config.in
  63. 35 6
      package/busybox/config/archival/Config.in
  64. 6 0
      package/busybox/config/console-tools/Config.in
  65. 1 1
      package/busybox/config/coreutils/Config.in
  66. 0 1
      package/busybox/config/editors/Config.in
  67. 39 0
      package/busybox/config/init/Config.in
  68. 1 1
      package/busybox/config/networking/Config.in
  69. 1 1
      package/busybox/config/shell/Config.in
  70. 10 2
      package/busybox/config/util-linux/Config.in
  71. 1 1
      package/busybox/files/crond.init
  72. 267 241
      package/busybox/patches/001-ipkg.patch
  73. 23 38
      package/busybox/patches/002-find-empty.patch
  74. 120 0
      package/busybox/patches/003-defaults-no.patch
  75. 23 0
      package/busybox/patches/004-wget-accept-long-opts.patch
  76. 15 10
      package/busybox/patches/patch-include_libbb_h
  77. 8 25
      package/busybox/patches/patch-include_platform_h
  78. 1 1
      package/bzip2/Makefile
  79. 1 1
      package/ca-certificates/Makefile
  80. 1 1
      package/ccid/Makefile
  81. 1 1
      package/cfgfs/Makefile
  82. 1 1
      package/chillispot/Makefile
  83. 1 1
      package/collectd/Makefile
  84. 3 4
      package/comgt/Makefile
  85. 34 0
      package/comgt/files/hsoauth.comgt
  86. 19 0
      package/comgt/files/hsoconnect.comgt
  87. 27 0
      package/comgt/files/hsodata.comgt
  88. 19 0
      package/comgt/files/hsodisconnect.comgt
  89. 14 0
      package/comgt/files/hsostatus.comgt
  90. 34 0
      package/comgt/files/waitready.comgt
  91. 2 1
      package/coreutils/Makefile
  92. 2 2
      package/cpio/Makefile
  93. 3 3
      package/cryptsetup/Makefile
  94. 0 17
      package/cryptsetup/patches/patch-lib_setup_c
  95. 1 1
      package/ctorrent/Makefile
  96. 1 1
      package/cups/Makefile
  97. 1 1
      package/curl/Makefile
  98. 1 1
      package/cutter/Makefile
  99. 1 1
      package/cxxtools/Makefile
  100. 1 1
      package/dansguardian/Makefile

+ 3 - 0
.gitignore

@@ -17,6 +17,7 @@ toolchain_build_*/
 .prereq_done
 .prereq_done
 .config*
 .config*
 .busyboxcfg
 .busyboxcfg
+.rebuild.*
 .defconfig
 .defconfig
 all.config
 all.config
 .cfg_*/
 .cfg_*/
@@ -28,6 +29,8 @@ config/*.o
 config/lxdialog/*.o
 config/lxdialog/*.o
 make.log
 make.log
 dl/
 dl/
+package/Config.in.auto*
+package/pkgconfigs.d/
 package/*/info.mk
 package/*/info.mk
 package/*/Config.in
 package/*/Config.in
 package/*/Config.in.lib
 package/*/Config.in.lib

+ 64 - 5
Config.in

@@ -17,6 +17,18 @@ config ADK_HAVE_DOT_CONFIG
 
 
 menu "ADK settings"
 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
 config ADK_DEVELSYSTEM
 	bool "Compile a ADK development system"
 	bool "Compile a ADK development system"
 	default n
 	default n
@@ -25,10 +37,11 @@ config ADK_DEVELSYSTEM
 	select BUSYBOX_INSTALL
 	select BUSYBOX_INSTALL
 	select BUSYBOX_MKTEMP
 	select BUSYBOX_MKTEMP
 	select BUSYBOX_UNZIP
 	select BUSYBOX_UNZIP
+	select BUSYBOX_RMDIR
 	select BUSYBOX_TAC
 	select BUSYBOX_TAC
 	select BUSYBOX_TEE
 	select BUSYBOX_TEE
-	select ADK_PACKAGE_AUTOCONF
-	select ADK_PACKAGE_AUTOMAKE
+	select BUSYBOX_WGET
+	select BUSYBOX_YES
 	select ADK_PACKAGE_BASH
 	select ADK_PACKAGE_BASH
 	select ADK_PACKAGE_BINUTILS
 	select ADK_PACKAGE_BINUTILS
 	select ADK_PACKAGE_BZIP2
 	select ADK_PACKAGE_BZIP2
@@ -44,7 +57,6 @@ config ADK_DEVELSYSTEM
 	select ADK_PACKAGE_GLIBC_DEV if ADK_TARGET_LIB_GLIBC
 	select ADK_PACKAGE_GLIBC_DEV if ADK_TARGET_LIB_GLIBC
 	select ADK_PACKAGE_LIBNCURSES
 	select ADK_PACKAGE_LIBNCURSES
 	select ADK_PACKAGE_LIBNCURSES_DEV
 	select ADK_PACKAGE_LIBNCURSES_DEV
-	select ADK_PACKAGE_LIBTOOL
 	select ADK_PACKAGE_M4
 	select ADK_PACKAGE_M4
 	select ADK_PACKAGE_MAKE
 	select ADK_PACKAGE_MAKE
 	select ADK_PACKAGE_MKSH
 	select ADK_PACKAGE_MKSH
@@ -53,7 +65,6 @@ config ADK_DEVELSYSTEM
 	select ADK_PACKAGE_MICROPERL
 	select ADK_PACKAGE_MICROPERL
 	select ADK_PACKAGE_TAR
 	select ADK_PACKAGE_TAR
 	select ADK_PACKAGE_TSORT
 	select ADK_PACKAGE_TSORT
-	select ADK_PACKAGE_WGET
 	select ADK_PACKAGE_ZLIB
 	select ADK_PACKAGE_ZLIB
 	select ADK_PACKAGE_ZLIB_DEV
 	select ADK_PACKAGE_ZLIB_DEV
 	select ADK_PACKAGE_XZ
 	select ADK_PACKAGE_XZ
@@ -136,4 +147,52 @@ endchoice
 endmenu
 endmenu
 
 
 source "target/Config.in"
 source "target/Config.in"
-source "package/Config.in"
+
+menu "Runtime configuration"
+
+config ADK_RUNTIME_HOSTNAME
+	string "hostname for the embedded system"
+	default "linux"
+	help
+	  Set your target hostname.
+
+config ADK_RUNTIME_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_RUNTIME_PASSWORD
+	string "root password for the embedded system"
+	default "linux123"
+	help
+	  Predefine the root password enabled in the built image.
+
+config ADK_RUNTIME_TIMEZONE
+	string "timezone for the embedded system"
+	default "Europe/Berlin"
+	help
+
+endmenu
+
+menu "Package selection"
+config ADK_ENABLE_IPV6
+	prompt "enable IPv6 globally"
+	boolean
+	default y
+	# FIXME: selecting stuff here is ugly, better fix package flavours to
+	#        support a symbol-value-based default (i.e., "default y if IPV6")
+	select ADK_PACKAGE_NFS_UTILS_WITH_TIRPC if ADK_PACKAGE_NFS_UTILS != n
+	help
+	  This enables IPv6 support in all related applications. Basically this
+	  just means passing --enable-ipv6 to the configure script, but the
+	  exception proves the rule. ;)
+
+source "package/Config.in.auto.global"
+source "package/Config.in.auto"
+endmenu
+
+menu "Kernel configuration"
+source "target/linux/Config.in"
+endmenu

+ 1 - 0
README

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

+ 4 - 2
TODO

@@ -1,4 +1,6 @@
-- add support for brcm 2.6
+- fix ARM OABI support
+- fix watchdog for alix1c (mfgpt timers problem)
+- convert global ipv6 to flavours
+- add support for brcm 2.6 (flash support)
 - macos x build
 - macos x build
 - help text for config/ needs adoption
 - help text for config/ needs adoption
-- fix watchdog for alix1c (mfgpt timers problem)

+ 22 - 6
mk/build.mk

@@ -16,6 +16,7 @@ DEFCONFIG=		ADK_DEVELSYSTEM=n \
 			ADK_MAKE_PARALLEL=y \
 			ADK_MAKE_PARALLEL=y \
 			ADK_MAKE_JOBS=4 \
 			ADK_MAKE_JOBS=4 \
 			ADK_FORCE_PARALLEL=n \
 			ADK_FORCE_PARALLEL=n \
+			ADK_PACKAGE_BZR=n \
 			ADK_PACKAGE_GRUB=n \
 			ADK_PACKAGE_GRUB=n \
 			ADK_PACKAGE_XORG_SERVER_WITH_DRI=n \
 			ADK_PACKAGE_XORG_SERVER_WITH_DRI=n \
 			ADK_PACKAGE_AUFS2_UTIL=n \
 			ADK_PACKAGE_AUFS2_UTIL=n \
@@ -28,6 +29,7 @@ DEFCONFIG=		ADK_DEVELSYSTEM=n \
 			ADK_PACKAGE_LIBHEIMDAL_CLIENT=n \
 			ADK_PACKAGE_LIBHEIMDAL_CLIENT=n \
 			BUSYBOX_BBCONFIG=n \
 			BUSYBOX_BBCONFIG=n \
 			BUSYBOX_SELINUX=n \
 			BUSYBOX_SELINUX=n \
+			BUSYBOX_INSTALL_NO_USR=n \
 			BUSYBOX_MODPROBE_SMALL=n \
 			BUSYBOX_MODPROBE_SMALL=n \
 			BUSYBOX_EJECT=n \
 			BUSYBOX_EJECT=n \
 			BUSYBOX_BUILD_LIBBUSYBOX=n \
 			BUSYBOX_BUILD_LIBBUSYBOX=n \
@@ -64,8 +66,17 @@ noconfig_targets:=	menuconfig \
 
 
 POSTCONFIG=		-@ \
 POSTCONFIG=		-@ \
 	if [ -f .config.old ];then \
 	if [ -f .config.old ];then \
-		if [ -f .busyboxcfg ];then \
-			rm .busyboxcfg; \
+		rebuild=0; \
+		if [ "$$(grep ^BUSYBOX .config|md5sum)" != "$$(grep ^BUSYBOX .config.old|md5sum)" ];then \
+			touch .rebuild.busybox;\
+			rebuild=1;\
+		fi; \
+		if [ "$$(grep ^ADK_RUNTIME_PASSWORD .config|md5sum)" != "$$(grep ^ADK_RUNTIME_PASSWORD .config.old|md5sum)" ];then \
+			touch .rebuild.base-files;\
+			rebuild=1;\
+		fi; \
+		if [ $$rebuild -eq 1 ];then \
+			cp .config .config.old; \
 		fi; \
 		fi; \
 	fi
 	fi
 
 
@@ -89,12 +100,12 @@ ${TOPDIR}/package/Depends.mk: ${TOPDIR}/.config $(wildcard ${TOPDIR}/package/*/M
 world: $(DISTDIR) $(BUILD_DIR) $(TARGET_DIR) $(PACKAGE_DIR) ${TOPDIR}/.ADK_HAVE_DOT_CONFIG
 world: $(DISTDIR) $(BUILD_DIR) $(TARGET_DIR) $(PACKAGE_DIR) ${TOPDIR}/.ADK_HAVE_DOT_CONFIG
 	${BASH} ${TOPDIR}/scripts/scan-pkgs.sh
 	${BASH} ${TOPDIR}/scripts/scan-pkgs.sh
 ifeq ($(ADK_NATIVE),y)
 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
 else
 ifeq ($(ADK_TOOLCHAIN_ONLY),y)
 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
 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
 endif
 endif
 
 
@@ -135,6 +146,9 @@ target/%: ${TOPDIR}/.ADK_HAVE_DOT_CONFIG
 toolchain/%: ${STAGING_DIR}
 toolchain/%: ${STAGING_DIR}
 	$(MAKE) -C toolchain $(patsubst toolchain/%,%,$@)
 	$(MAKE) -C toolchain $(patsubst toolchain/%,%,$@)
 
 
+tools/%:
+	$(MAKE) -C tools $(patsubst tools/%,%,$@)
+
 image:
 image:
 	$(MAKE) -C target image
 	$(MAKE) -C target image
 
 
@@ -163,7 +177,7 @@ newpackage:
 	$(SED) 's#@PKG@#$(PKG)#' $(TOPDIR)/package/$(PKG)/Makefile
 	$(SED) 's#@PKG@#$(PKG)#' $(TOPDIR)/package/$(PKG)/Makefile
 	$(SED) 's#@VER@#$(VER)#' $(TOPDIR)/package/$(PKG)/Makefile
 	$(SED) 's#@VER@#$(VER)#' $(TOPDIR)/package/$(PKG)/Makefile
 	@echo "Edit package/$(PKG)/Makefile to complete"
 	@echo "Edit package/$(PKG)/Makefile to complete"
-	@echo "Do not forget to add package to package/Config.in"
+	@echo "choose PKG_SECTION to add it to an existent submenu"  
 
 
 #############################################################
 #############################################################
 #
 #
@@ -471,10 +485,12 @@ bulkallmod:
 	done <${TOPDIR}/target/bulk.lst
 	done <${TOPDIR}/target/bulk.lst
 
 
 menu .menu: $(wildcard ${TOPDIR}/package/*/Makefile)
 menu .menu: $(wildcard ${TOPDIR}/package/*/Makefile)
+	@echo "Generating menu structure ..."
 	mksh $(TOPDIR)/package/pkgmaker
 	mksh $(TOPDIR)/package/pkgmaker
 	@:>.menu
 	@:>.menu
 
 
 dep:
 dep:
+	@echo "Generating dependencies ..."
 	mksh $(TOPDIR)/package/depmaker
 	mksh $(TOPDIR)/package/depmaker
 
 
 .PHONY: menu dep
 .PHONY: menu dep

+ 0 - 20
mk/cpu.mk

@@ -1,20 +0,0 @@
-# This file is part of the OpenADK project. OpenADK is copyrighted
-# material, please see the LICENCE file in the top-level directory.
-# 
-# optimization configure options for CPU features
-
-ifeq ($(ADK_TARGET),alix1c)
-CONFIGURE_CPU_OPTS:=	--disable-ssse3 \
-			--disable-sse \
-			--enable-amd3dnow \
-			--enable-amd3dnowext \
-			--enable-mmx \
-			--enable-mmx2
-else
-CONFIGURE_CPU_OPTS:=	--disable-ssse3 \
-			--disable-sse \
-			--disable-amd3dnow \
-			--disable-amd3dnowext \
-			--disable-mmx \
-			--disable-mmx2
-endif

+ 16 - 33
mk/image.mk

@@ -1,7 +1,7 @@
 # This file is part of the OpenADK project. OpenADK is copyrighted
 # This file is part of the OpenADK project. OpenADK is copyrighted
 # material, please see the LICENCE file in the top-level directory.
 # 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 
 # 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
 # root directory, do the same if make extra=/dir/to/extra is used
@@ -13,37 +13,6 @@ image-prepare-post:
 	rng=/dev/arandom; test -e $$rng || rng=/dev/urandom; \
 	rng=/dev/arandom; test -e $$rng || rng=/dev/urandom; \
 	    dd if=$$rng bs=512 count=1 >>${TARGET_DIR}/etc/.rnd 2>/dev/null; \
 	    dd if=$$rng bs=512 count=1 >>${TARGET_DIR}/etc/.rnd 2>/dev/null; \
 	    chmod 600 ${TARGET_DIR}/etc/.rnd
 	    chmod 600 ${TARGET_DIR}/etc/.rnd
-	@cd ${TARGET_DIR}; ls=; ln=; li=; x=1; md5sum $$(find . -type f) | \
-	    sed -e "s/*//" | \
-	    while read sum name; do \
-		inode=$$(ls -i "$$name"); \
-		echo "$$sum $${inode%% *} $$name"; \
-	    done | sort | while read sum inode name; do \
-		if [[ $$sum = $$ls ]]; then \
-			[[ $$li = $$inode ]] && continue; \
-			case $$x in \
-			1)	echo 'WARNING: duplicate files found' \
-				    'in filesystem! Please fix them.' >&2; \
-				echo -n "> $$ln "; \
-				;; \
-			2)	echo -n "> $$ln "; \
-				;; \
-			3)	echo -n ' '; \
-				;; \
-			esac; \
-			echo -n "$$name"; \
-			x=3; \
-		else \
-			case $$x in \
-			3)	echo; \
-				x=2; \
-				;; \
-			esac; \
-		fi; \
-		ls=$$sum; \
-		ln=$$name; \
-		li=$$inode; \
-	done
 	chmod 4511 ${TARGET_DIR}/bin/busybox
 	chmod 4511 ${TARGET_DIR}/bin/busybox
 	chmod 1777 ${TARGET_DIR}/tmp
 	chmod 1777 ${TARGET_DIR}/tmp
 	@if [ -d ${TARGET_DIR}/usr/share/fonts/X11 ];then \
 	@if [ -d ${TARGET_DIR}/usr/share/fonts/X11 ];then \
@@ -52,13 +21,27 @@ image-prepare-post:
 		done; \
 		done; \
 	fi
 	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) $(MAKE_TRACE)
+	$(TRACE) target/$(ADK_TARGET)-install-kernel-package
+	$(PKG_INSTALL) $(KERNEL_PKG) $(MAKE_TRACE)
+
 INITRAMFS=		${ADK_TARGET}-${ADK_LIBC}-${FS}
 INITRAMFS=		${ADK_TARGET}-${ADK_LIBC}-${FS}
 ROOTFSSQUASHFS=		${ADK_TARGET}-${ADK_LIBC}-${FS}.img
 ROOTFSSQUASHFS=		${ADK_TARGET}-${ADK_LIBC}-${FS}.img
 ROOTFSTARBALL=		${ADK_TARGET}-${ADK_LIBC}-${FS}+kernel.tar.gz
 ROOTFSTARBALL=		${ADK_TARGET}-${ADK_LIBC}-${FS}+kernel.tar.gz
 ROOTFSUSERTARBALL=	${ADK_TARGET}-${ADK_LIBC}-${FS}.tar.gz
 ROOTFSUSERTARBALL=	${ADK_TARGET}-${ADK_LIBC}-${FS}.tar.gz
 INITRAMFS_PIGGYBACK=	${ADK_TARGET}-${ADK_LIBC}-${FS}.cpio
 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 >$@
 	cd ${TARGET_DIR}; tar -cf - --owner=0 --group=0 . | gzip -n9 >$@
 
 
 ${BIN_DIR}/${ROOTFSUSERTARBALL}: ${TARGET_DIR}
 ${BIN_DIR}/${ROOTFSUSERTARBALL}: ${TARGET_DIR}

+ 3 - 12
mk/kernel-build.mk

@@ -3,11 +3,8 @@
 
 
 include $(TOPDIR)/rules.mk
 include $(TOPDIR)/rules.mk
 include $(TOPDIR)/mk/linux.mk
 include $(TOPDIR)/mk/linux.mk
-#include ${TOPDIR}/mk/buildhlp.mk
 include ${TOPDIR}/mk/kernel-vars.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:
 $(TOOLCHAIN_BUILD_DIR)/w-$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE)/linux-$(KERNEL_VERSION)/.patched:
 	$(TRACE) target/$(ADK_TARGET)-kernel-patch
 	$(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)
 	$(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 \
 		INSTALL_MOD_PATH=$(LINUX_BUILD_DIR)/modules \
 		modules_install $(MAKE_TRACE)
 		modules_install $(MAKE_TRACE)
 	$(TRACE) target/$(ADK_TARGET)-create-packages
 	$(TRACE) target/$(ADK_TARGET)-create-packages
-	$(MAKE) $(KERNEL_PKG) $(TARGETS) 
+ifneq ($(strip $(TARGETS)),)
+	$(MAKE) $(TARGETS)
+endif
 	touch -c $(LINUX_DIR)/vmlinux
 	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:
 prepare:
 compile: $(LINUX_DIR)/vmlinux
 compile: $(LINUX_DIR)/vmlinux
 install: compile
 install: compile

+ 0 - 2
mk/kernel.mk

@@ -1,7 +1,6 @@
 # This file is part of the OpenADK project. OpenADK is copyrighted
 # This file is part of the OpenADK project. OpenADK is copyrighted
 # material, please see the LICENCE file in the top-level directory.
 # material, please see the LICENCE file in the top-level directory.
 
 
-
 LINUX_KMOD_SUFFIX=ko
 LINUX_KMOD_SUFFIX=ko
 MODULES_SUBDIR := lib/modules/$(KERNEL_VERSION)
 MODULES_SUBDIR := lib/modules/$(KERNEL_VERSION)
 LINUX_BUILD_DIR := $(BUILD_DIR)/linux-$(ARCH)-$(ADK_TARGET)
 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)
 MODULES_DIR := $(LINUX_BUILD_DIR)/modules/$(MODULES_SUBDIR)
 TARGET_MODULES_DIR := $(LINUX_TARGET_DIR)/$(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)
 INSTALL_TARGETS:= $(KERNEL_PKG)
 NOINSTALL_TARGETS:=
 NOINSTALL_TARGETS:=
 TARGETS:=
 TARGETS:=

+ 1 - 1
mk/mirrors.mk

@@ -1,7 +1,7 @@
 # This file is part of the OpenADK project. OpenADK is copyrighted
 # This file is part of the OpenADK project. OpenADK is copyrighted
 # material, please see the LICENCE file in the top-level directory.
 # 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?=	\
 MASTER_SITE_OPENADK?=	\
 	http://www.openadk.org/distfiles/ \
 	http://www.openadk.org/distfiles/ \

+ 83 - 6
mk/modules.mk

@@ -4,6 +4,7 @@
 #
 #
 # Virtualization
 # Virtualization
 #
 #
+
 $(eval $(call KMOD_template,KVM,kvm,\
 $(eval $(call KMOD_template,KVM,kvm,\
 	$(MODULES_DIR)/kernel/arch/${ARCH}/kvm/kvm \
 	$(MODULES_DIR)/kernel/arch/${ARCH}/kvm/kvm \
 ,90))
 ,90))
@@ -16,10 +17,10 @@ $(eval $(call KMOD_template,KVM_INTEL,kvm-intel,\
 	$(MODULES_DIR)/kernel/arch/${ARCH}/kvm/kvm-intel \
 	$(MODULES_DIR)/kernel/arch/${ARCH}/kvm/kvm-intel \
 ,95))
 ,95))
 
 
-
 #
 #
 # Serial ATA devices
 # Serial ATA devices
 #
 #
+
 $(eval $(call KMOD_template,SATA_AHCI,sata-ahci,\
 $(eval $(call KMOD_template,SATA_AHCI,sata-ahci,\
 	$(MODULES_DIR)/kernel/drivers/ata/ahci \
 	$(MODULES_DIR)/kernel/drivers/ata/ahci \
 ,10))
 ,10))
@@ -27,6 +28,7 @@ $(eval $(call KMOD_template,SATA_AHCI,sata-ahci,\
 #
 #
 # Ethernet network devices
 # Ethernet network devices
 # 
 # 
+
 $(eval $(call KMOD_template,NE2K_PCI,ne2k-pci,\
 $(eval $(call KMOD_template,NE2K_PCI,ne2k-pci,\
 	$(MODULES_DIR)/kernel/drivers/net/8390 \
 	$(MODULES_DIR)/kernel/drivers/net/8390 \
 	$(MODULES_DIR)/kernel/drivers/net/ne2k-pci \
 	$(MODULES_DIR)/kernel/drivers/net/ne2k-pci \
@@ -52,10 +54,10 @@ $(eval $(call KMOD_template,SKY2,sky2,\
 	$(MODULES_DIR)/kernel/drivers/net/sky2 \
 	$(MODULES_DIR)/kernel/drivers/net/sky2 \
 ,20))
 ,20))
 
 
-
 # 
 # 
 # Wireless network devices
 # Wireless network devices
 #
 #
+
 $(eval $(call KMOD_template,MAC80211,mac80211,\
 $(eval $(call KMOD_template,MAC80211,mac80211,\
 	$(MODULES_DIR)/kernel/net/wireless/cfg80211 \
 	$(MODULES_DIR)/kernel/net/wireless/cfg80211 \
 	$(MODULES_DIR)/kernel/net/mac80211/mac80211 \
 	$(MODULES_DIR)/kernel/net/mac80211/mac80211 \
@@ -102,6 +104,7 @@ $(eval $(call KMOD_template,RT61PCI,rt61pci,\
 #
 #
 # Networking
 # Networking
 #
 #
+
 $(eval $(call KMOD_template,ATM,atm,\
 $(eval $(call KMOD_template,ATM,atm,\
 	$(MODULES_DIR)/kernel/net/atm/atm \
 	$(MODULES_DIR)/kernel/net/atm/atm \
 ,50))
 ,50))
@@ -170,6 +173,7 @@ $(eval $(call KMOD_template,BONDING,bonding,\
 #
 #
 # Traffic scheduling
 # Traffic scheduling
 #
 #
+
 $(eval $(call KMOD_template,NET_SCH_CBQ,net-sch-cbq,\
 $(eval $(call KMOD_template,NET_SCH_CBQ,net-sch-cbq,\
 	$(MODULES_DIR)/kernel/net/sched/sch_cbq \
 	$(MODULES_DIR)/kernel/net/sched/sch_cbq \
 ,40))
 ,40))
@@ -222,6 +226,7 @@ $(eval $(call KMOD_template,NET_SCH_INGRESS,net-sch-ingress,\
 #
 #
 # classifications
 # classifications
 #
 #
+
 $(eval $(call KMOD_template,NET_CLS_BASIC,net-cls-basic,\
 $(eval $(call KMOD_template,NET_CLS_BASIC,net-cls-basic,\
 	$(MODULES_DIR)/kernel/net/sched/cls_basic \
 	$(MODULES_DIR)/kernel/net/sched/cls_basic \
 ,40))
 ,40))
@@ -245,6 +250,7 @@ $(eval $(call KMOD_template,NET_CLS_U32,net-cls-u32,\
 #
 #
 # actions
 # actions
 #
 #
+
 $(eval $(call KMOD_template,NET_ACT_POLICE,net-act-police,\
 $(eval $(call KMOD_template,NET_ACT_POLICE,net-act-police,\
 	$(MODULES_DIR)/kernel/net/sched/act_police \
 	$(MODULES_DIR)/kernel/net/sched/act_police \
 ,45))
 ,45))
@@ -268,10 +274,15 @@ $(eval $(call KMOD_template,NET_ACT_PEDIT,net-act-pedit,\
 #
 #
 # IPsec 
 # IPsec 
 #
 #
+
 $(eval $(call KMOD_template,NET_KEY,net-key,\
 $(eval $(call KMOD_template,NET_KEY,net-key,\
 	$(MODULES_DIR)/kernel/net/key/af_key \
 	$(MODULES_DIR)/kernel/net/key/af_key \
 ,60))
 ,60))
 
 
+$(eval $(call KMOD_template,XFRM_USER,xfrm-user,\
+	$(MODULES_DIR)/kernel/net/xfrm/xfrm_user \
+,61))
+
 $(eval $(call KMOD_template,INET_AH,inet-ah,\
 $(eval $(call KMOD_template,INET_AH,inet-ah,\
 	$(MODULES_DIR)/kernel/net/ipv4/ah4 \
 	$(MODULES_DIR)/kernel/net/ipv4/ah4 \
 ,65))
 ,65))
@@ -300,9 +311,11 @@ $(eval $(call KMOD_template,INET_XFRM_MODE_BEET,inet-xfrm-mode-beet,\
 ##
 ##
 ## Filtering / Firewalling
 ## Filtering / Firewalling
 ##
 ##
+
 #
 #
 # Ethernet Bridging firewall
 # Ethernet Bridging firewall
 #
 #
+
 $(eval $(call KMOD_template,BRIDGE_NF_EBTABLES,bridge-nf-ebtables,\
 $(eval $(call KMOD_template,BRIDGE_NF_EBTABLES,bridge-nf-ebtables,\
 	$(MODULES_DIR)/kernel/net/bridge/netfilter/ebtables \
 	$(MODULES_DIR)/kernel/net/bridge/netfilter/ebtables \
 ,55))
 ,55))
@@ -342,6 +355,7 @@ $(eval $(call KMOD_template,BRIDGE_EBT_REDIRECT,bridge-ebt-redirect,\
 #
 #
 # Netfilter Core
 # Netfilter Core
 #
 #
+
 $(eval $(call KMOD_template,NETFILTER_XT_TARGET_CLASSIFY,netfiler-xt-target-classify,\
 $(eval $(call KMOD_template,NETFILTER_XT_TARGET_CLASSIFY,netfiler-xt-target-classify,\
 	$(MODULES_DIR)/kernel/net/netfilter/xt_CLASSIFY \
 	$(MODULES_DIR)/kernel/net/netfilter/xt_CLASSIFY \
 ,50))
 ,50))
@@ -369,6 +383,7 @@ $(eval $(call KMOD_template,NETFILTER_XT_TARGET_NOTRACK,netfilter-xt-target-notr
 #
 #
 # IP: Netfilter
 # IP: Netfilter
 #
 #
+
 $(eval $(call KMOD_template,NF_CONNTRACK,nf-conntrack,\
 $(eval $(call KMOD_template,NF_CONNTRACK,nf-conntrack,\
 	$(MODULES_DIR)/kernel/net/netfilter/nf_conntrack \
 	$(MODULES_DIR)/kernel/net/netfilter/nf_conntrack \
 ,45))
 ,45))
@@ -480,6 +495,7 @@ $(eval $(call KMOD_template,IP_NF_MATCH_MULTIPORT,ip-nf-match-multiport,\
 #
 #
 # Filtering
 # Filtering
 #
 #
+
 $(eval $(call KMOD_template,IP_NF_FILTER,ip-nf-filter,\
 $(eval $(call KMOD_template,IP_NF_FILTER,ip-nf-filter,\
 	$(MODULES_DIR)/kernel/net/ipv4/netfilter/iptable_filter \
 	$(MODULES_DIR)/kernel/net/ipv4/netfilter/iptable_filter \
 ,55))
 ,55))
@@ -515,6 +531,7 @@ $(eval $(call KMOD_template,IP_NF_TARGET_NETMAP,ip-nf-target-netmap,\
 #
 #
 # Mangle
 # Mangle
 #
 #
+
 $(eval $(call KMOD_template,IP_NF_MANGLE,ip-nf-mangle,\
 $(eval $(call KMOD_template,IP_NF_MANGLE,ip-nf-mangle,\
 	$(MODULES_DIR)/kernel/net/ipv4/netfilter/iptable_mangle \
 	$(MODULES_DIR)/kernel/net/ipv4/netfilter/iptable_mangle \
 ,60))
 ,60))
@@ -534,6 +551,7 @@ $(eval $(call KMOD_template,IP_NF_TARGET_TTL,ip-nf-target-ttl,\
 #
 #
 # IPv6: Netfilter
 # IPv6: Netfilter
 #
 #
+
 $(eval $(call KMOD_template,NF_CONNTRACK_IPV6,nf-conntrack-ipv6,\
 $(eval $(call KMOD_template,NF_CONNTRACK_IPV6,nf-conntrack-ipv6,\
 	$(MODULES_DIR)/kernel/net/ipv6/netfilter/nf_conntrack_ipv6 \
 	$(MODULES_DIR)/kernel/net/ipv6/netfilter/nf_conntrack_ipv6 \
 ,50))
 ,50))
@@ -577,6 +595,7 @@ $(eval $(call KMOD_template,IP6_NF_TARGET_LOG,ip6-nf-target-log,\
 #
 #
 # IPv6: Filtering
 # IPv6: Filtering
 #
 #
+
 $(eval $(call KMOD_template,IP6_NF_FILTER,ip6-nf-filter,\
 $(eval $(call KMOD_template,IP6_NF_FILTER,ip6-nf-filter,\
 	$(MODULES_DIR)/kernel/net/ipv6/netfilter/ip6table_filter \
 	$(MODULES_DIR)/kernel/net/ipv6/netfilter/ip6table_filter \
 ,55))
 ,55))
@@ -588,6 +607,7 @@ $(eval $(call KMOD_template,IP6_NF_TARGET_REJECT,ip6-nf-target-reject,\
 #
 #
 # IPv6: Mangle
 # IPv6: Mangle
 #
 #
+
 $(eval $(call KMOD_template,IP6_NF_MANGLE,ip6-nf-mangle,\
 $(eval $(call KMOD_template,IP6_NF_MANGLE,ip6-nf-mangle,\
 	$(MODULES_DIR)/kernel/net/ipv6/netfilter/ip6table_mangle \
 	$(MODULES_DIR)/kernel/net/ipv6/netfilter/ip6table_mangle \
 ,60))
 ,60))
@@ -649,6 +669,7 @@ $(eval $(call KMOD_template,IP_VS_FTP,ip-vs-ftp,\
 #
 #
 # Block devices
 # Block devices
 #
 #
+
 $(eval $(call KMOD_template,BLK_DEV_LOOP,blk-dev-loop,\
 $(eval $(call KMOD_template,BLK_DEV_LOOP,blk-dev-loop,\
     $(MODULES_DIR)/kernel/drivers/block/loop \
     $(MODULES_DIR)/kernel/drivers/block/loop \
 ,20))
 ,20))
@@ -674,6 +695,7 @@ $(eval $(call KMOD_template,BLK_DEV_SR,blk-dev-sr,\
 #
 #
 # RAID
 # RAID
 #
 #
+
 $(eval $(call KMOD_template,BLK_DEV_MD,blk-dev-md,\
 $(eval $(call KMOD_template,BLK_DEV_MD,blk-dev-md,\
     $(MODULES_DIR)/kernel/drivers/md/md-mod \
     $(MODULES_DIR)/kernel/drivers/md/md-mod \
 ,30))
 ,30))
@@ -699,6 +721,7 @@ $(eval $(call KMOD_template,MD_RAID456,md-raid456,\
 #
 #
 # Device Mapper
 # Device Mapper
 #
 #
+
 $(eval $(call KMOD_template,BLK_DEV_DM,blk-dev-dm,\
 $(eval $(call KMOD_template,BLK_DEV_DM,blk-dev-dm,\
     $(MODULES_DIR)/kernel/drivers/md/dm-mod \
     $(MODULES_DIR)/kernel/drivers/md/dm-mod \
 ,35))
 ,35))
@@ -717,7 +740,6 @@ $(eval $(call KMOD_template,DM_SNAPSHOT,dm-snapshot,\
     $(MODULES_DIR)/kernel/drivers/md/dm-snapshot \
     $(MODULES_DIR)/kernel/drivers/md/dm-snapshot \
 ,40))
 ,40))
 
 
-
 #
 #
 # Crypto
 # Crypto
 #
 #
@@ -755,6 +777,10 @@ $(eval $(call KMOD_template,CRYPTO_MANAGER,crypto-manager,\
     $(MODULES_DIR)/kernel/crypto/chainiv \
     $(MODULES_DIR)/kernel/crypto/chainiv \
 ,07))
 ,07))
 
 
+$(eval $(call KMOD_template,CRYPTO_AUTHENC,crypto-authenc,\
+    $(MODULES_DIR)/kernel/crypto/authenc \
+,11))
+
 $(eval $(call KMOD_template,CRYPTO_HMAC,crypto-hmac,\
 $(eval $(call KMOD_template,CRYPTO_HMAC,crypto-hmac,\
     $(MODULES_DIR)/kernel/crypto/hmac \
     $(MODULES_DIR)/kernel/crypto/hmac \
 ,11))
 ,11))
@@ -791,6 +817,18 @@ $(eval $(call KMOD_template,CRYPTO_TGR192,crypto-tgr192,\
     $(MODULES_DIR)/kernel/crypto/tgr192 \
     $(MODULES_DIR)/kernel/crypto/tgr192 \
 ,11))
 ,11))
 
 
+$(eval $(call KMOD_template,CRYPTO_SEQIV,crypto-seqiv,\
+    $(MODULES_DIR)/kernel/crypto/seqiv \
+,5))
+
+$(eval $(call KMOD_template,CRYPTO_CTR,crypto-ctr,\
+    $(MODULES_DIR)/kernel/crypto/ctr \
+,10))
+
+$(eval $(call KMOD_template,CRYPTO_CCM,crypto-ccm,\
+    $(MODULES_DIR)/kernel/crypto/ccm \
+,10))
+
 $(eval $(call KMOD_template,CRYPTO_ECB,crypto-ecb,\
 $(eval $(call KMOD_template,CRYPTO_ECB,crypto-ecb,\
     $(MODULES_DIR)/kernel/crypto/ecb \
     $(MODULES_DIR)/kernel/crypto/ecb \
 ,10))
 ,10))
@@ -862,6 +900,7 @@ $(eval $(call KMOD_template,CRYPTO_FCRYPT,crypto-fcrypt,\
 
 
 $(eval $(call KMOD_template,CRYPTO_DEFLATE,crypto-deflate,\
 $(eval $(call KMOD_template,CRYPTO_DEFLATE,crypto-deflate,\
     $(MODULES_DIR)/kernel/lib/zlib_deflate/zlib_deflate \
     $(MODULES_DIR)/kernel/lib/zlib_deflate/zlib_deflate \
+    $(MODULES_DIR)/kernel/lib/zlib_inflate/zlib_inflate \
     $(MODULES_DIR)/kernel/crypto/deflate \
     $(MODULES_DIR)/kernel/crypto/deflate \
 ,10))
 ,10))
 
 
@@ -902,6 +941,7 @@ $(eval $(call KMOD_template,OCF_TALITOS,ocf-talitos,\
 #
 #
 # Filesystems
 # Filesystems
 #
 #
+
 $(eval $(call KMOD_template,AUFS_FS,aufs-fs,\
 $(eval $(call KMOD_template,AUFS_FS,aufs-fs,\
 	$(MODULES_DIR)/kernel/fs/aufs/aufs \
 	$(MODULES_DIR)/kernel/fs/aufs/aufs \
 ,30))
 ,30))
@@ -1001,6 +1041,7 @@ $(eval $(call KMOD_template,UDF_FS,udf-fs,\
 #
 #
 # Multimedia
 # Multimedia
 #
 #
+
 $(eval $(call KMOD_template,SOUND,sound,\
 $(eval $(call KMOD_template,SOUND,sound,\
 	$(MODULES_DIR)/kernel/sound/soundcore \
 	$(MODULES_DIR)/kernel/sound/soundcore \
 ,30))
 ,30))
@@ -1040,9 +1081,13 @@ $(eval $(call KMOD_template,SND_CS5535AUDIO,sound-cs5535audio,\
 	$(MODULES_DIR)/kernel/sound/pci/cs5535audio/snd-cs5535audio \
 	$(MODULES_DIR)/kernel/sound/pci/cs5535audio/snd-cs5535audio \
 ,55))
 ,55))
 
 
+V4L_COMPAT:=drivers/media/video/v4l1-compat
+ifeq ($(ADK_LINUX_64),y)
+V4L_COMPAT+=drivers/media/video/v4l2-compat-ioctl32
+endif
+
 $(eval $(call KMOD_template,VIDEO_DEV,video-dev,\
 $(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 \
+	$(foreach mod, $(V4L_COMPAT),$(MODULES_DIR)/kernel/$(mod)) \
 	$(MODULES_DIR)/kernel/drivers/media/video/videodev \
 	$(MODULES_DIR)/kernel/drivers/media/video/videodev \
 ,65))
 ,65))
 
 
@@ -1057,6 +1102,7 @@ $(eval $(call KMOD_template,PWC,pwc,\
 #
 #
 # PCMCIA/CardBus
 # PCMCIA/CardBus
 #
 #
+
 $(eval $(call KMOD_template,PCCARD,pccard,\
 $(eval $(call KMOD_template,PCCARD,pccard,\
 	$(MODULES_DIR)/kernel/drivers/pcmcia/pcmcia_core \
 	$(MODULES_DIR)/kernel/drivers/pcmcia/pcmcia_core \
 ,40))
 ,40))
@@ -1156,6 +1202,10 @@ $(eval $(call KMOD_template,USB_PEGASUS,usb-pegasus,\
 	$(MODULES_DIR)/kernel/drivers/net/usb/pegasus \
 	$(MODULES_DIR)/kernel/drivers/net/usb/pegasus \
 ,75))
 ,75))
 
 
+$(eval $(call KMOD_template,USB_HSO,usb-hso,\
+	$(MODULES_DIR)/kernel/drivers/net/usb/hso \
+,75))
+
 $(eval $(call KMOD_template,SND_USB_AUDIO,snd-usb-audio,\
 $(eval $(call KMOD_template,SND_USB_AUDIO,snd-usb-audio,\
 	$(MODULES_DIR)/kernel/sound/usb/snd-usb-lib \
 	$(MODULES_DIR)/kernel/sound/usb/snd-usb-lib \
 	$(MODULES_DIR)/kernel/sound/usb/snd-usb-audio \
 	$(MODULES_DIR)/kernel/sound/usb/snd-usb-audio \
@@ -1233,10 +1283,10 @@ $(eval $(call KMOD_template,NETFILTER_XT_TARGET_LED,netfilter-xt-target-led,\
 	$(MODULES_DIR)/kernel/net/netfilter/xt_LED \
 	$(MODULES_DIR)/kernel/net/netfilter/xt_LED \
 ,90))
 ,90))
 
 
-
 #
 #
 # NLS
 # NLS
 #
 #
+
 $(eval $(call KMOD_template,NLS,nls,\
 $(eval $(call KMOD_template,NLS,nls,\
 	$(MODULES_DIR)/kernel/fs/nls/nls_base \
 	$(MODULES_DIR)/kernel/fs/nls/nls_base \
 ,10))
 ,10))
@@ -1403,7 +1453,10 @@ $(eval $(call KMOD_template,NLS_UTF8,nls-utf8, \
 	$(MODULES_DIR)/kernel/fs/nls/nls_utf8 \
 	$(MODULES_DIR)/kernel/fs/nls/nls_utf8 \
 ,20))
 ,20))
 
 
+#
 # ISDN
 # ISDN
+#
+
 ISDN_MODULES=drivers/isdn/i4l/isdn
 ISDN_MODULES=drivers/isdn/i4l/isdn
 
 
 $(eval $(call KMOD_template,ISDN,isdn, \
 $(eval $(call KMOD_template,ISDN,isdn, \
@@ -1460,7 +1513,10 @@ $(eval $(call KMOD_template,MISDN_SPEEDFAX,misdn-speedfax, \
 	$(MODULES_DIR)/kernel/drivers/isdn/hardware/mISDN/sedlfax \
 	$(MODULES_DIR)/kernel/drivers/isdn/hardware/mISDN/sedlfax \
 ,80))
 ,80))
 
 
+#
 # Library modules
 # Library modules
+#
+
 $(eval $(call KMOD_template,CRC_CCITT,crc-ccitt, \
 $(eval $(call KMOD_template,CRC_CCITT,crc-ccitt, \
 	$(MODULES_DIR)/kernel/lib/crc-ccitt \
 	$(MODULES_DIR)/kernel/lib/crc-ccitt \
 ,01))
 ,01))
@@ -1483,6 +1539,7 @@ $(eval $(call KMOD_template,LIBCRC32C,libcrc32c, \
 
 
 #
 #
 # parallel port support
 # parallel port support
+#
 
 
 $(eval $(call KMOD_template,LP,lp,\
 $(eval $(call KMOD_template,LP,lp,\
 	$(MODULES_DIR)/kernel/drivers/char/lp \
 	$(MODULES_DIR)/kernel/drivers/char/lp \
@@ -1499,3 +1556,23 @@ $(eval $(call KMOD_template,PARPORT,parport,\
 $(eval $(call KMOD_template,PLIP,plip,\
 $(eval $(call KMOD_template,PLIP,plip,\
 	$(MODULES_DIR)/kernel/drivers/net/plip \
 	$(MODULES_DIR)/kernel/drivers/net/plip \
 ,51))
 ,51))
+
+#
+# Profiling
+#
+$(eval $(call KMOD_template,OPROFILE,oprofile,\
+	$(MODULES_DIR)/kernel/arch/x86/oprofile/oprofile \
+,10))
+
+#
+# I2C
+#
+$(eval $(call KMOD_template,I2C,i2c,\
+	$(MODULES_DIR)/kernel/drivers/i2c/i2c-core \
+	$(MODULES_DIR)/kernel/drivers/i2c/i2c-dev \
+,20))
+
+$(eval $(call KMOD_template,SCx200_ACB,scx200-acb,\
+	$(MODULES_DIR)/kernel/drivers/i2c/busses/scx200_acb \
+,25))
+

+ 3 - 2
mk/package.mk

@@ -143,6 +143,7 @@ ALL_PKGOPTS+=	$(1)
 PKGNAME_$(1)=	$(2)
 PKGNAME_$(1)=	$(2)
 PKGDEPS_$(1)=	$(4)
 PKGDEPS_$(1)=	$(4)
 PKGDESC_$(1)=	$(5)
 PKGDESC_$(1)=	$(5)
+PKGSECT_$(1)=	$(6)
 IPKG_$(1)=	$(PACKAGE_DIR)/$(2)_$(3)_${CPU_ARCH}.${PKG_SUFFIX}
 IPKG_$(1)=	$(PACKAGE_DIR)/$(2)_$(3)_${CPU_ARCH}.${PKG_SUFFIX}
 IDIR_$(1)=	$(WRKDIR)/fake-${CPU_ARCH}/pkg-$(2)
 IDIR_$(1)=	$(WRKDIR)/fake-${CPU_ARCH}/pkg-$(2)
 ifneq (${ADK_PACKAGE_$(1)}${DEVELOPER},)
 ifneq (${ADK_PACKAGE_$(1)}${DEVELOPER},)
@@ -160,7 +161,7 @@ IDEPEND_$(1):=	$$(strip $(4))
 _ALL_CONTROLS+=	$$(IDIR_$(1))/CONTROL/control
 _ALL_CONTROLS+=	$$(IDIR_$(1))/CONTROL/control
 ICONTROL_$(1)?=	$(WRKDIR)/.$(2).control
 ICONTROL_$(1)?=	$(WRKDIR)/.$(2).control
 $$(IDIR_$(1))/CONTROL/control: ${_PATCH_COOKIE}
 $$(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 "Section: $(6)" >> $(WRKDIR)/.$(2).control
 	@echo "Description: $(5)" >> $(WRKDIR)/.$(2).control
 	@echo "Description: $(5)" >> $(WRKDIR)/.$(2).control
 	${BASH} ${SCRIPT_DIR}/make-ipkg-dir.sh $${IDIR_$(1)} $${ICONTROL_$(1)} $(3) ${CPU_ARCH}
 	${BASH} ${SCRIPT_DIR}/make-ipkg-dir.sh $${IDIR_$(1)} $${ICONTROL_$(1)} $(3) ${CPU_ARCH}
@@ -177,7 +178,7 @@ $$(IDIR_$(1))/CONTROL/control: ${_PATCH_COOKIE}
 			comma=", "; \
 			comma=", "; \
 			last=$$$$dep; \
 			last=$$$$dep; \
 		done; \
 		done; \
-		echo "Depends: $$$$deps" >>$${IDIR_$(1)}/CONTROL/control; \
+		echo "Depends: $$$$deps" | tr '_' '-' >>$${IDIR_$(1)}/CONTROL/control; \
 	fi
 	fi
 	@for file in conffiles preinst postinst prerm postrm; do \
 	@for file in conffiles preinst postinst prerm postrm; do \
 		[ ! -f ./files/$(2).$$$$file ] || cp ./files/$(2).$$$$file $$(IDIR_$(1))/CONTROL/$$$$file; \
 		[ ! -f ./files/$(2).$$$$file ] || cp ./files/$(2).$$$$file $$(IDIR_$(1))/CONTROL/$$$$file; \

+ 3 - 3
mk/vars.mk

@@ -37,8 +37,8 @@ PACKAGE_DIR:=		$(BIN_DIR)/packages
 TARGET_DIR:=		$(BASE_DIR)/root_${ADK_TARGET}_${ADK_LIBC}
 TARGET_DIR:=		$(BASE_DIR)/root_${ADK_TARGET}_${ADK_LIBC}
 TARGET_DIR_PFX:=	$(BASE_DIR)/root_*
 TARGET_DIR_PFX:=	$(BASE_DIR)/root_*
 TARGET_PATH=		${SCRIPT_DIR}:${STAGING_TOOLS}/bin:${STAGING_DIR}/scripts:${_PATH}
 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
 TOOLCHAIN_SYSROOT:=	$(TOOLCHAIN_BUILD_DIR)/libc_dev
 ifeq ($(ADK_NATIVE),y) 
 ifeq ($(ADK_NATIVE),y) 
 TARGET_CROSS:=		
 TARGET_CROSS:=		
@@ -127,6 +127,6 @@ QUIET:=
 else
 else
 QUIET:=			--quiet
 QUIET:=			--quiet
 endif
 endif
-FETCH_CMD?=		wget -t1 --timeout=30 $(QUIET)
+FETCH_CMD?=		wget --tries=1 --timeout=30 $(QUIET)
 
 
 include $(TOPDIR)/mk/mirrors.mk
 include $(TOPDIR)/mk/mirrors.mk

+ 1 - 1
package/6tunnel/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		0.11rc2
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		74e02d4f0704b3083a01feda66033449
 PKG_MD5SUM:=		74e02d4f0704b3083a01feda66033449
 PKG_DESCR:=		IPv4/IPv6 tunnel proxy
 PKG_DESCR:=		IPv4/IPv6 tunnel proxy
-PKG_SECTION:=		net
+PKG_SECTION:=		ipv6
 PKG_DEPENDS:=		kmod-ipv6
 PKG_DEPENDS:=		kmod-ipv6
 PKG_URL:=		http://toxygen.net/6tunnel/
 PKG_URL:=		http://toxygen.net/6tunnel/
 PKG_SITES:=		http://toxygen.net/6tunnel/
 PKG_SITES:=		http://toxygen.net/6tunnel/

+ 0 - 712
package/Config.in

@@ -1,712 +0,0 @@
-# This file is part of the OpenADK project. OpenADK is copyrighted
-# material, please see the LICENCE file in the top-level directory.
-
-menu "Package selection"
-
-config ADK_ENABLE_IPV6
-	prompt "enable IPv6 globally"
-	boolean
-	default y
-	# FIXME: selecting stuff here is ugly, better fix package flavours to
-	#        support a symbol-value-based default (i.e., "default y if IPV6")
-	select ADK_PACKAGE_NFS_UTILS_WITH_TIRPC if ADK_PACKAGE_NFS_UTILS != n
-	help
-	  This enables IPv6 support in all related applications. Basically this
-	  just means passing --enable-ipv6 to the configure script, but the
-	  exception proves the rule. ;)
-
-menu "Basesystem"
-source "package/adkinstall/Config.in"
-source "package/base-files/Config.in"
-source "package/base-files/Config.in.manual"
-source "package/busybox/Config.in.manual"
-source "package/cfgfs/Config.in"
-source "package/cryptinit/Config.in"
-source "package/uclibc/Config.in.manual"
-source "package/glibc/Config.in.manual"
-source "package/eglibc/Config.in.manual"
-source "package/libc/Config.in.manual"
-source "package/grub/Config.in"
-source "package/grub-bin/Config.in"
-source "package/rpm/Config.in"
-endmenu
-
-menu "Bluetooth"
-source "package/bluez-firmware/Config.in"
-source "package/bluez/Config.in"
-source "package/miax/Config.in"
-source "package/obexftp/Config.in"
-source "package/ussp-push/Config.in"
-endmenu
-
-menu "Browser / Editor / Pager"
-source "package/elinks/Config.in"
-source "package/less/Config.in"
-source "package/links/Config.in"
-source "package/lynx/Config.in"
-source "package/nano/Config.in"
-source "package/vim/Config.in"
-endmenu
-
-menu "Compression and Archivers"
-source "package/bzip2/Config.in"
-source "package/cpio/Config.in"
-source "package/tar/Config.in"
-source "package/xz/Config.in"
-endmenu
-
-menu "Cryptography"
-source "package/ccid/Config.in"
-source "package/cryptsetup/Config.in"
-source "package/gnupg/Config.in"
-source "package/gnutls/Config.in"
-source "package/heimdal/Config.in"
-source "package/krb5/Config.in"
-source "package/openct/Config.in"
-source "package/opensc/Config.in"
-source "package/openssl/Config.in"
-source "package/openssl-pkcs11/Config.in"
-source "package/pcsc-lite/Config.in"
-source "package/rng-tools/Config.in"
-endmenu
-
-menu "Debugging / Analyzing"
-source "package/exmap/Config.in"
-source "package/gdb/Config.in"
-source "package/gdbserver/Config.in"
-source "package/oprofile/Config.in"
-source "package/strace/Config.in"
-source "package/valgrind/Config.in"
-endmenu
-
-menu "DNS / DHCP"
-source "package/atftp/Config.in"
-source "package/avahi/Config.in"
-source "package/bind/Config.in"
-source "package/dhcp/Config.in"
-source "package/dhcp-forwarder/Config.in"
-source "package/dnsmasq/Config.in"
-source "package/ez-ipupdate/Config.in"
-source "package/maradns/Config.in"
-source "package/pdnsd/Config.in"
-source "package/updatedd/Config.in"
-endmenu
-
-menu "Filesystem / Blockdevice utilities"
-source "package/aufs2-util/Config.in"
-source "package/dosfstools/Config.in"
-source "package/e2fsprogs/Config.in"
-source "package/fuse/Config.in"
-source "package/mdadm/Config.in"
-source "package/mtd/Config.in"
-source "package/nand/Config.in"
-source "package/lvm/Config.in"
-source "package/parted/Config.in"
-source "package/util-linux-ng/Config.in"
-source "package/wdfs/Config.in"
-source "package/xfsprogs/Config.in"
-endmenu
-
-menu "Firewall / Routing / Bridging"
-source "package/arpd/Config.in"
-source "package/bridge-utils/Config.in"
-source "package/linux-atm/Config.in"
-source "package/conntrack-tools/Config.in"
-source "package/cutter/Config.in"
-source "package/ebtables/Config.in"
-source "package/ether-wake/Config.in"
-source "package/iproute2/Config.in"
-source "package/ipset/Config.in"
-source "package/iptables/Config.in"
-source "package/knock/Config.in"
-source "package/macchanger/Config.in"
-source "package/netstat-nat/Config.in"
-source "package/quagga/Config.in"
-source "package/ulogd/Config.in"
-source "package/shorewall-common/Config.in"
-source "package/shorewall-shell/Config.in"
-source "package/wol/Config.in"
-source "package/wondershaper/Config.in"
-source "package/vrrpd/Config.in"
-endmenu
-
-menu "HTTP / FTP"
-source "package/curl/Config.in"
-source "package/gatling/Config.in"
-source "package/lighttpd/Config.in"
-source "package/mini_httpd/Config.in"
-source "package/proftpd/Config.in"
-source "package/tntnet/Config.in"
-source "package/vsftpd/Config.in"
-source "package/wget/Config.in"
-source "package/wput/Config.in"
-endmenu
-
-menu "IPv6"
-source "package/6tunnel/Config.in"
-source "package/aiccu/Config.in"
-source "package/miredo/Config.in"
-source "package/mrd6/Config.in"
-source "package/ndisc/Config.in"
-source "package/radvd/Config.in"
-endmenu
-
-menu "IRC / ICQ / JABBER"
-source "package/bitlbee/Config.in"
-source "package/irssi/Config.in"
-source "package/miau/Config.in"
-source "package/reaim/Config.in"
-source "package/tmsnc/Config.in"
-endmenu
-
-menu "Libraries"
-source "package/alsa-lib/Config.in"
-source "package/apr/Config.in"
-source "package/apr-util/Config.in"
-source "package/atk/Config.in"
-source "package/avahi/Config.in.lib"
-source "package/axtls/Config.in.lib"
-source "package/bind/Config.in.lib"
-source "package/cairo/Config.in"
-source "package/cgilib/Config.in"
-source "package/curl/Config.in.lib"
-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/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/libao/Config.in"
-source "package/libao/Config.in.lib"
-source "package/libaudiofile/Config.in"
-source "package/libaudiofile/Config.in.lib"
-source "package/libart/Config.in"
-source "package/libart/Config.in.lib"
-source "package/linux-atm/Config.in.lib"
-source "package/libcli/Config.in"
-source "package/libcli/Config.in.lib"
-source "package/libdaemon/Config.in"
-source "package/libdaemon/Config.in.lib"
-source "package/libdb/Config.in"
-source "package/libdb/Config.in.lib"
-source "package/libdnet/Config.in"
-source "package/libdnet/Config.in.lib"
-source "package/libelf/Config.in"
-source "package/libelf/Config.in.lib"
-source "package/libevent/Config.in"
-source "package/libevent/Config.in.lib"
-source "package/libffi/Config.in"
-source "package/libffi/Config.in.lib"
-source "package/freeradius-client/Config.in.lib"
-source "package/expat/Config.in"
-source "package/expat/Config.in.lib"
-source "package/faad2/Config.in" 
-source "package/faad2/Config.in.lib" 
-source "package/flac/Config.in"
-source "package/flac/Config.in.lib"
-source "package/freetype/Config.in"
-source "package/freetype/Config.in.lib"
-source "package/libgcrypt/Config.in"
-source "package/libgcrypt/Config.in.lib"
-source "package/libgd/Config.in"
-source "package/libgd/Config.in.lib"
-source "package/gdbm/Config.in"
-source "package/gdbm/Config.in.lib"
-source "package/libgssglue/Config.in"
-source "package/libgssglue/Config.in.lib"
-source "package/gmp/Config.in" 
-source "package/gmp/Config.in.lib" 
-source "package/gnutls/Config.in.lib"
-source "package/libgpg-error/Config.in"
-source "package/libgpg-error/Config.in.lib"
-source "package/gsm/Config.in"
-source "package/gsm/Config.in.lib"
-source "package/libiconv/Config.in"
-source "package/libiconv/Config.in.lib"
-source "package/libid3tag/Config.in"
-source "package/libid3tag/Config.in.lib"
-source "package/libIDL/Config.in"
-source "package/libIDL/Config.in.lib"
-source "package/jpeg/Config.in"
-source "package/jpeg/Config.in.lib"
-source "package/krb5/Config.in.lib"
-source "package/lame/Config.in.lib"
-source "package/mpfr/Config.in"
-source "package/mysql/Config.in"
-source "package/mysql/Config.in.lib"
-source "package/libnotify/Config.in"
-source "package/libnotify/Config.in.lib"
-source "package/nspr/Config.in"
-source "package/nss/Config.in"
-source "package/libtool/Config.in.lib" 
-source "package/openldap/Config.in.lib"
-source "package/liblzo/Config.in"
-source "package/liblzo/Config.in.lib"
-source "package/libmad/Config.in"
-source "package/libmad/Config.in.lib"
-source "package/libmms/Config.in"
-source "package/libmms/Config.in.lib"
-source "package/ncurses/Config.in"  
-source "package/ncurses/Config.in.lib" 
-source "package/neon/Config.in"
-source "package/libnet/Config.in"
-source "package/libnet/Config.in.lib"
-source "package/libnetfilter_conntrack/Config.in"
-source "package/libnetfilter_conntrack/Config.in.lib"
-source "package/libnetfilter_log/Config.in"
-source "package/libnetfilter_log/Config.in.lib"
-source "package/libnetfilter_queue/Config.in"
-source "package/libnetfilter_queue/Config.in.lib"
-source "package/libnfsidmap/Config.in"
-source "package/libnfnetlink/Config.in"
-source "package/libnfnetlink/Config.in.lib"
-source "package/libnids/Config.in"
-source "package/libnids/Config.in.lib"
-source "package/libnl/Config.in"
-source "package/libnl/Config.in.lib"
-source "package/libogg/Config.in"
-source "package/libogg/Config.in.lib"
-source "package/libol/Config.in"
-source "package/libol/Config.in.lib"
-source "package/opencdk/Config.in"  
-source "package/opencdk/Config.in.lib"  
-source "package/obexftp/Config.in.lib"
-source "package/openobex/Config.in"
-source "package/libosip2/Config.in"
-source "package/libosip2/Config.in.lib"
-source "package/libp11/Config.in"
-source "package/libp11/Config.in.lib"
-source "package/libpcap/Config.in"
-source "package/libpcap/Config.in.lib"
-source "package/libpri/Config.in"
-source "package/libpri/Config.in.lib"
-source "package/lvm/Config.in.lib"
-source "package/pango/Config.in"
-source "package/pcre/Config.in"
-source "package/pcre/Config.in.lib"
-source "package/libpng/Config.in"
-source "package/libpng/Config.in.lib"
-source "package/popt/Config.in"
-source "package/popt/Config.in.lib"
-source "package/postgresql/Config.in"
-source "package/postgresql/Config.in.lib"
-source "package/libpthread/Config.in"
-source "package/libpthread/Config.in.lib"
-source "package/libthread_db/Config.in"
-source "package/libthread_db/Config.in.lib"
-source "package/readline/Config.in"
-source "package/readline/Config.in.lib"
-source "package/cyrus-sasl/Config.in"
-source "package/cyrus-sasl/Config.in.lib"
-source "package/sdl/Config.in"
-source "package/sdl/Config.in.lib"
-source "package/sdl-image/Config.in"
-source "package/sdl-image/Config.in.lib"
-source "package/net-snmp/Config.in.lib"
-source "package/speex/Config.in"
-source "package/speex/Config.in.lib"
-source "package/openssl/Config.in.lib"
-source "package/sqlite/Config.in.lib"
-source "package/librpcsecgss/Config.in"
-source "package/librpcsecgss/Config.in.lib"
-source "package/libshout/Config.in"
-source "package/libshout/Config.in.lib"
-source "package/libsigc++/Config.in"
-source "package/libsigc++/Config.in.lib"
-source "package/libstdcxx/Config.in"
-source "package/libstdcxx/Config.in.lib"
-source "package/libtasn1/Config.in"
-source "package/libtasn1/Config.in.lib"
-source "package/libtiff/Config.in"
-source "package/libtiff/Config.in.lib"
-source "package/libtirpc/Config.in"
-source "package/libtirpc/Config.in.lib"
-source "package/libtorrent/Config.in"
-source "package/libtorrent/Config.in.lib"
-source "package/libupnp/Config.in"
-source "package/libupnp/Config.in.lib"
-source "package/libusb/Config.in"
-source "package/libusb/Config.in.lib"
-source "package/libusb-compat/Config.in"
-source "package/libusb-compat/Config.in.lib"
-source "package/libvirt/Config.in"
-source "package/libvirt/Config.in.lib"
-source "package/libvorbis/Config.in"
-source "package/libvorbis/Config.in.lib"
-source "package/libvorbisidec/Config.in"
-source "package/libvorbisidec/Config.in.lib"
-source "package/tcp_wrappers/Config.in"
-source "package/tslib/Config.in"
-source "package/libxml2/Config.in"
-source "package/libxml2/Config.in.lib"
-source "package/libxslt/Config.in"
-source "package/libxslt/Config.in.lib"
-source "package/lua/Config.in.lib"
-source "package/uclibc++/Config.in.manual"
-source "package/zlib/Config.in"
-endmenu
-
-menu "Mail"
-source "package/bogofilter/Config.in"
-source "package/dovecot/Config.in"
-source "package/fetchmail/Config.in"
-source "package/mini_sendmail/Config.in"
-source "package/mutt/Config.in"
-source "package/procmail/Config.in"
-source "package/ssmtp/Config.in"
-source "package/vilistextum/Config.in"
-endmenu
-
-menu "Misc"
-source "package/collectd/Config.in"
-source "package/deco/Config.in"
-source "package/dialog/Config.in"
-source "package/digitemp/Config.in"
-source "package/gpm/Config.in"
-source "package/gpsd/Config.in"
-source "package/logrotate/Config.in"
-source "package/mc/Config.in"
-source "package/mgetty/Config.in"
-source "package/monit/Config.in"
-source "package/motion/Config.in"
-source "package/osiris/Config.in"
-source "package/rrdtool/Config.in"
-source "package/rrdcollect/Config.in"
-source "package/sane-backends/Config.in"
-source "package/screen/Config.in"
-source "package/scsi-spin/Config.in"
-source "package/ser2net/Config.in"
-source "package/sqlite/Config.in"
-source "package/syslog-ng/Config.in"
-endmenu
-
-menu "Multimedia"
-source "package/alsa-utils/Config.in"
-source "package/esound/Config.in"
-source "package/ffmpeg/Config.in"
-source "package/gmediaserver/Config.in"
-source "package/icecast/Config.in"
-source "package/lame/Config.in"
-source "package/madplay/Config.in"
-source "package/mpg123/Config.in"
-source "package/moc/Config.in"
-source "package/mpd/Config.in"
-source "package/mplayer/Config.in"
-source "package/mt-daapd/Config.in"
-source "package/palantir/Config.in"
-source "package/setpwc/Config.in"
-endmenu
-
-menu "Network - Analyze / Debugging / Monitoring"
-source "package/bwm/Config.in"
-source "package/dsniff/Config.in"
-source "package/ethtool/Config.in"
-source "package/fping/Config.in"
-source "package/fprobe/Config.in"
-source "package/fprobe-ulog/Config.in"
-source "package/httping/Config.in"
-source "package/iftop/Config.in"
-source "package/ipcad/Config.in"
-source "package/iperf/Config.in"
-source "package/iptraf/Config.in"
-source "package/mtr/Config.in"
-source "package/netperf/Config.in"
-source "package/nmap/Config.in"
-source "package/sipsak/Config.in"
-source "package/tcpdump/Config.in"
-source "package/tptest/Config.in"
-source "package/traceroute/Config.in"
-source "package/trafshow/Config.in"
-source "package/ttcp/Config.in"
-endmenu
-
-menu "Networking Misc"
-source "package/cups/Config.in"
-source "package/fakeidentd/Config.in"
-source "package/gkrellmd/Config.in"
-source "package/net-snmp/Config.in"
-# intentionally inserted here, as it depends on the above
-source "package/iptables-snmp/Config.in"
-source "package/nut/Config.in"
-source "package/openldap/Config.in"
-source "package/p910nd/Config.in"
-source "package/pipacs/Config.in"
-#source "package/pmacct/Config.in"
-source "package/portmap/Config.in"
-source "package/rarpd/Config.in"
-source "package/rpcbind/Config.in"
-source "package/rrs/Config.in"
-source "package/rsync/Config.in"
-source "package/shat/Config.in"
-source "package/socat/Config.in"
-source "package/udp-broadcast-relay/Config.in"
-source "package/vgp/Config.in"
-source "package/vnstat/Config.in"
-source "package/vtun/Config.in"
-source "package/wccpd/Config.in"
-source "package/xinetd/Config.in"
-endmenu
-
-menu "Network Filesystems"
-source "package/davfs2/Config.in"
-source "package/davfs2/Config.in.kernel"
-source "package/nfs-utils/Config.in"
-source "package/samba/Config.in"
-endmenu
-
-menu "Network Security"
-source "package/arpwatch/Config.in"
-source "package/autossh/Config.in"
-source "package/axtls/Config.in"
-source "package/ca-certificates/Config.in"
-source "package/dropbear/Config.in"
-source "package/httptunnel/Config.in"
-source "package/ipsec-tools/Config.in"
-source "package/l2tpns/Config.in"
-source "package/openssh/Config.in"
-source "package/openssh/Config.in.kerberos"
-source "package/openswan/Config.in"
-source "package/openvpn/Config.in"
-source "package/portsentry/Config.in"
-source "package/ptunnel/Config.in"
-source "package/scanlogd/Config.in"
-source "package/snort/Config.in"
-source "package/ssltunnel/Config.in"
-source "package/tinc/Config.in"
-source "package/vpnc/Config.in"
-endmenu
-
-menu "NTP"
-source "package/htpdate/Config.in"
-source "package/ntpclient/Config.in"
-source "package/openntpd/Config.in"
-source "package/rdate/Config.in"
-endmenu
-
-menu "P2P"
-source "package/ctorrent/Config.in"
-source "package/rtorrent/Config.in"
-endmenu
-
-menu "PPP / PPTP / RADIUS"
-source "package/freeradius-client/Config.in"
-source "package/freeradius-server/Config.in"
-source "package/ppp/Config.in"
-source "package/pptp/Config.in"
-source "package/pptpd/Config.in"
-source "package/rp-pppoe/Config.in"
-source "package/raddump/Config.in"
-endmenu
-
-menu "Proxy"
-source "package/dansguardian/Config.in"
-source "package/frickin/Config.in"
-source "package/igmpproxy/Config.in"
-source "package/parprouted/Config.in"
-source "package/privoxy/Config.in"
-source "package/siproxd/Config.in"
-source "package/squid/Config.in"
-source "package/srelay/Config.in"
-source "package/tinyproxy/Config.in"
-source "package/tor/Config.in"
-source "package/vnc-reflector/Config.in"
-endmenu
-
-menu "Programming / Languages"
-source "package/autoconf/Config.in"
-source "package/automake/Config.in"
-source "package/binutils/Config.in"
-source "package/bison/Config.in"
-source "package/diffutils/Config.in"
-source "package/flex/Config.in"
-source "package/gawk/Config.in"
-source "package/gcc/Config.in"
-source "package/gperf/Config.in"
-source "package/haserl/Config.in"
-source "package/jamvm/Config.in"
-source "package/libtool/Config.in"
-source "package/lua/Config.in"
-source "package/m4/Config.in"
-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"
-source "package/tcl/Config.in"
-endmenu
-
-menu "SCM"
-#source "package/bzr/Config.in"
-source "package/cvs/Config.in"
-source "package/git/Config.in"
-source "package/subversion/Config.in"
-endmenu
-
-menu "Shells"
-source "package/bash/Config.in"
-source "package/mksh/Config.in"
-source "package/tcsh/Config.in"
-source "package/zsh/Config.in"
-endmenu
-
-menu "Serial communications & terminal emulation"
-source "package/heyu/Config.in"
-source "package/lrzsz/Config.in"
-source "package/picocom/Config.in"
-source "package/serdisplib/Config.in"
-source "package/setserial/Config.in"
-endmenu
-
-menu "Telephony"
-source "package/asterisk/Config.in"
-source "package/opensips/Config.in"
-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"
-source "package/findutils/Config.in"
-source "package/grep/Config.in"
-source "package/hdparm/Config.in"
-source "package/usbutils/Config.in"
-source "package/patch/Config.in"
-source "package/pciutils/Config.in"
-source "package/pcmciautils/Config.in"
-source "package/procps/Config.in"
-source "package/sispmctl/Config.in"
-source "package/stress/Config.in"
-source "package/sysfsutils/Config.in"
-source "package/sysstat/Config.in"
-source "package/udev/Config.in"
-source "package/watchdog/Config.in"
-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"
-source "package/kismet/Config.in"
-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
-
-menu "X server and drivers"
-source "package/xorg-server/Config.in"
-source "package/xf86-video-cirrus/Config.in"
-source "package/xf86-video-geode/Config.in"
-source "package/xf86-video-fbdev/Config.in"
-source "package/xf86-video-intel/Config.in"
-source "package/xf86-video-siliconmotion/Config.in"
-source "package/xf86-input-mouse/Config.in"
-source "package/xf86-input-keyboard/Config.in"
-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/font-util/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"
-endmenu
-
-menu "X fonts"
-source "package/font-adobe-75dpi/Config.in"
-source "package/font-adobe-100dpi/Config.in"
-source "package/font-bitstream-75dpi/Config.in"
-source "package/font-bitstream-100dpi/Config.in"
-source "package/font-bitstream-type1/Config.in"
-source "package/font-bh-lucidatypewriter-75dpi/Config.in"
-source "package/font-bh-lucidatypewriter-100dpi/Config.in"
-source "package/font-bh-75dpi/Config.in"
-source "package/font-bh-100dpi/Config.in"
-source "package/font-bh-type1/Config.in"
-source "package/font-bh-ttf/Config.in"
-source "package/font-misc-misc/Config.in"
-source "package/font-xfree86-type1/Config.in"
-endmenu
-
-menu "X libraries"
-source "package/libdrm/Config.in"
-source "package/libdrm/Config.in.lib"
-source "package/libICE/Config.in"
-source "package/libICE/Config.in.lib"
-source "package/libSM/Config.in"
-source "package/libSM/Config.in.lib"
-source "package/libX11/Config.in"
-source "package/libX11/Config.in.lib"
-source "package/libXv/Config.in"
-source "package/libXv/Config.in.lib"
-source "package/libXdmcp/Config.in"
-source "package/libXdmcp/Config.in.lib"
-source "package/libXext/Config.in"
-source "package/libXext/Config.in.lib"
-source "package/libXfont/Config.in"
-source "package/libXfont/Config.in.lib"
-source "package/libfontenc/Config.in"
-source "package/libfontenc/Config.in.lib"
-source "package/libpciaccess/Config.in"
-source "package/libpciaccess/Config.in.lib"
-source "package/libxkbfile/Config.in"
-source "package/libxkbfile/Config.in.lib"
-source "package/libXau/Config.in"
-source "package/libXau/Config.in.lib"
-source "package/libXaw/Config.in"
-source "package/libXaw/Config.in.lib"
-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/libXt/Config.in"
-source "package/libXt/Config.in.lib"
-source "package/libXft/Config.in"
-source "package/libXft/Config.in.lib"
-source "package/libXxf86dga/Config.in"
-source "package/libXxf86dga/Config.in.lib"
-source "package/libXxf86vm/Config.in"
-source "package/libXxf86vm/Config.in.lib"
-source "package/MesaLib/Config.in"
-source "package/MesaLib/Config.in.lib"
-source "package/pixman/Config.in"
-source "package/xkbcomp/Config.in"
-source "package/xkeyboard-config/Config.in"
-endmenu
-endmenu
-
-menu "Kernel configuration"
-source "target/linux/Config.in"
-source "package/rtsp/Config.in"
-endmenu

+ 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

+ 2 - 1
package/Makefile

@@ -4,7 +4,6 @@
 # Main makefile for the packages
 # Main makefile for the packages
 
 
 include $(TOPDIR)/rules.mk
 include $(TOPDIR)/rules.mk
-include $(TOPDIR)/package/Depends.mk
 
 
 ifeq (${ADK_TARGET_LIB_GLIBC},y)
 ifeq (${ADK_TARGET_LIB_GLIBC},y)
 package-$(ADK_PACKAGE_GLIBC) += glibc
 package-$(ADK_PACKAGE_GLIBC) += glibc
@@ -26,6 +25,8 @@ endif
 package-$(ADK_PACKAGE_UCLIBCXX) += uclibc++
 package-$(ADK_PACKAGE_UCLIBCXX) += uclibc++
 endif
 endif
 
 
+include $(TOPDIR)/package/Depends.mk
+
 DOWNLOAD:=$(patsubst %,%-download,$(package-y) $(package-m))
 DOWNLOAD:=$(patsubst %,%-download,$(package-y) $(package-m))
 COMPILE_PACKAGES:=$(patsubst %,%-compile,$(package-y) $(package-m))
 COMPILE_PACKAGES:=$(patsubst %,%-compile,$(package-y) $(package-m))
 INSTALL_PACKAGES:=$(patsubst %,%-install,$(package-y))
 INSTALL_PACKAGES:=$(patsubst %,%-install,$(package-y))

+ 35 - 7
package/MesaLib/Makefile

@@ -10,27 +10,46 @@ PKG_MD5SUM:=		62e8e47cbd63741b4bbe634dcdc8a56a
 PKG_DESCR:=		MESA library
 PKG_DESCR:=		MESA library
 PKG_SECTION:=		libs
 PKG_SECTION:=		libs
 PKG_DEPENDS:=		libxdamage libxfixes libdrm
 PKG_DEPENDS:=		libxdamage libxfixes libdrm
-PKG_BUILDDEP+=		libXdamage libXfixes libXxf86vm libdrm 
+PKG_BUILDDEP+=		libXdamage libXfixes libXxf86vm libdrm
 PKG_BUILDDEP+=		dri2proto glproto expat
 PKG_BUILDDEP+=		dri2proto glproto expat
 PKG_URL:=		http://www.mesa3d.org/
 PKG_URL:=		http://www.mesa3d.org/
 PKG_SITES:=		ftp://ftp.freedesktop.org/pub/mesa/7.8.1/
 PKG_SITES:=		ftp://ftp.freedesktop.org/pub/mesa/7.8.1/
 
 
+PKG_DESCR_GLXINFO:=	Display various GLX information
+PKG_SECT_GLXINFO:=	x11/apps
+PKG_DESCR_GLXGEARS:=	Nice little OpenGL demo application
+PKG_SECT_GLXGEARS:=	x11/apps
+
 WRKDIST=		${WRKDIR}/Mesa-${PKG_VERSION}
 WRKDIST=		${WRKDIR}/Mesa-${PKG_VERSION}
 
 
 PKG_TARGET_DEPENDS:=  	ibmx40 lemote
 PKG_TARGET_DEPENDS:=  	ibmx40 lemote
+PKG_HOST_DEPENDS:=	!cygwin
 
 
 include $(TOPDIR)/mk/package.mk
 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,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 \
 CONFIGURE_ARGS+=	--disable-static \
 			--disable-gallium \
 			--disable-gallium \
 			--disable-glw \
 			--disable-glw \
 			--with-driver=dri \
 			--with-driver=dri \
-			--with-dri-drivers=i810 \
-			--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:
 pre-configure:
 	(cd ${WRKBUILD}; rm -rf config.{cache,status}; \
 	(cd ${WRKBUILD}; rm -rf config.{cache,status}; \
@@ -39,17 +58,26 @@ pre-configure:
 		--disable-glw \
 		--disable-glw \
 		--disable-gallium \
 		--disable-gallium \
 		--with-driver=xlib \
 		--with-driver=xlib \
-		--without-demos \
 	);
 	);
 	${MAKE} -C ${WRKBUILD}/src/glsl
 	${MAKE} -C ${WRKBUILD}/src/glsl
 	${MAKE} -C ${WRKBUILD}/src/glsl/apps
 	${MAKE} -C ${WRKBUILD}/src/glsl/apps
-	cp ${WRKBUILD}/src/glsl/apps/compile \
+	${CP} ${WRKBUILD}/src/glsl/apps/compile \
 		${STAGING_TOOLS}/bin
 		${STAGING_TOOLS}/bin
 	${MAKE} -C ${WRKBUILD}/src/glsl clean
 	${MAKE} -C ${WRKBUILD}/src/glsl clean
 
 
 post-install:
 post-install:
-	$(INSTALL_DIR) $(IDIR_MESALIB)/usr/lib
+	$(INSTALL_DIR) $(IDIR_MESALIB)/usr/lib/dri
 	$(CP) $(WRKINST)/usr/lib/libGL*.so* \
 	$(CP) $(WRKINST)/usr/lib/libGL*.so* \
 		$(IDIR_MESALIB)/usr/lib
 		$(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
 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

+ 4 - 7
package/adkinstall/Makefile

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

+ 127 - 28
package/adkinstall/src/adkinstall

@@ -1,38 +1,140 @@
 #!/bin/sh
 #!/bin/sh
 # installs a rootfs tar archive from OpenADK onto a Compact Flash disk
 # 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
 if [ -z $1 ];then
         printf "Please give your root tar archive as parameter\n"
         printf "Please give your root tar archive as parameter\n"
         exit 1
         exit 1
 fi
 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
 parted -s /dev/sda mklabel msdos
+check_exit
 sleep 2
 sleep 2
 maxsize=$(env LC_ALL=C parted /dev/sda -s unit cyl print |awk '/^Disk/ { print $3 }'|sed -e 's/cyl//')
 maxsize=$(env LC_ALL=C parted /dev/sda -s unit cyl print |awk '/^Disk/ { print $3 }'|sed -e 's/cyl//')
 rootsize=$(($maxsize-2))
 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
 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
 tar -C /mnt -xzpf $1
+check_exit
 chmod 1777 /mnt/tmp
 chmod 1777 /mnt/tmp
 chmod 4755 /mnt/bin/busybox
 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/ .*$//")
 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
 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
 cat << EOF > /mnt/boot/grub/grub.cfg
 set default=0
 set default=0
 set timeout=1
 set timeout=1
@@ -43,19 +145,16 @@ terminal_input serial
 menuentry "GNU/Linux (OpenADK)" {
 menuentry "GNU/Linux (OpenADK)" {
         insmod ext2
         insmod ext2
         set root=(hd0,1)
         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
 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
 umount /mnt
-printf "Successfully installed.\n"
+printf "Successfully installed. You can reboot now.\n"
 exit 0
 exit 0

+ 1 - 1
package/aiccu/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		20070115
 PKG_RELEASE:=		9
 PKG_RELEASE:=		9
 PKG_MD5SUM:=		c9bcc83644ed788e22a7c3f3d4021350
 PKG_MD5SUM:=		c9bcc83644ed788e22a7c3f3d4021350
 PKG_DESCR:=		SixXS Automatic IPv6 Connectivity Client Utility
 PKG_DESCR:=		SixXS Automatic IPv6 Connectivity Client Utility
-PKG_SECTION:=		net
+PKG_SECTION:=		ipv6
 PKG_DEPENDS:=		kmod-ipv6 libpthread
 PKG_DEPENDS:=		kmod-ipv6 libpthread
 PKG_URL:=		http://www.sixxs.net
 PKG_URL:=		http://www.sixxs.net
 PKG_SITES:=		http://www.sixxs.net/archive/sixxs/aiccu/unix/
 PKG_SITES:=		http://www.sixxs.net/archive/sixxs/aiccu/unix/

+ 1 - 1
package/aircrack-ng/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.1
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		f7a24ed8fad122c4187d06bfd6f998b4
 PKG_MD5SUM:=		f7a24ed8fad122c4187d06bfd6f998b4
 PKG_DESCR:=		set of tools for auditing wireless networks
 PKG_DESCR:=		set of tools for auditing wireless networks
-PKG_SECTION:=		net
+PKG_SECTION:=		wifi
 PKG_DEPENDS:=		libpthread libopenssl libpcap
 PKG_DEPENDS:=		libpthread libopenssl libpcap
 PKG_BUILDDEP+=		openssl libpcap
 PKG_BUILDDEP+=		openssl libpcap
 PKG_URL:=		http://www.aircrack-ng.org
 PKG_URL:=		http://www.aircrack-ng.org

+ 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:=		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;
+}

+ 18 - 3
package/alsa-utils/Makefile

@@ -5,26 +5,41 @@ include ${TOPDIR}/rules.mk
 
 
 PKG_NAME:=		alsa-utils
 PKG_NAME:=		alsa-utils
 PKG_VERSION:=		1.0.22
 PKG_VERSION:=		1.0.22
-PKG_RELEASE:=		2
+PKG_RELEASE:=		4
 PKG_MD5SUM:=		f7180316188552ee1e6759a03f1fe98d
 PKG_MD5SUM:=		f7180316188552ee1e6759a03f1fe98d
 PKG_DESCR:=		ALSA mixer utility
 PKG_DESCR:=		ALSA mixer utility
-PKG_SECTION:=		utils
+PKG_SECTION:=		multimedia
 PKG_DEPENDS:=		alsa-lib libpthread
 PKG_DEPENDS:=		alsa-lib libpthread
 PKG_BUILDDEP+=		alsa-lib
 PKG_BUILDDEP+=		alsa-lib
+ifeq (${ADK_PACKAGE_ALSA_UTILS_WITH_ALSAMIXER},y)
+PKG_BUILDDEP+=		ncurses
+endif
 PKG_URL:=		http://www.alsa-project.org
 PKG_URL:=		http://www.alsa-project.org
 PKG_SITES:=		ftp://ftp.task.gda.pl/pub/linux/misc/alsa/utils/ \
 PKG_SITES:=		ftp://ftp.task.gda.pl/pub/linux/misc/alsa/utils/ \
 			ftp://ftp.alsa-project.org/pub/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
 DISTFILES:=             ${PKG_NAME}-${PKG_VERSION}.tar.bz2
 
 
 include ${TOPDIR}/mk/package.mk
 include ${TOPDIR}/mk/package.mk
 
 
 $(eval $(call PKG_template,ALSA_UTILS,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
 $(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
 CONFIGURE_ARGS+=	--disable-alsamixer
+endif
 
 
 post-install:
 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/
 	${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
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 2 - 2
package/alsa-utils/files/alsa-utils.postinst

@@ -1,5 +1,5 @@
 #!/bin/sh
 #!/bin/sh
 . $IPKG_INSTROOT/etc/functions.sh
 . $IPKG_INSTROOT/etc/functions.sh
 add_rcconf amixer
 add_rcconf amixer
-add_rcconf amixer_volume amixer_volume "75%"
-add_rcconf amixer_mixer amixer_mixer "Master"
+add_rcconf amixer_volume amixer_volume "80%"
+add_rcconf amixer_mixer amixer_mixer "Master PCM"

+ 7 - 3
package/alsa-utils/files/amixer.init

@@ -10,11 +10,15 @@ autostart)
 	exec sh $0 start
 	exec sh $0 start
 	;;
 	;;
 start)
 start)
-	amixer set $amixer_mixer on
-	amixer set $amixer_mixer $amixer_volume
+	for mixer in $amixer_mixer; do
+		amixer set $mixer on
+		amixer set $mixer $amixer_volume
+	done
 	;;
 	;;
 stop)
 stop)
-	amixer set $amixer_mixer off
+	for mixer in $amixer_mixer; do
+		amixer set $mixer off
+	done
 	;;
 	;;
 restart)
 restart)
 	sh $0 stop
 	sh $0 stop

+ 1 - 1
package/arpd/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		0.2
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		e2911fa9de1b92ef50deda1489ae944d
 PKG_MD5SUM:=		e2911fa9de1b92ef50deda1489ae944d
 PKG_DESCR:=		Generates ARP responses for IP address ranges
 PKG_DESCR:=		Generates ARP responses for IP address ranges
-PKG_SECTION:=		net
+PKG_SECTION:=		route
 PKG_DEPENDS:=		libpcap libdnet libevent
 PKG_DEPENDS:=		libpcap libdnet libevent
 PKG_BUILDDEP+=		libpcap libdnet libevent
 PKG_BUILDDEP+=		libpcap libdnet libevent
 PKG_URL:=		http://niels.xtdnet.nl/honeyd/
 PKG_URL:=		http://niels.xtdnet.nl/honeyd/

+ 1 - 1
package/arpwatch/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		2.1a15
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		cebfeb99c4a7c2a6cee2564770415fe7
 PKG_MD5SUM:=		cebfeb99c4a7c2a6cee2564770415fe7
 PKG_DESCR:=		Ethernet monitor program
 PKG_DESCR:=		Ethernet monitor program
-PKG_SECTION:=		net
+PKG_SECTION:=		net/security
 PKG_DEPENDS:=		libpcap
 PKG_DEPENDS:=		libpcap
 PKG_BUILDDEP+=		libpcap
 PKG_BUILDDEP+=		libpcap
 PKG_URL:=		http://www-nrg.ee.lbl.gov
 PKG_URL:=		http://www-nrg.ee.lbl.gov

+ 10 - 4
package/asterisk/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.6.2.7
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		861f57ba43bfe05dc645e0679a260e41
 PKG_MD5SUM:=		861f57ba43bfe05dc645e0679a260e41
 PKG_DESCR:=		Open Source PBX
 PKG_DESCR:=		Open Source PBX
-PKG_SECTION:=		net
+PKG_SECTION:=		phone
 PKG_MULTI:=		1
 PKG_MULTI:=		1
 PKG_NOPARALLEL:=	1
 PKG_NOPARALLEL:=	1
 PKG_DEPENDS:=		libncurses libpthread libopenssl libcurl
 PKG_DEPENDS:=		libncurses libpthread libopenssl libcurl
@@ -22,6 +22,8 @@ endif
 PKG_URL:=		http://www.asterisk.org
 PKG_URL:=		http://www.asterisk.org
 PKG_SITES:=		http://downloads.asterisk.org/pub/telephony/asterisk/releases/
 PKG_SITES:=		http://downloads.asterisk.org/pub/telephony/asterisk/releases/
 
 
+PKG_TARGET_DEPENDS:=	!foxboard
+
 PKG_DESCR_CHAN_MGCP:=	Media Gateway Control Protocol implementation
 PKG_DESCR_CHAN_MGCP:=	Media Gateway Control Protocol implementation
 PKG_DESCR_CHAN_SKINNY:=	Skinny Client Control Protocol implementation
 PKG_DESCR_CHAN_SKINNY:=	Skinny Client Control Protocol implementation
 PKG_DESCR_CHAN_IAX2:=	Support for the Inter Asterisk Protocol
 PKG_DESCR_CHAN_IAX2:=	Support for the Inter Asterisk Protocol
@@ -121,7 +123,7 @@ MAKE_FLAGS+=		DESTDIR="$(WRKINST)" \
 ALL_TARGET:=		all install samples
 ALL_TARGET:=		all install samples
 
 
 pre-configure:
 pre-configure:
-	cd "$(WRKBUILD)/menuselect"; ./configure 
+	cd "$(WRKBUILD)/menuselect"; ./configure
 
 
 pre-build:
 pre-build:
 	$(MAKE) -C $(WRKBUILD)/menuselect
 	$(MAKE) -C $(WRKBUILD)/menuselect
@@ -174,6 +176,7 @@ do-install: ${SUB_INSTALLS-m} ${SUB_INSTALLS-y}
 		rm -f gtalk.conf ; \
 		rm -f gtalk.conf ; \
 		rm -f skinny.conf ; \
 		rm -f skinny.conf ; \
 		rm -f dundi.conf ; \
 		rm -f dundi.conf ; \
+		$(SED) '#^astdatadir = /var/#/usr/#' asterisk.conf ; \
 	)
 	)
 	${INSTALL_DATA} ./files/modules.conf $(IDIR_ASTERISK)/etc/asterisk/
 	${INSTALL_DATA} ./files/modules.conf $(IDIR_ASTERISK)/etc/asterisk/
 	$(SED) 's|/var/lib/asterisk|/usr/lib/asterisk|g' \
 	$(SED) 's|/var/lib/asterisk|/usr/lib/asterisk|g' \
@@ -191,8 +194,11 @@ asterisk-sounds-install:
 	${INSTALL_DIR} $(IDIR_ASTERISK_SOUNDS)/usr/lib/asterisk/sounds
 	${INSTALL_DIR} $(IDIR_ASTERISK_SOUNDS)/usr/lib/asterisk/sounds
 	$(CP) $(WRKBUILD)/sounds/* \
 	$(CP) $(WRKBUILD)/sounds/* \
 		$(IDIR_ASTERISK_SOUNDS)/usr/lib/asterisk/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:
 asterisk-voicemail-install:
 	${INSTALL_DIR} $(IDIR_ASTERISK_VOICEMAIL)/etc/asterisk
 	${INSTALL_DIR} $(IDIR_ASTERISK_VOICEMAIL)/etc/asterisk

+ 1 - 1
package/atftp/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		0.7
 PKG_RELEASE:=		2
 PKG_RELEASE:=		2
 PKG_MD5SUM:=		3b27365772d918050b2251d98a9c7c82
 PKG_MD5SUM:=		3b27365772d918050b2251d98a9c7c82
 PKG_DESCR:=		TFTP client
 PKG_DESCR:=		TFTP client
-PKG_SECTION:=		net
+PKG_SECTION:=		dhcp
 PKG_DEPENDS:=		libreadline libncurses
 PKG_DEPENDS:=		libreadline libncurses
 PKG_BUILDDEP+=		readline ncurses
 PKG_BUILDDEP+=		readline ncurses
 PKG_URL:=		http://freshmeat.net/projects/atftp
 PKG_URL:=		http://freshmeat.net/projects/atftp

+ 1 - 1
package/aufs2-util/Makefile

@@ -7,7 +7,7 @@ PKG_NAME:=		aufs2-util
 PKG_VERSION:=		130809
 PKG_VERSION:=		130809
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_DESCR:=		aufs2 utilities
 PKG_DESCR:=		aufs2 utilities
-PKG_SECTION:=		admin
+PKG_SECTION:=		fs
 PKG_URL:=		http://aufs.sf.net/
 PKG_URL:=		http://aufs.sf.net/
 PKG_HOST_DEPENDS:=	!cygwin !freebsd !openbsd !netbsd
 PKG_HOST_DEPENDS:=	!cygwin !freebsd !openbsd !netbsd
 
 

+ 1 - 1
package/autoconf/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		2.65
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		46cfb40e0babf4c64f8325f03da81c9b
 PKG_MD5SUM:=		46cfb40e0babf4c64f8325f03da81c9b
 PKG_DESCR:=		GNU autoconf
 PKG_DESCR:=		GNU autoconf
-PKG_SECTION:=		utils
+PKG_SECTION:=		lang
 PKG_URL:=		http://www.gnu.org/software/autoconf/
 PKG_URL:=		http://www.gnu.org/software/autoconf/
 PKG_SITES:=		${MASTER_SITE_GNU:=autoconf/}
 PKG_SITES:=		${MASTER_SITE_GNU:=autoconf/}
 PKG_OPTS:=		noscripts
 PKG_OPTS:=		noscripts

+ 1 - 1
package/automake/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.10
 PKG_RELEASE:=		3
 PKG_RELEASE:=		3
 PKG_MD5SUM:=		452163c32d061c53a7acc0e8c1b689ba
 PKG_MD5SUM:=		452163c32d061c53a7acc0e8c1b689ba
 PKG_DESCR:=		GNU automake
 PKG_DESCR:=		GNU automake
-PKG_SECTION:=		utils
+PKG_SECTION:=		lang
 PKG_DEPENDS:=		microperl
 PKG_DEPENDS:=		microperl
 PKG_URL:=		http://www.gnu.org/software/automake/
 PKG_URL:=		http://www.gnu.org/software/automake/
 PKG_SITES:=		${MASTER_SITE_GNU:=${PKG_NAME}/}
 PKG_SITES:=		${MASTER_SITE_GNU:=${PKG_NAME}/}

+ 1 - 1
package/autossh/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.4b
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		8f9aa006f6f69e912d3c2f504622d6f7
 PKG_MD5SUM:=		8f9aa006f6f69e912d3c2f504622d6f7
 PKG_DESCR:=		Automatically restart SSH sessions and tunnels
 PKG_DESCR:=		Automatically restart SSH sessions and tunnels
-PKG_SECTION:=		net
+PKG_SECTION:=		net/security
 PKG_DEPENDS:=		openssh-client
 PKG_DEPENDS:=		openssh-client
 PKG_URL:=		http://www.harding.motd.ca/autossh
 PKG_URL:=		http://www.harding.motd.ca/autossh
 PKG_SITES:=		http://www.harding.motd.ca/autossh/
 PKG_SITES:=		http://www.harding.motd.ca/autossh/

+ 3 - 3
package/avahi/Makefile

@@ -7,15 +7,15 @@ PKG_NAME:=		avahi
 PKG_VERSION:=		0.6.25
 PKG_VERSION:=		0.6.25
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		a83155a6e29e3988f07e5eea3287b21e
 PKG_MD5SUM:=		a83155a6e29e3988f07e5eea3287b21e
-PKG_DESCR:=		mDNS/DNS-SD (aka RendezVous/Bonjour/ZeroConf) daemon
-PKG_SECTION:=		net
+PKG_DESCR:=		mDNS daemon
+PKG_SECTION:=		dhcp
 PKG_DEPENDS:=		libavahi libdaemon libexpat gettext
 PKG_DEPENDS:=		libavahi libdaemon libexpat gettext
 PKG_BUILDDEP+=		libdaemon expat gdbm glib gettext
 PKG_BUILDDEP+=		libdaemon expat gdbm glib gettext
 PKG_URL:=		http://avahi.org
 PKG_URL:=		http://avahi.org
 PKG_SITES:=		http://avahi.org/download/
 PKG_SITES:=		http://avahi.org/download/
 
 
 PKG_DEPENDS_DNSCONFD:=	libavahi libdaemon avahi-daemon
 PKG_DEPENDS_DNSCONFD:=	libavahi libdaemon avahi-daemon
-PKG_DESCR_DNSCONFD:=	Unicast DNS server from mDNS/DNS-SD configuration daemon
+PKG_DESCR_DNSCONFD:=	DNS server from mDNS configuration daemon
 PKG_DESCR_LIB:=		DNS-SD over mDNS library
 PKG_DESCR_LIB:=		DNS-SD over mDNS library
 
 
 include ${TOPDIR}/mk/package.mk
 include ${TOPDIR}/mk/package.mk

+ 1 - 1
package/axtls/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.2.2
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		03471b5a5874e2ce86025f24b3fa0958
 PKG_MD5SUM:=		03471b5a5874e2ce86025f24b3fa0958
 PKG_DESCR:=		small embedded webserver
 PKG_DESCR:=		small embedded webserver
-PKG_SECTION:=		net
+PKG_SECTION:=		net/security
 PKG_DEPENDS:=		libaxtls
 PKG_DEPENDS:=		libaxtls
 PKG_URL:=		http://axtls.sourceforge.net
 PKG_URL:=		http://axtls.sourceforge.net
 PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=axtls/}
 PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=axtls/}

+ 1 - 1
package/b43-firmware/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.0
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		37c8d2c029a7e5b82f4433a6fa1e2ee5
 PKG_MD5SUM:=		37c8d2c029a7e5b82f4433a6fa1e2ee5
 PKG_DESCR:=		firmware for b43 wireless cards
 PKG_DESCR:=		firmware for b43 wireless cards
-PKG_SECTION:=		sys
+PKG_SECTION:=		wifi
 PKG_SITES:=		http://openadk.org/distfiles/
 PKG_SITES:=		http://openadk.org/distfiles/
 
 
 include ${TOPDIR}/mk/package.mk
 include ${TOPDIR}/mk/package.mk

+ 15 - 1
package/base-files/Config.in.manual

@@ -1,5 +1,19 @@
+config ADK_COMPILE_BASE_FILES
+	tristate
+	depends on ADK_PACKAGE_BASE_FILES
+	default n
+
+config ADK_PACKAGE_BASE_FILES
+	prompt "base-files............. basic filesystem structure and scripts"
+	tristate
+	default y if !ADK_TOOLCHAIN_ONLY
+	select ADK_COMPILE_BASE_FILES
+	depends on !ADK_TOOLCHAIN_ONLY
+	help
+	  basic filesystem structure and scripts
+
 config ADK_PACKAGE_CONFIG_IN_ETC
 config ADK_PACKAGE_CONFIG_IN_ETC
-	prompt ".config in /etc.................. include buildsystem configuration in image"
+	prompt ".config in /etc...... include buildsystem configuration in image"
 	bool
 	bool
 	depends on ADK_PACKAGE_BASE_FILES
 	depends on ADK_PACKAGE_BASE_FILES
 	default y if !ADK_TOOLCHAIN_ONLY
 	default y if !ADK_TOOLCHAIN_ONLY

+ 24 - 11
package/base-files/Makefile

@@ -6,9 +6,9 @@ include $(TOPDIR)/mk/rootfs.mk
 
 
 PKG_NAME:=		base-files
 PKG_NAME:=		base-files
 PKG_VERSION:=		1.0
 PKG_VERSION:=		1.0
-PKG_RELEASE:=		10
-PKG_DESCR:=		basic filesystem structure and scripts
+PKG_RELEASE:=		23
 PKG_SECTION:=		base
 PKG_SECTION:=		base
+PKG_DESCR:=		basic files and scripts
 
 
 WRKDIST=		${WRKDIR}/base-files
 WRKDIST=		${WRKDIR}/base-files
 NO_DISTFILES:=		1
 NO_DISTFILES:=		1
@@ -17,9 +17,6 @@ include $(TOPDIR)/mk/package.mk
 
 
 $(eval $(call PKG_template,BASE_FILES,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
 $(eval $(call PKG_template,BASE_FILES,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
 
 
-PKGDFLT_BASE_FILES=	y if !ADK_TOOLCHAIN_ONLY
-CFLINE_BASE_FILES:=	depends on !ADK_TOOLCHAIN_ONLY
-
 CONFIG_STYLE:=		manual
 CONFIG_STYLE:=		manual
 BUILD_STYLE:=		manual
 BUILD_STYLE:=		manual
 INSTALL_STYLE:=		manual
 INSTALL_STYLE:=		manual
@@ -31,12 +28,10 @@ do-install:
 ifeq (${ADK_TARGET_ROOTFS_NFSROOT},y)
 ifeq (${ADK_TARGET_ROOTFS_NFSROOT},y)
 	@-rm $(IDIR_BASE_FILES)/etc/network/interfaces
 	@-rm $(IDIR_BASE_FILES)/etc/network/interfaces
 endif
 endif
-ifeq (${ADK_TARGET_PACKAGE_IPKG},y)
 	$(SED) 's,@TARGET@,$(ADK_TARGET),g' $(IDIR_BASE_FILES)/etc/ipkg.conf
 	$(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/sh >${IDIR_BASE_FILES}/etc/shells
 	echo /bin/ash >>${IDIR_BASE_FILES}/etc/shells
 	echo /bin/ash >>${IDIR_BASE_FILES}/etc/shells
 ifneq (${ADK_PACKAGE_BASH},)
 ifneq (${ADK_PACKAGE_BASH},)
@@ -64,12 +59,30 @@ endif
 	mkdir -p $(IDIR_BASE_FILES)/usr/bin
 	mkdir -p $(IDIR_BASE_FILES)/usr/bin
 	chmod 755 $(IDIR_BASE_FILES)/lib/mdev/init
 	chmod 755 $(IDIR_BASE_FILES)/lib/mdev/init
 	chmod 600 $(IDIR_BASE_FILES)/etc/shadow
 	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
 	ln -sf ../proc/mounts $(IDIR_BASE_FILES)/etc/mtab
 	rm -rf $(IDIR_BASE_FILES)/var
 	rm -rf $(IDIR_BASE_FILES)/var
 	ln -sf tmp $(IDIR_BASE_FILES)/var
 	ln -sf tmp $(IDIR_BASE_FILES)/var
+	test -z $(ADK_RUNTIME_HOSTNAME) || \
+	    echo $(ADK_RUNTIME_HOSTNAME) > \
+	    $(IDIR_BASE_FILES)/etc/hostname
+	test -z $(ADK_RUNTIME_PASSWORD) || \
+	    $(SED) 's,\*NP\*,'"$$(${STAGING_TOOLS}/bin/mkcrypt \
+	    ${ADK_RUNTIME_PASSWORD}),g" $(IDIR_BASE_FILES)/etc/shadow
+	git log -1|head -1|sed -e 's#commit ##' \
+		> $(IDIR_BASE_FILES)/etc/adkversion
+	test -z $(ADK_TARGET) || \
+	    echo $(ADK_TARGET) > $(IDIR_BASE_FILES)/etc/adktarget
 ifneq (${ADK_PACKAGE_CONFIG_IN_ETC},)
 ifneq (${ADK_PACKAGE_CONFIG_IN_ETC},)
 	gzip -9c ${TOPDIR}/.config >$(IDIR_BASE_FILES)/etc/adkconfig.gz
 	gzip -9c ${TOPDIR}/.config >$(IDIR_BASE_FILES)/etc/adkconfig.gz
+	chmod 600 $(IDIR_BASE_FILES)/etc/adkconfig.gz
 endif
 endif
 
 
+rebuild:
+	@if [ -f ${TOPDIR}/.rebuild.${PKG_NAME} ];then \
+		rm ${WRKBUILD}/.build_done; \
+		rm ${TOPDIR}/.rebuild.${PKG_NAME}; \
+	fi
+
+fake: rebuild
+
 include ${TOPDIR}/mk/pkg-bottom.mk
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 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 root /
 dest ram /tmp
 dest ram /tmp

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

@@ -1,5 +1,4 @@
 #!/bin/sh 
 #!/bin/sh 
-#set -x
 set -e 
 set -e 
 
 
 [ "${IFACE%%[0-9]*}" = "wlan" ] || exit 0
 [ "${IFACE%%[0-9]*}" = "wlan" ] || exit 0
@@ -7,6 +6,7 @@ set -e
 [ "$IF_WIRELESS_SSID" ] || exit 1
 [ "$IF_WIRELESS_SSID" ] || exit 1
 [ "$IF_WIRELESS_CHANNEL" ] || exit 1
 [ "$IF_WIRELESS_CHANNEL" ] || exit 1
 [ "$IF_WIRELESS_HWMODE" ] || IF_WIRELESS_HWMODE=g
 [ "$IF_WIRELESS_HWMODE" ] || IF_WIRELESS_HWMODE=g
+[ "$IF_WIRELESS_EXTENSION" ] || IF_WIRELESS_EXTENSION=0
 
 
 wpa=0
 wpa=0
 wpa1=0
 wpa1=0
@@ -46,7 +46,7 @@ case "$IF_WIRELESS_MODE" in
 		echo "channel=$IF_WIRELESS_CHANNEL" >> /tmp/hostapd.conf
 		echo "channel=$IF_WIRELESS_CHANNEL" >> /tmp/hostapd.conf
 		echo "hw_mode=$IF_WIRELESS_HWMODE" >> /tmp/hostapd.conf
 		echo "hw_mode=$IF_WIRELESS_HWMODE" >> /tmp/hostapd.conf
 		echo "auth_algs=$sec" >> /tmp/hostapd.conf
 		echo "auth_algs=$sec" >> /tmp/hostapd.conf
-		[ $wpa -eq 0 ] && {
+		[ $wpa -eq 0 ] && [ $wpa1 -eq 0 ] && [ $wpa2 -eq 0 ] && {
 			logger -t hostap "using no security mechanism"
 			logger -t hostap "using no security mechanism"
 			echo "wpa=0" >> /tmp/hostapd.conf
 			echo "wpa=0" >> /tmp/hostapd.conf
 		}
 		}

+ 2 - 2
package/base-files/src/etc/profile

@@ -1,9 +1,9 @@
 export PATH=/bin:/sbin:/usr/bin:/usr/sbin
 export PATH=/bin:/sbin:/usr/bin:/usr/sbin
 export TERM=vt220
 export TERM=vt220
 if [[ $(id -u) = 0 ]]; then
 if [[ $(id -u) = 0 ]]; then
-	export PS1='# '
+	export PS1='`whoami`@`hostname`:`pwd` # '
 else
 else
-	export PS1='$ '
+	export PS1='`whoami`@`hostname`:`pwd` $ '
 fi
 fi
 cat /etc/banner 2>&-
 cat /etc/banner 2>&-
 [ -x /usr/bin/vim ] && alias vi=vim || alias vim=vi
 [ -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:::::
 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 -nt proc proc /proc
 mount -o nosuid,nodev,noexec -t sysfs sysfs /sys
 mount -o nosuid,nodev,noexec -t sysfs sysfs /sys
 [ ! -f /etc/notmpfs ] && {
 [ ! -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 size=${size}k
 	mount none /tmp -t tmpfs -o remount,nosuid,nodev,mode=1777
 	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() {
 prepare() {
 	cd /
 	cd /
 	if [ -x /sbin/cfgfs ];then
 	if [ -x /sbin/cfgfs ];then
+		pkill crond
 		umount -f /etc
 		umount -f /etc
+		check_exit
 	fi
 	fi
 	mount -o remount,rw /
 	mount -o remount,rw /
+	check_exit
 	if [ "$system" == "RB532" ];then
 	if [ "$system" == "RB532" ];then
 		mount -t yaffs2 /dev/mtdblock0 /boot
 		mount -t yaffs2 /dev/mtdblock0 /boot
 	elif [ "$system" == "AR7130" ];then
 	elif [ "$system" == "AR7130" ];then

+ 1 - 1
package/base-files/src/usr/share/udhcpc/default.script

@@ -4,7 +4,7 @@ if [[ -z $1 ]]; then
 	exit 1
 	exit 1
 fi
 fi
 
 
-RESOLV_CONF=/tmp/resolv.conf
+RESOLV_CONF=/etc/resolv.conf
 
 
 case $1 in
 case $1 in
 (deconfig)
 (deconfig)

+ 4 - 4
package/bind/Makefile

@@ -8,17 +8,17 @@ PKG_VERSION:=		9.7.0
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		c245b5d1aa0a4f53d9538faa1efe2c3f
 PKG_MD5SUM:=		c245b5d1aa0a4f53d9538faa1efe2c3f
 PKG_DESCR:=		popular DNS server
 PKG_DESCR:=		popular DNS server
-PKG_SECTION:=		net
+PKG_SECTION:=		dns
 PKG_DEPENDS:=		libopenssl libbind libxml2
 PKG_DEPENDS:=		libopenssl libbind libxml2
 PKG_BUILDDEP+=		openssl libxml2
 PKG_BUILDDEP+=		openssl libxml2
 PKG_URL:=		https://www.isc.org/software/bind
 PKG_URL:=		https://www.isc.org/software/bind
 PKG_SITES:=		ftp://ftp.isc.org/isc/bind9/${PKG_VERSION}/
 PKG_SITES:=		ftp://ftp.isc.org/isc/bind9/${PKG_VERSION}/
 
 
 PKG_DESCR_1:=		dynamic dns client (nsupdate utility)
 PKG_DESCR_1:=		dynamic dns client (nsupdate utility)
-PKG_DESCR_2:=		Support library for the bind tools and dns server/client
+PKG_DESCR_2:=		library for the bind software suite
 PKG_DESCR_3:=		rndc & rndc-confgen utilities
 PKG_DESCR_3:=		rndc & rndc-confgen utilities
-PKG_DESCR_4:=		named-checkconf & named-checkzone utilities
-PKG_DESCR_5:=		dnssec-keygen & dnssec-signzone utilities
+PKG_DESCR_4:=		check utilities
+PKG_DESCR_5:=		dnssec utilities
 PKG_DESCR_6:=		host utility
 PKG_DESCR_6:=		host utility
 PKG_DESCR_7:=		dig utility
 PKG_DESCR_7:=		dig utility
 
 

+ 16 - 14
package/binutils/Makefile

@@ -4,13 +4,21 @@
 include ${TOPDIR}/rules.mk
 include ${TOPDIR}/rules.mk
 include ${TOPDIR}/toolchain/binutils/Makefile.inc
 include ${TOPDIR}/toolchain/binutils/Makefile.inc
 
 
-PKG_DESCR:=		binary utilities (nm, objdump, ar, as, ..)
-PKG_SECTION:=		comp
+PKG_DESCR:=		binary utilities (nm, objdump, as, ..)
+PKG_SECTION:=		lang
+PKG_DEPENDS:=		libbfd
+
+# subpackage
+PKG_NAME_LIBBFD:=	libbfd
+PKG_DESCR_LIBBFD:=	bfd library
+PKG_SECTION_LIBBFD:=	libs
+
 PKG_HOST_DEPENDS:=      !cygwin
 PKG_HOST_DEPENDS:=      !cygwin
 
 
 include ${TOPDIR}/mk/package.mk
 include ${TOPDIR}/mk/package.mk
 
 
 $(eval $(call PKG_template,BINUTILS,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
 $(eval $(call PKG_template,BINUTILS,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION}))
+$(eval $(call PKG_template,LIBBFD,${PKG_NAME_LIBBFD},${PKG_VERSION}-${PKG_RELEASE},,${PKG_DESCR_LIBBFD},${PKG_SECTION_LIBBFD}))
 
 
 TCFLAGS+=		-fPIC
 TCFLAGS+=		-fPIC
 CONFIGURE_ARGS+=	--disable-werror \
 CONFIGURE_ARGS+=	--disable-werror \
@@ -18,18 +26,12 @@ CONFIGURE_ARGS+=	--disable-werror \
 			--target=$(REAL_GNU_TARGET_NAME)
 			--target=$(REAL_GNU_TARGET_NAME)
 
 
 post-install:
 post-install:
-	${INSTALL_DIR} ${IDIR_BINUTILS}/usr/lib
-	$(CP) ${WRKINST}/usr/lib/*.so ${IDIR_BINUTILS}/usr/lib
+	${INSTALL_DIR} ${IDIR_LIBBFD}/usr/lib
+	$(CP) ${WRKINST}/usr/lib/*.so ${IDIR_LIBBFD}/usr/lib
 	${INSTALL_DIR} ${IDIR_BINUTILS}/usr/bin
 	${INSTALL_DIR} ${IDIR_BINUTILS}/usr/bin
-	${INSTALL_BIN} ${WRKINST}/usr/bin/nm ${IDIR_BINUTILS}/usr/bin/
-	${INSTALL_BIN} ${WRKINST}/usr/bin/size ${IDIR_BINUTILS}/usr/bin/
-	${INSTALL_BIN} ${WRKINST}/usr/bin/ar ${IDIR_BINUTILS}/usr/bin/
-	${INSTALL_BIN} ${WRKINST}/usr/bin/as ${IDIR_BINUTILS}/usr/bin/
-	${INSTALL_BIN} ${WRKINST}/usr/bin/ld ${IDIR_BINUTILS}/usr/bin/
-	${INSTALL_BIN} ${WRKINST}/usr/bin/strip ${IDIR_BINUTILS}/usr/bin/
-	${INSTALL_BIN} ${WRKINST}/usr/bin/objdump ${IDIR_BINUTILS}/usr/bin/
-	${INSTALL_BIN} ${WRKINST}/usr/bin/objcopy ${IDIR_BINUTILS}/usr/bin/
-	${INSTALL_BIN} ${WRKINST}/usr/bin/ranlib ${IDIR_BINUTILS}/usr/bin/
-	${INSTALL_BIN} ${WRKINST}/usr/bin/readelf ${IDIR_BINUTILS}/usr/bin/
+	${INSTALL_BIN} ${WRKINST}/usr/bin/{ar,as,ld,strip,size,nm} \
+		${IDIR_BINUTILS}/usr/bin/
+	${INSTALL_BIN} ${WRKINST}/usr/bin/{objcopy,ranlib,readelf,objdump} \
+		 ${IDIR_BINUTILS}/usr/bin/
 
 
 include ${TOPDIR}/mk/pkg-bottom.mk
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 1 - 1
package/bison/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		2.4.1
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		c58aa1da418dc9704070872489e89bf5
 PKG_MD5SUM:=		c58aa1da418dc9704070872489e89bf5
 PKG_DESCR:=		GNU parser generator
 PKG_DESCR:=		GNU parser generator
-PKG_SECTION:=		utils
+PKG_SECTION:=		lang
 PKG_URL:=		http://www.gnu.org/software/bison
 PKG_URL:=		http://www.gnu.org/software/bison
 PKG_SITES:=		${MASTER_SITE_GNU:=${PKG_NAME}/}
 PKG_SITES:=		${MASTER_SITE_GNU:=${PKG_NAME}/}
 
 

+ 1 - 1
package/bitlbee/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.2.4
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		26b9bfc5446bdf0e932e8074d117be67
 PKG_MD5SUM:=		26b9bfc5446bdf0e932e8074d117be67
 PKG_DESCR:=		IRC gateway to IM chat networks
 PKG_DESCR:=		IRC gateway to IM chat networks
-PKG_SECTION:=		net
+PKG_SECTION:=		chat
 PKG_DEPENDS:=		glib libiconv libopenssl
 PKG_DEPENDS:=		glib libiconv libopenssl
 PKG_BUILDDEP+=		glib libiconv openssl
 PKG_BUILDDEP+=		glib libiconv openssl
 PKG_URL:=		http://www.bitlbee.org
 PKG_URL:=		http://www.bitlbee.org

+ 1 - 1
package/bridge-utils/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.4
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		0182fcac3a2b307113bbec34e5f1c673
 PKG_MD5SUM:=		0182fcac3a2b307113bbec34e5f1c673
 PKG_DESCR:=		Ethernet bridging tools
 PKG_DESCR:=		Ethernet bridging tools
-PKG_SECTION:=		net
+PKG_SECTION:=		bridge
 PKG_DEPENDS:=		kmod-bridge
 PKG_DEPENDS:=		kmod-bridge
 PKG_URL:=		http://www.linuxfoundation.org/en/Net:Bridge
 PKG_URL:=		http://www.linuxfoundation.org/en/Net:Bridge
 PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=bridge/}
 PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=bridge/}

+ 1 - 1
package/busybox/Config.in.manual

@@ -4,7 +4,7 @@ config ADK_COMPILE_BUSYBOX
 	default n
 	default n
 
 
 config ADK_PACKAGE_BUSYBOX
 config ADK_PACKAGE_BUSYBOX
-	prompt "busybox........................... Core utilities for embedded Linux systems"
+	prompt "busybox................ Core utilities for embedded systems"
 	boolean
 	boolean
 	select ADK_COMPILE_BUSYBOX
 	select ADK_COMPILE_BUSYBOX
 	default y if !ADK_TOOLCHAIN_ONLY
 	default y if !ADK_TOOLCHAIN_ONLY

+ 16 - 10
package/busybox/Makefile

@@ -4,12 +4,12 @@
 include $(TOPDIR)/rules.mk
 include $(TOPDIR)/rules.mk
 
 
 PKG_NAME:=		busybox
 PKG_NAME:=		busybox
-PKG_VERSION:=		1.16.1
-PKG_RELEASE:=		1
-PKG_MD5SUM:=		319486ec65078d07fde26eb620fecde7
-PKG_DESCR:=		Core utilities for embedded Linux systems
+PKG_VERSION:=		1.17.0
+PKG_RELEASE:=		3
+PKG_MD5SUM:=		2908d1d1ca83ff12bc0b05f0d2a3335c
+PKG_DESCR:=		Core utilities for embedded systems
 PKG_SECTION:=		base
 PKG_SECTION:=		base
-PKG_URL:=		http://www.busybox.net
+PKG_URL:=		http://www.busybox.net/
 PKG_SITES:=		http://www.busybox.net/downloads/
 PKG_SITES:=		http://www.busybox.net/downloads/
 
 
 DISTFILES:=		${PKG_NAME}-${PKG_VERSION}.tar.bz2
 DISTFILES:=		${PKG_NAME}-${PKG_VERSION}.tar.bz2
@@ -37,8 +37,8 @@ ${TOPDIR}/.busyboxcfg: ${TOPDIR}/.config
 ${WRKBUILD}/.config: ${TOPDIR}/.busyboxcfg
 ${WRKBUILD}/.config: ${TOPDIR}/.busyboxcfg
 	cp $(TOPDIR)/.busyboxcfg ${WRKBUILD}/.config
 	cp $(TOPDIR)/.busyboxcfg ${WRKBUILD}/.config
 	$(SED) 's;@IDIR@;${WRKINST};' ${WRKBUILD}/.config
 	$(SED) 's;@IDIR@;${WRKINST};' ${WRKBUILD}/.config
-	
-do-configure: $(TOPDIR)/.busyboxcfg ${WRKBUILD}/.config
+
+do-configure: ${WRKBUILD}/.config
 ifeq ($(ADK_NATIVE),y)
 ifeq ($(ADK_NATIVE),y)
 	yes '' | \
 	yes '' | \
 	$(MAKE) V=1 \
 	$(MAKE) V=1 \
@@ -51,7 +51,7 @@ else
 	    ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) oldconfig $(MAKE_TRACE)
 	    ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) oldconfig $(MAKE_TRACE)
 endif
 endif
 
 
-do-build: $(TOPDIR)/.busyboxcfg ${WRKBUILD}/.config
+do-build: do-configure
 ifeq ($(ADK_NATIVE),y)
 ifeq ($(ADK_NATIVE),y)
 	$(MAKE) V=1 \
 	$(MAKE) V=1 \
 	    IPKG_ARCH="$(CPU_ARCH)" ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) busybox
 	    IPKG_ARCH="$(CPU_ARCH)" ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) busybox
@@ -60,7 +60,7 @@ else
 	    IPKG_ARCH="$(CPU_ARCH)" ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) busybox
 	    IPKG_ARCH="$(CPU_ARCH)" ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) busybox
 endif
 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)
 ifeq ($(ADK_NATIVE),y)
 	$(MAKE) V=1 \
 	$(MAKE) V=1 \
 	    IPKG_ARCH="$(CPU_ARCH)" ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) install $(MAKE_TRACE)
 	    IPKG_ARCH="$(CPU_ARCH)" ARCH="$(ARCH)" HOSTCC="$(HOSTCC)" -C $(WRKBUILD) install $(MAKE_TRACE)
@@ -78,6 +78,12 @@ udhcpd-install:
 	${INSTALL_DIR} ${IDIR_UDHCPD}/etc/
 	${INSTALL_DIR} ${IDIR_UDHCPD}/etc/
 	${INSTALL_DATA} ./files/udhcpd.conf ${IDIR_UDHCPD}/etc/
 	${INSTALL_DATA} ./files/udhcpd.conf ${IDIR_UDHCPD}/etc/
 
 
-fake:	$(TOPDIR)/.busyboxcfg do-configure do-install
+rebuild:
+	@if [ -f ${TOPDIR}/.rebuild.${PKG_NAME} ];then \
+		rm ${WRKBUILD}/.build_done; \
+		rm ${TOPDIR}/.rebuild.${PKG_NAME}; \
+	fi
+
+fake: rebuild
 
 
 include ${TOPDIR}/mk/pkg-bottom.mk
 include ${TOPDIR}/mk/pkg-bottom.mk

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

@@ -119,7 +119,7 @@ config BUSYBOX_LOCALE_SUPPORT
 	  Enable this if your system has locale support and you would like
 	  Enable this if your system has locale support and you would like
 	  busybox to support locale settings.
 	  busybox to support locale settings.
 
 
-config BUSYBOX_FEATURE_ASSUME_UNICODE
+config BUSYBOX_UNICODE_SUPPORT
 	bool "Support Unicode"
 	bool "Support Unicode"
 	default n
 	default n
 	help
 	help

+ 35 - 6
package/busybox/config/archival/Config.in

@@ -63,6 +63,13 @@ config BUSYBOX_FEATURE_AR_LONG_FILENAMES
 	  It supports the GNU ar long filename method which moves multiple long
 	  It supports the GNU ar long filename method which moves multiple long
 	  filenames into a the data section of a new ar entry.
 	  filenames into a the data section of a new ar entry.
 
 
+config BUSYBOX_FEATURE_AR_CREATE
+	bool "Support archive creation"
+	default n
+	depends on BUSYBOX_AR
+	help
+	  This enables archive creation (-c and -r) with busybox ar.
+
 config BUSYBOX_BUNZIP2
 config BUSYBOX_BUNZIP2
 	bool "bunzip2"
 	bool "bunzip2"
 	depends on !ADK_PACKAGE_BZIP2
 	depends on !ADK_PACKAGE_BZIP2
@@ -93,8 +100,8 @@ config BUSYBOX_BZIP2
 
 
 config BUSYBOX_CPIO
 config BUSYBOX_CPIO
 	bool "cpio"
 	bool "cpio"
-	default n
 	depends on !ADK_PACKAGE_CPIO
 	depends on !ADK_PACKAGE_CPIO
+	default n
 	help
 	help
 	  cpio is an archival utility program used to create, modify, and
 	  cpio is an archival utility program used to create, modify, and
 	  extract contents from archives.
 	  extract contents from archives.
@@ -193,10 +200,8 @@ config BUSYBOX_LZOP_COMPR_HIGH
 
 
 config BUSYBOX_IPKG
 config BUSYBOX_IPKG
 	bool "ipkg"
 	bool "ipkg"
+	default y if ADK_TARGET_PACKAGE_IPKG
 	default n
 	default n
-	select BUSYBOX_MD5SUM
-	select BUSYBOX_WGET
-	depends on ADK_TARGET_PACKAGE_IPKG
 	help
 	help
 	  ipkg is the itsy package management system.
 	  ipkg is the itsy package management system.
 
 
@@ -251,7 +256,7 @@ config BUSYBOX_FEATURE_TAR_FROM
 
 
 config BUSYBOX_FEATURE_TAR_OLDGNU_COMPATIBILITY
 config BUSYBOX_FEATURE_TAR_OLDGNU_COMPATIBILITY
 	bool "Support for old tar header format"
 	bool "Support for old tar header format"
-	default N
+	default n
 	depends on BUSYBOX_TAR
 	depends on BUSYBOX_TAR
 	help
 	help
 	  This option is required to unpack archives created in
 	  This option is required to unpack archives created in
@@ -260,7 +265,7 @@ config BUSYBOX_FEATURE_TAR_OLDGNU_COMPATIBILITY
 
 
 config BUSYBOX_FEATURE_TAR_OLDSUN_COMPATIBILITY
 config BUSYBOX_FEATURE_TAR_OLDSUN_COMPATIBILITY
 	bool "Enable untarring of tarballs with checksums produced by buggy Sun tar"
 	bool "Enable untarring of tarballs with checksums produced by buggy Sun tar"
-	default N
+	default n
 	depends on BUSYBOX_TAR
 	depends on BUSYBOX_TAR
 	help
 	help
 	  This option is required to unpack archives created by some old
 	  This option is required to unpack archives created by some old
@@ -311,6 +316,7 @@ config BUSYBOX_UNCOMPRESS
 
 
 config BUSYBOX_UNLZMA
 config BUSYBOX_UNLZMA
 	bool "unlzma"
 	bool "unlzma"
+	depends on !ADK_PACKAGE_XZ
 	default n
 	default n
 	help
 	help
 	  unlzma is a compression utility using the Lempel-Ziv-Markov chain
 	  unlzma is a compression utility using the Lempel-Ziv-Markov chain
@@ -332,6 +338,29 @@ config BUSYBOX_FEATURE_LZMA_FAST
 	  This option reduces decompression time by about 25% at the cost of
 	  This option reduces decompression time by about 25% at the cost of
 	  a 1K bigger binary.
 	  a 1K bigger binary.
 
 
+config BUSYBOX_LZMA
+	bool "Provide lzma alias which supports only unpacking"
+	default n
+	depends on BUSYBOX_UNLZMA
+	help
+	  Enable this option if you want commands like "lzma -d" to work.
+	  IOW: you'll get lzma applet, but it will always require -d option.
+
+config BUSYBOX_UNXZ
+	bool "unxz"
+	depends on !ADK_PACKAGE_XZ
+	default n
+	help
+	  unxz is a unlzma successor.
+
+config BUSYBOX_XZ
+	bool "Provide xz alias which supports only unpacking"
+	default n
+	depends on BUSYBOX_UNXZ
+	help
+	  Enable this option if you want commands like "xz -d" to work.
+	  IOW: you'll get xz applet, but it will always require -d option.
+
 config BUSYBOX_UNZIP
 config BUSYBOX_UNZIP
 	bool "unzip"
 	bool "unzip"
 	default n
 	default n

+ 6 - 0
package/busybox/config/console-tools/Config.in

@@ -12,6 +12,12 @@ config BUSYBOX_CHVT
 	  This program is used to change to another terminal.
 	  This program is used to change to another terminal.
 	  Example: chvt 4 (change to terminal /dev/tty4)
 	  Example: chvt 4 (change to terminal /dev/tty4)
 
 
+config BUSYBOX_FGCONSOLE
+	bool "fgconsole"
+	default n
+	help
+	  This program prints active (foreground) console number.
+
 config BUSYBOX_CLEAR
 config BUSYBOX_CLEAR
 	bool "clear"
 	bool "clear"
 	default y
 	default y

+ 1 - 1
package/busybox/config/coreutils/Config.in

@@ -823,7 +823,7 @@ config BUSYBOX_WHO
 
 
 config BUSYBOX_WHOAMI
 config BUSYBOX_WHOAMI
 	bool "whoami"
 	bool "whoami"
-	default n
+	default y
 	help
 	help
 	  whoami is used to print the username of the current
 	  whoami is used to print the username of the current
 	  user id (same as id -un).
 	  user id (same as id -un).

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

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

+ 39 - 0
package/busybox/config/init/Config.in

@@ -5,6 +5,45 @@
 
 
 menu "Init Utilities"
 menu "Init Utilities"
 
 
+config BUSYBOX_BOOTCHARTD
+	bool "bootchartd"
+	default n
+	help
+	  bootchartd is commonly used to profile the boot process
+	  for the purpose of speeding it up. In this case, it is started
+	  by the kernel as the init process. This is configured by adding
+	  the init=/sbin/bootchartd option to the kernel command line.
+
+	  It can also be used to monitor the resource usage of a specific
+	  application or the running system in general. In this case,
+	  bootchartd is started interactively by running bootchartd start
+	  and stopped using bootchartd stop.
+
+config BUSYBOX_FEATURE_BOOTCHARTD_BLOATED_HEADER
+	bool "bootchartd"
+	default y
+	depends on BOOTCHARTD
+	help
+	  Create extended header file compatible with "big" bootchartd.
+	  "Big" bootchartd is a shell script and it dumps some
+	  "convenient" info int the header, such as:
+	    title = Boot chart for `hostname` (`date`)
+	    system.uname = `uname -srvm`
+	    system.release = `cat /etc/DISTRO-release`
+	    system.cpu = `grep '^model name' /proc/cpuinfo | head -1` ($cpucount)
+	    system.kernel.options = `cat /proc/cmdline`
+	  This data is not mandatory for bootchart graph generation,
+	  and is considered bloat. Nevertheless, this option
+	  makes bootchartd applet to dump a subset of it.
+
+config BUSYBOX_FEATURE_BOOTCHARTD_CONFIG_FILE
+	bool "bootchartd"
+	default y
+	depends on BOOTCHARTD
+	help
+	  Enable reading and parsing of $PWD/bootchartd.conf
+	  and /etc/bootchartd.conf files.
+
 config BUSYBOX_INIT
 config BUSYBOX_INIT
 	bool "init"
 	bool "init"
 	default y
 	default y

+ 1 - 1
package/busybox/config/networking/Config.in

@@ -974,7 +974,7 @@ config BUSYBOX_FEATURE_WGET_AUTHENTICATION
 
 
 config BUSYBOX_FEATURE_WGET_LONG_OPTIONS
 config BUSYBOX_FEATURE_WGET_LONG_OPTIONS
 	bool "Enable long options"
 	bool "Enable long options"
-	default n
+	default y
 	depends on BUSYBOX_WGET && BUSYBOX_LONG_OPTS
 	depends on BUSYBOX_WGET && BUSYBOX_LONG_OPTS
 	help
 	help
 	  Support long options for the wget applet.
 	  Support long options for the wget applet.

+ 1 - 1
package/busybox/config/shell/Config.in

@@ -130,7 +130,7 @@ config BUSYBOX_ASH_RANDOM_SUPPORT
 
 
 config BUSYBOX_ASH_EXPAND_PRMT
 config BUSYBOX_ASH_EXPAND_PRMT
 	bool "Expand prompt string"
 	bool "Expand prompt string"
-	default n
+	default y
 	depends on BUSYBOX_ASH
 	depends on BUSYBOX_ASH
 	help
 	help
 	  "PS#" may contain volatile content, such as backquote commands.
 	  "PS#" may contain volatile content, such as backquote commands.

+ 10 - 2
package/busybox/config/util-linux/Config.in

@@ -191,6 +191,12 @@ config BUSYBOX_FINDFS
 	  WARNING:
 	  WARNING:
 	  With all submodules selected, it will add ~8k to busybox.
 	  With all submodules selected, it will add ~8k to busybox.
 
 
+config BUSYBOX_FLOCK
+	bool "flock"
+	default n
+	help
+	  Manage locks from shell scripts
+
 config BUSYBOX_FREERAMDISK
 config BUSYBOX_FREERAMDISK
 	bool "freeramdisk"
 	bool "freeramdisk"
 	default n
 	default n
@@ -351,7 +357,8 @@ config BUSYBOX_LOSETUP
 
 
 config BUSYBOX_LSPCI
 config BUSYBOX_LSPCI
 	bool "lspci"
 	bool "lspci"
-	default n
+	default y
+	depends on !ADK_PACKAGE_PCIUTILS
 	help
 	help
 	  lspci is a utility for displaying information about PCI buses in the
 	  lspci is a utility for displaying information about PCI buses in the
 	  system and devices connected to them.
 	  system and devices connected to them.
@@ -360,7 +367,8 @@ config BUSYBOX_LSPCI
 
 
 config BUSYBOX_LSUSB
 config BUSYBOX_LSUSB
 	bool "lsusb"
 	bool "lsusb"
-	default n
+	default y
+	depends on !ADK_PACKAGE_LSUSB
 	help
 	help
 	  lsusb is a utility for displaying information about USB buses in the
 	  lsusb is a utility for displaying information about USB buses in the
 	  system and devices connected to them.
 	  system and devices connected to them.

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

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

Разница между файлами не показана из-за своего большого размера
+ 267 - 241
package/busybox/patches/001-ipkg.patch


+ 23 - 38
package/busybox/patches/002-find-empty.patch

@@ -1,25 +1,22 @@
-diff -Nur busybox-1.15.2.orig/findutils/Config.in busybox-1.15.2/findutils/Config.in
---- busybox-1.15.2.orig/findutils/Config.in	2009-09-26 15:14:57.000000000 +0200
-+++ busybox-1.15.2/findutils/Config.in	2009-11-28 12:41:31.000000000 +0100
-@@ -81,6 +81,14 @@
- 	help
- 	  Support the 'find -inum' option for searching by inode number.
- 
-+config FEATURE_FIND_EMPTY
-+	bool "Enable -empty option matching empty files and directories"
-+	default y
-+	depends on FIND
-+	help
-+	  Support the 'find -empty' option for searching empty files 
-+	  and directories.
-+
- config FEATURE_FIND_EXEC
- 	bool "Enable -exec: execute commands"
- 	default y
-diff -Nur busybox-1.15.2.orig/findutils/find.c busybox-1.15.2/findutils/find.c
---- busybox-1.15.2.orig/findutils/find.c	2009-10-08 03:04:40.000000000 +0200
-+++ busybox-1.15.2/findutils/find.c	2009-11-28 12:48:36.000000000 +0100
-@@ -93,6 +93,7 @@
+diff -Nur busybox-1.17.0.orig/findutils/find.c busybox-1.17.0/findutils/find.c
+--- busybox-1.17.0.orig/findutils/find.c	2010-06-24 04:40:43.000000000 +0200
++++ busybox-1.17.0/findutils/find.c	2010-07-08 12:33:55.759015289 +0200
+@@ -133,6 +133,14 @@
+ //config:	help
+ //config:	  Support the 'find -inum' option for searching by inode number.
+ //config:
++//config:config FEATURE_FIND_EMPTY
++//config:       bool "Enable -empty option matching empty files and directories"
++//config:       default y
++//config:       depends on FIND
++//config:       help
++//config:         Support the 'find -empty' option for searching empty files 
++//config:         and directories.
++//config:
+ //config:config FEATURE_FIND_EXEC
+ //config:	bool "Enable -exec: execute commands"
+ //config:	default y
+@@ -270,6 +278,7 @@
  IF_FEATURE_FIND_CONTEXT(ACTS(context, security_context_t context;))
  IF_FEATURE_FIND_CONTEXT(ACTS(context, security_context_t context;))
  IF_FEATURE_FIND_PAREN(  ACTS(paren, action ***subexpr;))
  IF_FEATURE_FIND_PAREN(  ACTS(paren, action ***subexpr;))
  IF_FEATURE_FIND_PRUNE(  ACTS(prune))
  IF_FEATURE_FIND_PRUNE(  ACTS(prune))
@@ -27,7 +24,7 @@ diff -Nur busybox-1.15.2.orig/findutils/find.c busybox-1.15.2/findutils/find.c
  IF_FEATURE_FIND_DELETE( ACTS(delete))
  IF_FEATURE_FIND_DELETE( ACTS(delete))
  IF_FEATURE_FIND_EXEC(   ACTS(exec,  char **exec_argv; unsigned *subst_count; int exec_argc;))
  IF_FEATURE_FIND_EXEC(   ACTS(exec,  char **exec_argv; unsigned *subst_count; int exec_argc;))
  IF_FEATURE_FIND_GROUP(  ACTS(group, gid_t gid;))
  IF_FEATURE_FIND_GROUP(  ACTS(group, gid_t gid;))
-@@ -333,6 +334,34 @@
+@@ -519,6 +528,34 @@
  	return exec_actions(ap->subexpr, fileName, statbuf);
  	return exec_actions(ap->subexpr, fileName, statbuf);
  }
  }
  #endif
  #endif
@@ -62,7 +59,7 @@ diff -Nur busybox-1.15.2.orig/findutils/find.c busybox-1.15.2/findutils/find.c
  #if ENABLE_FEATURE_FIND_SIZE
  #if ENABLE_FEATURE_FIND_SIZE
  ACTF(size)
  ACTF(size)
  {
  {
-@@ -476,6 +505,7 @@
+@@ -686,6 +723,7 @@
  	IF_FEATURE_FIND_PRINT0( PARM_print0    ,)
  	IF_FEATURE_FIND_PRINT0( PARM_print0    ,)
  	IF_FEATURE_FIND_DEPTH(  PARM_depth     ,)
  	IF_FEATURE_FIND_DEPTH(  PARM_depth     ,)
  	IF_FEATURE_FIND_PRUNE(  PARM_prune     ,)
  	IF_FEATURE_FIND_PRUNE(  PARM_prune     ,)
@@ -70,7 +67,7 @@ diff -Nur busybox-1.15.2.orig/findutils/find.c busybox-1.15.2/findutils/find.c
  	IF_FEATURE_FIND_DELETE( PARM_delete    ,)
  	IF_FEATURE_FIND_DELETE( PARM_delete    ,)
  	IF_FEATURE_FIND_EXEC(   PARM_exec      ,)
  	IF_FEATURE_FIND_EXEC(   PARM_exec      ,)
  	IF_FEATURE_FIND_PAREN(  PARM_char_brace,)
  	IF_FEATURE_FIND_PAREN(  PARM_char_brace,)
-@@ -509,6 +539,7 @@
+@@ -720,6 +758,7 @@
  	IF_FEATURE_FIND_PRINT0( "-print0\0" )
  	IF_FEATURE_FIND_PRINT0( "-print0\0" )
  	IF_FEATURE_FIND_DEPTH(  "-depth\0"  )
  	IF_FEATURE_FIND_DEPTH(  "-depth\0"  )
  	IF_FEATURE_FIND_PRUNE(  "-prune\0"  )
  	IF_FEATURE_FIND_PRUNE(  "-prune\0"  )
@@ -78,7 +75,7 @@ diff -Nur busybox-1.15.2.orig/findutils/find.c busybox-1.15.2/findutils/find.c
  	IF_FEATURE_FIND_DELETE( "-delete\0" )
  	IF_FEATURE_FIND_DELETE( "-delete\0" )
  	IF_FEATURE_FIND_EXEC(   "-exec\0"   )
  	IF_FEATURE_FIND_EXEC(   "-exec\0"   )
  	IF_FEATURE_FIND_PAREN(  "(\0"       )
  	IF_FEATURE_FIND_PAREN(  "(\0"       )
-@@ -627,6 +658,12 @@
+@@ -839,6 +878,12 @@
  			(void) ALLOC_ACTION(prune);
  			(void) ALLOC_ACTION(prune);
  		}
  		}
  #endif
  #endif
@@ -91,15 +88,3 @@ diff -Nur busybox-1.15.2.orig/findutils/find.c busybox-1.15.2/findutils/find.c
  #if ENABLE_FEATURE_FIND_DELETE
  #if ENABLE_FEATURE_FIND_DELETE
  		else if (parm == PARM_delete) {
  		else if (parm == PARM_delete) {
  			G.need_print = 0;
  			G.need_print = 0;
-diff -Nur busybox-1.15.2.orig/include/usage.h busybox-1.15.2/include/usage.h
---- busybox-1.15.2.orig/include/usage.h	2009-10-08 02:59:09.000000000 +0200
-+++ busybox-1.15.2/include/usage.h	2009-11-28 12:42:43.000000000 +0100
-@@ -1239,6 +1239,8 @@
-      "\n	-group NAME	File belongs to group NAME (numeric group ID allowed)") \
- 	IF_FEATURE_FIND_DEPTH( \
-      "\n	-depth		Process directory name after traversing it") \
-+ 	IF_FEATURE_FIND_EMPTY( \
-+     "\n	-empty		File or directory is empty") \
- 	IF_FEATURE_FIND_SIZE( \
-      "\n	-size N[bck]	File size is N (c:bytes,k:kbytes,b:512 bytes(def.))." \
-      "\n			+/-N: file size is bigger/smaller than N") \

+ 120 - 0
package/busybox/patches/003-defaults-no.patch

@@ -0,0 +1,120 @@
+diff -Nur busybox-1.17.0.orig/archival/Config.src busybox-1.17.0/archival/Config.src
+--- busybox-1.17.0.orig/archival/Config.src	2010-06-25 01:32:35.000000000 +0200
++++ busybox-1.17.0/archival/Config.src	2010-07-16 02:06:58.336016174 +0200
+@@ -39,7 +39,7 @@
+ 
+ config AR
+ 	bool "ar"
+-	default y
++	default n
+ 	help
+ 	  ar is an archival utility program used to create, modify, and
+ 	  extract contents from archives. An archive is a single file holding
+@@ -79,7 +79,7 @@
+ 
+ config BUNZIP2
+ 	bool "bunzip2"
+-	default y
++	default n
+ 	help
+ 	  bunzip2 is a compression utility using the Burrows-Wheeler block
+ 	  sorting text compression algorithm, and Huffman coding. Compression
+@@ -92,7 +92,7 @@
+ 
+ config BZIP2
+ 	bool "bzip2"
+-	default y
++	default n
+ 	help
+ 	  bzip2 is a compression utility using the Burrows-Wheeler block
+ 	  sorting text compression algorithm, and Huffman coding. Compression
+@@ -105,7 +105,7 @@
+ 
+ config CPIO
+ 	bool "cpio"
+-	default y
++	default n
+ 	help
+ 	  cpio is an archival utility program used to create, modify, and
+ 	  extract contents from archives.
+@@ -204,19 +204,19 @@
+ 
+ config RPM2CPIO
+ 	bool "rpm2cpio"
+-	default y
++	default n
+ 	help
+ 	  Converts an RPM file into a CPIO archive.
+ 
+ config RPM
+ 	bool "rpm"
+-	default y
++	default n
+ 	help
+ 	  Mini RPM applet - queries and extracts RPM packages.
+ 
+ config TAR
+ 	bool "tar"
+-	default y
++	default n
+ 	help
+ 	  tar is an archiving program. It's commonly used with gzip to
+ 	  create compressed archives. It's probably the most widely used
+@@ -323,7 +323,7 @@
+ 
+ config UNLZMA
+ 	bool "unlzma"
+-	default y
++	default n
+ 	help
+ 	  unlzma is a compression utility using the Lempel-Ziv-Markov chain
+ 	  compression algorithm, and range coding. Compression
+@@ -354,7 +354,7 @@
+ 
+ config UNXZ
+ 	bool "unxz"
+-	default y
++	default n
+ 	help
+ 	  unxz is a unlzma successor.
+ 
+diff -Nur busybox-1.17.0.orig/editors/Config.src busybox-1.17.0/editors/Config.src
+--- busybox-1.17.0.orig/editors/Config.src	2010-06-24 04:40:43.000000000 +0200
++++ busybox-1.17.0/editors/Config.src	2010-07-16 02:05:47.485881936 +0200
+@@ -31,7 +31,7 @@
+ 
+ config DIFF
+ 	bool "diff"
+-	default y
++	default n
+ 	help
+ 	  diff compares two files or directories and outputs the
+ 	  differences between them in a form that can be given to
+@@ -62,13 +62,13 @@
+ 
+ config PATCH
+ 	bool "patch"
+-	default y
++	default n
+ 	help
+ 	  Apply a unified diff formatted patch.
+ 
+ config SED
+ 	bool "sed"
+-	default y
++	default n
+ 	help
+ 	  sed is used to perform text transformations on a file
+ 	  or input from a pipeline.
+diff -Nur busybox-1.17.0.orig/networking/Config.src busybox-1.17.0/networking/Config.src
+--- busybox-1.17.0.orig/networking/Config.src	2010-06-27 04:21:56.000000000 +0200
++++ busybox-1.17.0/networking/Config.src	2010-07-16 02:05:16.665861002 +0200
+@@ -961,7 +961,7 @@
+ 
+ config WGET
+ 	bool "wget"
+-	default y
++	default n
+ 	help
+ 	  wget is a utility for non-interactive download of files from HTTP,
+ 	  HTTPS, and FTP servers.

+ 23 - 0
package/busybox/patches/004-wget-accept-long-opts.patch

@@ -0,0 +1,23 @@
+diff -Nur busybox-1.17.0.orig/networking/wget.c busybox-1.17.0/networking/wget.c
+--- busybox-1.17.0.orig/networking/wget.c	2010-06-24 04:40:43.000000000 +0200
++++ busybox-1.17.0/networking/wget.c	2010-07-16 15:00:51.819609996 +0200
+@@ -542,8 +542,8 @@
+ 		"proxy\0"            Required_argument "Y"
+ 		"user-agent\0"       Required_argument "U"
+ 		/* Ignored: */
+-		// "tries\0"            Required_argument "t"
+-		// "timeout\0"          Required_argument "T"
++		"tries\0"            Required_argument "t"
++		"timeout\0"          Required_argument "T"
+ 		/* Ignored (we always use PASV): */
+ 		"passive-ftp\0"      No_argument       "\xff"
+ 		"header\0"           Required_argument "\xfe"
+@@ -560,7 +560,7 @@
+ #endif
+ 	/* server.allocated = target.allocated = NULL; */
+ 	opt_complementary = "-1" IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::");
+-	opt = getopt32(argv, "csqO:P:Y:U:" /*ignored:*/ "t:T:",
++	opt = getopt32(argv, "csqO:P:Y:U:t:T:",
+ 				&fname_out, &dir_prefix,
+ 				&proxy_flag, &user_agent,
+ 				NULL, /* -t RETRIES */

+ 15 - 10
package/busybox/patches/patch-include_libbb_h

@@ -1,18 +1,23 @@
---- busybox-1.15.2.orig/include/libbb.h	Thu Oct  8 03:04:16 2009
-+++ busybox-1.15.2/include/libbb.h	Sat Dec 19 12:42:57 2009
-@@ -48,6 +48,7 @@
- #define PATH_MAX 256
- #endif
- 
+diff -Nur busybox-1.17.0.orig/include/libbb.h busybox-1.17.0/include/libbb.h
+--- busybox-1.17.0.orig/include/libbb.h	2010-07-04 15:32:24.000000000 +0200
++++ busybox-1.17.0/include/libbb.h	2010-07-08 12:27:04.531002165 +0200
+@@ -40,6 +40,9 @@
+ /* Try to pull in PATH_MAX */
+ #include <limits.h>
+ #include <sys/param.h>
++
 +#if !(defined __APPLE__ || defined __FreeBSD__ || defined __MirBSD__ )
 +#if !(defined __APPLE__ || defined __FreeBSD__ || defined __MirBSD__ )
++
  #ifdef HAVE_MNTENT_H
  #ifdef HAVE_MNTENT_H
  #include <mntent.h>
  #include <mntent.h>
  #endif
  #endif
-@@ -61,6 +62,7 @@
- #include <selinux/context.h>
+@@ -52,6 +55,9 @@
  #include <selinux/flask.h>
  #include <selinux/flask.h>
  #include <selinux/av_permissions.h>
  #include <selinux/av_permissions.h>
-+#endif
  #endif
  #endif
- 
++
++#endif
++
  #if ENABLE_LOCALE_SUPPORT
  #if ENABLE_LOCALE_SUPPORT
+ # include <locale.h>
+ #else

+ 8 - 25
package/busybox/patches/patch-include_platform_h

@@ -1,15 +1,16 @@
---- busybox-1.15.2.orig/include/platform.h	Sat Sep 26 15:14:33 2009
-+++ busybox-1.15.2/include/platform.h	Sat Dec 19 12:53:00 2009
-@@ -7,6 +7,8 @@
- #ifndef	BB_PLATFORM_H
- #define BB_PLATFORM_H 1
+diff -Nur busybox-1.17.0.orig/include/platform.h busybox-1.17.0/include/platform.h
+--- busybox-1.17.0.orig/include/platform.h	2010-06-24 04:40:43.000000000 +0200
++++ busybox-1.17.0/include/platform.h	2010-07-08 12:15:16.099001527 +0200
+@@ -20,6 +20,8 @@
+ #define HAVE_STRSIGNAL 1
+ #define HAVE_VASPRINTF 1
  
  
 +#include <sys/param.h>
 +#include <sys/param.h>
 +
 +
  /* Convenience macros to test the version of gcc. */
  /* Convenience macros to test the version of gcc. */
  #undef __GNUC_PREREQ
  #undef __GNUC_PREREQ
  #if defined __GNUC__ && defined __GNUC_MINOR__
  #if defined __GNUC__ && defined __GNUC_MINOR__
-@@ -133,7 +135,7 @@ char *strchrnul(const char *s, int c);
+@@ -161,7 +163,7 @@
  # define bswap_32 __bswap32
  # define bswap_32 __bswap32
  # define bswap_16 __bswap16
  # define bswap_16 __bswap16
  # define __BIG_ENDIAN__ (_BYTE_ORDER == _BIG_ENDIAN)
  # define __BIG_ENDIAN__ (_BYTE_ORDER == _BIG_ENDIAN)
@@ -18,16 +19,7 @@
  # include <byteswap.h>
  # include <byteswap.h>
  # include <endian.h>
  # include <endian.h>
  #endif
  #endif
-@@ -190,7 +192,7 @@ char *strchrnul(const char *s, int c);
- 
- /* ---- Networking ------------------------------------------ */
- 
--#ifndef __APPLE__
-+#if !(defined __APPLE__ || defined BSD)
- # include <arpa/inet.h>
- # if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED)
- typedef int socklen_t;
-@@ -202,7 +204,7 @@ typedef int socklen_t;
+@@ -230,7 +232,7 @@
  /* ---- Compiler dependent settings ------------------------- */
  /* ---- Compiler dependent settings ------------------------- */
  
  
  #if (defined __digital__ && defined __unix__) \
  #if (defined __digital__ && defined __unix__) \
@@ -36,12 +28,3 @@
  # undef HAVE_MNTENT_H
  # undef HAVE_MNTENT_H
  # undef HAVE_SYS_STATFS_H
  # undef HAVE_SYS_STATFS_H
  #else
  #else
-@@ -231,7 +233,7 @@ typedef int socklen_t;
- # define HAVE_FEATURES_H
- # include <stdint.h>
- # define HAVE_STDINT_H
--#elif !defined __APPLE__
-+#elif !(defined __APPLE__ || defined BSD)
- /* Largest integral types. */
- # if BB_BIG_ENDIAN
- /* Looks BROKEN! */

+ 1 - 1
package/bzip2/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.0.5
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		3c15a0c8d1d3ee1c46a1634d00617b1a
 PKG_MD5SUM:=		3c15a0c8d1d3ee1c46a1634d00617b1a
 PKG_DESCR:=		bzip2 compression utility
 PKG_DESCR:=		bzip2 compression utility
-PKG_SECTION:=		utils
+PKG_SECTION:=		archive
 PKG_URL:=		http://www.bzip.org
 PKG_URL:=		http://www.bzip.org
 PKG_SITES:=		http://www.bzip.org/1.0.5/
 PKG_SITES:=		http://www.bzip.org/1.0.5/
 
 

+ 1 - 1
package/ca-certificates/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		20090814
 PKG_RELEASE:=		2
 PKG_RELEASE:=		2
 PKG_MD5SUM:=		307052c985bec7f9a00eb84293eef779
 PKG_MD5SUM:=		307052c985bec7f9a00eb84293eef779
 PKG_DESCR:=		Collection of common CA certificates
 PKG_DESCR:=		Collection of common CA certificates
-PKG_SECTION:=		shells
+PKG_SECTION:=		net/security
 PKG_DEPENDS:=		openssl-util libopenssl
 PKG_DEPENDS:=		openssl-util libopenssl
 PKG_URL:=		http://packages.debian.org/sid/ca-certificates
 PKG_URL:=		http://packages.debian.org/sid/ca-certificates
 PKG_SITES:=		http://ftp.debian.org/debian/pool/main/c/ca-certificates/
 PKG_SITES:=		http://ftp.debian.org/debian/pool/main/c/ca-certificates/

+ 1 - 1
package/ccid/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.3.12
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		7fcdbacacd955659286f988fa9b6e0be
 PKG_MD5SUM:=		7fcdbacacd955659286f988fa9b6e0be
 PKG_DESCR:=		a generic USB CCID and ICCD driver
 PKG_DESCR:=		a generic USB CCID and ICCD driver
-PKG_SECTION:=		security
+PKG_SECTION:=		crypto
 PKG_BUILDDEP+=		pcsc-lite
 PKG_BUILDDEP+=		pcsc-lite
 PKG_URL:=		http://pcsclite.alioth.debian.org/ccid.html
 PKG_URL:=		http://pcsclite.alioth.debian.org/ccid.html
 PKG_SITES:=		https://alioth.debian.org/frs/download.php/3281/
 PKG_SITES:=		https://alioth.debian.org/frs/download.php/3281/

+ 1 - 1
package/cfgfs/Makefile

@@ -14,7 +14,7 @@ PKG_TARGET_DEPENDS:=	alix wrap foxboard ag241 foxg20 routerboard
 WRKDIST=		${WRKDIR}/${PKG_NAME}-${PKG_VERSION}
 WRKDIST=		${WRKDIR}/${PKG_NAME}-${PKG_VERSION}
 NO_DISTFILES:=		1
 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
 include ${TOPDIR}/mk/package.mk
 
 

+ 1 - 1
package/chillispot/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.1.0
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		9d2597756af3fa14d7331b4a3651fc9b
 PKG_MD5SUM:=		9d2597756af3fa14d7331b4a3651fc9b
 PKG_DESCR:=		Wireless LAN Access Point Controller
 PKG_DESCR:=		Wireless LAN Access Point Controller
-PKG_SECTION:=		net
+PKG_SECTION:=		wifi
 PKG_DEPENDS:=		kmod-tun
 PKG_DEPENDS:=		kmod-tun
 PKG_URL:=		http://www.chillispot.info
 PKG_URL:=		http://www.chillispot.info
 PKG_SITES=		http://www.chillispot.info/download/
 PKG_SITES=		http://www.chillispot.info/download/

+ 1 - 1
package/collectd/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		4.10.0
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		c473cf8e9f22f5a9f7ef4c5be1b0c436
 PKG_MD5SUM:=		c473cf8e9f22f5a9f7ef4c5be1b0c436
 PKG_DESCR:=		System statistics collection daemon
 PKG_DESCR:=		System statistics collection daemon
-PKG_SECTION:=		console
+PKG_SECTION:=		misc
 PKG_DEPENDS:=		libpthread
 PKG_DEPENDS:=		libpthread
 PKG_URL:=		http://collectd.org
 PKG_URL:=		http://collectd.org
 PKG_SITES:=		http://collectd.org/files/
 PKG_SITES:=		http://collectd.org/files/

+ 3 - 4
package/comgt/Makefile

@@ -5,10 +5,10 @@ include ${TOPDIR}/rules.mk
 
 
 PKG_NAME:=		comgt
 PKG_NAME:=		comgt
 PKG_VERSION:=		0.32
 PKG_VERSION:=		0.32
-PKG_RELEASE:=		1
+PKG_RELEASE:=		2
 PKG_MD5SUM:=		db2452680c3d953631299e331daf49ef
 PKG_MD5SUM:=		db2452680c3d953631299e331daf49ef
 PKG_DESCR:=		3G/GPRS datacard control tool
 PKG_DESCR:=		3G/GPRS datacard control tool
-PKG_SECTION:=		console
+PKG_SECTION:=		utils
 PKG_URL:=		http://sourceforge.net/projects/comgt
 PKG_URL:=		http://sourceforge.net/projects/comgt
 PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=comgt/}
 PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=comgt/}
 
 
@@ -21,12 +21,11 @@ $(eval $(call PKG_template,COMGT,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG
 
 
 CONFIG_STYLE:=		manual
 CONFIG_STYLE:=		manual
 INSTALL_STYLE:=		manual
 INSTALL_STYLE:=		manual
-
 ALL_TARGET=		comgt
 ALL_TARGET=		comgt
 
 
 do-install:
 do-install:
 	${INSTALL_DIR} ${IDIR_COMGT}/usr/bin ${IDIR_COMGT}/etc/comgt
 	${INSTALL_DIR} ${IDIR_COMGT}/usr/bin ${IDIR_COMGT}/etc/comgt
 	${INSTALL_BIN} ${WRKBUILD}/comgt ${IDIR_COMGT}/usr/bin/comgt
 	${INSTALL_BIN} ${WRKBUILD}/comgt ${IDIR_COMGT}/usr/bin/comgt
-	${INSTALL_DATA} ./files/dial.comgt ${IDIR_COMGT}/etc/comgt/dial.comgt
+	${INSTALL_DATA} ./files/*.comgt ${IDIR_COMGT}/etc/comgt/
 
 
 include ${TOPDIR}/mk/pkg-bottom.mk
 include ${TOPDIR}/mk/pkg-bottom.mk

+ 34 - 0
package/comgt/files/hsoauth.comgt

@@ -0,0 +1,34 @@
+opengt
+ set com 115200n81
+ set senddelay 0.02
+ waitquiet 1 0.2
+
+:start
+ flash 0.1
+
+:getuser
+ let $u=$env("USER")
+ let a=len($u)
+ if a=0 goto continue
+
+:getpass
+ let $p=$env("PASS")
+
+:auth
+ print "User: ",$u,"\n"
+ print "Pass: ",$p,"\n"
+ send "AT$QCPDPP=1,1,\""
+ send $p
+ send "\",\""
+ send $u
+ send "\"^m"
+ waitfor 2 "OK"
+ if % = -1 goto error
+ if % = 0 goto continue
+
+:error
+ exit 1
+
+:continue
+ exit 0
+

+ 19 - 0
package/comgt/files/hsoconnect.comgt

@@ -0,0 +1,19 @@
+opengt
+ set com 115200n81
+ set senddelay 0.02
+ waitquiet 1 0.2
+ flash 0.1
+
+:start
+ send "AT_OWANCALL=1,1,0^m"
+ waitfor 2 "OK"
+ if % = -1 goto error
+ if % = 0 goto continue
+
+ 
+:error
+ exit 1
+
+:continue
+ exit 0
+

+ 27 - 0
package/comgt/files/hsodata.comgt

@@ -0,0 +1,27 @@
+opengt
+ set com 115200n81
+ set senddelay 0.02
+ waitquiet 1 0.2
+ flash 0.1
+
+ let c=1
+:start
+ send "AT_OWANDATA=1^m"
+ waitfor 2 "ERROR"
+ if % = 0 goto repeat
+ send "AT_OWANDATA=1^m"
+ get 2 "^m" $s
+ get 2 "^m" $s
+ print $s
+ print "\n"
+ exit 0
+
+:repeat
+ sleep 3
+ inc c
+ if c > 15 goto error
+ goto start
+
+:error
+ exit 1
+

+ 19 - 0
package/comgt/files/hsodisconnect.comgt

@@ -0,0 +1,19 @@
+opengt
+ set com 115200n81
+ set senddelay 0.02
+ waitquiet 1 0.2
+ flash 0.1
+
+:start
+ send "AT_OWANCALL=1,0,0^m"
+ waitfor 2 "OK"
+ if % = -1 goto error
+ if % = 0 goto continue
+
+ 
+:error
+ exit 1
+
+:continue
+ exit 0
+

+ 14 - 0
package/comgt/files/hsostatus.comgt

@@ -0,0 +1,14 @@
+opengt
+ set com 115200n81
+ set senddelay 0.02
+ waitquiet 1 0.2
+ flash 0.1
+
+:start
+ send "AT_OWANCALL?^m"
+ get 2 "^m" $s
+ get 2 "^m" $s
+ print $s
+ print "\n"
+ exit 0
+

+ 34 - 0
package/comgt/files/waitready.comgt

@@ -0,0 +1,34 @@
+# wait till the sim is ready
+opengt
+ set com 115200n81
+ set senddelay 0.02
+ waitquiet 1 0.2
+ flash 0.1
+:start
+ print "Waiting for SIM..."
+ let c=0
+:waitready
+ send "AT+CPIN?^m"
+ waitfor 2 "SIM PUK","SIM PIN","READY","ERROR","ERR"
+ if % = -1 goto tryagain
+ if % = 0 goto simready
+ if % = 1 goto simready
+ if % = 2 goto simready
+ if % = 3 goto tryagain
+ if % = 4 goto tryagain
+
+:tryagain
+ if c > 120 goto waittimeout
+ let c=c+2
+ print "."
+ goto waitready
+
+:waittimeout
+ print " Timeout
+"
+ exit 1
+
+:simready
+ print " OK
+"
+ exit 0

+ 2 - 1
package/coreutils/Makefile

@@ -13,11 +13,12 @@ PKG_URL:=		http://www.gnu.org/software/coreutils/
 PKG_SITES:=		http://ftp.gnu.org/gnu/coreutils/
 PKG_SITES:=		http://ftp.gnu.org/gnu/coreutils/
 
 
 PKG_DESCR_TSORT:=	topological sort utility
 PKG_DESCR_TSORT:=	topological sort utility
+PKG_SECTION_TSORT:=	misc
 
 
 include $(TOPDIR)/mk/package.mk
 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,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}))
+$(eval $(call PKG_template,TSORT,tsort,$(PKG_VERSION)-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR_TSORT},${PKG_SECTION_TSORT}))
 
 
 post-install:
 post-install:
 	$(INSTALL_DIR) $(IDIR_TSORT)/usr/bin
 	$(INSTALL_DIR) $(IDIR_TSORT)/usr/bin

+ 2 - 2
package/cpio/Makefile

@@ -7,8 +7,8 @@ PKG_NAME:=		cpio
 PKG_VERSION:=		2.11
 PKG_VERSION:=		2.11
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		1112bb6c45863468b5496ba128792f6c
 PKG_MD5SUM:=		1112bb6c45863468b5496ba128792f6c
-PKG_DESCR:=		copies files into or out of a cpio archive
-PKG_SECTION:=		net
+PKG_DESCR:=		manages cpio archives
+PKG_SECTION:=		archive
 PKG_URL:=		http://www.gnu.org/software/cpio/
 PKG_URL:=		http://www.gnu.org/software/cpio/
 PKG_SITES:=		${MASTER_SITE_GNU:=cpio/}
 PKG_SITES:=		${MASTER_SITE_GNU:=cpio/}
 
 

+ 3 - 3
package/cryptsetup/Makefile

@@ -4,16 +4,16 @@
 include ${TOPDIR}/rules.mk
 include ${TOPDIR}/rules.mk
 
 
 PKG_NAME:=		cryptsetup
 PKG_NAME:=		cryptsetup
-PKG_VERSION:=		1.0.7
+PKG_VERSION:=		1.1.3
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
-PKG_MD5SUM:=		5eea2a77391a8a1a651b31cbaef59e22
+PKG_MD5SUM:=		318a64470861ea5b92a52f2014f1e7c1
 PKG_DESCR:=		LUKS cryptsetup tools
 PKG_DESCR:=		LUKS cryptsetup tools
 PKG_SECTION:=		crypto
 PKG_SECTION:=		crypto
 PKG_DEPENDS:=		libgcrypt device-mapper libuuid libpopt \
 PKG_DEPENDS:=		libgcrypt device-mapper libuuid libpopt \
 			kmod-dm-crypt kmod-crypto-aes kmod-crypto-cbc \
 			kmod-dm-crypt kmod-crypto-aes kmod-crypto-cbc \
 			kmod-crypto-sha256 kmod-blk-dev-dm
 			kmod-crypto-sha256 kmod-blk-dev-dm
 PKG_BUILDDEP+=		libgcrypt popt e2fsprogs lvm
 PKG_BUILDDEP+=		libgcrypt popt e2fsprogs lvm
-PKG_URL:=		http://cryptsetup.googlecode.com
+PKG_URL:=		http://cryptsetup.googlecode.com/
 PKG_SITES:=		http://cryptsetup.googlecode.com/files/
 PKG_SITES:=		http://cryptsetup.googlecode.com/files/
 
 
 PKG_TARGET_DEPENDS:=	!foxboard
 PKG_TARGET_DEPENDS:=	!foxboard

+ 0 - 17
package/cryptsetup/patches/patch-lib_setup_c

@@ -1,17 +0,0 @@
-already added in svn upstream
---- cryptsetup-1.0.7.orig/lib/setup.c	2009-07-22 13:12:44.000000000 +0200
-+++ cryptsetup-1.0.7/lib/setup.c	2009-08-22 15:10:32.000000000 +0200
-@@ -542,7 +542,12 @@ static int __crypt_luks_open(int arg, st
- start:
- 	mk=NULL;
- 
--	if(get_key(prompt, &password, &passwordLen, 0, options->key_file, options->passphrase_fd, options->timeout, options->flags))
-+	if(options->passphrase) {
-+		passwordLen = strlen(options->passphrase);
-+		password = safe_alloc(passwordLen + 1);
-+		strncpy(password, options->passphrase, passwordLen + 1);
-+		tries = 0;
-+	} else if(get_key(prompt, &password, &passwordLen, 0, options->key_file, options->passphrase_fd, options->timeout, options->flags))
- 		tries--;
- 	else
- 		tries = 0;

+ 1 - 1
package/ctorrent/Makefile

@@ -9,7 +9,7 @@ PKG_RELEASE:=		1
 PKG_BUILDDEP+=		openssl
 PKG_BUILDDEP+=		openssl
 PKG_MD5SUM:=		59b23dd05ff70791cd6449effa7fc3b6
 PKG_MD5SUM:=		59b23dd05ff70791cd6449effa7fc3b6
 PKG_DESCR:=		console-based BitTorrent client
 PKG_DESCR:=		console-based BitTorrent client
-PKG_SECTION:=		net
+PKG_SECTION:=		p2p
 PKG_URL:=		http://www.rahul.net/dholmes/ctorrent
 PKG_URL:=		http://www.rahul.net/dholmes/ctorrent
 PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=dtorrent/}
 PKG_SITES:=		${MASTER_SITE_SOURCEFORGE:=dtorrent/}
 
 

+ 1 - 1
package/cups/Makefile

@@ -9,7 +9,7 @@ PKG_RELEASE:=		1
 PKG_BUILDDEP+=		zlib
 PKG_BUILDDEP+=		zlib
 PKG_MD5SUM:=		d95e2d588e3d36e563027a963b117b1b
 PKG_MD5SUM:=		d95e2d588e3d36e563027a963b117b1b
 PKG_DESCR:=		Common Unix Printing System
 PKG_DESCR:=		Common Unix Printing System
-PKG_SECTION:=		net
+PKG_SECTION:=		net/misc
 PKG_DEPENDS:=		zlib libpthread
 PKG_DEPENDS:=		zlib libpthread
 PKG_BUILDDEP+=		zlib
 PKG_BUILDDEP+=		zlib
 PKG_URL:=		http://www.cups.org
 PKG_URL:=		http://www.cups.org

+ 1 - 1
package/curl/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		7.20.1
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		d7df0507db48546661b155b612cac19c
 PKG_MD5SUM:=		d7df0507db48546661b155b612cac19c
 PKG_DESCR:=		a client-side URL transfer tool
 PKG_DESCR:=		a client-side URL transfer tool
-PKG_SECTION:=		net
+PKG_SECTION:=		www
 PKG_DEPENDS:=		libcurl
 PKG_DEPENDS:=		libcurl
 PKG_BUILDDEP+=		openssl zlib
 PKG_BUILDDEP+=		openssl zlib
 PKG_URL:=		http://curl.haxx.se
 PKG_URL:=		http://curl.haxx.se

+ 1 - 1
package/cutter/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.03
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		50093db9b64277643969ee75b83ebbd1
 PKG_MD5SUM:=		50093db9b64277643969ee75b83ebbd1
 PKG_DESCR:=		Abort TCP/IP connections routed over a firewall
 PKG_DESCR:=		Abort TCP/IP connections routed over a firewall
-PKG_SECTION:=		net
+PKG_SECTION:=		firewall
 PKG_URL:=		http://www.lowth.com/cutter/software/
 PKG_URL:=		http://www.lowth.com/cutter/software/
 PKG_SITES:=		http://www.lowth.com/cutter/software/
 PKG_SITES:=		http://www.lowth.com/cutter/software/
 
 

+ 1 - 1
package/cxxtools/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		1.4.8
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		16ce92a83beb925fa5138fc9a52d55af
 PKG_MD5SUM:=		16ce92a83beb925fa5138fc9a52d55af
 PKG_DESCR:=		a collection of general-purpose C++ classes
 PKG_DESCR:=		a collection of general-purpose C++ classes
-PKG_SECTION:=		net
+PKG_SECTION:=		libs
 PKG_DEPENDS:=		libiconv
 PKG_DEPENDS:=		libiconv
 PKG_BUILDDEP+=		libiconv
 PKG_BUILDDEP+=		libiconv
 PKG_URL:=		http://www.tntnet.org
 PKG_URL:=		http://www.tntnet.org

+ 1 - 1
package/dansguardian/Makefile

@@ -8,7 +8,7 @@ PKG_VERSION:=		2.10.1.1
 PKG_RELEASE:=		1
 PKG_RELEASE:=		1
 PKG_MD5SUM:=		0987a1c9bfbdf398118386f10279611a
 PKG_MD5SUM:=		0987a1c9bfbdf398118386f10279611a
 PKG_DESCR:=		web content filter proxy
 PKG_DESCR:=		web content filter proxy
-PKG_SECTION:=		net
+PKG_SECTION:=		proxy
 PKG_CXX:=		DANSGUARDIAN
 PKG_CXX:=		DANSGUARDIAN
 PKG_DEPENDS:=		libpcre zlib
 PKG_DEPENDS:=		libpcre zlib
 PKG_BUILDDEP+=		pcre zlib
 PKG_BUILDDEP+=		pcre zlib

Некоторые файлы не были показаны из-за большого количества измененных файлов