diff options
52 files changed, 3416 insertions, 4481 deletions
diff --git a/X11/xtrans/doc/xtrans.xml b/X11/xtrans/doc/xtrans.xml index 6d7c0c542..c586f6e35 100644 --- a/X11/xtrans/doc/xtrans.xml +++ b/X11/xtrans/doc/xtrans.xml @@ -1,6 +1,9 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" +[ +<!ENTITY % defs SYSTEM "defs.ent"> %defs; +]> <!-- lifted from troff+ms+XMan by doclifter --> <book id="xtrans"> @@ -8,18 +11,20 @@ <bookinfo> <title>X Transport Interface</title> <subtitle>X Consortium Standard</subtitle> - <releaseinfo>X Version 11, Release 7.X</releaseinfo> + <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> <authorgroup> <author> <firstname>Stuart</firstname><surname>Anderson</surname> + <affiliation><orgname>NCR Corporation</orgname></affiliation> </author> </authorgroup> - <othercredit><firstname>Ralph</firstname><surname>Mor</surname></othercredit> - <othercredit><firstname>Alan</firstname><surname>Coopersmith</surname></othercredit> - <corpname>NCR Corporation</corpname> + <othercredit><firstname>Ralph</firstname><surname>Mor</surname> + <affiliation><orgname>X Consortium</orgname></affiliation> + </othercredit> + <othercredit><firstname>Alan</firstname><surname>Coopersmith</surname> + <affiliation><orgname>Oracle Corp.</orgname></affiliation> + </othercredit> <releaseinfo>Version 0.7</releaseinfo> - <affiliation><orgname>The Open Group</orgname></affiliation> - <productnumber>X Version 11, Release 7.x</productnumber> <legalnotice> <para> diff --git a/X11/xtrans/docbook.am b/X11/xtrans/docbook.am index 2ffb7e60a..bba4d5453 100644 --- a/X11/xtrans/docbook.am +++ b/X11/xtrans/docbook.am @@ -21,74 +21,82 @@ shelf_DATA = dist_shelf_DATA = $(docbook) $(chapters) if HAVE_XMLTO -# -# Generate DocBook/XML output formats with or without stylesheets -# - -# Stylesheets are available if the package xorg-sgml-doctools is installed if HAVE_STYLESHEETS -# The location where all cross reference databases are installed -sgmldbsdir = $(XORG_SGML_PATH)/X11/dbs -masterdb = "$(sgmldbsdir)/masterdb$(suffix $@).xml" -XMLTO_FLAGS = \ - --searchpath "$(XORG_SGML_PATH)/X11" \ - --stringparam target.database.document=$(masterdb) \ - --stringparam current.docid="$(<:.xml=)" \ - --stringparam collect.xref.targets="no" - -XMLTO_XHTML_FLAGS = \ - -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl \ - --stringparam html.stylesheet=$(STYLESHEET_SRCDIR)/xorg.css - -XMLTO_FO_FLAGS = \ - -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl -endif HAVE_STYLESHEETS +XMLTO_SEARCHPATH_FLAGS = \ + --searchpath "$(XORG_SGML_PATH)/X11" \ + --searchpath "$(abs_top_builddir)" +XMLTO_HTML_OLINK_FLAGS = \ + --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.html.xml \ + --stringparam current.docid="$(<:.xml=)" +XMLTO_HTML_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl +XMLTO_HTML_FLAGS = \ + $(XMLTO_SEARCHPATH_FLAGS) \ + $(XMLTO_HTML_STYLESHEET_FLAGS) \ + $(XMLTO_HTML_OLINK_FLAGS) shelf_DATA += $(docbook:.xml=.html) -%.html: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) xhtml-nochunks $< - -if HAVE_FOP -shelf_DATA += $(docbook:.xml=.pdf) $(docbook:.xml=.ps) -%.pdf: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop pdf $< -%.ps: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop ps $< -endif HAVE_FOP +%.html: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) xhtml-nochunks $< if HAVE_XMLTO_TEXT + shelf_DATA += $(docbook:.xml=.txt) %.txt: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) txt $< + $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) txt $< endif HAVE_XMLTO_TEXT -# -# Generate documents cross-reference target databases -# +if HAVE_FOP +XMLTO_FO_IMAGEPATH_FLAGS = --stringparam img.src.path=$(abs_builddir)/ +XMLTO_PDF_OLINK_FLAGS = \ + --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.pdf.xml \ + --stringparam current.docid="$(<:.xml=)" +XMLTO_FO_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl + +XMLTO_FO_FLAGS = \ + $(XMLTO_SEARCHPATH_FLAGS) \ + $(XMLTO_FO_STYLESHEET_FLAGS) \ + $(XMLTO_FO_IMAGEPATH_FLAGS) \ + $(XMLTO_PDF_OLINK_FLAGS) + +shelf_DATA += $(docbook:.xml=.pdf) +%.pdf: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop pdf $< -# This is only possible if the xorg-sgml-doctools package is installed -if HAVE_STYLESHEETS -if HAVE_XSLTPROC +shelf_DATA += $(docbook:.xml=.ps) +%.ps: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop ps $< +endif HAVE_FOP -# DocBook/XML generated document cross-reference database -shelf_DATA += $(docbook:.xml=.html.db) $(docbook:.xml=.fo.db) +# Generate documents cross-reference target databases +if HAVE_XSLTPROC -# Generate DocBook/XML document cross-reference database -# Flags for the XSL Transformation processor generating xref target databases -XSLTPROC_FLAGS = \ +XSLT_SEARCHPATH_FLAGS = \ --path "$(XORG_SGML_PATH)/X11" \ - --stringparam targets.filename "$@" \ - --stringparam collect.xref.targets "only" \ - --nonet --xinclude - + --path "$(abs_top_builddir)" +XSLT_OLINK_FLAGS = \ + --stringparam targets.filename "$@" \ + --stringparam collect.xref.targets "only" \ + --stringparam olink.base.uri "$(@:.db=)" + +XSLT_HTML_FLAGS = \ + $(XSLT_SEARCHPATH_FLAGS) \ + $(XSLT_OLINK_FLAGS) \ + --nonet --xinclude \ + $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl +XSLT_PDF_FLAGS = \ + $(XSLT_SEARCHPATH_FLAGS) \ + $(XSLT_OLINK_FLAGS) \ + --nonet --xinclude \ + $(STYLESHEET_SRCDIR)/xorg-fo.xsl + +shelf_DATA += $(docbook:.xml=.html.db) %.html.db: %.xml $(chapters) - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \ - http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl $< + $(AM_V_GEN)$(XSLTPROC) $(XSLT_HTML_FLAGS) $< -%.fo.db: %.xml $(chapters) - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \ - http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl $< +shelf_DATA += $(docbook:.xml=.pdf.db) +%.pdf.db: %.xml $(chapters) + $(AM_V_GEN)$(XSLTPROC) $(XSLT_PDF_FLAGS) $< endif HAVE_XSLTPROC endif HAVE_STYLESHEETS diff --git a/libX11/specs/XIM/xim.xml b/libX11/specs/XIM/xim.xml index fbb603c20..dc4b8c804 100644 --- a/libX11/specs/XIM/xim.xml +++ b/libX11/specs/XIM/xim.xml @@ -27,7 +27,6 @@ <copyright><year>1993</year><year>1994</year><holder>FUJITSU LIMITED</holder></copyright> <copyright><year>1993</year><year>1994</year><holder>Oracle and/or its affiliates</holder></copyright> <releaseinfo>Version 1.0</releaseinfo> - <affiliation><orgname>X Consortium</orgname></affiliation> <abstract> <para> diff --git a/libX11/specs/XKB/xkblib.xml b/libX11/specs/XKB/xkblib.xml index 3ed55285b..e45841c98 100644 --- a/libX11/specs/XKB/xkblib.xml +++ b/libX11/specs/XKB/xkblib.xml @@ -11,6 +11,7 @@ <bookinfo> <title>The X Keyboard Extension:</title> <subtitle>Library Specification</subtitle> + <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> <authorgroup> <author> <firstname>Amber</firstname> @@ -42,13 +43,12 @@ <affiliation><orgname>Digital Equipment Corporation</orgname></affiliation> </author> </authorgroup> - <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> + <copyright><year>1995</year><year>1996</year><holder>X Consortium Inc.</holder></copyright> + <copyright><year>1995</year><year>1996</year><holder>Silicon Graphics Inc.</holder></copyright> + <copyright><year>1995</year><year>1996</year><holder>Hewlett-Packard Company</holder></copyright> + <copyright><year>1995</year><year>1996</year><holder>Digital Equipment Corporation</holder></copyright> <legalnotice> -<para>Copyright © 1995, 1996 X Consortium Inc.</para> -<para>Copyright © 1995, 1996 Silicon Graphics Inc.</para> -<para>Copyright © 1995, 1996 Hewlett-Packard Company</para> -<para>Copyright © 1995, 1996 Digital Equipment Corporation</para> <para> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), diff --git a/libXext/docbook.am b/libXext/docbook.am index 2ffb7e60a..bba4d5453 100644 --- a/libXext/docbook.am +++ b/libXext/docbook.am @@ -21,74 +21,82 @@ shelf_DATA = dist_shelf_DATA = $(docbook) $(chapters) if HAVE_XMLTO -# -# Generate DocBook/XML output formats with or without stylesheets -# - -# Stylesheets are available if the package xorg-sgml-doctools is installed if HAVE_STYLESHEETS -# The location where all cross reference databases are installed -sgmldbsdir = $(XORG_SGML_PATH)/X11/dbs -masterdb = "$(sgmldbsdir)/masterdb$(suffix $@).xml" -XMLTO_FLAGS = \ - --searchpath "$(XORG_SGML_PATH)/X11" \ - --stringparam target.database.document=$(masterdb) \ - --stringparam current.docid="$(<:.xml=)" \ - --stringparam collect.xref.targets="no" - -XMLTO_XHTML_FLAGS = \ - -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl \ - --stringparam html.stylesheet=$(STYLESHEET_SRCDIR)/xorg.css - -XMLTO_FO_FLAGS = \ - -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl -endif HAVE_STYLESHEETS +XMLTO_SEARCHPATH_FLAGS = \ + --searchpath "$(XORG_SGML_PATH)/X11" \ + --searchpath "$(abs_top_builddir)" +XMLTO_HTML_OLINK_FLAGS = \ + --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.html.xml \ + --stringparam current.docid="$(<:.xml=)" +XMLTO_HTML_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl +XMLTO_HTML_FLAGS = \ + $(XMLTO_SEARCHPATH_FLAGS) \ + $(XMLTO_HTML_STYLESHEET_FLAGS) \ + $(XMLTO_HTML_OLINK_FLAGS) shelf_DATA += $(docbook:.xml=.html) -%.html: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) xhtml-nochunks $< - -if HAVE_FOP -shelf_DATA += $(docbook:.xml=.pdf) $(docbook:.xml=.ps) -%.pdf: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop pdf $< -%.ps: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop ps $< -endif HAVE_FOP +%.html: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) xhtml-nochunks $< if HAVE_XMLTO_TEXT + shelf_DATA += $(docbook:.xml=.txt) %.txt: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) txt $< + $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) txt $< endif HAVE_XMLTO_TEXT -# -# Generate documents cross-reference target databases -# +if HAVE_FOP +XMLTO_FO_IMAGEPATH_FLAGS = --stringparam img.src.path=$(abs_builddir)/ +XMLTO_PDF_OLINK_FLAGS = \ + --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.pdf.xml \ + --stringparam current.docid="$(<:.xml=)" +XMLTO_FO_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl + +XMLTO_FO_FLAGS = \ + $(XMLTO_SEARCHPATH_FLAGS) \ + $(XMLTO_FO_STYLESHEET_FLAGS) \ + $(XMLTO_FO_IMAGEPATH_FLAGS) \ + $(XMLTO_PDF_OLINK_FLAGS) + +shelf_DATA += $(docbook:.xml=.pdf) +%.pdf: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop pdf $< -# This is only possible if the xorg-sgml-doctools package is installed -if HAVE_STYLESHEETS -if HAVE_XSLTPROC +shelf_DATA += $(docbook:.xml=.ps) +%.ps: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop ps $< +endif HAVE_FOP -# DocBook/XML generated document cross-reference database -shelf_DATA += $(docbook:.xml=.html.db) $(docbook:.xml=.fo.db) +# Generate documents cross-reference target databases +if HAVE_XSLTPROC -# Generate DocBook/XML document cross-reference database -# Flags for the XSL Transformation processor generating xref target databases -XSLTPROC_FLAGS = \ +XSLT_SEARCHPATH_FLAGS = \ --path "$(XORG_SGML_PATH)/X11" \ - --stringparam targets.filename "$@" \ - --stringparam collect.xref.targets "only" \ - --nonet --xinclude - + --path "$(abs_top_builddir)" +XSLT_OLINK_FLAGS = \ + --stringparam targets.filename "$@" \ + --stringparam collect.xref.targets "only" \ + --stringparam olink.base.uri "$(@:.db=)" + +XSLT_HTML_FLAGS = \ + $(XSLT_SEARCHPATH_FLAGS) \ + $(XSLT_OLINK_FLAGS) \ + --nonet --xinclude \ + $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl +XSLT_PDF_FLAGS = \ + $(XSLT_SEARCHPATH_FLAGS) \ + $(XSLT_OLINK_FLAGS) \ + --nonet --xinclude \ + $(STYLESHEET_SRCDIR)/xorg-fo.xsl + +shelf_DATA += $(docbook:.xml=.html.db) %.html.db: %.xml $(chapters) - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \ - http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl $< + $(AM_V_GEN)$(XSLTPROC) $(XSLT_HTML_FLAGS) $< -%.fo.db: %.xml $(chapters) - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \ - http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl $< +shelf_DATA += $(docbook:.xml=.pdf.db) +%.pdf.db: %.xml $(chapters) + $(AM_V_GEN)$(XSLTPROC) $(XSLT_PDF_FLAGS) $< endif HAVE_XSLTPROC endif HAVE_STYLESHEETS diff --git a/libXext/specs/dbelib.xml b/libXext/specs/dbelib.xml index 5a969a287..1f9068a7d 100644 --- a/libXext/specs/dbelib.xml +++ b/libXext/specs/dbelib.xml @@ -1,6 +1,9 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" +[ +<!ENTITY % defs SYSTEM "defs.ent"> %defs; +]> <!-- lifted from troff+ms+XMan by doclifter --> @@ -9,7 +12,7 @@ <bookinfo> <title>Double Buffer Extension Library</title> <subtitle>X Consortium Standard</subtitle> - <!-- <releaseinfo>X Version 11, Release 6.4</releaseinfo> --> + <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> <authorgroup> <author> <firstname>Ian</firstname><surname>Elliot</surname> @@ -26,7 +29,6 @@ <copyright><year>1995</year><holder>X Consortium, Inc and Hewlett-Packard Company</holder></copyright> <releaseinfo>Version 1.0</releaseinfo> <affiliation><orgname>X Consortium</orgname></affiliation> - <productnumber>X Version 11, Release 7</productnumber> <legalnotice> <para> diff --git a/libXext/specs/dpmslib.xml b/libXext/specs/dpmslib.xml index 1fe81d2af..d0e24472d 100644 --- a/libXext/specs/dpmslib.xml +++ b/libXext/specs/dpmslib.xml @@ -1,6 +1,9 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" +[ +<!ENTITY % defs SYSTEM "defs.ent"> %defs; +]> <!-- lifted from troff+ms+XMan by doclifter --> <book id="dpmslib"> @@ -8,7 +11,7 @@ <bookinfo> <title>X Display Power Management Signaling (DPMS) Extension</title> <subtitle>X Consortium Standard</subtitle> - <releaseinfo>X Version 11, Release 6.8</releaseinfo> + <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> <authorgroup> <author> <firstname>Rob</firstname><surname>Lembree</surname> @@ -18,7 +21,6 @@ <copyright><year>1996</year><holder>X Consortium</holder></copyright> <releaseinfo>Version 1.0</releaseinfo> <affiliation><orgname>X Consortium</orgname></affiliation> - <productnumber>X Version 11, Release 6.8</productnumber> <legalnotice> <para> diff --git a/libXext/specs/shapelib.xml b/libXext/specs/shapelib.xml index 7fb108c77..9a158ee61 100644 --- a/libXext/specs/shapelib.xml +++ b/libXext/specs/shapelib.xml @@ -1,6 +1,9 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" +[ +<!ENTITY % defs SYSTEM "defs.ent"> %defs; +]> <!-- lifted from troff+ms+XMan by doclifter --> <book id="shapelib"> @@ -8,17 +11,16 @@ <bookinfo> <title>X Nonrectangular Window Shape Extension Library</title> <subtitle>X Consortium Standard</subtitle> - <releaseinfo>X Version 11, Release 6.4</releaseinfo> + <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> + <releaseinfo>Version 1.0</releaseinfo> <authorgroup> <author> <firstname>Keith</firstname><surname>Packard</surname> + <affiliation><orgname>MIT X Consortium</orgname></affiliation> </author> </authorgroup> <corpname>MIT X Consortium</corpname> <copyright><year>1989</year><holder>X Consortium</holder></copyright> - <releaseinfo>Version 1.0</releaseinfo> - <affiliation><orgname>MIT X Consortium</orgname></affiliation> - <productnumber>X Version 11, Release 6.4</productnumber> <legalnotice> diff --git a/libXext/specs/synclib.xml b/libXext/specs/synclib.xml index 36c716297..67a7b5255 100644 --- a/libXext/specs/synclib.xml +++ b/libXext/specs/synclib.xml @@ -1,6 +1,9 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" +[ +<!ENTITY % defs SYSTEM "defs.ent"> %defs; +]> <!-- lifted from troff+ms+XMan by doclifter --> @@ -9,7 +12,8 @@ <bookinfo> <title>X Synchronization Extension Library</title> <subtitle>X Consortium Standard</subtitle> - <releaseinfo>X Version 11, Release 6.4</releaseinfo> + <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> + <releaseinfo>Version 3.0</releaseinfo> <authorgroup> <author> <firstname>Tim</firstname><surname>Glauert</surname> @@ -31,9 +35,6 @@ <affiliation><orgname>X Consortium, Inc.</orgname></affiliation> </author> </authorgroup> - <releaseinfo>Version 3.0</releaseinfo> - <affiliation><orgname>X Consortium</orgname></affiliation> - <productnumber>X Version 11, Release 6.4</productnumber> <legalnotice> <para> diff --git a/libXext/specs/xtest1.xml b/libXext/specs/xtest1.xml index 72496210f..22d046767 100644 --- a/libXext/specs/xtest1.xml +++ b/libXext/specs/xtest1.xml @@ -1,952 +1,951 @@ -<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
- "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
-
-
-<article id="xtest1">
-
-<articleinfo>
- <title>X11 INPUT SYNTHESIS EXTENSION PROPOSAL</title>
- <subtitle>X Consortium Standard</subtitle>
- <releaseinfo>Version 1.0</releaseinfo>
- <authorgroup>
- <author>
- <firstname>Larry</firstname><surname>Woestman</surname>
- <affiliation><jobtitle>Member of Technical Staff</jobtitle>
- <orgname>Hewlett Packard</orgname></affiliation>
- </author>
- </authorgroup>
- <corpname>X Consortium Standard</corpname>
- <copyright><year>1993</year><holder>X Consortium</holder></copyright>
- <affiliation><orgname>X Consortium</orgname></affiliation>
- <productnumber>X Version 11, Release 7</productnumber>
-
-<abstract>
-<para>
-This is a proposal for an extension to the X11 server and Xlib.
-</para>
-</abstract>
-
-</articleinfo>
-
-<sect1 id="introduction">
-<title>Introduction</title>
-<para>
-This is a proposal for an extension to the X11 server and Xlib.
-It provides two capabilities:
-</para>
-
-<itemizedlist>
- <listitem>
- <para>
-It allows a client to generate user input actions in the server without
-requiring a user to be present.
- </para>
- </listitem>
- <listitem>
- <para>
-It also allows a client to control the
-handling of user input actions by the server.
- </para>
- </listitem>
-</itemizedlist>
-
-<para>
-The capability
-to allow a client to generate user input actions in the server
-will be used by some of the X Testing Consortium Xlib tests.
-Both capabilities will be used by the X Testing Consortium client exerciser
-program.
-These capabilities may also be useful in other programs.
-</para>
-
-<para>
-This extension requires modification to device-dependent code in the
-server. Therefore it is not a 'portable' extension as defined by the
-X11 Server Extensions document. However, the majority of the code
-and functionality of this extension will be implementation-independent.
-</para>
-
-</sect1>
-
-<sect1 id="conventions_used_in_this_document">
-<title>Conventions Used In This Document</title>
-
-<para>
-The naming conventions used in the Xlib documentation are followed
-with these additions:
-</para>
-
-<itemizedlist>
- <listitem>
- <para>
-The names of all functions defined in this extension begin with 'XTest',
-with the first letter of each additional word capitalized.
- </para>
- </listitem>
- <listitem>
- <para>
-The names of the protocol request structures follow the Xlib convention
-of 'x<name>Req'.
- </para>
- </listitem>
- <listitem>
- <para>
-The names of the protocol request minor type codes follow the Xlib convention
-of 'X_<name>'.
- </para>
- </listitem>
- <listitem>
- <para>
-The names of all other constants defined in this extension begin with 'XTest',
-with the rest of the name in upper case letters.
- </para>
- </listitem>
- <listitem>
- <para>
-All constants and structures defined in this extension will have their
-values specified in the 'xtestext1.h' file (listed in section 5).
- </para>
- </listitem>
-</itemizedlist>
-
-</sect1>
-<sect1 id="definition_of_terms">
-<title>Definition Of Terms</title>
-
-<sect2 id="input_actions">
-<title>Input Actions</title>
-<para>
-Input actions are pointer movements, button presses and releases,
-and key presses and releases. They can be generated by a user or by a client
-(using functions in this extension).
-</para>
-</sect2>
-
-<sect2 id="user_input_actions">
-<title>User Input Actions</title>
-<para>
-User input actions are input actions that are generated by the user
-moving a pointing device (typically a mouse), pressing and releasing buttons on
-the pointing device, and pressing and releasing keys on the keyboard.
-</para>
-</sect2>
-
-</sect1>
-
-<sect1 id="what_does_this_extension_do">
-<title>What Does This Extension Do?</title>
-<para>
-Without this extension, user input actions are processed by the server,
-and are converted into normal X events that are sent to the
-appropriate client or clients.
-</para>
-
-<para>
-This extension adds the following capabilities:
-</para>
-
-<itemizedlist>
- <listitem>
- <para>
-Input actions may be sent from a client to the server to be
-processed just as if the user had physically performed them.
-The input actions are provided to the server in the form of X protocol
-requests defined by this extension.
-The information provided to the server includes what action should be
-performed, and how long to delay before processing the action in the server.
- </para>
- </listitem>
- <listitem>
- <para>
-User input actions may be diverted to a client before being processed by the
-server.
-The effect on the server is as if the user had performed no input action.
-The user input actions are provided to the client in the form of X events
-defined by this extension.
-The information provided to the client includes what user input action
-occurred and the delay between this user input action and the previous user
-input action.
-The client may then do anything it wishes with this information.
- </para>
- </listitem>
- <listitem>
- <para>
-User input actions may be copied, with one copy going to the server in the
-normal way, and the other copy being sent to a client as described above.
- </para>
- </listitem>
-</itemizedlist>
-
-</sect1>
-<sect1 id="functions_in_this_extension">
-<title>Functions In This Extension</title>
-
-<sect2 id="high_level_functions">
-<title>High Level Functions</title>
-
-<para>
-These functions are built on top of the low level functions described later.
-</para>
-
-<sect3 id="xtestmovepointer">
-<title>XTestMovePointer</title>
-
-<funcsynopsis>
-<funcprototype>
- <funcdef>int <function>XTestMovePointer</function></funcdef>
- <paramdef>Display <parameter>*display</parameter></paramdef>
- <paramdef>int <parameter>device_id</parameter></paramdef>
- <paramdef>unsigned long <parameter>delay</parameter></paramdef>
- <paramdef>int <parameter>x</parameter></paramdef>
- <paramdef>int <parameter>y</parameter></paramdef>
- <paramdef>unsigned int <parameter>count</parameter></paramdef>
-</funcprototype>
-</funcsynopsis>
-
-<variablelist>
- <varlistentry>
- <term>display</term>
- <listitem>
- <para>
-Specifies the connection to the X server.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>device_id</term>
- <listitem>
- <para>
-Specifies which pointer device was supposed to have caused the input action.
-This is a provision for future support of multiple (distinguishable) pointer
-devices, and should always be set to 0 for now.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>delay</term>
- <listitem>
- <para>
-Specifies the time (in milliseconds) to wait before each movement
-of the pointer.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>x, y</term>
- <listitem>
- <para>
-Specifies the x and y coordinates to move the pointer to relative to the
-root window for the specified display.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>count</term>
- <listitem>
- <para>
-Specifies the number of 'delay, x, y' triplets contained in the
-<emphasis>delay</emphasis>,
-<emphasis>x</emphasis> and
-<emphasis>y</emphasis> arrays.
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-<para>
-The
-<function>XTestMovePointer</function>
-function creates input actions to be sent to the the server.
-The input actions will be accumulated in a request defined by this extension
-until the request is full or the XTestFlush function is called.
-They will then be sent to the server.
-When the input actions are sent to the server, the input actions will cause
-the server to think that the pointer was moved to the specified position(s),
-with the specified delay before each input action.
-</para>
-<para>
-The
-<function>XTestMovePointer</function>
-function will return -1 if there is an error, and 0 otherwise.
-</para>
-</sect3>
-
-<sect3 id="xtestpressbutton">
-<title>XTestPressButton</title>
-
-<funcsynopsis>
-<funcprototype>
- <funcdef>int <function>XTestPressButton</function></funcdef>
- <paramdef>Display <parameter>*display</parameter></paramdef>
- <paramdef>int <parameter>device_id</parameter></paramdef>
- <paramdef>unsigned long <parameter>delay</parameter></paramdef>
- <paramdef>unsigned int <parameter>button_number</parameter></paramdef>
- <paramdef>unsigned int <parameter>button_action</parameter></paramdef>
-</funcprototype>
-</funcsynopsis>
-
-
-<!-- .VL 15 -->
-<variablelist>
- <varlistentry>
- <term>display</term>
- <listitem>
- <para>
-Specifies the connection to the X server.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>device_id</term>
- <listitem>
- <para>
-Specifies which button device was supposed to have caused the input action.
-This is a provision for future support of multiple (distinguishable) button
-devices, and should always be set to 0 for now.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>delay</term>
- <listitem>
- <para>
-Specifies the time (in milliseconds) to wait before the input action.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>button_number</term>
- <listitem>
- <para>
-Specifies which button is being acted upon.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>button_action</term>
- <listitem>
- <para>
-Specifies the action to be performed (one of
-<emphasis>XTestPRESS</emphasis>,
-<emphasis>XTestRELEASE</emphasis>, or
-<emphasis>XTestSTROKE</emphasis>).
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-<para>
-The
-<function>XTestPressButton</function>
-function creates input actions to be sent to the the server.
-The input actions will be accumulated in a request defined by this extension
-until the request is full or the XTestFlush function is called.
-They will then be sent to the server.
-When the input actions are sent to the server, the input actions will cause
-the server to think that the specified button was moved as specified.
-</para>
-<para>
-The
-<function>XTestPressButton</function>
-function will return -1 if there is an error, and 0 otherwise.
-</para>
-</sect3>
-
-<sect3 id="xtestpresskey">
-<title>XTestPressKey</title>
-
-<funcsynopsis>
-<funcprototype>
- <funcdef>int <function>XTestPressKey</function></funcdef>
- <paramdef>Display <parameter>*display</parameter></paramdef>
- <paramdef>int <parameter>device_id</parameter></paramdef>
- <paramdef>unsigned long <parameter>delay</parameter></paramdef>
- <paramdef>unsigned int <parameter>keycode</parameter></paramdef>
- <paramdef>unsigned int <parameter>key_action</parameter></paramdef>
-</funcprototype>
-</funcsynopsis>
-
-<!-- .VL 12 -->
-<variablelist>
- <varlistentry>
- <term>display</term>
- <listitem>
- <para>
-Specifies the connection to the X server.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>device_id</term>
- <listitem>
- <para>
-Specifies which keyboard device was supposed to have caused the input action.
-This is a provision for future support of multiple (distinguishable) keyboard
-devices, and should always be set to 0 for now.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>delay</term>
- <listitem>
- <para>
-Specifies the time (in milliseconds) to wait before the input action.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>keycode</term>
- <listitem>
- <para>
-Specifies which keycode is being acted upon.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>key_action</term>
- <listitem>
- <para>
-Specifies the action to be performed (one of
-<emphasis>XTestPRESS</emphasis>,
-<emphasis>XTestRELEASE</emphasis>, or
-<emphasis>XTestSTROKE</emphasis>).
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-
-<para>
-The
-<function>XTestPressKey</function>
-function creates input actions to be sent to the the server.
-The input actions will be accumulated in a request defined by this extension
-until the request is full or the XTestFlush function is called.
-They will then be sent to the server.
-When the input actions are sent to the server, the input actions will cause
-the server to think that the specified key on the keyboard was moved as
-specified.
-</para>
-
-<para>
-The
-<function>XTestPressKey</function>
-function will return -1 if there is an error, and 0 otherwise.
-</para>
-
-</sect3>
-<sect3 id="xtestflush">
-<title>XTestFlush</title>
-
-<funcsynopsis>
-<funcprototype>
- <funcdef>int <function>XTestFlush</function></funcdef>
- <paramdef>Display <parameter>*display</parameter></paramdef>
-</funcprototype>
-</funcsynopsis>
-
-<!-- .VL 9 -->
-<variablelist>
- <varlistentry>
- <term>display</term>
- <listitem>
- <para>
-Specifies the connection to the X server.
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-<para>
-The
-<function>XTestFlush</function>
-will send any remaining input actions to the server.
-</para>
-
-<para>
-The
-<function>XTestFlush</function>
-function will return -1 if there is an error, and 0 otherwise.
-</para>
-
-</sect3>
-</sect2>
-
-<!-- .H 2 Low~Level~Functions -->
-<sect2 id="low_level_functions">
-<title>Low Level Functions</title>
-
-<!-- .H 3 XTestGetInput -->
-<sect3 id="xtestgetinput">
-<title>XTestGetInput</title>
-
-<funcsynopsis>
-<funcprototype>
- <funcdef>int <function>XTestGetInput</function></funcdef>
- <paramdef>Display <parameter>*display</parameter></paramdef>
- <paramdef>int <parameter>action_handling</parameter></paramdef>
-</funcprototype>
-</funcsynopsis>
-
-
-<variablelist>
- <varlistentry>
- <term>display</term>
- <listitem>
- <para>
-Specifies the connection to the X server.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>action_handling</term>
- <listitem>
- <para>
-Specifies to the server what to do with the user input actions. (one of
-0, <emphasis>XTestPACKED_MOTION</emphasis> or
-<emphasis>XTestPACKED_ACTIONS</emphasis>; optionally 'or'ed
-with <emphasis>XTestEXCLUSIVE</emphasis>).
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-
-<para>
-The
-<function>XTestGetInput</function>
-function tells the server to begin putting information about user input actions
-into events to be sent to the client that called this function. These events
-can be read via the Xlib <function>XNextEvent</function>fR function.
-</para>
-
-<para>
-The server assigns an event type of
-<emphasis>XTestInputActionType</emphasis> to these events
-to distinguish them from other events.
-Since the actual value of the event type may vary depending on how many
-extensions are included with an X11 implementation,
-<emphasis>XTestInputActionType</emphasis> is a variable that will be
-contained in the Xlib
-part of this extension. It may be referenced as follows:
-</para>
-
-<para>
-extern int XTestInputActionType;
-</para>
-
-<itemizedlist>
- <listitem>
- <para>
-An <emphasis>action_handling</emphasis> value of 0 causes the server
-to send one user input action in each
-<emphasis>XTestInputActionType</emphasis> event.
-This can sometimes cause performance problems.
- </para>
- </listitem>
- <listitem>
- <para>
-An <emphasis>action_handling</emphasis> value of
-<emphasis>XTestPACKED_ACTIONS</emphasis> causes the server
-to pack as many user input actions as possible into a
-<emphasis>XTestInputActionType</emphasis> event.
-This is needed if user input actions are happening rapidly (such as
-when the user moves the pointer) to keep performance at a reasonable level.
- </para>
- </listitem>
- <listitem>
- <para>
-An <emphasis>action_handling</emphasis> value of
-<emphasis>XTestPACKED_MOTION</emphasis> causes the server
-to pack only user input actions associated with moving the pointer.
-This allows the
-client to receive button and key motions as they happen without waiting for the
-event to fill up, while still keeping performance at a reasonable level.
- </para>
- </listitem>
- <listitem>
- <para>
-An <emphasis>action_handling</emphasis> value with
-<emphasis>XTestEXCLUSIVE</emphasis> 'or'ed in
-causes the server to send user input actions only to the client.
-The effect on the server is as if the user had performed no input actions.
- </para>
- </listitem>
- <listitem>
- <para>
-An <emphasis>action_handling</emphasis> value without
-<emphasis>XTestEXCLUSIVE</emphasis>
-causes the server to copy user input actions, sending one copy to the
-client, and handling the other copy normally (as it would if this extension
-were not installed).
- </para>
- </listitem>
-</itemizedlist>
-
-<para>
-There are four types of input actions that are passed from the server
-to the client. They are:
-</para>
-
-<variablelist>
- <varlistentry>
- <term>key/button~state~change</term>
- <listitem>
- <para>
-This type of input action contains the keycode of the key or button that
-changed state;
-whether the key or button is up or down,
-and the time delay between this input action and the previous input action.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>pointer~motions</term>
- <listitem>
- <para>
-This type of input action contains information about the motion of the
-pointer when the pointer has only moved a short distance.
-If the pointer has moved a long distance,
-the pointer jump input action is used.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>pointer~jumps</term>
- <listitem>
- <para>
-This type of input action contains information about the motion of the
-pointer when the pointer has moved a long distance.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>delays</term>
- <listitem>
- <para>
-This type of input action is used when the delay between input actions is too
-large to be held in the other input actions.
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-<para>
-The
-<function>XTestGetInput</function>
-function will return -1 if there is an error, and 0 otherwise.
-</para>
-<para>
-An error code of <emphasis>BadAccess</emphasis> means that another client
-has already requested that user input actions be sent to it.
-</para>
-
-</sect3>
-
-<!-- .H 3 XTestStopInput -->
-<sect3 id="xteststopinput">
-<title>XTestStopInput</title>
-
-<funcsynopsis>
-<funcprototype>
- <funcdef>int <function>XTestStopInput</function></funcdef>
- <paramdef>Display <parameter>*display</parameter></paramdef>
-</funcprototype>
-</funcsynopsis>
-
-
-
-<variablelist>
- <varlistentry>
- <term>display</term>
- <listitem>
- <para>
-Specifies the connection to the X server.
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-<para>
-The
-<function>XTestStopInput</function>
-function tells the server to stop putting information about user input actions
-into events.
-The server will process user input actions normally (as it would
-if this extension were not in the server).
-</para>
-
-<para>
-The
-<function>XTestStopInput</function>
-function will return -1 if there is an error, and 0 otherwise.
-</para>
-
-<para>
-An error code of <emphasis>BadAccess</emphasis> means that a request
-was made to stop input when input has never been started.
-</para>
-
-</sect3>
-
-<!-- .H 3 XTestFakeInput -->
-<sect3 id="xtestfakeinput">
-<title>XTestFakeInput</title>
-
-<funcsynopsis>
-<funcprototype>
- <funcdef>int <function>XTestFakeInput</function></funcdef>
- <paramdef>Display <parameter>*display</parameter></paramdef>
- <paramdef>char <parameter>*action_list_addr</parameter></paramdef>
- <paramdef>int <parameter>action_list_size</parameter></paramdef>
- <paramdef>int <parameter>ack_flag</parameter></paramdef>
-</funcprototype>
-</funcsynopsis>
-
-
-<!-- .VL 18 -->
-
-<variablelist>
- <varlistentry>
- <term>display</term>
- <listitem>
- <para>
-Specifies the connection to the X server.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>action_list_addr</term>
- <listitem>
- <para>
-Specifies the address of an list of input actions to be sent to the server.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>action_list_size</term>
- <listitem>
- <para>
-Specifies the size (in bytes) of the list of input actions.
-It may be no larger than <emphasis>XTestMAX_ACTION_LIST_SIZE</emphasis> bytes.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>ack_flag</term>
- <listitem>
- <para>
-Specifies whether the server needs to send an event to indicate that its
-input action buffer is empty (one of
-<emphasis>XTestFAKE_ACK_NOT_NEEDED</emphasis> or
-<emphasis>XTestFAKE_ACK_REQUEST</emphasis>).
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-<para>
-The
-<function>XTestFakeInput</function>
-function tells the server to take the specified user input actions and process
-them as if the user had physically performed them.
-</para>
-
-<para>
-The server can only accept a limited number of input actions at one
-time. This limit can be determined by the
-<function>XTestQueryInputSize</function> function
-in this extension.
-</para>
-
-<para>
-The client should set <emphasis>ack_flag</emphasis> to
-<emphasis>XTestFAKE_ACK_NOT_NEEDED</emphasis>
-on calls to <emphasis>XTestFakeInput</emphasis> that do not reach this limit.
-</para>
-
-<para>
-The client should set <emphasis>ack_flag</emphasis> to
-<emphasis>XTestFAKE_ACK_REQUEST</emphasis>
-on the call to <emphasis>XTestFakeInput</emphasis> that reaches this limit.
-</para>
-
-<para>
-When the server sees an <emphasis>ack_flag</emphasis> value of
-<emphasis>XTestFAKE_ACK_REQUEST</emphasis>
-it finishes processing its input action buffer, then sends an event with
-type <emphasis>XTestFakeAckType</emphasis> to the client.
-When the client reads this event, it knows that it is safe to resume
-sending input actions to the server.
-</para>
-
-<para>
-Since the actual value of the event type may vary depending on how many
-extensions are included with an X11 implementation,
-<emphasis>XTestFakeAckType</emphasis> is a variable that is contained
-in the Xlib part of this extension. It may be referenced as follows:
-</para>
-
-<para>
-extern int XTestFakeAckType;
-</para>
-
-<para>
-There are four types of input actions that are passed from the client
-to the server. They are:
-</para>
-
-<variablelist>
- <varlistentry>
- <term>key/button~state~change</term>
- <listitem>
- <para>
-This type of input action contains the keycode of the key or button that
-is to change state;
-whether the key or button is to be up or down,
-and the time to delay before changing the state of the key or button.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>pointer~motions</term>
- <listitem>
- <para>
-This type of input action contains information about the motion of the
-pointer when the pointer is to be moved a short distance,
-and the time to delay before moving the pointer.
-If the pointer is to be moved a long distance,
-the pointer jump input action must be used.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>pointer~jumps</term>
- <listitem>
- <para>
-This type of input action contains information about the motion of the
-pointer when the pointer is to be moved a long distance,
-and the time to delay before moving the pointer.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>delays</term>
- <listitem>
- <para>
-This type of input action is used when the delay between input actions is too
-large to be held in the other input actions.
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-
-<para>
-The
-<function>XTestFakeInput</function>
-function will return -1 if there is an error, and 0 otherwise.
-</para>
-
-<para>
-An error code of \fIBadAccess\fR means that another client has already
-sent user input actions to the server, and the server has not finished
-processing the user input actions.
-</para>
-
-</sect3>
-
-<!-- .H 3 XTestQueryInputSize -->
-<sect3 id="xtestqueryinputsize">
-<title>XTestQueryInputSize</title>
-
-<funcsynopsis>
-<funcprototype>
- <funcdef>int <function>XTestQueryInputSize</function></funcdef>
- <paramdef>Display <parameter>*display</parameter></paramdef>
- <paramdef>unsigned long <parameter>size_return</parameter></paramdef>
-</funcprototype>
-</funcsynopsis>
-
-
-<variablelist>
- <varlistentry>
- <term>display</term>
- <listitem>
- <para>
-Specifies the connection to the X server.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>size_return</term>
- <listitem>
- <para>
-Returns the number of input actions that the server's input action buffer can
-hold.
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-<para>
-The
-<function>XTestQueryInputSize</function>
-function asks the server to return the number of input actions that it can hold
-in its input action buffer in the unsigned long pointed to by \fIsize_return\fR.
-</para>
-<para>
-The
-<function>XTestQueryInputSize</function>
-function will return -1 if there is an error, and 0 otherwise.
-</para>
-</sect3>
-
-<!-- .H 3 XTestReset -->
-<sect3 id="xtestreset">
-<title>XTestReset</title>
-
-<funcsynopsis>
-<funcprototype>
- <funcdef>int <function>XTestReset</function></funcdef>
- <paramdef>Display <parameter>*display</parameter></paramdef>
-</funcprototype>
-</funcsynopsis>
-
-
-<variablelist>
- <varlistentry>
- <term>display</term>
- <listitem>
- <para>
-Specifies the connection to the X server.
- </para>
- </listitem>
- </varlistentry>
-</variablelist>
-
-<para>
-The
-<function>XTestReset</function>
-function tells the server to set everything having to do with this extension
-back to its initial state. After this call the server will act as if this
-extension were not installed until one of the extension functions is called by
-a client. This function is not normally needed, but is included in case a
-client wishes to clean up the server state, such as after a serious error.
-</para>
-
-<para>
-The
-<function>XTestReset</function>
-function will return -1 if there is an error, and 0 otherwise.
-</para>
-
-</sect3>
-</sect2>
-</sect1>
-
-<!-- .H 1 'xtestext1.h'~File~Listing -->
-<!-- .so xtestext1.h -->
-<!-- .TC 1 1 4 -->
-</article>
+<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> + + +<article id="xtest1"> + +<articleinfo> + <title>X11 INPUT SYNTHESIS EXTENSION PROPOSAL</title> + <subtitle>X Consortium Standard</subtitle> + <releaseinfo>Version 1.0</releaseinfo> + <authorgroup> + <author> + <firstname>Larry</firstname><surname>Woestman</surname> + <affiliation><jobtitle>Member of Technical Staff</jobtitle> + <orgname>Hewlett Packard</orgname></affiliation> + </author> + </authorgroup> + <corpname>X Consortium Standard</corpname> + <copyright><year>1993</year><holder>X Consortium</holder></copyright> + <affiliation><orgname>X Consortium</orgname></affiliation> + +<abstract> +<para> +This is a proposal for an extension to the X11 server and Xlib. +</para> +</abstract> + +</articleinfo> + +<sect1 id="introduction"> +<title>Introduction</title> +<para> +This is a proposal for an extension to the X11 server and Xlib. +It provides two capabilities: +</para> + +<itemizedlist> + <listitem> + <para> +It allows a client to generate user input actions in the server without +requiring a user to be present. + </para> + </listitem> + <listitem> + <para> +It also allows a client to control the +handling of user input actions by the server. + </para> + </listitem> +</itemizedlist> + +<para> +The capability +to allow a client to generate user input actions in the server +will be used by some of the X Testing Consortium Xlib tests. +Both capabilities will be used by the X Testing Consortium client exerciser +program. +These capabilities may also be useful in other programs. +</para> + +<para> +This extension requires modification to device-dependent code in the +server. Therefore it is not a 'portable' extension as defined by the +X11 Server Extensions document. However, the majority of the code +and functionality of this extension will be implementation-independent. +</para> + +</sect1> + +<sect1 id="conventions_used_in_this_document"> +<title>Conventions Used In This Document</title> + +<para> +The naming conventions used in the Xlib documentation are followed +with these additions: +</para> + +<itemizedlist> + <listitem> + <para> +The names of all functions defined in this extension begin with 'XTest', +with the first letter of each additional word capitalized. + </para> + </listitem> + <listitem> + <para> +The names of the protocol request structures follow the Xlib convention +of 'x<name>Req'. + </para> + </listitem> + <listitem> + <para> +The names of the protocol request minor type codes follow the Xlib convention +of 'X_<name>'. + </para> + </listitem> + <listitem> + <para> +The names of all other constants defined in this extension begin with 'XTest', +with the rest of the name in upper case letters. + </para> + </listitem> + <listitem> + <para> +All constants and structures defined in this extension will have their +values specified in the 'xtestext1.h' file (listed in section 5). + </para> + </listitem> +</itemizedlist> + +</sect1> +<sect1 id="definition_of_terms"> +<title>Definition Of Terms</title> + +<sect2 id="input_actions"> +<title>Input Actions</title> +<para> +Input actions are pointer movements, button presses and releases, +and key presses and releases. They can be generated by a user or by a client +(using functions in this extension). +</para> +</sect2> + +<sect2 id="user_input_actions"> +<title>User Input Actions</title> +<para> +User input actions are input actions that are generated by the user +moving a pointing device (typically a mouse), pressing and releasing buttons on +the pointing device, and pressing and releasing keys on the keyboard. +</para> +</sect2> + +</sect1> + +<sect1 id="what_does_this_extension_do"> +<title>What Does This Extension Do?</title> +<para> +Without this extension, user input actions are processed by the server, +and are converted into normal X events that are sent to the +appropriate client or clients. +</para> + +<para> +This extension adds the following capabilities: +</para> + +<itemizedlist> + <listitem> + <para> +Input actions may be sent from a client to the server to be +processed just as if the user had physically performed them. +The input actions are provided to the server in the form of X protocol +requests defined by this extension. +The information provided to the server includes what action should be +performed, and how long to delay before processing the action in the server. + </para> + </listitem> + <listitem> + <para> +User input actions may be diverted to a client before being processed by the +server. +The effect on the server is as if the user had performed no input action. +The user input actions are provided to the client in the form of X events +defined by this extension. +The information provided to the client includes what user input action +occurred and the delay between this user input action and the previous user +input action. +The client may then do anything it wishes with this information. + </para> + </listitem> + <listitem> + <para> +User input actions may be copied, with one copy going to the server in the +normal way, and the other copy being sent to a client as described above. + </para> + </listitem> +</itemizedlist> + +</sect1> +<sect1 id="functions_in_this_extension"> +<title>Functions In This Extension</title> + +<sect2 id="high_level_functions"> +<title>High Level Functions</title> + +<para> +These functions are built on top of the low level functions described later. +</para> + +<sect3 id="xtestmovepointer"> +<title>XTestMovePointer</title> + +<funcsynopsis> +<funcprototype> + <funcdef>int <function>XTestMovePointer</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>int <parameter>device_id</parameter></paramdef> + <paramdef>unsigned long <parameter>delay</parameter></paramdef> + <paramdef>int <parameter>x</parameter></paramdef> + <paramdef>int <parameter>y</parameter></paramdef> + <paramdef>unsigned int <parameter>count</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>device_id</term> + <listitem> + <para> +Specifies which pointer device was supposed to have caused the input action. +This is a provision for future support of multiple (distinguishable) pointer +devices, and should always be set to 0 for now. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>delay</term> + <listitem> + <para> +Specifies the time (in milliseconds) to wait before each movement +of the pointer. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>x, y</term> + <listitem> + <para> +Specifies the x and y coordinates to move the pointer to relative to the +root window for the specified display. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>count</term> + <listitem> + <para> +Specifies the number of 'delay, x, y' triplets contained in the +<emphasis>delay</emphasis>, +<emphasis>x</emphasis> and +<emphasis>y</emphasis> arrays. + </para> + </listitem> + </varlistentry> +</variablelist> + +<para> +The +<function>XTestMovePointer</function> +function creates input actions to be sent to the the server. +The input actions will be accumulated in a request defined by this extension +until the request is full or the XTestFlush function is called. +They will then be sent to the server. +When the input actions are sent to the server, the input actions will cause +the server to think that the pointer was moved to the specified position(s), +with the specified delay before each input action. +</para> +<para> +The +<function>XTestMovePointer</function> +function will return -1 if there is an error, and 0 otherwise. +</para> +</sect3> + +<sect3 id="xtestpressbutton"> +<title>XTestPressButton</title> + +<funcsynopsis> +<funcprototype> + <funcdef>int <function>XTestPressButton</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>int <parameter>device_id</parameter></paramdef> + <paramdef>unsigned long <parameter>delay</parameter></paramdef> + <paramdef>unsigned int <parameter>button_number</parameter></paramdef> + <paramdef>unsigned int <parameter>button_action</parameter></paramdef> +</funcprototype> +</funcsynopsis> + + +<!-- .VL 15 --> +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>device_id</term> + <listitem> + <para> +Specifies which button device was supposed to have caused the input action. +This is a provision for future support of multiple (distinguishable) button +devices, and should always be set to 0 for now. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>delay</term> + <listitem> + <para> +Specifies the time (in milliseconds) to wait before the input action. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>button_number</term> + <listitem> + <para> +Specifies which button is being acted upon. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>button_action</term> + <listitem> + <para> +Specifies the action to be performed (one of +<emphasis>XTestPRESS</emphasis>, +<emphasis>XTestRELEASE</emphasis>, or +<emphasis>XTestSTROKE</emphasis>). + </para> + </listitem> + </varlistentry> +</variablelist> + +<para> +The +<function>XTestPressButton</function> +function creates input actions to be sent to the the server. +The input actions will be accumulated in a request defined by this extension +until the request is full or the XTestFlush function is called. +They will then be sent to the server. +When the input actions are sent to the server, the input actions will cause +the server to think that the specified button was moved as specified. +</para> +<para> +The +<function>XTestPressButton</function> +function will return -1 if there is an error, and 0 otherwise. +</para> +</sect3> + +<sect3 id="xtestpresskey"> +<title>XTestPressKey</title> + +<funcsynopsis> +<funcprototype> + <funcdef>int <function>XTestPressKey</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>int <parameter>device_id</parameter></paramdef> + <paramdef>unsigned long <parameter>delay</parameter></paramdef> + <paramdef>unsigned int <parameter>keycode</parameter></paramdef> + <paramdef>unsigned int <parameter>key_action</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<!-- .VL 12 --> +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>device_id</term> + <listitem> + <para> +Specifies which keyboard device was supposed to have caused the input action. +This is a provision for future support of multiple (distinguishable) keyboard +devices, and should always be set to 0 for now. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>delay</term> + <listitem> + <para> +Specifies the time (in milliseconds) to wait before the input action. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>keycode</term> + <listitem> + <para> +Specifies which keycode is being acted upon. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>key_action</term> + <listitem> + <para> +Specifies the action to be performed (one of +<emphasis>XTestPRESS</emphasis>, +<emphasis>XTestRELEASE</emphasis>, or +<emphasis>XTestSTROKE</emphasis>). + </para> + </listitem> + </varlistentry> +</variablelist> + + +<para> +The +<function>XTestPressKey</function> +function creates input actions to be sent to the the server. +The input actions will be accumulated in a request defined by this extension +until the request is full or the XTestFlush function is called. +They will then be sent to the server. +When the input actions are sent to the server, the input actions will cause +the server to think that the specified key on the keyboard was moved as +specified. +</para> + +<para> +The +<function>XTestPressKey</function> +function will return -1 if there is an error, and 0 otherwise. +</para> + +</sect3> +<sect3 id="xtestflush"> +<title>XTestFlush</title> + +<funcsynopsis> +<funcprototype> + <funcdef>int <function>XTestFlush</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> +</funcprototype> +</funcsynopsis> + +<!-- .VL 9 --> +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> +</variablelist> + +<para> +The +<function>XTestFlush</function> +will send any remaining input actions to the server. +</para> + +<para> +The +<function>XTestFlush</function> +function will return -1 if there is an error, and 0 otherwise. +</para> + +</sect3> +</sect2> + +<!-- .H 2 Low~Level~Functions --> +<sect2 id="low_level_functions"> +<title>Low Level Functions</title> + +<!-- .H 3 XTestGetInput --> +<sect3 id="xtestgetinput"> +<title>XTestGetInput</title> + +<funcsynopsis> +<funcprototype> + <funcdef>int <function>XTestGetInput</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>int <parameter>action_handling</parameter></paramdef> +</funcprototype> +</funcsynopsis> + + +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>action_handling</term> + <listitem> + <para> +Specifies to the server what to do with the user input actions. (one of +0, <emphasis>XTestPACKED_MOTION</emphasis> or +<emphasis>XTestPACKED_ACTIONS</emphasis>; optionally 'or'ed +with <emphasis>XTestEXCLUSIVE</emphasis>). + </para> + </listitem> + </varlistentry> +</variablelist> + + +<para> +The +<function>XTestGetInput</function> +function tells the server to begin putting information about user input actions +into events to be sent to the client that called this function. These events +can be read via the Xlib <function>XNextEvent</function>fR function. +</para> + +<para> +The server assigns an event type of +<emphasis>XTestInputActionType</emphasis> to these events +to distinguish them from other events. +Since the actual value of the event type may vary depending on how many +extensions are included with an X11 implementation, +<emphasis>XTestInputActionType</emphasis> is a variable that will be +contained in the Xlib +part of this extension. It may be referenced as follows: +</para> + +<para> +extern int XTestInputActionType; +</para> + +<itemizedlist> + <listitem> + <para> +An <emphasis>action_handling</emphasis> value of 0 causes the server +to send one user input action in each +<emphasis>XTestInputActionType</emphasis> event. +This can sometimes cause performance problems. + </para> + </listitem> + <listitem> + <para> +An <emphasis>action_handling</emphasis> value of +<emphasis>XTestPACKED_ACTIONS</emphasis> causes the server +to pack as many user input actions as possible into a +<emphasis>XTestInputActionType</emphasis> event. +This is needed if user input actions are happening rapidly (such as +when the user moves the pointer) to keep performance at a reasonable level. + </para> + </listitem> + <listitem> + <para> +An <emphasis>action_handling</emphasis> value of +<emphasis>XTestPACKED_MOTION</emphasis> causes the server +to pack only user input actions associated with moving the pointer. +This allows the +client to receive button and key motions as they happen without waiting for the +event to fill up, while still keeping performance at a reasonable level. + </para> + </listitem> + <listitem> + <para> +An <emphasis>action_handling</emphasis> value with +<emphasis>XTestEXCLUSIVE</emphasis> 'or'ed in +causes the server to send user input actions only to the client. +The effect on the server is as if the user had performed no input actions. + </para> + </listitem> + <listitem> + <para> +An <emphasis>action_handling</emphasis> value without +<emphasis>XTestEXCLUSIVE</emphasis> +causes the server to copy user input actions, sending one copy to the +client, and handling the other copy normally (as it would if this extension +were not installed). + </para> + </listitem> +</itemizedlist> + +<para> +There are four types of input actions that are passed from the server +to the client. They are: +</para> + +<variablelist> + <varlistentry> + <term>key/button~state~change</term> + <listitem> + <para> +This type of input action contains the keycode of the key or button that +changed state; +whether the key or button is up or down, +and the time delay between this input action and the previous input action. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>pointer~motions</term> + <listitem> + <para> +This type of input action contains information about the motion of the +pointer when the pointer has only moved a short distance. +If the pointer has moved a long distance, +the pointer jump input action is used. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>pointer~jumps</term> + <listitem> + <para> +This type of input action contains information about the motion of the +pointer when the pointer has moved a long distance. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>delays</term> + <listitem> + <para> +This type of input action is used when the delay between input actions is too +large to be held in the other input actions. + </para> + </listitem> + </varlistentry> +</variablelist> + +<para> +The +<function>XTestGetInput</function> +function will return -1 if there is an error, and 0 otherwise. +</para> +<para> +An error code of <emphasis>BadAccess</emphasis> means that another client +has already requested that user input actions be sent to it. +</para> + +</sect3> + +<!-- .H 3 XTestStopInput --> +<sect3 id="xteststopinput"> +<title>XTestStopInput</title> + +<funcsynopsis> +<funcprototype> + <funcdef>int <function>XTestStopInput</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> +</funcprototype> +</funcsynopsis> + + + +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> +</variablelist> + +<para> +The +<function>XTestStopInput</function> +function tells the server to stop putting information about user input actions +into events. +The server will process user input actions normally (as it would +if this extension were not in the server). +</para> + +<para> +The +<function>XTestStopInput</function> +function will return -1 if there is an error, and 0 otherwise. +</para> + +<para> +An error code of <emphasis>BadAccess</emphasis> means that a request +was made to stop input when input has never been started. +</para> + +</sect3> + +<!-- .H 3 XTestFakeInput --> +<sect3 id="xtestfakeinput"> +<title>XTestFakeInput</title> + +<funcsynopsis> +<funcprototype> + <funcdef>int <function>XTestFakeInput</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>char <parameter>*action_list_addr</parameter></paramdef> + <paramdef>int <parameter>action_list_size</parameter></paramdef> + <paramdef>int <parameter>ack_flag</parameter></paramdef> +</funcprototype> +</funcsynopsis> + + +<!-- .VL 18 --> + +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>action_list_addr</term> + <listitem> + <para> +Specifies the address of an list of input actions to be sent to the server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>action_list_size</term> + <listitem> + <para> +Specifies the size (in bytes) of the list of input actions. +It may be no larger than <emphasis>XTestMAX_ACTION_LIST_SIZE</emphasis> bytes. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>ack_flag</term> + <listitem> + <para> +Specifies whether the server needs to send an event to indicate that its +input action buffer is empty (one of +<emphasis>XTestFAKE_ACK_NOT_NEEDED</emphasis> or +<emphasis>XTestFAKE_ACK_REQUEST</emphasis>). + </para> + </listitem> + </varlistentry> +</variablelist> + +<para> +The +<function>XTestFakeInput</function> +function tells the server to take the specified user input actions and process +them as if the user had physically performed them. +</para> + +<para> +The server can only accept a limited number of input actions at one +time. This limit can be determined by the +<function>XTestQueryInputSize</function> function +in this extension. +</para> + +<para> +The client should set <emphasis>ack_flag</emphasis> to +<emphasis>XTestFAKE_ACK_NOT_NEEDED</emphasis> +on calls to <emphasis>XTestFakeInput</emphasis> that do not reach this limit. +</para> + +<para> +The client should set <emphasis>ack_flag</emphasis> to +<emphasis>XTestFAKE_ACK_REQUEST</emphasis> +on the call to <emphasis>XTestFakeInput</emphasis> that reaches this limit. +</para> + +<para> +When the server sees an <emphasis>ack_flag</emphasis> value of +<emphasis>XTestFAKE_ACK_REQUEST</emphasis> +it finishes processing its input action buffer, then sends an event with +type <emphasis>XTestFakeAckType</emphasis> to the client. +When the client reads this event, it knows that it is safe to resume +sending input actions to the server. +</para> + +<para> +Since the actual value of the event type may vary depending on how many +extensions are included with an X11 implementation, +<emphasis>XTestFakeAckType</emphasis> is a variable that is contained +in the Xlib part of this extension. It may be referenced as follows: +</para> + +<para> +extern int XTestFakeAckType; +</para> + +<para> +There are four types of input actions that are passed from the client +to the server. They are: +</para> + +<variablelist> + <varlistentry> + <term>key/button~state~change</term> + <listitem> + <para> +This type of input action contains the keycode of the key or button that +is to change state; +whether the key or button is to be up or down, +and the time to delay before changing the state of the key or button. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>pointer~motions</term> + <listitem> + <para> +This type of input action contains information about the motion of the +pointer when the pointer is to be moved a short distance, +and the time to delay before moving the pointer. +If the pointer is to be moved a long distance, +the pointer jump input action must be used. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>pointer~jumps</term> + <listitem> + <para> +This type of input action contains information about the motion of the +pointer when the pointer is to be moved a long distance, +and the time to delay before moving the pointer. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>delays</term> + <listitem> + <para> +This type of input action is used when the delay between input actions is too +large to be held in the other input actions. + </para> + </listitem> + </varlistentry> +</variablelist> + + +<para> +The +<function>XTestFakeInput</function> +function will return -1 if there is an error, and 0 otherwise. +</para> + +<para> +An error code of \fIBadAccess\fR means that another client has already +sent user input actions to the server, and the server has not finished +processing the user input actions. +</para> + +</sect3> + +<!-- .H 3 XTestQueryInputSize --> +<sect3 id="xtestqueryinputsize"> +<title>XTestQueryInputSize</title> + +<funcsynopsis> +<funcprototype> + <funcdef>int <function>XTestQueryInputSize</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> + <paramdef>unsigned long <parameter>size_return</parameter></paramdef> +</funcprototype> +</funcsynopsis> + + +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>size_return</term> + <listitem> + <para> +Returns the number of input actions that the server's input action buffer can +hold. + </para> + </listitem> + </varlistentry> +</variablelist> + +<para> +The +<function>XTestQueryInputSize</function> +function asks the server to return the number of input actions that it can hold +in its input action buffer in the unsigned long pointed to by \fIsize_return\fR. +</para> +<para> +The +<function>XTestQueryInputSize</function> +function will return -1 if there is an error, and 0 otherwise. +</para> +</sect3> + +<!-- .H 3 XTestReset --> +<sect3 id="xtestreset"> +<title>XTestReset</title> + +<funcsynopsis> +<funcprototype> + <funcdef>int <function>XTestReset</function></funcdef> + <paramdef>Display <parameter>*display</parameter></paramdef> +</funcprototype> +</funcsynopsis> + + +<variablelist> + <varlistentry> + <term>display</term> + <listitem> + <para> +Specifies the connection to the X server. + </para> + </listitem> + </varlistentry> +</variablelist> + +<para> +The +<function>XTestReset</function> +function tells the server to set everything having to do with this extension +back to its initial state. After this call the server will act as if this +extension were not installed until one of the extension functions is called by +a client. This function is not normally needed, but is included in case a +client wishes to clean up the server state, such as after a serious error. +</para> + +<para> +The +<function>XTestReset</function> +function will return -1 if there is an error, and 0 otherwise. +</para> + +</sect3> +</sect2> +</sect1> + +<!-- .H 1 'xtestext1.h'~File~Listing --> +<!-- .so xtestext1.h --> +<!-- .TC 1 1 4 --> +</article> diff --git a/libXmu/doc/Xmu.xml b/libXmu/doc/Xmu.xml index b1817991d..43d8047c9 100644 --- a/libXmu/doc/Xmu.xml +++ b/libXmu/doc/Xmu.xml @@ -1,19 +1,22 @@ <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> + "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" +[ +<!ENTITY % defs SYSTEM "defs.ent"> %defs; +]> <!-- lifted from troff+ms+XMan by doclifter --> <article id='xmu'> <articleinfo> <title>Xmu and Xmuu Library API Reference</title> + <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo> + <copyright><year>1989</year><holder>X Consortium</holder> + </copyright> <abstract><para>“Don't ask.”</para></abstract> <legalnotice> <para> -Copyright © 1989 X Consortium - </para> - <para> 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 diff --git a/libXmu/docbook.am b/libXmu/docbook.am index 4809ce3be..bba4d5453 100644 --- a/libXmu/docbook.am +++ b/libXmu/docbook.am @@ -21,76 +21,82 @@ shelf_DATA = dist_shelf_DATA = $(docbook) $(chapters) if HAVE_XMLTO -# -# Generate DocBook/XML output formats with or without stylesheets -# - -# Stylesheets are available if the package xorg-sgml-doctools is installed if HAVE_STYLESHEETS -# The location where all cross reference databases are installed -sgmldbsdir = $(XORG_SGML_PATH)/X11/dbs -masterdb = "$(sgmldbsdir)/masterdb$(suffix $@).xml" -XMLTO_FLAGS = \ - --searchpath "$(XORG_SGML_PATH)/X11" \ - --stringparam target.database.document=$(masterdb) \ - --stringparam current.docid="$(<:.xml=)" \ - --stringparam collect.xref.targets="no" - -XMLTO_XHTML_FLAGS = \ - -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl \ - --stringparam html.stylesheet=$(STYLESHEET_SRCDIR)/xorg.css - -# Caution: img.src.path *must* not be used for html. Pdf copies the image. -XMLTO_FO_FLAGS = \ - -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl \ - --stringparam img.src.path=$(abs_builddir)/ -endif HAVE_STYLESHEETS +XMLTO_SEARCHPATH_FLAGS = \ + --searchpath "$(XORG_SGML_PATH)/X11" \ + --searchpath "$(abs_top_builddir)" +XMLTO_HTML_OLINK_FLAGS = \ + --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.html.xml \ + --stringparam current.docid="$(<:.xml=)" +XMLTO_HTML_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl +XMLTO_HTML_FLAGS = \ + $(XMLTO_SEARCHPATH_FLAGS) \ + $(XMLTO_HTML_STYLESHEET_FLAGS) \ + $(XMLTO_HTML_OLINK_FLAGS) shelf_DATA += $(docbook:.xml=.html) -%.html: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) xhtml-nochunks $< - -if HAVE_FOP -shelf_DATA += $(docbook:.xml=.pdf) $(docbook:.xml=.ps) -%.pdf: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop pdf $< -%.ps: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_FO_FLAGS) --with-fop ps $< -endif HAVE_FOP +%.html: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) xhtml-nochunks $< if HAVE_XMLTO_TEXT + shelf_DATA += $(docbook:.xml=.txt) %.txt: %.xml $(chapters) - $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) $(XMLTO_XHTML_FLAGS) txt $< + $(AM_V_GEN)$(XMLTO) $(XMLTO_HTML_FLAGS) txt $< endif HAVE_XMLTO_TEXT -# -# Generate documents cross-reference target databases -# +if HAVE_FOP +XMLTO_FO_IMAGEPATH_FLAGS = --stringparam img.src.path=$(abs_builddir)/ +XMLTO_PDF_OLINK_FLAGS = \ + --stringparam target.database.document=$(XORG_SGML_PATH)/X11/dbs/masterdb.pdf.xml \ + --stringparam current.docid="$(<:.xml=)" +XMLTO_FO_STYLESHEET_FLAGS = -x $(STYLESHEET_SRCDIR)/xorg-fo.xsl + +XMLTO_FO_FLAGS = \ + $(XMLTO_SEARCHPATH_FLAGS) \ + $(XMLTO_FO_STYLESHEET_FLAGS) \ + $(XMLTO_FO_IMAGEPATH_FLAGS) \ + $(XMLTO_PDF_OLINK_FLAGS) + +shelf_DATA += $(docbook:.xml=.pdf) +%.pdf: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop pdf $< -# This is only possible if the xorg-sgml-doctools package is installed -if HAVE_STYLESHEETS -if HAVE_XSLTPROC +shelf_DATA += $(docbook:.xml=.ps) +%.ps: %.xml $(chapters) + $(AM_V_GEN)$(XMLTO) $(XMLTO_FO_FLAGS) --with-fop ps $< +endif HAVE_FOP -# DocBook/XML generated document cross-reference database -shelf_DATA += $(docbook:.xml=.html.db) $(docbook:.xml=.fo.db) +# Generate documents cross-reference target databases +if HAVE_XSLTPROC -# Generate DocBook/XML document cross-reference database -# Flags for the XSL Transformation processor generating xref target databases -XSLTPROC_FLAGS = \ +XSLT_SEARCHPATH_FLAGS = \ --path "$(XORG_SGML_PATH)/X11" \ - --stringparam targets.filename "$@" \ - --stringparam collect.xref.targets "only" \ - --nonet --xinclude - + --path "$(abs_top_builddir)" +XSLT_OLINK_FLAGS = \ + --stringparam targets.filename "$@" \ + --stringparam collect.xref.targets "only" \ + --stringparam olink.base.uri "$(@:.db=)" + +XSLT_HTML_FLAGS = \ + $(XSLT_SEARCHPATH_FLAGS) \ + $(XSLT_OLINK_FLAGS) \ + --nonet --xinclude \ + $(STYLESHEET_SRCDIR)/xorg-xhtml.xsl +XSLT_PDF_FLAGS = \ + $(XSLT_SEARCHPATH_FLAGS) \ + $(XSLT_OLINK_FLAGS) \ + --nonet --xinclude \ + $(STYLESHEET_SRCDIR)/xorg-fo.xsl + +shelf_DATA += $(docbook:.xml=.html.db) %.html.db: %.xml $(chapters) - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \ - http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl $< + $(AM_V_GEN)$(XSLTPROC) $(XSLT_HTML_FLAGS) $< -%.fo.db: %.xml $(chapters) - $(AM_V_GEN)$(XSLTPROC) $(XSLTPROC_FLAGS) \ - http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl $< +shelf_DATA += $(docbook:.xml=.pdf.db) +%.pdf.db: %.xml $(chapters) + $(AM_V_GEN)$(XSLTPROC) $(XSLT_PDF_FLAGS) $< endif HAVE_XSLTPROC endif HAVE_STYLESHEETS diff --git a/mesalib/scons/mslib_sa.py b/mesalib/scons/mslib_sa.py deleted file mode 100644 index d7957f705..000000000 --- a/mesalib/scons/mslib_sa.py +++ /dev/null @@ -1,137 +0,0 @@ -"""mslib_sa
-
-Tool-specific initialization for lib (MicroSoft library archiver).
-
-Based on SCons.Tool.mslib, without the MSVC detection.
-
-"""
-
-#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-import os
-import tempfile
-import string
-
-import SCons.Defaults
-import SCons.Tool
-import SCons.Util
-import SCons.Errors
-
-class TempFileMunge:
- """Same as SCons.Platform.TempFileMunge, but preserves LINK /LIB
- together."""
-
- def __init__(self, cmd):
- self.cmd = cmd
-
- def __call__(self, target, source, env, for_signature):
- if for_signature:
- return self.cmd
- cmd = env.subst_list(self.cmd, 0, target, source)[0]
- try:
- maxline = int(env.subst('$MAXLINELENGTH'))
- except ValueError:
- maxline = 2048
-
- if (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= maxline:
- return self.cmd
-
- # We do a normpath because mktemp() has what appears to be
- # a bug in Windows that will use a forward slash as a path
- # delimiter. Windows's link mistakes that for a command line
- # switch and barfs.
- #
- # We use the .lnk suffix for the benefit of the Phar Lap
- # linkloc linker, which likes to append an .lnk suffix if
- # none is given.
- tmp = os.path.normpath(tempfile.mktemp('.lnk'))
- native_tmp = SCons.Util.get_native_path(tmp)
-
- if env['SHELL'] and env['SHELL'] == 'sh':
- # The sh shell will try to escape the backslashes in the
- # path, so unescape them.
- native_tmp = string.replace(native_tmp, '\\', r'\\\\')
- # In Cygwin, we want to use rm to delete the temporary
- # file, because del does not exist in the sh shell.
- rm = env.Detect('rm') or 'del'
- else:
- # Don't use 'rm' if the shell is not sh, because rm won't
- # work with the Windows shells (cmd.exe or command.com) or
- # Windows path names.
- rm = 'del'
-
- prefix = env.subst('$TEMPFILEPREFIX')
- if not prefix:
- prefix = '@'
-
- if cmd[0:2] == ['link', '/lib']:
- split = 2
- else:
- split = 1
-
- args = map(SCons.Subst.quote_spaces, cmd[split:])
- open(tmp, 'w').write(string.join(args, " ") + "\n")
- # XXX Using the SCons.Action.print_actions value directly
- # like this is bogus, but expedient. This class should
- # really be rewritten as an Action that defines the
- # __call__() and strfunction() methods and lets the
- # normal action-execution logic handle whether or not to
- # print/execute the action. The problem, though, is all
- # of that is decided before we execute this method as
- # part of expanding the $TEMPFILE construction variable.
- # Consequently, refactoring this will have to wait until
- # we get more flexible with allowing Actions to exist
- # independently and get strung together arbitrarily like
- # Ant tasks. In the meantime, it's going to be more
- # user-friendly to not let obsession with architectural
- # purity get in the way of just being helpful, so we'll
- # reach into SCons.Action directly.
- if SCons.Action.print_actions:
- print("Using tempfile "+native_tmp+" for command line:\n"+
- " ".join(map(str,cmd)))
- return cmd[:split] + [ prefix + native_tmp + '\n' + rm, native_tmp ]
-
-def generate(env):
- """Add Builders and construction variables for lib to an Environment."""
- SCons.Tool.createStaticLibBuilder(env)
-
- if env.Detect('lib'):
- env['AR'] = 'lib'
- else:
- # Recent WINDDK versions do not ship with lib.
- env['AR'] = 'link /lib'
- env['TEMPFILE'] = TempFileMunge
- env['ARFLAGS'] = SCons.Util.CLVar('/nologo')
- env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}"
- env['LIBPREFIX'] = ''
- env['LIBSUFFIX'] = '.lib'
-
-def exists(env):
- return env.Detect('lib') or env.Detect('link')
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/mesalib/scons/mslink_sa.py b/mesalib/scons/mslink_sa.py deleted file mode 100644 index a0cfde33e..000000000 --- a/mesalib/scons/mslink_sa.py +++ /dev/null @@ -1,246 +0,0 @@ -"""mslink_sa
-
-Tool-specific initialization for the Microsoft linker.
-
-Based on SCons.Tool.mslink, without the MSVS detection.
-
-"""
-
-#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-import os.path
-
-import SCons.Action
-import SCons.Defaults
-import SCons.Errors
-import SCons.Platform.win32
-import SCons.Tool
-import SCons.Tool.msvc
-import SCons.Util
-
-def pdbGenerator(env, target, source, for_signature):
- try:
- return ['/PDB:%s' % target[0].attributes.pdb, '/DEBUG']
- except (AttributeError, IndexError):
- return None
-
-def _dllTargets(target, source, env, for_signature, paramtp):
- listCmd = []
- dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp)
- if dll: listCmd.append("/out:%s"%dll.get_string(for_signature))
-
- implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX')
- if implib: listCmd.append("/implib:%s"%implib.get_string(for_signature))
-
- return listCmd
-
-def _dllSources(target, source, env, for_signature, paramtp):
- listCmd = []
-
- deffile = env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")
- for src in source:
- # Check explicitly for a non-None deffile so that the __cmp__
- # method of the base SCons.Util.Proxy class used for some Node
- # proxies doesn't try to use a non-existent __dict__ attribute.
- if deffile and src == deffile:
- # Treat this source as a .def file.
- listCmd.append("/def:%s" % src.get_string(for_signature))
- else:
- # Just treat it as a generic source file.
- listCmd.append(src)
- return listCmd
-
-def windowsShlinkTargets(target, source, env, for_signature):
- return _dllTargets(target, source, env, for_signature, 'SHLIB')
-
-def windowsShlinkSources(target, source, env, for_signature):
- return _dllSources(target, source, env, for_signature, 'SHLIB')
-
-def _windowsLdmodTargets(target, source, env, for_signature):
- """Get targets for loadable modules."""
- return _dllTargets(target, source, env, for_signature, 'LDMODULE')
-
-def _windowsLdmodSources(target, source, env, for_signature):
- """Get sources for loadable modules."""
- return _dllSources(target, source, env, for_signature, 'LDMODULE')
-
-def _dllEmitter(target, source, env, paramtp):
- """Common implementation of dll emitter."""
- SCons.Tool.msvc.validate_vars(env)
-
- extratargets = []
- extrasources = []
-
- dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp)
- no_import_lib = env.get('no_import_lib', 0)
-
- if not dll:
- raise SCons.Errors.UserError, 'A shared library should have exactly one target with the suffix: %s' % env.subst('$%sSUFFIX' % paramtp)
-
- insert_def = env.subst("$WINDOWS_INSERT_DEF")
- if not insert_def in ['', '0', 0] and \
- not env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"):
-
- # append a def file to the list of sources
- extrasources.append(
- env.ReplaceIxes(dll,
- '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,
- "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"))
-
- if env.has_key('PDB') and env['PDB']:
- pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
- extratargets.append(pdb)
- target[0].attributes.pdb = pdb
-
- if not no_import_lib and \
- not env.FindIxes(target, "LIBPREFIX", "LIBSUFFIX"):
- # Append an import library to the list of targets.
- extratargets.append(
- env.ReplaceIxes(dll,
- '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,
- "LIBPREFIX", "LIBSUFFIX"))
- # and .exp file is created if there are exports from a DLL
- extratargets.append(
- env.ReplaceIxes(dll,
- '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,
- "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX"))
-
- return (target+extratargets, source+extrasources)
-
-def windowsLibEmitter(target, source, env):
- return _dllEmitter(target, source, env, 'SHLIB')
-
-def ldmodEmitter(target, source, env):
- """Emitter for loadable modules.
-
- Loadable modules are identical to shared libraries on Windows, but building
- them is subject to different parameters (LDMODULE*).
- """
- return _dllEmitter(target, source, env, 'LDMODULE')
-
-def prog_emitter(target, source, env):
- SCons.Tool.msvc.validate_vars(env)
-
- extratargets = []
-
- exe = env.FindIxes(target, "PROGPREFIX", "PROGSUFFIX")
- if not exe:
- raise SCons.Errors.UserError, "An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX")
-
- if env.has_key('PDB') and env['PDB']:
- pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
- extratargets.append(pdb)
- target[0].attributes.pdb = pdb
-
- return (target+extratargets,source)
-
-def RegServerFunc(target, source, env):
- if env.has_key('register') and env['register']:
- ret = regServerAction([target[0]], [source[0]], env)
- if ret:
- raise SCons.Errors.UserError, "Unable to register %s" % target[0]
- else:
- print "Registered %s sucessfully" % target[0]
- return ret
- return 0
-
-regServerAction = SCons.Action.Action("$REGSVRCOM", "$REGSVRCOMSTR")
-regServerCheck = SCons.Action.Action(RegServerFunc, None)
-shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}')
-compositeShLinkAction = shlibLinkAction + regServerCheck
-ldmodLinkAction = SCons.Action.Action('${TEMPFILE("$LDMODULE $LDMODULEFLAGS $_LDMODULE_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_LDMODULE_SOURCES")}')
-compositeLdmodAction = ldmodLinkAction + regServerCheck
-
-def generate(env):
- """Add Builders and construction variables for ar to an Environment."""
- SCons.Tool.createSharedLibBuilder(env)
- SCons.Tool.createProgBuilder(env)
-
- env['SHLINK'] = '$LINK'
- env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll')
- env['_SHLINK_TARGETS'] = windowsShlinkTargets
- env['_SHLINK_SOURCES'] = windowsShlinkSources
- env['SHLINKCOM'] = compositeShLinkAction
- env.Append(SHLIBEMITTER = [windowsLibEmitter])
- env['LINK'] = 'link'
- env['LINKFLAGS'] = SCons.Util.CLVar('/nologo')
- env['_PDB'] = pdbGenerator
- env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows")}'
- env.Append(PROGEMITTER = [prog_emitter])
- env['LIBDIRPREFIX']='/LIBPATH:'
- env['LIBDIRSUFFIX']=''
- env['LIBLINKPREFIX']=''
- env['LIBLINKSUFFIX']='$LIBSUFFIX'
-
- env['WIN32DEFPREFIX'] = ''
- env['WIN32DEFSUFFIX'] = '.def'
- env['WIN32_INSERT_DEF'] = 0
- env['WINDOWSDEFPREFIX'] = '${WIN32DEFPREFIX}'
- env['WINDOWSDEFSUFFIX'] = '${WIN32DEFSUFFIX}'
- env['WINDOWS_INSERT_DEF'] = '${WIN32_INSERT_DEF}'
-
- env['WIN32EXPPREFIX'] = ''
- env['WIN32EXPSUFFIX'] = '.exp'
- env['WINDOWSEXPPREFIX'] = '${WIN32EXPPREFIX}'
- env['WINDOWSEXPSUFFIX'] = '${WIN32EXPSUFFIX}'
-
- env['WINDOWSSHLIBMANIFESTPREFIX'] = ''
- env['WINDOWSSHLIBMANIFESTSUFFIX'] = '${SHLIBSUFFIX}.manifest'
- env['WINDOWSPROGMANIFESTPREFIX'] = ''
- env['WINDOWSPROGMANIFESTSUFFIX'] = '${PROGSUFFIX}.manifest'
-
- env['REGSVRACTION'] = regServerCheck
- env['REGSVR'] = os.path.join(SCons.Platform.win32.get_system_root(),'System32','regsvr32')
- env['REGSVRFLAGS'] = '/s '
- env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}'
-
- # Loadable modules are on Windows the same as shared libraries, but they
- # are subject to different build parameters (LDMODULE* variables).
- # Therefore LDMODULE* variables correspond as much as possible to
- # SHLINK*/SHLIB* ones.
- SCons.Tool.createLoadableModuleBuilder(env)
- env['LDMODULE'] = '$SHLINK'
- env['LDMODULEPREFIX'] = '$SHLIBPREFIX'
- env['LDMODULESUFFIX'] = '$SHLIBSUFFIX'
- env['LDMODULEFLAGS'] = '$SHLINKFLAGS'
- env['_LDMODULE_TARGETS'] = _windowsLdmodTargets
- env['_LDMODULE_SOURCES'] = _windowsLdmodSources
- env['LDMODULEEMITTER'] = [ldmodEmitter]
- env['LDMODULECOM'] = compositeLdmodAction
-
-def exists(env):
- platform = env.get('PLATFORM', '')
- if platform in ('win32', 'cygwin'):
- # Only explicitly search for a 'link' executable on Windows
- # systems. Some other systems (e.g. Ubuntu Linux) have an
- # executable named 'link' and we don't want that to make SCons
- # think Visual Studio is installed.
- return env.Detect('link')
- return None
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/mesalib/scons/msvc_sa.py b/mesalib/scons/msvc_sa.py deleted file mode 100644 index 0bfc8920f..000000000 --- a/mesalib/scons/msvc_sa.py +++ /dev/null @@ -1,246 +0,0 @@ -"""msvc_sa
-
-Tool-specific initialization for Microsoft Visual C/C++.
-
-Based on SCons.Tool.msvc, without the MSVS detection.
-
-"""
-
-#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-import os.path
-import re
-import string
-
-import SCons.Action
-import SCons.Builder
-import SCons.Errors
-import SCons.Platform.win32
-import SCons.Tool
-import SCons.Util
-import SCons.Warnings
-import SCons.Scanner.RC
-
-CSuffixes = ['.c', '.C']
-CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
-
-def validate_vars(env):
- """Validate the PCH and PCHSTOP construction variables."""
- if env.has_key('PCH') and env['PCH']:
- if not env.has_key('PCHSTOP'):
- raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
- if not SCons.Util.is_String(env['PCHSTOP']):
- raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']
-
-def pch_emitter(target, source, env):
- """Adds the object file target."""
-
- validate_vars(env)
-
- pch = None
- obj = None
-
- for t in target:
- if SCons.Util.splitext(str(t))[1] == '.pch':
- pch = t
- if SCons.Util.splitext(str(t))[1] == '.obj':
- obj = t
-
- if not obj:
- obj = SCons.Util.splitext(str(pch))[0]+'.obj'
-
- target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work
-
- return (target, source)
-
-def object_emitter(target, source, env, parent_emitter):
- """Sets up the PCH dependencies for an object file."""
-
- validate_vars(env)
-
- parent_emitter(target, source, env)
-
- if env.has_key('PCH') and env['PCH']:
- env.Depends(target, env['PCH'])
-
- return (target, source)
-
-def static_object_emitter(target, source, env):
- return object_emitter(target, source, env,
- SCons.Defaults.StaticObjectEmitter)
-
-def shared_object_emitter(target, source, env):
- return object_emitter(target, source, env,
- SCons.Defaults.SharedObjectEmitter)
-
-pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR')
-pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch',
- emitter=pch_emitter,
- source_scanner=SCons.Tool.SourceFileScanner)
-
-
-# Logic to build .rc files into .res files (resource files)
-res_scanner = SCons.Scanner.RC.RCScan()
-res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')
-res_builder = SCons.Builder.Builder(action=res_action,
- src_suffix='.rc',
- suffix='.res',
- src_builder=[],
- source_scanner=res_scanner)
-
-def msvc_batch_key(action, env, target, source):
- """
- Returns a key to identify unique batches of sources for compilation.
-
- If batching is enabled (via the $MSVC_BATCH setting), then all
- target+source pairs that use the same action, defined by the same
- environment, and have the same target and source directories, will
- be batched.
-
- Returning None specifies that the specified target+source should not
- be batched with other compilations.
- """
- b = env.subst('$MSVC_BATCH')
- if b in (None, '', '0'):
- # We're not using batching; return no key.
- return None
- t = target[0]
- s = source[0]
- if os.path.splitext(t.name)[0] != os.path.splitext(s.name)[0]:
- # The base names are different, so this *must* be compiled
- # separately; return no key.
- return None
- return (id(action), id(env), t.dir, s.dir)
-
-def msvc_output_flag(target, source, env, for_signature):
- """
- Returns the correct /Fo flag for batching.
-
- If batching is disabled or there's only one source file, then we
- return an /Fo string that specifies the target explicitly. Otherwise,
- we return an /Fo string that just specifies the first target's
- directory (where the Visual C/C++ compiler will put the .obj files).
- """
- b = env.subst('$MSVC_BATCH')
- if b in (None, '', '0') or len(source) == 1:
- return '/Fo$TARGET'
- else:
- # The Visual C/C++ compiler requires a \ at the end of the /Fo
- # option to indicate an output directory. We use os.sep here so
- # that the test(s) for this can be run on non-Windows systems
- # without having a hard-coded backslash mess up command-line
- # argument parsing.
- return '/Fo${TARGET.dir}' + os.sep
-
-CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR",
- batch_key=msvc_batch_key,
- targets='$CHANGED_TARGETS')
-ShCAction = SCons.Action.Action("$SHCCCOM", "$SHCCCOMSTR",
- batch_key=msvc_batch_key,
- targets='$CHANGED_TARGETS')
-CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR",
- batch_key=msvc_batch_key,
- targets='$CHANGED_TARGETS')
-ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR",
- batch_key=msvc_batch_key,
- targets='$CHANGED_TARGETS')
-
-def generate(env):
- """Add Builders and construction variables for MSVC++ to an Environment."""
- static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
-
- # TODO(batch): shouldn't reach in to cmdgen this way; necessary
- # for now to bypass the checks in Builder.DictCmdGenerator.__call__()
- # and allow .cc and .cpp to be compiled in the same command line.
- static_obj.cmdgen.source_ext_match = False
- shared_obj.cmdgen.source_ext_match = False
-
- for suffix in CSuffixes:
- static_obj.add_action(suffix, CAction)
- shared_obj.add_action(suffix, ShCAction)
- static_obj.add_emitter(suffix, static_object_emitter)
- shared_obj.add_emitter(suffix, shared_object_emitter)
-
- for suffix in CXXSuffixes:
- static_obj.add_action(suffix, CXXAction)
- shared_obj.add_action(suffix, ShCXXAction)
- static_obj.add_emitter(suffix, static_object_emitter)
- shared_obj.add_emitter(suffix, shared_object_emitter)
-
- env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
- env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'])
- env['_MSVC_OUTPUT_FLAG'] = msvc_output_flag
- env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS'
- env['CC'] = 'cl'
- env['CCFLAGS'] = SCons.Util.CLVar('/nologo')
- env['CFLAGS'] = SCons.Util.CLVar('')
- env['CCCOM'] = '$CC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM'
- env['SHCC'] = '$CC'
- env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
- env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS')
- env['SHCCCOM'] = '$SHCC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM'
- env['CXX'] = '$CC'
- env['CXXFLAGS'] = SCons.Util.CLVar('$( /TP $)')
- env['CXXCOM'] = '$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM'
- env['SHCXX'] = '$CXX'
- env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
- env['SHCXXCOM'] = '$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM'
- env['CPPDEFPREFIX'] = '/D'
- env['CPPDEFSUFFIX'] = ''
- env['INCPREFIX'] = '/I'
- env['INCSUFFIX'] = ''
-# env.Append(OBJEMITTER = [static_object_emitter])
-# env.Append(SHOBJEMITTER = [shared_object_emitter])
- env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
-
- env['RC'] = 'rc'
- env['RCFLAGS'] = SCons.Util.CLVar('')
- env['RCSUFFIXES']=['.rc','.rc2']
- env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
- env['BUILDERS']['RES'] = res_builder
- env['OBJPREFIX'] = ''
- env['OBJSUFFIX'] = '.obj'
- env['SHOBJPREFIX'] = '$OBJPREFIX'
- env['SHOBJSUFFIX'] = '$OBJSUFFIX'
-
- env['CFILESUFFIX'] = '.c'
- env['CXXFILESUFFIX'] = '.cc'
-
- env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}'])
- env['PCHCOM'] = '$CXX /Fo${TARGETS[1]} $CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
- env['BUILDERS']['PCH'] = pch_builder
-
- if not env.has_key('ENV'):
- env['ENV'] = {}
- if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders
- env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
-
-def exists(env):
- return env.Detect('cl')
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/mesalib/scons/wcesdk.py b/mesalib/scons/wcesdk.py deleted file mode 100644 index cd797a789..000000000 --- a/mesalib/scons/wcesdk.py +++ /dev/null @@ -1,176 +0,0 @@ -"""wcesdk
-
-Tool-specific initialization for Microsoft Window CE SDKs.
-
-"""
-
-#
-# Copyright (c) 2001-2007 The SCons Foundation
-# Copyright (c) 2008 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 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.
-#
-
-import os.path
-import re
-import string
-
-import SCons.Action
-import SCons.Builder
-import SCons.Errors
-import SCons.Platform.win32
-import SCons.Tool
-import SCons.Util
-import SCons.Warnings
-
-import msvc_sa
-import mslib_sa
-import mslink_sa
-
-def get_wce500_paths(env):
- """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
- of those three environment variables that should be set
- in order to execute the MSVC tools properly."""
-
- exe_paths = []
- lib_paths = []
- include_paths = []
-
- # mymic the batch files located in Microsoft eMbedded C++ 4.0\EVC\WCExxx\BIN
- os_version = os.environ.get('OSVERSION', 'WCE500')
- platform = os.environ.get('PLATFORM', 'STANDARDSDK_500')
- wce_root = os.environ.get('WCEROOT', 'C:\\Program Files\\Microsoft eMbedded C++ 4.0')
- sdk_root = os.environ.get('SDKROOT', 'C:\\Windows CE Tools')
-
- target_cpu = 'x86'
- cfg = 'none'
-
- exe_paths.append( os.path.join(wce_root, 'COMMON', 'EVC', 'bin') )
- exe_paths.append( os.path.join(wce_root, 'EVC', os_version, 'bin') )
- include_paths.append( os.path.join(sdk_root, os_version, platform, 'include', target_cpu) )
- include_paths.append( os.path.join(sdk_root, os_version, platform, 'MFC', 'include') )
- include_paths.append( os.path.join(sdk_root, os_version, platform, 'ATL', 'include') )
- lib_paths.append( os.path.join(sdk_root, os_version, platform, 'lib', target_cpu) )
- lib_paths.append( os.path.join(sdk_root, os_version, platform, 'MFC', 'lib', target_cpu) )
- lib_paths.append( os.path.join(sdk_root, os_version, platform, 'ATL', 'lib', target_cpu) )
-
- include_path = string.join( include_paths, os.pathsep )
- lib_path = string.join(lib_paths, os.pathsep )
- exe_path = string.join(exe_paths, os.pathsep )
- return (include_path, lib_path, exe_path)
-
-def get_wce600_root(env):
- try:
- return os.environ['_WINCEROOT']
- except KeyError:
- pass
-
- if SCons.Util.can_read_reg:
- key = r'SOFTWARE\Microsoft\Platform Builder\6.00\Directories\OS Install Dir'
- try:
- path, t = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE, key)
- except SCons.Util.RegError:
- pass
- else:
- return path
-
- default_path = os.path.join(r'C:\WINCE600', version)
- if os.path.exists(default_path):
- return default_path
-
- return None
-
-def get_wce600_paths(env):
- """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
- of those three environment variables that should be set
- in order to execute the MSVC tools properly."""
-
- exe_paths = []
- lib_paths = []
- include_paths = []
-
- # See also C:\WINCE600\public\common\oak\misc\wince.bat
-
- wince_root = get_wce600_root(env)
- if wince_root is None:
- raise SCons.Errors.InternalError, "Windows CE 6.0 SDK not found"
-
- os_version = os.environ.get('_WINCEOSVER', '600')
- platform_root = os.environ.get('_PLATFORMROOT', os.path.join(wince_root, 'platform'))
- sdk_root = os.environ.get('_SDKROOT' ,os.path.join(wince_root, 'sdk'))
-
- platform_root = os.environ.get('_PLATFORMROOT', os.path.join(wince_root, 'platform'))
- sdk_root = os.environ.get('_SDKROOT' ,os.path.join(wince_root, 'sdk'))
-
- host_cpu = os.environ.get('_HOSTCPUTYPE', 'i386')
- target_cpu = os.environ.get('_TGTCPU', 'x86')
-
- if env['build'] == 'debug':
- build = 'debug'
- else:
- build = 'retail'
-
- try:
- project_root = os.environ['_PROJECTROOT']
- except KeyError:
- # No project root defined -- use the common stuff instead
- project_root = os.path.join(wince_root, 'public', 'common')
-
- exe_paths.append( os.path.join(sdk_root, 'bin', host_cpu) )
- exe_paths.append( os.path.join(sdk_root, 'bin', host_cpu, target_cpu) )
- exe_paths.append( os.path.join(wince_root, 'common', 'oak', 'bin', host_cpu) )
- exe_paths.append( os.path.join(wince_root, 'common', 'oak', 'misc') )
-
- include_paths.append( os.path.join(project_root, 'sdk', 'inc') )
- include_paths.append( os.path.join(project_root, 'oak', 'inc') )
- include_paths.append( os.path.join(project_root, 'ddk', 'inc') )
- include_paths.append( os.path.join(sdk_root, 'CE', 'inc') )
-
- lib_paths.append( os.path.join(project_root, 'sdk', 'lib', target_cpu, build) )
- lib_paths.append( os.path.join(project_root, 'oak', 'lib', target_cpu, build) )
- lib_paths.append( os.path.join(project_root, 'ddk', 'lib', target_cpu, build) )
-
- include_path = string.join( include_paths, os.pathsep )
- lib_path = string.join(lib_paths, os.pathsep )
- exe_path = string.join(exe_paths, os.pathsep )
- return (include_path, lib_path, exe_path)
-
-def generate(env):
-
- msvc_sa.generate(env)
- mslib_sa.generate(env)
- mslink_sa.generate(env)
-
- if not env.has_key('ENV'):
- env['ENV'] = {}
-
- try:
- include_path, lib_path, exe_path = get_wce600_paths(env)
-
- env.PrependENVPath('INCLUDE', include_path)
- env.PrependENVPath('LIB', lib_path)
- env.PrependENVPath('PATH', exe_path)
- except (SCons.Util.RegError, SCons.Errors.InternalError):
- pass
-
-def exists(env):
- return get_wce600_root(env) is not None
-
-# vim:set ts=4 sw=4 et:
diff --git a/mesalib/scons/winddk.py b/mesalib/scons/winddk.py deleted file mode 100644 index 9e47b9428..000000000 --- a/mesalib/scons/winddk.py +++ /dev/null @@ -1,148 +0,0 @@ -"""winddk
-
-Tool-specific initialization for Microsoft Windows DDK.
-
-"""
-
-#
-# Copyright (c) 2001-2007 The SCons Foundation
-# Copyright (c) 2008 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 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.
-#
-
-import os.path
-import re
-import string
-
-import SCons.Action
-import SCons.Builder
-import SCons.Errors
-import SCons.Platform.win32
-import SCons.Tool
-import SCons.Util
-import SCons.Warnings
-
-import msvc_sa
-import mslib_sa
-import mslink_sa
-
-versions = [
- '6001.18002',
- '3790.1830',
-]
-
-def cpu_bin(target_cpu):
- if target_cpu == 'i386':
- return 'x86'
- else:
- return target_cpu
-
-def get_winddk_root(env, version):
- default_path = os.path.join(r'C:\WINDDK', version)
- if os.path.exists(default_path):
- return default_path
- return None
-
-def get_winddk_paths(env, version, root):
- version_major, version_minor = map(int, version.split('.'))
-
- if version_major >= 6000:
- target_os = 'wlh'
- else:
- target_os = 'wxp'
-
- if env['machine'] in ('generic', 'x86'):
- target_cpu = 'i386'
- elif env['machine'] == 'x86_64':
- target_cpu = 'amd64'
- else:
- raise SCons.Errors.InternalError, "Unsupported target machine"
-
- if version_major >= 6000:
- # TODO: take in consideration the host cpu
- bin_dir = os.path.join(root, 'bin', 'x86', cpu_bin(target_cpu))
- else:
- if target_cpu == 'i386':
- bin_dir = os.path.join(root, 'bin', 'x86')
- else:
- # TODO: take in consideration the host cpu
- bin_dir = os.path.join(root, 'bin', 'win64', 'x86', cpu_bin(target_cpu))
-
- crt_inc_dir = os.path.join(root, 'inc', 'crt')
- if version_major >= 6000:
- sdk_inc_dir = os.path.join(root, 'inc', 'api')
- ddk_inc_dir = os.path.join(root, 'inc', 'ddk')
- wdm_inc_dir = os.path.join(root, 'inc', 'ddk')
- else:
- ddk_inc_dir = os.path.join(root, 'inc', 'ddk', target_os)
- sdk_inc_dir = os.path.join(root, 'inc', target_os)
- wdm_inc_dir = os.path.join(root, 'inc', 'ddk', 'wdm', target_os)
-
- if env['toolchain'] == 'winddk':
- env.PrependENVPath('PATH', [bin_dir])
- env.PrependENVPath('INCLUDE', [
- wdm_inc_dir,
- ddk_inc_dir,
- crt_inc_dir,
- sdk_inc_dir,
- ])
- env.PrependENVPath('LIB', [
- os.path.join(root, 'lib', 'crt', target_cpu),
- os.path.join(root, 'lib', target_os, target_cpu),
- ])
- elif env['toolchain'] == 'crossmingw':
- env.Prepend(CPPFLAGS = [
- '-isystem', ddk_inc_dir,
- '-isystem', sdk_inc_dir,
- ])
- else:
- env.Prepend(CPPPATH = [
- wdm_inc_dir,
- ddk_inc_dir,
- sdk_inc_dir,
- ])
- env.Prepend(LIBPATH = [
- os.path.join(root, 'lib', target_os, target_cpu),
- ])
-
-
-def generate(env):
- if not env.has_key('ENV'):
- env['ENV'] = {}
-
- for version in versions:
- root = get_winddk_root(env, version)
- if root is not None:
- get_winddk_paths(env, version, root)
- break
-
- if env['toolchain'] == 'winddk':
- msvc_sa.generate(env)
- mslib_sa.generate(env)
- mslink_sa.generate(env)
-
-def exists(env):
- for version in versions:
- if get_winddk_root(env, version) is not None:
- return True
- return False
-
-# vim:set ts=4 sw=4 et:
diff --git a/mesalib/scons/winsdk.py b/mesalib/scons/winsdk.py deleted file mode 100644 index ab4369046..000000000 --- a/mesalib/scons/winsdk.py +++ /dev/null @@ -1,131 +0,0 @@ -"""winsdk
-
-Tool-specific initialization for Microsoft Windows SDK.
-
-"""
-
-#
-# Copyright (c) 2001-2007 The SCons Foundation
-# Copyright (c) 2008 Tungsten Graphics, Inc.
-# Copyright (c) 2009 VMware, 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 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.
-#
-
-import os.path
-import platform
-
-import SCons.Errors
-import SCons.Util
-
-import msvc_sa
-import mslib_sa
-import mslink_sa
-
-
-def get_vs_root(env):
- # TODO: Check HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7
- path = os.path.join(os.getenv('ProgramFiles', r'C:\Program Files'), 'Microsoft Visual Studio 9.0')
- return path
-
-def get_vs_paths(env):
- vs_root = get_vs_root(env)
- if vs_root is None:
- raise SCons.Errors.InternalError, "WINSDK compiler not found"
-
- tool_path = os.path.join(vs_root, 'Common7', 'IDE')
-
- env.PrependENVPath('PATH', tool_path)
-
-def get_vc_root(env):
- # TODO: Check HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VC7
- path = os.path.join(os.getenv('ProgramFiles', r'C:\Program Files'), 'Microsoft Visual Studio 9.0', 'VC')
- return path
-
-def get_vc_paths(env):
- vc_root = get_vc_root(env)
- if vc_root is None:
- raise SCons.Errors.InternalError, "WINSDK compiler not found"
-
- target_cpu = env['machine']
-
- if target_cpu in ('generic', 'x86'):
- bin_dir = 'bin'
- lib_dir = 'lib'
- elif target_cpu == 'x86_64':
- # TODO: take in consideration the host cpu
- bin_dir = r'bin\x86_amd64'
- lib_dir = r'lib\amd64'
- else:
- raise SCons.Errors.InternalError, "Unsupported target machine"
- include_dir = 'include'
-
- env.PrependENVPath('PATH', os.path.join(vc_root, bin_dir))
- env.PrependENVPath('INCLUDE', os.path.join(vc_root, include_dir))
- env.PrependENVPath('LIB', os.path.join(vc_root, lib_dir))
-
-def get_sdk_root(env):
- if SCons.Util.can_read_reg:
- key = r'SOFTWARE\Microsoft\Microsoft SDKs\Windows\CurrentInstallFolder'
- try:
- path, t = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE, key)
- except SCons.Util.RegError:
- pass
- else:
- return path
-
- return None
-
-def get_sdk_paths(env):
- sdk_root = get_sdk_root(env)
- if sdk_root is None:
- raise SCons.Errors.InternalError, "WINSDK not found"
-
- target_cpu = env['machine']
-
- bin_dir = 'Bin'
- if target_cpu in ('generic', 'x86'):
- lib_dir = 'Lib'
- elif target_cpu == 'x86_64':
- lib_dir = r'Lib\x64'
- else:
- raise SCons.Errors.InternalError, "Unsupported target machine"
- include_dir = 'Include'
-
- env.PrependENVPath('PATH', os.path.join(sdk_root, bin_dir))
- env.PrependENVPath('INCLUDE', os.path.join(sdk_root, include_dir))
- env.PrependENVPath('LIB', os.path.join(sdk_root, lib_dir))
-
-def generate(env):
- if not env.has_key('ENV'):
- env['ENV'] = {}
-
- get_vs_paths(env)
- get_vc_paths(env)
- get_sdk_paths(env)
-
- msvc_sa.generate(env)
- mslib_sa.generate(env)
- mslink_sa.generate(env)
-
-def exists(env):
- return get_vc_root(env) is not None and get_sdk_root(env) is not None
-
-# vim:set ts=4 sw=4 et:
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 484786c5f..ce29d5a87 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2120,25 +2120,6 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, var->depth_layout = ir_depth_layout_unchanged; else var->depth_layout = ir_depth_layout_none; - - /* From page 46 (page 52 of the PDF) of the GLSL ES specification: - * - * "Array variables are l-values and may be passed to parameters - * declared as out or inout. However, they may not be used as - * the target of an assignment." - * - * From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: - * - * "Other binary or unary expressions, non-dereferenced arrays, - * function names, swizzles with repeated fields, and constants - * cannot be l-values." - * - * So we only mark 1.10 as non-lvalues, and check for array - * assignment in 100 specifically in do_assignment. - */ - if (var->type->is_array() && state->language_version != 110) { - var->array_lvalue = true; - } } /** @@ -2953,6 +2934,26 @@ ast_parameter_declarator::hir(exec_list *instructions, type = glsl_type::error_type; } + /* From page 39 (page 45 of the PDF) of the GLSL 1.10 spec: + * + * "When calling a function, expressions that do not evaluate to + * l-values cannot be passed to parameters declared as out or inout." + * + * From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: + * + * "Other binary or unary expressions, non-dereferenced arrays, + * function names, swizzles with repeated fields, and constants + * cannot be l-values." + * + * So for GLSL 1.10, passing an array as an out or inout parameter is not + * allowed. This restriction is removed in GLSL 1.20, and in GLSL ES. + */ + if ((var->mode == ir_var_inout || var->mode == ir_var_out) + && type->is_array() && state->language_version == 110) { + _mesa_glsl_error(&loc, state, "Arrays cannot be out or inout parameters in GLSL 1.10"); + type = glsl_type::error_type; + } + instructions->push_tail(var); /* Parameter declarations do not have r-values. diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 41ed4f114..d6594cd9a 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -1105,9 +1105,6 @@ ir_dereference::is_lvalue() const if ((var == NULL) || var->read_only) return false; - if (this->type->is_array() && !var->array_lvalue) - return false; - /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec: * * "Samplers cannot be treated as l-values; hence cannot be used @@ -1323,7 +1320,7 @@ ir_swizzle::variable_referenced() const ir_variable::ir_variable(const struct glsl_type *type, const char *name, ir_variable_mode mode) : max_array_access(0), read_only(false), centroid(false), invariant(false), - mode(mode), interpolation(ir_var_smooth), array_lvalue(false) + mode(mode), interpolation(ir_var_smooth) { this->ir_type = ir_type_variable; this->type = type; diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index 2e899f3ed..cc4e68002 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -346,14 +346,6 @@ public: unsigned interpolation:2; /** - * Flag that the whole array is assignable - * - * In GLSL 1.20 and later whole arrays are assignable (and comparable for - * equality). This flag enables this behavior. - */ - unsigned array_lvalue:1; - - /** * \name ARB_fragment_coord_conventions * @{ */ diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index f0757365d..c1befa95c 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -47,7 +47,6 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const var->centroid = this->centroid; var->invariant = this->invariant; var->interpolation = this->interpolation; - var->array_lvalue = this->array_lvalue; var->location = this->location; var->warn_extension = this->warn_extension; var->origin_upper_left = this->origin_upper_left; diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 2ebcd35bd..482bd98a2 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -1569,10 +1569,10 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) /* vertex colors */ for (i = 0; i < 4; i++) { - verts[i].r = ctx->Color.ClearColorUnclamped[0]; - verts[i].g = ctx->Color.ClearColorUnclamped[1]; - verts[i].b = ctx->Color.ClearColorUnclamped[2]; - verts[i].a = ctx->Color.ClearColorUnclamped[3]; + verts[i].r = ctx->Color.ClearColor.f[0]; + verts[i].g = ctx->Color.ClearColor.f[1]; + verts[i].b = ctx->Color.ClearColor.f[2]; + verts[i].a = ctx->Color.ClearColor.f[3]; } /* upload new vertex data */ @@ -1679,7 +1679,7 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) _mesa_UseProgramObjectARB(clear->ShaderProg); _mesa_Uniform4fvARB(clear->ColorLocation, 1, - ctx->Color.ClearColorUnclamped); + ctx->Color.ClearColor.f); _mesa_BindVertexArray(clear->ArrayObj); _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index 6d6401934..cdd413737 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -816,8 +816,10 @@ driCreateNewScreen(int scrn, (void) loaderPrivate; - if (driDriverAPI.InitScreen == NULL) + if (driDriverAPI.InitScreen == NULL) { + __driUtilMessage("driver does not support DRI1"); return NULL; + } psp = calloc(1, sizeof *psp); if (!psp) diff --git a/mesalib/src/mesa/drivers/windows/gdi/wmesa.c b/mesalib/src/mesa/drivers/windows/gdi/wmesa.c index 35a150d06..14d15ed6c 100644 --- a/mesalib/src/mesa/drivers/windows/gdi/wmesa.c +++ b/mesalib/src/mesa/drivers/windows/gdi/wmesa.c @@ -249,14 +249,15 @@ static void wmesa_flush(struct gl_context *ctx) /* * Set the color used to clear the color buffer. */ -static void clear_color(struct gl_context *ctx, const GLfloat color[4]) +static void clear_color(struct gl_context *ctx, + const union gl_color_union color) { WMesaContext pwc = wmesa_context(ctx); GLubyte col[3]; - CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]); - CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]); - CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]); + UNCLAMPED_FLOAT_TO_UBYTE(col[0], color.f[0]); + UNCLAMPED_FLOAT_TO_UBYTE(col[1], color.f[1]); + UNCLAMPED_FLOAT_TO_UBYTE(col[2], color.f[2]); pwc->clearColorRef = RGB(col[0], col[1], col[2]); DeleteObject(pwc->clearPen); DeleteObject(pwc->clearBrush); diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index 573100402..9767740a3 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -884,10 +884,10 @@ _mesa_PopAttrib(void) color = (const struct gl_colorbuffer_attrib *) attr->data; _mesa_ClearIndex((GLfloat) color->ClearIndex); - _mesa_ClearColor(color->ClearColorUnclamped[0], - color->ClearColorUnclamped[1], - color->ClearColorUnclamped[2], - color->ClearColorUnclamped[3]); + _mesa_ClearColor(color->ClearColor.f[0], + color->ClearColor.f[1], + color->ClearColor.f[2], + color->ClearColor.f[3]); _mesa_IndexMask(color->IndexMask); if (!ctx->Extensions.EXT_draw_buffers2) { _mesa_ColorMask((GLboolean) (color->ColorMask[0][0] != 0), diff --git a/mesalib/src/mesa/main/blend.c b/mesalib/src/mesa/main/blend.c index 94a457f58..4214a661b 100644 --- a/mesalib/src/mesa/main/blend.c +++ b/mesalib/src/mesa/main/blend.c @@ -1,833 +1,832 @@ -/**
- * \file blend.c
- * Blending operations.
- */
-
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.1
- *
- * 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.
- */
-
-
-
-#include "glheader.h"
-#include "blend.h"
-#include "context.h"
-#include "enums.h"
-#include "macros.h"
-#include "mtypes.h"
-
-
-
-/**
- * Check if given blend source factor is legal.
- * \return GL_TRUE if legal, GL_FALSE otherwise.
- */
-static GLboolean
-legal_src_factor(const struct gl_context *ctx, GLenum factor)
-{
- switch (factor) {
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- return ctx->Extensions.NV_blend_square;
- case GL_ZERO:
- case GL_ONE:
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_SRC_ALPHA_SATURATE:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Check if given blend destination factor is legal.
- * \return GL_TRUE if legal, GL_FALSE otherwise.
- */
-static GLboolean
-legal_dst_factor(const struct gl_context *ctx, GLenum factor)
-{
- switch (factor) {
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- return ctx->Extensions.NV_blend_square;
- case GL_ZERO:
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Check if src/dest RGB/A blend factors are legal. If not generate
- * a GL error.
- * \return GL_TRUE if factors are legal, GL_FALSE otherwise.
- */
-static GLboolean
-validate_blend_factors(struct gl_context *ctx, const char *func,
- GLenum sfactorRGB, GLenum dfactorRGB,
- GLenum sfactorA, GLenum dfactorA)
-{
- if (!legal_src_factor(ctx, sfactorRGB)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "%s(sfactorRGB = %s)", func,
- _mesa_lookup_enum_by_nr(sfactorRGB));
- return GL_FALSE;
- }
-
- if (!legal_dst_factor(ctx, dfactorRGB)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "%s(dfactorRGB = %s)", func,
- _mesa_lookup_enum_by_nr(dfactorRGB));
- return GL_FALSE;
- }
-
- if (sfactorA != sfactorRGB && !legal_src_factor(ctx, sfactorA)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "%s(sfactorA = %s)", func,
- _mesa_lookup_enum_by_nr(sfactorA));
- return GL_FALSE;
- }
-
- if (dfactorA != dfactorRGB && !legal_dst_factor(ctx, dfactorA)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "%s(dfactorA = %s)", func,
- _mesa_lookup_enum_by_nr(dfactorA));
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Specify the blending operation.
- *
- * \param sfactor source factor operator.
- * \param dfactor destination factor operator.
- *
- * \sa glBlendFunc, glBlendFuncSeparateEXT
- */
-void GLAPIENTRY
-_mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
-{
- _mesa_BlendFuncSeparateEXT(sfactor, dfactor, sfactor, dfactor);
-}
-
-
-/**
- * Set the separate blend source/dest factors for all draw buffers.
- *
- * \param sfactorRGB RGB source factor operator.
- * \param dfactorRGB RGB destination factor operator.
- * \param sfactorA alpha source factor operator.
- * \param dfactorA alpha destination factor operator.
- */
-void GLAPIENTRY
-_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
- GLenum sfactorA, GLenum dfactorA )
-{
- GLuint buf, numBuffers;
- GLboolean changed;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n",
- _mesa_lookup_enum_by_nr(sfactorRGB),
- _mesa_lookup_enum_by_nr(dfactorRGB),
- _mesa_lookup_enum_by_nr(sfactorA),
- _mesa_lookup_enum_by_nr(dfactorA));
-
- if (!validate_blend_factors(ctx, "glBlendFuncSeparate",
- sfactorRGB, dfactorRGB,
- sfactorA, dfactorA)) {
- return;
- }
-
- numBuffers = ctx->Extensions.ARB_draw_buffers_blend
- ? ctx->Const.MaxDrawBuffers : 1;
-
- changed = GL_FALSE;
- for (buf = 0; buf < numBuffers; buf++) {
- if (ctx->Color.Blend[buf].SrcRGB != sfactorRGB ||
- ctx->Color.Blend[buf].DstRGB != dfactorRGB ||
- ctx->Color.Blend[buf].SrcA != sfactorA ||
- ctx->Color.Blend[buf].DstA != dfactorA) {
- changed = GL_TRUE;
- break;
- }
- }
- if (!changed)
- return;
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
-
- for (buf = 0; buf < numBuffers; buf++) {
- ctx->Color.Blend[buf].SrcRGB = sfactorRGB;
- ctx->Color.Blend[buf].DstRGB = dfactorRGB;
- ctx->Color.Blend[buf].SrcA = sfactorA;
- ctx->Color.Blend[buf].DstA = dfactorA;
- }
- ctx->Color._BlendFuncPerBuffer = GL_FALSE;
-
- if (ctx->Driver.BlendFuncSeparate) {
- ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB,
- sfactorA, dfactorA);
- }
-}
-
-
-#if _HAVE_FULL_GL
-
-
-/**
- * Set blend source/dest factors for one color buffer/target.
- */
-void GLAPIENTRY
-_mesa_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
-{
- _mesa_BlendFuncSeparatei(buf, sfactor, dfactor, sfactor, dfactor);
-}
-
-
-/**
- * Set separate blend source/dest factors for one color buffer/target.
- */
-void GLAPIENTRY
-_mesa_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
- GLenum sfactorA, GLenum dfactorA)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (!ctx->Extensions.ARB_draw_buffers_blend) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBlendFunc[Separate]i()");
- return;
- }
-
- if (buf >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)",
- buf);
- return;
- }
-
- if (!validate_blend_factors(ctx, "glBlendFuncSeparatei",
- sfactorRGB, dfactorRGB,
- sfactorA, dfactorA)) {
- return;
- }
-
- if (ctx->Color.Blend[buf].SrcRGB == sfactorRGB &&
- ctx->Color.Blend[buf].DstRGB == dfactorRGB &&
- ctx->Color.Blend[buf].SrcA == sfactorA &&
- ctx->Color.Blend[buf].DstA == dfactorA)
- return; /* no change */
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
-
- ctx->Color.Blend[buf].SrcRGB = sfactorRGB;
- ctx->Color.Blend[buf].DstRGB = dfactorRGB;
- ctx->Color.Blend[buf].SrcA = sfactorA;
- ctx->Color.Blend[buf].DstA = dfactorA;
- ctx->Color._BlendFuncPerBuffer = GL_TRUE;
-
- if (ctx->Driver.BlendFuncSeparatei) {
- ctx->Driver.BlendFuncSeparatei(ctx, buf, sfactorRGB, dfactorRGB,
- sfactorA, dfactorA);
- }
-}
-
-
-/**
- * Check if given blend equation is legal.
- * \return GL_TRUE if legal, GL_FALSE otherwise.
- */
-static GLboolean
-legal_blend_equation(const struct gl_context *ctx,
- GLenum mode, GLboolean is_separate)
-{
- switch (mode) {
- case GL_FUNC_ADD:
- return GL_TRUE;
- case GL_MIN:
- case GL_MAX:
- return ctx->Extensions.EXT_blend_minmax;
- case GL_LOGIC_OP:
- /* glBlendEquationSeparate cannot take GL_LOGIC_OP as a parameter.
- */
- return ctx->Extensions.EXT_blend_logic_op && !is_separate;
- case GL_FUNC_SUBTRACT:
- case GL_FUNC_REVERSE_SUBTRACT:
- return ctx->Extensions.EXT_blend_subtract;
- default:
- return GL_FALSE;
- }
-}
-
-
-/* This is really an extension function! */
-void GLAPIENTRY
-_mesa_BlendEquation( GLenum mode )
-{
- GLuint buf, numBuffers;
- GLboolean changed;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glBlendEquation(%s)\n",
- _mesa_lookup_enum_by_nr(mode));
-
- if (!legal_blend_equation(ctx, mode, GL_FALSE)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
- return;
- }
-
- numBuffers = ctx->Extensions.ARB_draw_buffers_blend
- ? ctx->Const.MaxDrawBuffers : 1;
-
- changed = GL_FALSE;
- for (buf = 0; buf < numBuffers; buf++) {
- if (ctx->Color.Blend[buf].EquationRGB != mode ||
- ctx->Color.Blend[buf].EquationA != mode) {
- changed = GL_TRUE;
- break;
- }
- }
- if (!changed)
- return;
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- for (buf = 0; buf < numBuffers; buf++) {
- ctx->Color.Blend[buf].EquationRGB = mode;
- ctx->Color.Blend[buf].EquationA = mode;
- }
- ctx->Color._BlendEquationPerBuffer = GL_FALSE;
-
- if (ctx->Driver.BlendEquationSeparate)
- (*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode );
-}
-
-
-/**
- * Set blend equation for one color buffer/target.
- */
-void GLAPIENTRY
-_mesa_BlendEquationi(GLuint buf, GLenum mode)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glBlendEquationi(%u, %s)\n",
- buf, _mesa_lookup_enum_by_nr(mode));
-
- if (buf >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)",
- buf);
- return;
- }
-
- if (!legal_blend_equation(ctx, mode, GL_FALSE)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationi");
- return;
- }
-
- if (ctx->Color.Blend[buf].EquationRGB == mode &&
- ctx->Color.Blend[buf].EquationA == mode)
- return; /* no change */
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.Blend[buf].EquationRGB = mode;
- ctx->Color.Blend[buf].EquationA = mode;
- ctx->Color._BlendEquationPerBuffer = GL_TRUE;
-
- if (ctx->Driver.BlendEquationSeparatei)
- ctx->Driver.BlendEquationSeparatei(ctx, buf, mode, mode);
-}
-
-
-void GLAPIENTRY
-_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA )
-{
- GLuint buf, numBuffers;
- GLboolean changed;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glBlendEquationSeparateEXT(%s %s)\n",
- _mesa_lookup_enum_by_nr(modeRGB),
- _mesa_lookup_enum_by_nr(modeA));
-
- if ( (modeRGB != modeA) && !ctx->Extensions.EXT_blend_equation_separate ) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlendEquationSeparateEXT not supported by driver");
- return;
- }
-
- if (!legal_blend_equation(ctx, modeRGB, GL_TRUE)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeRGB)");
- return;
- }
-
- if (!legal_blend_equation(ctx, modeA, GL_TRUE)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeA)");
- return;
- }
-
- numBuffers = ctx->Extensions.ARB_draw_buffers_blend
- ? ctx->Const.MaxDrawBuffers : 1;
-
- changed = GL_FALSE;
- for (buf = 0; buf < numBuffers; buf++) {
- if (ctx->Color.Blend[buf].EquationRGB != modeRGB ||
- ctx->Color.Blend[buf].EquationA != modeA) {
- changed = GL_TRUE;
- break;
- }
- }
- if (!changed)
- return;
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- for (buf = 0; buf < numBuffers; buf++) {
- ctx->Color.Blend[buf].EquationRGB = modeRGB;
- ctx->Color.Blend[buf].EquationA = modeA;
- }
- ctx->Color._BlendEquationPerBuffer = GL_FALSE;
-
- if (ctx->Driver.BlendEquationSeparate)
- ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA);
-}
-
-
-/**
- * Set separate blend equations for one color buffer/target.
- */
-void GLAPIENTRY
-_mesa_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glBlendEquationSeparatei(%u, %s %s)\n", buf,
- _mesa_lookup_enum_by_nr(modeRGB),
- _mesa_lookup_enum_by_nr(modeA));
-
- if (buf >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glBlendEquationSeparatei(buffer=%u)",
- buf);
- return;
- }
-
- if (!legal_blend_equation(ctx, modeRGB, GL_TRUE)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeRGB)");
- return;
- }
-
- if (!legal_blend_equation(ctx, modeA, GL_TRUE)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeA)");
- return;
- }
-
- if (ctx->Color.Blend[buf].EquationRGB == modeRGB &&
- ctx->Color.Blend[buf].EquationA == modeA)
- return; /* no change */
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.Blend[buf].EquationRGB = modeRGB;
- ctx->Color.Blend[buf].EquationA = modeA;
- ctx->Color._BlendEquationPerBuffer = GL_TRUE;
-
- if (ctx->Driver.BlendEquationSeparatei)
- ctx->Driver.BlendEquationSeparatei(ctx, buf, modeRGB, modeA);
-}
-
-
-
-#endif /* _HAVE_FULL_GL */
-
-
-/**
- * Set the blending color.
- *
- * \param red red color component.
- * \param green green color component.
- * \param blue blue color component.
- * \param alpha alpha color component.
- *
- * \sa glBlendColor().
- *
- * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor. On a
- * change, flushes the vertices and notifies the driver via
- * dd_function_table::BlendColor callback.
- */
-void GLAPIENTRY
-_mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
-{
- GLfloat tmp[4];
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- tmp[0] = red;
- tmp[1] = green;
- tmp[2] = blue;
- tmp[3] = alpha;
-
- if (TEST_EQ_4V(tmp, ctx->Color.BlendColorUnclamped))
- return;
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- COPY_4FV( ctx->Color.BlendColorUnclamped, tmp );
-
- ctx->Color.BlendColor[0] = CLAMP(tmp[0], 0.0F, 1.0F);
- ctx->Color.BlendColor[1] = CLAMP(tmp[1], 0.0F, 1.0F);
- ctx->Color.BlendColor[2] = CLAMP(tmp[2], 0.0F, 1.0F);
- ctx->Color.BlendColor[3] = CLAMP(tmp[3], 0.0F, 1.0F);
-
- if (ctx->Driver.BlendColor)
- (*ctx->Driver.BlendColor)(ctx, ctx->Color.BlendColor);
-}
-
-
-/**
- * Specify the alpha test function.
- *
- * \param func alpha comparison function.
- * \param ref reference value.
- *
- * Verifies the parameters and updates gl_colorbuffer_attrib.
- * On a change, flushes the vertices and notifies the driver via
- * dd_function_table::AlphaFunc callback.
- */
-void GLAPIENTRY
-_mesa_AlphaFunc( GLenum func, GLclampf ref )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glAlphaFunc(%s, %f)\n",
- _mesa_lookup_enum_by_nr(func), ref);
-
- switch (func) {
- case GL_NEVER:
- case GL_LESS:
- case GL_EQUAL:
- case GL_LEQUAL:
- case GL_GREATER:
- case GL_NOTEQUAL:
- case GL_GEQUAL:
- case GL_ALWAYS:
- if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRefUnclamped == ref)
- return; /* no change */
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.AlphaFunc = func;
- ctx->Color.AlphaRefUnclamped = ref;
- ctx->Color.AlphaRef = CLAMP(ref, 0.0F, 1.0F);
-
- if (ctx->Driver.AlphaFunc)
- ctx->Driver.AlphaFunc(ctx, func, ctx->Color.AlphaRef);
- return;
-
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" );
- return;
- }
-}
-
-
-/**
- * Specify a logic pixel operation for color index rendering.
- *
- * \param opcode operation.
- *
- * Verifies that \p opcode is a valid enum and updates
-gl_colorbuffer_attrib::LogicOp.
- * On a change, flushes the vertices and notifies the driver via the
- * dd_function_table::LogicOpcode callback.
- */
-void GLAPIENTRY
-_mesa_LogicOp( GLenum opcode )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glLogicOp(%s)\n", _mesa_lookup_enum_by_nr(opcode));
-
- switch (opcode) {
- case GL_CLEAR:
- case GL_SET:
- case GL_COPY:
- case GL_COPY_INVERTED:
- case GL_NOOP:
- case GL_INVERT:
- case GL_AND:
- case GL_NAND:
- case GL_OR:
- case GL_NOR:
- case GL_XOR:
- case GL_EQUIV:
- case GL_AND_REVERSE:
- case GL_AND_INVERTED:
- case GL_OR_REVERSE:
- case GL_OR_INVERTED:
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glLogicOp" );
- return;
- }
-
- if (ctx->Color.LogicOp == opcode)
- return;
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.LogicOp = opcode;
-
- if (ctx->Driver.LogicOpcode)
- ctx->Driver.LogicOpcode( ctx, opcode );
-}
-
-#if _HAVE_FULL_GL
-void GLAPIENTRY
-_mesa_IndexMask( GLuint mask )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (ctx->Color.IndexMask == mask)
- return;
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.IndexMask = mask;
-}
-#endif
-
-
-/**
- * Enable or disable writing of frame buffer color components.
- *
- * \param red whether to mask writing of the red color component.
- * \param green whether to mask writing of the green color component.
- * \param blue whether to mask writing of the blue color component.
- * \param alpha whether to mask writing of the alpha color component.
- *
- * \sa glColorMask().
- *
- * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask. On a
- * change, flushes the vertices and notifies the driver via the
- * dd_function_table::ColorMask callback.
- */
-void GLAPIENTRY
-_mesa_ColorMask( GLboolean red, GLboolean green,
- GLboolean blue, GLboolean alpha )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLubyte tmp[4];
- GLuint i;
- GLboolean flushed;
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glColorMask(%d, %d, %d, %d)\n",
- red, green, blue, alpha);
-
- /* Shouldn't have any information about channel depth in core mesa
- * -- should probably store these as the native booleans:
- */
- tmp[RCOMP] = red ? 0xff : 0x0;
- tmp[GCOMP] = green ? 0xff : 0x0;
- tmp[BCOMP] = blue ? 0xff : 0x0;
- tmp[ACOMP] = alpha ? 0xff : 0x0;
-
- flushed = GL_FALSE;
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
- if (!TEST_EQ_4V(tmp, ctx->Color.ColorMask[i])) {
- if (!flushed) {
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- }
- flushed = GL_TRUE;
- COPY_4UBV(ctx->Color.ColorMask[i], tmp);
- }
- }
-
- if (ctx->Driver.ColorMask)
- ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
-}
-
-
-/**
- * For GL_EXT_draw_buffers2 and GL3
- */
-void GLAPIENTRY
-_mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green,
- GLboolean blue, GLboolean alpha )
-{
- GLubyte tmp[4];
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glColorMaskIndexed %u %d %d %d %d\n",
- buf, red, green, blue, alpha);
-
- if (buf >= ctx->Const.MaxDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glColorMaskIndexed(buf=%u)", buf);
- return;
- }
-
- /* Shouldn't have any information about channel depth in core mesa
- * -- should probably store these as the native booleans:
- */
- tmp[RCOMP] = red ? 0xff : 0x0;
- tmp[GCOMP] = green ? 0xff : 0x0;
- tmp[BCOMP] = blue ? 0xff : 0x0;
- tmp[ACOMP] = alpha ? 0xff : 0x0;
-
- if (TEST_EQ_4V(tmp, ctx->Color.ColorMask[buf]))
- return;
-
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- COPY_4UBV(ctx->Color.ColorMask[buf], tmp);
-
- if (ctx->Driver.ColorMaskIndexed)
- ctx->Driver.ColorMaskIndexed(ctx, buf, red, green, blue, alpha);
-}
-
-
-void GLAPIENTRY
-_mesa_ClampColorARB(GLenum target, GLenum clamp)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (clamp != GL_TRUE && clamp != GL_FALSE && clamp != GL_FIXED_ONLY_ARB) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(clamp)");
- return;
- }
-
- switch (target) {
- case GL_CLAMP_VERTEX_COLOR_ARB:
- FLUSH_VERTICES(ctx, _NEW_LIGHT);
- ctx->Light.ClampVertexColor = clamp;
- break;
- case GL_CLAMP_FRAGMENT_COLOR_ARB:
- FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP);
- ctx->Color.ClampFragmentColor = clamp;
- break;
- case GL_CLAMP_READ_COLOR_ARB:
- FLUSH_VERTICES(ctx, _NEW_COLOR);
- ctx->Color.ClampReadColor = clamp;
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(target)");
- return;
- }
-}
-
-
-
-
-/**********************************************************************/
-/** \name Initialization */
-/*@{*/
-
-/**
- * Initialization of the context's Color attribute group.
- *
- * \param ctx GL context.
- *
- * Initializes the related fields in the context color attribute group,
- * __struct gl_contextRec::Color.
- */
-void _mesa_init_color( struct gl_context * ctx )
-{
- GLuint i;
-
- /* Color buffer group */
- ctx->Color.IndexMask = ~0u;
- memset(ctx->Color.ColorMask, 0xff, sizeof(ctx->Color.ColorMask));
- ctx->Color.ClearIndex = 0;
- ASSIGN_4V( ctx->Color.ClearColor, 0, 0, 0, 0 );
- ASSIGN_4V( ctx->Color.ClearColorUnclamped, 0, 0, 0, 0 );
- ctx->Color.AlphaEnabled = GL_FALSE;
- ctx->Color.AlphaFunc = GL_ALWAYS;
- ctx->Color.AlphaRef = 0;
- ctx->Color.BlendEnabled = 0x0;
- for (i = 0; i < Elements(ctx->Color.Blend); i++) {
- ctx->Color.Blend[i].SrcRGB = GL_ONE;
- ctx->Color.Blend[i].DstRGB = GL_ZERO;
- ctx->Color.Blend[i].SrcA = GL_ONE;
- ctx->Color.Blend[i].DstA = GL_ZERO;
- ctx->Color.Blend[i].EquationRGB = GL_FUNC_ADD;
- ctx->Color.Blend[i].EquationA = GL_FUNC_ADD;
- }
- ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( ctx->Color.BlendColorUnclamped, 0.0, 0.0, 0.0, 0.0 );
- ctx->Color.IndexLogicOpEnabled = GL_FALSE;
- ctx->Color.ColorLogicOpEnabled = GL_FALSE;
- ctx->Color._LogicOpEnabled = GL_FALSE;
- ctx->Color.LogicOp = GL_COPY;
- ctx->Color.DitherFlag = GL_TRUE;
-
- if (ctx->Visual.doubleBufferMode) {
- ctx->Color.DrawBuffer[0] = GL_BACK;
- }
- else {
- ctx->Color.DrawBuffer[0] = GL_FRONT;
- }
-
- ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
- ctx->Color._ClampFragmentColor = GL_TRUE;
- ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB;
- ctx->Color._ClampReadColor = GL_TRUE;
-}
-
-/*@}*/
+/** + * \file blend.c + * Blending operations. + */ + +/* + * Mesa 3-D graphics library + * Version: 6.5.1 + * + * 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. + */ + + + +#include "glheader.h" +#include "blend.h" +#include "context.h" +#include "enums.h" +#include "macros.h" +#include "mtypes.h" + + + +/** + * Check if given blend source factor is legal. + * \return GL_TRUE if legal, GL_FALSE otherwise. + */ +static GLboolean +legal_src_factor(const struct gl_context *ctx, GLenum factor) +{ + switch (factor) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + return ctx->Extensions.NV_blend_square; + case GL_ZERO: + case GL_ONE: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_SRC_ALPHA_SATURATE: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * Check if given blend destination factor is legal. + * \return GL_TRUE if legal, GL_FALSE otherwise. + */ +static GLboolean +legal_dst_factor(const struct gl_context *ctx, GLenum factor) +{ + switch (factor) { + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + return ctx->Extensions.NV_blend_square; + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * Check if src/dest RGB/A blend factors are legal. If not generate + * a GL error. + * \return GL_TRUE if factors are legal, GL_FALSE otherwise. + */ +static GLboolean +validate_blend_factors(struct gl_context *ctx, const char *func, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + if (!legal_src_factor(ctx, sfactorRGB)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(sfactorRGB = %s)", func, + _mesa_lookup_enum_by_nr(sfactorRGB)); + return GL_FALSE; + } + + if (!legal_dst_factor(ctx, dfactorRGB)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(dfactorRGB = %s)", func, + _mesa_lookup_enum_by_nr(dfactorRGB)); + return GL_FALSE; + } + + if (sfactorA != sfactorRGB && !legal_src_factor(ctx, sfactorA)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(sfactorA = %s)", func, + _mesa_lookup_enum_by_nr(sfactorA)); + return GL_FALSE; + } + + if (dfactorA != dfactorRGB && !legal_dst_factor(ctx, dfactorA)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(dfactorA = %s)", func, + _mesa_lookup_enum_by_nr(dfactorA)); + return GL_FALSE; + } + + return GL_TRUE; +} + + +/** + * Specify the blending operation. + * + * \param sfactor source factor operator. + * \param dfactor destination factor operator. + * + * \sa glBlendFunc, glBlendFuncSeparateEXT + */ +void GLAPIENTRY +_mesa_BlendFunc( GLenum sfactor, GLenum dfactor ) +{ + _mesa_BlendFuncSeparateEXT(sfactor, dfactor, sfactor, dfactor); +} + + +/** + * Set the separate blend source/dest factors for all draw buffers. + * + * \param sfactorRGB RGB source factor operator. + * \param dfactorRGB RGB destination factor operator. + * \param sfactorA alpha source factor operator. + * \param dfactorA alpha destination factor operator. + */ +void GLAPIENTRY +_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + GLuint buf, numBuffers; + GLboolean changed; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n", + _mesa_lookup_enum_by_nr(sfactorRGB), + _mesa_lookup_enum_by_nr(dfactorRGB), + _mesa_lookup_enum_by_nr(sfactorA), + _mesa_lookup_enum_by_nr(dfactorA)); + + if (!validate_blend_factors(ctx, "glBlendFuncSeparate", + sfactorRGB, dfactorRGB, + sfactorA, dfactorA)) { + return; + } + + numBuffers = ctx->Extensions.ARB_draw_buffers_blend + ? ctx->Const.MaxDrawBuffers : 1; + + changed = GL_FALSE; + for (buf = 0; buf < numBuffers; buf++) { + if (ctx->Color.Blend[buf].SrcRGB != sfactorRGB || + ctx->Color.Blend[buf].DstRGB != dfactorRGB || + ctx->Color.Blend[buf].SrcA != sfactorA || + ctx->Color.Blend[buf].DstA != dfactorA) { + changed = GL_TRUE; + break; + } + } + if (!changed) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + + for (buf = 0; buf < numBuffers; buf++) { + ctx->Color.Blend[buf].SrcRGB = sfactorRGB; + ctx->Color.Blend[buf].DstRGB = dfactorRGB; + ctx->Color.Blend[buf].SrcA = sfactorA; + ctx->Color.Blend[buf].DstA = dfactorA; + } + ctx->Color._BlendFuncPerBuffer = GL_FALSE; + + if (ctx->Driver.BlendFuncSeparate) { + ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB, + sfactorA, dfactorA); + } +} + + +#if _HAVE_FULL_GL + + +/** + * Set blend source/dest factors for one color buffer/target. + */ +void GLAPIENTRY +_mesa_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) +{ + _mesa_BlendFuncSeparatei(buf, sfactor, dfactor, sfactor, dfactor); +} + + +/** + * Set separate blend source/dest factors for one color buffer/target. + */ +void GLAPIENTRY +_mesa_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!ctx->Extensions.ARB_draw_buffers_blend) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBlendFunc[Separate]i()"); + return; + } + + if (buf >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)", + buf); + return; + } + + if (!validate_blend_factors(ctx, "glBlendFuncSeparatei", + sfactorRGB, dfactorRGB, + sfactorA, dfactorA)) { + return; + } + + if (ctx->Color.Blend[buf].SrcRGB == sfactorRGB && + ctx->Color.Blend[buf].DstRGB == dfactorRGB && + ctx->Color.Blend[buf].SrcA == sfactorA && + ctx->Color.Blend[buf].DstA == dfactorA) + return; /* no change */ + + FLUSH_VERTICES(ctx, _NEW_COLOR); + + ctx->Color.Blend[buf].SrcRGB = sfactorRGB; + ctx->Color.Blend[buf].DstRGB = dfactorRGB; + ctx->Color.Blend[buf].SrcA = sfactorA; + ctx->Color.Blend[buf].DstA = dfactorA; + ctx->Color._BlendFuncPerBuffer = GL_TRUE; + + if (ctx->Driver.BlendFuncSeparatei) { + ctx->Driver.BlendFuncSeparatei(ctx, buf, sfactorRGB, dfactorRGB, + sfactorA, dfactorA); + } +} + + +/** + * Check if given blend equation is legal. + * \return GL_TRUE if legal, GL_FALSE otherwise. + */ +static GLboolean +legal_blend_equation(const struct gl_context *ctx, + GLenum mode, GLboolean is_separate) +{ + switch (mode) { + case GL_FUNC_ADD: + return GL_TRUE; + case GL_MIN: + case GL_MAX: + return ctx->Extensions.EXT_blend_minmax; + case GL_LOGIC_OP: + /* glBlendEquationSeparate cannot take GL_LOGIC_OP as a parameter. + */ + return ctx->Extensions.EXT_blend_logic_op && !is_separate; + case GL_FUNC_SUBTRACT: + case GL_FUNC_REVERSE_SUBTRACT: + return ctx->Extensions.EXT_blend_subtract; + default: + return GL_FALSE; + } +} + + +/* This is really an extension function! */ +void GLAPIENTRY +_mesa_BlendEquation( GLenum mode ) +{ + GLuint buf, numBuffers; + GLboolean changed; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glBlendEquation(%s)\n", + _mesa_lookup_enum_by_nr(mode)); + + if (!legal_blend_equation(ctx, mode, GL_FALSE)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation"); + return; + } + + numBuffers = ctx->Extensions.ARB_draw_buffers_blend + ? ctx->Const.MaxDrawBuffers : 1; + + changed = GL_FALSE; + for (buf = 0; buf < numBuffers; buf++) { + if (ctx->Color.Blend[buf].EquationRGB != mode || + ctx->Color.Blend[buf].EquationA != mode) { + changed = GL_TRUE; + break; + } + } + if (!changed) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + for (buf = 0; buf < numBuffers; buf++) { + ctx->Color.Blend[buf].EquationRGB = mode; + ctx->Color.Blend[buf].EquationA = mode; + } + ctx->Color._BlendEquationPerBuffer = GL_FALSE; + + if (ctx->Driver.BlendEquationSeparate) + (*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode ); +} + + +/** + * Set blend equation for one color buffer/target. + */ +void GLAPIENTRY +_mesa_BlendEquationi(GLuint buf, GLenum mode) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glBlendEquationi(%u, %s)\n", + buf, _mesa_lookup_enum_by_nr(mode)); + + if (buf >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)", + buf); + return; + } + + if (!legal_blend_equation(ctx, mode, GL_FALSE)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationi"); + return; + } + + if (ctx->Color.Blend[buf].EquationRGB == mode && + ctx->Color.Blend[buf].EquationA == mode) + return; /* no change */ + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.Blend[buf].EquationRGB = mode; + ctx->Color.Blend[buf].EquationA = mode; + ctx->Color._BlendEquationPerBuffer = GL_TRUE; + + if (ctx->Driver.BlendEquationSeparatei) + ctx->Driver.BlendEquationSeparatei(ctx, buf, mode, mode); +} + + +void GLAPIENTRY +_mesa_BlendEquationSeparateEXT( GLenum modeRGB, GLenum modeA ) +{ + GLuint buf, numBuffers; + GLboolean changed; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glBlendEquationSeparateEXT(%s %s)\n", + _mesa_lookup_enum_by_nr(modeRGB), + _mesa_lookup_enum_by_nr(modeA)); + + if ( (modeRGB != modeA) && !ctx->Extensions.EXT_blend_equation_separate ) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBlendEquationSeparateEXT not supported by driver"); + return; + } + + if (!legal_blend_equation(ctx, modeRGB, GL_TRUE)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeRGB)"); + return; + } + + if (!legal_blend_equation(ctx, modeA, GL_TRUE)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeA)"); + return; + } + + numBuffers = ctx->Extensions.ARB_draw_buffers_blend + ? ctx->Const.MaxDrawBuffers : 1; + + changed = GL_FALSE; + for (buf = 0; buf < numBuffers; buf++) { + if (ctx->Color.Blend[buf].EquationRGB != modeRGB || + ctx->Color.Blend[buf].EquationA != modeA) { + changed = GL_TRUE; + break; + } + } + if (!changed) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + for (buf = 0; buf < numBuffers; buf++) { + ctx->Color.Blend[buf].EquationRGB = modeRGB; + ctx->Color.Blend[buf].EquationA = modeA; + } + ctx->Color._BlendEquationPerBuffer = GL_FALSE; + + if (ctx->Driver.BlendEquationSeparate) + ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA); +} + + +/** + * Set separate blend equations for one color buffer/target. + */ +void GLAPIENTRY +_mesa_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glBlendEquationSeparatei(%u, %s %s)\n", buf, + _mesa_lookup_enum_by_nr(modeRGB), + _mesa_lookup_enum_by_nr(modeA)); + + if (buf >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBlendEquationSeparatei(buffer=%u)", + buf); + return; + } + + if (!legal_blend_equation(ctx, modeRGB, GL_TRUE)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeRGB)"); + return; + } + + if (!legal_blend_equation(ctx, modeA, GL_TRUE)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeA)"); + return; + } + + if (ctx->Color.Blend[buf].EquationRGB == modeRGB && + ctx->Color.Blend[buf].EquationA == modeA) + return; /* no change */ + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.Blend[buf].EquationRGB = modeRGB; + ctx->Color.Blend[buf].EquationA = modeA; + ctx->Color._BlendEquationPerBuffer = GL_TRUE; + + if (ctx->Driver.BlendEquationSeparatei) + ctx->Driver.BlendEquationSeparatei(ctx, buf, modeRGB, modeA); +} + + + +#endif /* _HAVE_FULL_GL */ + + +/** + * Set the blending color. + * + * \param red red color component. + * \param green green color component. + * \param blue blue color component. + * \param alpha alpha color component. + * + * \sa glBlendColor(). + * + * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor. On a + * change, flushes the vertices and notifies the driver via + * dd_function_table::BlendColor callback. + */ +void GLAPIENTRY +_mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) +{ + GLfloat tmp[4]; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + tmp[0] = red; + tmp[1] = green; + tmp[2] = blue; + tmp[3] = alpha; + + if (TEST_EQ_4V(tmp, ctx->Color.BlendColorUnclamped)) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + COPY_4FV( ctx->Color.BlendColorUnclamped, tmp ); + + ctx->Color.BlendColor[0] = CLAMP(tmp[0], 0.0F, 1.0F); + ctx->Color.BlendColor[1] = CLAMP(tmp[1], 0.0F, 1.0F); + ctx->Color.BlendColor[2] = CLAMP(tmp[2], 0.0F, 1.0F); + ctx->Color.BlendColor[3] = CLAMP(tmp[3], 0.0F, 1.0F); + + if (ctx->Driver.BlendColor) + (*ctx->Driver.BlendColor)(ctx, ctx->Color.BlendColor); +} + + +/** + * Specify the alpha test function. + * + * \param func alpha comparison function. + * \param ref reference value. + * + * Verifies the parameters and updates gl_colorbuffer_attrib. + * On a change, flushes the vertices and notifies the driver via + * dd_function_table::AlphaFunc callback. + */ +void GLAPIENTRY +_mesa_AlphaFunc( GLenum func, GLclampf ref ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glAlphaFunc(%s, %f)\n", + _mesa_lookup_enum_by_nr(func), ref); + + switch (func) { + case GL_NEVER: + case GL_LESS: + case GL_EQUAL: + case GL_LEQUAL: + case GL_GREATER: + case GL_NOTEQUAL: + case GL_GEQUAL: + case GL_ALWAYS: + if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRefUnclamped == ref) + return; /* no change */ + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.AlphaFunc = func; + ctx->Color.AlphaRefUnclamped = ref; + ctx->Color.AlphaRef = CLAMP(ref, 0.0F, 1.0F); + + if (ctx->Driver.AlphaFunc) + ctx->Driver.AlphaFunc(ctx, func, ctx->Color.AlphaRef); + return; + + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" ); + return; + } +} + + +/** + * Specify a logic pixel operation for color index rendering. + * + * \param opcode operation. + * + * Verifies that \p opcode is a valid enum and updates +gl_colorbuffer_attrib::LogicOp. + * On a change, flushes the vertices and notifies the driver via the + * dd_function_table::LogicOpcode callback. + */ +void GLAPIENTRY +_mesa_LogicOp( GLenum opcode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glLogicOp(%s)\n", _mesa_lookup_enum_by_nr(opcode)); + + switch (opcode) { + case GL_CLEAR: + case GL_SET: + case GL_COPY: + case GL_COPY_INVERTED: + case GL_NOOP: + case GL_INVERT: + case GL_AND: + case GL_NAND: + case GL_OR: + case GL_NOR: + case GL_XOR: + case GL_EQUIV: + case GL_AND_REVERSE: + case GL_AND_INVERTED: + case GL_OR_REVERSE: + case GL_OR_INVERTED: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glLogicOp" ); + return; + } + + if (ctx->Color.LogicOp == opcode) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.LogicOp = opcode; + + if (ctx->Driver.LogicOpcode) + ctx->Driver.LogicOpcode( ctx, opcode ); +} + +#if _HAVE_FULL_GL +void GLAPIENTRY +_mesa_IndexMask( GLuint mask ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->Color.IndexMask == mask) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.IndexMask = mask; +} +#endif + + +/** + * Enable or disable writing of frame buffer color components. + * + * \param red whether to mask writing of the red color component. + * \param green whether to mask writing of the green color component. + * \param blue whether to mask writing of the blue color component. + * \param alpha whether to mask writing of the alpha color component. + * + * \sa glColorMask(). + * + * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask. On a + * change, flushes the vertices and notifies the driver via the + * dd_function_table::ColorMask callback. + */ +void GLAPIENTRY +_mesa_ColorMask( GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha ) +{ + GET_CURRENT_CONTEXT(ctx); + GLubyte tmp[4]; + GLuint i; + GLboolean flushed; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glColorMask(%d, %d, %d, %d)\n", + red, green, blue, alpha); + + /* Shouldn't have any information about channel depth in core mesa + * -- should probably store these as the native booleans: + */ + tmp[RCOMP] = red ? 0xff : 0x0; + tmp[GCOMP] = green ? 0xff : 0x0; + tmp[BCOMP] = blue ? 0xff : 0x0; + tmp[ACOMP] = alpha ? 0xff : 0x0; + + flushed = GL_FALSE; + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { + if (!TEST_EQ_4V(tmp, ctx->Color.ColorMask[i])) { + if (!flushed) { + FLUSH_VERTICES(ctx, _NEW_COLOR); + } + flushed = GL_TRUE; + COPY_4UBV(ctx->Color.ColorMask[i], tmp); + } + } + + if (ctx->Driver.ColorMask) + ctx->Driver.ColorMask( ctx, red, green, blue, alpha ); +} + + +/** + * For GL_EXT_draw_buffers2 and GL3 + */ +void GLAPIENTRY +_mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha ) +{ + GLubyte tmp[4]; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glColorMaskIndexed %u %d %d %d %d\n", + buf, red, green, blue, alpha); + + if (buf >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, "glColorMaskIndexed(buf=%u)", buf); + return; + } + + /* Shouldn't have any information about channel depth in core mesa + * -- should probably store these as the native booleans: + */ + tmp[RCOMP] = red ? 0xff : 0x0; + tmp[GCOMP] = green ? 0xff : 0x0; + tmp[BCOMP] = blue ? 0xff : 0x0; + tmp[ACOMP] = alpha ? 0xff : 0x0; + + if (TEST_EQ_4V(tmp, ctx->Color.ColorMask[buf])) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + COPY_4UBV(ctx->Color.ColorMask[buf], tmp); + + if (ctx->Driver.ColorMaskIndexed) + ctx->Driver.ColorMaskIndexed(ctx, buf, red, green, blue, alpha); +} + + +void GLAPIENTRY +_mesa_ClampColorARB(GLenum target, GLenum clamp) +{ + GET_CURRENT_CONTEXT(ctx); + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (clamp != GL_TRUE && clamp != GL_FALSE && clamp != GL_FIXED_ONLY_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(clamp)"); + return; + } + + switch (target) { + case GL_CLAMP_VERTEX_COLOR_ARB: + FLUSH_VERTICES(ctx, _NEW_LIGHT); + ctx->Light.ClampVertexColor = clamp; + break; + case GL_CLAMP_FRAGMENT_COLOR_ARB: + FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP); + ctx->Color.ClampFragmentColor = clamp; + break; + case GL_CLAMP_READ_COLOR_ARB: + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.ClampReadColor = clamp; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(target)"); + return; + } +} + + + + +/**********************************************************************/ +/** \name Initialization */ +/*@{*/ + +/** + * Initialization of the context's Color attribute group. + * + * \param ctx GL context. + * + * Initializes the related fields in the context color attribute group, + * __struct gl_contextRec::Color. + */ +void _mesa_init_color( struct gl_context * ctx ) +{ + GLuint i; + + /* Color buffer group */ + ctx->Color.IndexMask = ~0u; + memset(ctx->Color.ColorMask, 0xff, sizeof(ctx->Color.ColorMask)); + ctx->Color.ClearIndex = 0; + ASSIGN_4V( ctx->Color.ClearColor.f, 0, 0, 0, 0 ); + ctx->Color.AlphaEnabled = GL_FALSE; + ctx->Color.AlphaFunc = GL_ALWAYS; + ctx->Color.AlphaRef = 0; + ctx->Color.BlendEnabled = 0x0; + for (i = 0; i < Elements(ctx->Color.Blend); i++) { + ctx->Color.Blend[i].SrcRGB = GL_ONE; + ctx->Color.Blend[i].DstRGB = GL_ZERO; + ctx->Color.Blend[i].SrcA = GL_ONE; + ctx->Color.Blend[i].DstA = GL_ZERO; + ctx->Color.Blend[i].EquationRGB = GL_FUNC_ADD; + ctx->Color.Blend[i].EquationA = GL_FUNC_ADD; + } + ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 ); + ASSIGN_4V( ctx->Color.BlendColorUnclamped, 0.0, 0.0, 0.0, 0.0 ); + ctx->Color.IndexLogicOpEnabled = GL_FALSE; + ctx->Color.ColorLogicOpEnabled = GL_FALSE; + ctx->Color._LogicOpEnabled = GL_FALSE; + ctx->Color.LogicOp = GL_COPY; + ctx->Color.DitherFlag = GL_TRUE; + + if (ctx->Visual.doubleBufferMode) { + ctx->Color.DrawBuffer[0] = GL_BACK; + } + else { + ctx->Color.DrawBuffer[0] = GL_FRONT; + } + + ctx->Color.ClampFragmentColor = GL_FIXED_ONLY_ARB; + ctx->Color._ClampFragmentColor = GL_TRUE; + ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB; + ctx->Color._ClampReadColor = GL_TRUE; +} + +/*@}*/ diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c index fa95e4522..301fe694c 100644 --- a/mesalib/src/mesa/main/clear.c +++ b/mesalib/src/mesa/main/clear.c @@ -83,16 +83,11 @@ _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) tmp[2] = blue; tmp[3] = alpha; - if (TEST_EQ_4V(tmp, ctx->Color.ClearColorUnclamped)) + if (TEST_EQ_4V(tmp, ctx->Color.ClearColor.f)) return; /* no change */ FLUSH_VERTICES(ctx, _NEW_COLOR); - COPY_4V(ctx->Color.ClearColorUnclamped, tmp); - - ctx->Color.ClearColor[0] = CLAMP(tmp[0], 0.0F, 1.0F); - ctx->Color.ClearColor[1] = CLAMP(tmp[1], 0.0F, 1.0F); - ctx->Color.ClearColor[2] = CLAMP(tmp[2], 0.0F, 1.0F); - ctx->Color.ClearColor[3] = CLAMP(tmp[3], 0.0F, 1.0F); + COPY_4V(ctx->Color.ClearColor.f, tmp); if (ctx->Driver.ClearColor) { /* it's OK to call glClearColor in CI mode but it should be a NOP */ @@ -110,25 +105,22 @@ _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) void GLAPIENTRY _mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a) { - GLfloat tmp[4]; + GLint tmp[4]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - tmp[0] = (GLfloat) r; - tmp[1] = (GLfloat) g; - tmp[2] = (GLfloat) b; - tmp[3] = (GLfloat) a; + tmp[0] = r; + tmp[1] = g; + tmp[2] = b; + tmp[3] = a; - if (TEST_EQ_4V(tmp, ctx->Color.ClearColor)) + if (TEST_EQ_4V(tmp, ctx->Color.ClearColor.i)) return; /* no change */ FLUSH_VERTICES(ctx, _NEW_COLOR); + COPY_4V(ctx->Color.ClearColor.i, tmp); - /* XXX we should eventually have a float/int/uint union for - * the ctx->Color.ClearColor state. - */ - COPY_4V(ctx->Color.ClearColor, tmp); - + /* these should be NOP calls for drivers supporting EXT_texture_integer */ if (ctx->Driver.ClearColor) { ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); } @@ -141,25 +133,22 @@ _mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a) void GLAPIENTRY _mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a) { - GLfloat tmp[4]; + GLuint tmp[4]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - tmp[0] = (GLfloat) r; - tmp[1] = (GLfloat) g; - tmp[2] = (GLfloat) b; - tmp[3] = (GLfloat) a; + tmp[0] = r; + tmp[1] = g; + tmp[2] = b; + tmp[3] = a; - if (TEST_EQ_4V(tmp, ctx->Color.ClearColor)) + if (TEST_EQ_4V(tmp, ctx->Color.ClearColor.ui)) return; /* no change */ FLUSH_VERTICES(ctx, _NEW_COLOR); + COPY_4V(ctx->Color.ClearColor.ui, tmp); - /* XXX we should eventually have a float/int/uint union for - * the ctx->Color.ClearColor state. - */ - COPY_4V(ctx->Color.ClearColor, tmp); - + /* these should be NOP calls for drivers supporting EXT_texture_integer */ if (ctx->Driver.ClearColor) { ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); } @@ -364,21 +353,18 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) return; } else if (mask) { - /* XXX note: we're putting the integer clear values into the - * floating point state var. This will not always work. We'll - * need a new ctx->Driver.ClearBuffer() hook.... - */ - GLclampf clearSave[4]; + union gl_color_union clearSave; + /* save color */ - COPY_4V(clearSave, ctx->Color.ClearColor); + clearSave = ctx->Color.ClearColor; /* set color */ - COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); + COPY_4V(ctx->Color.ClearColor.i, value); if (ctx->Driver.ClearColor) ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); /* clear buffer(s) */ ctx->Driver.Clear(ctx, mask); /* restore color */ - COPY_4V(ctx->Color.ClearColor, clearSave); + ctx->Color.ClearColor = clearSave; if (ctx->Driver.ClearColor) ctx->Driver.ClearColor(ctx, clearSave); } @@ -418,21 +404,18 @@ _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) return; } else if (mask) { - /* XXX note: we're putting the uint clear values into the - * floating point state var. This will not always work. We'll - * need a new ctx->Driver.ClearBuffer() hook.... - */ - GLclampf clearSave[4]; + union gl_color_union clearSave; + /* save color */ - COPY_4V(clearSave, ctx->Color.ClearColor); + clearSave = ctx->Color.ClearColor; /* set color */ - COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); + COPY_4V(ctx->Color.ClearColor.ui, value); if (ctx->Driver.ClearColor) ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); /* clear buffer(s) */ ctx->Driver.Clear(ctx, mask); /* restore color */ - COPY_4V(ctx->Color.ClearColor, clearSave); + ctx->Color.ClearColor = clearSave; if (ctx->Driver.ClearColor) ctx->Driver.ClearColor(ctx, clearSave); } @@ -495,17 +478,18 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) return; } else if (mask) { - GLclampf clearSave[4]; + union gl_color_union clearSave; + /* save color */ - COPY_4V(clearSave, ctx->Color.ClearColor); + clearSave = ctx->Color.ClearColor; /* set color */ - COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); + COPY_4V_CAST(ctx->Color.ClearColor.f, value, GLclampf); if (ctx->Driver.ClearColor) ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); /* clear buffer(s) */ ctx->Driver.Clear(ctx, mask); /* restore color */ - COPY_4V(ctx->Color.ClearColor, clearSave); + ctx->Color.ClearColor = clearSave; if (ctx->Driver.ClearColor) ctx->Driver.ClearColor(ctx, clearSave); } diff --git a/mesalib/src/mesa/main/colormac.h b/mesalib/src/mesa/main/colormac.h index d308c48b6..4b7c3b4a0 100644 --- a/mesalib/src/mesa/main/colormac.h +++ b/mesalib/src/mesa/main/colormac.h @@ -169,6 +169,17 @@ do { \ } while (0) +/** + * Convert four float values in [0,1] to ubytes in [0,255] with clamping. + */ +static inline void +_mesa_unclamped_float_rgba_to_ubyte(GLubyte dst[4], const GLfloat src[4]) +{ + int i; + for (i = 0; i < 4; i++) + UNCLAMPED_FLOAT_TO_UBYTE(dst[i], src[i]); +} + /** * \name Generic color packing macros. All inputs should be GLubytes. diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index b77e4f092..d6cc0196d 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -589,7 +589,8 @@ struct dd_function_table { GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA); /** Specify clear values for the color buffers */ - void (*ClearColor)(struct gl_context *ctx, const GLfloat color[4]); + void (*ClearColor)(struct gl_context *ctx, + const union gl_color_union color); /** Specify the clear value for the depth buffer */ void (*ClearDepth)(struct gl_context *ctx, GLclampd d); /** Specify the clear value for the stencil buffer */ diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 069254b18..a777bd8c4 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -1673,10 +1673,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu COPY_4FV(v->value_float_4, ctx->Fog.ColorUnclamped); break; case GL_COLOR_CLEAR_VALUE: - if(ctx->Color._ClampFragmentColor) - COPY_4FV(v->value_float_4, ctx->Color.ClearColor); - else - COPY_4FV(v->value_float_4, ctx->Color.ClearColorUnclamped); + if(ctx->Color._ClampFragmentColor) { + v->value_float_4[0] = CLAMP(ctx->Color.ClearColor.f[0], 0.0F, 1.0F); + v->value_float_4[1] = CLAMP(ctx->Color.ClearColor.f[1], 0.0F, 1.0F); + v->value_float_4[2] = CLAMP(ctx->Color.ClearColor.f[2], 0.0F, 1.0F); + v->value_float_4[3] = CLAMP(ctx->Color.ClearColor.f[3], 0.0F, 1.0F); + } else + COPY_4FV(v->value_float_4, ctx->Color.ClearColor.f); break; case GL_BLEND_COLOR_EXT: if(ctx->Color._ClampFragmentColor) diff --git a/mesalib/src/mesa/main/image.c b/mesalib/src/mesa/main/image.c index 3e75e7c6b..66d7eec65 100644 --- a/mesalib/src/mesa/main/image.c +++ b/mesalib/src/mesa/main/image.c @@ -1513,12 +1513,8 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src, GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst); GLuint i; for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][RCOMP], src4[i][RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][GCOMP], src4[i][GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][BCOMP], src4[i][BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][ACOMP], src4[i][ACOMP]); - } + if (!mask || mask[i]) + _mesa_unclamped_float_rgba_to_ubyte(dst1[i], src4[i]); } if (useTemp) memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index ae500b4c2..8671ecda9 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -721,16 +721,26 @@ struct gl_accum_attrib /** + * Used for storing clear color, texture border color, etc. + * The float values are typically unclamped. + */ +union gl_color_union +{ + GLfloat f[4]; + GLint i[4]; + GLuint ui[4]; +}; + + +/** * Color buffer attribute group (GL_COLOR_BUFFER_BIT). */ struct gl_colorbuffer_attrib { - GLuint ClearIndex; /**< Index to use for glClear */ - GLfloat ClearColorUnclamped[4]; /**< Color to use for glClear*/ - GLclampf ClearColor[4]; /**< Color to use for glClear */ - - GLuint IndexMask; /**< Color index write mask */ - GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */ + GLuint ClearIndex; /**< Index for glClear */ + union gl_color_union ClearColor; /**< Color for glClear, unclamped */ + GLuint IndexMask; /**< Color index write mask */ + GLubyte ColorMask[MAX_DRAW_BUFFERS][4]; /**< Each flag is 0xff or 0x0 */ GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */ @@ -750,8 +760,8 @@ struct gl_colorbuffer_attrib /*@{*/ GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */ - /* NOTE: this does _not_ depend on fragment clamping or any other clamping control, - * only on the fixed-pointness of the render target. + /* NOTE: this does _not_ depend on fragment clamping or any other clamping + * control, only on the fixed-pointness of the render target. * The query does however depend on fragment color clamping. */ GLfloat BlendColorUnclamped[4]; /**< Blending color */ @@ -1356,11 +1366,7 @@ struct gl_sampler_object GLenum WrapR; /**< R-axis texture image wrap mode */ GLenum MinFilter; /**< minification filter */ GLenum MagFilter; /**< magnification filter */ - union { - GLfloat f[4]; - GLuint ui[4]; - GLint i[4]; - } BorderColor; /**< Interpreted according to texture format */ + union gl_color_union BorderColor; /**< Interpreted according to texture format */ GLfloat MinLod; /**< min lambda, OpenGL 1.2 */ GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */ GLfloat LodBias; /**< OpenGL 1.4 */ diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index b0f9c33b8..2323819aa 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -111,21 +111,43 @@ is_sampler_type(GLenum type) { switch (type) { case GL_SAMPLER_1D: + case GL_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_1D: case GL_SAMPLER_2D: + case GL_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_2D: case GL_SAMPLER_3D: + case GL_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_3D: case GL_SAMPLER_CUBE: + case GL_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_CUBE: case GL_SAMPLER_1D_SHADOW: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_CUBE_SHADOW: case GL_SAMPLER_2D_RECT_ARB: + case GL_INT_SAMPLER_2D_RECT: + case GL_UNSIGNED_INT_SAMPLER_2D_RECT: case GL_SAMPLER_2D_RECT_SHADOW_ARB: case GL_SAMPLER_1D_ARRAY_EXT: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: case GL_SAMPLER_2D_ARRAY_EXT: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: case GL_SAMPLER_1D_ARRAY_SHADOW_EXT: case GL_SAMPLER_2D_ARRAY_SHADOW_EXT: case GL_SAMPLER_CUBE_MAP_ARRAY: case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: case GL_SAMPLER_BUFFER: + case GL_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: return GL_TRUE; default: return GL_FALSE; diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c index 117000ba7..a4799e3cc 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.c +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c @@ -323,9 +323,9 @@ clear_with_quad(struct gl_context *ctx, set_vertex_shader(st); if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { - st_translate_color(ctx->Color.ClearColorUnclamped, - ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, - clearColor); + st_translate_color(ctx->Color.ClearColor.f, + ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, + clearColor); } /* draw quad matching scissor rect */ @@ -582,12 +582,12 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { - st_translate_color(ctx->Color.ClearColor, - ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, - clearColor); + st_translate_color(ctx->Color.ClearColor.f, + ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, + clearColor); } - st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColorUnclamped, + st->pipe->clear(st->pipe, clear_buffers, clearColor, ctx->Depth.Clear, ctx->Stencil.Clear); } if (mask & BUFFER_BIT_ACCUM) diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index bd4f0860c..6eb8a506b 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -1441,8 +1441,9 @@ st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2) * This is used for translating texture border color and the clear * color. For example, the clear color is interpreted according to * the renderbuffer's base format. For example, if clearing a - * GL_LUMINANCE buffer, ClearColor[0] = luminance and ClearColor[1] = - * alpha. Similarly for texture border colors. + * GL_LUMINANCE buffer, we'll return colorOut[0] = colorOut[1] = + * colorOut[2] = colorIn[0]. + * Similarly for texture border colors. */ void st_translate_color(const GLfloat colorIn[4], GLenum baseFormat, diff --git a/mesalib/src/mesa/swrast/s_blend.c b/mesalib/src/mesa/swrast/s_blend.c index 125364913..3760f91d6 100644 --- a/mesalib/src/mesa/swrast/s_blend.c +++ b/mesalib/src/mesa/swrast/s_blend.c @@ -1,1014 +1,1010 @@ -/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-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.
- */
-
-
-/**
- * \file swrast/s_blend.c
- * \brief software blending.
- * \author Brian Paul
- *
- * Only a few blend modes have been optimized (min, max, transparency, add)
- * more optimized cases can easily be added if needed.
- * Celestia uses glBlendFunc(GL_SRC_ALPHA, GL_ONE), for example.
- */
-
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/colormac.h"
-#include "main/macros.h"
-
-#include "s_blend.h"
-#include "s_context.h"
-#include "s_span.h"
-
-
-#if defined(USE_MMX_ASM)
-#include "x86/mmx.h"
-#include "x86/common_x86_asm.h"
-#define _BLENDAPI _ASMAPI
-#else
-#define _BLENDAPI
-#endif
-
-
-/**
- * Integer divide by 255
- * Declare "int divtemp" before using.
- * This satisfies Glean and should be reasonably fast.
- * Contributed by Nathan Hand.
- */
-#define DIV255(X) (divtemp = (X), ((divtemp << 8) + divtemp + 256) >> 16)
-
-
-
-/**
- * Special case for glBlendFunc(GL_ZERO, GL_ONE).
- * No-op means the framebuffer values remain unchanged.
- * Any chanType ok.
- */
-static void _BLENDAPI
-blend_noop(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLvoid *src, const GLvoid *dst, GLenum chanType)
-{
- GLint bytes;
-
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ZERO);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE);
- (void) ctx;
-
- /* just memcpy */
- if (chanType == GL_UNSIGNED_BYTE)
- bytes = 4 * n * sizeof(GLubyte);
- else if (chanType == GL_UNSIGNED_SHORT)
- bytes = 4 * n * sizeof(GLushort);
- else
- bytes = 4 * n * sizeof(GLfloat);
-
- memcpy(src, dst, bytes);
-}
-
-
-/**
- * Special case for glBlendFunc(GL_ONE, GL_ZERO)
- * Any chanType ok.
- */
-static void _BLENDAPI
-blend_replace(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLvoid *src, const GLvoid *dst, GLenum chanType)
-{
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ZERO);
- (void) ctx;
- (void) n;
- (void) mask;
- (void) src;
- (void) dst;
-}
-
-
-/**
- * Common transparency blending mode:
- * glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).
- */
-static void _BLENDAPI
-blend_transparency_ubyte(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLvoid *src, const GLvoid *dst, GLenum chanType)
-{
- GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
- const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
- GLuint i;
-
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(chanType == GL_UNSIGNED_BYTE);
-
- (void) ctx;
-
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- const GLint t = rgba[i][ACOMP]; /* t is in [0, 255] */
- if (t == 0) {
- /* 0% alpha */
- COPY_4UBV(rgba[i], dest[i]);
- }
- else if (t != 255) {
- GLint divtemp;
- const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP];
- const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP];
- const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP];
- const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP];
- ASSERT(r <= 255);
- ASSERT(g <= 255);
- ASSERT(b <= 255);
- ASSERT(a <= 255);
- rgba[i][RCOMP] = (GLubyte) r;
- rgba[i][GCOMP] = (GLubyte) g;
- rgba[i][BCOMP] = (GLubyte) b;
- rgba[i][ACOMP] = (GLubyte) a;
- }
- }
- }
-}
-
-
-static void _BLENDAPI
-blend_transparency_ushort(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLvoid *src, const GLvoid *dst, GLenum chanType)
-{
- GLushort (*rgba)[4] = (GLushort (*)[4]) src;
- const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
- GLuint i;
-
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(chanType == GL_UNSIGNED_SHORT);
-
- (void) ctx;
-
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- const GLint t = rgba[i][ACOMP];
- if (t == 0) {
- /* 0% alpha */
- COPY_4V(rgba[i], dest[i]);
- }
- else if (t != 65535) {
- const GLfloat tt = (GLfloat) t / 65535.0F;
- GLushort r = (GLushort) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]);
- GLushort g = (GLushort) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]);
- GLushort b = (GLushort) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]);
- GLushort a = (GLushort) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]);
- ASSIGN_4V(rgba[i], r, g, b, a);
- }
- }
- }
-}
-
-
-static void _BLENDAPI
-blend_transparency_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLvoid *src, const GLvoid *dst, GLenum chanType)
-{
- GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
- const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
- GLuint i;
-
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA);
- ASSERT(chanType == GL_FLOAT);
-
- (void) ctx;
-
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- const GLfloat t = rgba[i][ACOMP]; /* t in [0, 1] */
- if (t == 0.0F) {
- /* 0% alpha */
- COPY_4V(rgba[i], dest[i]);
- }
- else if (t != 1.0F) {
- GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * t + dest[i][RCOMP];
- GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * t + dest[i][GCOMP];
- GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * t + dest[i][BCOMP];
- GLfloat a = (rgba[i][ACOMP] - dest[i][ACOMP]) * t + dest[i][ACOMP];
- ASSIGN_4V(rgba[i], r, g, b, a);
- }
- }
- }
-}
-
-
-
-/**
- * Add src and dest: glBlendFunc(GL_ONE, GL_ONE).
- * Any chanType ok.
- */
-static void _BLENDAPI
-blend_add(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLvoid *src, const GLvoid *dst, GLenum chanType)
-{
- GLuint i;
-
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD);
- ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE);
- ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE);
- (void) ctx;
-
- if (chanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
- const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
- GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
- GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
- GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
- rgba[i][RCOMP] = (GLubyte) MIN2( r, 255 );
- rgba[i][GCOMP] = (GLubyte) MIN2( g, 255 );
- rgba[i][BCOMP] = (GLubyte) MIN2( b, 255 );
- rgba[i][ACOMP] = (GLubyte) MIN2( a, 255 );
- }
- }
- }
- else if (chanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = (GLushort (*)[4]) src;
- const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
- GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
- GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
- GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
- rgba[i][RCOMP] = (GLshort) MIN2( r, 255 );
- rgba[i][GCOMP] = (GLshort) MIN2( g, 255 );
- rgba[i][BCOMP] = (GLshort) MIN2( b, 255 );
- rgba[i][ACOMP] = (GLshort) MIN2( a, 255 );
- }
- }
- }
- else {
- GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
- const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
- ASSERT(chanType == GL_FLOAT);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- /* don't RGB clamp to max */
- rgba[i][RCOMP] += dest[i][RCOMP];
- rgba[i][GCOMP] += dest[i][GCOMP];
- rgba[i][BCOMP] += dest[i][BCOMP];
- rgba[i][ACOMP] += dest[i][ACOMP];
- }
- }
- }
-}
-
-
-
-/**
- * Blend min function.
- * Any chanType ok.
- */
-static void _BLENDAPI
-blend_min(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLvoid *src, const GLvoid *dst, GLenum chanType)
-{
- GLuint i;
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MIN);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_MIN);
- (void) ctx;
-
- if (chanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
- const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
- rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
- rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
- rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
- }
- }
- }
- else if (chanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = (GLushort (*)[4]) src;
- const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
- rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
- rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
- rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
- }
- }
- }
- else {
- GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
- const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
- ASSERT(chanType == GL_FLOAT);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
- rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
- rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
- rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
- }
- }
- }
-}
-
-
-/**
- * Blend max function.
- * Any chanType ok.
- */
-static void _BLENDAPI
-blend_max(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLvoid *src, const GLvoid *dst, GLenum chanType)
-{
- GLuint i;
- ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MAX);
- ASSERT(ctx->Color.Blend[0].EquationA == GL_MAX);
- (void) ctx;
-
- if (chanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
- const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
- rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
- rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
- rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
- }
- }
- }
- else if (chanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = (GLushort (*)[4]) src;
- const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
- rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
- rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
- rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
- }
- }
- }
- else {
- GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
- const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
- ASSERT(chanType == GL_FLOAT);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
- rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
- rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
- rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
- }
- }
- }
-}
-
-
-
-/**
- * Modulate: result = src * dest
- * Any chanType ok.
- */
-static void _BLENDAPI
-blend_modulate(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLvoid *src, const GLvoid *dst, GLenum chanType)
-{
- GLuint i;
- (void) ctx;
-
- if (chanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
- const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- GLint divtemp;
- rgba[i][RCOMP] = DIV255(rgba[i][RCOMP] * dest[i][RCOMP]);
- rgba[i][GCOMP] = DIV255(rgba[i][GCOMP] * dest[i][GCOMP]);
- rgba[i][BCOMP] = DIV255(rgba[i][BCOMP] * dest[i][BCOMP]);
- rgba[i][ACOMP] = DIV255(rgba[i][ACOMP] * dest[i][ACOMP]);
- }
- }
- }
- else if (chanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = (GLushort (*)[4]) src;
- const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = (rgba[i][RCOMP] * dest[i][RCOMP] + 65535) >> 16;
- rgba[i][GCOMP] = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16;
- rgba[i][BCOMP] = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16;
- rgba[i][ACOMP] = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16;
- }
- }
- }
- else {
- GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
- const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
- ASSERT(chanType == GL_FLOAT);
- for (i=0;i<n;i++) {
- if (mask[i]) {
- rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP];
- rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP];
- rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP];
- rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP];
- }
- }
- }
-}
-
-
-/**
- * Do any blending operation, using floating point.
- * \param n number of pixels
- * \param mask fragment writemask array
- * \param rgba array of incoming (and modified) pixels
- * \param dest array of pixels from the dest color buffer
- */
-static void
-blend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- GLfloat rgba[][4], GLfloat dest[][4],
- GLenum chanType)
-{
- GLuint i;
-
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- /* Incoming/source Color */
- const GLfloat Rs = rgba[i][RCOMP];
- const GLfloat Gs = rgba[i][GCOMP];
- const GLfloat Bs = rgba[i][BCOMP];
- const GLfloat As = rgba[i][ACOMP];
-
- /* Frame buffer/dest color */
- const GLfloat Rd = dest[i][RCOMP];
- const GLfloat Gd = dest[i][GCOMP];
- const GLfloat Bd = dest[i][BCOMP];
- const GLfloat Ad = dest[i][ACOMP];
-
- GLfloat sR, sG, sB, sA; /* Source factor */
- GLfloat dR, dG, dB, dA; /* Dest factor */
- GLfloat r, g, b, a; /* result color */
-
- /* XXX for the case of constant blend terms we could init
- * the sX and dX variables just once before the loop.
- */
-
- /* Source RGB factor */
- switch (ctx->Color.Blend[0].SrcRGB) {
- case GL_ZERO:
- sR = sG = sB = 0.0F;
- break;
- case GL_ONE:
- sR = sG = sB = 1.0F;
- break;
- case GL_DST_COLOR:
- sR = Rd;
- sG = Gd;
- sB = Bd;
- break;
- case GL_ONE_MINUS_DST_COLOR:
- sR = 1.0F - Rd;
- sG = 1.0F - Gd;
- sB = 1.0F - Bd;
- break;
- case GL_SRC_ALPHA:
- sR = sG = sB = As;
- break;
- case GL_ONE_MINUS_SRC_ALPHA:
- sR = sG = sB = 1.0F - As;
- break;
- case GL_DST_ALPHA:
- sR = sG = sB = Ad;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- sR = sG = sB = 1.0F - Ad;
- break;
- case GL_SRC_ALPHA_SATURATE:
- if (As < 1.0F - Ad) {
- sR = sG = sB = As;
- }
- else {
- sR = sG = sB = 1.0F - Ad;
- }
- break;
- case GL_CONSTANT_COLOR:
- sR = ctx->Color.BlendColor[0];
- sG = ctx->Color.BlendColor[1];
- sB = ctx->Color.BlendColor[2];
- break;
- case GL_ONE_MINUS_CONSTANT_COLOR:
- sR = 1.0F - ctx->Color.BlendColor[0];
- sG = 1.0F - ctx->Color.BlendColor[1];
- sB = 1.0F - ctx->Color.BlendColor[2];
- break;
- case GL_CONSTANT_ALPHA:
- sR = sG = sB = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_SRC_COLOR:
- sR = Rs;
- sG = Gs;
- sB = Bs;
- break;
- case GL_ONE_MINUS_SRC_COLOR:
- sR = 1.0F - Rs;
- sG = 1.0F - Gs;
- sB = 1.0F - Bs;
- break;
- default:
- /* this should never happen */
- _mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float");
- return;
- }
-
- /* Source Alpha factor */
- switch (ctx->Color.Blend[0].SrcA) {
- case GL_ZERO:
- sA = 0.0F;
- break;
- case GL_ONE:
- sA = 1.0F;
- break;
- case GL_DST_COLOR:
- sA = Ad;
- break;
- case GL_ONE_MINUS_DST_COLOR:
- sA = 1.0F - Ad;
- break;
- case GL_SRC_ALPHA:
- sA = As;
- break;
- case GL_ONE_MINUS_SRC_ALPHA:
- sA = 1.0F - As;
- break;
- case GL_DST_ALPHA:
- sA = Ad;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- sA = 1.0F - Ad;
- break;
- case GL_SRC_ALPHA_SATURATE:
- sA = 1.0;
- break;
- case GL_CONSTANT_COLOR:
- sA = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_COLOR:
- sA = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_CONSTANT_ALPHA:
- sA = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- sA = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_SRC_COLOR:
- sA = As;
- break;
- case GL_ONE_MINUS_SRC_COLOR:
- sA = 1.0F - As;
- break;
- default:
- /* this should never happen */
- sA = 0.0F;
- _mesa_problem(ctx, "Bad blend source A factor in blend_general_float");
- return;
- }
-
- /* Dest RGB factor */
- switch (ctx->Color.Blend[0].DstRGB) {
- case GL_ZERO:
- dR = dG = dB = 0.0F;
- break;
- case GL_ONE:
- dR = dG = dB = 1.0F;
- break;
- case GL_SRC_COLOR:
- dR = Rs;
- dG = Gs;
- dB = Bs;
- break;
- case GL_ONE_MINUS_SRC_COLOR:
- dR = 1.0F - Rs;
- dG = 1.0F - Gs;
- dB = 1.0F - Bs;
- break;
- case GL_SRC_ALPHA:
- dR = dG = dB = As;
- break;
- case GL_ONE_MINUS_SRC_ALPHA:
- dR = dG = dB = 1.0F - As;
- break;
- case GL_DST_ALPHA:
- dR = dG = dB = Ad;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- dR = dG = dB = 1.0F - Ad;
- break;
- case GL_CONSTANT_COLOR:
- dR = ctx->Color.BlendColor[0];
- dG = ctx->Color.BlendColor[1];
- dB = ctx->Color.BlendColor[2];
- break;
- case GL_ONE_MINUS_CONSTANT_COLOR:
- dR = 1.0F - ctx->Color.BlendColor[0];
- dG = 1.0F - ctx->Color.BlendColor[1];
- dB = 1.0F - ctx->Color.BlendColor[2];
- break;
- case GL_CONSTANT_ALPHA:
- dR = dG = dB = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_DST_COLOR:
- dR = Rd;
- dG = Gd;
- dB = Bd;
- break;
- case GL_ONE_MINUS_DST_COLOR:
- dR = 1.0F - Rd;
- dG = 1.0F - Gd;
- dB = 1.0F - Bd;
- break;
- default:
- /* this should never happen */
- dR = dG = dB = 0.0F;
- _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float");
- return;
- }
-
- /* Dest Alpha factor */
- switch (ctx->Color.Blend[0].DstA) {
- case GL_ZERO:
- dA = 0.0F;
- break;
- case GL_ONE:
- dA = 1.0F;
- break;
- case GL_SRC_COLOR:
- dA = As;
- break;
- case GL_ONE_MINUS_SRC_COLOR:
- dA = 1.0F - As;
- break;
- case GL_SRC_ALPHA:
- dA = As;
- break;
- case GL_ONE_MINUS_SRC_ALPHA:
- dA = 1.0F - As;
- break;
- case GL_DST_ALPHA:
- dA = Ad;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- dA = 1.0F - Ad;
- break;
- case GL_CONSTANT_COLOR:
- dA = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_COLOR:
- dA = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_CONSTANT_ALPHA:
- dA = ctx->Color.BlendColor[3];
- break;
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- dA = 1.0F - ctx->Color.BlendColor[3];
- break;
- case GL_DST_COLOR:
- dA = Ad;
- break;
- case GL_ONE_MINUS_DST_COLOR:
- dA = 1.0F - Ad;
- break;
- default:
- /* this should never happen */
- dA = 0.0F;
- _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float");
- return;
- }
-
- /* compute the blended RGB */
- switch (ctx->Color.Blend[0].EquationRGB) {
- case GL_FUNC_ADD:
- r = Rs * sR + Rd * dR;
- g = Gs * sG + Gd * dG;
- b = Bs * sB + Bd * dB;
- a = As * sA + Ad * dA;
- break;
- case GL_FUNC_SUBTRACT:
- r = Rs * sR - Rd * dR;
- g = Gs * sG - Gd * dG;
- b = Bs * sB - Bd * dB;
- a = As * sA - Ad * dA;
- break;
- case GL_FUNC_REVERSE_SUBTRACT:
- r = Rd * dR - Rs * sR;
- g = Gd * dG - Gs * sG;
- b = Bd * dB - Bs * sB;
- a = Ad * dA - As * sA;
- break;
- case GL_MIN:
- r = MIN2( Rd, Rs );
- g = MIN2( Gd, Gs );
- b = MIN2( Bd, Bs );
- break;
- case GL_MAX:
- r = MAX2( Rd, Rs );
- g = MAX2( Gd, Gs );
- b = MAX2( Bd, Bs );
- break;
- default:
- /* should never get here */
- r = g = b = 0.0F; /* silence uninitialized var warning */
- _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
- return;
- }
-
- /* compute the blended alpha */
- switch (ctx->Color.Blend[0].EquationA) {
- case GL_FUNC_ADD:
- a = As * sA + Ad * dA;
- break;
- case GL_FUNC_SUBTRACT:
- a = As * sA - Ad * dA;
- break;
- case GL_FUNC_REVERSE_SUBTRACT:
- a = Ad * dA - As * sA;
- break;
- case GL_MIN:
- a = MIN2( Ad, As );
- break;
- case GL_MAX:
- a = MAX2( Ad, As );
- break;
- default:
- /* should never get here */
- a = 0.0F; /* silence uninitialized var warning */
- _mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
- return;
- }
-
- /* final clamping */
-#if 0
- rgba[i][RCOMP] = MAX2( r, 0.0F );
- rgba[i][GCOMP] = MAX2( g, 0.0F );
- rgba[i][BCOMP] = MAX2( b, 0.0F );
- rgba[i][ACOMP] = CLAMP( a, 0.0F, 1.0F );
-#else
- ASSIGN_4V(rgba[i], r, g, b, a);
-#endif
- }
- }
-}
-
-
-/**
- * Do any blending operation, any chanType.
- */
-static void
-blend_general(struct gl_context *ctx, GLuint n, const GLubyte mask[],
- void *src, const void *dst, GLenum chanType)
-{
- GLfloat (*rgbaF)[4], (*destF)[4];
-
- rgbaF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
- destF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
- if (!rgbaF || !destF) {
- free(rgbaF);
- free(destF);
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "blending");
- return;
- }
-
- if (chanType == GL_UNSIGNED_BYTE) {
- GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
- const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
- GLuint i;
- /* convert ubytes to floats */
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]);
- rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]);
- rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]);
- rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]);
- destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]);
- destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]);
- destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]);
- destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]);
- }
- }
- /* do blend */
- blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
- /* convert back to ubytes */
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], rgbaF[i][RCOMP]);
- UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], rgbaF[i][GCOMP]);
- UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], rgbaF[i][BCOMP]);
- UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], rgbaF[i][ACOMP]);
- }
- }
- }
- else if (chanType == GL_UNSIGNED_SHORT) {
- GLushort (*rgba)[4] = (GLushort (*)[4]) src;
- const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
- GLuint i;
- /* convert ushorts to floats */
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]);
- rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]);
- rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]);
- rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]);
- destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]);
- destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]);
- destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]);
- destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]);
- }
- }
- /* do blend */
- blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
- /* convert back to ushorts */
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]);
- UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]);
- }
- }
- }
- else {
- blend_general_float(ctx, n, mask, (GLfloat (*)[4]) src,
- (GLfloat (*)[4]) dst, chanType);
- }
-
- free(rgbaF);
- free(destF);
-}
-
-
-
-/**
- * Analyze current blending parameters to pick fastest blending function.
- * Result: the ctx->Color.BlendFunc pointer is updated.
- */
-void
-_swrast_choose_blend_func(struct gl_context *ctx, GLenum chanType)
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const GLenum eq = ctx->Color.Blend[0].EquationRGB;
- const GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
- const GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
- const GLenum srcA = ctx->Color.Blend[0].SrcA;
- const GLenum dstA = ctx->Color.Blend[0].DstA;
-
- if (ctx->Color.Blend[0].EquationRGB != ctx->Color.Blend[0].EquationA) {
- swrast->BlendFunc = blend_general;
- }
- else if (eq == GL_MIN) {
- /* Note: GL_MIN ignores the blending weight factors */
-#if defined(USE_MMX_ASM)
- if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
- swrast->BlendFunc = _mesa_mmx_blend_min;
- }
- else
-#endif
- swrast->BlendFunc = blend_min;
- }
- else if (eq == GL_MAX) {
- /* Note: GL_MAX ignores the blending weight factors */
-#if defined(USE_MMX_ASM)
- if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
- swrast->BlendFunc = _mesa_mmx_blend_max;
- }
- else
-#endif
- swrast->BlendFunc = blend_max;
- }
- else if (srcRGB != srcA || dstRGB != dstA) {
- swrast->BlendFunc = blend_general;
- }
- else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA
- && dstRGB == GL_ONE_MINUS_SRC_ALPHA) {
-#if defined(USE_MMX_ASM)
- if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
- swrast->BlendFunc = _mesa_mmx_blend_transparency;
- }
- else
-#endif
- {
- if (chanType == GL_UNSIGNED_BYTE)
- swrast->BlendFunc = blend_transparency_ubyte;
- else if (chanType == GL_UNSIGNED_SHORT)
- swrast->BlendFunc = blend_transparency_ushort;
- else
- swrast->BlendFunc = blend_transparency_float;
- }
- }
- else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) {
-#if defined(USE_MMX_ASM)
- if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
- swrast->BlendFunc = _mesa_mmx_blend_add;
- }
- else
-#endif
- swrast->BlendFunc = blend_add;
- }
- else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT)
- && (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR))
- ||
- ((eq == GL_FUNC_ADD || eq == GL_FUNC_SUBTRACT)
- && (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) {
-#if defined(USE_MMX_ASM)
- if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) {
- swrast->BlendFunc = _mesa_mmx_blend_modulate;
- }
- else
-#endif
- swrast->BlendFunc = blend_modulate;
- }
- else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
- swrast->BlendFunc = blend_noop;
- }
- else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
- swrast->BlendFunc = blend_replace;
- }
- else {
- swrast->BlendFunc = blend_general;
- }
-}
-
-
-
-/**
- * Apply the blending operator to a span of pixels.
- * We can handle horizontal runs of pixels (spans) or arrays of x/y
- * pixel coordinates.
- */
-void
-_swrast_blend_span(struct gl_context *ctx, struct gl_renderbuffer *rb, SWspan *span)
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- void *rbPixels;
-
- ASSERT(span->end <= MAX_WIDTH);
- ASSERT(span->arrayMask & SPAN_RGBA);
- ASSERT(rb->DataType == span->array->ChanType);
- ASSERT(!ctx->Color._LogicOpEnabled);
-
- rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
-
- swrast->BlendFunc(ctx, span->end, span->array->mask,
- span->array->rgba, rbPixels, span->array->ChanType);
-}
+/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-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. + */ + + +/** + * \file swrast/s_blend.c + * \brief software blending. + * \author Brian Paul + * + * Only a few blend modes have been optimized (min, max, transparency, add) + * more optimized cases can easily be added if needed. + * Celestia uses glBlendFunc(GL_SRC_ALPHA, GL_ONE), for example. + */ + + + +#include "main/glheader.h" +#include "main/context.h" +#include "main/colormac.h" +#include "main/macros.h" + +#include "s_blend.h" +#include "s_context.h" +#include "s_span.h" + + +#if defined(USE_MMX_ASM) +#include "x86/mmx.h" +#include "x86/common_x86_asm.h" +#define _BLENDAPI _ASMAPI +#else +#define _BLENDAPI +#endif + + +/** + * Integer divide by 255 + * Declare "int divtemp" before using. + * This satisfies Glean and should be reasonably fast. + * Contributed by Nathan Hand. + */ +#define DIV255(X) (divtemp = (X), ((divtemp << 8) + divtemp + 256) >> 16) + + + +/** + * Special case for glBlendFunc(GL_ZERO, GL_ONE). + * No-op means the framebuffer values remain unchanged. + * Any chanType ok. + */ +static void _BLENDAPI +blend_noop(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + GLint bytes; + + ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ZERO); + ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE); + (void) ctx; + + /* just memcpy */ + if (chanType == GL_UNSIGNED_BYTE) + bytes = 4 * n * sizeof(GLubyte); + else if (chanType == GL_UNSIGNED_SHORT) + bytes = 4 * n * sizeof(GLushort); + else + bytes = 4 * n * sizeof(GLfloat); + + memcpy(src, dst, bytes); +} + + +/** + * Special case for glBlendFunc(GL_ONE, GL_ZERO) + * Any chanType ok. + */ +static void _BLENDAPI +blend_replace(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE); + ASSERT(ctx->Color.Blend[0].DstRGB == GL_ZERO); + (void) ctx; + (void) n; + (void) mask; + (void) src; + (void) dst; +} + + +/** + * Common transparency blending mode: + * glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). + */ +static void _BLENDAPI +blend_transparency_ubyte(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; + const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; + GLuint i; + + ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA); + ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA); + ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA); + ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA); + ASSERT(chanType == GL_UNSIGNED_BYTE); + + (void) ctx; + + for (i = 0; i < n; i++) { + if (mask[i]) { + const GLint t = rgba[i][ACOMP]; /* t is in [0, 255] */ + if (t == 0) { + /* 0% alpha */ + COPY_4UBV(rgba[i], dest[i]); + } + else if (t != 255) { + GLint divtemp; + const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP]; + const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP]; + const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP]; + const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP]; + ASSERT(r <= 255); + ASSERT(g <= 255); + ASSERT(b <= 255); + ASSERT(a <= 255); + rgba[i][RCOMP] = (GLubyte) r; + rgba[i][GCOMP] = (GLubyte) g; + rgba[i][BCOMP] = (GLubyte) b; + rgba[i][ACOMP] = (GLubyte) a; + } + } + } +} + + +static void _BLENDAPI +blend_transparency_ushort(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + GLushort (*rgba)[4] = (GLushort (*)[4]) src; + const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; + GLuint i; + + ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA); + ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA); + ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA); + ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA); + ASSERT(chanType == GL_UNSIGNED_SHORT); + + (void) ctx; + + for (i = 0; i < n; i++) { + if (mask[i]) { + const GLint t = rgba[i][ACOMP]; + if (t == 0) { + /* 0% alpha */ + COPY_4V(rgba[i], dest[i]); + } + else if (t != 65535) { + const GLfloat tt = (GLfloat) t / 65535.0F; + GLushort r = (GLushort) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]); + GLushort g = (GLushort) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]); + GLushort b = (GLushort) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]); + GLushort a = (GLushort) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]); + ASSIGN_4V(rgba[i], r, g, b, a); + } + } + } +} + + +static void _BLENDAPI +blend_transparency_float(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; + const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; + GLuint i; + + ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].SrcRGB == GL_SRC_ALPHA); + ASSERT(ctx->Color.Blend[0].SrcA == GL_SRC_ALPHA); + ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE_MINUS_SRC_ALPHA); + ASSERT(ctx->Color.Blend[0].DstA == GL_ONE_MINUS_SRC_ALPHA); + ASSERT(chanType == GL_FLOAT); + + (void) ctx; + + for (i = 0; i < n; i++) { + if (mask[i]) { + const GLfloat t = rgba[i][ACOMP]; /* t in [0, 1] */ + if (t == 0.0F) { + /* 0% alpha */ + COPY_4V(rgba[i], dest[i]); + } + else if (t != 1.0F) { + GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * t + dest[i][RCOMP]; + GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * t + dest[i][GCOMP]; + GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * t + dest[i][BCOMP]; + GLfloat a = (rgba[i][ACOMP] - dest[i][ACOMP]) * t + dest[i][ACOMP]; + ASSIGN_4V(rgba[i], r, g, b, a); + } + } + } +} + + + +/** + * Add src and dest: glBlendFunc(GL_ONE, GL_ONE). + * Any chanType ok. + */ +static void _BLENDAPI +blend_add(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + GLuint i; + + ASSERT(ctx->Color.Blend[0].EquationRGB == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].EquationA == GL_FUNC_ADD); + ASSERT(ctx->Color.Blend[0].SrcRGB == GL_ONE); + ASSERT(ctx->Color.Blend[0].DstRGB == GL_ONE); + (void) ctx; + + if (chanType == GL_UNSIGNED_BYTE) { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; + const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; + for (i=0;i<n;i++) { + if (mask[i]) { + GLint r = rgba[i][RCOMP] + dest[i][RCOMP]; + GLint g = rgba[i][GCOMP] + dest[i][GCOMP]; + GLint b = rgba[i][BCOMP] + dest[i][BCOMP]; + GLint a = rgba[i][ACOMP] + dest[i][ACOMP]; + rgba[i][RCOMP] = (GLubyte) MIN2( r, 255 ); + rgba[i][GCOMP] = (GLubyte) MIN2( g, 255 ); + rgba[i][BCOMP] = (GLubyte) MIN2( b, 255 ); + rgba[i][ACOMP] = (GLubyte) MIN2( a, 255 ); + } + } + } + else if (chanType == GL_UNSIGNED_SHORT) { + GLushort (*rgba)[4] = (GLushort (*)[4]) src; + const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; + for (i=0;i<n;i++) { + if (mask[i]) { + GLint r = rgba[i][RCOMP] + dest[i][RCOMP]; + GLint g = rgba[i][GCOMP] + dest[i][GCOMP]; + GLint b = rgba[i][BCOMP] + dest[i][BCOMP]; + GLint a = rgba[i][ACOMP] + dest[i][ACOMP]; + rgba[i][RCOMP] = (GLshort) MIN2( r, 255 ); + rgba[i][GCOMP] = (GLshort) MIN2( g, 255 ); + rgba[i][BCOMP] = (GLshort) MIN2( b, 255 ); + rgba[i][ACOMP] = (GLshort) MIN2( a, 255 ); + } + } + } + else { + GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; + const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; + ASSERT(chanType == GL_FLOAT); + for (i=0;i<n;i++) { + if (mask[i]) { + /* don't RGB clamp to max */ + rgba[i][RCOMP] += dest[i][RCOMP]; + rgba[i][GCOMP] += dest[i][GCOMP]; + rgba[i][BCOMP] += dest[i][BCOMP]; + rgba[i][ACOMP] += dest[i][ACOMP]; + } + } + } +} + + + +/** + * Blend min function. + * Any chanType ok. + */ +static void _BLENDAPI +blend_min(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + GLuint i; + ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MIN); + ASSERT(ctx->Color.Blend[0].EquationA == GL_MIN); + (void) ctx; + + if (chanType == GL_UNSIGNED_BYTE) { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; + const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; + for (i=0;i<n;i++) { + if (mask[i]) { + rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] ); + rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] ); + rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] ); + rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] ); + } + } + } + else if (chanType == GL_UNSIGNED_SHORT) { + GLushort (*rgba)[4] = (GLushort (*)[4]) src; + const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; + for (i=0;i<n;i++) { + if (mask[i]) { + rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] ); + rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] ); + rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] ); + rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] ); + } + } + } + else { + GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; + const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; + ASSERT(chanType == GL_FLOAT); + for (i=0;i<n;i++) { + if (mask[i]) { + rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] ); + rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] ); + rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] ); + rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] ); + } + } + } +} + + +/** + * Blend max function. + * Any chanType ok. + */ +static void _BLENDAPI +blend_max(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + GLuint i; + ASSERT(ctx->Color.Blend[0].EquationRGB == GL_MAX); + ASSERT(ctx->Color.Blend[0].EquationA == GL_MAX); + (void) ctx; + + if (chanType == GL_UNSIGNED_BYTE) { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; + const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; + for (i=0;i<n;i++) { + if (mask[i]) { + rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] ); + rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] ); + rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] ); + rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] ); + } + } + } + else if (chanType == GL_UNSIGNED_SHORT) { + GLushort (*rgba)[4] = (GLushort (*)[4]) src; + const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; + for (i=0;i<n;i++) { + if (mask[i]) { + rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] ); + rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] ); + rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] ); + rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] ); + } + } + } + else { + GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; + const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; + ASSERT(chanType == GL_FLOAT); + for (i=0;i<n;i++) { + if (mask[i]) { + rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] ); + rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] ); + rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] ); + rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] ); + } + } + } +} + + + +/** + * Modulate: result = src * dest + * Any chanType ok. + */ +static void _BLENDAPI +blend_modulate(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLvoid *src, const GLvoid *dst, GLenum chanType) +{ + GLuint i; + (void) ctx; + + if (chanType == GL_UNSIGNED_BYTE) { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; + const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; + for (i=0;i<n;i++) { + if (mask[i]) { + GLint divtemp; + rgba[i][RCOMP] = DIV255(rgba[i][RCOMP] * dest[i][RCOMP]); + rgba[i][GCOMP] = DIV255(rgba[i][GCOMP] * dest[i][GCOMP]); + rgba[i][BCOMP] = DIV255(rgba[i][BCOMP] * dest[i][BCOMP]); + rgba[i][ACOMP] = DIV255(rgba[i][ACOMP] * dest[i][ACOMP]); + } + } + } + else if (chanType == GL_UNSIGNED_SHORT) { + GLushort (*rgba)[4] = (GLushort (*)[4]) src; + const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; + for (i=0;i<n;i++) { + if (mask[i]) { + rgba[i][RCOMP] = (rgba[i][RCOMP] * dest[i][RCOMP] + 65535) >> 16; + rgba[i][GCOMP] = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16; + rgba[i][BCOMP] = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16; + rgba[i][ACOMP] = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16; + } + } + } + else { + GLfloat (*rgba)[4] = (GLfloat (*)[4]) src; + const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst; + ASSERT(chanType == GL_FLOAT); + for (i=0;i<n;i++) { + if (mask[i]) { + rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP]; + rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP]; + rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP]; + rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP]; + } + } + } +} + + +/** + * Do any blending operation, using floating point. + * \param n number of pixels + * \param mask fragment writemask array + * \param rgba array of incoming (and modified) pixels + * \param dest array of pixels from the dest color buffer + */ +static void +blend_general_float(struct gl_context *ctx, GLuint n, const GLubyte mask[], + GLfloat rgba[][4], GLfloat dest[][4], + GLenum chanType) +{ + GLuint i; + + for (i = 0; i < n; i++) { + if (mask[i]) { + /* Incoming/source Color */ + const GLfloat Rs = rgba[i][RCOMP]; + const GLfloat Gs = rgba[i][GCOMP]; + const GLfloat Bs = rgba[i][BCOMP]; + const GLfloat As = rgba[i][ACOMP]; + + /* Frame buffer/dest color */ + const GLfloat Rd = dest[i][RCOMP]; + const GLfloat Gd = dest[i][GCOMP]; + const GLfloat Bd = dest[i][BCOMP]; + const GLfloat Ad = dest[i][ACOMP]; + + GLfloat sR, sG, sB, sA; /* Source factor */ + GLfloat dR, dG, dB, dA; /* Dest factor */ + GLfloat r, g, b, a; /* result color */ + + /* XXX for the case of constant blend terms we could init + * the sX and dX variables just once before the loop. + */ + + /* Source RGB factor */ + switch (ctx->Color.Blend[0].SrcRGB) { + case GL_ZERO: + sR = sG = sB = 0.0F; + break; + case GL_ONE: + sR = sG = sB = 1.0F; + break; + case GL_DST_COLOR: + sR = Rd; + sG = Gd; + sB = Bd; + break; + case GL_ONE_MINUS_DST_COLOR: + sR = 1.0F - Rd; + sG = 1.0F - Gd; + sB = 1.0F - Bd; + break; + case GL_SRC_ALPHA: + sR = sG = sB = As; + break; + case GL_ONE_MINUS_SRC_ALPHA: + sR = sG = sB = 1.0F - As; + break; + case GL_DST_ALPHA: + sR = sG = sB = Ad; + break; + case GL_ONE_MINUS_DST_ALPHA: + sR = sG = sB = 1.0F - Ad; + break; + case GL_SRC_ALPHA_SATURATE: + if (As < 1.0F - Ad) { + sR = sG = sB = As; + } + else { + sR = sG = sB = 1.0F - Ad; + } + break; + case GL_CONSTANT_COLOR: + sR = ctx->Color.BlendColor[0]; + sG = ctx->Color.BlendColor[1]; + sB = ctx->Color.BlendColor[2]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + sR = 1.0F - ctx->Color.BlendColor[0]; + sG = 1.0F - ctx->Color.BlendColor[1]; + sB = 1.0F - ctx->Color.BlendColor[2]; + break; + case GL_CONSTANT_ALPHA: + sR = sG = sB = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + sR = sG = sB = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_SRC_COLOR: + sR = Rs; + sG = Gs; + sB = Bs; + break; + case GL_ONE_MINUS_SRC_COLOR: + sR = 1.0F - Rs; + sG = 1.0F - Gs; + sB = 1.0F - Bs; + break; + default: + /* this should never happen */ + _mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float"); + return; + } + + /* Source Alpha factor */ + switch (ctx->Color.Blend[0].SrcA) { + case GL_ZERO: + sA = 0.0F; + break; + case GL_ONE: + sA = 1.0F; + break; + case GL_DST_COLOR: + sA = Ad; + break; + case GL_ONE_MINUS_DST_COLOR: + sA = 1.0F - Ad; + break; + case GL_SRC_ALPHA: + sA = As; + break; + case GL_ONE_MINUS_SRC_ALPHA: + sA = 1.0F - As; + break; + case GL_DST_ALPHA: + sA = Ad; + break; + case GL_ONE_MINUS_DST_ALPHA: + sA = 1.0F - Ad; + break; + case GL_SRC_ALPHA_SATURATE: + sA = 1.0; + break; + case GL_CONSTANT_COLOR: + sA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + sA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_CONSTANT_ALPHA: + sA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + sA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_SRC_COLOR: + sA = As; + break; + case GL_ONE_MINUS_SRC_COLOR: + sA = 1.0F - As; + break; + default: + /* this should never happen */ + sA = 0.0F; + _mesa_problem(ctx, "Bad blend source A factor in blend_general_float"); + return; + } + + /* Dest RGB factor */ + switch (ctx->Color.Blend[0].DstRGB) { + case GL_ZERO: + dR = dG = dB = 0.0F; + break; + case GL_ONE: + dR = dG = dB = 1.0F; + break; + case GL_SRC_COLOR: + dR = Rs; + dG = Gs; + dB = Bs; + break; + case GL_ONE_MINUS_SRC_COLOR: + dR = 1.0F - Rs; + dG = 1.0F - Gs; + dB = 1.0F - Bs; + break; + case GL_SRC_ALPHA: + dR = dG = dB = As; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dR = dG = dB = 1.0F - As; + break; + case GL_DST_ALPHA: + dR = dG = dB = Ad; + break; + case GL_ONE_MINUS_DST_ALPHA: + dR = dG = dB = 1.0F - Ad; + break; + case GL_CONSTANT_COLOR: + dR = ctx->Color.BlendColor[0]; + dG = ctx->Color.BlendColor[1]; + dB = ctx->Color.BlendColor[2]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + dR = 1.0F - ctx->Color.BlendColor[0]; + dG = 1.0F - ctx->Color.BlendColor[1]; + dB = 1.0F - ctx->Color.BlendColor[2]; + break; + case GL_CONSTANT_ALPHA: + dR = dG = dB = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + dR = dG = dB = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_DST_COLOR: + dR = Rd; + dG = Gd; + dB = Bd; + break; + case GL_ONE_MINUS_DST_COLOR: + dR = 1.0F - Rd; + dG = 1.0F - Gd; + dB = 1.0F - Bd; + break; + default: + /* this should never happen */ + dR = dG = dB = 0.0F; + _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float"); + return; + } + + /* Dest Alpha factor */ + switch (ctx->Color.Blend[0].DstA) { + case GL_ZERO: + dA = 0.0F; + break; + case GL_ONE: + dA = 1.0F; + break; + case GL_SRC_COLOR: + dA = As; + break; + case GL_ONE_MINUS_SRC_COLOR: + dA = 1.0F - As; + break; + case GL_SRC_ALPHA: + dA = As; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dA = 1.0F - As; + break; + case GL_DST_ALPHA: + dA = Ad; + break; + case GL_ONE_MINUS_DST_ALPHA: + dA = 1.0F - Ad; + break; + case GL_CONSTANT_COLOR: + dA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + dA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_CONSTANT_ALPHA: + dA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + dA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_DST_COLOR: + dA = Ad; + break; + case GL_ONE_MINUS_DST_COLOR: + dA = 1.0F - Ad; + break; + default: + /* this should never happen */ + dA = 0.0F; + _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float"); + return; + } + + /* compute the blended RGB */ + switch (ctx->Color.Blend[0].EquationRGB) { + case GL_FUNC_ADD: + r = Rs * sR + Rd * dR; + g = Gs * sG + Gd * dG; + b = Bs * sB + Bd * dB; + a = As * sA + Ad * dA; + break; + case GL_FUNC_SUBTRACT: + r = Rs * sR - Rd * dR; + g = Gs * sG - Gd * dG; + b = Bs * sB - Bd * dB; + a = As * sA - Ad * dA; + break; + case GL_FUNC_REVERSE_SUBTRACT: + r = Rd * dR - Rs * sR; + g = Gd * dG - Gs * sG; + b = Bd * dB - Bs * sB; + a = Ad * dA - As * sA; + break; + case GL_MIN: + r = MIN2( Rd, Rs ); + g = MIN2( Gd, Gs ); + b = MIN2( Bd, Bs ); + break; + case GL_MAX: + r = MAX2( Rd, Rs ); + g = MAX2( Gd, Gs ); + b = MAX2( Bd, Bs ); + break; + default: + /* should never get here */ + r = g = b = 0.0F; /* silence uninitialized var warning */ + _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); + return; + } + + /* compute the blended alpha */ + switch (ctx->Color.Blend[0].EquationA) { + case GL_FUNC_ADD: + a = As * sA + Ad * dA; + break; + case GL_FUNC_SUBTRACT: + a = As * sA - Ad * dA; + break; + case GL_FUNC_REVERSE_SUBTRACT: + a = Ad * dA - As * sA; + break; + case GL_MIN: + a = MIN2( Ad, As ); + break; + case GL_MAX: + a = MAX2( Ad, As ); + break; + default: + /* should never get here */ + a = 0.0F; /* silence uninitialized var warning */ + _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); + return; + } + + /* final clamping */ +#if 0 + rgba[i][RCOMP] = MAX2( r, 0.0F ); + rgba[i][GCOMP] = MAX2( g, 0.0F ); + rgba[i][BCOMP] = MAX2( b, 0.0F ); + rgba[i][ACOMP] = CLAMP( a, 0.0F, 1.0F ); +#else + ASSIGN_4V(rgba[i], r, g, b, a); +#endif + } + } +} + + +/** + * Do any blending operation, any chanType. + */ +static void +blend_general(struct gl_context *ctx, GLuint n, const GLubyte mask[], + void *src, const void *dst, GLenum chanType) +{ + GLfloat (*rgbaF)[4], (*destF)[4]; + + rgbaF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); + destF = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat)); + if (!rgbaF || !destF) { + free(rgbaF); + free(destF); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "blending"); + return; + } + + if (chanType == GL_UNSIGNED_BYTE) { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; + const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; + GLuint i; + /* convert ubytes to floats */ + for (i = 0; i < n; i++) { + if (mask[i]) { + rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]); + rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]); + rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]); + rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]); + destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]); + destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]); + destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]); + destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]); + } + } + /* do blend */ + blend_general_float(ctx, n, mask, rgbaF, destF, chanType); + /* convert back to ubytes */ + for (i = 0; i < n; i++) { + if (mask[i]) + _mesa_unclamped_float_rgba_to_ubyte(rgba[i], rgbaF[i]); + } + } + else if (chanType == GL_UNSIGNED_SHORT) { + GLushort (*rgba)[4] = (GLushort (*)[4]) src; + const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; + GLuint i; + /* convert ushorts to floats */ + for (i = 0; i < n; i++) { + if (mask[i]) { + rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]); + rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]); + rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]); + rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]); + destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]); + destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]); + destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]); + destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]); + } + } + /* do blend */ + blend_general_float(ctx, n, mask, rgbaF, destF, chanType); + /* convert back to ushorts */ + for (i = 0; i < n; i++) { + if (mask[i]) { + UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]); + } + } + } + else { + blend_general_float(ctx, n, mask, (GLfloat (*)[4]) src, + (GLfloat (*)[4]) dst, chanType); + } + + free(rgbaF); + free(destF); +} + + + +/** + * Analyze current blending parameters to pick fastest blending function. + * Result: the ctx->Color.BlendFunc pointer is updated. + */ +void +_swrast_choose_blend_func(struct gl_context *ctx, GLenum chanType) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLenum eq = ctx->Color.Blend[0].EquationRGB; + const GLenum srcRGB = ctx->Color.Blend[0].SrcRGB; + const GLenum dstRGB = ctx->Color.Blend[0].DstRGB; + const GLenum srcA = ctx->Color.Blend[0].SrcA; + const GLenum dstA = ctx->Color.Blend[0].DstA; + + if (ctx->Color.Blend[0].EquationRGB != ctx->Color.Blend[0].EquationA) { + swrast->BlendFunc = blend_general; + } + else if (eq == GL_MIN) { + /* Note: GL_MIN ignores the blending weight factors */ +#if defined(USE_MMX_ASM) + if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { + swrast->BlendFunc = _mesa_mmx_blend_min; + } + else +#endif + swrast->BlendFunc = blend_min; + } + else if (eq == GL_MAX) { + /* Note: GL_MAX ignores the blending weight factors */ +#if defined(USE_MMX_ASM) + if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { + swrast->BlendFunc = _mesa_mmx_blend_max; + } + else +#endif + swrast->BlendFunc = blend_max; + } + else if (srcRGB != srcA || dstRGB != dstA) { + swrast->BlendFunc = blend_general; + } + else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA + && dstRGB == GL_ONE_MINUS_SRC_ALPHA) { +#if defined(USE_MMX_ASM) + if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { + swrast->BlendFunc = _mesa_mmx_blend_transparency; + } + else +#endif + { + if (chanType == GL_UNSIGNED_BYTE) + swrast->BlendFunc = blend_transparency_ubyte; + else if (chanType == GL_UNSIGNED_SHORT) + swrast->BlendFunc = blend_transparency_ushort; + else + swrast->BlendFunc = blend_transparency_float; + } + } + else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) { +#if defined(USE_MMX_ASM) + if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { + swrast->BlendFunc = _mesa_mmx_blend_add; + } + else +#endif + swrast->BlendFunc = blend_add; + } + else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT) + && (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR)) + || + ((eq == GL_FUNC_ADD || eq == GL_FUNC_SUBTRACT) + && (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) { +#if defined(USE_MMX_ASM) + if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { + swrast->BlendFunc = _mesa_mmx_blend_modulate; + } + else +#endif + swrast->BlendFunc = blend_modulate; + } + else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) { + swrast->BlendFunc = blend_noop; + } + else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) { + swrast->BlendFunc = blend_replace; + } + else { + swrast->BlendFunc = blend_general; + } +} + + + +/** + * Apply the blending operator to a span of pixels. + * We can handle horizontal runs of pixels (spans) or arrays of x/y + * pixel coordinates. + */ +void +_swrast_blend_span(struct gl_context *ctx, struct gl_renderbuffer *rb, SWspan *span) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + void *rbPixels; + + ASSERT(span->end <= MAX_WIDTH); + ASSERT(span->arrayMask & SPAN_RGBA); + ASSERT(rb->DataType == span->array->ChanType); + ASSERT(!ctx->Color._LogicOpEnabled); + + rbPixels = _swrast_get_dest_rgba(ctx, rb, span); + + swrast->BlendFunc(ctx, span->end, span->array->mask, + span->array->rgba, rbPixels, span->array->ChanType); +} diff --git a/mesalib/src/mesa/swrast/s_clear.c b/mesalib/src/mesa/swrast/s_clear.c index 9e9b53116..980d29bba 100644 --- a/mesalib/src/mesa/swrast/s_clear.c +++ b/mesalib/src/mesa/swrast/s_clear.c @@ -60,20 +60,17 @@ clear_rgba_buffer_with_masking(struct gl_context *ctx, struct gl_renderbuffer *r span.array->ChanType = rb->DataType; if (span.array->ChanType == GL_UNSIGNED_BYTE) { GLubyte clearColor[4]; - UNCLAMPED_FLOAT_TO_UBYTE(clearColor[RCOMP], ctx->Color.ClearColor[0]); - UNCLAMPED_FLOAT_TO_UBYTE(clearColor[GCOMP], ctx->Color.ClearColor[1]); - UNCLAMPED_FLOAT_TO_UBYTE(clearColor[BCOMP], ctx->Color.ClearColor[2]); - UNCLAMPED_FLOAT_TO_UBYTE(clearColor[ACOMP], ctx->Color.ClearColor[3]); + _mesa_unclamped_float_rgba_to_ubyte(clearColor, ctx->Color.ClearColor.f); for (i = 0; i < width; i++) { COPY_4UBV(span.array->rgba[i], clearColor); } } else if (span.array->ChanType == GL_UNSIGNED_SHORT) { GLushort clearColor[4]; - UNCLAMPED_FLOAT_TO_USHORT(clearColor[RCOMP], ctx->Color.ClearColor[0]); - UNCLAMPED_FLOAT_TO_USHORT(clearColor[GCOMP], ctx->Color.ClearColor[1]); - UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor[2]); - UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor[3]); + UNCLAMPED_FLOAT_TO_USHORT(clearColor[RCOMP], ctx->Color.ClearColor.f[0]); + UNCLAMPED_FLOAT_TO_USHORT(clearColor[GCOMP], ctx->Color.ClearColor.f[1]); + UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor.f[2]); + UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor.f[3]); for (i = 0; i < width; i++) { COPY_4V_CAST(span.array->rgba[i], clearColor, GLchan); } @@ -81,10 +78,10 @@ clear_rgba_buffer_with_masking(struct gl_context *ctx, struct gl_renderbuffer *r else { ASSERT(span.array->ChanType == GL_FLOAT); for (i = 0; i < width; i++) { - CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColor[0]); - CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColor[1]); - CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColor[2]); - CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColor[3]); + UNCLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColor.f[0]); + UNCLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColor.f[1]); + UNCLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColor.f[2]); + UNCLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColor.f[3]); } } @@ -115,6 +112,7 @@ clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint buf GLubyte clear8[4]; GLushort clear16[4]; GLvoid *clearVal; + GLfloat clearFloat[4]; GLint i; ASSERT(ctx->Color.ColorMask[buf][0] && @@ -126,21 +124,22 @@ clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint buf switch (rb->DataType) { case GL_UNSIGNED_BYTE: - UNCLAMPED_FLOAT_TO_UBYTE(clear8[0], ctx->Color.ClearColor[0]); - UNCLAMPED_FLOAT_TO_UBYTE(clear8[1], ctx->Color.ClearColor[1]); - UNCLAMPED_FLOAT_TO_UBYTE(clear8[2], ctx->Color.ClearColor[2]); - UNCLAMPED_FLOAT_TO_UBYTE(clear8[3], ctx->Color.ClearColor[3]); + _mesa_unclamped_float_rgba_to_ubyte(clear8, ctx->Color.ClearColor.f); clearVal = clear8; break; case GL_UNSIGNED_SHORT: - UNCLAMPED_FLOAT_TO_USHORT(clear16[0], ctx->Color.ClearColor[0]); - UNCLAMPED_FLOAT_TO_USHORT(clear16[1], ctx->Color.ClearColor[1]); - UNCLAMPED_FLOAT_TO_USHORT(clear16[2], ctx->Color.ClearColor[2]); - UNCLAMPED_FLOAT_TO_USHORT(clear16[3], ctx->Color.ClearColor[3]); + UNCLAMPED_FLOAT_TO_USHORT(clear16[0], ctx->Color.ClearColor.f[0]); + UNCLAMPED_FLOAT_TO_USHORT(clear16[1], ctx->Color.ClearColor.f[1]); + UNCLAMPED_FLOAT_TO_USHORT(clear16[2], ctx->Color.ClearColor.f[2]); + UNCLAMPED_FLOAT_TO_USHORT(clear16[3], ctx->Color.ClearColor.f[3]); clearVal = clear16; break; case GL_FLOAT: - clearVal = ctx->Color.ClearColor; + clearFloat[0] = CLAMP(ctx->Color.ClearColor.f[0], 0.0F, 1.0F); + clearFloat[1] = CLAMP(ctx->Color.ClearColor.f[1], 0.0F, 1.0F); + clearFloat[2] = CLAMP(ctx->Color.ClearColor.f[2], 0.0F, 1.0F); + clearFloat[3] = CLAMP(ctx->Color.ClearColor.f[3], 0.0F, 1.0F); + clearVal = clearFloat; break; default: _mesa_problem(ctx, "Bad rb DataType in clear_color_buffer"); diff --git a/pixman/Makefile.win32 b/pixman/Makefile.win32 new file mode 100644 index 000000000..91cd12a52 --- /dev/null +++ b/pixman/Makefile.win32 @@ -0,0 +1,25 @@ +default: all + +top_srcdir = . +include $(top_srcdir)/Makefile.win32.common + +# Recursive targets +pixman_r: + @$(MAKE) -C pixman -f Makefile.win32 + +test_r: + @$(MAKE) -C test -f Makefile.win32 + +clean_r: + @$(MAKE) -C pixman -f Makefile.win32 clean + @$(MAKE) -C test -f Makefile.win32 clean + +check_r: + @$(MAKE) -C test -f Makefile.win32 check + +# Base targets +all: test_r + +clean: clean_r + +check: check_r diff --git a/pixman/Makefile.win32.common b/pixman/Makefile.win32.common new file mode 100644 index 000000000..56c3593d2 --- /dev/null +++ b/pixman/Makefile.win32.common @@ -0,0 +1,54 @@ +LIBRARY = pixman-1 + +CC = cl +LD = link +AR = lib +PERL = perl + +ifeq ($(top_builddir),) +top_builddir = $(top_srcdir) +endif + +CFG_VAR = $(CFG) +ifeq ($(CFG_VAR),) +CFG_VAR = release +endif + +ifeq ($(CFG_VAR),debug) +CFG_CFLAGS = -MDd -Od -Zi +CFG_LDFLAGS = -DEBUG +else +CFG_CFLAGS = -MD -O2 +CFG_LDFLAGS = +endif + +# Package definitions, to be used instead of those provided in config.h +PKG_CFLAGS = -DPACKAGE=$(LIBRARY) -DPACKAGE_VERSION="" -DPACKAGE_BUGREPORT="" + +BASE_CFLAGS = -nologo -I. -I$(top_srcdir) -I$(top_srcdir)/pixman + +PIXMAN_CFLAGS = $(BASE_CFLAGS) $(PKG_CFLAGS) $(CFG_CFLAGS) $(CFLAGS) +PIXMAN_LDFLAGS = -nologo $(CFG_LDFLAGS) $(LDFLAGS) +PIXMAN_ARFLAGS = -nologo $(LDFLAGS) + + +inform: +ifneq ($(CFG),release) +ifneq ($(CFG),debug) +ifneq ($(CFG),) + @echo "Invalid specified configuration option: "$(CFG)"." + @echo + @echo "Possible choices for configuration are 'release' and 'debug'" + @exit 1 +endif + @echo "Using default RELEASE configuration... (use CFG=release or CFG=debug)" +endif +endif + + +$(CFG_VAR)/%.obj: %.c $(BUILT_SOURCES) + @mkdir -p $(CFG_VAR) + @$(CC) -c $(PIXMAN_CFLAGS) -Fo"$@" $< + +clean: inform + @$(RM) $(CFG_VAR)/*.{exe,ilk,lib,obj,pdb} $(BUILT_SOURCES) || exit 0 diff --git a/pixman/pixman/Makefile.am b/pixman/pixman/Makefile.am index 44e6b17e4..2421a4f9e 100644 --- a/pixman/pixman/Makefile.am +++ b/pixman/pixman/Makefile.am @@ -1,60 +1,25 @@ +include $(top_srcdir)/pixman/Makefile.sources + lib_LTLIBRARIES = libpixman-1.la + libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined @PTHREAD_LDFLAGS@ libpixman_1_la_LIBADD = @PTHREAD_LIBS@ @DEP_LIBS@ -lm -libpixman_1_la_SOURCES = \ - pixman.h \ - pixman-accessor.h \ - pixman-access.c \ - pixman-access-accessors.c \ - pixman-cpu.c \ - pixman-gradient-walker.c \ - pixman-region16.c \ - pixman-region32.c \ - pixman-compiler.h \ - pixman-private.h \ - pixman-image.c \ - pixman-implementation.c \ - pixman-combine32.c \ - pixman-combine32.h \ - pixman-combine64.c \ - pixman-combine64.h \ - pixman-general.c \ - pixman.c \ - pixman-noop.c \ - pixman-fast-path.c \ - pixman-solid-fill.c \ - pixman-conical-gradient.c \ - pixman-linear-gradient.c \ - pixman-radial-gradient.c \ - pixman-bits-image.c \ - pixman-utils.c \ - pixman-edge.c \ - pixman-edge-accessors.c \ - pixman-edge-imp.h \ - pixman-inlines.h \ - pixman-trap.c \ - pixman-timer.c \ - pixman-matrix.c +libpixman_1_la_SOURCES = $(libpixman_sources) $(libpixman_headers) libpixmanincludedir = $(includedir)/pixman-1 libpixmaninclude_HEADERS = pixman.h pixman-version.h noinst_LTLIBRARIES = -BUILT_SOURCES = pixman-combine32.h pixman-combine32.c pixman-combine64.h pixman-combine64.c - -pixman-combine32.c : pixman-combine.c.template pixman-combine32.h make-combine.pl - $(PERL) $(srcdir)/make-combine.pl 8 < $(srcdir)/pixman-combine.c.template > $@ || ($(RM) $@; exit 1) -pixman-combine32.h : pixman-combine.h.template make-combine.pl - $(PERL) $(srcdir)/make-combine.pl 8 < $(srcdir)/pixman-combine.h.template > $@ || ($(RM) $@; exit 1) - -pixman-combine64.c : pixman-combine.c.template pixman-combine64.h make-combine.pl - $(PERL) $(srcdir)/make-combine.pl 16 < $(srcdir)/pixman-combine.c.template > $@ || ($(RM) $@; exit 1) -pixman-combine64.h : pixman-combine.h.template make-combine.pl - $(PERL) $(srcdir)/make-combine.pl 16 < $(srcdir)/pixman-combine.h.template > $@ || ($(RM) $@; exit 1) +EXTRA_DIST = \ + Makefile.win32 \ + make-combine.pl \ + pixman-combine.c.template \ + pixman-combine.h.template \ + pixman-region.c \ + solaris-hwcap.mapfile \ + $(NULL) -EXTRA_DIST = Makefile.win32 pixman-combine.c.template make-combine.pl pixman-region.c \ - pixman-combine.h.template solaris-hwcap.mapfile -CLEANFILES = pixman-combine32.c pixman-combine64.c pixman-combine32.h pixman-combine64.h +DISTCLEANFILES = $(BUILT_SOURCES) # mmx code if USE_MMX diff --git a/pixman/pixman/Makefile.sources b/pixman/pixman/Makefile.sources new file mode 100644 index 000000000..ca3f001db --- /dev/null +++ b/pixman/pixman/Makefile.sources @@ -0,0 +1,55 @@ +libpixman_sources = \ + pixman.c \ + pixman-access.c \ + pixman-access-accessors.c \ + pixman-bits-image.c \ + pixman-combine32.c \ + pixman-combine64.c \ + pixman-conical-gradient.c \ + pixman-cpu.c \ + pixman-edge.c \ + pixman-edge-accessors.c \ + pixman-fast-path.c \ + pixman-general.c \ + pixman-gradient-walker.c \ + pixman-image.c \ + pixman-implementation.c \ + pixman-linear-gradient.c \ + pixman-matrix.c \ + pixman-noop.c \ + pixman-radial-gradient.c \ + pixman-region16.c \ + pixman-region32.c \ + pixman-solid-fill.c \ + pixman-timer.c \ + pixman-trap.c \ + pixman-utils.c \ + $(NULL) + +libpixman_headers = \ + pixman.h \ + pixman-accessor.h \ + pixman-combine32.h \ + pixman-combine64.h \ + pixman-compiler.h \ + pixman-edge-imp.h \ + pixman-inlines.h \ + pixman-private.h \ + $(NULL) + +BUILT_SOURCES = \ + pixman-combine32.c \ + pixman-combine32.h \ + pixman-combine64.c \ + pixman-combine64.h \ + $(NULL) + +pixman-combine32.c: pixman-combine.c.template make-combine.pl + $(PERL) $(lastword $+) 8 < $< > $@ || ($(RM) $@; exit 1) +pixman-combine32.h: pixman-combine.h.template make-combine.pl + $(PERL) $(lastword $+) 8 < $< > $@ || ($(RM) $@; exit 1) + +pixman-combine64.c: pixman-combine.c.template make-combine.pl + $(PERL) $(lastword $+) 16 < $< > $@ || ($(RM) $@; exit 1) +pixman-combine64.h: pixman-combine.h.template make-combine.pl + $(PERL) $(lastword $+) 16 < $< > $@ || ($(RM) $@; exit 1) diff --git a/pixman/pixman/Makefile.win32 b/pixman/pixman/Makefile.win32 index 7c92722c3..beff4a068 100644 --- a/pixman/pixman/Makefile.win32 +++ b/pixman/pixman/Makefile.win32 @@ -1,12 +1,8 @@ -LIBRARY = pixman-1 +default: all -CC = cl -LINK = link - -CFG_VAR = $(CFG) -ifeq ($(CFG_VAR),) -CFG_VAR=release -endif +top_srcdir = .. +include $(top_srcdir)/pixman/Makefile.sources +include $(top_srcdir)/Makefile.win32.common MMX_VAR = $(MMX) ifeq ($(MMX_VAR),) @@ -18,83 +14,25 @@ ifeq ($(SSE2_VAR),) SSE2_VAR=on endif -CFLAGS = -MD -nologo -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -I../pixman/src -I. -DPACKAGE=$(LIBRARY) -DPACKAGE_VERSION="" -DPACKAGE_BUGREPORT="" MMX_CFLAGS = -DUSE_MMX -w14710 -w14714 SSE2_CFLAGS = -DUSE_SSE2 -# optimization flags -ifeq ($(CFG_VAR),debug) -CFLAGS += -Od -Zi -else -CFLAGS += -O2 -endif - -SOURCES = \ - pixman-image.c \ - pixman-access.c \ - pixman-access-accessors.c \ - pixman-region16.c \ - pixman-region32.c \ - pixman-combine32.c \ - pixman-combine64.c \ - pixman-utils.c \ - pixman-edge.c \ - pixman-edge-accessors.c \ - pixman-trap.c \ - pixman-timer.c \ - pixman-matrix.c \ - pixman-gradient-walker.c \ - pixman-conical-gradient.c \ - pixman-linear-gradient.c \ - pixman-radial-gradient.c \ - pixman-bits-image.c \ - pixman.c \ - pixman-noop.c \ - pixman-cpu.c \ - pixman-fast-path.c \ - pixman-implementation.c \ - pixman-solid-fill.c \ - pixman-general.c \ - $(NULL) - -BUILT_SOURCES = pixman-combine32.h pixman-combine32.c pixman-combine64.h pixman-combine64.c - # MMX compilation flags ifeq ($(MMX_VAR),on) -CFLAGS += $(MMX_CFLAGS) -SOURCES += pixman-mmx.c +PIXMAN_CFLAGS += $(MMX_CFLAGS) +libpixman_sources += pixman-mmx.c endif # SSE2 compilation flags ifeq ($(SSE2_VAR),on) -CFLAGS += $(SSE2_CFLAGS) -SOURCES += pixman-sse2.c +PIXMAN_CFLAGS += $(SSE2_CFLAGS) +libpixman_sources += pixman-sse2.c endif -OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(SOURCES)) +OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(libpixman_sources)) # targets all: inform informMMX informSSE2 $(CFG_VAR)/$(LIBRARY).lib - @exit 0 -clean: inform clean_r - @exit 0 -pixman: inform informMMX informSSE2 $(CFG_VAR)/$(LIBRARY).lib - @exit 0 - -inform: -ifneq ($(CFG),release) -ifneq ($(CFG),debug) -ifneq ($(CFG),) - @echo "Invalid specified configuration option : "$(CFG)"." - @echo - @echo -n "Possible choices for configuration are " - @echo "'release' and 'debug'" - @echo "" - @exit 1 -endif - @echo "Using default RELEASE configuration... (use CFG=release or CFG=debug)" -endif -endif informMMX: ifneq ($(MMX),off) @@ -102,8 +40,7 @@ ifneq ($(MMX),on) ifneq ($(MMX),) @echo "Invalid specified MMX option : "$(MMX_VAR)"." @echo - @echo -n "Possible choices for MMX are 'on' or 'off'" - @echo "" + @echo "Possible choices for MMX are 'on' or 'off'" @exit 1 endif @echo "Setting MMX flag to default value 'on'... (use MMX=on or MMX=off)" @@ -116,32 +53,14 @@ ifneq ($(SSE2),on) ifneq ($(SSE2),) @echo "Invalid specified SSE option : "$(SSE2)"." @echo - @echo -n "Possible choices for SSE2 are 'on' or 'off'" - @echo "" + @echo "Possible choices for SSE2 are 'on' or 'off'" @exit 1 endif @echo "Setting SSE2 flag to default value 'on'... (use SSE2=on or SSE2=off)" endif endif -# pixman compilation and linking -$(CFG_VAR)/%.obj: %.c $(BUILT_SOURCES) - @mkdir -p $(CFG_VAR) - @$(CC) -c $(CFLAGS) -Fo"$@" $< +# pixman linking $(CFG_VAR)/$(LIBRARY).lib: $(OBJECTS) - lib -NOLOGO -OUT:$@ $(OBJECTS) || exit 0 - -pixman-combine32.c: pixman-combine.c.template pixman-combine32.h make-combine.pl - perl ./make-combine.pl 8 < $< > $@ || ($(RM) $@; exit 1) -pixman-combine32.h: pixman-combine.h.template make-combine.pl - perl ./make-combine.pl 8 < $< > $@ || ($(RM) $@; exit 1) - -pixman-combine64.c: pixman-combine.c.template pixman-combine64.h make-combine.pl - perl ./make-combine.pl 16 < $< > $@ || ($(RM) $@; exit 1) -pixman-combine64.h: pixman-combine.h.template make-combine.pl - perl ./make-combine.pl 16 < $< > $@ || ($(RM) $@; exit 1) - -clean_r: - @rm -f $(CFG_VAR)/*.obj $(CFG_VAR)/*.lib $(CFG_VAR)/*.pdb $(CFG)/*.ilk || exit 0 - @rm -f $(CFG)/*.obj $(CFG)/*.lib $(CFG)/*.pdb $(CFG)/*.ilk $(BUILT_SOURCES) || exit 0 + @$(AR) $(PIXMAN_ARFLAGS) -OUT:$@ $^ diff --git a/pixman/test/Makefile.am b/pixman/test/Makefile.am index 6687bed35..4268cd7c5 100644 --- a/pixman/test/Makefile.am +++ b/pixman/test/Makefile.am @@ -1,50 +1,13 @@ +include $(top_srcdir)/test/Makefile.sources + AM_CFLAGS = @OPENMP_CFLAGS@ AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@ -LDADD = $(top_builddir)/pixman/libpixman-1.la -lm @PNG_LIBS@ +LDADD = $(top_builddir)/pixman/libpixman-1.la libutils.la -lm @PNG_LIBS@ INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman @PNG_CFLAGS@ -TESTPROGRAMS = \ - a1-trap-test \ - pdf-op-test \ - region-test \ - region-translate-test \ - fetch-test \ - oob-test \ - trap-crasher \ - alpha-loop \ - scaling-crash-test \ - scaling-helpers-test \ - gradient-crash-test \ - region-contains-test \ - alphamap \ - stress-test \ - composite-traps-test \ - blitters-test \ - scaling-test \ - affine-test \ - composite - -pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h -region_test_SOURCES = region-test.c utils.c utils.h -blitters_test_SOURCES = blitters-test.c utils.c utils.h -region_contains_test_SOURCES = region-contains-test.c utils.c utils.h -composite_traps_test_SOURCES = composite-traps-test.c utils.c utils.h -scaling_test_SOURCES = scaling-test.c utils.c utils.h -affine_test_SOURCES = affine-test.c utils.c utils.h -alphamap_SOURCES = alphamap.c utils.c utils.h -alpha_loop_SOURCES = alpha-loop.c utils.c utils.h -composite_SOURCES = composite.c utils.c utils.h -gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h -stress_test_SOURCES = stress-test.c utils.c utils.h -scaling_helpers_test_SOURCES = scaling-helpers-test.c utils.c utils.h - -# Benchmarks - -BENCHMARKS = \ - lowlevel-blt-bench - -lowlevel_blt_bench_SOURCES = lowlevel-blt-bench.c utils.c utils.h +libutils_la_SOURCES = $(libutils_sources) $(libutils_headers) +noinst_LTLIBRARIES = libutils.la noinst_PROGRAMS = $(TESTPROGRAMS) $(BENCHMARKS) TESTS = $(TESTPROGRAMS) diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources new file mode 100644 index 000000000..99eb705af --- /dev/null +++ b/pixman/test/Makefile.sources @@ -0,0 +1,36 @@ +# Tests (sorted by expected completion time) +TESTPROGRAMS = \ + a1-trap-test \ + pdf-op-test \ + region-test \ + region-translate-test \ + fetch-test \ + oob-test \ + trap-crasher \ + alpha-loop \ + scaling-crash-test \ + scaling-helpers-test \ + gradient-crash-test \ + region-contains-test \ + alphamap \ + stress-test \ + composite-traps-test \ + blitters-test \ + scaling-test \ + affine-test \ + composite \ + $(NULL) + +# Benchmarks +BENCHMARKS = \ + lowlevel-blt-bench \ + $(NULL) + +# Utility functions +libutils_sources = \ + utils.c \ + $(NULL) + +libutils_headers = \ + utils.h \ + $(NULL) diff --git a/pixman/test/Makefile.win32 b/pixman/test/Makefile.win32 index a62b6fc35..307ba0c23 100644 --- a/pixman/test/Makefile.win32 +++ b/pixman/test/Makefile.win32 @@ -1,76 +1,31 @@ -CC = cl -LINK = link +default: all -CFG_VAR = $(CFG) -ifeq ($(CFG_VAR),) -CFG_VAR=release -endif +top_srcdir = .. +include $(top_srcdir)/test/Makefile.sources +include $(top_srcdir)/Makefile.win32.common -CFLAGS = -MD -nologo -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_BIND_TO_CURRENT_VCLIBS_VERSION -D_MT -I../pixman -I. -I../ -TEST_LDADD = ../pixman/$(CFG_VAR)/pixman-1.lib -INCLUDES = -I../pixman -I$(top_builddir)/pixman +TEST_LDADD = \ + $(top_builddir)/pixman/$(CFG_VAR)/$(LIBRARY).lib \ + $(CFG_VAR)/libutils.lib \ + $(NULL) -# optimization flags -ifeq ($(CFG_VAR),debug) -CFLAGS += -Od -Zi -else -CFLAGS += -O2 -endif +libutils_OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(libutils_sources)) -SOURCES = \ - a1-trap-test.c \ - pdf-op-test.c \ - region-test.c \ - region-translate-test.c \ - fetch-test.c \ - oob-test.c \ - trap-crasher.c \ - alpha-loop.c \ - scaling-crash-test.c \ - gradient-crash-test.c \ - alphamap.c \ - stress-test.c \ - composite-traps-test.c \ - blitters-test.c \ - scaling-test.c \ - affine-test.c \ - composite.c \ - lowlevel-blt-bench.c \ - utils.c +SOURCES = $(patsubst %, %.c, $(TESTPROGRAMS) $(BENCHMARKS)) +OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(SOURCES)) +TESTS = $(patsubst %, $(CFG_VAR)/%.exe, $(TESTPROGRAMS)) +BENCHS = $(patsubst %, $(CFG_VAR)/%.exe, $(BENCHMARKS)) -TESTS = \ - $(CFG_VAR)/a1-trap-test.exe \ - $(CFG_VAR)/pdf-op-test.exe \ - $(CFG_VAR)/region-test.exe \ - $(CFG_VAR)/region-translate-test.exe \ - $(CFG_VAR)/fetch-test.exe \ - $(CFG_VAR)/oob-test.exe \ - $(CFG_VAR)/trap-crasher.exe \ - $(CFG_VAR)/alpha-loop.exe \ - $(CFG_VAR)/scaling-crash-test.exe \ - $(CFG_VAR)/gradient-crash-test.exe \ - $(CFG_VAR)/alphamap.exe \ - $(CFG_VAR)/stress-test.exe \ - $(CFG_VAR)/composite-traps-test.exe \ - $(CFG_VAR)/blitters-test.exe \ - $(CFG_VAR)/scaling-test.exe \ - $(CFG_VAR)/affine-test.exe \ - $(CFG_VAR)/composite.exe +all: inform $(TESTS) $(BENCHS) -BENCHMARKS = \ - $(CFG_VAR)/lowlevel-blt-bench.exe +check: inform $(TESTS) + @for test in $(TESTS) ; do ./$$test && echo "PASS: $$test" || echo "FAIL: $$test" ; done -OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(SOURCES)) +$(CFG_VAR)/libutils.lib: $(libutils_OBJECTS) + @$(AR) $(PIXMAN_ARFLAGS) -OUT:$@ $^ -$(CFG_VAR)/%.obj: %.c - @mkdir -p $(CFG_VAR) - @$(CC) -c $(CFLAGS) -Fo"$@" $< +$(CFG_VAR)/%.exe: $(CFG_VAR)/%.obj $(TEST_LDADD) + @$(LD) $(PIXMAN_LDFLAGS) -OUT:$@ $^ -$(CFG_VAR)/%.exe: $(CFG_VAR)/%.obj - $(LINK) /NOLOGO /OUT:$@ $< $(CFG_VAR)/utils.obj $(TEST_LDADD) - -all: $(OBJECTS) $(TESTS) $(BENCHMARKS) - @exit 0 - -clean: - @rm -f $(CFG_VAR)/*.obj $(CFG_VAR)/*.pdb || exit 0 +$(top_builddir)/pixman/$(CFG_VAR)/$(LIBRARY).lib: + @$(MAKE) -C $(top_builddir)/pixman -f Makefile.win32 diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c index 594ec548b..790a27f03 100644 --- a/pixman/test/blitters-test.c +++ b/pixman/test/blitters-test.c @@ -8,7 +8,6 @@ #include <assert.h> #include <stdlib.h> #include <stdio.h> -#include <config.h> #include "utils.h" static pixman_indexed_t rgb_palette[9]; diff --git a/pixman/test/composite.c b/pixman/test/composite.c index edea9a96b..408c363a3 100644 --- a/pixman/test/composite.c +++ b/pixman/test/composite.c @@ -27,7 +27,6 @@ #include <stdio.h> #include <stdlib.h> /* abort() */ #include <math.h> -#include <config.h> #include <time.h> #include "utils.h" diff --git a/pixman/test/fetch-test.c b/pixman/test/fetch-test.c index feb98d9b7..9f80eec1b 100644 --- a/pixman/test/fetch-test.c +++ b/pixman/test/fetch-test.c @@ -1,8 +1,11 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <assert.h> #include <stdlib.h> #include <stdio.h> #include "pixman.h" -#include <config.h> #define SIZE 1024 diff --git a/pixman/test/pdf-op-test.c b/pixman/test/pdf-op-test.c index dc7a4fd0b..99cb7dfea 100644 --- a/pixman/test/pdf-op-test.c +++ b/pixman/test/pdf-op-test.c @@ -1,4 +1,3 @@ -#include <config.h> #include <stdlib.h> #include "utils.h" diff --git a/pixman/test/scaling-helpers-test.c b/pixman/test/scaling-helpers-test.c index a38cac544..a8b94b0c7 100644 --- a/pixman/test/scaling-helpers-test.c +++ b/pixman/test/scaling-helpers-test.c @@ -1,4 +1,3 @@ -#include <config.h> #include <stdint.h> #include <stdlib.h> #include <stdio.h> @@ -20,12 +19,12 @@ bilinear_pad_repeat_get_scanline_bounds_ref (int32_t source_image_width, int32_t * right_pad) { int w = *width; + int64_t vx = vx_; *left_pad = 0; *left_tz = 0; *width = 0; *right_tz = 0; *right_pad = 0; - int64_t vx = vx_; while (--w >= 0) { if (vx < 0) diff --git a/pixman/test/utils.h b/pixman/test/utils.h index 3790483db..b23925c4a 100644 --- a/pixman/test/utils.h +++ b/pixman/test/utils.h @@ -1,5 +1,8 @@ -#include <stdlib.h> +#ifdef HAVE_CONFIG_H #include <config.h> +#endif + +#include <stdlib.h> #include <assert.h> #include "pixman-private.h" /* For 'inline' definition */ |