Dawn of a new world
This commit is contained in:
commit
5971d63df6
|
@ -0,0 +1,38 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
.msg
|
||||
*.lo
|
||||
*.la
|
||||
*.a
|
||||
*.o
|
||||
*~
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
m4/lt*m4
|
||||
m4/libtool.m4
|
||||
compile
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
xorg-server.pc
|
||||
stamp-h?
|
||||
do-not-use-config.h
|
||||
do-not-use-config.h.in
|
||||
kdrive/fbdev/Xfbdev
|
||||
kdrive/vesa/Xvesa
|
||||
include/dix-config.h
|
||||
include/kdrive-config.h
|
||||
include/xkb-config.h
|
||||
ylwrap
|
||||
err
|
||||
*rig
|
||||
*rej
|
|
@ -0,0 +1,675 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
ACLOCAL_AMFLAGS=-I m4
|
||||
|
||||
if DBE
|
||||
DBE_DIR=dbe
|
||||
endif
|
||||
|
||||
SUBDIRS = \
|
||||
include \
|
||||
dix \
|
||||
fb \
|
||||
mi \
|
||||
Xext \
|
||||
miext \
|
||||
os \
|
||||
randr \
|
||||
render \
|
||||
$(DBE_DIR) \
|
||||
xfixes \
|
||||
damageext \
|
||||
kdrive
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
include \
|
||||
dix \
|
||||
fb \
|
||||
mi \
|
||||
Xext \
|
||||
miext \
|
||||
os \
|
||||
randr \
|
||||
render \
|
||||
dbe \
|
||||
xfixes \
|
||||
damageext \
|
||||
kdrive
|
|
@ -0,0 +1,43 @@
|
|||
Necromancy
|
||||
==========
|
||||
|
||||
We resurrected Xvesa from the depths of git history, and intend to maintain it with Xfbdev.
|
||||
|
||||
This includes bugfixes, security fixes, and occasional new features if required.
|
||||
|
||||
|
||||
Why?
|
||||
----
|
||||
|
||||
The TinyX servers fill our needs while being a lot smaller than Xorg can be made.
|
||||
|
||||
|
||||
Why 1.2.0 and not 1.3.0?
|
||||
------------------------
|
||||
|
||||
As you know, Xvesa was killed in 1.4.0, so the latest released version would be 1.3.0.
|
||||
However, they broke all input in 1.3.0 (keyboard and mouse), so the last working released
|
||||
version is 1.2.0.
|
||||
|
||||
There were also some changes later on that we disagree with (mandatory xinput & xkb).
|
||||
|
||||
|
||||
Design choices
|
||||
--------------
|
||||
|
||||
We aim for the smallest fully featured X server binary. Currently there are the vesa and
|
||||
fbdev servers, but others may appear in the future (Xmodesetting?).
|
||||
|
||||
- no xkb; it's bloat when console keymaps suffice
|
||||
- no xinput
|
||||
- no xinerama
|
||||
- no gl
|
||||
- TCP listening disabled by default, shadow FB enabled by default
|
||||
...
|
||||
|
||||
|
||||
Licensing
|
||||
---------
|
||||
|
||||
While the original codebase is MIT, any changes here are GPLv3. Supporting closed devices
|
||||
with this code is not a goal.
|
|
@ -0,0 +1,65 @@
|
|||
# libXext.la: includes all extensions and should be linked into Xvfb,
|
||||
# Xnest, Xdmx and Xprt
|
||||
# libXextbuiltin.la: includes those extensions that are built directly into
|
||||
# Xorg by default
|
||||
# libXextmodule.la: includes those extensions that are built into a module
|
||||
# that Xorg loads
|
||||
noinst_LTLIBRARIES = libXext.la
|
||||
|
||||
AM_CFLAGS = $(DIX_CFLAGS)
|
||||
|
||||
# Sources always included in libXextbuiltin.la & libXext.la
|
||||
BUILTIN_SRCS = \
|
||||
shape.c \
|
||||
sleepuntil.c \
|
||||
sleepuntil.h \
|
||||
xtest.c
|
||||
|
||||
# Sources always included in libXextmodule.la & libXext.la
|
||||
MODULE_SRCS = \
|
||||
bigreq.c \
|
||||
shape.c \
|
||||
sync.c \
|
||||
xcmisc.c
|
||||
|
||||
# Optional sources included if extension enabled by configure.ac rules
|
||||
|
||||
# MIT Shared Memory extension
|
||||
MITSHM_SRCS = shm.c shmint.h
|
||||
BUILTIN_SRCS += $(MITSHM_SRCS)
|
||||
|
||||
# XResource extension: lets clients get data about per-client resource usage
|
||||
RES_SRCS = xres.c
|
||||
if RES
|
||||
MODULE_SRCS += $(RES_SRCS)
|
||||
endif
|
||||
|
||||
# MIT ScreenSaver extension
|
||||
SCREENSAVER_SRCS = saver.c
|
||||
if SCREENSAVER
|
||||
MODULE_SRCS += $(SCREENSAVER_SRCS)
|
||||
endif
|
||||
|
||||
# XF86 Big Font extension
|
||||
BIGFONT_SRCS = xf86bigfont.c xf86bigfontsrv.h
|
||||
if XF86BIGFONT
|
||||
BUILTIN_SRCS += $(BIGFONT_SRCS)
|
||||
endif
|
||||
|
||||
# DPMS extension
|
||||
DPMS_SRCS = dpms.c dpmsproc.h
|
||||
if DPMSExtension
|
||||
MODULE_SRCS += $(DPMS_SRCS)
|
||||
endif
|
||||
|
||||
# Now take all of the above, mix well, bake for 10 minutes and get libXext*.la
|
||||
|
||||
libXext_la_SOURCES = $(BUILTIN_SRCS) $(MODULE_SRCS)
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(MITSHM_SRCS) \
|
||||
$(RES_SRCS) \
|
||||
$(SCREENSAVER_SRCS) \
|
||||
$(BIGFONT_SRCS) \
|
||||
$(DPMS_SRCS)
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
|
||||
Copyright 1992, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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 OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include <X11/extensions/bigreqsproto.h>
|
||||
#include "opaque.h"
|
||||
#include "extinit.h"
|
||||
|
||||
#if 0
|
||||
static unsigned char XBigReqCode;
|
||||
#endif
|
||||
|
||||
static void BigReqResetProc(ExtensionEntry * /* extEntry */
|
||||
);
|
||||
|
||||
static DISPATCH_PROC(ProcBigReqDispatch);
|
||||
|
||||
void
|
||||
BigReqExtensionInit(INITARGS)
|
||||
{
|
||||
#if 0
|
||||
ExtensionEntry *extEntry;
|
||||
|
||||
if ((extEntry = AddExtension(XBigReqExtensionName, 0, 0,
|
||||
ProcBigReqDispatch, ProcBigReqDispatch,
|
||||
BigReqResetProc, StandardMinorOpcode)) != 0)
|
||||
XBigReqCode = (unsigned char) extEntry->base;
|
||||
#else
|
||||
(void) AddExtension(XBigReqExtensionName, 0, 0,
|
||||
ProcBigReqDispatch, ProcBigReqDispatch,
|
||||
BigReqResetProc, StandardMinorOpcode);
|
||||
#endif
|
||||
|
||||
DeclareExtensionSecurity(XBigReqExtensionName, TRUE);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/ static void
|
||||
BigReqResetProc(extEntry)
|
||||
ExtensionEntry *extEntry;
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
ProcBigReqDispatch(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xBigReqEnableReq);
|
||||
xBigReqEnableReply rep = {0};
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&stuff->length);
|
||||
}
|
||||
if (stuff->brReqType != X_BigReqEnable)
|
||||
return BadRequest;
|
||||
REQUEST_SIZE_MATCH(xBigReqEnableReq);
|
||||
client->big_requests = TRUE;
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.max_request_size = maxBigRequestSize;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.max_request_size);
|
||||
}
|
||||
WriteToClient(client, sizeof(xBigReqEnableReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
|
@ -0,0 +1,453 @@
|
|||
/*****************************************************************
|
||||
|
||||
Copyright (c) 1996 Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
|
||||
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
|
||||
|
||||
Except as contained in this notice, the name of Digital Equipment Corporation
|
||||
shall not be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Software without prior written authorization from Digital
|
||||
Equipment Corporation.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* HISTORY
|
||||
*
|
||||
* @(#)RCSfile: dpms.c,v Revision: 1.1.4.5 (DEC) Date: 1996/03/04 15:27:00
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include "opaque.h"
|
||||
#define DPMS_SERVER
|
||||
#include <X11/extensions/dpms.h>
|
||||
#include <X11/extensions/dpmsproto.h>
|
||||
#include "dpmsproc.h"
|
||||
#include "extinit.h"
|
||||
|
||||
#if 0
|
||||
static unsigned char DPMSCode;
|
||||
#endif
|
||||
static DISPATCH_PROC(ProcDPMSDispatch);
|
||||
|
||||
static DISPATCH_PROC(SProcDPMSDispatch);
|
||||
|
||||
static DISPATCH_PROC(ProcDPMSGetVersion);
|
||||
|
||||
static DISPATCH_PROC(SProcDPMSGetVersion);
|
||||
|
||||
static DISPATCH_PROC(ProcDPMSGetTimeouts);
|
||||
|
||||
static DISPATCH_PROC(SProcDPMSGetTimeouts);
|
||||
|
||||
static DISPATCH_PROC(ProcDPMSSetTimeouts);
|
||||
|
||||
static DISPATCH_PROC(SProcDPMSSetTimeouts);
|
||||
|
||||
static DISPATCH_PROC(ProcDPMSEnable);
|
||||
|
||||
static DISPATCH_PROC(SProcDPMSEnable);
|
||||
|
||||
static DISPATCH_PROC(ProcDPMSDisable);
|
||||
|
||||
static DISPATCH_PROC(SProcDPMSDisable);
|
||||
|
||||
static DISPATCH_PROC(ProcDPMSForceLevel);
|
||||
|
||||
static DISPATCH_PROC(SProcDPMSForceLevel);
|
||||
|
||||
static DISPATCH_PROC(ProcDPMSInfo);
|
||||
|
||||
static DISPATCH_PROC(SProcDPMSInfo);
|
||||
|
||||
static DISPATCH_PROC(ProcDPMSCapable);
|
||||
|
||||
static DISPATCH_PROC(SProcDPMSCapable);
|
||||
|
||||
static void DPMSResetProc(ExtensionEntry * extEntry);
|
||||
|
||||
void
|
||||
DPMSExtensionInit(INITARGS)
|
||||
{
|
||||
#if 0
|
||||
ExtensionEntry *extEntry;
|
||||
|
||||
if ((extEntry = AddExtension(DPMSExtensionName, 0, 0,
|
||||
ProcDPMSDispatch, SProcDPMSDispatch,
|
||||
DPMSResetProc, StandardMinorOpcode)))
|
||||
DPMSCode = (unsigned char) extEntry->base;
|
||||
#else
|
||||
(void) AddExtension(DPMSExtensionName, 0, 0,
|
||||
ProcDPMSDispatch, SProcDPMSDispatch,
|
||||
DPMSResetProc, StandardMinorOpcode);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*ARGSUSED*/ static void
|
||||
DPMSResetProc(extEntry)
|
||||
ExtensionEntry *extEntry;
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDPMSGetVersion(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
/* REQUEST(xDPMSGetVersionReq); */
|
||||
xDPMSGetVersionReply rep;
|
||||
|
||||
|
||||
REQUEST_SIZE_MATCH(xDPMSGetVersionReq);
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.majorVersion = DPMSMajorVersion;
|
||||
rep.minorVersion = DPMSMinorVersion;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swaps(&rep.majorVersion);
|
||||
swaps(&rep.minorVersion);
|
||||
}
|
||||
WriteToClient(client, sizeof(xDPMSGetVersionReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDPMSCapable(register ClientPtr client)
|
||||
{
|
||||
/* REQUEST(xDPMSCapableReq); */
|
||||
xDPMSCapableReply rep;
|
||||
|
||||
|
||||
REQUEST_SIZE_MATCH(xDPMSCapableReq);
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.capable = DPMSCapableFlag;
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
}
|
||||
WriteToClient(client, sizeof(xDPMSCapableReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDPMSGetTimeouts(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
/* REQUEST(xDPMSGetTimeoutsReq); */
|
||||
xDPMSGetTimeoutsReply rep;
|
||||
|
||||
|
||||
REQUEST_SIZE_MATCH(xDPMSGetTimeoutsReq);
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.standby = DPMSStandbyTime / MILLI_PER_SECOND;
|
||||
rep.suspend = DPMSSuspendTime / MILLI_PER_SECOND;
|
||||
rep.off = DPMSOffTime / MILLI_PER_SECOND;
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swaps(&rep.standby);
|
||||
swaps(&rep.suspend);
|
||||
swaps(&rep.off);
|
||||
}
|
||||
WriteToClient(client, sizeof(xDPMSGetTimeoutsReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDPMSSetTimeouts(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xDPMSSetTimeoutsReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xDPMSSetTimeoutsReq);
|
||||
|
||||
if ((stuff->off != 0) && (stuff->off < stuff->suspend)) {
|
||||
client->errorValue = stuff->off;
|
||||
return BadValue;
|
||||
}
|
||||
if ((stuff->suspend != 0) && (stuff->suspend < stuff->standby)) {
|
||||
client->errorValue = stuff->suspend;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
DPMSStandbyTime = stuff->standby * MILLI_PER_SECOND;
|
||||
DPMSSuspendTime = stuff->suspend * MILLI_PER_SECOND;
|
||||
DPMSOffTime = stuff->off * MILLI_PER_SECOND;
|
||||
SetScreenSaverTimer();
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDPMSEnable(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
/* REQUEST(xDPMSEnableReq); */
|
||||
|
||||
REQUEST_SIZE_MATCH(xDPMSEnableReq);
|
||||
|
||||
if (DPMSCapableFlag)
|
||||
DPMSEnabled = TRUE;
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDPMSDisable(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
/* REQUEST(xDPMSDisableReq); */
|
||||
|
||||
REQUEST_SIZE_MATCH(xDPMSDisableReq);
|
||||
|
||||
DPMSSet(DPMSModeOn);
|
||||
|
||||
DPMSEnabled = FALSE;
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDPMSForceLevel(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xDPMSForceLevelReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xDPMSForceLevelReq);
|
||||
|
||||
if (!DPMSEnabled)
|
||||
return BadMatch;
|
||||
|
||||
if (stuff->level == DPMSModeOn) {
|
||||
lastDeviceEventTime.milliseconds = GetTimeInMillis();
|
||||
}
|
||||
else if (stuff->level == DPMSModeStandby) {
|
||||
lastDeviceEventTime.milliseconds = GetTimeInMillis() - DPMSStandbyTime;
|
||||
}
|
||||
else if (stuff->level == DPMSModeSuspend) {
|
||||
lastDeviceEventTime.milliseconds = GetTimeInMillis() - DPMSSuspendTime;
|
||||
}
|
||||
else if (stuff->level == DPMSModeOff) {
|
||||
lastDeviceEventTime.milliseconds = GetTimeInMillis() - DPMSOffTime;
|
||||
}
|
||||
else {
|
||||
client->errorValue = stuff->level;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
DPMSSet(stuff->level);
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDPMSInfo(register ClientPtr client)
|
||||
{
|
||||
/* REQUEST(xDPMSInfoReq); */
|
||||
xDPMSInfoReply rep;
|
||||
|
||||
|
||||
REQUEST_SIZE_MATCH(xDPMSInfoReq);
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.power_level = DPMSPowerLevel;
|
||||
rep.state = DPMSEnabled;
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swaps(&rep.power_level);
|
||||
}
|
||||
WriteToClient(client, sizeof(xDPMSInfoReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDPMSDispatch(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xReq);
|
||||
|
||||
switch (stuff->data) {
|
||||
case X_DPMSGetVersion:
|
||||
return ProcDPMSGetVersion(client);
|
||||
case X_DPMSCapable:
|
||||
return ProcDPMSCapable(client);
|
||||
case X_DPMSGetTimeouts:
|
||||
return ProcDPMSGetTimeouts(client);
|
||||
case X_DPMSSetTimeouts:
|
||||
return ProcDPMSSetTimeouts(client);
|
||||
case X_DPMSEnable:
|
||||
return ProcDPMSEnable(client);
|
||||
case X_DPMSDisable:
|
||||
return ProcDPMSDisable(client);
|
||||
case X_DPMSForceLevel:
|
||||
return ProcDPMSForceLevel(client);
|
||||
case X_DPMSInfo:
|
||||
return ProcDPMSInfo(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDPMSGetVersion(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xDPMSGetVersionReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDPMSGetVersionReq);
|
||||
swaps(&stuff->majorVersion);
|
||||
swaps(&stuff->minorVersion);
|
||||
return ProcDPMSGetVersion(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDPMSCapable(register ClientPtr client)
|
||||
{
|
||||
REQUEST(xDPMSCapableReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDPMSCapableReq);
|
||||
|
||||
return ProcDPMSCapable(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDPMSGetTimeouts(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xDPMSGetTimeoutsReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDPMSGetTimeoutsReq);
|
||||
|
||||
return ProcDPMSGetTimeouts(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDPMSSetTimeouts(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xDPMSSetTimeoutsReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDPMSSetTimeoutsReq);
|
||||
|
||||
swaps(&stuff->standby);
|
||||
swaps(&stuff->suspend);
|
||||
swaps(&stuff->off);
|
||||
return ProcDPMSSetTimeouts(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDPMSEnable(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xDPMSEnableReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDPMSEnableReq);
|
||||
|
||||
return ProcDPMSEnable(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDPMSDisable(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xDPMSDisableReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDPMSDisableReq);
|
||||
|
||||
return ProcDPMSDisable(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDPMSForceLevel(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xDPMSForceLevelReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDPMSForceLevelReq);
|
||||
|
||||
swaps(&stuff->level);
|
||||
|
||||
return ProcDPMSForceLevel(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDPMSInfo(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xDPMSInfoReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDPMSInfoReq);
|
||||
|
||||
return ProcDPMSInfo(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDPMSDispatch(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xReq);
|
||||
switch (stuff->data) {
|
||||
case X_DPMSGetVersion:
|
||||
return SProcDPMSGetVersion(client);
|
||||
case X_DPMSCapable:
|
||||
return SProcDPMSCapable(client);
|
||||
case X_DPMSGetTimeouts:
|
||||
return SProcDPMSGetTimeouts(client);
|
||||
case X_DPMSSetTimeouts:
|
||||
return SProcDPMSSetTimeouts(client);
|
||||
case X_DPMSEnable:
|
||||
return SProcDPMSEnable(client);
|
||||
case X_DPMSDisable:
|
||||
return SProcDPMSDisable(client);
|
||||
case X_DPMSForceLevel:
|
||||
return SProcDPMSForceLevel(client);
|
||||
case X_DPMSInfo:
|
||||
return SProcDPMSInfo(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
/* Prototypes for functions that the DDX must provide */
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _DPMSPROC_H_
|
||||
#define _DPMSPROC_H_
|
||||
|
||||
void DPMSSet(int level);
|
||||
|
||||
Bool DPMSSupported(void);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,991 @@
|
|||
/************************************************************
|
||||
|
||||
Copyright 1989, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
********************************************************/
|
||||
|
||||
/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
|
||||
|
||||
#define SHM
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
#include "resource.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "windowstr.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include "servermd.h"
|
||||
#define _XSHM_SERVER_
|
||||
#include <X11/extensions/shmstr.h>
|
||||
#include <X11/Xfuncproto.h>
|
||||
|
||||
|
||||
#include "extinit.h"
|
||||
|
||||
typedef struct _ShmDesc {
|
||||
struct _ShmDesc *next;
|
||||
int shmid;
|
||||
int refcnt;
|
||||
char *addr;
|
||||
Bool writable;
|
||||
unsigned long size;
|
||||
} ShmDescRec, *ShmDescPtr;
|
||||
|
||||
static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
|
||||
|
||||
static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
|
||||
|
||||
static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
|
||||
|
||||
static int ShmDetachSegment(pointer /* value */ ,
|
||||
XID /* shmseg */
|
||||
);
|
||||
|
||||
static void ShmResetProc(ExtensionEntry * /* extEntry */
|
||||
);
|
||||
|
||||
static void SShmCompletionEvent(xShmCompletionEvent * /* from */ ,
|
||||
xShmCompletionEvent * /* to */
|
||||
);
|
||||
|
||||
static Bool ShmDestroyPixmap(PixmapPtr pPixmap);
|
||||
|
||||
static DISPATCH_PROC(ProcShmAttach);
|
||||
|
||||
static DISPATCH_PROC(ProcShmCreatePixmap);
|
||||
|
||||
static DISPATCH_PROC(ProcShmDetach);
|
||||
|
||||
static DISPATCH_PROC(ProcShmDispatch);
|
||||
|
||||
static DISPATCH_PROC(ProcShmGetImage);
|
||||
|
||||
static DISPATCH_PROC(ProcShmPutImage);
|
||||
|
||||
static DISPATCH_PROC(ProcShmQueryVersion);
|
||||
|
||||
static DISPATCH_PROC(SProcShmAttach);
|
||||
|
||||
static DISPATCH_PROC(SProcShmCreatePixmap);
|
||||
|
||||
static DISPATCH_PROC(SProcShmDetach);
|
||||
|
||||
static DISPATCH_PROC(SProcShmDispatch);
|
||||
|
||||
static DISPATCH_PROC(SProcShmGetImage);
|
||||
|
||||
static DISPATCH_PROC(SProcShmPutImage);
|
||||
|
||||
static DISPATCH_PROC(SProcShmQueryVersion);
|
||||
|
||||
static unsigned char ShmReqCode;
|
||||
|
||||
_X_EXPORT int ShmCompletionCode;
|
||||
|
||||
_X_EXPORT int BadShmSegCode;
|
||||
|
||||
_X_EXPORT RESTYPE ShmSegType;
|
||||
|
||||
static ShmDescPtr Shmsegs;
|
||||
|
||||
static Bool sharedPixmaps;
|
||||
|
||||
static int pixmapFormat;
|
||||
|
||||
static int shmPixFormat[MAXSCREENS];
|
||||
|
||||
static const ShmFuncs * shmFuncs[MAXSCREENS];
|
||||
|
||||
static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
|
||||
|
||||
static int shmPixmapPrivate;
|
||||
static const ShmFuncs miFuncs = { NULL, miShmPutImage };
|
||||
static const ShmFuncs fbFuncs = { fbShmCreatePixmap, fbShmPutImage };
|
||||
|
||||
#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
|
||||
{ \
|
||||
shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
|
||||
if (!shmdesc) \
|
||||
{ \
|
||||
client->errorValue = shmseg; \
|
||||
return BadShmSegCode; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
|
||||
{ \
|
||||
VERIFY_SHMSEG(shmseg, shmdesc, client); \
|
||||
if ((offset & 3) || (offset > shmdesc->size)) \
|
||||
{ \
|
||||
client->errorValue = offset; \
|
||||
return BadValue; \
|
||||
} \
|
||||
if (needwrite && !shmdesc->writable) \
|
||||
return BadAccess; \
|
||||
}
|
||||
|
||||
#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
|
||||
{ \
|
||||
if ((offset + len) > shmdesc->size) \
|
||||
{ \
|
||||
return BadAccess; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
|
||||
#include <sys/signal.h>
|
||||
|
||||
static Bool badSysCall = FALSE;
|
||||
|
||||
static void
|
||||
SigSysHandler(signo)
|
||||
int signo;
|
||||
{
|
||||
badSysCall = TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
CheckForShmSyscall()
|
||||
{
|
||||
void (*oldHandler) ();
|
||||
|
||||
int shmid = -1;
|
||||
|
||||
/* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
|
||||
oldHandler = signal(SIGSYS, SigSysHandler);
|
||||
|
||||
badSysCall = FALSE;
|
||||
shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
|
||||
|
||||
if (shmid != -1) {
|
||||
/* Successful allocation - clean up */
|
||||
shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL);
|
||||
}
|
||||
else {
|
||||
/* Allocation failed */
|
||||
badSysCall = TRUE;
|
||||
}
|
||||
signal(SIGSYS, oldHandler);
|
||||
return (!badSysCall);
|
||||
}
|
||||
|
||||
#define MUST_CHECK_FOR_SHM_SYSCALL
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
ShmExtensionInit(INITARGS)
|
||||
{
|
||||
ExtensionEntry *extEntry;
|
||||
|
||||
int i;
|
||||
|
||||
#ifdef MUST_CHECK_FOR_SHM_SYSCALL
|
||||
if (!CheckForShmSyscall()) {
|
||||
ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
sharedPixmaps = xFalse;
|
||||
pixmapFormat = 0;
|
||||
{
|
||||
sharedPixmaps = xTrue;
|
||||
pixmapFormat = shmPixFormat[0];
|
||||
for (i = 0; i < screenInfo.numScreens; i++) {
|
||||
if (!shmFuncs[i])
|
||||
shmFuncs[i] = &miFuncs;
|
||||
if (!shmFuncs[i]->CreatePixmap)
|
||||
sharedPixmaps = xFalse;
|
||||
if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat)) {
|
||||
sharedPixmaps = xFalse;
|
||||
pixmapFormat = 0;
|
||||
}
|
||||
}
|
||||
if (!pixmapFormat)
|
||||
pixmapFormat = ZPixmap;
|
||||
if (sharedPixmaps) {
|
||||
for (i = 0; i < screenInfo.numScreens; i++) {
|
||||
destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
|
||||
screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
|
||||
}
|
||||
shmPixmapPrivate = AllocatePixmapPrivateIndex();
|
||||
for (i = 0; i < screenInfo.numScreens; i++) {
|
||||
if (!AllocatePixmapPrivate(screenInfo.screens[i],
|
||||
shmPixmapPrivate, 0))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ShmSegType = CreateNewResourceType(ShmDetachSegment);
|
||||
if (ShmSegType &&
|
||||
(extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
|
||||
ProcShmDispatch, SProcShmDispatch,
|
||||
ShmResetProc, StandardMinorOpcode))) {
|
||||
ShmReqCode = (unsigned char) extEntry->base;
|
||||
ShmCompletionCode = extEntry->eventBase;
|
||||
BadShmSegCode = extEntry->errorBase;
|
||||
EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/ static void
|
||||
ShmResetProc(extEntry)
|
||||
ExtensionEntry *extEntry;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXSCREENS; i++) {
|
||||
shmFuncs[i] = (ShmFuncsPtr) NULL;
|
||||
shmPixFormat[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs)
|
||||
{
|
||||
shmFuncs[pScreen->myNum] = funcs;
|
||||
}
|
||||
|
||||
void
|
||||
ShmSetPixmapFormat(ScreenPtr pScreen, int format)
|
||||
{
|
||||
shmPixFormat[pScreen->myNum] = format;
|
||||
}
|
||||
|
||||
static Bool
|
||||
ShmDestroyPixmap(PixmapPtr pPixmap)
|
||||
{
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
|
||||
Bool ret;
|
||||
|
||||
if (pPixmap->refcnt == 1) {
|
||||
ShmDescPtr shmdesc;
|
||||
|
||||
shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
|
||||
if (shmdesc)
|
||||
ShmDetachSegment((pointer) shmdesc, pPixmap->drawable.id);
|
||||
}
|
||||
|
||||
pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
|
||||
ret = (*pScreen->DestroyPixmap) (pPixmap);
|
||||
destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
|
||||
pScreen->DestroyPixmap = ShmDestroyPixmap;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
ShmRegisterFbFuncs(pScreen)
|
||||
ScreenPtr pScreen;
|
||||
{
|
||||
shmFuncs[pScreen->myNum] = &fbFuncs;
|
||||
}
|
||||
|
||||
static int
|
||||
ProcShmQueryVersion(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
xShmQueryVersionReply rep;
|
||||
|
||||
|
||||
REQUEST_SIZE_MATCH(xShmQueryVersionReq);
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.sharedPixmaps = sharedPixmaps;
|
||||
rep.pixmapFormat = pixmapFormat;
|
||||
rep.majorVersion = SHM_MAJOR_VERSION;
|
||||
rep.minorVersion = SHM_MINOR_VERSION;
|
||||
rep.uid = geteuid();
|
||||
rep.gid = getegid();
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
swaps(&rep.majorVersion);
|
||||
swaps(&rep.minorVersion);
|
||||
swaps(&rep.uid);
|
||||
swaps(&rep.gid);
|
||||
}
|
||||
WriteToClient(client, sizeof(xShmQueryVersionReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simulate the access() system call for a shared memory segement,
|
||||
* using the credentials from the client if available
|
||||
*/
|
||||
static int
|
||||
shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
|
||||
{
|
||||
int uid, gid;
|
||||
|
||||
mode_t mask;
|
||||
|
||||
if (LocalClientCred(client, &uid, &gid) != -1) {
|
||||
|
||||
/* User id 0 always gets access */
|
||||
if (uid == 0) {
|
||||
return 0;
|
||||
}
|
||||
/* Check the owner */
|
||||
if (perm->uid == uid || perm->cuid == uid) {
|
||||
mask = S_IRUSR;
|
||||
if (!readonly) {
|
||||
mask |= S_IWUSR;
|
||||
}
|
||||
return (perm->mode & mask) == mask ? 0 : -1;
|
||||
}
|
||||
/* Check the group */
|
||||
if (perm->gid == gid || perm->cgid == gid) {
|
||||
mask = S_IRGRP;
|
||||
if (!readonly) {
|
||||
mask |= S_IWGRP;
|
||||
}
|
||||
return (perm->mode & mask) == mask ? 0 : -1;
|
||||
}
|
||||
}
|
||||
/* Otherwise, check everyone else */
|
||||
mask = S_IROTH;
|
||||
if (!readonly) {
|
||||
mask |= S_IWOTH;
|
||||
}
|
||||
return (perm->mode & mask) == mask ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
ProcShmAttach(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
struct shmid_ds buf;
|
||||
|
||||
ShmDescPtr shmdesc;
|
||||
|
||||
REQUEST(xShmAttachReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xShmAttachReq);
|
||||
LEGAL_NEW_RESOURCE(stuff->shmseg, client);
|
||||
if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) {
|
||||
client->errorValue = stuff->readOnly;
|
||||
return (BadValue);
|
||||
}
|
||||
for (shmdesc = Shmsegs;
|
||||
shmdesc && (shmdesc->shmid != stuff->shmid); shmdesc = shmdesc->next);
|
||||
if (shmdesc) {
|
||||
if (!stuff->readOnly && !shmdesc->writable)
|
||||
return BadAccess;
|
||||
shmdesc->refcnt++;
|
||||
}
|
||||
else {
|
||||
shmdesc = malloc(sizeof(ShmDescRec));
|
||||
if (!shmdesc)
|
||||
return BadAlloc;
|
||||
shmdesc->addr = shmat(stuff->shmid, 0,
|
||||
stuff->readOnly ? SHM_RDONLY : 0);
|
||||
if ((shmdesc->addr == ((char *) -1)) ||
|
||||
shmctl(stuff->shmid, IPC_STAT, &buf)) {
|
||||
free(shmdesc);
|
||||
return BadAccess;
|
||||
}
|
||||
|
||||
/* The attach was performed with root privs. We must
|
||||
* do manual checking of access rights for the credentials
|
||||
* of the client */
|
||||
|
||||
if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
|
||||
shmdt(shmdesc->addr);
|
||||
free(shmdesc);
|
||||
return BadAccess;
|
||||
}
|
||||
|
||||
shmdesc->shmid = stuff->shmid;
|
||||
shmdesc->refcnt = 1;
|
||||
shmdesc->writable = !stuff->readOnly;
|
||||
shmdesc->size = buf.shm_segsz;
|
||||
shmdesc->next = Shmsegs;
|
||||
Shmsegs = shmdesc;
|
||||
}
|
||||
if (!AddResource(stuff->shmseg, ShmSegType, (pointer) shmdesc))
|
||||
return BadAlloc;
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/ static int
|
||||
ShmDetachSegment(value, shmseg)
|
||||
pointer value; /* must conform to DeleteType */
|
||||
|
||||
XID shmseg;
|
||||
{
|
||||
ShmDescPtr shmdesc = (ShmDescPtr) value;
|
||||
|
||||
ShmDescPtr *prev;
|
||||
|
||||
if (--shmdesc->refcnt)
|
||||
return TRUE;
|
||||
shmdt(shmdesc->addr);
|
||||
for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next);
|
||||
*prev = shmdesc->next;
|
||||
free(shmdesc);
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
ProcShmDetach(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
ShmDescPtr shmdesc;
|
||||
|
||||
REQUEST(xShmDetachReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xShmDetachReq);
|
||||
VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
|
||||
FreeResource(stuff->shmseg, RT_NONE);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static void
|
||||
miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
|
||||
DrawablePtr dst;
|
||||
|
||||
GCPtr pGC;
|
||||
|
||||
int depth, w, h, sx, sy, sw, sh, dx, dy;
|
||||
|
||||
unsigned int format;
|
||||
|
||||
char *data;
|
||||
{
|
||||
PixmapPtr pmap;
|
||||
|
||||
GCPtr putGC;
|
||||
|
||||
putGC = GetScratchGC(depth, dst->pScreen);
|
||||
if (!putGC)
|
||||
return;
|
||||
pmap = (*dst->pScreen->CreatePixmap) (dst->pScreen, sw, sh, depth);
|
||||
if (!pmap) {
|
||||
FreeScratchGC(putGC);
|
||||
return;
|
||||
}
|
||||
ValidateGC((DrawablePtr) pmap, putGC);
|
||||
(*putGC->ops->PutImage) ((DrawablePtr) pmap, putGC, depth, -sx, -sy, w, h,
|
||||
0, (format == XYPixmap) ? XYPixmap : ZPixmap,
|
||||
data);
|
||||
FreeScratchGC(putGC);
|
||||
if (format == XYBitmap)
|
||||
(void) (*pGC->ops->CopyPlane) ((DrawablePtr) pmap, dst, pGC, 0, 0, sw,
|
||||
sh, dx, dy, 1L);
|
||||
else
|
||||
(void) (*pGC->ops->CopyArea) ((DrawablePtr) pmap, dst, pGC, 0, 0, sw,
|
||||
sh, dx, dy);
|
||||
(*pmap->drawable.pScreen->DestroyPixmap) (pmap);
|
||||
}
|
||||
|
||||
static void
|
||||
fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
|
||||
DrawablePtr dst;
|
||||
|
||||
GCPtr pGC;
|
||||
|
||||
int depth, w, h, sx, sy, sw, sh, dx, dy;
|
||||
|
||||
unsigned int format;
|
||||
|
||||
char *data;
|
||||
{
|
||||
if ((format == ZPixmap) || (depth == 1)) {
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
|
||||
BitsPerPixel(depth), PixmapBytePad(w,
|
||||
depth),
|
||||
(pointer) data);
|
||||
if (!pPixmap)
|
||||
return;
|
||||
if (format == XYBitmap)
|
||||
(void) (*pGC->ops->CopyPlane) ((DrawablePtr) pPixmap, dst, pGC,
|
||||
sx, sy, sw, sh, dx, dy, 1L);
|
||||
else
|
||||
(void) (*pGC->ops->CopyArea) ((DrawablePtr) pPixmap, dst, pGC,
|
||||
sx, sy, sw, sh, dx, dy);
|
||||
FreeScratchPixmapHeader(pPixmap);
|
||||
}
|
||||
else
|
||||
miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
|
||||
data);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ProcShmPutImage(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
GCPtr pGC;
|
||||
|
||||
DrawablePtr pDraw;
|
||||
|
||||
long length;
|
||||
|
||||
ShmDescPtr shmdesc;
|
||||
|
||||
REQUEST(xShmPutImageReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xShmPutImageReq);
|
||||
VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
|
||||
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
|
||||
if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
|
||||
return BadValue;
|
||||
if (stuff->format == XYBitmap) {
|
||||
if (stuff->depth != 1)
|
||||
return BadMatch;
|
||||
length = PixmapBytePad(stuff->totalWidth, 1);
|
||||
}
|
||||
else if (stuff->format == XYPixmap) {
|
||||
if (pDraw->depth != stuff->depth)
|
||||
return BadMatch;
|
||||
length = PixmapBytePad(stuff->totalWidth, 1);
|
||||
length *= stuff->depth;
|
||||
}
|
||||
else if (stuff->format == ZPixmap) {
|
||||
if (pDraw->depth != stuff->depth)
|
||||
return BadMatch;
|
||||
length = PixmapBytePad(stuff->totalWidth, stuff->depth);
|
||||
}
|
||||
else {
|
||||
client->errorValue = stuff->format;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, client);
|
||||
if (stuff->srcX > stuff->totalWidth) {
|
||||
client->errorValue = stuff->srcX;
|
||||
return BadValue;
|
||||
}
|
||||
if (stuff->srcY > stuff->totalHeight) {
|
||||
client->errorValue = stuff->srcY;
|
||||
return BadValue;
|
||||
}
|
||||
if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth) {
|
||||
client->errorValue = stuff->srcWidth;
|
||||
return BadValue;
|
||||
}
|
||||
if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight) {
|
||||
client->errorValue = stuff->srcHeight;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
|
||||
((stuff->format != ZPixmap) &&
|
||||
(stuff->srcX < screenInfo.bitmapScanlinePad) &&
|
||||
((stuff->format == XYBitmap) ||
|
||||
((stuff->srcY == 0) &&
|
||||
(stuff->srcHeight == stuff->totalHeight))))) &&
|
||||
((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
|
||||
(*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
|
||||
stuff->dstX, stuff->dstY,
|
||||
stuff->totalWidth, stuff->srcHeight,
|
||||
stuff->srcX, stuff->format,
|
||||
shmdesc->addr + stuff->offset +
|
||||
(stuff->srcY * length));
|
||||
else
|
||||
(*shmFuncs[pDraw->pScreen->myNum]->PutImage) (pDraw, pGC, stuff->depth,
|
||||
stuff->format,
|
||||
stuff->totalWidth,
|
||||
stuff->totalHeight,
|
||||
stuff->srcX, stuff->srcY,
|
||||
stuff->srcWidth,
|
||||
stuff->srcHeight,
|
||||
stuff->dstX, stuff->dstY,
|
||||
shmdesc->addr +
|
||||
stuff->offset);
|
||||
|
||||
if (stuff->sendEvent) {
|
||||
xShmCompletionEvent ev;
|
||||
|
||||
ev.type = ShmCompletionCode;
|
||||
ev.drawable = stuff->drawable;
|
||||
ev.sequenceNumber = client->sequence;
|
||||
ev.minorEvent = X_ShmPutImage;
|
||||
ev.majorEvent = ShmReqCode;
|
||||
ev.shmseg = stuff->shmseg;
|
||||
ev.offset = stuff->offset;
|
||||
WriteEventsToClient(client, 1, (xEvent *) &ev);
|
||||
}
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcShmGetImage(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
DrawablePtr pDraw;
|
||||
|
||||
long lenPer = 0, length;
|
||||
|
||||
Mask plane = 0;
|
||||
|
||||
xShmGetImageReply xgi;
|
||||
|
||||
ShmDescPtr shmdesc;
|
||||
|
||||
REQUEST(xShmGetImageReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xShmGetImageReq);
|
||||
if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
|
||||
client->errorValue = stuff->format;
|
||||
return (BadValue);
|
||||
}
|
||||
VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
|
||||
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
|
||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
||||
if ( /* check for being viewable */
|
||||
!((WindowPtr) pDraw)->realized ||
|
||||
/* check for being on screen */
|
||||
pDraw->x + stuff->x < 0 ||
|
||||
pDraw->x + stuff->x + (int) stuff->width > pDraw->pScreen->width
|
||||
|| pDraw->y + stuff->y < 0 ||
|
||||
pDraw->y + stuff->y + (int) stuff->height >
|
||||
pDraw->pScreen->height ||
|
||||
/* check for being inside of border */
|
||||
stuff->x < -wBorderWidth((WindowPtr) pDraw) ||
|
||||
stuff->x + (int) stuff->width >
|
||||
wBorderWidth((WindowPtr) pDraw) + (int) pDraw->width ||
|
||||
stuff->y < -wBorderWidth((WindowPtr) pDraw) ||
|
||||
stuff->y + (int) stuff->height >
|
||||
wBorderWidth((WindowPtr) pDraw) + (int) pDraw->height)
|
||||
return (BadMatch);
|
||||
xgi.visual = wVisual(((WindowPtr) pDraw));
|
||||
}
|
||||
else {
|
||||
if (stuff->x < 0 ||
|
||||
stuff->x + (int) stuff->width > pDraw->width ||
|
||||
stuff->y < 0 || stuff->y + (int) stuff->height > pDraw->height)
|
||||
return (BadMatch);
|
||||
xgi.visual = None;
|
||||
}
|
||||
xgi.type = X_Reply;
|
||||
xgi.length = 0;
|
||||
xgi.sequenceNumber = client->sequence;
|
||||
xgi.depth = pDraw->depth;
|
||||
if (stuff->format == ZPixmap) {
|
||||
length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
|
||||
}
|
||||
else {
|
||||
lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
|
||||
plane = ((Mask) 1) << (pDraw->depth - 1);
|
||||
/* only planes asked for */
|
||||
length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
|
||||
}
|
||||
|
||||
VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
|
||||
xgi.size = length;
|
||||
|
||||
if (length == 0) {
|
||||
/* nothing to do */
|
||||
}
|
||||
else if (stuff->format == ZPixmap) {
|
||||
(*pDraw->pScreen->GetImage) (pDraw, stuff->x, stuff->y,
|
||||
stuff->width, stuff->height,
|
||||
stuff->format, stuff->planeMask,
|
||||
shmdesc->addr + stuff->offset);
|
||||
}
|
||||
else {
|
||||
|
||||
length = stuff->offset;
|
||||
for (; plane; plane >>= 1) {
|
||||
if (stuff->planeMask & plane) {
|
||||
(*pDraw->pScreen->GetImage) (pDraw,
|
||||
stuff->x, stuff->y,
|
||||
stuff->width, stuff->height,
|
||||
stuff->format, plane,
|
||||
shmdesc->addr + length);
|
||||
length += lenPer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (client->swapped) {
|
||||
swaps(&xgi.sequenceNumber);
|
||||
swapl(&xgi.length);
|
||||
swapl(&xgi.visual);
|
||||
swapl(&xgi.size);
|
||||
}
|
||||
WriteToClient(client, sizeof(xShmGetImageReply), (char *) &xgi);
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static PixmapPtr
|
||||
fbShmCreatePixmap(pScreen, width, height, depth, addr)
|
||||
ScreenPtr pScreen;
|
||||
|
||||
int width;
|
||||
|
||||
int height;
|
||||
|
||||
int depth;
|
||||
|
||||
char *addr;
|
||||
{
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth);
|
||||
if (!pPixmap)
|
||||
return NullPixmap;
|
||||
|
||||
if (!(*pScreen->ModifyPixmapHeader) (pPixmap, width, height, depth,
|
||||
BitsPerPixel(depth),
|
||||
PixmapBytePad(width, depth),
|
||||
(pointer) addr)) {
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
return NullPixmap;
|
||||
}
|
||||
return pPixmap;
|
||||
}
|
||||
|
||||
static int
|
||||
ProcShmCreatePixmap(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
PixmapPtr pMap;
|
||||
|
||||
DrawablePtr pDraw;
|
||||
|
||||
DepthPtr pDepth;
|
||||
|
||||
int i;
|
||||
|
||||
ShmDescPtr shmdesc;
|
||||
|
||||
REQUEST(xShmCreatePixmapReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
|
||||
client->errorValue = stuff->pid;
|
||||
if (!sharedPixmaps)
|
||||
return BadImplementation;
|
||||
LEGAL_NEW_RESOURCE(stuff->pid, client);
|
||||
VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
|
||||
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
|
||||
if (!stuff->width || !stuff->height) {
|
||||
client->errorValue = 0;
|
||||
return BadValue;
|
||||
}
|
||||
if (stuff->depth != 1) {
|
||||
pDepth = pDraw->pScreen->allowedDepths;
|
||||
for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++)
|
||||
if (pDepth->depth == stuff->depth)
|
||||
goto CreatePmap;
|
||||
client->errorValue = stuff->depth;
|
||||
return BadValue;
|
||||
}
|
||||
CreatePmap:
|
||||
VERIFY_SHMSIZE(shmdesc, stuff->offset,
|
||||
PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
|
||||
client);
|
||||
pMap =
|
||||
(*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap) (pDraw->pScreen,
|
||||
stuff->width,
|
||||
stuff->height,
|
||||
stuff->depth,
|
||||
shmdesc->addr +
|
||||
stuff->offset);
|
||||
if (pMap) {
|
||||
pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
|
||||
shmdesc->refcnt++;
|
||||
pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
pMap->drawable.id = stuff->pid;
|
||||
if (AddResource(stuff->pid, RT_PIXMAP, (pointer) pMap)) {
|
||||
return (client->noClientException);
|
||||
}
|
||||
}
|
||||
return (BadAlloc);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcShmDispatch(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xReq);
|
||||
switch (stuff->data) {
|
||||
case X_ShmQueryVersion:
|
||||
return ProcShmQueryVersion(client);
|
||||
case X_ShmAttach:
|
||||
return ProcShmAttach(client);
|
||||
case X_ShmDetach:
|
||||
return ProcShmDetach(client);
|
||||
case X_ShmPutImage:
|
||||
return ProcShmPutImage(client);
|
||||
case X_ShmGetImage:
|
||||
return ProcShmGetImage(client);
|
||||
case X_ShmCreatePixmap:
|
||||
return ProcShmCreatePixmap(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SShmCompletionEvent(from, to)
|
||||
xShmCompletionEvent *from, *to;
|
||||
{
|
||||
to->type = from->type;
|
||||
cpswaps(from->sequenceNumber, to->sequenceNumber);
|
||||
cpswapl(from->drawable, to->drawable);
|
||||
cpswaps(from->minorEvent, to->minorEvent);
|
||||
to->majorEvent = from->majorEvent;
|
||||
cpswapl(from->shmseg, to->shmseg);
|
||||
cpswapl(from->offset, to->offset);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcShmQueryVersion(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xShmQueryVersionReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
return ProcShmQueryVersion(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcShmAttach(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xShmAttachReq);
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xShmAttachReq);
|
||||
swapl(&stuff->shmseg);
|
||||
swapl(&stuff->shmid);
|
||||
return ProcShmAttach(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcShmDetach(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xShmDetachReq);
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xShmDetachReq);
|
||||
swapl(&stuff->shmseg);
|
||||
return ProcShmDetach(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcShmPutImage(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xShmPutImageReq);
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xShmPutImageReq);
|
||||
swapl(&stuff->drawable);
|
||||
swapl(&stuff->gc);
|
||||
swaps(&stuff->totalWidth);
|
||||
swaps(&stuff->totalHeight);
|
||||
swaps(&stuff->srcX);
|
||||
swaps(&stuff->srcY);
|
||||
swaps(&stuff->srcWidth);
|
||||
swaps(&stuff->srcHeight);
|
||||
swaps(&stuff->dstX);
|
||||
swaps(&stuff->dstY);
|
||||
swapl(&stuff->shmseg);
|
||||
swapl(&stuff->offset);
|
||||
return ProcShmPutImage(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcShmGetImage(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xShmGetImageReq);
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xShmGetImageReq);
|
||||
swapl(&stuff->drawable);
|
||||
swaps(&stuff->x);
|
||||
swaps(&stuff->y);
|
||||
swaps(&stuff->width);
|
||||
swaps(&stuff->height);
|
||||
swapl(&stuff->planeMask);
|
||||
swapl(&stuff->shmseg);
|
||||
swapl(&stuff->offset);
|
||||
return ProcShmGetImage(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcShmCreatePixmap(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xShmCreatePixmapReq);
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
|
||||
swapl(&stuff->pid);
|
||||
swapl(&stuff->drawable);
|
||||
swaps(&stuff->width);
|
||||
swaps(&stuff->height);
|
||||
swapl(&stuff->shmseg);
|
||||
swapl(&stuff->offset);
|
||||
return ProcShmCreatePixmap(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcShmDispatch(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xReq);
|
||||
switch (stuff->data) {
|
||||
case X_ShmQueryVersion:
|
||||
return SProcShmQueryVersion(client);
|
||||
case X_ShmAttach:
|
||||
return SProcShmAttach(client);
|
||||
case X_ShmDetach:
|
||||
return SProcShmDetach(client);
|
||||
case X_ShmPutImage:
|
||||
return SProcShmPutImage(client);
|
||||
case X_ShmGetImage:
|
||||
return SProcShmGetImage(client);
|
||||
case X_ShmCreatePixmap:
|
||||
return SProcShmCreatePixmap(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 2003 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _SHMINT_H_
|
||||
#define _SHMINT_H_
|
||||
|
||||
#define _XSHM_SERVER_
|
||||
#include <X11/extensions/shmstr.h>
|
||||
|
||||
#include "screenint.h"
|
||||
#include "pixmap.h"
|
||||
#include "gc.h"
|
||||
|
||||
void
|
||||
ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs);
|
||||
|
||||
void
|
||||
ShmSetPixmapFormat(ScreenPtr pScreen, int format);
|
||||
|
||||
void
|
||||
ShmRegisterFbFuncs(ScreenPtr pScreen);
|
||||
|
||||
#endif /* _SHMINT_H_ */
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
*
|
||||
Copyright 1992, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
*
|
||||
* Author: Keith Packard, MIT X Consortium
|
||||
*/
|
||||
|
||||
/* dixsleep.c - implement millisecond timeouts for X clients */
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "sleepuntil.h"
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include "misc.h"
|
||||
#include "windowstr.h"
|
||||
#include "dixstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "scrnintstr.h"
|
||||
|
||||
typedef struct _Sertafied {
|
||||
struct _Sertafied *next;
|
||||
TimeStamp revive;
|
||||
ClientPtr pClient;
|
||||
XID id;
|
||||
void (*notifyFunc) (ClientPtr /* client */ ,
|
||||
pointer /* closure */
|
||||
);
|
||||
|
||||
pointer closure;
|
||||
} SertafiedRec, *SertafiedPtr;
|
||||
|
||||
static SertafiedPtr pPending;
|
||||
|
||||
static RESTYPE SertafiedResType;
|
||||
|
||||
static Bool BlockHandlerRegistered;
|
||||
|
||||
static int SertafiedGeneration;
|
||||
|
||||
static void ClientAwaken(ClientPtr /* client */ ,
|
||||
pointer /* closure */
|
||||
);
|
||||
|
||||
static int SertafiedDelete(pointer /* value */ ,
|
||||
XID /* id */
|
||||
);
|
||||
|
||||
static void SertafiedBlockHandler(pointer /* data */ ,
|
||||
OSTimePtr /* wt */ ,
|
||||
pointer /* LastSelectMask */
|
||||
);
|
||||
|
||||
static void SertafiedWakeupHandler(pointer /* data */ ,
|
||||
int /* i */ ,
|
||||
pointer /* LastSelectMask */
|
||||
);
|
||||
|
||||
_X_EXPORT int
|
||||
ClientSleepUntil(client, revive, notifyFunc, closure)
|
||||
ClientPtr client;
|
||||
|
||||
TimeStamp *revive;
|
||||
|
||||
void (*notifyFunc) (ClientPtr /* client */ ,
|
||||
pointer /* closure */ );
|
||||
|
||||
pointer closure;
|
||||
{
|
||||
SertafiedPtr pRequest, pReq, pPrev;
|
||||
|
||||
if (SertafiedGeneration != serverGeneration) {
|
||||
SertafiedResType = CreateNewResourceType(SertafiedDelete);
|
||||
if (!SertafiedResType)
|
||||
return FALSE;
|
||||
SertafiedGeneration = serverGeneration;
|
||||
BlockHandlerRegistered = FALSE;
|
||||
}
|
||||
pRequest = malloc(sizeof(SertafiedRec));
|
||||
if (!pRequest)
|
||||
return FALSE;
|
||||
pRequest->pClient = client;
|
||||
pRequest->revive = *revive;
|
||||
pRequest->id = FakeClientID(client->index);
|
||||
pRequest->closure = closure;
|
||||
if (!BlockHandlerRegistered) {
|
||||
if (!RegisterBlockAndWakeupHandlers(SertafiedBlockHandler,
|
||||
SertafiedWakeupHandler,
|
||||
(pointer) 0)) {
|
||||
free(pRequest);
|
||||
return FALSE;
|
||||
}
|
||||
BlockHandlerRegistered = TRUE;
|
||||
}
|
||||
pRequest->notifyFunc = 0;
|
||||
if (!AddResource(pRequest->id, SertafiedResType, (pointer) pRequest))
|
||||
return FALSE;
|
||||
if (!notifyFunc)
|
||||
notifyFunc = ClientAwaken;
|
||||
pRequest->notifyFunc = notifyFunc;
|
||||
/* Insert into time-ordered queue, with earliest activation time coming first. */
|
||||
pPrev = 0;
|
||||
for (pReq = pPending; pReq; pReq = pReq->next) {
|
||||
if (CompareTimeStamps(pReq->revive, *revive) == LATER)
|
||||
break;
|
||||
pPrev = pReq;
|
||||
}
|
||||
if (pPrev)
|
||||
pPrev->next = pRequest;
|
||||
else
|
||||
pPending = pRequest;
|
||||
pRequest->next = pReq;
|
||||
IgnoreClient(client);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ClientAwaken(client, closure)
|
||||
ClientPtr client;
|
||||
|
||||
pointer closure;
|
||||
{
|
||||
if (!client->clientGone)
|
||||
AttendClient(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SertafiedDelete(value, id)
|
||||
pointer value;
|
||||
|
||||
XID id;
|
||||
{
|
||||
SertafiedPtr pRequest = (SertafiedPtr) value;
|
||||
|
||||
SertafiedPtr pReq, pPrev;
|
||||
|
||||
pPrev = 0;
|
||||
for (pReq = pPending; pReq; pPrev = pReq, pReq = pReq->next)
|
||||
if (pReq == pRequest) {
|
||||
if (pPrev)
|
||||
pPrev->next = pReq->next;
|
||||
else
|
||||
pPending = pReq->next;
|
||||
break;
|
||||
}
|
||||
if (pRequest->notifyFunc)
|
||||
(*pRequest->notifyFunc) (pRequest->pClient, pRequest->closure);
|
||||
free(pRequest);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
SertafiedBlockHandler(data, wt, LastSelectMask)
|
||||
pointer data; /* unused */
|
||||
|
||||
OSTimePtr wt; /* wait time */
|
||||
|
||||
pointer LastSelectMask;
|
||||
{
|
||||
SertafiedPtr pReq, pNext;
|
||||
|
||||
unsigned long delay;
|
||||
|
||||
TimeStamp now;
|
||||
|
||||
if (!pPending)
|
||||
return;
|
||||
now.milliseconds = GetTimeInMillis();
|
||||
now.months = currentTime.months;
|
||||
if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
|
||||
now.months++;
|
||||
for (pReq = pPending; pReq; pReq = pNext) {
|
||||
pNext = pReq->next;
|
||||
if (CompareTimeStamps(pReq->revive, now) == LATER)
|
||||
break;
|
||||
FreeResource(pReq->id, RT_NONE);
|
||||
|
||||
/* AttendClient() may have been called via the resource delete
|
||||
* function so a client may have input to be processed and so
|
||||
* set delay to 0 to prevent blocking in WaitForSomething().
|
||||
*/
|
||||
AdjustWaitForDelay(wt, 0);
|
||||
}
|
||||
pReq = pPending;
|
||||
if (!pReq)
|
||||
return;
|
||||
delay = pReq->revive.milliseconds - now.milliseconds;
|
||||
AdjustWaitForDelay(wt, delay);
|
||||
}
|
||||
|
||||
static void
|
||||
SertafiedWakeupHandler(data, i, LastSelectMask)
|
||||
pointer data;
|
||||
|
||||
int i;
|
||||
|
||||
pointer LastSelectMask;
|
||||
{
|
||||
SertafiedPtr pReq, pNext;
|
||||
|
||||
TimeStamp now;
|
||||
|
||||
now.milliseconds = GetTimeInMillis();
|
||||
now.months = currentTime.months;
|
||||
if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
|
||||
now.months++;
|
||||
for (pReq = pPending; pReq; pReq = pNext) {
|
||||
pNext = pReq->next;
|
||||
if (CompareTimeStamps(pReq->revive, now) == LATER)
|
||||
break;
|
||||
FreeResource(pReq->id, RT_NONE);
|
||||
}
|
||||
if (!pPending) {
|
||||
RemoveBlockAndWakeupHandlers(SertafiedBlockHandler,
|
||||
SertafiedWakeupHandler, (pointer) 0);
|
||||
BlockHandlerRegistered = FALSE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2001 The XFree86 Project, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XFREE86 PROJECT 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.
|
||||
*
|
||||
* Except as contained in this notice, the name of the XFree86 Project shall
|
||||
* not be used in advertising or otherwise to promote the sale, use or other
|
||||
* dealings in this Software without prior written authorization from the
|
||||
* XFree86 Project.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _SLEEPUNTIL_H_
|
||||
#define _SLEEPUNTIL_H_ 1
|
||||
|
||||
#include "dix.h"
|
||||
|
||||
extern int ClientSleepUntil(ClientPtr client,
|
||||
TimeStamp *revive,
|
||||
void (*notifyFunc) (ClientPtr /* client */ ,
|
||||
pointer /* closure */
|
||||
), pointer Closure);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
|
||||
Copyright 1993, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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 OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include "swaprep.h"
|
||||
#include <X11/extensions/xcmiscproto.h>
|
||||
#include "extinit.h"
|
||||
|
||||
#if 0
|
||||
static unsigned char XCMiscCode;
|
||||
#endif
|
||||
|
||||
static void XCMiscResetProc(ExtensionEntry * /* extEntry */
|
||||
);
|
||||
|
||||
static DISPATCH_PROC(ProcXCMiscDispatch);
|
||||
|
||||
static DISPATCH_PROC(ProcXCMiscGetVersion);
|
||||
|
||||
static DISPATCH_PROC(ProcXCMiscGetXIDList);
|
||||
|
||||
static DISPATCH_PROC(ProcXCMiscGetXIDRange);
|
||||
|
||||
static DISPATCH_PROC(SProcXCMiscDispatch);
|
||||
|
||||
static DISPATCH_PROC(SProcXCMiscGetVersion);
|
||||
|
||||
static DISPATCH_PROC(SProcXCMiscGetXIDList);
|
||||
|
||||
static DISPATCH_PROC(SProcXCMiscGetXIDRange);
|
||||
|
||||
void
|
||||
XCMiscExtensionInit(INITARGS)
|
||||
{
|
||||
#if 0
|
||||
ExtensionEntry *extEntry;
|
||||
|
||||
if ((extEntry = AddExtension(XCMiscExtensionName, 0, 0,
|
||||
ProcXCMiscDispatch, SProcXCMiscDispatch,
|
||||
XCMiscResetProc, StandardMinorOpcode)) != 0)
|
||||
XCMiscCode = (unsigned char) extEntry->base;
|
||||
#else
|
||||
(void) AddExtension(XCMiscExtensionName, 0, 0,
|
||||
ProcXCMiscDispatch, SProcXCMiscDispatch,
|
||||
XCMiscResetProc, StandardMinorOpcode);
|
||||
#endif
|
||||
|
||||
DeclareExtensionSecurity(XCMiscExtensionName, TRUE);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/ static void
|
||||
XCMiscResetProc(extEntry)
|
||||
ExtensionEntry *extEntry;
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXCMiscGetVersion(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
xXCMiscGetVersionReply rep;
|
||||
|
||||
|
||||
REQUEST_SIZE_MATCH(xXCMiscGetVersionReq);
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.majorVersion = XCMiscMajorVersion;
|
||||
rep.minorVersion = XCMiscMinorVersion;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swaps(&rep.majorVersion);
|
||||
swaps(&rep.minorVersion);
|
||||
}
|
||||
WriteToClient(client, sizeof(xXCMiscGetVersionReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXCMiscGetXIDRange(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
xXCMiscGetXIDRangeReply rep;
|
||||
|
||||
|
||||
XID min_id, max_id;
|
||||
|
||||
REQUEST_SIZE_MATCH(xXCMiscGetXIDRangeReq);
|
||||
GetXIDRange(client->index, FALSE, &min_id, &max_id);
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.start_id = min_id;
|
||||
rep.count = max_id - min_id + 1;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.start_id);
|
||||
swapl(&rep.count);
|
||||
}
|
||||
WriteToClient(client, sizeof(xXCMiscGetXIDRangeReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXCMiscGetXIDList(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xXCMiscGetXIDListReq);
|
||||
xXCMiscGetXIDListReply rep;
|
||||
|
||||
|
||||
XID *pids;
|
||||
|
||||
unsigned int count;
|
||||
|
||||
REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq);
|
||||
|
||||
pids = (XID *) ALLOCATE_LOCAL(stuff->count * sizeof(XID));
|
||||
if (!pids) {
|
||||
return BadAlloc;
|
||||
}
|
||||
count = GetXIDList(client, stuff->count, pids);
|
||||
rep.type = X_Reply;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = count;
|
||||
rep.count = count;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
swapl(&rep.count);
|
||||
}
|
||||
WriteToClient(client, sizeof(xXCMiscGetXIDListReply), (char *) &rep);
|
||||
if (count) {
|
||||
client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
|
||||
WriteSwappedDataToClient(client, count * sizeof(XID), pids);
|
||||
}
|
||||
DEALLOCATE_LOCAL(pids);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXCMiscDispatch(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xReq);
|
||||
switch (stuff->data) {
|
||||
case X_XCMiscGetVersion:
|
||||
return ProcXCMiscGetVersion(client);
|
||||
case X_XCMiscGetXIDRange:
|
||||
return ProcXCMiscGetXIDRange(client);
|
||||
case X_XCMiscGetXIDList:
|
||||
return ProcXCMiscGetXIDList(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXCMiscGetVersion(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xXCMiscGetVersionReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xXCMiscGetVersionReq);
|
||||
swaps(&stuff->majorVersion);
|
||||
swaps(&stuff->minorVersion);
|
||||
return ProcXCMiscGetVersion(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXCMiscGetXIDRange(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
return ProcXCMiscGetXIDRange(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXCMiscGetXIDList(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xXCMiscGetXIDListReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
swapl(&stuff->count);
|
||||
return ProcXCMiscGetXIDList(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXCMiscDispatch(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xReq);
|
||||
switch (stuff->data) {
|
||||
case X_XCMiscGetVersion:
|
||||
return SProcXCMiscGetVersion(client);
|
||||
case X_XCMiscGetXIDRange:
|
||||
return SProcXCMiscGetXIDRange(client);
|
||||
case X_XCMiscGetXIDList:
|
||||
return SProcXCMiscGetXIDList(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,779 @@
|
|||
/*
|
||||
* BIGFONT extension for sharing font metrics between clients (if possible)
|
||||
* and for transmitting font metrics to clients in a compressed form.
|
||||
*
|
||||
* Copyright (c) 1999-2000 Bruno Haible
|
||||
* Copyright (c) 1999-2000 The XFree86 Project, Inc.
|
||||
*/
|
||||
|
||||
/* THIS IS NOT AN X CONSORTIUM STANDARD */
|
||||
|
||||
/*
|
||||
* Big fonts suffer from the following: All clients that have opened a
|
||||
* font can access the complete glyph metrics array (the XFontStruct member
|
||||
* `per_char') directly, without going through a macro. Moreover these
|
||||
* glyph metrics are ink metrics, i.e. are not redundant even for a
|
||||
* fixed-width font. For a Unicode font, the size of this array is 768 KB.
|
||||
*
|
||||
* Problems: 1. It eats a lot of memory in each client. 2. All this glyph
|
||||
* metrics data is piped through the socket when the font is opened.
|
||||
*
|
||||
* This extension addresses these two problems for local clients, by using
|
||||
* shared memory. It also addresses the second problem for non-local clients,
|
||||
* by compressing the data before transmit by a factor of nearly 6.
|
||||
*
|
||||
* If you use this extension, your OS ought to nicely support shared memory.
|
||||
* This means: Shared memory should be swappable to the swap, and the limits
|
||||
* should be high enough (SHMMNI at least 64, SHMMAX at least 768 KB,
|
||||
* SHMALL at least 48 MB). It is a plus if your OS allows shmat() calls
|
||||
* on segments that have already been marked "removed", because it permits
|
||||
* these segments to be cleaned up by the OS if the X server is killed with
|
||||
* signal SIGKILL.
|
||||
*
|
||||
* This extension is transparently exploited by Xlib (functions XQueryFont,
|
||||
* XLoadQueryFont).
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(linux) && (!defined(__GNU_LIBRARY__) || __GNU_LIBRARY__ < 2)
|
||||
/* libc4 does not define __GNU_LIBRARY__, libc5 defines __GNU_LIBRARY__ as 1 */
|
||||
/* Linux libc4 and libc5 only (because glibc doesn't include kernel headers):
|
||||
Linux 2.0.x and 2.2.x define SHMLBA as PAGE_SIZE, but forget to define
|
||||
PAGE_SIZE. It is defined in <asm/page.h>. */
|
||||
#include <asm/page.h>
|
||||
#endif
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
#include "gcstruct.h"
|
||||
#include "dixfontstr.h"
|
||||
#include "extnsionst.h"
|
||||
|
||||
#define _XF86BIGFONT_SERVER_
|
||||
#include <X11/extensions/xf86bigfproto.h>
|
||||
|
||||
static void XF86BigfontResetProc(ExtensionEntry * /* extEntry */
|
||||
);
|
||||
|
||||
static DISPATCH_PROC(ProcXF86BigfontDispatch);
|
||||
|
||||
static DISPATCH_PROC(ProcXF86BigfontQueryVersion);
|
||||
|
||||
static DISPATCH_PROC(ProcXF86BigfontQueryFont);
|
||||
|
||||
static DISPATCH_PROC(SProcXF86BigfontDispatch);
|
||||
|
||||
static DISPATCH_PROC(SProcXF86BigfontQueryVersion);
|
||||
|
||||
static DISPATCH_PROC(SProcXF86BigfontQueryFont);
|
||||
|
||||
#if 0
|
||||
static unsigned char XF86BigfontReqCode;
|
||||
#endif
|
||||
|
||||
|
||||
/* A random signature, transmitted to the clients so they can verify that the
|
||||
shared memory segment they are attaching to was really established by the
|
||||
X server they are talking to. */
|
||||
static CARD32 signature;
|
||||
|
||||
/* Index for additional information stored in a FontRec's devPrivates array. */
|
||||
static int FontShmdescIndex;
|
||||
|
||||
static unsigned int pagesize;
|
||||
|
||||
static Bool badSysCall = FALSE;
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
|
||||
|
||||
#include <sys/signal.h>
|
||||
|
||||
static void
|
||||
SigSysHandler(int signo)
|
||||
{
|
||||
badSysCall = TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
CheckForShmSyscall(void)
|
||||
{
|
||||
void (*oldHandler) (int);
|
||||
|
||||
int shmid = -1;
|
||||
|
||||
/* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
|
||||
oldHandler = signal(SIGSYS, SigSysHandler);
|
||||
|
||||
badSysCall = FALSE;
|
||||
shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
|
||||
if (shmid != -1) {
|
||||
/* Successful allocation - clean up */
|
||||
shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL);
|
||||
}
|
||||
else {
|
||||
/* Allocation failed */
|
||||
badSysCall = TRUE;
|
||||
}
|
||||
signal(SIGSYS, oldHandler);
|
||||
return (!badSysCall);
|
||||
}
|
||||
|
||||
#define MUST_CHECK_FOR_SHM_SYSCALL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
XFree86BigfontExtensionInit()
|
||||
{
|
||||
#if 0
|
||||
ExtensionEntry *extEntry;
|
||||
|
||||
if ((extEntry = AddExtension(XF86BIGFONTNAME,
|
||||
XF86BigfontNumberEvents,
|
||||
XF86BigfontNumberErrors,
|
||||
ProcXF86BigfontDispatch,
|
||||
SProcXF86BigfontDispatch,
|
||||
XF86BigfontResetProc, StandardMinorOpcode))) {
|
||||
XF86BigfontReqCode = (unsigned char) extEntry->base;
|
||||
#else
|
||||
if (AddExtension(XF86BIGFONTNAME,
|
||||
XF86BigfontNumberEvents,
|
||||
XF86BigfontNumberErrors,
|
||||
ProcXF86BigfontDispatch,
|
||||
SProcXF86BigfontDispatch,
|
||||
XF86BigfontResetProc, StandardMinorOpcode)) {
|
||||
#endif
|
||||
#ifdef MUST_CHECK_FOR_SHM_SYSCALL
|
||||
/*
|
||||
* Note: Local-clients will not be optimized without shared memory
|
||||
* support. Remote-client optimization does not depend on shared
|
||||
* memory support. Thus, the extension is still registered even
|
||||
* when shared memory support is not functional.
|
||||
*/
|
||||
if (!CheckForShmSyscall()) {
|
||||
ErrorF(XF86BIGFONTNAME
|
||||
" extension local-client optimization disabled due to lack of shared memory support in the kernel\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
srand((unsigned int) time(NULL));
|
||||
signature = ((unsigned int) (65536.0 / (RAND_MAX + 1.0) * rand()) << 16)
|
||||
+ (unsigned int) (65536.0 / (RAND_MAX + 1.0) * rand());
|
||||
/* fprintf(stderr, "signature = 0x%08X\n", signature); */
|
||||
|
||||
FontShmdescIndex = AllocateFontPrivateIndex();
|
||||
|
||||
#if !defined(CSRG_BASED) && !defined(__CYGWIN__)
|
||||
pagesize = SHMLBA;
|
||||
#else
|
||||
# ifdef _SC_PAGESIZE
|
||||
pagesize = sysconf(_SC_PAGESIZE);
|
||||
# else
|
||||
pagesize = getpagesize();
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== Management of shared memory segments ========== */
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
/* On Linux, shared memory marked as "removed" can still be attached.
|
||||
Nice feature, because the kernel will automatically free the associated
|
||||
storage when the server and all clients are gone. */
|
||||
#define EARLY_REMOVE
|
||||
#endif
|
||||
|
||||
typedef struct _ShmDesc {
|
||||
struct _ShmDesc *next;
|
||||
struct _ShmDesc **prev;
|
||||
int shmid;
|
||||
char *attach_addr;
|
||||
} ShmDescRec, *ShmDescPtr;
|
||||
|
||||
static ShmDescPtr ShmList = (ShmDescPtr) NULL;
|
||||
|
||||
static ShmDescPtr
|
||||
shmalloc(unsigned int size)
|
||||
{
|
||||
ShmDescPtr pDesc;
|
||||
|
||||
int shmid;
|
||||
|
||||
char *addr;
|
||||
|
||||
#ifdef MUST_CHECK_FOR_SHM_SYSCALL
|
||||
if (pagesize == 0)
|
||||
return (ShmDescPtr) NULL;
|
||||
#endif
|
||||
|
||||
/* On some older Linux systems, the number of shared memory segments
|
||||
system-wide is 127. In Linux 2.4, it is 4095.
|
||||
Therefore there is a tradeoff to be made between allocating a
|
||||
shared memory segment on one hand, and allocating memory and piping
|
||||
the glyph metrics on the other hand. If the glyph metrics size is
|
||||
small, we prefer the traditional way. */
|
||||
if (size < 3500)
|
||||
return (ShmDescPtr) NULL;
|
||||
|
||||
pDesc = malloc(sizeof(ShmDescRec));
|
||||
if (!pDesc)
|
||||
return (ShmDescPtr) NULL;
|
||||
|
||||
size = (size + pagesize - 1) & -pagesize;
|
||||
shmid = shmget(IPC_PRIVATE, size, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
|
||||
if (shmid == -1) {
|
||||
ErrorF(XF86BIGFONTNAME
|
||||
" extension: shmget() failed, size = %u, errno = %d\n", size,
|
||||
errno);
|
||||
free(pDesc);
|
||||
return (ShmDescPtr) NULL;
|
||||
}
|
||||
|
||||
if ((addr = shmat(shmid, 0, 0)) == (char *) -1) {
|
||||
ErrorF(XF86BIGFONTNAME
|
||||
" extension: shmat() failed, size = %u, errno = %d\n", size,
|
||||
errno);
|
||||
shmctl(shmid, IPC_RMID, (void *) 0);
|
||||
free(pDesc);
|
||||
return (ShmDescPtr) NULL;
|
||||
}
|
||||
|
||||
#ifdef EARLY_REMOVE
|
||||
shmctl(shmid, IPC_RMID, (void *) 0);
|
||||
#endif
|
||||
|
||||
pDesc->shmid = shmid;
|
||||
pDesc->attach_addr = addr;
|
||||
if (ShmList)
|
||||
ShmList->prev = &pDesc->next;
|
||||
pDesc->next = ShmList;
|
||||
pDesc->prev = &ShmList;
|
||||
ShmList = pDesc;
|
||||
|
||||
return pDesc;
|
||||
}
|
||||
|
||||
static void
|
||||
shmdealloc(ShmDescPtr pDesc)
|
||||
{
|
||||
#ifndef EARLY_REMOVE
|
||||
shmctl(pDesc->shmid, IPC_RMID, (void *) 0);
|
||||
#endif
|
||||
shmdt(pDesc->attach_addr);
|
||||
|
||||
if (pDesc->next)
|
||||
pDesc->next->prev = pDesc->prev;
|
||||
*pDesc->prev = pDesc->next;
|
||||
free(pDesc);
|
||||
}
|
||||
|
||||
|
||||
/* Called when a font is closed. */
|
||||
void
|
||||
XF86BigfontFreeFontShm(FontPtr pFont)
|
||||
{
|
||||
ShmDescPtr pDesc;
|
||||
|
||||
/* If during shutdown of the server, XF86BigfontCleanup() has already
|
||||
* called shmdealloc() for all segments, we don't need to do it here.
|
||||
*/
|
||||
if (!ShmList)
|
||||
return;
|
||||
|
||||
pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex);
|
||||
if (pDesc)
|
||||
shmdealloc(pDesc);
|
||||
}
|
||||
|
||||
/* Called upon fatal signal. */
|
||||
void
|
||||
XF86BigfontCleanup()
|
||||
{
|
||||
while (ShmList)
|
||||
shmdealloc(ShmList);
|
||||
}
|
||||
|
||||
/* Called when a server generation dies. */
|
||||
static void
|
||||
XF86BigfontResetProc(ExtensionEntry * extEntry)
|
||||
{
|
||||
/* This function is normally called from CloseDownExtensions(), called
|
||||
* from main(). It will be followed by a call to FreeAllResources(),
|
||||
* which will call XF86BigfontFreeFontShm() for each font. Thus it
|
||||
* appears that we do not need to do anything in this function. --
|
||||
* But I prefer to write robust code, and not keep shared memory lying
|
||||
* around when it's not needed any more. (Someone might close down the
|
||||
* extension without calling FreeAllResources()...)
|
||||
*/
|
||||
XF86BigfontCleanup();
|
||||
}
|
||||
|
||||
/* ========== Handling of extension specific requests ========== */
|
||||
|
||||
static int
|
||||
ProcXF86BigfontQueryVersion(ClientPtr client)
|
||||
{
|
||||
xXF86BigfontQueryVersionReply reply = {0};
|
||||
|
||||
REQUEST_SIZE_MATCH(xXF86BigfontQueryVersionReq);
|
||||
reply.type = X_Reply;
|
||||
reply.length = 0;
|
||||
reply.sequenceNumber = client->sequence;
|
||||
reply.majorVersion = XF86BIGFONT_MAJOR_VERSION;
|
||||
reply.minorVersion = XF86BIGFONT_MINOR_VERSION;
|
||||
reply.uid = geteuid();
|
||||
reply.gid = getegid();
|
||||
reply.signature = signature;
|
||||
reply.capabilities =
|
||||
(LocalClient(client) && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0)
|
||||
; /* may add more bits here in future versions */
|
||||
if (client->swapped) {
|
||||
swaps(&reply.sequenceNumber);
|
||||
swapl(&reply.length);
|
||||
swaps(&reply.majorVersion);
|
||||
swaps(&reply.minorVersion);
|
||||
swapl(&reply.uid);
|
||||
swapl(&reply.gid);
|
||||
swapl(&reply.signature);
|
||||
}
|
||||
WriteToClient(client,
|
||||
sizeof(xXF86BigfontQueryVersionReply), (char *) &reply);
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
static void
|
||||
swapCharInfo(xCharInfo * pCI)
|
||||
{
|
||||
swaps(&pCI->leftSideBearing);
|
||||
swaps(&pCI->rightSideBearing);
|
||||
swaps(&pCI->characterWidth);
|
||||
swaps(&pCI->ascent);
|
||||
swaps(&pCI->descent);
|
||||
swaps(&pCI->attributes);
|
||||
}
|
||||
|
||||
/* static CARD32 hashCI (xCharInfo *p); */
|
||||
#define hashCI(p) \
|
||||
(CARD32)(((p->leftSideBearing << 27) + (p->leftSideBearing >> 5) + \
|
||||
(p->rightSideBearing << 23) + (p->rightSideBearing >> 9) + \
|
||||
(p->characterWidth << 16) + \
|
||||
(p->ascent << 11) + (p->descent << 6)) ^ p->attributes)
|
||||
|
||||
static int
|
||||
ProcXF86BigfontQueryFont(ClientPtr client)
|
||||
{
|
||||
FontPtr pFont;
|
||||
|
||||
REQUEST(xXF86BigfontQueryFontReq);
|
||||
CARD32 stuff_flags;
|
||||
|
||||
xCharInfo *pmax;
|
||||
|
||||
xCharInfo *pmin;
|
||||
|
||||
int nCharInfos;
|
||||
|
||||
int shmid;
|
||||
|
||||
ShmDescPtr pDesc;
|
||||
xCharInfo *pCI;
|
||||
|
||||
CARD16 *pIndex2UniqIndex;
|
||||
|
||||
CARD16 *pUniqIndex2Index;
|
||||
|
||||
CARD32 nUniqCharInfos;
|
||||
|
||||
#if 0
|
||||
REQUEST_SIZE_MATCH(xXF86BigfontQueryFontReq);
|
||||
#else
|
||||
switch (client->req_len) {
|
||||
case 2: /* client with version 1.0 libX11 */
|
||||
stuff_flags = (LocalClient(client) &&
|
||||
!client->swapped ? XF86Bigfont_FLAGS_Shm : 0);
|
||||
break;
|
||||
case 3: /* client with version 1.1 libX11 */
|
||||
stuff_flags = stuff->flags;
|
||||
break;
|
||||
default:
|
||||
return BadLength;
|
||||
}
|
||||
#endif
|
||||
client->errorValue = stuff->id; /* EITHER font or gc */
|
||||
pFont = (FontPtr) SecurityLookupIDByType(client, stuff->id, RT_FONT,
|
||||
SecurityReadAccess);
|
||||
if (!pFont) {
|
||||
/* can't use VERIFY_GC because it might return BadGC */
|
||||
GC *pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
|
||||
SecurityReadAccess);
|
||||
|
||||
if (!pGC) {
|
||||
client->errorValue = stuff->id;
|
||||
return BadFont; /* procotol spec says only error is BadFont */
|
||||
}
|
||||
pFont = pGC->font;
|
||||
}
|
||||
|
||||
pmax = FONTINKMAX(pFont);
|
||||
pmin = FONTINKMIN(pFont);
|
||||
nCharInfos =
|
||||
(pmax->rightSideBearing == pmin->rightSideBearing
|
||||
&& pmax->leftSideBearing == pmin->leftSideBearing
|
||||
&& pmax->descent == pmin->descent
|
||||
&& pmax->ascent == pmin->ascent
|
||||
&& pmax->characterWidth == pmin->characterWidth)
|
||||
? 0 : N2dChars(pFont);
|
||||
shmid = -1;
|
||||
pCI = NULL;
|
||||
pIndex2UniqIndex = NULL;
|
||||
pUniqIndex2Index = NULL;
|
||||
nUniqCharInfos = 0;
|
||||
|
||||
if (nCharInfos > 0) {
|
||||
if (!badSysCall)
|
||||
pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex);
|
||||
else
|
||||
pDesc = NULL;
|
||||
if (pDesc) {
|
||||
pCI = (xCharInfo *) pDesc->attach_addr;
|
||||
if (stuff_flags & XF86Bigfont_FLAGS_Shm)
|
||||
shmid = pDesc->shmid;
|
||||
}
|
||||
else {
|
||||
if (stuff_flags & XF86Bigfont_FLAGS_Shm && !badSysCall)
|
||||
pDesc = shmalloc(nCharInfos * sizeof(xCharInfo)
|
||||
+ sizeof(CARD32));
|
||||
if (pDesc) {
|
||||
pCI = (xCharInfo *) pDesc->attach_addr;
|
||||
shmid = pDesc->shmid;
|
||||
}
|
||||
else {
|
||||
pCI = (xCharInfo *)
|
||||
ALLOCATE_LOCAL(nCharInfos * sizeof(xCharInfo));
|
||||
if (!pCI)
|
||||
return BadAlloc;
|
||||
}
|
||||
/* Fill nCharInfos starting at pCI. */
|
||||
{
|
||||
xCharInfo *prCI = pCI;
|
||||
|
||||
int ninfos = 0;
|
||||
|
||||
int ncols = pFont->info.lastCol - pFont->info.firstCol + 1;
|
||||
|
||||
int row;
|
||||
|
||||
for (row = pFont->info.firstRow;
|
||||
row <= pFont->info.lastRow && ninfos < nCharInfos; row++) {
|
||||
unsigned char chars[512];
|
||||
|
||||
xCharInfo *tmpCharInfos[256];
|
||||
|
||||
unsigned long count;
|
||||
|
||||
int col;
|
||||
|
||||
unsigned long i;
|
||||
|
||||
i = 0;
|
||||
for (col = pFont->info.firstCol;
|
||||
col <= pFont->info.lastCol; col++) {
|
||||
chars[i++] = row;
|
||||
chars[i++] = col;
|
||||
}
|
||||
(*pFont->get_metrics) (pFont, ncols, chars, TwoD16Bit,
|
||||
&count, tmpCharInfos);
|
||||
for (i = 0; i < count && ninfos < nCharInfos; i++) {
|
||||
*prCI++ = *tmpCharInfos[i];
|
||||
ninfos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pDesc && !badSysCall) {
|
||||
*(CARD32 *) (pCI + nCharInfos) = signature;
|
||||
if (!FontSetPrivate(pFont, FontShmdescIndex, pDesc)) {
|
||||
shmdealloc(pDesc);
|
||||
return BadAlloc;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shmid == -1) {
|
||||
/* Cannot use shared memory, so remove-duplicates the xCharInfos
|
||||
using a temporary hash table. */
|
||||
/* Note that CARD16 is suitable as index type, because
|
||||
nCharInfos <= 0x10000. */
|
||||
CARD32 hashModulus;
|
||||
|
||||
CARD16 *pHash2UniqIndex;
|
||||
|
||||
CARD16 *pUniqIndex2NextUniqIndex;
|
||||
|
||||
CARD32 NextIndex;
|
||||
|
||||
CARD32 NextUniqIndex;
|
||||
|
||||
CARD16 *tmp;
|
||||
|
||||
CARD32 i, j;
|
||||
|
||||
hashModulus = 67;
|
||||
if (hashModulus > nCharInfos + 1)
|
||||
hashModulus = nCharInfos + 1;
|
||||
|
||||
tmp = (CARD16 *)
|
||||
ALLOCATE_LOCAL((4 * nCharInfos + 1) * sizeof(CARD16));
|
||||
if (!tmp) {
|
||||
if (!pDesc)
|
||||
DEALLOCATE_LOCAL(pCI);
|
||||
return BadAlloc;
|
||||
}
|
||||
pIndex2UniqIndex = tmp;
|
||||
/* nCharInfos elements */
|
||||
pUniqIndex2Index = tmp + nCharInfos;
|
||||
/* max. nCharInfos elements */
|
||||
pUniqIndex2NextUniqIndex = tmp + 2 * nCharInfos;
|
||||
/* max. nCharInfos elements */
|
||||
pHash2UniqIndex = tmp + 3 * nCharInfos;
|
||||
/* hashModulus (<= nCharInfos+1) elements */
|
||||
|
||||
/* Note that we can use 0xffff as end-of-list indicator, because
|
||||
even if nCharInfos = 0x10000, 0xffff can not occur as valid
|
||||
entry before the last element has been inserted. And once the
|
||||
last element has been inserted, we don't need the hash table
|
||||
any more. */
|
||||
for (j = 0; j < hashModulus; j++)
|
||||
pHash2UniqIndex[j] = (CARD16) (-1);
|
||||
|
||||
NextUniqIndex = 0;
|
||||
for (NextIndex = 0; NextIndex < nCharInfos; NextIndex++) {
|
||||
xCharInfo *p = &pCI[NextIndex];
|
||||
|
||||
CARD32 hashCode = hashCI(p) % hashModulus;
|
||||
|
||||
for (i = pHash2UniqIndex[hashCode];
|
||||
i != (CARD16) (-1); i = pUniqIndex2NextUniqIndex[i]) {
|
||||
j = pUniqIndex2Index[i];
|
||||
if (pCI[j].leftSideBearing == p->leftSideBearing
|
||||
&& pCI[j].rightSideBearing == p->rightSideBearing
|
||||
&& pCI[j].characterWidth == p->characterWidth
|
||||
&& pCI[j].ascent == p->ascent
|
||||
&& pCI[j].descent == p->descent
|
||||
&& pCI[j].attributes == p->attributes)
|
||||
break;
|
||||
}
|
||||
if (i != (CARD16) (-1)) {
|
||||
/* Found *p at Index j, UniqIndex i */
|
||||
pIndex2UniqIndex[NextIndex] = i;
|
||||
}
|
||||
else {
|
||||
/* Allocate a new entry in the Uniq table */
|
||||
if (hashModulus <= 2 * NextUniqIndex
|
||||
&& hashModulus < nCharInfos + 1) {
|
||||
/* Time to increate hash table size */
|
||||
hashModulus = 2 * hashModulus + 1;
|
||||
if (hashModulus > nCharInfos + 1)
|
||||
hashModulus = nCharInfos + 1;
|
||||
for (j = 0; j < hashModulus; j++)
|
||||
pHash2UniqIndex[j] = (CARD16) (-1);
|
||||
for (i = 0; i < NextUniqIndex; i++)
|
||||
pUniqIndex2NextUniqIndex[i] = (CARD16) (-1);
|
||||
for (i = 0; i < NextUniqIndex; i++) {
|
||||
j = pUniqIndex2Index[i];
|
||||
p = &pCI[j];
|
||||
hashCode = hashCI(p) % hashModulus;
|
||||
pUniqIndex2NextUniqIndex[i] =
|
||||
pHash2UniqIndex[hashCode];
|
||||
pHash2UniqIndex[hashCode] = i;
|
||||
}
|
||||
p = &pCI[NextIndex];
|
||||
hashCode = hashCI(p) % hashModulus;
|
||||
}
|
||||
i = NextUniqIndex++;
|
||||
pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode];
|
||||
pHash2UniqIndex[hashCode] = i;
|
||||
pUniqIndex2Index[i] = NextIndex;
|
||||
pIndex2UniqIndex[NextIndex] = i;
|
||||
}
|
||||
}
|
||||
nUniqCharInfos = NextUniqIndex;
|
||||
/* fprintf(stderr, "font metrics: nCharInfos = %d, nUniqCharInfos = %d, hashModulus = %d\n", nCharInfos, nUniqCharInfos, hashModulus); */
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int nfontprops = pFont->info.nprops;
|
||||
|
||||
int rlength = sizeof(xXF86BigfontQueryFontReply)
|
||||
+ nfontprops * sizeof(xFontProp)
|
||||
+ (nCharInfos > 0 && shmid == -1
|
||||
? nUniqCharInfos * sizeof(xCharInfo)
|
||||
+ (nCharInfos + 1) / 2 * 2 * sizeof(CARD16)
|
||||
: 0);
|
||||
|
||||
xXF86BigfontQueryFontReply *reply =
|
||||
(xXF86BigfontQueryFontReply *) ALLOCATE_LOCAL(rlength);
|
||||
char *p;
|
||||
|
||||
if (!reply) {
|
||||
if (nCharInfos > 0) {
|
||||
if (shmid == -1)
|
||||
DEALLOCATE_LOCAL(pIndex2UniqIndex);
|
||||
if (!pDesc)
|
||||
DEALLOCATE_LOCAL(pCI);
|
||||
}
|
||||
return BadAlloc;
|
||||
}
|
||||
memset(reply, 0, rlength);
|
||||
|
||||
reply->type = X_Reply;
|
||||
reply->length = (rlength - sizeof(xGenericReply)) >> 2;
|
||||
reply->sequenceNumber = client->sequence;
|
||||
reply->minBounds = pFont->info.ink_minbounds;
|
||||
reply->maxBounds = pFont->info.ink_maxbounds;
|
||||
reply->minCharOrByte2 = pFont->info.firstCol;
|
||||
reply->maxCharOrByte2 = pFont->info.lastCol;
|
||||
reply->defaultChar = pFont->info.defaultCh;
|
||||
reply->nFontProps = pFont->info.nprops;
|
||||
reply->drawDirection = pFont->info.drawDirection;
|
||||
reply->minByte1 = pFont->info.firstRow;
|
||||
reply->maxByte1 = pFont->info.lastRow;
|
||||
reply->allCharsExist = pFont->info.allExist;
|
||||
reply->fontAscent = pFont->info.fontAscent;
|
||||
reply->fontDescent = pFont->info.fontDescent;
|
||||
reply->nCharInfos = nCharInfos;
|
||||
reply->nUniqCharInfos = nUniqCharInfos;
|
||||
reply->shmid = shmid;
|
||||
reply->shmsegoffset = 0;
|
||||
if (client->swapped) {
|
||||
swaps(&reply->sequenceNumber);
|
||||
swapl(&reply->length);
|
||||
swapCharInfo(&reply->minBounds);
|
||||
swapCharInfo(&reply->maxBounds);
|
||||
swaps(&reply->minCharOrByte2);
|
||||
swaps(&reply->maxCharOrByte2);
|
||||
swaps(&reply->defaultChar);
|
||||
swaps(&reply->nFontProps);
|
||||
swaps(&reply->fontAscent);
|
||||
swaps(&reply->fontDescent);
|
||||
swapl(&reply->nCharInfos);
|
||||
swapl(&reply->nUniqCharInfos);
|
||||
swapl(&reply->shmid);
|
||||
swapl(&reply->shmsegoffset);
|
||||
}
|
||||
p = (char *) &reply[1];
|
||||
{
|
||||
FontPropPtr pFP;
|
||||
|
||||
xFontProp *prFP;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) p;
|
||||
i < nfontprops; i++, pFP++, prFP++) {
|
||||
prFP->name = pFP->name;
|
||||
prFP->value = pFP->value;
|
||||
if (client->swapped) {
|
||||
swapl(&prFP->name);
|
||||
swapl(&prFP->value);
|
||||
}
|
||||
}
|
||||
p = (char *) prFP;
|
||||
}
|
||||
if (nCharInfos > 0 && shmid == -1) {
|
||||
xCharInfo *pci;
|
||||
|
||||
CARD16 *ps;
|
||||
|
||||
int i, j;
|
||||
|
||||
pci = (xCharInfo *) p;
|
||||
for (i = 0; i < nUniqCharInfos; i++, pci++) {
|
||||
*pci = pCI[pUniqIndex2Index[i]];
|
||||
if (client->swapped)
|
||||
swapCharInfo(pci);
|
||||
}
|
||||
ps = (CARD16 *) pci;
|
||||
for (j = 0; j < nCharInfos; j++, ps++) {
|
||||
*ps = pIndex2UniqIndex[j];
|
||||
if (client->swapped) {
|
||||
swaps(ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
WriteToClient(client, rlength, (char *) reply);
|
||||
DEALLOCATE_LOCAL(reply);
|
||||
if (nCharInfos > 0) {
|
||||
if (shmid == -1)
|
||||
DEALLOCATE_LOCAL(pIndex2UniqIndex);
|
||||
if (!pDesc)
|
||||
DEALLOCATE_LOCAL(pCI);
|
||||
}
|
||||
return (client->noClientException);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXF86BigfontDispatch(ClientPtr client)
|
||||
{
|
||||
REQUEST(xReq);
|
||||
|
||||
switch (stuff->data) {
|
||||
case X_XF86BigfontQueryVersion:
|
||||
return ProcXF86BigfontQueryVersion(client);
|
||||
case X_XF86BigfontQueryFont:
|
||||
return ProcXF86BigfontQueryFont(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXF86BigfontQueryVersion(ClientPtr client)
|
||||
{
|
||||
REQUEST(xXF86BigfontQueryVersionReq);
|
||||
swaps(&stuff->length);
|
||||
return ProcXF86BigfontQueryVersion(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXF86BigfontQueryFont(ClientPtr client)
|
||||
{
|
||||
REQUEST(xXF86BigfontQueryFontReq);
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xXF86BigfontQueryFontReq);
|
||||
swapl(&stuff->id);
|
||||
return ProcXF86BigfontQueryFont(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXF86BigfontDispatch(ClientPtr client)
|
||||
{
|
||||
REQUEST(xReq);
|
||||
|
||||
switch (stuff->data) {
|
||||
case X_XF86BigfontQueryVersion:
|
||||
return SProcXF86BigfontQueryVersion(client);
|
||||
case X_XF86BigfontQueryFont:
|
||||
return SProcXF86BigfontQueryFont(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright © 2010 Yaakov Selkowitz
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _XF86BIGFONTSRV_H_
|
||||
#define _XF86BIGFONTSRV_H_
|
||||
|
||||
#include <X11/fonts/font.h>
|
||||
|
||||
extern void XF86BigfontFreeFontShm(FontPtr);
|
||||
extern void XF86BigfontCleanup(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,392 @@
|
|||
/*
|
||||
Copyright (c) 2002 XFree86 Inc
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include "swaprep.h"
|
||||
#include <X11/extensions/XResproto.h>
|
||||
#include "pixmapstr.h"
|
||||
#include "windowstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "extinit.h"
|
||||
|
||||
static int
|
||||
ProcXResQueryVersion(ClientPtr client)
|
||||
{
|
||||
xXResQueryVersionReply rep;
|
||||
|
||||
REQUEST_SIZE_MATCH(xXResQueryVersionReq);
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.server_major = XRES_MAJOR_VERSION;
|
||||
rep.server_minor = XRES_MINOR_VERSION;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
swaps(&rep.server_major);
|
||||
swaps(&rep.server_minor);
|
||||
}
|
||||
WriteToClient(client, sizeof(xXResQueryVersionReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXResQueryClients(ClientPtr client)
|
||||
{
|
||||
/* REQUEST(xXResQueryClientsReq); */
|
||||
xXResQueryClientsReply rep;
|
||||
|
||||
int *current_clients;
|
||||
|
||||
int i, num_clients;
|
||||
|
||||
REQUEST_SIZE_MATCH(xXResQueryClientsReq);
|
||||
|
||||
current_clients = ALLOCATE_LOCAL((currentMaxClients - 1) * sizeof(int));
|
||||
|
||||
num_clients = 0;
|
||||
for (i = 1; i < currentMaxClients; i++) {
|
||||
if (clients[i]) {
|
||||
current_clients[num_clients] = i;
|
||||
num_clients++;
|
||||
}
|
||||
}
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.num_clients = num_clients;
|
||||
rep.length = rep.num_clients * sz_xXResClient >> 2;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
swapl(&rep.num_clients);
|
||||
}
|
||||
WriteToClient(client, sizeof(xXResQueryClientsReply), (char *) &rep);
|
||||
|
||||
if (num_clients) {
|
||||
xXResClient scratch;
|
||||
|
||||
for (i = 0; i < num_clients; i++) {
|
||||
scratch.resource_base = clients[current_clients[i]]->clientAsMask;
|
||||
scratch.resource_mask = RESOURCE_ID_MASK;
|
||||
|
||||
if (client->swapped) {
|
||||
|
||||
swapl(&scratch.resource_base);
|
||||
swapl(&scratch.resource_mask);
|
||||
}
|
||||
WriteToClient(client, sz_xXResClient, (char *) &scratch);
|
||||
}
|
||||
}
|
||||
|
||||
DEALLOCATE_LOCAL(current_clients);
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static void
|
||||
ResFindAllRes(pointer value, XID id, RESTYPE type, pointer cdata)
|
||||
{
|
||||
int *counts = (int *) cdata;
|
||||
|
||||
counts[(type & TypeMask) - 1]++;
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXResQueryClientResources(ClientPtr client)
|
||||
{
|
||||
REQUEST(xXResQueryClientResourcesReq);
|
||||
xXResQueryClientResourcesReply rep;
|
||||
|
||||
int i, clientID, num_types;
|
||||
|
||||
int *counts;
|
||||
|
||||
REQUEST_SIZE_MATCH(xXResQueryClientResourcesReq);
|
||||
|
||||
clientID = CLIENT_ID(stuff->xid);
|
||||
|
||||
/* we could remove the (clientID == 0) check if we wanted to allow
|
||||
probing the X-server's resource usage */
|
||||
if (!clientID || (clientID >= currentMaxClients) || !clients[clientID]) {
|
||||
client->errorValue = stuff->xid;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
counts = ALLOCATE_LOCAL((lastResourceType + 1) * sizeof(int));
|
||||
|
||||
memset(counts, 0, (lastResourceType + 1) * sizeof(int));
|
||||
|
||||
FindAllClientResources(clients[clientID], ResFindAllRes, counts);
|
||||
|
||||
num_types = 0;
|
||||
|
||||
for (i = 0; i <= lastResourceType; i++) {
|
||||
if (counts[i])
|
||||
num_types++;
|
||||
}
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.num_types = num_types;
|
||||
rep.length = rep.num_types * sz_xXResType >> 2;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
swapl(&rep.num_types);
|
||||
}
|
||||
|
||||
WriteToClient(client, sizeof(xXResQueryClientResourcesReply),
|
||||
(char *) &rep);
|
||||
|
||||
if (num_types) {
|
||||
xXResType scratch;
|
||||
|
||||
for (i = 0; i < lastResourceType; i++) {
|
||||
if (!counts[i])
|
||||
continue;
|
||||
|
||||
if (!ResourceNames[i + 1]) {
|
||||
char buf[40];
|
||||
|
||||
snprintf(buf, sizeof(buf), "Unregistered resource %i", i + 1);
|
||||
RegisterResourceName(i + 1, buf);
|
||||
}
|
||||
|
||||
scratch.resource_type = ResourceNames[i + 1];
|
||||
scratch.count = counts[i];
|
||||
|
||||
if (client->swapped) {
|
||||
|
||||
swapl(&scratch.resource_type);
|
||||
swapl(&scratch.count);
|
||||
}
|
||||
WriteToClient(client, sz_xXResType, (char *) &scratch);
|
||||
}
|
||||
}
|
||||
|
||||
DEALLOCATE_LOCAL(counts);
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
ResGetApproxPixmapBytes(PixmapPtr pix)
|
||||
{
|
||||
unsigned long nPixels;
|
||||
|
||||
int bytesPerPixel;
|
||||
|
||||
bytesPerPixel = pix->drawable.bitsPerPixel >> 3;
|
||||
nPixels = pix->drawable.width * pix->drawable.height;
|
||||
|
||||
/* Divide by refcnt as pixmap could be shared between clients,
|
||||
* so total pixmap mem is shared between these.
|
||||
*/
|
||||
return (nPixels * bytesPerPixel) / pix->refcnt;
|
||||
}
|
||||
|
||||
static void
|
||||
ResFindPixmaps(pointer value, XID id, pointer cdata)
|
||||
{
|
||||
unsigned long *bytes = (unsigned long *) cdata;
|
||||
|
||||
PixmapPtr pix = (PixmapPtr) value;
|
||||
|
||||
*bytes += ResGetApproxPixmapBytes(pix);
|
||||
}
|
||||
|
||||
static void
|
||||
ResFindWindowPixmaps(pointer value, XID id, pointer cdata)
|
||||
{
|
||||
unsigned long *bytes = (unsigned long *) cdata;
|
||||
|
||||
WindowPtr pWin = (WindowPtr) value;
|
||||
|
||||
if (pWin->backgroundState == BackgroundPixmap)
|
||||
*bytes += ResGetApproxPixmapBytes(pWin->background.pixmap);
|
||||
|
||||
if (pWin->border.pixmap != NULL && !pWin->borderIsPixel)
|
||||
*bytes += ResGetApproxPixmapBytes(pWin->border.pixmap);
|
||||
}
|
||||
|
||||
static void
|
||||
ResFindGCPixmaps(pointer value, XID id, pointer cdata)
|
||||
{
|
||||
unsigned long *bytes = (unsigned long *) cdata;
|
||||
|
||||
GCPtr pGC = (GCPtr) value;
|
||||
|
||||
if (pGC->stipple != NULL)
|
||||
*bytes += ResGetApproxPixmapBytes(pGC->stipple);
|
||||
|
||||
if (pGC->tile.pixmap != NULL && !pGC->tileIsPixel)
|
||||
*bytes += ResGetApproxPixmapBytes(pGC->tile.pixmap);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXResQueryClientPixmapBytes(ClientPtr client)
|
||||
{
|
||||
REQUEST(xXResQueryClientPixmapBytesReq);
|
||||
xXResQueryClientPixmapBytesReply rep;
|
||||
|
||||
int clientID;
|
||||
|
||||
unsigned long bytes;
|
||||
|
||||
REQUEST_SIZE_MATCH(xXResQueryClientPixmapBytesReq);
|
||||
|
||||
clientID = CLIENT_ID(stuff->xid);
|
||||
|
||||
/* we could remove the (clientID == 0) check if we wanted to allow
|
||||
probing the X-server's resource usage */
|
||||
if (!clientID || (clientID >= currentMaxClients) || !clients[clientID]) {
|
||||
client->errorValue = stuff->xid;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
bytes = 0;
|
||||
|
||||
FindClientResourcesByType(clients[clientID], RT_PIXMAP, ResFindPixmaps,
|
||||
(pointer) (&bytes));
|
||||
|
||||
/*
|
||||
* Make sure win background pixmaps also held to account.
|
||||
*/
|
||||
FindClientResourcesByType(clients[clientID], RT_WINDOW,
|
||||
ResFindWindowPixmaps, (pointer) (&bytes));
|
||||
|
||||
/*
|
||||
* GC Tile & Stipple pixmaps too.
|
||||
*/
|
||||
FindClientResourcesByType(clients[clientID], RT_GC,
|
||||
ResFindGCPixmaps, (pointer) (&bytes));
|
||||
|
||||
|
||||
rep.type = X_Reply;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.length = 0;
|
||||
rep.bytes = bytes;
|
||||
#ifdef _XSERVER64
|
||||
rep.bytes_overflow = bytes >> 32;
|
||||
#else
|
||||
rep.bytes_overflow = 0;
|
||||
#endif
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
swapl(&rep.bytes);
|
||||
swapl(&rep.bytes_overflow);
|
||||
}
|
||||
WriteToClient(client, sizeof(xXResQueryClientPixmapBytesReply),
|
||||
(char *) &rep);
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static void
|
||||
ResResetProc(ExtensionEntry * extEntry)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
ProcResDispatch(ClientPtr client)
|
||||
{
|
||||
REQUEST(xReq);
|
||||
switch (stuff->data) {
|
||||
case X_XResQueryVersion:
|
||||
return ProcXResQueryVersion(client);
|
||||
case X_XResQueryClients:
|
||||
return ProcXResQueryClients(client);
|
||||
case X_XResQueryClientResources:
|
||||
return ProcXResQueryClientResources(client);
|
||||
case X_XResQueryClientPixmapBytes:
|
||||
return ProcXResQueryClientPixmapBytes(client);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return BadRequest;
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXResQueryVersion(ClientPtr client)
|
||||
{
|
||||
REQUEST_SIZE_MATCH(xXResQueryVersionReq);
|
||||
return ProcXResQueryVersion(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXResQueryClientResources(ClientPtr client)
|
||||
{
|
||||
REQUEST(xXResQueryClientResourcesReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xXResQueryClientResourcesReq);
|
||||
swapl(&stuff->xid);
|
||||
return ProcXResQueryClientResources(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXResQueryClientPixmapBytes(ClientPtr client)
|
||||
{
|
||||
REQUEST(xXResQueryClientPixmapBytesReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xXResQueryClientPixmapBytesReq);
|
||||
swapl(&stuff->xid);
|
||||
return ProcXResQueryClientPixmapBytes(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcResDispatch(ClientPtr client)
|
||||
{
|
||||
REQUEST(xReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
|
||||
switch (stuff->data) {
|
||||
case X_XResQueryVersion:
|
||||
return SProcXResQueryVersion(client);
|
||||
case X_XResQueryClients: /* nothing to swap */
|
||||
return ProcXResQueryClients(client);
|
||||
case X_XResQueryClientResources:
|
||||
return SProcXResQueryClientResources(client);
|
||||
case X_XResQueryClientPixmapBytes:
|
||||
return SProcXResQueryClientPixmapBytes(client);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return BadRequest;
|
||||
}
|
||||
|
||||
void
|
||||
ResExtensionInit(INITARGS)
|
||||
{
|
||||
(void) AddExtension(XRES_NAME, 0, 0,
|
||||
ProcResDispatch, SProcResDispatch,
|
||||
ResResetProc, StandardMinorOpcode);
|
||||
|
||||
RegisterResourceName(RT_NONE, "NONE");
|
||||
RegisterResourceName(RT_WINDOW, "WINDOW");
|
||||
RegisterResourceName(RT_PIXMAP, "PIXMAP");
|
||||
RegisterResourceName(RT_GC, "GC");
|
||||
RegisterResourceName(RT_FONT, "FONT");
|
||||
RegisterResourceName(RT_CURSOR, "CURSOR");
|
||||
RegisterResourceName(RT_COLORMAP, "COLORMAP");
|
||||
RegisterResourceName(RT_CMAPENTRY, "COLORMAP ENTRY");
|
||||
RegisterResourceName(RT_OTHERCLIENT, "OTHER CLIENT");
|
||||
RegisterResourceName(RT_PASSIVEGRAB, "PASSIVE GRAB");
|
||||
}
|
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
|
||||
Copyright 1992, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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 OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include "windowstr.h"
|
||||
#include "inputstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "dixevents.h"
|
||||
#include "sleepuntil.h"
|
||||
#define _XTEST_SERVER_
|
||||
#include <X11/extensions/xtestproto.h>
|
||||
|
||||
#include "extinit.h"
|
||||
|
||||
#if 0
|
||||
static unsigned char XTestReqCode;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void XTestResetProc(ExtensionEntry * /* extEntry */
|
||||
);
|
||||
|
||||
static int XTestSwapFakeInput(ClientPtr /* client */ ,
|
||||
xReq * /* req */
|
||||
);
|
||||
|
||||
static DISPATCH_PROC(ProcXTestCompareCursor);
|
||||
|
||||
static DISPATCH_PROC(ProcXTestDispatch);
|
||||
|
||||
static DISPATCH_PROC(ProcXTestFakeInput);
|
||||
|
||||
static DISPATCH_PROC(ProcXTestGetVersion);
|
||||
|
||||
static DISPATCH_PROC(ProcXTestGrabControl);
|
||||
|
||||
static DISPATCH_PROC(SProcXTestCompareCursor);
|
||||
|
||||
static DISPATCH_PROC(SProcXTestDispatch);
|
||||
|
||||
static DISPATCH_PROC(SProcXTestFakeInput);
|
||||
|
||||
static DISPATCH_PROC(SProcXTestGetVersion);
|
||||
|
||||
static DISPATCH_PROC(SProcXTestGrabControl);
|
||||
|
||||
void
|
||||
XTestExtensionInit(INITARGS)
|
||||
{
|
||||
#if 0
|
||||
ExtensionEntry *extEntry;
|
||||
|
||||
if ((extEntry = AddExtension(XTestExtensionName, 0, 0,
|
||||
ProcXTestDispatch, SProcXTestDispatch,
|
||||
XTestResetProc, StandardMinorOpcode)) != 0)
|
||||
XTestReqCode = (unsigned char) extEntry->base;
|
||||
#else
|
||||
(void) AddExtension(XTestExtensionName, 0, 0,
|
||||
ProcXTestDispatch, SProcXTestDispatch,
|
||||
XTestResetProc, StandardMinorOpcode);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*ARGSUSED*/ static void
|
||||
XTestResetProc(extEntry)
|
||||
ExtensionEntry *extEntry;
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXTestGetVersion(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
xXTestGetVersionReply rep;
|
||||
|
||||
|
||||
REQUEST_SIZE_MATCH(xXTestGetVersionReq);
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.majorVersion = XTestMajorVersion;
|
||||
rep.minorVersion = XTestMinorVersion;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swaps(&rep.minorVersion);
|
||||
}
|
||||
WriteToClient(client, sizeof(xXTestGetVersionReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXTestCompareCursor(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xXTestCompareCursorReq);
|
||||
xXTestCompareCursorReply rep;
|
||||
|
||||
WindowPtr pWin;
|
||||
|
||||
CursorPtr pCursor;
|
||||
|
||||
|
||||
REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
|
||||
pWin = (WindowPtr) LookupWindow(stuff->window, client);
|
||||
if (!pWin)
|
||||
return (BadWindow);
|
||||
if (stuff->cursor == None)
|
||||
pCursor = NullCursor;
|
||||
else if (stuff->cursor == XTestCurrentCursor)
|
||||
pCursor = GetSpriteCursor();
|
||||
else {
|
||||
pCursor = (CursorPtr) LookupIDByType(stuff->cursor, RT_CURSOR);
|
||||
if (!pCursor) {
|
||||
client->errorValue = stuff->cursor;
|
||||
return (BadCursor);
|
||||
}
|
||||
}
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
rep.same = (wCursor(pWin) == pCursor);
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
}
|
||||
WriteToClient(client, sizeof(xXTestCompareCursorReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXTestFakeInput(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xXTestFakeInputReq);
|
||||
int nev;
|
||||
|
||||
xEvent *ev;
|
||||
|
||||
DeviceIntPtr dev = NULL;
|
||||
|
||||
WindowPtr root;
|
||||
|
||||
int type;
|
||||
|
||||
|
||||
nev = (stuff->length << 2) - sizeof(xReq);
|
||||
if ((nev % sizeof(xEvent)) || !nev)
|
||||
return BadLength;
|
||||
nev /= sizeof(xEvent);
|
||||
UpdateCurrentTime();
|
||||
ev = (xEvent *) &((xReq *) stuff)[1];
|
||||
type = ev->u.u.type & 0177;
|
||||
{
|
||||
if (nev != 1)
|
||||
return BadLength;
|
||||
switch (type) {
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
case MotionNotify:
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
break;
|
||||
default:
|
||||
client->errorValue = ev->u.u.type;
|
||||
return BadValue;
|
||||
}
|
||||
}
|
||||
if (ev->u.keyButtonPointer.time) {
|
||||
TimeStamp activateTime;
|
||||
|
||||
CARD32 ms;
|
||||
|
||||
activateTime = currentTime;
|
||||
ms = activateTime.milliseconds + ev->u.keyButtonPointer.time;
|
||||
if (ms < activateTime.milliseconds)
|
||||
activateTime.months++;
|
||||
activateTime.milliseconds = ms;
|
||||
ev->u.keyButtonPointer.time = 0;
|
||||
|
||||
/* see mbuf.c:QueueDisplayRequest for code similar to this */
|
||||
|
||||
if (!ClientSleepUntil(client, &activateTime, NULL, NULL)) {
|
||||
return BadAlloc;
|
||||
}
|
||||
/* swap the request back so we can simply re-execute it */
|
||||
if (client->swapped) {
|
||||
(void) XTestSwapFakeInput(client, (xReq *) stuff);
|
||||
swaps(&stuff->length);
|
||||
}
|
||||
ResetCurrentRequest(client);
|
||||
client->sequence--;
|
||||
return Success;
|
||||
}
|
||||
switch (type) {
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
dev = (DeviceIntPtr) LookupKeyboardDevice();
|
||||
if (ev->u.u.detail < dev->key->curKeySyms.minKeyCode ||
|
||||
ev->u.u.detail > dev->key->curKeySyms.maxKeyCode) {
|
||||
client->errorValue = ev->u.u.detail;
|
||||
return BadValue;
|
||||
}
|
||||
break;
|
||||
case MotionNotify:
|
||||
dev = (DeviceIntPtr) LookupPointerDevice();
|
||||
if (ev->u.keyButtonPointer.root == None)
|
||||
root = GetCurrentRootWindow();
|
||||
else {
|
||||
root = LookupWindow(ev->u.keyButtonPointer.root, client);
|
||||
if (!root)
|
||||
return BadWindow;
|
||||
if (root->parent) {
|
||||
client->errorValue = ev->u.keyButtonPointer.root;
|
||||
return BadValue;
|
||||
}
|
||||
}
|
||||
if (ev->u.u.detail == xTrue) {
|
||||
int x, y;
|
||||
|
||||
GetSpritePosition(&x, &y);
|
||||
ev->u.keyButtonPointer.rootX += x;
|
||||
ev->u.keyButtonPointer.rootY += y;
|
||||
}
|
||||
else if (ev->u.u.detail != xFalse) {
|
||||
client->errorValue = ev->u.u.detail;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
|
||||
if (ev->u.keyButtonPointer.rootX < 0)
|
||||
ev->u.keyButtonPointer.rootX = 0;
|
||||
else if (ev->u.keyButtonPointer.rootX >= root->drawable.width)
|
||||
ev->u.keyButtonPointer.rootX = root->drawable.width - 1;
|
||||
if (ev->u.keyButtonPointer.rootY < 0)
|
||||
ev->u.keyButtonPointer.rootY = 0;
|
||||
else if (ev->u.keyButtonPointer.rootY >= root->drawable.height)
|
||||
ev->u.keyButtonPointer.rootY = root->drawable.height - 1;
|
||||
|
||||
if (root != GetCurrentRootWindow())
|
||||
{
|
||||
NewCurrentScreen(root->drawable.pScreen,
|
||||
ev->u.keyButtonPointer.rootX,
|
||||
ev->u.keyButtonPointer.rootY);
|
||||
return client->noClientException;
|
||||
}
|
||||
(*root->drawable.pScreen->SetCursorPosition)
|
||||
(root->drawable.pScreen,
|
||||
ev->u.keyButtonPointer.rootX, ev->u.keyButtonPointer.rootY, FALSE);
|
||||
break;
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
dev = (DeviceIntPtr) LookupPointerDevice();
|
||||
if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons) {
|
||||
client->errorValue = ev->u.u.detail;
|
||||
return BadValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (screenIsSaved == SCREEN_SAVER_ON)
|
||||
SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
|
||||
ev->u.keyButtonPointer.time = currentTime.milliseconds;
|
||||
(*dev->public.processInputProc) (ev, dev, nev);
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXTestGrabControl(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xXTestGrabControlReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xXTestGrabControlReq);
|
||||
if ((stuff->impervious != xTrue) && (stuff->impervious != xFalse)) {
|
||||
client->errorValue = stuff->impervious;
|
||||
return (BadValue);
|
||||
}
|
||||
if (stuff->impervious)
|
||||
MakeClientGrabImpervious(client);
|
||||
else
|
||||
MakeClientGrabPervious(client);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcXTestDispatch(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xReq);
|
||||
switch (stuff->data) {
|
||||
case X_XTestGetVersion:
|
||||
return ProcXTestGetVersion(client);
|
||||
case X_XTestCompareCursor:
|
||||
return ProcXTestCompareCursor(client);
|
||||
case X_XTestFakeInput:
|
||||
return ProcXTestFakeInput(client);
|
||||
case X_XTestGrabControl:
|
||||
return ProcXTestGrabControl(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXTestGetVersion(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xXTestGetVersionReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xXTestGetVersionReq);
|
||||
swaps(&stuff->minorVersion);
|
||||
return ProcXTestGetVersion(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXTestCompareCursor(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xXTestCompareCursorReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
|
||||
swapl(&stuff->window);
|
||||
swapl(&stuff->cursor);
|
||||
return ProcXTestCompareCursor(client);
|
||||
}
|
||||
|
||||
static int
|
||||
XTestSwapFakeInput(client, req)
|
||||
ClientPtr client;
|
||||
|
||||
xReq *req;
|
||||
{
|
||||
int nev;
|
||||
|
||||
xEvent *ev;
|
||||
|
||||
xEvent sev;
|
||||
|
||||
EventSwapPtr proc;
|
||||
|
||||
nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
|
||||
for (ev = (xEvent *) &req[1]; --nev >= 0; ev++) {
|
||||
/* Swap event */
|
||||
proc = EventSwapVector[ev->u.u.type & 0177];
|
||||
/* no swapping proc; invalid event type? */
|
||||
if (!proc || proc == NotImplemented) {
|
||||
client->errorValue = ev->u.u.type;
|
||||
return BadValue;
|
||||
}
|
||||
(*proc) (ev, &sev);
|
||||
*ev = sev;
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXTestFakeInput(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
int n = XTestSwapFakeInput(client, stuff);
|
||||
if (n != Success)
|
||||
return n;
|
||||
return ProcXTestFakeInput(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXTestGrabControl(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
|
||||
REQUEST(xXTestGrabControlReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xXTestGrabControlReq);
|
||||
return ProcXTestGrabControl(client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcXTestDispatch(client)
|
||||
ClientPtr client;
|
||||
{
|
||||
REQUEST(xReq);
|
||||
switch (stuff->data) {
|
||||
case X_XTestGetVersion:
|
||||
return SProcXTestGetVersion(client);
|
||||
case X_XTestCompareCursor:
|
||||
return SProcXTestCompareCursor(client);
|
||||
case X_XTestFakeInput:
|
||||
return SProcXTestFakeInput(client);
|
||||
case X_XTestGrabControl:
|
||||
return SProcXTestGrabControl(client);
|
||||
default:
|
||||
return BadRequest;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#! /bin/sh
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
ORIGDIR=`pwd`
|
||||
cd $srcdir
|
||||
|
||||
autoreconf -v --install || exit 1
|
||||
cd $ORIGDIR || exit $?
|
|
@ -0,0 +1,687 @@
|
|||
dnl Copyright © 2003-2005 Keith Packard, Daniel Stone
|
||||
dnl Copyright © 2013 Lauri Kasanen
|
||||
dnl
|
||||
dnl Permission to use, copy, modify, distribute, and sell this software and its
|
||||
dnl documentation for any purpose is hereby granted without fee, provided that
|
||||
dnl the above copyright notice appear in all copies and that both that
|
||||
dnl copyright notice and this permission notice appear in supporting
|
||||
dnl documentation, and that the names of Keith Packard and Daniel Stone not be
|
||||
dnl used in advertising or publicity pertaining to distribution of the software
|
||||
dnl without specific, written prior permission. Keith Packard and Daniel Stone
|
||||
dnl make no representations about the suitability of this software for any
|
||||
dnl purpose. It is provided "as is" without express or implied warranty.
|
||||
dnl
|
||||
dnl KEITH PACKARD AND DANIEL STONE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
dnl SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
|
||||
dnl IN NO EVENT SHALL KEITH PACKARD OR DANIEL STONE BE LIABLE FOR ANY SPECIAL,
|
||||
dnl INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
dnl LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
dnl OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
dnl PERFORMANCE OF THIS SOFTWARE.
|
||||
dnl
|
||||
dnl Process this file with autoconf to create configure.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([tinyx], 1.0)
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip foreign -Wall])
|
||||
|
||||
dnl this gets generated by autoheader, and thus contains all the defines. we
|
||||
dnl don't ever actually use it, internally.
|
||||
AC_CONFIG_HEADERS(include/do-not-use-config.h)
|
||||
dnl dix-config.h covers most of the DIX (i.e. everything but the DDX, not just
|
||||
dnl dix/).
|
||||
AC_CONFIG_HEADERS(include/dix-config.h)
|
||||
dnl kdrive-config.h covers the kdrive DDX
|
||||
AC_CONFIG_HEADERS(include/kdrive-config.h)
|
||||
|
||||
AC_PROG_CC
|
||||
AM_PROG_AS
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_DISABLE_SHARED
|
||||
AC_PROG_LIBTOOL
|
||||
PKG_PROG_PKG_CONFIG
|
||||
AC_PROG_LEX
|
||||
AC_PROG_YACC
|
||||
XORG_PROG_RAWCPP
|
||||
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h])
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_C_BIGENDIAN([ENDIAN="X_BIG_ENDIAN"], [ENDIAN="X_LITTLE_ENDIAN"])
|
||||
|
||||
AC_CHECK_SIZEOF([unsigned long])
|
||||
if test "$ac_cv_sizeof_unsigned_long" = 8; then
|
||||
AC_DEFINE(_XSERVER64, 1, [Define to 1 if unsigned long is 64 bits.])
|
||||
fi
|
||||
|
||||
AC_TYPE_PID_T
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
|
||||
strtol getopt getopt_long vsnprintf])
|
||||
AC_FUNC_ALLOCA
|
||||
dnl Old HAS_* names used in os/*.c.
|
||||
AC_CHECK_FUNC([getdtablesize],
|
||||
AC_DEFINE(HAS_GETDTABLESIZE, 1, [Have the `getdtablesize' function.]))
|
||||
AC_CHECK_FUNC([getifaddrs],
|
||||
AC_DEFINE(HAS_GETIFADDRS, 1, [Have the `getifaddrs' function.]))
|
||||
AC_CHECK_FUNC([getpeereid],
|
||||
AC_DEFINE(HAS_GETPEEREID, 1, [Have the `getpeereid' function.]))
|
||||
AC_CHECK_FUNC([getpeerucred],
|
||||
AC_DEFINE(HAS_GETPEERUCRED, 1, [Have the `getpeerucred' function.]))
|
||||
AC_CHECK_FUNC([strlcat], HAVE_STRLCAT=yes, HAVE_STRLCAT=no)
|
||||
AM_CONDITIONAL(NEED_STRLCAT, [test x$HAVE_STRLCAT = xno])
|
||||
|
||||
AM_CONDITIONAL(NEED_VSNPRINTF, [test x$HAVE_VSNPRINTF = xno])
|
||||
|
||||
dnl Check for mmap support for Xvfb
|
||||
AC_CHECK_FUNC([mmap], AC_DEFINE(HAS_MMAP, 1, [Have the `mmap' function.]))
|
||||
|
||||
dnl Find the math libary
|
||||
AC_CHECK_LIB(m, sqrt)
|
||||
|
||||
dnl APM header
|
||||
AC_CHECK_HEADERS([linux/apm_bios.h], LNXAPM=yes)
|
||||
AM_CONDITIONAL(LNXAPM, [test "x$LNXAPM" = xyes])
|
||||
|
||||
dnl fbdev header
|
||||
AC_CHECK_HEADERS([linux/fb.h], FBDEV=yes)
|
||||
AM_CONDITIONAL(FBDEVHW, [test "x$FBDEV" = xyes])
|
||||
|
||||
dnl MTRR header
|
||||
AC_CHECK_HEADERS([asm/mtrr.h], ac_cv_asm_mtrr_h=yes)
|
||||
if test "x$ac_cv_asm_mtrr_h" = xyes; then
|
||||
HAVE_MTRR=yes
|
||||
fi
|
||||
|
||||
dnl BSD MTRR header
|
||||
AC_CHECK_HEADERS([sys/memrange.h], ac_cv_memrange_h=yes)
|
||||
if test "x$ac_cv_memrange_h" = xyes; then
|
||||
HAVE_MTRR=yes
|
||||
fi
|
||||
|
||||
if test "x$HAVE_MTRR" = xyes; then
|
||||
AC_DEFINE(HAS_MTRR_SUPPORT, 1, [MTRR support available])
|
||||
fi
|
||||
|
||||
dnl A NetBSD MTRR header
|
||||
AC_CHECK_HEADERS([machine/mtrr.h], ac_cv_machine_mtrr_h=yes)
|
||||
if test "x$ac_cv_machine_mtrr_h" = xyes; then
|
||||
AC_DEFINE(HAS_MTRR_BUILTIN, 1, [Define to 1 if NetBSD built-in MTRR
|
||||
support is available])
|
||||
fi
|
||||
|
||||
dnl FreeBSD kldload support (sys/linker.h)
|
||||
AC_CHECK_HEADERS([sys/linker.h],
|
||||
[ac_cv_sys_linker_h=yes],
|
||||
[ac_cv_sys_linker_h=no],
|
||||
[#include <sys/param.h>])
|
||||
AM_CONDITIONAL(FREEBSD_KLDLOAD, [test "x$ac_cv_sys_linker_h" = xyes])
|
||||
|
||||
AC_CACHE_CHECK([for SYSV IPC],
|
||||
ac_cv_sysv_ipc,
|
||||
[AC_TRY_LINK([
|
||||
#include <sys/shm.h>
|
||||
],[
|
||||
{
|
||||
int id;
|
||||
id = shmget(IPC_PRIVATE, 512, SHM_W | SHM_R);
|
||||
if (id < 0) return -1;
|
||||
return shmctl(id, IPC_RMID, 0);
|
||||
}],
|
||||
[ac_cv_sysv_ipc=yes],
|
||||
[ac_cv_sysv_ipc=no])])
|
||||
if test "x$ac_cv_sysv_ipc" = xyes; then
|
||||
AC_DEFINE(HAVE_SYSV_IPC, 1, [Define to 1 if SYSV IPC is available])
|
||||
fi
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Bus options and CPU capabilities. Replaces logic in
|
||||
dnl hw/xfree86/os-support/bus/Makefile.am, among others.
|
||||
dnl ---------------------------------------------------------------------------
|
||||
DEFAULT_INT10="x86emu"
|
||||
|
||||
dnl Override defaults as needed for specific platforms:
|
||||
|
||||
case $host_cpu in
|
||||
alpha*)
|
||||
ALPHA_VIDEO=yes
|
||||
case $host_os in
|
||||
*netbsd*) AC_DEFINE(USE_ALPHA_PIO, 1, [NetBSD PIO alpha IO]) ;;
|
||||
esac
|
||||
;;
|
||||
arm*)
|
||||
ARM_VIDEO=yes
|
||||
;;
|
||||
i*86)
|
||||
I386_VIDEO=yes
|
||||
case $host_os in
|
||||
*linux*) DEFAULT_INT10=vm86 ;;
|
||||
*freebsd*) AC_DEFINE(USE_DEV_IO) ;;
|
||||
*netbsd*) AC_DEFINE(USE_I386_IOPL)
|
||||
SYS_LIBS=-li386
|
||||
;;
|
||||
*openbsd*) AC_DEFINE(USE_I386_IOPL)
|
||||
SYS_LIBS=-li386
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
powerpc*)
|
||||
PPC_VIDEO=yes
|
||||
case $host_os in
|
||||
*freebsd*) DEFAULT_INT10=stub ;;
|
||||
esac
|
||||
;;
|
||||
sparc*)
|
||||
xorg_loader_sparcmuldiv="yes"
|
||||
SPARC64_VIDEO=yes
|
||||
BSD_ARCH_SOURCES="sparc64_video.c ioperm_noop.c"
|
||||
;;
|
||||
x86_64*|amd64*)
|
||||
I386_VIDEO=yes
|
||||
case $host_os in
|
||||
*freebsd*) AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;;
|
||||
*netbsd*) AC_DEFINE(USE_I386_IOPL, 1, [BSD i386 iopl])
|
||||
SYS_LIBS=-lx86_64
|
||||
;;
|
||||
*openbsd*) AC_DEFINE(USE_AMD64_IOPL, 1, [BSD AMD64 iopl])
|
||||
SYS_LIBS=-lamd64
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl BSD *_video.c selection
|
||||
AM_CONDITIONAL(ALPHA_VIDEO, [test "x$ALPHA_VIDEO" = xyes])
|
||||
AM_CONDITIONAL(ARM_VIDEO, [test "x$ARM_VIDEO" = xyes])
|
||||
AM_CONDITIONAL(I386_VIDEO, [test "x$I386_VIDEO" = xyes])
|
||||
AM_CONDITIONAL(PPC_VIDEO, [test "x$PPC_VIDEO" = xyes])
|
||||
AM_CONDITIONAL(SPARC64_VIDEO, [test "x$SPARC64_VIDEO" = xyes])
|
||||
|
||||
DRI=no
|
||||
dnl it would be nice to autodetect these *CONS_SUPPORTs
|
||||
case $host_os in
|
||||
*freebsd*)
|
||||
case $host_os in
|
||||
kfreebsd*-gnu) ;;
|
||||
*) AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) ;;
|
||||
esac
|
||||
AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console])
|
||||
AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console])
|
||||
AC_DEFINE(SYSCONS_SUPPORT, 1, [System has syscons console])
|
||||
;;
|
||||
*netbsd*)
|
||||
AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
|
||||
AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console])
|
||||
AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console])
|
||||
;;
|
||||
*openbsd*)
|
||||
AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
|
||||
AC_DEFINE(PCVT_SUPPORT, 1, [System has PC console])
|
||||
AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console])
|
||||
;;
|
||||
esac
|
||||
|
||||
OSNAME=`uname -srm`
|
||||
AC_DEFINE_UNQUOTED(OSNAME, "$OSNAME",
|
||||
[Define to OS Name string to display for build OS in Xorg log])
|
||||
|
||||
DEFAULT_VENDOR_NAME="TinyCore Linux"
|
||||
DEFAULT_VENDOR_NAME_SHORT="TinyCore"
|
||||
VERSION_MAJOR=1
|
||||
VERSION_MINOR=0
|
||||
VERSION_PATCH=0
|
||||
VERSION_SNAP=0
|
||||
RELEASE_DATE="9 Nov 2013"
|
||||
DEFAULT_VENDOR_WEB="http://tinycorelinux.com"
|
||||
|
||||
m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))])
|
||||
|
||||
dnl Build options.
|
||||
AC_ARG_ENABLE(werror, AS_HELP_STRING([--enable-werror],
|
||||
[Treat warnings as errors (default: disabled)]),
|
||||
[WERROR=$enableval], [WERROR=no])
|
||||
AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],
|
||||
[Enable debugging (default: disabled)]),
|
||||
[DEBUGGING=$enableval], [DEBUGGING=no])
|
||||
AC_ARG_WITH(int10, AS_HELP_STRING([--with-int10=BACKEND], [int10 backend: vm86, x86emu or stub]),
|
||||
[INT10="$withval"],
|
||||
[INT10="$DEFAULT_INT10"])
|
||||
AC_ARG_WITH(vendor-name, AS_HELP_STRING([--with-vendor-string=VENDOR],
|
||||
[Vendor string reported by the server]),
|
||||
[ VENDOR_STRING="$withval" ],
|
||||
[ VENDOR_STRING="$DEFAULT_VENDOR_NAME" ])
|
||||
AC_ARG_WITH(vendor-name-short, AS_HELP_STRING([--with-vendor-string-short=VENDOR],
|
||||
[Short version of vendor string reported by the server]),
|
||||
[ VENDOR_STRING_SHORT="$withval" ],
|
||||
[ VENDOR_STRING_SHORT="$DEFAULT_VENDOR_NAME_SHORT" ])
|
||||
AC_ARG_WITH(vendor-web, AS_HELP_STRING([--with-vendor-web=URL],
|
||||
[Vendor web address reported by the server]),
|
||||
[ VENDOR_WEB="$withval" ],
|
||||
[ VENDOR_WEB="$DEFAULT_VENDOR_WEB" ])
|
||||
AC_ARG_WITH(builder-addr, AS_HELP_STRING([--with-builder-addr=ADDRESS],
|
||||
[Builder address (default: xorg@lists.freedesktop.org)]),
|
||||
[ BUILDERADDR="$withval" ],
|
||||
[ BUILDERADDR="xorg@lists.freedesktop.org" ])
|
||||
AC_ARG_WITH(fontdir, AS_HELP_STRING([--with-fontdir=FONTDIR], [Path to top level dir where fonts are installed (default: ${libdir}/X11/fonts)]),
|
||||
[ FONTDIR="$withval" ],
|
||||
[ FONTDIR="${libdir}/X11/fonts" ])
|
||||
DEFAULT_FONT_PATH="${FONTDIR}/misc/,${FONTDIR}/TTF/,${FONTDIR}/OTF,${FONTDIR}/Type1/,${FONTDIR}/100dpi/,${FONTDIR}/75dpi/"
|
||||
AC_ARG_WITH(default-font-path, AS_HELP_STRING([--with-default-font-path=PATH], [Comma separated list of font dirs]),
|
||||
[ FONTPATH="$withval" ],
|
||||
[ FONTPATH="${DEFAULT_FONT_PATH}" ])
|
||||
|
||||
dnl Extensions.
|
||||
AC_ARG_ENABLE(xres, AS_HELP_STRING([--disable-xres], [Build XRes extension (default: enabled)]), [RES=$enableval], [RES=yes])
|
||||
AC_ARG_ENABLE(screensaver, AS_HELP_STRING([--disable-screensaver], [Build ScreenSaver extension (default: enabled)]), [SCREENSAVER=$enableval], [SCREENSAVER=yes])
|
||||
AC_ARG_ENABLE(xdmcp, AS_HELP_STRING([--disable-xdmcp], [Build XDMCP extension (default: auto)]), [XDMCP=$enableval], [XDMCP=auto])
|
||||
AC_ARG_ENABLE(xdm-auth-1, AS_HELP_STRING([--disable-xdm-auth-1], [Build XDM-Auth-1 extension (default: auto)]), [XDMAUTH=$enableval], [XDMAUTH=auto])
|
||||
AC_ARG_ENABLE(dbe, AS_HELP_STRING([--disable-dbe], [Build DBE extension (default: enabled)]), [DBE=$enableval], [DBE=yes])
|
||||
AC_ARG_ENABLE(xf86bigfont, AS_HELP_STRING([--disable-xf86bigfont], [Build XF86 Big Font extension (default: enabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=yes])
|
||||
AC_ARG_ENABLE(dpms, AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
|
||||
|
||||
dnl kdrive and its subsystems
|
||||
AC_ARG_ENABLE(kdrive, AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: yes)]), [KDRIVE=$enableval], [KDRIVE=yes])
|
||||
|
||||
|
||||
dnl chown/chmod to be setuid root as part of build
|
||||
dnl Replaces InstallXserverSetUID in imake
|
||||
AC_ARG_ENABLE(install-setuid,
|
||||
AS_HELP_STRING([--enable-install-setuid],
|
||||
[Install Xorg server as owned by root with setuid bit (default: auto)]),
|
||||
[SETUID=$enableval], [SETUID=auto])
|
||||
AC_MSG_CHECKING([to see if we can install the Xorg server as root])
|
||||
if test "x$SETUID" = "xauto" ; then
|
||||
case $host_os in
|
||||
darwin*) SETUID="no" ;;
|
||||
*)
|
||||
case $host_cpu in
|
||||
sparc) SETUID="no" ;;
|
||||
*) SETUID="yes" ;;
|
||||
esac
|
||||
esac
|
||||
if test "x$SETUID" = xyes; then
|
||||
touch testfile
|
||||
chown root testfile > /dev/null 2>&1 || SETUID="no"
|
||||
rm -f testfile
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT([$SETUID])
|
||||
AM_CONDITIONAL(INSTALL_SETUID, [test "x$SETUID" = "xyes"])
|
||||
|
||||
dnl Issue an error if xtrans.m4 was not found and XTRANS_CONNECTION_FLAGS macro
|
||||
dnl was not expanded, since xorg-server with no transport types is rather useless.
|
||||
dnl
|
||||
dnl If you're seeing an error here, be sure you installed the lib/xtrans module
|
||||
dnl first and if it's not in the default location, that you set the ACLOCAL
|
||||
dnl environment variable to find it, such as:
|
||||
dnl ACLOCAL="aclocal -I ${PREFIX}/share/aclocal"
|
||||
m4_pattern_forbid([^XTRANS_CONNECTION_FLAGS$])
|
||||
|
||||
# Transport selection macro from xtrans.m4
|
||||
XTRANS_CONNECTION_FLAGS
|
||||
|
||||
# Secure RPC detection macro from xtrans.m4
|
||||
XTRANS_SECURE_RPC_FLAGS
|
||||
|
||||
AM_CONDITIONAL(INT10_VM86, [test "x$INT10" = xvm86])
|
||||
AM_CONDITIONAL(INT10_X86EMU, [test "x$INT10" = xx86emu])
|
||||
AM_CONDITIONAL(INT10_STUB, [test "x$INT10" = xstub])
|
||||
if test "x$INT10" = xyes; then
|
||||
dnl VM86 headers
|
||||
AC_CHECK_HEADERS([sys/vm86.h sys/io.h])
|
||||
fi
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Extension section
|
||||
dnl ---------------------------------------------------------------------------
|
||||
XEXT_INC='-I$(top_srcdir)/Xext'
|
||||
XEXT_LIB='$(top_builddir)/Xext/libXext.la'
|
||||
XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
|
||||
|
||||
dnl Core modules for most extensions, et al.
|
||||
REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto xproto xtrans xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto [kbproto >= 1.0.3]"
|
||||
REQUIRED_LIBS="xfont fontenc"
|
||||
|
||||
AM_CONDITIONAL(SCREENSAVER, [test "x$SCREENSAVER" = xyes])
|
||||
if test "x$SCREENSAVER" = xyes; then
|
||||
AC_DEFINE(SCREENSAVER, 1, [Support MIT-SCREEN-SAVER extension])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(RES, [test "x$RES" = xyes])
|
||||
if test "x$RES" = xyes; then
|
||||
AC_DEFINE(RES, 1, [Support X resource extension])
|
||||
REQUIRED_MODULES="$REQUIRED_MODULES resourceproto"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(DBE, [test "x$DBE" = xyes])
|
||||
if test "x$DBE" = xyes; then
|
||||
AC_DEFINE(DBE, 1, [Support DBE extension])
|
||||
DBE_LIB='$(top_builddir)/dbe/libdbe.la'
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(XF86BIGFONT, [test "x$XF86BIGFONT" = xyes])
|
||||
if test "x$XF86BIGFONT" = xyes; then
|
||||
AC_DEFINE(XF86BIGFONT, 1, [Support XF86 Big font extension])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(DPMSExtension, [test "x$DPMSExtension" = xyes])
|
||||
if test "x$DPMSExtension" = xyes; then
|
||||
AC_DEFINE(DPMSExtension, 1, [Support DPMS extension])
|
||||
fi
|
||||
|
||||
RENDER_LIB='$(top_builddir)/render/librender.la'
|
||||
RENDER_INC='-I$(top_srcdir)/render'
|
||||
|
||||
RANDR_LIB='$(top_builddir)/randr/librandr.la'
|
||||
RANDR_INC='-I$(top_srcdir)/randr'
|
||||
|
||||
FIXES_LIB='$(top_builddir)/xfixes/libxfixes.la'
|
||||
FIXES_INC='-I$(top_srcdir)/xfixes'
|
||||
|
||||
DAMAGE_LIB='$(top_builddir)/damageext/libdamageext.la'
|
||||
DAMAGE_INC='-I$(top_srcdir)/damageext'
|
||||
MIEXT_DAMAGE_LIB='$(top_builddir)/miext/damage/libdamage.la'
|
||||
MIEXT_DAMAGE_INC='-I$(top_srcdir)/miext/damage'
|
||||
|
||||
AC_CHECK_FUNC(strcasecmp, [], AC_DEFINE([NEED_STRCASECMP], 1,
|
||||
[Do not have `strcasecmp'.]))
|
||||
|
||||
PKG_CHECK_MODULES([XDMCP], [xdmcp], [have_libxdmcp="yes"], [have_libxdmcp="no"])
|
||||
if test "x$have_libxdmcp" = xyes; then
|
||||
AC_CHECK_LIB(Xdmcp, XdmcpWrap, [have_xdmcpwrap="yes"], [have_xdmcpwrap="no"], [$XDMCP_LIBS])
|
||||
fi
|
||||
if test "x$XDMCP" = xauto; then
|
||||
if test "x$have_libxdmcp" = xyes; then
|
||||
XDMCP=yes
|
||||
else
|
||||
XDMCP=no
|
||||
fi
|
||||
fi
|
||||
if test "x$XDMAUTH" = xauto; then
|
||||
if test "x$have_libxdmcp" = xyes && test "x$have_xdmcpwrap" = xyes; then
|
||||
XDMAUTH=yes
|
||||
else
|
||||
XDMAUTH=no
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(XDMCP, [test "x$XDMCP" = xyes])
|
||||
if test "x$XDMCP" = xyes; then
|
||||
AC_DEFINE(XDMCP, 1, [Support XDM Control Protocol])
|
||||
REQUIRED_LIBS="$REQUIRED_LIBS xdmcp"
|
||||
XDMCP_MODULES="xdmcp"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(XDMAUTH, [test "x$XDMAUTH" = xyes])
|
||||
if test "x$XDMAUTH" = xyes; then
|
||||
AC_DEFINE(HASXDMAUTH,1,[Support XDM-AUTH*-1])
|
||||
if ! test "x$XDMCP" = xyes; then
|
||||
REQUIRED_LIBS="$REQUIRED_LIBS xdmcp"
|
||||
XDMCP_MODULES="xdmcp"
|
||||
fi
|
||||
fi
|
||||
|
||||
VENDOR_RELEASE="((($VERSION_MAJOR) * 10000000) + (($VERSION_MINOR) * 100000) + (($VERSION_PATCH) * 1000) + $VERSION_SNAP)"
|
||||
|
||||
if test $VERSION_SNAP = "0"; then
|
||||
if test $VERSION_PATCH = "0"; then
|
||||
VENDOR_VERSION_STRING="${VERSION_MAJOR}.${VERSION_MINOR}"
|
||||
else
|
||||
VENDOR_VERSION_STRING="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"
|
||||
fi
|
||||
else
|
||||
VENDOR_VERSION_STRING="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_SNAP}"
|
||||
fi
|
||||
|
||||
VENDOR_RELEASE_STRING="Release ${VENDOR_VERSION_STRING}"
|
||||
VENDOR_MAN_VERSION="Version ${VENDOR_VERSION_STRING}"
|
||||
|
||||
AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path])
|
||||
AC_DEFINE_DIR(BASE_FONT_PATH, FONTDIR, [Default base font path])
|
||||
AC_DEFINE_UNQUOTED(XVENDORNAME, ["$VENDOR_STRING"], [Vendor name])
|
||||
AC_DEFINE_UNQUOTED(XVENDORNAMESHORT, ["$VENDOR_STRING_SHORT"], [Short vendor name])
|
||||
AC_DEFINE_UNQUOTED(XORG_RELEASE, ["$VENDOR_RELEASE_STRING"], [Vendor release])
|
||||
AC_DEFINE_UNQUOTED(XORG_DATE, ["$RELEASE_DATE"], [Vendor release])
|
||||
AC_DEFINE_UNQUOTED(XORG_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version])
|
||||
AC_DEFINE_UNQUOTED(BUILDERADDR, ["$BUILDERADDR"], [Builder address])
|
||||
AC_DEFINE_UNQUOTED(OSNAME, ["$OSNAME"], [Operating System Name])
|
||||
AC_SUBST([VENDOR_STRING])
|
||||
AC_SUBST([VENDOR_STRING_SHORT])
|
||||
AC_SUBST([VENDOR_RELEASE])
|
||||
AC_SUBST([VENDOR_MAN_VERSION])
|
||||
|
||||
AC_DEFINE(SMART_SCHEDULE, 1, [Include time-based scheduler])
|
||||
AM_CONDITIONAL(DEBUG, test "x$DEBUGGING" = xyes)
|
||||
|
||||
if ! test "x$DEBUGGING" = xyes; then
|
||||
AC_DEFINE(NDEBUG, 1, [Disable some debugging code])
|
||||
fi
|
||||
|
||||
DIX_LIB='$(top_builddir)/dix/libdix.la'
|
||||
OS_LIB='$(top_builddir)/os/libos.la'
|
||||
MI_LIB='$(top_builddir)/mi/libmi.la'
|
||||
MI_EXT_LIB='$(top_builddir)/mi/libmiext.la'
|
||||
MI_INC='-I$(top_srcdir)/mi'
|
||||
FB_LIB='$(top_builddir)/fb/libfb.la'
|
||||
FB_INC='-I$(top_srcdir)/fb'
|
||||
MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow'
|
||||
MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la'
|
||||
CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include'
|
||||
|
||||
PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS])
|
||||
PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
|
||||
|
||||
XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}"
|
||||
XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} -lm"
|
||||
AC_SUBST([SYS_LIBS])
|
||||
|
||||
AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes],
|
||||
[AC_CHECK_LIB([rt], [clock_gettime], [have_clock_gettime=-lrt],
|
||||
[have_clock_gettime=no])])
|
||||
|
||||
AC_MSG_CHECKING([for a useful monotonic clock ...])
|
||||
|
||||
if ! test "x$have_clock_gettime" = xno; then
|
||||
if ! test "x$have_clock_gettime" = xyes; then
|
||||
LIBS="$have_clock_gettime"
|
||||
else
|
||||
LIBS=""
|
||||
fi
|
||||
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#include <time.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct timespec tp;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
])], [MONOTONIC_CLOCK=yes], [MONOTONIC_CLOCK=no],
|
||||
[MONOTONIC_CLOCK="cross compiling"])
|
||||
else
|
||||
MONOTONIC_CLOCK=no
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$MONOTONIC_CLOCK])
|
||||
|
||||
if test "x$MONOTONIC_CLOCK" = xyes; then
|
||||
AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()])
|
||||
XSERVER_LIBS="$XSERVER_LIBS $LIBS"
|
||||
fi
|
||||
|
||||
XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $DAMAGE_INC $FIXES_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC"
|
||||
AC_DEFINE_UNQUOTED(X_BYTE_ORDER,[$ENDIAN],[Endian order])
|
||||
|
||||
AC_SUBST([XSERVER_LIBS])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl DDX section.
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
# XORG_CORE_LIBS is needed even if you're not building the Xorg DDX
|
||||
XORG_CORE_LIBS="$DIX_LIB"
|
||||
AC_SUBST([XORG_CORE_LIBS])
|
||||
|
||||
xorg_bus_linuxpci=no
|
||||
xorg_bus_freebsdpci=no
|
||||
xorg_bus_netbsdpci=no
|
||||
xorg_bus_ix86pci=no
|
||||
xorg_bus_ppcpci=no
|
||||
xorg_bus_sparcpci=no
|
||||
xorg_bus_sparc=no
|
||||
|
||||
AM_CONDITIONAL([XORG], [test "x$XORG" = xyes])
|
||||
AM_CONDITIONAL([XORG_BUS_LINUXPCI], [test "x$xorg_bus_linuxpci" = xyes])
|
||||
AM_CONDITIONAL([XORG_BUS_FREEBSDPCI], [test "x$xorg_bus_freebsdpci" = xyes])
|
||||
AM_CONDITIONAL([XORG_BUS_NETBSDPCI], [test "x$xorg_bus_netbsdpci" = xyes])
|
||||
AM_CONDITIONAL([XORG_BUS_IX86PCI], [test "x$xorg_bus_ix86pci" = xyes])
|
||||
AM_CONDITIONAL([XORG_BUS_PPCPCI], [test "x$xorg_bus_ppcpci" = xyes])
|
||||
AM_CONDITIONAL([XORG_BUS_SPARCPCI], [test "x$xorg_bus_sparcpci" = xyes])
|
||||
AM_CONDITIONAL([XORG_BUS_SPARC], [test "x$xorg_bus_sparc" = xyes])
|
||||
AM_CONDITIONAL([XORG_LOADER_SPARC], [test "x$xorg_loader_sparcmuldiv" = xyes])
|
||||
AM_CONDITIONAL([LINUX_IA64], [test "x$linux_ia64" = xyes])
|
||||
AM_CONDITIONAL([LINUX_ALPHA], [test "x$linux_alpha" = xyes])
|
||||
AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes])
|
||||
|
||||
dnl kdrive DDX
|
||||
|
||||
AM_CONDITIONAL(KDRIVE, [test x$KDRIVE = xyes])
|
||||
if test "$KDRIVE" = yes; then
|
||||
AC_DEFINE(KDRIVESERVER,1,[Build Kdrive X server])
|
||||
AC_DEFINE(KDRIVEDDXACTIONS,,[Build kdrive ddx])
|
||||
|
||||
AC_CHECK_HEADERS([asm/vm86.h sys/io.h])
|
||||
if test "$ac_cv_header_asm_vm86_h" = yes; then
|
||||
AC_DEFINE(KDRIVEVESA, 1, [Build VESA-based kdrive servers])
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS([linux/fb.h])
|
||||
if test "$ac_cv_header_linux_fb_h" = yes; then
|
||||
AC_DEFINE(KDRIVEFBDEV, 1, [Build fbdev-based kdrive server])
|
||||
fi
|
||||
|
||||
# damage shadow extension fb mi
|
||||
KDRIVE_INC='-I$(top_srcdir)/kdrive/src'
|
||||
KDRIVE_PURE_INCS="$KDRIVE_INC $MIEXT_DAMAGE_INC $MIEXT_SHADOW_INC $XEXT_INC $FB_INC $MI_INC"
|
||||
KDRIVE_OS_INC='-I$(top_srcdir)/kdrive/linux'
|
||||
KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC"
|
||||
|
||||
KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H"
|
||||
|
||||
# dix os fb mi extension glx (NOTYET) damage shadow
|
||||
#KDRIVE_PURE_LIBS="$DIX_LIB $OS_LIB $FB_LIB $XEXT_LIB $MIEXT_DAMAGE_LIB \
|
||||
# $MIEXT_SHADOW_LIB"
|
||||
KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $OS_LIB"
|
||||
KDRIVE_LIB='$(top_builddir)/kdrive/src/libkdrive.a'
|
||||
case $host_os in
|
||||
*linux*)
|
||||
KDRIVE_OS_LIB='$(top_builddir)/kdrive/linux/liblinux.a'
|
||||
KDRIVELINUX=yes
|
||||
;;
|
||||
esac
|
||||
KDRIVE_STUB_LIB='$(top_builddir)/kdrive/src/libkdrivestubs.a'
|
||||
KDRIVE_LIBS="$DIX_LIB $KDRIVE_LIB $KDRIVE_OS_LIB $KDRIVE_PURE_LIBS $KDRIVE_STUB_LIB"
|
||||
fi
|
||||
AC_SUBST(KDRIVE_INCS)
|
||||
AC_SUBST(KDRIVE_PURE_INCS)
|
||||
AC_SUBST(KDRIVE_CFLAGS)
|
||||
AC_SUBST(KDRIVE_PURE_LIBS)
|
||||
AC_SUBST(KDRIVE_LIBS)
|
||||
AM_CONDITIONAL(KDRIVELINUX, [test "x$KDRIVELINUX" = xyes])
|
||||
AM_CONDITIONAL(KDRIVEVESA, [test x"$ac_cv_header_asm_vm86_h" = xyes])
|
||||
AM_CONDITIONAL(KDRIVEFBDEV, [test x"$ac_cv_header_linux_fb_h" = xyes])
|
||||
|
||||
dnl and the rest of these are generic, so they're in config.h
|
||||
AC_DEFINE(XResExtension, 1, [Build XRes extension])
|
||||
|
||||
AC_TRY_COMPILE([
|
||||
#include <features.h>
|
||||
#ifndef __GLIBC__
|
||||
#error not glibc
|
||||
#endif
|
||||
], [], [AC_DEFINE(_GNU_SOURCE, 1,
|
||||
[ Enable GNU and other extensions to the C environment for glibc])])
|
||||
|
||||
dnl ---------- Compiler arguments
|
||||
|
||||
AX_CHECK_COMPILE_FLAG([-flto],
|
||||
[CFLAGS="$CFLAGS -flto"; LDFLAGS="$LDFLAGS -flto"; ac_cv_lto_supported=yes],
|
||||
[ac_cv_lto_supported=no],
|
||||
[])
|
||||
|
||||
if test x"$ac_cv_lto_supported" = xno; then
|
||||
AC_MSG_NOTICE([LTO not supported, checking sections instead...])
|
||||
|
||||
AX_CHECK_COMPILE_FLAG([-ffunction-sections],
|
||||
[CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
|
||||
LDFLAGS="$LDFLAGS -Wl,-gc-sections"
|
||||
ac_cv_sections_supported=yes],
|
||||
[ac_cv_sections_supported=no],
|
||||
[])
|
||||
fi
|
||||
|
||||
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],
|
||||
[CFLAGS="$CFLAGS -fvisibility=hidden"; ac_cv_visibility_supported=yes],
|
||||
[ac_cv_visiblity_supported=no],
|
||||
[])
|
||||
|
||||
AX_CHECK_LINK_FLAG([-Wl,-as-needed], [LDFLAGS="$LDFLAGS -Wl,-as-needed"],
|
||||
[], [])
|
||||
|
||||
dnl ----------
|
||||
|
||||
AC_CHECK_LIB([ife],[meaning])
|
||||
|
||||
CFLAGS="$XSERVER_CFLAGS $CFLAGS -Wall"
|
||||
AC_SUBST([CFLAGS])
|
||||
|
||||
LDFLAGS="$LDFLAGS -Wl,-O1"
|
||||
AC_SUBST([LDFLAGS])
|
||||
|
||||
BUILD_DATE="$(date +'%Y%m%d')"
|
||||
AC_SUBST([BUILD_DATE])
|
||||
|
||||
DIX_CFLAGS="-DHAVE_DIX_CONFIG_H"
|
||||
AC_SUBST([DIX_CFLAGS])
|
||||
|
||||
AC_SUBST([libdir])
|
||||
AC_SUBST([exec_prefix])
|
||||
AC_SUBST([prefix])
|
||||
|
||||
# XORG in this case refers to the roll-up releases, not the Xorg DDX.
|
||||
XORG_RELEASE_VERSION
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
include/Makefile
|
||||
damageext/Makefile
|
||||
dbe/Makefile
|
||||
dix/Makefile
|
||||
fb/Makefile
|
||||
mi/Makefile
|
||||
miext/Makefile
|
||||
miext/damage/Makefile
|
||||
miext/shadow/Makefile
|
||||
os/Makefile
|
||||
randr/Makefile
|
||||
render/Makefile
|
||||
Xext/Makefile
|
||||
xfixes/Makefile
|
||||
kdrive/Makefile
|
||||
kdrive/fbdev/Makefile
|
||||
kdrive/linux/Makefile
|
||||
kdrive/src/Makefile
|
||||
kdrive/vesa/Makefile
|
||||
])
|
|
@ -0,0 +1,8 @@
|
|||
noinst_LTLIBRARIES = libdamageext.la
|
||||
|
||||
AM_CFLAGS = $(DIX_CFLAGS)
|
||||
|
||||
libdamageext_la_SOURCES = \
|
||||
damageext.c \
|
||||
damageext.h \
|
||||
damageextint.h
|
|
@ -0,0 +1,515 @@
|
|||
/*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "damageextint.h"
|
||||
#include "extinit.h"
|
||||
|
||||
unsigned char DamageReqCode;
|
||||
|
||||
int DamageEventBase;
|
||||
|
||||
int DamageErrorBase;
|
||||
|
||||
int DamageClientPrivateIndex;
|
||||
|
||||
RESTYPE DamageExtType;
|
||||
|
||||
RESTYPE DamageExtWinType;
|
||||
|
||||
/* Version of the damage extension supported by the server, as opposed to the
|
||||
* DAMAGE_* defines from damageproto for what version the proto header
|
||||
* supports.
|
||||
*/
|
||||
#define SERVER_DAMAGE_MAJOR 1
|
||||
#define SERVER_DAMAGE_MINOR 1
|
||||
|
||||
#define prScreen screenInfo.screens[0]
|
||||
|
||||
static void
|
||||
DamageExtNotify(DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes)
|
||||
{
|
||||
ClientPtr pClient = pDamageExt->pClient;
|
||||
DamageClientPtr pDamageClient = GetDamageClient(pClient);
|
||||
DrawablePtr pDrawable = pDamageExt->pDrawable;
|
||||
xDamageNotifyEvent ev;
|
||||
int i;
|
||||
|
||||
UpdateCurrentTimeIf();
|
||||
ev = (xDamageNotifyEvent) {
|
||||
.type = DamageEventBase + XDamageNotify,
|
||||
.level = pDamageExt->level,
|
||||
.drawable = pDamageExt->drawable,
|
||||
.damage = pDamageExt->id,
|
||||
.timestamp = currentTime.milliseconds,
|
||||
.geometry.x = pDrawable->x,
|
||||
.geometry.y = pDrawable->y,
|
||||
.geometry.width = pDrawable->width,
|
||||
.geometry.height = pDrawable->height
|
||||
};
|
||||
if (pBoxes) {
|
||||
for (i = 0; i < nBoxes; i++) {
|
||||
ev.level = pDamageExt->level;
|
||||
if (i < nBoxes - 1)
|
||||
ev.level |= DamageNotifyMore;
|
||||
ev.area.x = pBoxes[i].x1;
|
||||
ev.area.y = pBoxes[i].y1;
|
||||
ev.area.width = pBoxes[i].x2 - pBoxes[i].x1;
|
||||
ev.area.height = pBoxes[i].y2 - pBoxes[i].y1;
|
||||
WriteEventsToClient(pClient, 1, (xEvent *) &ev);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ev.area.x = 0;
|
||||
ev.area.y = 0;
|
||||
ev.area.width = pDrawable->width;
|
||||
ev.area.height = pDrawable->height;
|
||||
WriteEventsToClient(pClient, 1, (xEvent *) &ev);
|
||||
}
|
||||
/* Composite extension marks clients with manual Subwindows as critical */
|
||||
if (pDamageClient->critical > 0) {
|
||||
SetCriticalOutputPending();
|
||||
pClient->smart_priority = SMART_MAX_PRIORITY;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DamageExtReport(DamagePtr pDamage, RegionPtr pRegion, void *closure)
|
||||
{
|
||||
DamageExtPtr pDamageExt = closure;
|
||||
|
||||
switch (pDamageExt->level) {
|
||||
case DamageReportRawRegion:
|
||||
case DamageReportDeltaRegion:
|
||||
DamageExtNotify(pDamageExt, REGION_RECTS(pRegion),
|
||||
REGION_NUM_RECTS(pRegion));
|
||||
break;
|
||||
case DamageReportBoundingBox:
|
||||
DamageExtNotify(pDamageExt, REGION_EXTENTS(pRegion), 1);
|
||||
break;
|
||||
case DamageReportNonEmpty:
|
||||
DamageExtNotify(pDamageExt, NullBox, 0);
|
||||
break;
|
||||
case DamageReportNone:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DamageExtDestroy(DamagePtr pDamage, void *closure)
|
||||
{
|
||||
DamageExtPtr pDamageExt = closure;
|
||||
|
||||
pDamageExt->pDamage = 0;
|
||||
if (pDamageExt->id)
|
||||
FreeResource(pDamageExt->id, RT_NONE);
|
||||
}
|
||||
|
||||
void
|
||||
DamageExtSetCritical(ClientPtr pClient, Bool critical)
|
||||
{
|
||||
DamageClientPtr pDamageClient = GetDamageClient(pClient);
|
||||
|
||||
if (pDamageClient)
|
||||
pDamageClient->critical += critical ? 1 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDamageQueryVersion(ClientPtr client)
|
||||
{
|
||||
DamageClientPtr pDamageClient = GetDamageClient(client);
|
||||
|
||||
xDamageQueryVersionReply rep;
|
||||
|
||||
|
||||
REQUEST(xDamageQueryVersionReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xDamageQueryVersionReq);
|
||||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
if (stuff->majorVersion < SERVER_DAMAGE_MAJOR) {
|
||||
rep.majorVersion = stuff->majorVersion;
|
||||
rep.minorVersion = stuff->minorVersion;
|
||||
}
|
||||
else {
|
||||
rep.majorVersion = SERVER_DAMAGE_MAJOR;
|
||||
if (stuff->majorVersion == SERVER_DAMAGE_MAJOR &&
|
||||
stuff->minorVersion < SERVER_DAMAGE_MINOR)
|
||||
rep.minorVersion = stuff->minorVersion;
|
||||
else
|
||||
rep.minorVersion = SERVER_DAMAGE_MINOR;
|
||||
}
|
||||
pDamageClient->major_version = rep.majorVersion;
|
||||
pDamageClient->minor_version = rep.minorVersion;
|
||||
if (client->swapped) {
|
||||
swaps(&rep.sequenceNumber);
|
||||
swapl(&rep.length);
|
||||
swapl(&rep.majorVersion);
|
||||
swapl(&rep.minorVersion);
|
||||
}
|
||||
WriteToClient(client, sizeof(xDamageQueryVersionReply), (char *) &rep);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDamageCreate(ClientPtr client)
|
||||
{
|
||||
DrawablePtr pDrawable;
|
||||
DamageExtPtr pDamageExt;
|
||||
DamageReportLevel level;
|
||||
RegionPtr pRegion;
|
||||
|
||||
REQUEST(xDamageCreateReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xDamageCreateReq);
|
||||
LEGAL_NEW_RESOURCE(stuff->damage, client);
|
||||
SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
|
||||
SecurityReadAccess);
|
||||
switch (stuff->level) {
|
||||
case XDamageReportRawRectangles:
|
||||
level = DamageReportRawRegion;
|
||||
break;
|
||||
case XDamageReportDeltaRectangles:
|
||||
level = DamageReportDeltaRegion;
|
||||
break;
|
||||
case XDamageReportBoundingBox:
|
||||
level = DamageReportBoundingBox;
|
||||
break;
|
||||
case XDamageReportNonEmpty:
|
||||
level = DamageReportNonEmpty;
|
||||
break;
|
||||
default:
|
||||
client->errorValue = stuff->level;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
pDamageExt = malloc(sizeof(DamageExtRec));
|
||||
if (!pDamageExt)
|
||||
return BadAlloc;
|
||||
pDamageExt->id = stuff->damage;
|
||||
pDamageExt->pDrawable = pDrawable;
|
||||
pDamageExt->level = level;
|
||||
pDamageExt->pClient = client;
|
||||
pDamageExt->pDamage = DamageCreate(DamageExtReport,
|
||||
DamageExtDestroy,
|
||||
level,
|
||||
FALSE, pDrawable->pScreen, pDamageExt);
|
||||
if (!pDamageExt->pDamage) {
|
||||
free(pDamageExt);
|
||||
return BadAlloc;
|
||||
}
|
||||
if (!AddResource(stuff->damage, DamageExtType, (pointer) pDamageExt))
|
||||
return BadAlloc;
|
||||
|
||||
DamageRegister(pDamageExt->pDrawable, pDamageExt->pDamage);
|
||||
|
||||
if (pDrawable->type == DRAWABLE_WINDOW) {
|
||||
pRegion = &((WindowPtr) pDrawable)->borderClip;
|
||||
DamageDamageRegion(pDrawable, pRegion);
|
||||
}
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDamageDestroy(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDamageDestroyReq);
|
||||
DamageExtPtr pDamageExt;
|
||||
|
||||
REQUEST_SIZE_MATCH(xDamageDestroyReq);
|
||||
VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, SecurityWriteAccess);
|
||||
FreeResource(stuff->damage, RT_NONE);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDamageSubtract(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDamageSubtractReq);
|
||||
DamageExtPtr pDamageExt;
|
||||
|
||||
RegionPtr pRepair;
|
||||
|
||||
RegionPtr pParts;
|
||||
|
||||
REQUEST_SIZE_MATCH(xDamageSubtractReq);
|
||||
VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, SecurityWriteAccess);
|
||||
VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, SecurityWriteAccess);
|
||||
VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, SecurityWriteAccess);
|
||||
|
||||
if (pDamageExt->level != DamageReportRawRegion) {
|
||||
DamagePtr pDamage = pDamageExt->pDamage;
|
||||
|
||||
if (pRepair) {
|
||||
if (pParts)
|
||||
REGION_INTERSECT(pParts, DamageRegion(pDamage),
|
||||
pRepair);
|
||||
if (DamageSubtract(pDamage, pRepair))
|
||||
DamageExtReport(pDamage, DamageRegion(pDamage),
|
||||
(void *) pDamageExt);
|
||||
}
|
||||
else {
|
||||
if (pParts)
|
||||
REGION_COPY(pParts, DamageRegion(pDamage));
|
||||
DamageEmpty(pDamage);
|
||||
}
|
||||
}
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
static int
|
||||
ProcDamageAdd(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDamageAddReq);
|
||||
DrawablePtr pDrawable;
|
||||
|
||||
RegionPtr pRegion;
|
||||
|
||||
REQUEST_SIZE_MATCH(xDamageAddReq);
|
||||
VERIFY_REGION(pRegion, stuff->region, client, SecurityWriteAccess);
|
||||
SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
|
||||
SecurityReadAccess);
|
||||
|
||||
/* The region is relative to the drawable origin, so translate it out to
|
||||
* screen coordinates like damage expects.
|
||||
*/
|
||||
REGION_TRANSLATE(pRegion, pDrawable->x, pDrawable->y);
|
||||
DamageDamageRegion(pDrawable, pRegion);
|
||||
REGION_TRANSLATE(pRegion, -pDrawable->x, -pDrawable->y);
|
||||
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
/* Major version controls available requests */
|
||||
static const int version_requests[] = {
|
||||
X_DamageQueryVersion, /* before client sends QueryVersion */
|
||||
X_DamageAdd, /* Version 1 */
|
||||
};
|
||||
|
||||
#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0]))
|
||||
|
||||
int (*ProcDamageVector[XDamageNumberRequests]) (ClientPtr) = {
|
||||
/*************** Version 1 ******************/
|
||||
ProcDamageQueryVersion,
|
||||
ProcDamageCreate, ProcDamageDestroy, ProcDamageSubtract,
|
||||
/*************** Version 1.1 ****************/
|
||||
ProcDamageAdd,};
|
||||
|
||||
static int
|
||||
ProcDamageDispatch(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDamageReq);
|
||||
DamageClientPtr pDamageClient = GetDamageClient(client);
|
||||
|
||||
if (pDamageClient->major_version >= NUM_VERSION_REQUESTS)
|
||||
return BadRequest;
|
||||
if (stuff->damageReqType > version_requests[pDamageClient->major_version])
|
||||
return BadRequest;
|
||||
return (*ProcDamageVector[stuff->damageReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDamageQueryVersion(ClientPtr client)
|
||||
{
|
||||
|
||||
REQUEST(xDamageQueryVersionReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDamageQueryVersionReq);
|
||||
swapl(&stuff->majorVersion);
|
||||
swapl(&stuff->minorVersion);
|
||||
return (*ProcDamageVector[stuff->damageReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDamageCreate(ClientPtr client)
|
||||
{
|
||||
|
||||
REQUEST(xDamageCreateReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDamageCreateReq);
|
||||
swapl(&stuff->damage);
|
||||
swapl(&stuff->drawable);
|
||||
return (*ProcDamageVector[stuff->damageReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDamageDestroy(ClientPtr client)
|
||||
{
|
||||
|
||||
REQUEST(xDamageDestroyReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDamageDestroyReq);
|
||||
swapl(&stuff->damage);
|
||||
return (*ProcDamageVector[stuff->damageReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDamageSubtract(ClientPtr client)
|
||||
{
|
||||
|
||||
REQUEST(xDamageSubtractReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDamageSubtractReq);
|
||||
swapl(&stuff->damage);
|
||||
swapl(&stuff->repair);
|
||||
swapl(&stuff->parts);
|
||||
return (*ProcDamageVector[stuff->damageReqType]) (client);
|
||||
}
|
||||
|
||||
static int
|
||||
SProcDamageAdd(ClientPtr client)
|
||||
{
|
||||
|
||||
REQUEST(xDamageAddReq);
|
||||
|
||||
swaps(&stuff->length);
|
||||
REQUEST_SIZE_MATCH(xDamageSubtractReq);
|
||||
swapl(&stuff->drawable);
|
||||
swapl(&stuff->region);
|
||||
return (*ProcDamageVector[stuff->damageReqType]) (client);
|
||||
}
|
||||
|
||||
int (*SProcDamageVector[XDamageNumberRequests]) (ClientPtr) = {
|
||||
/*************** Version 1 ******************/
|
||||
SProcDamageQueryVersion,
|
||||
SProcDamageCreate, SProcDamageDestroy, SProcDamageSubtract,
|
||||
/*************** Version 1.1 ****************/
|
||||
SProcDamageAdd,};
|
||||
|
||||
static int
|
||||
SProcDamageDispatch(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDamageReq);
|
||||
if (stuff->damageReqType >= XDamageNumberRequests)
|
||||
return BadRequest;
|
||||
return (*SProcDamageVector[stuff->damageReqType]) (client);
|
||||
}
|
||||
|
||||
static void
|
||||
DamageClientCallback(CallbackListPtr *list, pointer closure, pointer data)
|
||||
{
|
||||
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
|
||||
ClientPtr pClient = clientinfo->client;
|
||||
DamageClientPtr pDamageClient = GetDamageClient(pClient);
|
||||
|
||||
pDamageClient->critical = 0;
|
||||
pDamageClient->major_version = 0;
|
||||
pDamageClient->minor_version = 0;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/ static void
|
||||
DamageResetProc(ExtensionEntry * extEntry)
|
||||
{
|
||||
DeleteCallback(&ClientStateCallback, DamageClientCallback, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
FreeDamageExt(pointer value, XID did)
|
||||
{
|
||||
DamageExtPtr pDamageExt = (DamageExtPtr) value;
|
||||
|
||||
/*
|
||||
* Get rid of the resource table entry hanging from the window id
|
||||
*/
|
||||
pDamageExt->id = 0;
|
||||
if (WindowDrawable(pDamageExt->pDrawable->type))
|
||||
FreeResourceByType(pDamageExt->pDrawable->id, DamageExtWinType, TRUE);
|
||||
if (pDamageExt->pDamage) {
|
||||
DamageUnregister(pDamageExt->pDrawable, pDamageExt->pDamage);
|
||||
DamageDestroy(pDamageExt->pDamage);
|
||||
}
|
||||
free(pDamageExt);
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
FreeDamageExtWin(pointer value, XID wid)
|
||||
{
|
||||
DamageExtPtr pDamageExt = (DamageExtPtr) value;
|
||||
|
||||
if (pDamageExt->id)
|
||||
FreeResource(pDamageExt->id, RT_NONE);
|
||||
return Success;
|
||||
}
|
||||
|
||||
void
|
||||
SDamageNotifyEvent(xDamageNotifyEvent * from, xDamageNotifyEvent * to)
|
||||
{
|
||||
to->type = from->type;
|
||||
cpswaps(from->sequenceNumber, to->sequenceNumber);
|
||||
cpswapl(from->drawable, to->drawable);
|
||||
cpswapl(from->damage, to->damage);
|
||||
cpswaps(from->area.x, to->area.x);
|
||||
cpswaps(from->area.y, to->area.y);
|
||||
cpswaps(from->area.width, to->area.width);
|
||||
cpswaps(from->area.height, to->area.height);
|
||||
cpswaps(from->geometry.x, to->geometry.x);
|
||||
cpswaps(from->geometry.y, to->geometry.y);
|
||||
cpswaps(from->geometry.width, to->geometry.width);
|
||||
cpswaps(from->geometry.height, to->geometry.height);
|
||||
}
|
||||
|
||||
void
|
||||
DamageExtensionInit(void)
|
||||
{
|
||||
ExtensionEntry *extEntry;
|
||||
|
||||
int s;
|
||||
|
||||
for (s = 0; s < screenInfo.numScreens; s++)
|
||||
DamageSetup(screenInfo.screens[s]);
|
||||
|
||||
DamageExtType = CreateNewResourceType(FreeDamageExt);
|
||||
if (!DamageExtType)
|
||||
return;
|
||||
|
||||
DamageExtWinType = CreateNewResourceType(FreeDamageExtWin);
|
||||
if (!DamageExtWinType)
|
||||
return;
|
||||
|
||||
DamageClientPrivateIndex = AllocateClientPrivateIndex();
|
||||
if (!AllocateClientPrivate(DamageClientPrivateIndex,
|
||||
sizeof(DamageClientRec)))
|
||||
return;
|
||||
if (!AddCallback(&ClientStateCallback, DamageClientCallback, 0))
|
||||
return;
|
||||
|
||||
if ((extEntry = AddExtension(DAMAGE_NAME, XDamageNumberEvents,
|
||||
XDamageNumberErrors,
|
||||
ProcDamageDispatch, SProcDamageDispatch,
|
||||
DamageResetProc, StandardMinorOpcode)) != 0) {
|
||||
DamageReqCode = (unsigned char) extEntry->base;
|
||||
DamageEventBase = extEntry->eventBase;
|
||||
DamageErrorBase = extEntry->errorBase;
|
||||
EventSwapVector[DamageEventBase + XDamageNotify] =
|
||||
(EventSwapPtr) SDamageNotifyEvent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _DAMAGEEXT_H_
|
||||
#define _DAMAGEEXT_H_
|
||||
|
||||
void
|
||||
DamageExtensionInit(void);
|
||||
|
||||
#endif /* _DAMAGEEXT_H_ */
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _DAMAGEEXTINT_H_
|
||||
#define _DAMAGEEXTINT_H_
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include <X11/extensions/damageproto.h>
|
||||
#include "windowstr.h"
|
||||
#include "selection.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "damageext.h"
|
||||
#include "damage.h"
|
||||
#include "xfixes.h"
|
||||
|
||||
extern unsigned char DamageReqCode;
|
||||
|
||||
extern int DamageEventBase;
|
||||
|
||||
extern int DamageErrorBase;
|
||||
|
||||
extern int DamageClientPrivateIndex;
|
||||
|
||||
extern RESTYPE DamageExtType;
|
||||
|
||||
extern RESTYPE DamageExtWinType;
|
||||
|
||||
typedef struct _DamageClient {
|
||||
CARD32 major_version;
|
||||
CARD32 minor_version;
|
||||
int critical;
|
||||
} DamageClientRec, *DamageClientPtr;
|
||||
|
||||
#define GetDamageClient(pClient) ((DamageClientPtr) (pClient)->devPrivates[DamageClientPrivateIndex].ptr)
|
||||
|
||||
typedef struct _DamageExt {
|
||||
DamagePtr pDamage;
|
||||
DrawablePtr pDrawable;
|
||||
DamageReportLevel level;
|
||||
ClientPtr pClient;
|
||||
XID id;
|
||||
XID drawable;
|
||||
} DamageExtRec, *DamageExtPtr;
|
||||
|
||||
extern int (*ProcDamageVector[ /*XDamageNumberRequests */ ]) (ClientPtr);
|
||||
|
||||
extern int (*SProcDamageVector[ /*XDamageNumberRequests */ ]) (ClientPtr);
|
||||
|
||||
#define VERIFY_DAMAGEEXT(pDamageExt, rid, client, mode) { \
|
||||
pDamageExt = SecurityLookupIDByType (client, rid, DamageExtType, mode); \
|
||||
if (!pDamageExt) { \
|
||||
client->errorValue = rid; \
|
||||
return DamageErrorBase + BadDamage; \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
SDamageNotifyEvent(xDamageNotifyEvent * from, xDamageNotifyEvent * to);
|
||||
|
||||
void
|
||||
DamageExtSetCritical(ClientPtr pClient, Bool critical);
|
||||
|
||||
#endif /* _DAMAGEEXTINT_H_ */
|
|
@ -0,0 +1,10 @@
|
|||
noinst_LTLIBRARIES = libdbe.la
|
||||
|
||||
AM_CFLAGS = $(DIX_CFLAGS)
|
||||
|
||||
libdbe_la_SOURCES = \
|
||||
dbe.c \
|
||||
dbestruct.h \
|
||||
midbe.c \
|
||||
midbe.h \
|
||||
midbestr.h
|
|
@ -0,0 +1,226 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (c) 1994, 1995 Hewlett-Packard Company
|
||||
*
|
||||
* 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 HEWLETT-PACKARD COMPANY 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.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Hewlett-Packard
|
||||
* Company shall not be used in advertising or otherwise to promote the
|
||||
* sale, use or other dealings in this Software without prior written
|
||||
* authorization from the Hewlett-Packard Company.
|
||||
*
|
||||
* Header file for DIX-related DBE
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef DBE_STRUCT_H
|
||||
#define DBE_STRUCT_H
|
||||
|
||||
/* INCLUDES */
|
||||
|
||||
#define NEED_DBE_PROTOCOL
|
||||
#include <X11/extensions/dbeproto.h>
|
||||
#include "windowstr.h"
|
||||
|
||||
typedef struct {
|
||||
VisualID visual; /* one visual ID that supports double-buffering */
|
||||
int depth; /* depth of visual in bits */
|
||||
int perflevel; /* performance level of visual */
|
||||
} XdbeVisualInfo;
|
||||
|
||||
typedef struct {
|
||||
int count; /* number of items in visual_depth */
|
||||
XdbeVisualInfo *visinfo; /* list of visuals & depths for scrn */
|
||||
} XdbeScreenVisualInfo;
|
||||
|
||||
/* DEFINES */
|
||||
|
||||
#define DBE_SCREEN_PRIV(pScreen) \
|
||||
((dbeScreenPrivIndex < 0) ? \
|
||||
NULL : \
|
||||
((DbeScreenPrivPtr)((pScreen)->devPrivates[dbeScreenPrivIndex].ptr)))
|
||||
|
||||
#define DBE_SCREEN_PRIV_FROM_DRAWABLE(pDrawable) \
|
||||
DBE_SCREEN_PRIV((pDrawable)->pScreen)
|
||||
|
||||
#define DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(pDbeWindowPriv) \
|
||||
DBE_SCREEN_PRIV((pDbeWindowPriv)->pWindow->drawable.pScreen)
|
||||
|
||||
#define DBE_SCREEN_PRIV_FROM_WINDOW(pWindow) \
|
||||
DBE_SCREEN_PRIV((pWindow)->drawable.pScreen)
|
||||
|
||||
#define DBE_SCREEN_PRIV_FROM_PIXMAP(pPixmap) \
|
||||
DBE_SCREEN_PRIV((pPixmap)->drawable.pScreen)
|
||||
|
||||
#define DBE_SCREEN_PRIV_FROM_GC(pGC)\
|
||||
DBE_SCREEN_PRIV((pGC)->pScreen)
|
||||
|
||||
#define DBE_WINDOW_PRIV(pWindow)\
|
||||
((dbeWindowPrivIndex < 0) ? \
|
||||
NULL : \
|
||||
((DbeWindowPrivPtr)(pWindow->devPrivates[dbeWindowPrivIndex].ptr)))
|
||||
|
||||
/* Initial size of the buffer ID array in the window priv. */
|
||||
#define DBE_INIT_MAX_IDS 2
|
||||
|
||||
/* Reallocation increment for the buffer ID array. */
|
||||
#define DBE_INCR_MAX_IDS 4
|
||||
|
||||
/* Marker for free elements in the buffer ID array. */
|
||||
#define DBE_FREE_ID_ELEMENT 0
|
||||
|
||||
/* TYPEDEFS */
|
||||
|
||||
/* Record used to pass swap information between DIX and DDX swapping
|
||||
* procedures.
|
||||
*/
|
||||
typedef struct _DbeSwapInfoRec {
|
||||
WindowPtr pWindow;
|
||||
unsigned char swapAction;
|
||||
|
||||
} DbeSwapInfoRec, *DbeSwapInfoPtr;
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
** Per-window data
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct _DbeWindowPrivRec {
|
||||
/* A pointer to the window with which the DBE window private (buffer) is
|
||||
* associated.
|
||||
*/
|
||||
WindowPtr pWindow;
|
||||
|
||||
/* Last known swap action for this buffer. Legal values for this field
|
||||
* are XdbeUndefined, XdbeBackground, XdbeUntouched, and XdbeCopied.
|
||||
*/
|
||||
unsigned char swapAction;
|
||||
|
||||
/* Last known buffer size.
|
||||
*/
|
||||
unsigned short width, height;
|
||||
|
||||
/* Coordinates used for static gravity when the window is positioned.
|
||||
*/
|
||||
short x, y;
|
||||
|
||||
/* Number of XIDs associated with this buffer.
|
||||
*/
|
||||
int nBufferIDs;
|
||||
|
||||
/* Capacity of the current buffer ID array, IDs. */
|
||||
int maxAvailableIDs;
|
||||
|
||||
/* Pointer to the array of buffer IDs. This initially points to initIDs.
|
||||
* When the static limit of the initIDs array is reached, the array is
|
||||
* reallocated and this pointer is set to the new array instead of initIDs.
|
||||
*/
|
||||
XID *IDs;
|
||||
|
||||
/* Initial array of buffer IDs. We are defining the XID array within the
|
||||
* window priv to optimize for data locality. In most cases, only one
|
||||
* buffer will be associated with a window. Having the array declared
|
||||
* here can prevent us from accessing the data in another memory page,
|
||||
* possibly resulting in a page swap and loss of performance. Initially we
|
||||
* will use this array to store buffer IDs. For situations where we have
|
||||
* more IDs than can fit in this static array, we will allocate a larger
|
||||
* array to use, possibly suffering a performance loss.
|
||||
*/
|
||||
XID initIDs[DBE_INIT_MAX_IDS];
|
||||
|
||||
/* Device-specific private information.
|
||||
*/
|
||||
DevUnion *devPrivates;
|
||||
|
||||
} DbeWindowPrivRec, *DbeWindowPrivPtr;
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
** Per-screen data
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct _DbeScreenPrivRec {
|
||||
/* Info for creating window privs */
|
||||
int winPrivPrivLen; /* Length of privs in DbeWindowPrivRec */
|
||||
unsigned int *winPrivPrivSizes; /* Array of private record sizes */
|
||||
unsigned int totalWinPrivSize; /* PrivRec + size of all priv priv ptrs */
|
||||
|
||||
/* Resources created by DIX to be used by DDX */
|
||||
RESTYPE dbeDrawableResType;
|
||||
RESTYPE dbeWindowPrivResType;
|
||||
|
||||
/* Private indices created by DIX to be used by DDX */
|
||||
int dbeScreenPrivIndex;
|
||||
int dbeWindowPrivIndex;
|
||||
|
||||
/* Wrapped functions
|
||||
* It is the responsibilty of the DDX layer to wrap PositionWindow().
|
||||
* DbeExtensionInit wraps DestroyWindow().
|
||||
*/
|
||||
PositionWindowProcPtr PositionWindow;
|
||||
DestroyWindowProcPtr DestroyWindow;
|
||||
|
||||
/* Per-screen DIX routines */
|
||||
Bool (*SetupBackgroundPainter) (WindowPtr /*pWin */ ,
|
||||
GCPtr /*pGC */
|
||||
);
|
||||
DbeWindowPrivPtr(*AllocWinPriv) (ScreenPtr /*pScreen */
|
||||
);
|
||||
int (*AllocWinPrivPrivIndex) (void);
|
||||
Bool (*AllocWinPrivPriv) (ScreenPtr /*pScreen */ ,
|
||||
int /*index */ ,
|
||||
unsigned /*amount */
|
||||
);
|
||||
|
||||
/* Per-screen DDX routines */
|
||||
Bool (*GetVisualInfo) (ScreenPtr /*pScreen */ ,
|
||||
XdbeScreenVisualInfo * /*pVisInfo */
|
||||
);
|
||||
int (*AllocBackBufferName) (WindowPtr /*pWin */ ,
|
||||
XID /*bufId */ ,
|
||||
int /*swapAction */
|
||||
);
|
||||
int (*SwapBuffers) (ClientPtr /*client */ ,
|
||||
int * /*pNumWindows */ ,
|
||||
DbeSwapInfoPtr /*swapInfo */
|
||||
);
|
||||
void (*BeginIdiom) (ClientPtr /*client */
|
||||
);
|
||||
void (*EndIdiom) (ClientPtr /*client */
|
||||
);
|
||||
void (*WinPrivDelete) (DbeWindowPrivPtr /*pDbeWindowPriv */ ,
|
||||
XID /*bufId */
|
||||
);
|
||||
void (*ResetProc) (ScreenPtr /*pScreen */
|
||||
);
|
||||
void (*ValidateBuffer) (WindowPtr /*pWin */ ,
|
||||
XID /*bufId */ ,
|
||||
Bool /*dstbuffer */
|
||||
);
|
||||
|
||||
/* Device-specific private information.
|
||||
*/
|
||||
DevUnion *devPrivates;
|
||||
|
||||
} DbeScreenPrivRec, *DbeScreenPrivPtr;
|
||||
|
||||
#endif /* DBE_STRUCT_H */
|
|
@ -0,0 +1,791 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (c) 1994, 1995 Hewlett-Packard Company
|
||||
*
|
||||
* 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 HEWLETT-PACKARD COMPANY 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.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Hewlett-Packard
|
||||
* Company shall not be used in advertising or otherwise to promote the
|
||||
* sale, use or other dealings in this Software without prior written
|
||||
* authorization from the Hewlett-Packard Company.
|
||||
*
|
||||
* Machine-independent DBE code
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* INCLUDES */
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "windowstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "extnsionst.h"
|
||||
#include "dixstruct.h"
|
||||
#include "resource.h"
|
||||
#include "opaque.h"
|
||||
#include "dbestruct.h"
|
||||
#include "midbestr.h"
|
||||
#include "regionstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "inputstr.h"
|
||||
#include "midbe.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* DEFINES */
|
||||
|
||||
/* TYPEDEFS */
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
static int miDbePrivPrivGeneration = 0;
|
||||
|
||||
static int miDbeWindowPrivPrivIndex = -1;
|
||||
|
||||
RESTYPE dbeDrawableResType;
|
||||
|
||||
RESTYPE dbeWindowPrivResType;
|
||||
|
||||
int dbeScreenPrivIndex = -1;
|
||||
|
||||
int dbeWindowPrivIndex = -1;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DBE MI Procedure: miDbeGetVisualInfo
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This is the MI function for the DbeGetVisualInfo request. This function
|
||||
* is called through pDbeScreenPriv->GetVisualInfo. This function is also
|
||||
* called for the DbeAllocateBackBufferName request at the extension level;
|
||||
* it is called by ProcDbeAllocateBackBufferName() in dbe.c.
|
||||
*
|
||||
* If memory allocation fails or we can not get the visual info, this
|
||||
* function returns FALSE. Otherwise, it returns TRUE for success.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static Bool
|
||||
miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo)
|
||||
{
|
||||
int i, j, k;
|
||||
int count;
|
||||
DepthPtr pDepth;
|
||||
XdbeVisualInfo *visInfo;
|
||||
|
||||
/* Determine number of visuals for this screen. */
|
||||
for (i = 0, count = 0; i < pScreen->numDepths; i++) {
|
||||
count += pScreen->allowedDepths[i].numVids;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return FALSE;
|
||||
|
||||
/* Allocate an array of XdbeVisualInfo items. */
|
||||
if (!(visInfo = malloc(count * sizeof(XdbeVisualInfo)))) {
|
||||
return FALSE; /* memory alloc failure */
|
||||
}
|
||||
|
||||
for (i = 0, k = 0; i < pScreen->numDepths; i++) {
|
||||
/* For each depth of this screen, get visual information. */
|
||||
|
||||
pDepth = &pScreen->allowedDepths[i];
|
||||
|
||||
for (j = 0; j < pDepth->numVids; j++) {
|
||||
/* For each visual for this depth of this screen, get visual ID
|
||||
* and visual depth. Since this is MI code, we will always return
|
||||
* the same performance level for all visuals (0). A higher
|
||||
* performance level value indicates higher performance.
|
||||
*/
|
||||
visInfo[k].visual = pDepth->vids[j];
|
||||
visInfo[k].depth = pDepth->depth;
|
||||
visInfo[k].perflevel = 0;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Record the number of visuals and point visual_depth to
|
||||
* the array of visual info.
|
||||
*/
|
||||
pScrVisInfo->count = count;
|
||||
pScrVisInfo->visinfo = visInfo;
|
||||
|
||||
return TRUE; /* success */
|
||||
|
||||
} /* miDbeGetVisualInfo() */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DBE MI Procedure: miAllocBackBufferName
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This is the MI function for the DbeAllocateBackBufferName request.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static int
|
||||
miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction)
|
||||
{
|
||||
ScreenPtr pScreen;
|
||||
|
||||
DbeWindowPrivPtr pDbeWindowPriv;
|
||||
|
||||
MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
|
||||
|
||||
DbeScreenPrivPtr pDbeScreenPriv;
|
||||
|
||||
GCPtr pGC;
|
||||
|
||||
xRectangle clearRect;
|
||||
|
||||
pScreen = pWin->drawable.pScreen;
|
||||
pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
|
||||
|
||||
if (pDbeWindowPriv->nBufferIDs == 0) {
|
||||
/* There is no buffer associated with the window.
|
||||
* We have to create the window priv priv. Remember, the window
|
||||
* priv was created at the DIX level, so all we need to do is
|
||||
* create the priv priv and attach it to the priv.
|
||||
*/
|
||||
|
||||
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
|
||||
|
||||
/* Setup the window priv priv. */
|
||||
pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
|
||||
pDbeWindowPrivPriv->pDbeWindowPriv = pDbeWindowPriv;
|
||||
|
||||
/* Get a front pixmap. */
|
||||
if (!(pDbeWindowPrivPriv->pFrontBuffer =
|
||||
(*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width,
|
||||
pDbeWindowPriv->height,
|
||||
pWin->drawable.depth))) {
|
||||
return (BadAlloc);
|
||||
}
|
||||
|
||||
/* Get a back pixmap. */
|
||||
if (!(pDbeWindowPrivPriv->pBackBuffer =
|
||||
(*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width,
|
||||
pDbeWindowPriv->height,
|
||||
pWin->drawable.depth))) {
|
||||
(*pScreen->DestroyPixmap) (pDbeWindowPrivPriv->pFrontBuffer);
|
||||
return (BadAlloc);
|
||||
}
|
||||
|
||||
/* Make the back pixmap a DBE drawable resource. */
|
||||
if (!AddResource(bufId, dbeDrawableResType,
|
||||
(pointer) pDbeWindowPrivPriv->pBackBuffer)) {
|
||||
/* free the buffer and the drawable resource */
|
||||
FreeResource(bufId, RT_NONE);
|
||||
return (BadAlloc);
|
||||
}
|
||||
|
||||
/* Attach the priv priv to the priv. */
|
||||
pDbeWindowPriv->devPrivates[miDbeWindowPrivPrivIndex].ptr =
|
||||
(pointer) pDbeWindowPrivPriv;
|
||||
|
||||
/* Clear the back buffer. */
|
||||
pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
|
||||
if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) {
|
||||
ValidateGC((DrawablePtr) pDbeWindowPrivPriv->pBackBuffer, pGC);
|
||||
clearRect.x = clearRect.y = 0;
|
||||
clearRect.width = pDbeWindowPrivPriv->pBackBuffer->drawable.width;
|
||||
clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height;
|
||||
(*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPrivPriv->
|
||||
pBackBuffer, pGC, 1, &clearRect);
|
||||
}
|
||||
FreeScratchGC(pGC);
|
||||
|
||||
} /* if no buffer associated with the window */
|
||||
|
||||
else {
|
||||
/* A buffer is already associated with the window.
|
||||
* Place the new buffer ID information at the head of the ID list.
|
||||
*/
|
||||
|
||||
/* Associate the new ID with an existing pixmap. */
|
||||
pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
|
||||
if (!AddResource(bufId, dbeDrawableResType,
|
||||
(pointer) pDbeWindowPrivPriv->pBackBuffer)) {
|
||||
return (BadAlloc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (Success);
|
||||
|
||||
} /* miDbeAllocBackBufferName() */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DBE MI Procedure: miDbeAliasBuffers
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function associates all XIDs of a buffer with the back pixmap
|
||||
* stored in the window priv.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void
|
||||
miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv)
|
||||
{
|
||||
int i;
|
||||
|
||||
MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv =
|
||||
MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
|
||||
|
||||
for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) {
|
||||
ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType,
|
||||
(pointer) pDbeWindowPrivPriv->pBackBuffer);
|
||||
}
|
||||
|
||||
} /* miDbeAliasBuffers() */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DBE MI Procedure: miDbeSwapBuffers
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This is the MI function for the DbeSwapBuffers request.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static int
|
||||
miDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo)
|
||||
{
|
||||
DbeScreenPrivPtr pDbeScreenPriv;
|
||||
|
||||
GCPtr pGC;
|
||||
|
||||
WindowPtr pWin;
|
||||
|
||||
MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
|
||||
|
||||
PixmapPtr pTmpBuffer;
|
||||
|
||||
xRectangle clearRect;
|
||||
|
||||
pWin = swapInfo[0].pWindow;
|
||||
pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
|
||||
pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin);
|
||||
pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
** Setup before swap.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
switch (swapInfo[0].swapAction) {
|
||||
case XdbeUndefined:
|
||||
break;
|
||||
|
||||
case XdbeBackground:
|
||||
break;
|
||||
|
||||
case XdbeUntouched:
|
||||
ValidateGC((DrawablePtr) pDbeWindowPrivPriv->pFrontBuffer, pGC);
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pWin,
|
||||
(DrawablePtr) pDbeWindowPrivPriv->pFrontBuffer,
|
||||
pGC, 0, 0, pWin->drawable.width,
|
||||
pWin->drawable.height, 0, 0);
|
||||
break;
|
||||
|
||||
case XdbeCopied:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
** Swap.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
ValidateGC((DrawablePtr) pWin, pGC);
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPrivPriv->pBackBuffer,
|
||||
(DrawablePtr) pWin, pGC, 0, 0,
|
||||
pWin->drawable.width, pWin->drawable.height, 0, 0);
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
** Tasks after swap.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
switch (swapInfo[0].swapAction) {
|
||||
case XdbeUndefined:
|
||||
break;
|
||||
|
||||
case XdbeBackground:
|
||||
if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) {
|
||||
ValidateGC((DrawablePtr) pDbeWindowPrivPriv->pBackBuffer, pGC);
|
||||
clearRect.x = 0;
|
||||
clearRect.y = 0;
|
||||
clearRect.width = pDbeWindowPrivPriv->pBackBuffer->drawable.width;
|
||||
clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height;
|
||||
(*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPrivPriv->
|
||||
pBackBuffer, pGC, 1, &clearRect);
|
||||
}
|
||||
break;
|
||||
|
||||
case XdbeUntouched:
|
||||
/* Swap pixmap pointers. */
|
||||
pTmpBuffer = pDbeWindowPrivPriv->pBackBuffer;
|
||||
pDbeWindowPrivPriv->pBackBuffer = pDbeWindowPrivPriv->pFrontBuffer;
|
||||
pDbeWindowPrivPriv->pFrontBuffer = pTmpBuffer;
|
||||
|
||||
miDbeAliasBuffers(pDbeWindowPrivPriv->pDbeWindowPriv);
|
||||
|
||||
break;
|
||||
|
||||
case XdbeCopied:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* Remove the swapped window from the swap information array and decrement
|
||||
* pNumWindows to indicate to the DIX level how many windows were actually
|
||||
* swapped.
|
||||
*/
|
||||
|
||||
if (*pNumWindows > 1) {
|
||||
/* We were told to swap more than one window, but we only swapped the
|
||||
* first one. Remove the first window in the list by moving the last
|
||||
* window to the beginning.
|
||||
*/
|
||||
swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow;
|
||||
swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction;
|
||||
|
||||
/* Clear the last window information just to be safe. */
|
||||
swapInfo[*pNumWindows - 1].pWindow = (WindowPtr) NULL;
|
||||
swapInfo[*pNumWindows - 1].swapAction = 0;
|
||||
}
|
||||
else {
|
||||
/* Clear the window information just to be safe. */
|
||||
swapInfo[0].pWindow = (WindowPtr) NULL;
|
||||
swapInfo[0].swapAction = 0;
|
||||
}
|
||||
|
||||
(*pNumWindows)--;
|
||||
|
||||
FreeScratchGC(pGC);
|
||||
|
||||
return Success;
|
||||
|
||||
} /* miSwapBuffers() */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DBE MI Procedure: miDbeWinPrivDelete
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This is the MI function for deleting the dbeWindowPrivResType resource.
|
||||
* This function is invoked indirectly by calling FreeResource() to free
|
||||
* the resources associated with a DBE buffer ID. There are 5 ways that
|
||||
* miDbeWinPrivDelete() can be called by FreeResource(). They are:
|
||||
*
|
||||
* - A DBE window is destroyed, in which case the DbeDestroyWindow()
|
||||
* wrapper is invoked. The wrapper calls FreeResource() for all DBE
|
||||
* buffer IDs.
|
||||
*
|
||||
* - miDbeAllocBackBufferName() calls FreeResource() to clean up resources
|
||||
* after a buffer allocation failure.
|
||||
*
|
||||
* - The PositionWindow wrapper, miDbePositionWindow(), calls
|
||||
* FreeResource() when it fails to create buffers of the new size.
|
||||
* FreeResource() is called for all DBE buffer IDs.
|
||||
*
|
||||
* - FreeClientResources() calls FreeResource() when a client dies or the
|
||||
* the server resets.
|
||||
*
|
||||
* When FreeResource() is called for a DBE buffer ID, the delete function
|
||||
* for the only other type of DBE resource, dbeDrawableResType, is also
|
||||
* invoked. This delete function (DbeDrawableDelete) is a NOOP to make
|
||||
* resource deletion easier. It is not guaranteed which delete function is
|
||||
* called first. Hence, we will let miDbeWinPrivDelete() free all DBE
|
||||
* resources.
|
||||
*
|
||||
* This function deletes/frees the following stuff associated with
|
||||
* the window private:
|
||||
*
|
||||
* - the ID node in the ID list representing the passed in ID.
|
||||
*
|
||||
* In addition, pDbeWindowPriv->nBufferIDs is decremented.
|
||||
*
|
||||
* If this function is called for the last/only buffer ID for a window,
|
||||
* these are additionally deleted/freed:
|
||||
*
|
||||
* - the front and back pixmaps
|
||||
* - the window priv itself
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void
|
||||
miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId)
|
||||
{
|
||||
MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
|
||||
|
||||
if (pDbeWindowPriv->nBufferIDs != 0) {
|
||||
/* We still have at least one more buffer ID associated with this
|
||||
* window.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* We have no more buffer IDs associated with this window. We need to
|
||||
* free some stuff.
|
||||
*/
|
||||
|
||||
pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
|
||||
|
||||
/* Destroy the front and back pixmaps. */
|
||||
if (pDbeWindowPrivPriv->pFrontBuffer) {
|
||||
(*pDbeWindowPriv->pWindow->drawable.pScreen->
|
||||
DestroyPixmap) (pDbeWindowPrivPriv->pFrontBuffer);
|
||||
}
|
||||
if (pDbeWindowPrivPriv->pBackBuffer) {
|
||||
(*pDbeWindowPriv->pWindow->drawable.pScreen->
|
||||
DestroyPixmap) (pDbeWindowPrivPriv->pBackBuffer);
|
||||
}
|
||||
|
||||
} /* miDbeWinPrivDelete() */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DBE MI Procedure: miDbePositionWindow
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function was cloned from miMbxPositionWindow() in mimultibuf.c.
|
||||
* This function resizes the buffer when the window is resized.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static Bool
|
||||
miDbePositionWindow(WindowPtr pWin, int x, int y)
|
||||
{
|
||||
ScreenPtr pScreen;
|
||||
DbeScreenPrivPtr pDbeScreenPriv;
|
||||
DbeWindowPrivPtr pDbeWindowPriv;
|
||||
int width, height;
|
||||
int dx, dy, dw, dh;
|
||||
int sourcex, sourcey;
|
||||
int destx, desty;
|
||||
int savewidth, saveheight;
|
||||
PixmapPtr pFrontBuffer;
|
||||
PixmapPtr pBackBuffer;
|
||||
Bool clear;
|
||||
GCPtr pGC;
|
||||
xRectangle clearRect;
|
||||
Bool ret;
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
** 1. Unwrap the member routine.
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
pScreen = pWin->drawable.pScreen;
|
||||
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
|
||||
pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
** 2. Do any work necessary before the member routine is called.
|
||||
**
|
||||
** In this case we do not need to do anything.
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
** 3. Call the member routine, saving its result if necessary.
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
ret = (*pScreen->PositionWindow) (pWin, x, y);
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
** 4. Rewrap the member routine, restoring the wrapper value first in case
|
||||
** the wrapper (or something that it wrapped) change this value.
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
|
||||
pScreen->PositionWindow = miDbePositionWindow;
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
** 5. Do any work necessary after the member routine has been called.
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pDbeWindowPriv->width == pWin->drawable.width &&
|
||||
pDbeWindowPriv->height == pWin->drawable.height) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
width = pWin->drawable.width;
|
||||
height = pWin->drawable.height;
|
||||
|
||||
dx = pWin->drawable.x - pDbeWindowPriv->x;
|
||||
dy = pWin->drawable.y - pDbeWindowPriv->y;
|
||||
dw = width - pDbeWindowPriv->width;
|
||||
dh = height - pDbeWindowPriv->height;
|
||||
|
||||
GravityTranslate(0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty);
|
||||
|
||||
clear = ((pDbeWindowPriv->width < (unsigned short) width) ||
|
||||
(pDbeWindowPriv->height < (unsigned short) height) ||
|
||||
(pWin->bitGravity == ForgetGravity));
|
||||
|
||||
sourcex = 0;
|
||||
sourcey = 0;
|
||||
savewidth = pDbeWindowPriv->width;
|
||||
saveheight = pDbeWindowPriv->height;
|
||||
|
||||
/* Clip rectangle to source and destination. */
|
||||
if (destx < 0) {
|
||||
savewidth += destx;
|
||||
sourcex -= destx;
|
||||
destx = 0;
|
||||
}
|
||||
|
||||
if (destx + savewidth > width) {
|
||||
savewidth = width - destx;
|
||||
}
|
||||
|
||||
if (desty < 0) {
|
||||
saveheight += desty;
|
||||
sourcey -= desty;
|
||||
desty = 0;
|
||||
}
|
||||
|
||||
if (desty + saveheight > height) {
|
||||
saveheight = height - desty;
|
||||
}
|
||||
|
||||
pDbeWindowPriv->width = width;
|
||||
pDbeWindowPriv->height = height;
|
||||
pDbeWindowPriv->x = pWin->drawable.x;
|
||||
pDbeWindowPriv->y = pWin->drawable.y;
|
||||
|
||||
pGC = GetScratchGC(pWin->drawable.depth, pScreen);
|
||||
|
||||
if (clear) {
|
||||
if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) {
|
||||
clearRect.x = 0;
|
||||
clearRect.y = 0;
|
||||
clearRect.width = width;
|
||||
clearRect.height = height;
|
||||
}
|
||||
else {
|
||||
clear = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create DBE buffer pixmaps equal to size of resized window. */
|
||||
pFrontBuffer = (*pScreen->CreatePixmap) (pScreen, width, height,
|
||||
pWin->drawable.depth);
|
||||
|
||||
pBackBuffer = (*pScreen->CreatePixmap) (pScreen, width, height,
|
||||
pWin->drawable.depth);
|
||||
|
||||
if (!pFrontBuffer || !pBackBuffer) {
|
||||
/* We failed at creating 1 or 2 of the pixmaps. */
|
||||
|
||||
if (pFrontBuffer) {
|
||||
(*pScreen->DestroyPixmap) (pFrontBuffer);
|
||||
}
|
||||
|
||||
if (pBackBuffer) {
|
||||
(*pScreen->DestroyPixmap) (pBackBuffer);
|
||||
}
|
||||
|
||||
/* Destroy all buffers for this window. */
|
||||
while (pDbeWindowPriv) {
|
||||
/* DbeWindowPrivDelete() will free the window private if there no
|
||||
* more buffer IDs associated with this window.
|
||||
*/
|
||||
FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
|
||||
pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
|
||||
}
|
||||
|
||||
FreeScratchGC(pGC);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
else {
|
||||
/* Clear out the new DBE buffer pixmaps. */
|
||||
|
||||
MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
|
||||
|
||||
pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
|
||||
ValidateGC((DrawablePtr) pFrontBuffer, pGC);
|
||||
|
||||
/* I suppose this could avoid quite a bit of work if
|
||||
* it computed the minimal area required.
|
||||
*/
|
||||
if (clear) {
|
||||
(*pGC->ops->PolyFillRect) ((DrawablePtr) pFrontBuffer, pGC, 1,
|
||||
&clearRect);
|
||||
(*pGC->ops->PolyFillRect) ((DrawablePtr) pBackBuffer, pGC, 1,
|
||||
&clearRect);
|
||||
}
|
||||
|
||||
/* Copy the contents of the old DBE pixmaps to the new pixmaps. */
|
||||
if (pWin->bitGravity != ForgetGravity) {
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPrivPriv->
|
||||
pFrontBuffer, (DrawablePtr) pFrontBuffer,
|
||||
pGC, sourcex, sourcey, savewidth, saveheight,
|
||||
destx, desty);
|
||||
(*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPrivPriv->
|
||||
pBackBuffer, (DrawablePtr) pBackBuffer, pGC,
|
||||
sourcex, sourcey, savewidth, saveheight,
|
||||
destx, desty);
|
||||
}
|
||||
|
||||
/* Destroy the old pixmaps, and point the DBE window priv to the new
|
||||
* pixmaps.
|
||||
*/
|
||||
|
||||
(*pScreen->DestroyPixmap) (pDbeWindowPrivPriv->pFrontBuffer);
|
||||
(*pScreen->DestroyPixmap) (pDbeWindowPrivPriv->pBackBuffer);
|
||||
|
||||
pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer;
|
||||
pDbeWindowPrivPriv->pBackBuffer = pBackBuffer;
|
||||
|
||||
/* Make sure all XID are associated with the new back pixmap. */
|
||||
miDbeAliasBuffers(pDbeWindowPriv);
|
||||
|
||||
FreeScratchGC(pGC);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
|
||||
} /* miDbePositionWindow() */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DBE MI Procedure: miDbeResetProc
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function is called from DbeResetProc(), which is called at the end
|
||||
* of every server generation. This function peforms any MI-specific
|
||||
* shutdown tasks.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void
|
||||
miDbeResetProc(ScreenPtr pScreen)
|
||||
{
|
||||
DbeScreenPrivPtr pDbeScreenPriv;
|
||||
|
||||
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
|
||||
|
||||
/* Unwrap wrappers */
|
||||
pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
|
||||
|
||||
} /* miDbeResetProc() */
|
||||
|
||||
static void
|
||||
miDbeNopValidateBuffer(WindowPtr pWin, XID bufId, Bool dstbuffer)
|
||||
{
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DBE MI Procedure: miDbeInit
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This is the MI initialization function called by DbeExtensionInit().
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
Bool
|
||||
miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv)
|
||||
{
|
||||
/* Copy resource types created by DIX */
|
||||
dbeDrawableResType = pDbeScreenPriv->dbeDrawableResType;
|
||||
dbeWindowPrivResType = pDbeScreenPriv->dbeWindowPrivResType;
|
||||
|
||||
/* Copy private indices created by DIX */
|
||||
dbeScreenPrivIndex = pDbeScreenPriv->dbeScreenPrivIndex;
|
||||
dbeWindowPrivIndex = pDbeScreenPriv->dbeWindowPrivIndex;
|
||||
|
||||
/* Reset the window priv privs if generations do not match. */
|
||||
if (miDbePrivPrivGeneration != serverGeneration) {
|
||||
/*
|
||||
**********************************************************************
|
||||
** Allocate the window priv priv.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
miDbeWindowPrivPrivIndex = (*pDbeScreenPriv->AllocWinPrivPrivIndex) ();
|
||||
|
||||
/* Make sure we only do this code once. */
|
||||
miDbePrivPrivGeneration = serverGeneration;
|
||||
|
||||
} /* if -- Reset priv privs. */
|
||||
|
||||
if (!(*pDbeScreenPriv->AllocWinPrivPriv) (pScreen,
|
||||
miDbeWindowPrivPrivIndex,
|
||||
sizeof(MiDbeWindowPrivPrivRec))) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/* Wrap functions. */
|
||||
pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
|
||||
pScreen->PositionWindow = miDbePositionWindow;
|
||||
|
||||
/* Initialize the per-screen DBE function pointers. */
|
||||
pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo;
|
||||
pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName;
|
||||
pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers;
|
||||
pDbeScreenPriv->BeginIdiom = 0;
|
||||
pDbeScreenPriv->EndIdiom = 0;
|
||||
pDbeScreenPriv->ResetProc = miDbeResetProc;
|
||||
pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete;
|
||||
|
||||
/* The mi implementation doesn't need buffer validation. */
|
||||
pDbeScreenPriv->ValidateBuffer = miDbeNopValidateBuffer;
|
||||
|
||||
return (TRUE);
|
||||
|
||||
} /* miDbeInit() */
|
|
@ -0,0 +1,43 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 1994, 1995 Hewlett-Packard Company
|
||||
*
|
||||
* 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 HEWLETT-PACKARD COMPANY 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.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Hewlett-Packard
|
||||
* Company shall not be used in advertising or otherwise to promote the
|
||||
* sale, use or other dealings in this Software without prior written
|
||||
* authorization from the Hewlett-Packard Company.
|
||||
*
|
||||
* Header file for users of machine-independent DBE code
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef MIDBE_H
|
||||
#define MIDBE_H
|
||||
|
||||
/* EXTERNS */
|
||||
|
||||
extern Bool miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv);
|
||||
|
||||
#endif /* MIDBE_H */
|
|
@ -0,0 +1,93 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (c) 1994, 1995 Hewlett-Packard Company
|
||||
*
|
||||
* 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 HEWLETT-PACKARD COMPANY 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.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Hewlett-Packard
|
||||
* Company shall not be used in advertising or otherwise to promote the
|
||||
* sale, use or other dealings in this Software without prior written
|
||||
* authorization from the Hewlett-Packard Company.
|
||||
*
|
||||
* Header file for users of machine-independent DBE code
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef MIDBE_STRUCT_H
|
||||
#define MIDBE_STRUCT_H
|
||||
|
||||
/* DEFINES */
|
||||
|
||||
#define MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv) \
|
||||
(((miDbeWindowPrivPrivIndex < 0) || (!pDbeWindowPriv)) ? \
|
||||
NULL : \
|
||||
((MiDbeWindowPrivPrivPtr) \
|
||||
((pDbeWindowPriv)->devPrivates[miDbeWindowPrivPrivIndex].ptr)))
|
||||
|
||||
#define MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin)\
|
||||
MI_DBE_WINDOW_PRIV_PRIV(DBE_WINDOW_PRIV(pWin))
|
||||
|
||||
#define MI_DBE_SCREEN_PRIV_PRIV(pDbeScreenPriv) \
|
||||
(((miDbeScreenPrivPrivIndex < 0) || (!pDbeScreenPriv)) ? \
|
||||
NULL : \
|
||||
((MiDbeScreenPrivPrivPtr) \
|
||||
((pDbeScreenPriv)->devPrivates[miDbeScreenPrivPrivIndex].ptr)))
|
||||
|
||||
/* TYPEDEFS */
|
||||
|
||||
typedef struct _MiDbeWindowPrivPrivRec {
|
||||
/* Place machine-specific fields in here.
|
||||
* Since this is mi code, we do not really have machine-specific fields.
|
||||
*/
|
||||
|
||||
/* Pointer to a drawable that contains the contents of the back buffer.
|
||||
*/
|
||||
PixmapPtr pBackBuffer;
|
||||
|
||||
/* Pointer to a drawable that contains the contents of the front buffer.
|
||||
* This pointer is only used for the XdbeUntouched swap action. For that
|
||||
* swap action, we need to copy the front buffer (window) contents into
|
||||
* this drawable, copy the contents of current back buffer drawable (the
|
||||
* back buffer) into the window, swap the front and back drawable pointers,
|
||||
* and then swap the drawable/resource associations in the resource
|
||||
* database.
|
||||
*/
|
||||
PixmapPtr pFrontBuffer;
|
||||
|
||||
/* Pointer back to our window private with which we are associated. */
|
||||
DbeWindowPrivPtr pDbeWindowPriv;
|
||||
|
||||
} MiDbeWindowPrivPrivRec, *MiDbeWindowPrivPrivPtr;
|
||||
|
||||
typedef struct _MiDbeScreenPrivPrivRec {
|
||||
/* Place machine-specific fields in here.
|
||||
* Since this is mi code, we do not really have machine-specific fields.
|
||||
*/
|
||||
|
||||
/* Pointer back to our screen private with which we are associated. */
|
||||
DbeScreenPrivPtr pDbeScreenPriv;
|
||||
|
||||
} MiDbeScreenPrivPrivRec, *MiDbeScreenPrivPrivPtr;
|
||||
|
||||
#endif /* MIDBE_STRUCT_H */
|
|
@ -0,0 +1,33 @@
|
|||
noinst_LTLIBRARIES = libdix.la
|
||||
|
||||
AM_CFLAGS = $(DIX_CFLAGS) \
|
||||
-DVENDOR_STRING=\""@VENDOR_STRING@"\" \
|
||||
-DVENDOR_RELEASE="@VENDOR_RELEASE@"
|
||||
|
||||
libdix_la_SOURCES = \
|
||||
atom.c \
|
||||
colormap.c \
|
||||
cursor.c \
|
||||
devices.c \
|
||||
dispatch.c \
|
||||
dispatch.h \
|
||||
dixfonts.c \
|
||||
dixutils.c \
|
||||
events.c \
|
||||
extension.c \
|
||||
ffs.c \
|
||||
gc.c \
|
||||
globals.c \
|
||||
glyphcurs.c \
|
||||
grabs.c \
|
||||
initatoms.c \
|
||||
main.c \
|
||||
pixmap.c \
|
||||
privates.c \
|
||||
property.c \
|
||||
resource.c \
|
||||
swaprep.c \
|
||||
swapreq.c \
|
||||
tables.c \
|
||||
window.c \
|
||||
strcasecmp.c
|
|
@ -0,0 +1,212 @@
|
|||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "misc.h"
|
||||
#include "resource.h"
|
||||
#include "dix.h"
|
||||
|
||||
#define InitialTableSize 100
|
||||
|
||||
typedef struct _Node {
|
||||
struct _Node *left, *right;
|
||||
Atom a;
|
||||
unsigned int fingerPrint;
|
||||
char *string;
|
||||
} NodeRec, *NodePtr;
|
||||
|
||||
static Atom lastAtom = None;
|
||||
|
||||
static NodePtr atomRoot = (NodePtr) NULL;
|
||||
|
||||
static unsigned long tableLength;
|
||||
|
||||
static NodePtr *nodeTable;
|
||||
|
||||
void FreeAtom(NodePtr patom);
|
||||
|
||||
_X_EXPORT Atom
|
||||
MakeAtom(char *string, unsigned len, Bool makeit)
|
||||
{
|
||||
NodePtr *np;
|
||||
|
||||
unsigned i;
|
||||
|
||||
int comp;
|
||||
|
||||
unsigned int fp = 0;
|
||||
|
||||
np = &atomRoot;
|
||||
for (i = 0; i < (len + 1) / 2; i++) {
|
||||
fp = fp * 27 + string[i];
|
||||
fp = fp * 27 + string[len - 1 - i];
|
||||
}
|
||||
while (*np != (NodePtr) NULL) {
|
||||
if (fp < (*np)->fingerPrint)
|
||||
np = &((*np)->left);
|
||||
else if (fp > (*np)->fingerPrint)
|
||||
np = &((*np)->right);
|
||||
else { /* now start testing the strings */
|
||||
comp = strncmp(string, (*np)->string, (int) len);
|
||||
if ((comp < 0) || ((comp == 0) && (len < strlen((*np)->string))))
|
||||
np = &((*np)->left);
|
||||
else if (comp > 0)
|
||||
np = &((*np)->right);
|
||||
else
|
||||
return (*np)->a;
|
||||
}
|
||||
}
|
||||
if (makeit) {
|
||||
NodePtr nd;
|
||||
|
||||
nd = malloc(sizeof(NodeRec));
|
||||
if (!nd)
|
||||
return BAD_RESOURCE;
|
||||
if (lastAtom < XA_LAST_PREDEFINED) {
|
||||
nd->string = string;
|
||||
}
|
||||
else {
|
||||
nd->string = malloc(len + 1);
|
||||
if (!nd->string) {
|
||||
free(nd);
|
||||
return BAD_RESOURCE;
|
||||
}
|
||||
strncpy(nd->string, string, (int) len);
|
||||
nd->string[len] = 0;
|
||||
}
|
||||
if ((lastAtom + 1) >= tableLength) {
|
||||
NodePtr *table;
|
||||
|
||||
table = (NodePtr *) realloc(nodeTable,
|
||||
tableLength * (2 * sizeof(NodePtr)));
|
||||
if (!table) {
|
||||
if (nd->string != string)
|
||||
free(nd->string);
|
||||
free(nd);
|
||||
return BAD_RESOURCE;
|
||||
}
|
||||
tableLength <<= 1;
|
||||
nodeTable = table;
|
||||
}
|
||||
*np = nd;
|
||||
nd->left = nd->right = (NodePtr) NULL;
|
||||
nd->fingerPrint = fp;
|
||||
nd->a = (++lastAtom);
|
||||
*(nodeTable + lastAtom) = nd;
|
||||
return nd->a;
|
||||
}
|
||||
else
|
||||
return None;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
ValidAtom(Atom atom)
|
||||
{
|
||||
return (atom != None) && (atom <= lastAtom);
|
||||
}
|
||||
|
||||
_X_EXPORT char *
|
||||
NameForAtom(Atom atom)
|
||||
{
|
||||
NodePtr node;
|
||||
|
||||
if (atom > lastAtom)
|
||||
return 0;
|
||||
if ((node = nodeTable[atom]) == (NodePtr) NULL)
|
||||
return 0;
|
||||
return node->string;
|
||||
}
|
||||
|
||||
void
|
||||
AtomError()
|
||||
{
|
||||
FatalError("initializing atoms");
|
||||
}
|
||||
|
||||
void
|
||||
FreeAtom(NodePtr patom)
|
||||
{
|
||||
if (patom->left)
|
||||
FreeAtom(patom->left);
|
||||
if (patom->right)
|
||||
FreeAtom(patom->right);
|
||||
if (patom->a > XA_LAST_PREDEFINED)
|
||||
free(patom->string);
|
||||
free(patom);
|
||||
}
|
||||
|
||||
void
|
||||
FreeAllAtoms()
|
||||
{
|
||||
if (atomRoot == (NodePtr) NULL)
|
||||
return;
|
||||
FreeAtom(atomRoot);
|
||||
atomRoot = (NodePtr) NULL;
|
||||
free(nodeTable);
|
||||
nodeTable = (NodePtr *) NULL;
|
||||
lastAtom = None;
|
||||
}
|
||||
|
||||
void
|
||||
InitAtoms()
|
||||
{
|
||||
FreeAllAtoms();
|
||||
tableLength = InitialTableSize;
|
||||
nodeTable = malloc(InitialTableSize * sizeof(NodePtr));
|
||||
if (!nodeTable)
|
||||
AtomError();
|
||||
nodeTable[None] = (NodePtr) NULL;
|
||||
MakePredeclaredAtoms();
|
||||
if (lastAtom != XA_LAST_PREDEFINED)
|
||||
AtomError();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,442 @@
|
|||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include "servermd.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "dixstruct.h"
|
||||
#include "cursorstr.h"
|
||||
#include "dixfontstr.h"
|
||||
#include "opaque.h"
|
||||
|
||||
typedef struct _GlyphShare {
|
||||
FontPtr font;
|
||||
unsigned short sourceChar;
|
||||
unsigned short maskChar;
|
||||
CursorBitsPtr bits;
|
||||
struct _GlyphShare *next;
|
||||
} GlyphShare, *GlyphSharePtr;
|
||||
|
||||
static GlyphSharePtr sharedGlyphs = (GlyphSharePtr) NULL;
|
||||
|
||||
static CARD32 cursorSerial;
|
||||
|
||||
static void
|
||||
FreeCursorBits(CursorBitsPtr bits)
|
||||
{
|
||||
if (--bits->refcnt > 0)
|
||||
return;
|
||||
free(bits->source);
|
||||
free(bits->mask);
|
||||
#ifdef ARGB_CURSOR
|
||||
free(bits->argb);
|
||||
#endif
|
||||
if (bits->refcnt == 0) {
|
||||
GlyphSharePtr *prev, this;
|
||||
|
||||
for (prev = &sharedGlyphs;
|
||||
(this = *prev) && (this->bits != bits); prev = &this->next);
|
||||
if (this) {
|
||||
*prev = this->next;
|
||||
CloseFont(this->font, (Font) 0);
|
||||
free(this);
|
||||
}
|
||||
free(bits);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called indirectly by DeleteResource; must use exactly two args.
|
||||
*
|
||||
* \param value must conform to DeleteType
|
||||
*/
|
||||
_X_EXPORT int
|
||||
FreeCursor(pointer value, XID cid)
|
||||
{
|
||||
int nscr;
|
||||
|
||||
CursorPtr pCurs = (CursorPtr) value;
|
||||
|
||||
ScreenPtr pscr;
|
||||
|
||||
if (--pCurs->refcnt > 0)
|
||||
return (Success);
|
||||
|
||||
for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
|
||||
pscr = screenInfo.screens[nscr];
|
||||
(void) (*pscr->UnrealizeCursor) (pscr, pCurs);
|
||||
}
|
||||
FreeCursorBits(pCurs->bits);
|
||||
free(pCurs);
|
||||
return (Success);
|
||||
}
|
||||
|
||||
/*
|
||||
* We check for empty cursors so that we won't have to display them
|
||||
*/
|
||||
static void
|
||||
CheckForEmptyMask(CursorBitsPtr bits)
|
||||
{
|
||||
unsigned char *msk = bits->mask;
|
||||
|
||||
int n = BitmapBytePad(bits->width) * bits->height;
|
||||
|
||||
bits->emptyMask = FALSE;
|
||||
while (n--)
|
||||
if (*(msk++) != 0)
|
||||
return;
|
||||
#ifdef ARGB_CURSOR
|
||||
if (bits->argb) {
|
||||
CARD32 *argb = bits->argb;
|
||||
|
||||
int n = bits->width * bits->height;
|
||||
|
||||
while (n--)
|
||||
if (*argb++ & 0xff000000)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
bits->emptyMask = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* does nothing about the resource table, just creates the data structure.
|
||||
* does not copy the src and mask bits
|
||||
*
|
||||
* \param psrcbits server-defined padding
|
||||
* \param pmaskbits server-defined padding
|
||||
* \param argb no padding
|
||||
*/
|
||||
CursorPtr
|
||||
AllocCursorARGB(unsigned char *psrcbits, unsigned char *pmaskbits, CARD32 *argb,
|
||||
CursorMetricPtr cm,
|
||||
unsigned foreRed, unsigned foreGreen, unsigned foreBlue,
|
||||
unsigned backRed, unsigned backGreen, unsigned backBlue)
|
||||
{
|
||||
CursorBitsPtr bits;
|
||||
|
||||
CursorPtr pCurs;
|
||||
|
||||
int nscr;
|
||||
|
||||
ScreenPtr pscr;
|
||||
|
||||
pCurs = malloc(sizeof(CursorRec) + sizeof(CursorBits));
|
||||
if (!pCurs) {
|
||||
free(psrcbits);
|
||||
free(pmaskbits);
|
||||
return (CursorPtr) NULL;
|
||||
}
|
||||
bits = (CursorBitsPtr) ((char *) pCurs + sizeof(CursorRec));
|
||||
bits->source = psrcbits;
|
||||
bits->mask = pmaskbits;
|
||||
#ifdef ARGB_CURSOR
|
||||
bits->argb = argb;
|
||||
#endif
|
||||
bits->width = cm->width;
|
||||
bits->height = cm->height;
|
||||
bits->xhot = cm->xhot;
|
||||
bits->yhot = cm->yhot;
|
||||
bits->refcnt = -1;
|
||||
CheckForEmptyMask(bits);
|
||||
|
||||
pCurs->bits = bits;
|
||||
pCurs->refcnt = 1;
|
||||
pCurs->serialNumber = ++cursorSerial;
|
||||
pCurs->name = None;
|
||||
|
||||
pCurs->foreRed = foreRed;
|
||||
pCurs->foreGreen = foreGreen;
|
||||
pCurs->foreBlue = foreBlue;
|
||||
|
||||
pCurs->backRed = backRed;
|
||||
pCurs->backGreen = backGreen;
|
||||
pCurs->backBlue = backBlue;
|
||||
|
||||
/*
|
||||
* realize the cursor for every screen
|
||||
*/
|
||||
for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
|
||||
pscr = screenInfo.screens[nscr];
|
||||
if (!(*pscr->RealizeCursor) (pscr, pCurs)) {
|
||||
while (--nscr >= 0) {
|
||||
pscr = screenInfo.screens[nscr];
|
||||
(*pscr->UnrealizeCursor) (pscr, pCurs);
|
||||
}
|
||||
FreeCursorBits(bits);
|
||||
free(pCurs);
|
||||
return (CursorPtr) NULL;
|
||||
}
|
||||
}
|
||||
return pCurs;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* \param psrcbits server-defined padding
|
||||
* \param pmaskbits server-defined padding
|
||||
*/
|
||||
CursorPtr
|
||||
AllocCursor(unsigned char *psrcbits, unsigned char *pmaskbits,
|
||||
CursorMetricPtr cm,
|
||||
unsigned foreRed, unsigned foreGreen, unsigned foreBlue,
|
||||
unsigned backRed, unsigned backGreen, unsigned backBlue)
|
||||
{
|
||||
return AllocCursorARGB(psrcbits, pmaskbits, (CARD32 *) 0, cm,
|
||||
foreRed, foreGreen, foreBlue,
|
||||
backRed, backGreen, backBlue);
|
||||
}
|
||||
|
||||
int
|
||||
AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
|
||||
unsigned foreRed, unsigned foreGreen, unsigned foreBlue,
|
||||
unsigned backRed, unsigned backGreen, unsigned backBlue,
|
||||
CursorPtr *ppCurs, ClientPtr client)
|
||||
{
|
||||
FontPtr sourcefont, maskfont;
|
||||
|
||||
unsigned char *srcbits;
|
||||
|
||||
unsigned char *mskbits;
|
||||
|
||||
CursorMetricRec cm;
|
||||
|
||||
int res;
|
||||
|
||||
CursorBitsPtr bits;
|
||||
|
||||
CursorPtr pCurs = NULL;
|
||||
|
||||
int nscr;
|
||||
|
||||
ScreenPtr pscr;
|
||||
|
||||
GlyphSharePtr pShare;
|
||||
|
||||
sourcefont = (FontPtr) SecurityLookupIDByType(client, source, RT_FONT,
|
||||
SecurityReadAccess);
|
||||
maskfont = (FontPtr) SecurityLookupIDByType(client, mask, RT_FONT,
|
||||
SecurityReadAccess);
|
||||
|
||||
if (!sourcefont) {
|
||||
client->errorValue = source;
|
||||
return (BadFont);
|
||||
}
|
||||
if (!maskfont && (mask != None)) {
|
||||
client->errorValue = mask;
|
||||
return (BadFont);
|
||||
}
|
||||
if (sourcefont != maskfont)
|
||||
pShare = (GlyphSharePtr) NULL;
|
||||
else {
|
||||
for (pShare = sharedGlyphs;
|
||||
pShare &&
|
||||
((pShare->font != sourcefont) ||
|
||||
(pShare->sourceChar != sourceChar) ||
|
||||
(pShare->maskChar != maskChar)); pShare = pShare->next);
|
||||
}
|
||||
if (pShare) {
|
||||
pCurs = malloc(sizeof(CursorRec));
|
||||
if (!pCurs)
|
||||
return BadAlloc;
|
||||
bits = pShare->bits;
|
||||
bits->refcnt++;
|
||||
}
|
||||
else {
|
||||
if (!CursorMetricsFromGlyph(sourcefont, sourceChar, &cm)) {
|
||||
client->errorValue = sourceChar;
|
||||
return BadValue;
|
||||
}
|
||||
if (!maskfont) {
|
||||
long n;
|
||||
|
||||
unsigned char *mskptr;
|
||||
|
||||
n = BitmapBytePad(cm.width) * (long) cm.height;
|
||||
mskptr = mskbits = malloc(n);
|
||||
if (!mskptr)
|
||||
return BadAlloc;
|
||||
while (--n >= 0)
|
||||
*mskptr++ = ~0;
|
||||
}
|
||||
else {
|
||||
if (!CursorMetricsFromGlyph(maskfont, maskChar, &cm)) {
|
||||
client->errorValue = maskChar;
|
||||
return BadValue;
|
||||
}
|
||||
if ((res =
|
||||
ServerBitsFromGlyph(maskfont, maskChar, &cm, &mskbits)) != 0)
|
||||
return res;
|
||||
}
|
||||
if ((res =
|
||||
ServerBitsFromGlyph(sourcefont, sourceChar, &cm, &srcbits)) != 0) {
|
||||
free(mskbits);
|
||||
return res;
|
||||
}
|
||||
if (sourcefont != maskfont) {
|
||||
pCurs = malloc(sizeof(CursorRec) + sizeof(CursorBits));
|
||||
if (pCurs)
|
||||
bits = (CursorBitsPtr) ((char *) pCurs + sizeof(CursorRec));
|
||||
else
|
||||
bits = (CursorBitsPtr) NULL;
|
||||
}
|
||||
else {
|
||||
pCurs = malloc(sizeof(CursorRec));
|
||||
if (pCurs)
|
||||
bits = malloc(sizeof(CursorBits));
|
||||
else
|
||||
bits = (CursorBitsPtr) NULL;
|
||||
}
|
||||
if (!bits) {
|
||||
free(pCurs);
|
||||
free(mskbits);
|
||||
free(srcbits);
|
||||
return BadAlloc;
|
||||
}
|
||||
bits->source = srcbits;
|
||||
bits->mask = mskbits;
|
||||
#ifdef ARGB_CURSOR
|
||||
bits->argb = 0;
|
||||
#endif
|
||||
bits->width = cm.width;
|
||||
bits->height = cm.height;
|
||||
bits->xhot = cm.xhot;
|
||||
bits->yhot = cm.yhot;
|
||||
if (sourcefont != maskfont)
|
||||
bits->refcnt = -1;
|
||||
else {
|
||||
bits->refcnt = 1;
|
||||
pShare = malloc(sizeof(GlyphShare));
|
||||
if (!pShare) {
|
||||
FreeCursorBits(bits);
|
||||
free(pCurs);
|
||||
return BadAlloc;
|
||||
}
|
||||
pShare->font = sourcefont;
|
||||
sourcefont->refcnt++;
|
||||
pShare->sourceChar = sourceChar;
|
||||
pShare->maskChar = maskChar;
|
||||
pShare->bits = bits;
|
||||
pShare->next = sharedGlyphs;
|
||||
sharedGlyphs = pShare;
|
||||
}
|
||||
}
|
||||
CheckForEmptyMask(bits);
|
||||
pCurs->bits = bits;
|
||||
pCurs->refcnt = 1;
|
||||
pCurs->serialNumber = ++cursorSerial;
|
||||
pCurs->name = None;
|
||||
|
||||
pCurs->foreRed = foreRed;
|
||||
pCurs->foreGreen = foreGreen;
|
||||
pCurs->foreBlue = foreBlue;
|
||||
|
||||
pCurs->backRed = backRed;
|
||||
pCurs->backGreen = backGreen;
|
||||
pCurs->backBlue = backBlue;
|
||||
|
||||
/*
|
||||
* realize the cursor for every screen
|
||||
*/
|
||||
for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
|
||||
pscr = screenInfo.screens[nscr];
|
||||
if (!(*pscr->RealizeCursor) (pscr, pCurs)) {
|
||||
while (--nscr >= 0) {
|
||||
pscr = screenInfo.screens[nscr];
|
||||
(*pscr->UnrealizeCursor) (pscr, pCurs);
|
||||
}
|
||||
FreeCursorBits(pCurs->bits);
|
||||
free(pCurs);
|
||||
return BadAlloc;
|
||||
}
|
||||
}
|
||||
*ppCurs = pCurs;
|
||||
return Success;
|
||||
}
|
||||
|
||||
/** CreateRootCursor
|
||||
*
|
||||
* look up the name of a font
|
||||
* open the font
|
||||
* add the font to the resource table
|
||||
* make a cursor from the glyphs
|
||||
* add the cursor to the resource table
|
||||
*************************************************************/
|
||||
|
||||
CursorPtr
|
||||
CreateRootCursor(char *pfilename, unsigned glyph)
|
||||
{
|
||||
CursorPtr curs;
|
||||
|
||||
FontPtr cursorfont;
|
||||
|
||||
int err;
|
||||
|
||||
XID fontID;
|
||||
|
||||
fontID = FakeClientID(0);
|
||||
err = OpenFont(serverClient, fontID, FontLoadAll | FontOpenSync,
|
||||
(unsigned) strlen(pfilename), pfilename);
|
||||
if (err != Success)
|
||||
return NullCursor;
|
||||
|
||||
cursorfont = (FontPtr) LookupIDByType(fontID, RT_FONT);
|
||||
if (!cursorfont)
|
||||
return NullCursor;
|
||||
if (AllocGlyphCursor(fontID, glyph, fontID, glyph + 1,
|
||||
0, 0, 0, ~0, ~0, ~0, &curs, serverClient) != Success)
|
||||
return NullCursor;
|
||||
|
||||
if (!AddResource(FakeClientID(0), RT_CURSOR, (pointer) curs))
|
||||
return NullCursor;
|
||||
|
||||
return curs;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,146 @@
|
|||
/************************************************************
|
||||
|
||||
Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of the above listed
|
||||
copyright holder(s) not be used in advertising or publicity pertaining
|
||||
to distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
|
||||
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
|
||||
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* This prototypes the dispatch.c module (except for functions declared in
|
||||
* global headers), plus related dispatch procedures from devices.c, events.c,
|
||||
* extension.c, property.c.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef DISPATCH_H
|
||||
#define DISPATCH_H 1
|
||||
|
||||
DISPATCH_PROC(InitClientPrivates);
|
||||
DISPATCH_PROC(ProcAllocColor);
|
||||
DISPATCH_PROC(ProcAllocColorCells);
|
||||
DISPATCH_PROC(ProcAllocColorPlanes);
|
||||
DISPATCH_PROC(ProcAllocNamedColor);
|
||||
DISPATCH_PROC(ProcBell);
|
||||
DISPATCH_PROC(ProcChangeAccessControl);
|
||||
DISPATCH_PROC(ProcChangeCloseDownMode);
|
||||
DISPATCH_PROC(ProcChangeGC);
|
||||
DISPATCH_PROC(ProcChangeHosts);
|
||||
DISPATCH_PROC(ProcChangeKeyboardControl);
|
||||
DISPATCH_PROC(ProcChangeKeyboardMapping);
|
||||
DISPATCH_PROC(ProcChangePointerControl);
|
||||
DISPATCH_PROC(ProcChangeProperty);
|
||||
DISPATCH_PROC(ProcChangeSaveSet);
|
||||
DISPATCH_PROC(ProcChangeWindowAttributes);
|
||||
DISPATCH_PROC(ProcCirculateWindow);
|
||||
DISPATCH_PROC(ProcClearToBackground);
|
||||
DISPATCH_PROC(ProcCloseFont);
|
||||
DISPATCH_PROC(ProcConfigureWindow);
|
||||
DISPATCH_PROC(ProcConvertSelection);
|
||||
DISPATCH_PROC(ProcCopyArea);
|
||||
DISPATCH_PROC(ProcCopyColormapAndFree);
|
||||
DISPATCH_PROC(ProcCopyGC);
|
||||
DISPATCH_PROC(ProcCopyPlane);
|
||||
DISPATCH_PROC(ProcCreateColormap);
|
||||
DISPATCH_PROC(ProcCreateCursor);
|
||||
DISPATCH_PROC(ProcCreateGC);
|
||||
DISPATCH_PROC(ProcCreateGlyphCursor);
|
||||
DISPATCH_PROC(ProcCreatePixmap);
|
||||
DISPATCH_PROC(ProcCreateWindow);
|
||||
DISPATCH_PROC(ProcDeleteProperty);
|
||||
DISPATCH_PROC(ProcDestroySubwindows);
|
||||
DISPATCH_PROC(ProcDestroyWindow);
|
||||
DISPATCH_PROC(ProcEstablishConnection);
|
||||
DISPATCH_PROC(ProcFillPoly);
|
||||
DISPATCH_PROC(ProcForceScreenSaver);
|
||||
DISPATCH_PROC(ProcFreeColormap);
|
||||
DISPATCH_PROC(ProcFreeColors);
|
||||
DISPATCH_PROC(ProcFreeCursor);
|
||||
DISPATCH_PROC(ProcFreeGC);
|
||||
DISPATCH_PROC(ProcFreePixmap);
|
||||
DISPATCH_PROC(ProcGetAtomName);
|
||||
DISPATCH_PROC(ProcGetFontPath);
|
||||
DISPATCH_PROC(ProcGetGeometry);
|
||||
DISPATCH_PROC(ProcGetImage);
|
||||
DISPATCH_PROC(ProcGetKeyboardControl);
|
||||
DISPATCH_PROC(ProcGetKeyboardMapping);
|
||||
DISPATCH_PROC(ProcGetModifierMapping);
|
||||
DISPATCH_PROC(ProcGetMotionEvents);
|
||||
DISPATCH_PROC(ProcGetPointerControl);
|
||||
DISPATCH_PROC(ProcGetPointerMapping);
|
||||
DISPATCH_PROC(ProcGetProperty);
|
||||
DISPATCH_PROC(ProcGetScreenSaver);
|
||||
DISPATCH_PROC(ProcGetSelectionOwner);
|
||||
DISPATCH_PROC(ProcGetWindowAttributes);
|
||||
DISPATCH_PROC(ProcGrabServer);
|
||||
DISPATCH_PROC(ProcImageText16);
|
||||
DISPATCH_PROC(ProcImageText8);
|
||||
DISPATCH_PROC(ProcInitialConnection);
|
||||
DISPATCH_PROC(ProcInstallColormap);
|
||||
DISPATCH_PROC(ProcInternAtom);
|
||||
DISPATCH_PROC(ProcKillClient);
|
||||
DISPATCH_PROC(ProcListExtensions);
|
||||
DISPATCH_PROC(ProcListFonts);
|
||||
DISPATCH_PROC(ProcListFontsWithInfo);
|
||||
DISPATCH_PROC(ProcListHosts);
|
||||
DISPATCH_PROC(ProcListInstalledColormaps);
|
||||
DISPATCH_PROC(ProcListProperties);
|
||||
DISPATCH_PROC(ProcLookupColor);
|
||||
DISPATCH_PROC(ProcMapSubwindows);
|
||||
DISPATCH_PROC(ProcMapWindow);
|
||||
DISPATCH_PROC(ProcNoOperation);
|
||||
DISPATCH_PROC(ProcOpenFont);
|
||||
DISPATCH_PROC(ProcPolyArc);
|
||||
DISPATCH_PROC(ProcPolyFillArc);
|
||||
DISPATCH_PROC(ProcPolyFillRectangle);
|
||||
DISPATCH_PROC(ProcPolyLine);
|
||||
DISPATCH_PROC(ProcPolyPoint);
|
||||
DISPATCH_PROC(ProcPolyRectangle);
|
||||
DISPATCH_PROC(ProcPolySegment);
|
||||
DISPATCH_PROC(ProcPolyText);
|
||||
DISPATCH_PROC(ProcPutImage);
|
||||
DISPATCH_PROC(ProcQueryBestSize);
|
||||
DISPATCH_PROC(ProcQueryColors);
|
||||
DISPATCH_PROC(ProcQueryExtension);
|
||||
DISPATCH_PROC(ProcQueryFont);
|
||||
DISPATCH_PROC(ProcQueryKeymap);
|
||||
DISPATCH_PROC(ProcQueryTextExtents);
|
||||
DISPATCH_PROC(ProcQueryTree);
|
||||
DISPATCH_PROC(ProcReparentWindow);
|
||||
DISPATCH_PROC(ProcRotateProperties);
|
||||
DISPATCH_PROC(ProcSetClipRectangles);
|
||||
DISPATCH_PROC(ProcSetDashes);
|
||||
DISPATCH_PROC(ProcSetFontPath);
|
||||
DISPATCH_PROC(ProcSetModifierMapping);
|
||||
DISPATCH_PROC(ProcSetPointerMapping);
|
||||
DISPATCH_PROC(ProcSetScreenSaver);
|
||||
DISPATCH_PROC(ProcSetSelectionOwner);
|
||||
DISPATCH_PROC(ProcStoreColors);
|
||||
DISPATCH_PROC(ProcStoreNamedColor);
|
||||
DISPATCH_PROC(ProcTranslateCoords);
|
||||
DISPATCH_PROC(ProcUngrabServer);
|
||||
DISPATCH_PROC(ProcUninstallColormap);
|
||||
DISPATCH_PROC(ProcUnmapSubwindows);
|
||||
DISPATCH_PROC(ProcUnmapWindow);
|
||||
|
||||
#endif /* DISPATCH_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,837 @@
|
|||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
(c)Copyright 1988,1991 Adobe Systems Incorporated. All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, distribute, and sublicense this software and its
|
||||
documentation for any purpose and without fee is hereby granted, provided that
|
||||
the above copyright notices appear in all copies and that both those copyright
|
||||
notices and this permission notice appear in supporting documentation and that
|
||||
the name of Adobe Systems Incorporated not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific, written prior
|
||||
permission. No trademark license to use the Adobe trademarks is hereby
|
||||
granted. If the Adobe trademark "Display PostScript"(tm) is used to describe
|
||||
this software, its functionality or for any other purpose, such use shall be
|
||||
limited to a statement that this software works in conjunction with the Display
|
||||
PostScript system. Proper trademark attribution to reflect Adobe's ownership
|
||||
of the trademark shall be given whenever any such reference to the Display
|
||||
PostScript system is made.
|
||||
|
||||
ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY
|
||||
PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. ADOBE
|
||||
DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-
|
||||
INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE TO YOU
|
||||
OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
|
||||
DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,NEGLIGENCE, STRICT
|
||||
LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT PROVIDE ANY TRAINING OR OTHER
|
||||
SUPPORT FOR THE SOFTWARE.
|
||||
|
||||
Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
|
||||
Incorporated which may be registered in certain jurisdictions.
|
||||
|
||||
Author: Adobe Systems Incorporated
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include "misc.h"
|
||||
#include "windowstr.h"
|
||||
#include "dixstruct.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#define XK_LATIN1
|
||||
#include <X11/keysymdef.h>
|
||||
|
||||
/*
|
||||
* CompareTimeStamps returns -1, 0, or +1 depending on if the first
|
||||
* argument is less than, equal to or greater than the second argument.
|
||||
*/
|
||||
|
||||
_X_EXPORT int
|
||||
CompareTimeStamps(TimeStamp a, TimeStamp b)
|
||||
{
|
||||
if (a.months < b.months)
|
||||
return EARLIER;
|
||||
if (a.months > b.months)
|
||||
return LATER;
|
||||
if (a.milliseconds < b.milliseconds)
|
||||
return EARLIER;
|
||||
if (a.milliseconds > b.milliseconds)
|
||||
return LATER;
|
||||
return SAMETIME;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert client times to server TimeStamps
|
||||
*/
|
||||
|
||||
#define HALFMONTH ((unsigned long) 1<<31)
|
||||
_X_EXPORT TimeStamp
|
||||
ClientTimeToServerTime(CARD32 c)
|
||||
{
|
||||
TimeStamp ts;
|
||||
|
||||
if (c == CurrentTime)
|
||||
return currentTime;
|
||||
ts.months = currentTime.months;
|
||||
ts.milliseconds = c;
|
||||
if (c > currentTime.milliseconds) {
|
||||
if (((unsigned long) c - currentTime.milliseconds) > HALFMONTH)
|
||||
ts.months -= 1;
|
||||
}
|
||||
else if (c < currentTime.milliseconds) {
|
||||
if (((unsigned long) currentTime.milliseconds - c) > HALFMONTH)
|
||||
ts.months += 1;
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
/*
|
||||
* ISO Latin-1 case conversion routine
|
||||
*
|
||||
* this routine always null-terminates the result, so
|
||||
* beware of too-small buffers
|
||||
*/
|
||||
|
||||
static unsigned char
|
||||
ISOLatin1ToLower(unsigned char source)
|
||||
{
|
||||
unsigned char dest;
|
||||
|
||||
if ((source >= XK_A) && (source <= XK_Z))
|
||||
dest = source + (XK_a - XK_A);
|
||||
else if ((source >= XK_Agrave) && (source <= XK_Odiaeresis))
|
||||
dest = source + (XK_agrave - XK_Agrave);
|
||||
else if ((source >= XK_Ooblique) && (source <= XK_Thorn))
|
||||
dest = source + (XK_oslash - XK_Ooblique);
|
||||
else
|
||||
dest = source;
|
||||
return dest;
|
||||
}
|
||||
|
||||
int
|
||||
CompareISOLatin1Lowered(unsigned char *s1, int s1len,
|
||||
unsigned char *s2, int s2len)
|
||||
{
|
||||
unsigned char c1, c2;
|
||||
|
||||
for (;;) {
|
||||
/* note -- compare against zero so that -1 ignores len */
|
||||
c1 = s1len-- ? *s1++ : '\0';
|
||||
c2 = s2len-- ? *s2++ : '\0';
|
||||
if (!c1 ||
|
||||
(c1 != c2 &&
|
||||
(c1 = ISOLatin1ToLower(c1)) != (c2 = ISOLatin1ToLower(c2))))
|
||||
break;
|
||||
}
|
||||
return (int) c1 - (int) c2;
|
||||
}
|
||||
|
||||
|
||||
WindowPtr
|
||||
LookupWindow(XID rid, ClientPtr client)
|
||||
{
|
||||
WindowPtr pWin;
|
||||
|
||||
client->errorValue = rid;
|
||||
if (rid == INVALID)
|
||||
return NULL;
|
||||
if (client->lastDrawableID == rid) {
|
||||
if (client->lastDrawable->type == DRAWABLE_WINDOW)
|
||||
return ((WindowPtr) client->lastDrawable);
|
||||
return (WindowPtr) NULL;
|
||||
}
|
||||
pWin = (WindowPtr) LookupIDByType(rid, RT_WINDOW);
|
||||
if (pWin && pWin->drawable.type == DRAWABLE_WINDOW) {
|
||||
client->lastDrawable = (DrawablePtr) pWin;
|
||||
client->lastDrawableID = rid;
|
||||
client->lastGCID = INVALID;
|
||||
client->lastGC = (GCPtr) NULL;
|
||||
}
|
||||
return pWin;
|
||||
}
|
||||
|
||||
pointer
|
||||
LookupDrawable(XID rid, ClientPtr client)
|
||||
{
|
||||
DrawablePtr pDraw;
|
||||
|
||||
if (rid == INVALID)
|
||||
return (pointer) NULL;
|
||||
if (client->lastDrawableID == rid)
|
||||
return ((pointer) client->lastDrawable);
|
||||
pDraw = (DrawablePtr) LookupIDByClass(rid, RC_DRAWABLE);
|
||||
if (pDraw && (pDraw->type != UNDRAWABLE_WINDOW))
|
||||
return (pointer) pDraw;
|
||||
return (pointer) NULL;
|
||||
}
|
||||
|
||||
|
||||
_X_EXPORT ClientPtr
|
||||
LookupClient(XID rid, ClientPtr client)
|
||||
{
|
||||
pointer pRes = (pointer) SecurityLookupIDByClass(client, rid, RC_ANY,
|
||||
SecurityReadAccess);
|
||||
|
||||
int clientIndex = CLIENT_ID(rid);
|
||||
|
||||
if (clientIndex && pRes && clients[clientIndex] && !(rid & SERVER_BIT)) {
|
||||
return clients[clientIndex];
|
||||
}
|
||||
return (ClientPtr) NULL;
|
||||
}
|
||||
|
||||
int
|
||||
AlterSaveSetForClient(ClientPtr client, WindowPtr pWin, unsigned mode,
|
||||
Bool toRoot, Bool remap)
|
||||
{
|
||||
int numnow;
|
||||
|
||||
SaveSetElt *pTmp = NULL;
|
||||
|
||||
int j;
|
||||
|
||||
numnow = client->numSaved;
|
||||
j = 0;
|
||||
if (numnow) {
|
||||
pTmp = client->saveSet;
|
||||
while ((j < numnow) && (SaveSetWindow(pTmp[j]) != (pointer) pWin))
|
||||
j++;
|
||||
}
|
||||
if (mode == SetModeInsert) {
|
||||
if (j < numnow) /* duplicate */
|
||||
return (Success);
|
||||
numnow++;
|
||||
pTmp = (SaveSetElt *) realloc(client->saveSet, sizeof(*pTmp) * numnow);
|
||||
if (!pTmp)
|
||||
return (BadAlloc);
|
||||
client->saveSet = pTmp;
|
||||
client->numSaved = numnow;
|
||||
SaveSetAssignWindow(client->saveSet[numnow - 1], pWin);
|
||||
SaveSetAssignToRoot(client->saveSet[numnow - 1], toRoot);
|
||||
SaveSetAssignRemap(client->saveSet[numnow - 1], remap);
|
||||
return (Success);
|
||||
}
|
||||
else if ((mode == SetModeDelete) && (j < numnow)) {
|
||||
while (j < numnow - 1) {
|
||||
pTmp[j] = pTmp[j + 1];
|
||||
j++;
|
||||
}
|
||||
numnow--;
|
||||
if (numnow) {
|
||||
pTmp =
|
||||
(SaveSetElt *) realloc(client->saveSet,
|
||||
sizeof(*pTmp) * numnow);
|
||||
if (pTmp)
|
||||
client->saveSet = pTmp;
|
||||
}
|
||||
else {
|
||||
free(client->saveSet);
|
||||
client->saveSet = (SaveSetElt *) NULL;
|
||||
}
|
||||
client->numSaved = numnow;
|
||||
return (Success);
|
||||
}
|
||||
return (Success);
|
||||
}
|
||||
|
||||
void
|
||||
DeleteWindowFromAnySaveSet(WindowPtr pWin)
|
||||
{
|
||||
int i;
|
||||
|
||||
ClientPtr client;
|
||||
|
||||
for (i = 0; i < currentMaxClients; i++) {
|
||||
client = clients[i];
|
||||
if (client && client->numSaved)
|
||||
(void) AlterSaveSetForClient(client, pWin, SetModeDelete, FALSE,
|
||||
TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* No-op Don't Do Anything : sometimes we need to be able to call a procedure
|
||||
* that doesn't do anything. For example, on screen with only static
|
||||
* colormaps, if someone calls install colormap, it's easier to have a dummy
|
||||
* procedure to call than to check if there's a procedure
|
||||
*/
|
||||
_X_EXPORT void
|
||||
NoopDDA(void)
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct _BlockHandler {
|
||||
BlockHandlerProcPtr BlockHandler;
|
||||
WakeupHandlerProcPtr WakeupHandler;
|
||||
pointer blockData;
|
||||
Bool deleted;
|
||||
} BlockHandlerRec, *BlockHandlerPtr;
|
||||
|
||||
static BlockHandlerPtr handlers;
|
||||
|
||||
static int numHandlers;
|
||||
|
||||
static int sizeHandlers;
|
||||
|
||||
static Bool inHandler;
|
||||
|
||||
static Bool handlerDeleted;
|
||||
|
||||
/**
|
||||
*
|
||||
* \param pTimeout DIX doesn't want to know how OS represents time
|
||||
* \param pReadMask nor how it represents the det of descriptors
|
||||
*/
|
||||
void
|
||||
BlockHandler(pointer pTimeout, pointer pReadmask)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
++inHandler;
|
||||
for (i = 0; i < screenInfo.numScreens; i++)
|
||||
(*screenInfo.screens[i]->BlockHandler) (i,
|
||||
screenInfo.screens[i]->
|
||||
blockData, pTimeout, pReadmask);
|
||||
for (i = 0; i < numHandlers; i++)
|
||||
(*handlers[i].BlockHandler) (handlers[i].blockData,
|
||||
pTimeout, pReadmask);
|
||||
if (handlerDeleted) {
|
||||
for (i = 0; i < numHandlers;)
|
||||
if (handlers[i].deleted) {
|
||||
for (j = i; j < numHandlers - 1; j++)
|
||||
handlers[j] = handlers[j + 1];
|
||||
numHandlers--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
handlerDeleted = FALSE;
|
||||
}
|
||||
--inHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* \param result 32 bits of undefined result from the wait
|
||||
* \param pReadmask the resulting descriptor mask
|
||||
*/
|
||||
void
|
||||
WakeupHandler(int result, pointer pReadmask)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
++inHandler;
|
||||
for (i = numHandlers - 1; i >= 0; i--)
|
||||
(*handlers[i].WakeupHandler) (handlers[i].blockData, result, pReadmask);
|
||||
for (i = 0; i < screenInfo.numScreens; i++)
|
||||
(*screenInfo.screens[i]->WakeupHandler) (i,
|
||||
screenInfo.screens[i]->
|
||||
wakeupData, result, pReadmask);
|
||||
if (handlerDeleted) {
|
||||
for (i = 0; i < numHandlers;)
|
||||
if (handlers[i].deleted) {
|
||||
for (j = i; j < numHandlers - 1; j++)
|
||||
handlers[j] = handlers[j + 1];
|
||||
numHandlers--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
handlerDeleted = FALSE;
|
||||
}
|
||||
--inHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reentrant with BlockHandler and WakeupHandler, except wakeup won't
|
||||
* get called until next time
|
||||
*/
|
||||
_X_EXPORT Bool
|
||||
RegisterBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler,
|
||||
WakeupHandlerProcPtr wakeupHandler,
|
||||
pointer blockData)
|
||||
{
|
||||
BlockHandlerPtr new;
|
||||
|
||||
if (numHandlers >= sizeHandlers) {
|
||||
new = (BlockHandlerPtr) realloc(handlers, (numHandlers + 1) *
|
||||
sizeof(BlockHandlerRec));
|
||||
if (!new)
|
||||
return FALSE;
|
||||
handlers = new;
|
||||
sizeHandlers = numHandlers + 1;
|
||||
}
|
||||
handlers[numHandlers].BlockHandler = blockHandler;
|
||||
handlers[numHandlers].WakeupHandler = wakeupHandler;
|
||||
handlers[numHandlers].blockData = blockData;
|
||||
handlers[numHandlers].deleted = FALSE;
|
||||
numHandlers = numHandlers + 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
RemoveBlockAndWakeupHandlers(BlockHandlerProcPtr blockHandler,
|
||||
WakeupHandlerProcPtr wakeupHandler,
|
||||
pointer blockData)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numHandlers; i++)
|
||||
if (handlers[i].BlockHandler == blockHandler &&
|
||||
handlers[i].WakeupHandler == wakeupHandler &&
|
||||
handlers[i].blockData == blockData) {
|
||||
if (inHandler) {
|
||||
handlerDeleted = TRUE;
|
||||
handlers[i].deleted = TRUE;
|
||||
}
|
||||
else {
|
||||
for (; i < numHandlers - 1; i++)
|
||||
handlers[i] = handlers[i + 1];
|
||||
numHandlers--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
InitBlockAndWakeupHandlers()
|
||||
{
|
||||
free(handlers);
|
||||
handlers = (BlockHandlerPtr) 0;
|
||||
numHandlers = 0;
|
||||
sizeHandlers = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A general work queue. Perform some task before the server
|
||||
* sleeps for input.
|
||||
*/
|
||||
|
||||
WorkQueuePtr workQueue;
|
||||
|
||||
static WorkQueuePtr *workQueueLast = &workQueue;
|
||||
|
||||
void
|
||||
ProcessWorkQueue(void)
|
||||
{
|
||||
WorkQueuePtr q, *p;
|
||||
|
||||
p = &workQueue;
|
||||
/*
|
||||
* Scan the work queue once, calling each function. Those
|
||||
* which return TRUE are removed from the queue, otherwise
|
||||
* they will be called again. This must be reentrant with
|
||||
* QueueWorkProc.
|
||||
*/
|
||||
while ((q = *p)) {
|
||||
if ((*q->function) (q->client, q->closure)) {
|
||||
/* remove q from the list */
|
||||
*p = q->next; /* don't fetch until after func called */
|
||||
free(q);
|
||||
}
|
||||
else {
|
||||
p = &q->next; /* don't fetch until after func called */
|
||||
}
|
||||
}
|
||||
workQueueLast = p;
|
||||
}
|
||||
|
||||
void
|
||||
ProcessWorkQueueZombies(void)
|
||||
{
|
||||
WorkQueuePtr q, *p;
|
||||
|
||||
p = &workQueue;
|
||||
while ((q = *p)) {
|
||||
if (q->client && q->client->clientGone) {
|
||||
(void) (*q->function) (q->client, q->closure);
|
||||
/* remove q from the list */
|
||||
*p = q->next; /* don't fetch until after func called */
|
||||
free(q);
|
||||
}
|
||||
else {
|
||||
p = &q->next; /* don't fetch until after func called */
|
||||
}
|
||||
}
|
||||
workQueueLast = p;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
QueueWorkProc(Bool (*function)
|
||||
(ClientPtr /* pClient */ , pointer /* closure */ ),
|
||||
ClientPtr client, pointer closure)
|
||||
{
|
||||
WorkQueuePtr q;
|
||||
|
||||
q = malloc(sizeof *q);
|
||||
if (!q)
|
||||
return FALSE;
|
||||
q->function = function;
|
||||
q->client = client;
|
||||
q->closure = closure;
|
||||
q->next = NULL;
|
||||
*workQueueLast = q;
|
||||
workQueueLast = &q->next;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Manage a queue of sleeping clients, awakening them
|
||||
* when requested, by using the OS functions IgnoreClient
|
||||
* and AttendClient. Note that this *ignores* the troubles
|
||||
* with request data interleaving itself with events, but
|
||||
* we'll leave that until a later time.
|
||||
*/
|
||||
|
||||
typedef struct _SleepQueue {
|
||||
struct _SleepQueue *next;
|
||||
ClientPtr client;
|
||||
ClientSleepProcPtr function;
|
||||
pointer closure;
|
||||
} SleepQueueRec, *SleepQueuePtr;
|
||||
|
||||
static SleepQueuePtr sleepQueue = NULL;
|
||||
|
||||
_X_EXPORT Bool
|
||||
ClientSleep(ClientPtr client, ClientSleepProcPtr function, pointer closure)
|
||||
{
|
||||
SleepQueuePtr q;
|
||||
|
||||
q = malloc(sizeof *q);
|
||||
if (!q)
|
||||
return FALSE;
|
||||
|
||||
IgnoreClient(client);
|
||||
q->next = sleepQueue;
|
||||
q->client = client;
|
||||
q->function = function;
|
||||
q->closure = closure;
|
||||
sleepQueue = q;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
ClientSignal(ClientPtr client)
|
||||
{
|
||||
SleepQueuePtr q;
|
||||
|
||||
for (q = sleepQueue; q; q = q->next)
|
||||
if (q->client == client) {
|
||||
return QueueWorkProc(q->function, q->client, q->closure);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
ClientWakeup(ClientPtr client)
|
||||
{
|
||||
SleepQueuePtr q, *prev;
|
||||
|
||||
prev = &sleepQueue;
|
||||
while ((q = *prev)) {
|
||||
if (q->client == client) {
|
||||
*prev = q->next;
|
||||
free(q);
|
||||
if (client->clientGone)
|
||||
/* Oops -- new zombie cleanup code ensures this only
|
||||
* happens from inside CloseDownClient; don't want to
|
||||
* recurse here...
|
||||
*/
|
||||
/* CloseDownClient(client) */ ;
|
||||
else
|
||||
AttendClient(client);
|
||||
break;
|
||||
}
|
||||
prev = &q->next;
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
ClientIsAsleep(ClientPtr client)
|
||||
{
|
||||
SleepQueuePtr q;
|
||||
|
||||
for (q = sleepQueue; q; q = q->next)
|
||||
if (q->client == client)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic Callback Manager
|
||||
*/
|
||||
|
||||
/* ===== Private Procedures ===== */
|
||||
|
||||
static int numCallbackListsToCleanup = 0;
|
||||
|
||||
static CallbackListPtr **listsToCleanup = NULL;
|
||||
|
||||
static Bool
|
||||
_AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
|
||||
{
|
||||
CallbackPtr cbr;
|
||||
|
||||
cbr = malloc(sizeof(CallbackRec));
|
||||
if (!cbr)
|
||||
return FALSE;
|
||||
cbr->proc = callback;
|
||||
cbr->data = data;
|
||||
cbr->next = (*pcbl)->list;
|
||||
cbr->deleted = FALSE;
|
||||
(*pcbl)->list = cbr;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
_DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
|
||||
{
|
||||
CallbackListPtr cbl = *pcbl;
|
||||
|
||||
CallbackPtr cbr, pcbr;
|
||||
|
||||
for (pcbr = NULL, cbr = cbl->list; cbr != NULL; pcbr = cbr, cbr = cbr->next) {
|
||||
if ((cbr->proc == callback) && (cbr->data == data))
|
||||
break;
|
||||
}
|
||||
if (cbr != NULL) {
|
||||
if (cbl->inCallback) {
|
||||
++(cbl->numDeleted);
|
||||
cbr->deleted = TRUE;
|
||||
}
|
||||
else {
|
||||
if (pcbr == NULL)
|
||||
cbl->list = cbr->next;
|
||||
else
|
||||
pcbr->next = cbr->next;
|
||||
free(cbr);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_CallCallbacks(CallbackListPtr *pcbl, pointer call_data)
|
||||
{
|
||||
CallbackListPtr cbl = *pcbl;
|
||||
|
||||
CallbackPtr cbr, pcbr;
|
||||
|
||||
++(cbl->inCallback);
|
||||
for (cbr = cbl->list; cbr != NULL; cbr = cbr->next) {
|
||||
(*(cbr->proc)) (pcbl, cbr->data, call_data);
|
||||
}
|
||||
--(cbl->inCallback);
|
||||
|
||||
if (cbl->inCallback)
|
||||
return;
|
||||
|
||||
/* Was the entire list marked for deletion? */
|
||||
|
||||
if (cbl->deleted) {
|
||||
DeleteCallbackList(pcbl);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Were some individual callbacks on the list marked for deletion?
|
||||
* If so, do the deletions.
|
||||
*/
|
||||
|
||||
if (cbl->numDeleted) {
|
||||
for (pcbr = NULL, cbr = cbl->list; (cbr != NULL) && cbl->numDeleted;) {
|
||||
if (cbr->deleted) {
|
||||
if (pcbr) {
|
||||
cbr = cbr->next;
|
||||
free(pcbr->next);
|
||||
pcbr->next = cbr;
|
||||
}
|
||||
else {
|
||||
cbr = cbr->next;
|
||||
free(cbl->list);
|
||||
cbl->list = cbr;
|
||||
}
|
||||
cbl->numDeleted--;
|
||||
}
|
||||
else { /* this one wasn't deleted */
|
||||
|
||||
pcbr = cbr;
|
||||
cbr = cbr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_DeleteCallbackList(CallbackListPtr *pcbl)
|
||||
{
|
||||
CallbackListPtr cbl = *pcbl;
|
||||
|
||||
CallbackPtr cbr, nextcbr;
|
||||
|
||||
int i;
|
||||
|
||||
if (cbl->inCallback) {
|
||||
cbl->deleted = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < numCallbackListsToCleanup; i++) {
|
||||
if ((listsToCleanup[i] = pcbl) != 0) {
|
||||
listsToCleanup[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (cbr = cbl->list; cbr != NULL; cbr = nextcbr) {
|
||||
nextcbr = cbr->next;
|
||||
free(cbr);
|
||||
}
|
||||
free(cbl);
|
||||
*pcbl = NULL;
|
||||
}
|
||||
|
||||
static CallbackFuncsRec default_cbfuncs = {
|
||||
_AddCallback,
|
||||
_DeleteCallback,
|
||||
_CallCallbacks,
|
||||
_DeleteCallbackList
|
||||
};
|
||||
|
||||
/* ===== Public Procedures ===== */
|
||||
|
||||
Bool
|
||||
CreateCallbackList(CallbackListPtr *pcbl, CallbackFuncsPtr cbfuncs)
|
||||
{
|
||||
CallbackListPtr cbl;
|
||||
|
||||
int i;
|
||||
|
||||
if (!pcbl)
|
||||
return FALSE;
|
||||
cbl = malloc(sizeof(CallbackListRec));
|
||||
if (!cbl)
|
||||
return FALSE;
|
||||
cbl->funcs = cbfuncs ? *cbfuncs : default_cbfuncs;
|
||||
cbl->inCallback = 0;
|
||||
cbl->deleted = FALSE;
|
||||
cbl->numDeleted = 0;
|
||||
cbl->list = NULL;
|
||||
*pcbl = cbl;
|
||||
|
||||
for (i = 0; i < numCallbackListsToCleanup; i++) {
|
||||
if (!listsToCleanup[i]) {
|
||||
listsToCleanup[i] = pcbl;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
listsToCleanup = (CallbackListPtr **) realloc(listsToCleanup,
|
||||
sizeof(CallbackListPtr *) *
|
||||
(numCallbackListsToCleanup
|
||||
+ 1));
|
||||
listsToCleanup[numCallbackListsToCleanup] = pcbl;
|
||||
numCallbackListsToCleanup++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
|
||||
{
|
||||
if (!pcbl)
|
||||
return FALSE;
|
||||
if (!*pcbl) { /* list hasn't been created yet; go create it */
|
||||
if (!CreateCallbackList(pcbl, (CallbackFuncsPtr) NULL))
|
||||
return FALSE;
|
||||
}
|
||||
return ((*(*pcbl)->funcs.AddCallback) (pcbl, callback, data));
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
|
||||
{
|
||||
if (!pcbl || !*pcbl)
|
||||
return FALSE;
|
||||
return ((*(*pcbl)->funcs.DeleteCallback) (pcbl, callback, data));
|
||||
}
|
||||
|
||||
void
|
||||
CallCallbacks(CallbackListPtr *pcbl, pointer call_data)
|
||||
{
|
||||
if (!pcbl || !*pcbl)
|
||||
return;
|
||||
(*(*pcbl)->funcs.CallCallbacks) (pcbl, call_data);
|
||||
}
|
||||
|
||||
void
|
||||
DeleteCallbackList(CallbackListPtr *pcbl)
|
||||
{
|
||||
if (!pcbl || !*pcbl)
|
||||
return;
|
||||
(*(*pcbl)->funcs.DeleteCallbackList) (pcbl);
|
||||
}
|
||||
|
||||
void
|
||||
InitCallbackManager()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numCallbackListsToCleanup; i++) {
|
||||
DeleteCallbackList(listsToCleanup[i]);
|
||||
}
|
||||
if (listsToCleanup)
|
||||
free(listsToCleanup);
|
||||
|
||||
numCallbackListsToCleanup = 0;
|
||||
listsToCleanup = NULL;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,404 @@
|
|||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "misc.h"
|
||||
#include "dixstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include "gcstruct.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "dispatch.h"
|
||||
|
||||
#define EXTENSION_BASE 128
|
||||
#define EXTENSION_EVENT_BASE 64
|
||||
#define LAST_EVENT 128
|
||||
#define LAST_ERROR 255
|
||||
|
||||
ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
|
||||
|
||||
static ExtensionEntry **extensions = (ExtensionEntry **) NULL;
|
||||
|
||||
int lastEvent = EXTENSION_EVENT_BASE;
|
||||
|
||||
static int lastError = FirstExtensionError;
|
||||
|
||||
static unsigned int NumExtensions = 0;
|
||||
|
||||
extern int extensionPrivateLen;
|
||||
|
||||
extern unsigned *extensionPrivateSizes;
|
||||
|
||||
extern unsigned totalExtensionSize;
|
||||
|
||||
static void
|
||||
InitExtensionPrivates(ExtensionEntry * ext)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
DevUnion *ppriv;
|
||||
|
||||
unsigned *sizes;
|
||||
|
||||
unsigned size;
|
||||
|
||||
int i;
|
||||
|
||||
if (totalExtensionSize == sizeof(ExtensionEntry))
|
||||
ppriv = (DevUnion *) NULL;
|
||||
else
|
||||
ppriv = (DevUnion *) (ext + 1);
|
||||
|
||||
ext->devPrivates = ppriv;
|
||||
sizes = extensionPrivateSizes;
|
||||
ptr = (char *) (ppriv + extensionPrivateLen);
|
||||
for (i = extensionPrivateLen; --i >= 0; ppriv++, sizes++) {
|
||||
if ((size = *sizes)) {
|
||||
ppriv->ptr = (pointer) ptr;
|
||||
ptr += size;
|
||||
}
|
||||
else
|
||||
ppriv->ptr = (pointer) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_X_EXPORT ExtensionEntry *
|
||||
AddExtension(char *name, int NumEvents, int NumErrors,
|
||||
int (*MainProc) (ClientPtr c1),
|
||||
int (*SwappedMainProc) (ClientPtr c2),
|
||||
void (*CloseDownProc) (ExtensionEntry * e),
|
||||
unsigned short (*MinorOpcodeProc) (ClientPtr c3))
|
||||
{
|
||||
int i;
|
||||
|
||||
ExtensionEntry *ext, **newexts;
|
||||
|
||||
if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
|
||||
return ((ExtensionEntry *) NULL);
|
||||
if ((lastEvent + NumEvents > LAST_EVENT) ||
|
||||
(unsigned) (lastError + NumErrors > LAST_ERROR))
|
||||
return ((ExtensionEntry *) NULL);
|
||||
|
||||
ext = malloc(totalExtensionSize);
|
||||
if (!ext)
|
||||
return ((ExtensionEntry *) NULL);
|
||||
bzero(ext, totalExtensionSize);
|
||||
InitExtensionPrivates(ext);
|
||||
ext->name = malloc(strlen(name) + 1);
|
||||
ext->num_aliases = 0;
|
||||
ext->aliases = (char **) NULL;
|
||||
if (!ext->name) {
|
||||
free(ext);
|
||||
return ((ExtensionEntry *) NULL);
|
||||
}
|
||||
strcpy(ext->name, name);
|
||||
i = NumExtensions;
|
||||
newexts = (ExtensionEntry **) realloc(extensions,
|
||||
(i + 1) * sizeof(ExtensionEntry *));
|
||||
if (!newexts) {
|
||||
free(ext->name);
|
||||
free(ext);
|
||||
return ((ExtensionEntry *) NULL);
|
||||
}
|
||||
NumExtensions++;
|
||||
extensions = newexts;
|
||||
extensions[i] = ext;
|
||||
ext->index = i;
|
||||
ext->base = i + EXTENSION_BASE;
|
||||
ext->CloseDown = CloseDownProc;
|
||||
ext->MinorOpcode = MinorOpcodeProc;
|
||||
ProcVector[i + EXTENSION_BASE] = MainProc;
|
||||
SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
|
||||
if (NumEvents) {
|
||||
ext->eventBase = lastEvent;
|
||||
ext->eventLast = lastEvent + NumEvents;
|
||||
lastEvent += NumEvents;
|
||||
}
|
||||
else {
|
||||
ext->eventBase = 0;
|
||||
ext->eventLast = 0;
|
||||
}
|
||||
if (NumErrors) {
|
||||
ext->errorBase = lastError;
|
||||
ext->errorLast = lastError + NumErrors;
|
||||
lastError += NumErrors;
|
||||
}
|
||||
else {
|
||||
ext->errorBase = 0;
|
||||
ext->errorLast = 0;
|
||||
}
|
||||
|
||||
return (ext);
|
||||
}
|
||||
|
||||
static int
|
||||
FindExtension(char *extname, int len)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < NumExtensions; i++) {
|
||||
if ((strlen(extensions[i]->name) == len) &&
|
||||
!strncmp(extname, extensions[i]->name, len))
|
||||
break;
|
||||
for (j = extensions[i]->num_aliases; --j >= 0;) {
|
||||
if ((strlen(extensions[i]->aliases[j]) == len) &&
|
||||
!strncmp(extname, extensions[i]->aliases[j], len))
|
||||
break;
|
||||
}
|
||||
if (j >= 0)
|
||||
break;
|
||||
}
|
||||
return ((i == NumExtensions) ? -1 : i);
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
DeclareExtensionSecurity(char *extname, Bool secure)
|
||||
{
|
||||
}
|
||||
|
||||
_X_EXPORT unsigned short
|
||||
StandardMinorOpcode(ClientPtr client)
|
||||
{
|
||||
return ((xReq *) client->requestBuffer)->data;
|
||||
}
|
||||
|
||||
_X_EXPORT unsigned short
|
||||
MinorOpcodeOfRequest(ClientPtr client)
|
||||
{
|
||||
unsigned char major;
|
||||
|
||||
major = ((xReq *) client->requestBuffer)->reqType;
|
||||
if (major < EXTENSION_BASE)
|
||||
return 0;
|
||||
major -= EXTENSION_BASE;
|
||||
if (major >= NumExtensions)
|
||||
return 0;
|
||||
return (*extensions[major]->MinorOpcode) (client);
|
||||
}
|
||||
|
||||
void
|
||||
CloseDownExtensions()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = NumExtensions - 1; i >= 0; i--) {
|
||||
(*extensions[i]->CloseDown) (extensions[i]);
|
||||
NumExtensions = i;
|
||||
free(extensions[i]->name);
|
||||
for (j = extensions[i]->num_aliases; --j >= 0;)
|
||||
free(extensions[i]->aliases[j]);
|
||||
free(extensions[i]->aliases);
|
||||
free(extensions[i]);
|
||||
}
|
||||
free(extensions);
|
||||
extensions = (ExtensionEntry **) NULL;
|
||||
lastEvent = EXTENSION_EVENT_BASE;
|
||||
lastError = FirstExtensionError;
|
||||
for (i = 0; i < MAXSCREENS; i++) {
|
||||
ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
|
||||
|
||||
while (spentry->num) {
|
||||
spentry->num--;
|
||||
free(spentry->procList[spentry->num].name);
|
||||
}
|
||||
free(spentry->procList);
|
||||
spentry->procList = (ProcEntryPtr) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ProcQueryExtension(ClientPtr client)
|
||||
{
|
||||
xQueryExtensionReply reply = {0};
|
||||
|
||||
int i;
|
||||
|
||||
REQUEST(xQueryExtensionReq);
|
||||
|
||||
REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
|
||||
|
||||
reply.type = X_Reply;
|
||||
reply.length = 0;
|
||||
reply.major_opcode = 0;
|
||||
reply.sequenceNumber = client->sequence;
|
||||
|
||||
if (!NumExtensions)
|
||||
reply.present = xFalse;
|
||||
else {
|
||||
i = FindExtension((char *) &stuff[1], stuff->nbytes);
|
||||
if (i < 0
|
||||
)
|
||||
reply.present = xFalse;
|
||||
else {
|
||||
reply.present = xTrue;
|
||||
reply.major_opcode = extensions[i]->base;
|
||||
reply.first_event = extensions[i]->eventBase;
|
||||
reply.first_error = extensions[i]->errorBase;
|
||||
}
|
||||
}
|
||||
WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
int
|
||||
ProcListExtensions(ClientPtr client)
|
||||
{
|
||||
xListExtensionsReply reply = {0};
|
||||
|
||||
char *bufptr, *buffer;
|
||||
|
||||
int total_length = 0;
|
||||
|
||||
REQUEST_SIZE_MATCH(xReq);
|
||||
|
||||
reply.type = X_Reply;
|
||||
reply.nExtensions = 0;
|
||||
reply.length = 0;
|
||||
reply.sequenceNumber = client->sequence;
|
||||
buffer = NULL;
|
||||
|
||||
if (NumExtensions) {
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < NumExtensions; i++) {
|
||||
total_length += strlen(extensions[i]->name) + 1;
|
||||
reply.nExtensions += 1 + extensions[i]->num_aliases;
|
||||
for (j = extensions[i]->num_aliases; --j >= 0;)
|
||||
total_length += strlen(extensions[i]->aliases[j]) + 1;
|
||||
}
|
||||
reply.length = (total_length + 3) >> 2;
|
||||
buffer = bufptr = (char *) ALLOCATE_LOCAL(total_length);
|
||||
if (!buffer)
|
||||
return (BadAlloc);
|
||||
for (i = 0; i < NumExtensions; i++) {
|
||||
int len;
|
||||
|
||||
*bufptr++ = len = strlen(extensions[i]->name);
|
||||
memmove(bufptr, extensions[i]->name, len);
|
||||
bufptr += len;
|
||||
for (j = extensions[i]->num_aliases; --j >= 0;) {
|
||||
*bufptr++ = len = strlen(extensions[i]->aliases[j]);
|
||||
memmove(bufptr, extensions[i]->aliases[j], len);
|
||||
bufptr += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
|
||||
if (reply.length) {
|
||||
WriteToClient(client, total_length, buffer);
|
||||
DEALLOCATE_LOCAL(buffer);
|
||||
}
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
ExtensionLookupProc
|
||||
LookupProc(char *name, GCPtr pGC)
|
||||
{
|
||||
int i;
|
||||
|
||||
ScreenProcEntry *spentry;
|
||||
|
||||
spentry = &AuxillaryScreenProcs[pGC->pScreen->myNum];
|
||||
if (spentry->num) {
|
||||
for (i = 0; i < spentry->num; i++)
|
||||
if (strcmp(name, spentry->procList[i].name) == 0)
|
||||
return (spentry->procList[i].proc);
|
||||
}
|
||||
return (ExtensionLookupProc) NULL;
|
||||
}
|
||||
|
||||
Bool
|
||||
RegisterProc(char *name, GC * pGC, ExtensionLookupProc proc)
|
||||
{
|
||||
return RegisterScreenProc(name, pGC->pScreen, proc);
|
||||
}
|
||||
|
||||
Bool
|
||||
RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
|
||||
{
|
||||
ScreenProcEntry *spentry;
|
||||
|
||||
ProcEntryPtr procEntry = (ProcEntryPtr) NULL;
|
||||
|
||||
char *newname;
|
||||
|
||||
int i;
|
||||
|
||||
spentry = &AuxillaryScreenProcs[pScreen->myNum];
|
||||
/* first replace duplicates */
|
||||
if (spentry->num) {
|
||||
for (i = 0; i < spentry->num; i++)
|
||||
if (strcmp(name, spentry->procList[i].name) == 0) {
|
||||
procEntry = &spentry->procList[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (procEntry)
|
||||
procEntry->proc = proc;
|
||||
else {
|
||||
newname = malloc(strlen(name) + 1);
|
||||
if (!newname)
|
||||
return FALSE;
|
||||
procEntry = (ProcEntryPtr)
|
||||
realloc(spentry->procList,
|
||||
sizeof(ProcEntryRec) * (spentry->num + 1));
|
||||
if (!procEntry) {
|
||||
free(newname);
|
||||
return FALSE;
|
||||
}
|
||||
spentry->procList = procEntry;
|
||||
procEntry += spentry->num;
|
||||
procEntry->name = newname;
|
||||
strcpy(newname, name);
|
||||
procEntry->proc = proc;
|
||||
spentry->num++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
|
||||
Copyright 1996, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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 MERCHANTABIL-
|
||||
ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
|
||||
ITY, 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization from
|
||||
The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
ffs(int i)
|
||||
{
|
||||
int j;
|
||||
|
||||
if (i == 0)
|
||||
return 0;
|
||||
for (j = 1; (i & 1) == 0; j++)
|
||||
i >>= 1;
|
||||
return j;
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
/************************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include "misc.h"
|
||||
#include "windowstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "input.h"
|
||||
#include "dixfont.h"
|
||||
#include "site.h"
|
||||
#include "dixstruct.h"
|
||||
#include "os.h"
|
||||
|
||||
_X_EXPORT ScreenInfo screenInfo;
|
||||
|
||||
KeybdCtrl defaultKeyboardControl = {
|
||||
DEFAULT_KEYBOARD_CLICK,
|
||||
DEFAULT_BELL,
|
||||
DEFAULT_BELL_PITCH,
|
||||
DEFAULT_BELL_DURATION,
|
||||
DEFAULT_AUTOREPEAT,
|
||||
DEFAULT_AUTOREPEATS,
|
||||
DEFAULT_LEDS,
|
||||
0
|
||||
};
|
||||
|
||||
PtrCtrl defaultPointerControl = {
|
||||
DEFAULT_PTR_NUMERATOR,
|
||||
DEFAULT_PTR_DENOMINATOR,
|
||||
DEFAULT_PTR_THRESHOLD,
|
||||
0
|
||||
};
|
||||
|
||||
_X_EXPORT ClientPtr clients[MAXCLIENTS];
|
||||
_X_EXPORT ClientPtr serverClient;
|
||||
_X_EXPORT int currentMaxClients; /* current size of clients array */
|
||||
|
||||
_X_EXPORT long maxBigRequestSize = MAX_BIG_REQUEST_SIZE;
|
||||
|
||||
_X_EXPORT WindowPtr WindowTable[MAXSCREENS];
|
||||
|
||||
_X_EXPORT unsigned long globalSerialNumber = 0;
|
||||
|
||||
_X_EXPORT unsigned long serverGeneration = 0;
|
||||
|
||||
/* these next four are initialized in main.c */
|
||||
_X_EXPORT CARD32 ScreenSaverTime;
|
||||
|
||||
CARD32 ScreenSaverInterval;
|
||||
|
||||
_X_EXPORT int ScreenSaverBlanking;
|
||||
|
||||
int ScreenSaverAllowExposures;
|
||||
|
||||
#ifdef DPMSExtension
|
||||
# ifndef DEFAULT_STANDBY_TIME
|
||||
# define DEFAULT_STANDBY_TIME DEFAULT_SCREEN_SAVER_TIME * 2
|
||||
# endif
|
||||
# ifndef DEFAULT_SUSPEND_TIME
|
||||
# define DEFAULT_SUSPEND_TIME DEFAULT_SCREEN_SAVER_TIME * 3
|
||||
# endif
|
||||
# ifndef DEFAULT_OFF_TIME
|
||||
# define DEFAULT_OFF_TIME DEFAULT_SCREEN_SAVER_TIME * 4
|
||||
# endif
|
||||
# ifndef DEFAULT_DPMS_ENABLED
|
||||
# define DEFAULT_DPMS_ENABLED TRUE
|
||||
# endif
|
||||
|
||||
_X_EXPORT CARD16 DPMSPowerLevel = 0;
|
||||
|
||||
_X_EXPORT Bool DPMSEnabledSwitch = FALSE; /* these denote the DPMS command */
|
||||
_X_EXPORT Bool DPMSDisabledSwitch = FALSE; /* lind switch states */
|
||||
_X_EXPORT Bool DPMSCapableFlag = FALSE;
|
||||
|
||||
_X_EXPORT CARD32 DPMSStandbyTime;
|
||||
_X_EXPORT CARD32 DPMSSuspendTime;
|
||||
_X_EXPORT CARD32 DPMSOffTime;
|
||||
|
||||
_X_EXPORT Bool DPMSEnabled;
|
||||
#endif
|
||||
|
||||
CARD32 defaultScreenSaverTime = DEFAULT_SCREEN_SAVER_TIME;
|
||||
|
||||
CARD32 defaultScreenSaverInterval = DEFAULT_SCREEN_SAVER_INTERVAL;
|
||||
|
||||
int defaultScreenSaverBlanking = DEFAULT_SCREEN_SAVER_BLANKING;
|
||||
|
||||
int defaultScreenSaverAllowExposures = DEFAULT_SCREEN_SAVER_EXPOSURES;
|
||||
|
||||
#ifndef NOLOGOHACK
|
||||
int logoScreenSaver = DEFAULT_LOGO_SCREEN_SAVER;
|
||||
#endif
|
||||
|
||||
#ifdef SCREENSAVER
|
||||
Bool screenSaverSuspended = FALSE;
|
||||
#endif
|
||||
|
||||
char *defaultFontPath = COMPILEDDEFAULTFONTPATH;
|
||||
|
||||
char *defaultTextFont = COMPILEDDEFAULTFONT;
|
||||
|
||||
char *defaultCursorFont = COMPILEDCURSORFONT;
|
||||
|
||||
char *defaultDisplayClass = COMPILEDDISPLAYCLASS;
|
||||
|
||||
FontPtr defaultFont; /* not declared in dix.h to avoid including font.h in
|
||||
every compilation of dix code */
|
||||
CursorPtr rootCursor;
|
||||
|
||||
Bool blackRoot = FALSE;
|
||||
|
||||
Bool whiteRoot = FALSE;
|
||||
|
||||
ClientPtr requestingClient; /* XXX this should be obsolete now, remove? */
|
||||
|
||||
_X_EXPORT TimeStamp currentTime;
|
||||
|
||||
_X_EXPORT TimeStamp lastDeviceEventTime;
|
||||
|
||||
_X_EXPORT int defaultColorVisualClass = -1;
|
||||
|
||||
_X_EXPORT int monitorResolution = 0;
|
||||
|
||||
_X_EXPORT char *display;
|
||||
|
||||
CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
|
||||
|
||||
DDXPointRec dixScreenOrigins[MAXSCREENS];
|
|
@ -0,0 +1,194 @@
|
|||
/************************************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
#include <X11/fonts/fontstruct.h>
|
||||
#include "dixfontstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "gcstruct.h"
|
||||
#include "resource.h"
|
||||
#include "dix.h"
|
||||
#include "cursorstr.h"
|
||||
#include "opaque.h"
|
||||
#include "servermd.h"
|
||||
|
||||
/*
|
||||
get the bits out of the font in a portable way. to avoid
|
||||
dealing with padding and such-like, we draw the glyph into
|
||||
a bitmap, then read the bits out with GetImage, which
|
||||
uses server-natural format.
|
||||
since all screens return the same bitmap format, we'll just use
|
||||
the first one we find.
|
||||
the character origin lines up with the hotspot in the
|
||||
cursor metrics.
|
||||
*/
|
||||
|
||||
int
|
||||
ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm,
|
||||
unsigned char **ppbits)
|
||||
{
|
||||
ScreenPtr pScreen;
|
||||
|
||||
GCPtr pGC;
|
||||
|
||||
xRectangle rect;
|
||||
|
||||
PixmapPtr ppix;
|
||||
|
||||
long nby;
|
||||
|
||||
char *pbits;
|
||||
|
||||
ChangeGCVal gcval[3];
|
||||
|
||||
unsigned char char2b[2];
|
||||
|
||||
/* turn glyph index into a protocol-format char2b */
|
||||
char2b[0] = (unsigned char) (ch >> 8);
|
||||
char2b[1] = (unsigned char) (ch & 0xff);
|
||||
|
||||
pScreen = screenInfo.screens[0];
|
||||
nby = BitmapBytePad(cm->width) * (long) cm->height;
|
||||
pbits = malloc(nby);
|
||||
if (!pbits)
|
||||
return BadAlloc;
|
||||
/* zeroing the (pad) bits seems to help some ddx cursor handling */
|
||||
bzero(pbits, nby);
|
||||
|
||||
ppix = (PixmapPtr) (*pScreen->CreatePixmap) (pScreen, cm->width,
|
||||
cm->height, 1);
|
||||
pGC = GetScratchGC(1, pScreen);
|
||||
if (!ppix || !pGC) {
|
||||
if (ppix)
|
||||
(*pScreen->DestroyPixmap) (ppix);
|
||||
if (pGC)
|
||||
FreeScratchGC(pGC);
|
||||
free(pbits);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = cm->width;
|
||||
rect.height = cm->height;
|
||||
|
||||
/* fill the pixmap with 0 */
|
||||
gcval[0].val = GXcopy;
|
||||
gcval[1].val = 0;
|
||||
gcval[2].ptr = (pointer) pfont;
|
||||
dixChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFont,
|
||||
NULL, gcval);
|
||||
ValidateGC((DrawablePtr) ppix, pGC);
|
||||
(*pGC->ops->PolyFillRect) ((DrawablePtr) ppix, pGC, 1, &rect);
|
||||
|
||||
/* draw the glyph */
|
||||
gcval[0].val = 1;
|
||||
dixChangeGC(NullClient, pGC, GCForeground, NULL, gcval);
|
||||
ValidateGC((DrawablePtr) ppix, pGC);
|
||||
(*pGC->ops->PolyText16) ((DrawablePtr) ppix, pGC, cm->xhot, cm->yhot,
|
||||
1, (unsigned short *) char2b);
|
||||
(*pScreen->GetImage) ((DrawablePtr) ppix, 0, 0, cm->width, cm->height,
|
||||
XYPixmap, 1, pbits);
|
||||
*ppbits = (unsigned char *) pbits;
|
||||
FreeScratchGC(pGC);
|
||||
(*pScreen->DestroyPixmap) (ppix);
|
||||
return Success;
|
||||
}
|
||||
|
||||
Bool
|
||||
CursorMetricsFromGlyph(register FontPtr pfont, unsigned ch,
|
||||
register CursorMetricPtr cm)
|
||||
{
|
||||
CharInfoPtr pci;
|
||||
|
||||
unsigned long nglyphs;
|
||||
|
||||
CARD8 chs[2];
|
||||
|
||||
FontEncoding encoding;
|
||||
|
||||
chs[0] = ch >> 8;
|
||||
chs[1] = ch;
|
||||
encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
|
||||
if (encoding == Linear16Bit) {
|
||||
if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
|
||||
return FALSE;
|
||||
if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
|
||||
return FALSE;
|
||||
}
|
||||
(*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
|
||||
if (nglyphs == 0)
|
||||
return FALSE;
|
||||
cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
|
||||
cm->height = pci->metrics.descent + pci->metrics.ascent;
|
||||
if (pci->metrics.leftSideBearing > 0) {
|
||||
cm->width += pci->metrics.leftSideBearing;
|
||||
cm->xhot = 0;
|
||||
}
|
||||
else {
|
||||
cm->xhot = -pci->metrics.leftSideBearing;
|
||||
if (pci->metrics.rightSideBearing < 0)
|
||||
cm->width -= pci->metrics.rightSideBearing;
|
||||
}
|
||||
if (pci->metrics.ascent < 0) {
|
||||
cm->height -= pci->metrics.ascent;
|
||||
cm->yhot = 0;
|
||||
}
|
||||
else {
|
||||
cm->yhot = pci->metrics.ascent;
|
||||
if (pci->metrics.descent < 0)
|
||||
cm->height -= pci->metrics.descent;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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 OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN action OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include "misc.h"
|
||||
#include <X11/Xproto.h>
|
||||
#include "windowstr.h"
|
||||
#include "inputstr.h"
|
||||
#include "cursorstr.h"
|
||||
#include "dixgrabs.h"
|
||||
|
||||
#define BITMASK(i) (((Mask)1) << ((i) & 31))
|
||||
#define MASKIDX(i) ((i) >> 5)
|
||||
#define MASKWORD(buf, i) buf[MASKIDX(i)]
|
||||
#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
|
||||
#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
|
||||
#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
|
||||
|
||||
GrabPtr
|
||||
CreateGrab(int client, DeviceIntPtr device, WindowPtr window, Mask eventMask, Bool ownerEvents, Bool keyboardMode, Bool pointerMode, DeviceIntPtr modDevice, unsigned short modifiers, int type, KeyCode keybut, /* key or button */
|
||||
WindowPtr confineTo, CursorPtr cursor)
|
||||
{
|
||||
GrabPtr grab;
|
||||
|
||||
grab = malloc(sizeof(GrabRec));
|
||||
if (!grab)
|
||||
return (GrabPtr) NULL;
|
||||
grab->resource = FakeClientID(client);
|
||||
grab->device = device;
|
||||
grab->coreGrab = ((device == inputInfo.keyboard) ||
|
||||
(device == inputInfo.pointer));
|
||||
grab->window = window;
|
||||
grab->eventMask = eventMask;
|
||||
grab->ownerEvents = ownerEvents;
|
||||
grab->keyboardMode = keyboardMode;
|
||||
grab->pointerMode = pointerMode;
|
||||
grab->modifiersDetail.exact = modifiers;
|
||||
grab->modifiersDetail.pMask = NULL;
|
||||
grab->modifierDevice = modDevice;
|
||||
grab->coreMods = ((modDevice == inputInfo.keyboard) ||
|
||||
(modDevice == inputInfo.pointer));
|
||||
grab->type = type;
|
||||
grab->detail.exact = keybut;
|
||||
grab->detail.pMask = NULL;
|
||||
grab->confineTo = confineTo;
|
||||
grab->cursor = cursor;
|
||||
if (cursor)
|
||||
cursor->refcnt++;
|
||||
return grab;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
FreeGrab(GrabPtr pGrab)
|
||||
{
|
||||
if (pGrab->modifiersDetail.pMask != NULL)
|
||||
free(pGrab->modifiersDetail.pMask);
|
||||
|
||||
if (pGrab->detail.pMask != NULL)
|
||||
free(pGrab->detail.pMask);
|
||||
|
||||
if (pGrab->cursor)
|
||||
FreeCursor(pGrab->cursor, (Cursor) 0);
|
||||
|
||||
free(pGrab);
|
||||
}
|
||||
|
||||
int
|
||||
DeletePassiveGrab(pointer value, XID id)
|
||||
{
|
||||
GrabPtr g, prev;
|
||||
|
||||
GrabPtr pGrab = (GrabPtr) value;
|
||||
|
||||
/* it is OK if the grab isn't found */
|
||||
prev = 0;
|
||||
for (g = (wPassiveGrabs(pGrab->window)); g; g = g->next) {
|
||||
if (pGrab == g) {
|
||||
if (prev)
|
||||
prev->next = g->next;
|
||||
else if (!(pGrab->window->optional->passiveGrabs = g->next))
|
||||
CheckWindowOptionalNeed(pGrab->window);
|
||||
break;
|
||||
}
|
||||
prev = g;
|
||||
}
|
||||
FreeGrab(pGrab);
|
||||
return Success;
|
||||
}
|
||||
|
||||
static Mask *
|
||||
DeleteDetailFromMask(Mask *pDetailMask, unsigned short detail)
|
||||
{
|
||||
Mask *mask;
|
||||
|
||||
int i;
|
||||
|
||||
mask = malloc(sizeof(Mask) * MasksPerDetailMask);
|
||||
if (mask) {
|
||||
if (pDetailMask)
|
||||
for (i = 0; i < MasksPerDetailMask; i++)
|
||||
mask[i] = pDetailMask[i];
|
||||
else
|
||||
for (i = 0; i < MasksPerDetailMask; i++)
|
||||
mask[i] = ~0L;
|
||||
BITCLEAR(mask, detail);
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
static Bool
|
||||
IsInGrabMask(DetailRec firstDetail,
|
||||
DetailRec secondDetail, unsigned short exception)
|
||||
{
|
||||
if (firstDetail.exact == exception) {
|
||||
if (firstDetail.pMask == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* (at present) never called with two non-null pMasks */
|
||||
if (secondDetail.exact == exception)
|
||||
return FALSE;
|
||||
|
||||
if (GETBIT(firstDetail.pMask, secondDetail.exact))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
IdenticalExactDetails(unsigned short firstExact,
|
||||
unsigned short secondExact, unsigned short exception)
|
||||
{
|
||||
if ((firstExact == exception) || (secondExact == exception))
|
||||
return FALSE;
|
||||
|
||||
if (firstExact == secondExact)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
DetailSupersedesSecond(DetailRec firstDetail,
|
||||
DetailRec secondDetail, unsigned short exception)
|
||||
{
|
||||
if (IsInGrabMask(firstDetail, secondDetail, exception))
|
||||
return TRUE;
|
||||
|
||||
if (IdenticalExactDetails(firstDetail.exact, secondDetail.exact, exception))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
|
||||
{
|
||||
if (!DetailSupersedesSecond(pFirstGrab->modifiersDetail,
|
||||
pSecondGrab->modifiersDetail,
|
||||
(unsigned short) AnyModifier))
|
||||
return FALSE;
|
||||
|
||||
if (DetailSupersedesSecond(pFirstGrab->detail,
|
||||
pSecondGrab->detail, (unsigned short) AnyKey))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool
|
||||
GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
|
||||
{
|
||||
if ((pFirstGrab->device != pSecondGrab->device) ||
|
||||
(pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) ||
|
||||
(pFirstGrab->type != pSecondGrab->type))
|
||||
return FALSE;
|
||||
|
||||
if (GrabSupersedesSecond(pFirstGrab, pSecondGrab) ||
|
||||
GrabSupersedesSecond(pSecondGrab, pFirstGrab))
|
||||
return TRUE;
|
||||
|
||||
if (DetailSupersedesSecond(pSecondGrab->detail, pFirstGrab->detail,
|
||||
(unsigned short) AnyKey)
|
||||
&&
|
||||
DetailSupersedesSecond(pFirstGrab->modifiersDetail,
|
||||
pSecondGrab->modifiersDetail,
|
||||
(unsigned short) AnyModifier))
|
||||
return TRUE;
|
||||
|
||||
if (DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail,
|
||||
(unsigned short) AnyKey)
|
||||
&&
|
||||
DetailSupersedesSecond(pSecondGrab->modifiersDetail,
|
||||
pFirstGrab->modifiersDetail,
|
||||
(unsigned short) AnyModifier))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
AddPassiveGrabToList(GrabPtr pGrab)
|
||||
{
|
||||
GrabPtr grab;
|
||||
|
||||
for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next) {
|
||||
if (GrabMatchesSecond(pGrab, grab)) {
|
||||
if (CLIENT_BITS(pGrab->resource) != CLIENT_BITS(grab->resource)) {
|
||||
FreeGrab(pGrab);
|
||||
return BadAccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pGrab->window->optional && !MakeWindowOptional(pGrab->window)) {
|
||||
FreeGrab(pGrab);
|
||||
return BadAlloc;
|
||||
}
|
||||
pGrab->next = pGrab->window->optional->passiveGrabs;
|
||||
pGrab->window->optional->passiveGrabs = pGrab;
|
||||
if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (pointer) pGrab))
|
||||
return Success;
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
/* the following is kinda complicated, because we need to be able to back out
|
||||
* if any allocation fails
|
||||
*/
|
||||
|
||||
Bool
|
||||
DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
|
||||
{
|
||||
GrabPtr grab;
|
||||
|
||||
GrabPtr *deletes, *adds;
|
||||
|
||||
Mask ***updates, **details;
|
||||
|
||||
int i, ndels, nadds, nups;
|
||||
|
||||
Bool ok;
|
||||
|
||||
#define UPDATE(mask,exact) \
|
||||
if (!(details[nups] = DeleteDetailFromMask(mask, exact))) \
|
||||
ok = FALSE; \
|
||||
else \
|
||||
updates[nups++] = &(mask)
|
||||
|
||||
i = 0;
|
||||
for (grab = wPassiveGrabs(pMinuendGrab->window); grab; grab = grab->next)
|
||||
i++;
|
||||
if (!i)
|
||||
return TRUE;
|
||||
deletes = (GrabPtr *) ALLOCATE_LOCAL(i * sizeof(GrabPtr));
|
||||
adds = (GrabPtr *) ALLOCATE_LOCAL(i * sizeof(GrabPtr));
|
||||
updates = (Mask ***) ALLOCATE_LOCAL(i * sizeof(Mask **));
|
||||
details = (Mask **) ALLOCATE_LOCAL(i * sizeof(Mask *));
|
||||
if (!deletes || !adds || !updates || !details) {
|
||||
if (details)
|
||||
DEALLOCATE_LOCAL(details);
|
||||
if (updates)
|
||||
DEALLOCATE_LOCAL(updates);
|
||||
if (adds)
|
||||
DEALLOCATE_LOCAL(adds);
|
||||
if (deletes)
|
||||
DEALLOCATE_LOCAL(deletes);
|
||||
return FALSE;
|
||||
}
|
||||
ndels = nadds = nups = 0;
|
||||
ok = TRUE;
|
||||
for (grab = wPassiveGrabs(pMinuendGrab->window);
|
||||
grab && ok; grab = grab->next) {
|
||||
if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource))
|
||||
|| !GrabMatchesSecond(grab, pMinuendGrab))
|
||||
continue;
|
||||
if (GrabSupersedesSecond(pMinuendGrab, grab)) {
|
||||
deletes[ndels++] = grab;
|
||||
}
|
||||
else if ((grab->detail.exact == AnyKey)
|
||||
&& (grab->modifiersDetail.exact != AnyModifier)) {
|
||||
UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
|
||||
}
|
||||
else if ((grab->modifiersDetail.exact == AnyModifier)
|
||||
&& (grab->detail.exact != AnyKey)) {
|
||||
UPDATE(grab->modifiersDetail.pMask,
|
||||
pMinuendGrab->modifiersDetail.exact);
|
||||
}
|
||||
else if ((pMinuendGrab->detail.exact != AnyKey)
|
||||
&& (pMinuendGrab->modifiersDetail.exact != AnyModifier)) {
|
||||
GrabPtr pNewGrab;
|
||||
|
||||
UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
|
||||
|
||||
pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device,
|
||||
grab->window, (Mask) grab->eventMask,
|
||||
(Bool) grab->ownerEvents,
|
||||
(Bool) grab->keyboardMode,
|
||||
(Bool) grab->pointerMode,
|
||||
grab->modifierDevice,
|
||||
AnyModifier, (int) grab->type,
|
||||
pMinuendGrab->detail.exact,
|
||||
grab->confineTo, grab->cursor);
|
||||
if (!pNewGrab)
|
||||
ok = FALSE;
|
||||
else if (!(pNewGrab->modifiersDetail.pMask =
|
||||
DeleteDetailFromMask(grab->modifiersDetail.pMask,
|
||||
pMinuendGrab->modifiersDetail.
|
||||
exact))
|
||||
|| (!pNewGrab->window->optional &&
|
||||
!MakeWindowOptional(pNewGrab->window))) {
|
||||
FreeGrab(pNewGrab);
|
||||
ok = FALSE;
|
||||
}
|
||||
else if (!AddResource(pNewGrab->resource, RT_PASSIVEGRAB,
|
||||
(pointer) pNewGrab))
|
||||
ok = FALSE;
|
||||
else
|
||||
adds[nadds++] = pNewGrab;
|
||||
}
|
||||
else if (pMinuendGrab->detail.exact == AnyKey) {
|
||||
UPDATE(grab->modifiersDetail.pMask,
|
||||
pMinuendGrab->modifiersDetail.exact);
|
||||
}
|
||||
else {
|
||||
UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
for (i = 0; i < nadds; i++)
|
||||
FreeResource(adds[i]->resource, RT_NONE);
|
||||
for (i = 0; i < nups; i++)
|
||||
free(details[i]);
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < ndels; i++)
|
||||
FreeResource(deletes[i]->resource, RT_NONE);
|
||||
for (i = 0; i < nadds; i++) {
|
||||
grab = adds[i];
|
||||
grab->next = grab->window->optional->passiveGrabs;
|
||||
grab->window->optional->passiveGrabs = grab;
|
||||
}
|
||||
for (i = 0; i < nups; i++) {
|
||||
free(*updates[i]);
|
||||
*updates[i] = details[i];
|
||||
}
|
||||
}
|
||||
DEALLOCATE_LOCAL(details);
|
||||
DEALLOCATE_LOCAL(updates);
|
||||
DEALLOCATE_LOCAL(adds);
|
||||
DEALLOCATE_LOCAL(deletes);
|
||||
return ok;
|
||||
|
||||
#undef UPDATE
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/* THIS IS A GENERATED FILE
|
||||
*
|
||||
* Do not change! Changing this file implies a protocol change!
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include "misc.h"
|
||||
#include "dix.h"
|
||||
void
|
||||
MakePredeclaredAtoms()
|
||||
{
|
||||
if (MakeAtom("PRIMARY", 7, 1) != XA_PRIMARY)
|
||||
AtomError();
|
||||
if (MakeAtom("SECONDARY", 9, 1) != XA_SECONDARY)
|
||||
AtomError();
|
||||
if (MakeAtom("ARC", 3, 1) != XA_ARC)
|
||||
AtomError();
|
||||
if (MakeAtom("ATOM", 4, 1) != XA_ATOM)
|
||||
AtomError();
|
||||
if (MakeAtom("BITMAP", 6, 1) != XA_BITMAP)
|
||||
AtomError();
|
||||
if (MakeAtom("CARDINAL", 8, 1) != XA_CARDINAL)
|
||||
AtomError();
|
||||
if (MakeAtom("COLORMAP", 8, 1) != XA_COLORMAP)
|
||||
AtomError();
|
||||
if (MakeAtom("CURSOR", 6, 1) != XA_CURSOR)
|
||||
AtomError();
|
||||
if (MakeAtom("CUT_BUFFER0", 11, 1) != XA_CUT_BUFFER0)
|
||||
AtomError();
|
||||
if (MakeAtom("CUT_BUFFER1", 11, 1) != XA_CUT_BUFFER1)
|
||||
AtomError();
|
||||
if (MakeAtom("CUT_BUFFER2", 11, 1) != XA_CUT_BUFFER2)
|
||||
AtomError();
|
||||
if (MakeAtom("CUT_BUFFER3", 11, 1) != XA_CUT_BUFFER3)
|
||||
AtomError();
|
||||
if (MakeAtom("CUT_BUFFER4", 11, 1) != XA_CUT_BUFFER4)
|
||||
AtomError();
|
||||
if (MakeAtom("CUT_BUFFER5", 11, 1) != XA_CUT_BUFFER5)
|
||||
AtomError();
|
||||
if (MakeAtom("CUT_BUFFER6", 11, 1) != XA_CUT_BUFFER6)
|
||||
AtomError();
|
||||
if (MakeAtom("CUT_BUFFER7", 11, 1) != XA_CUT_BUFFER7)
|
||||
AtomError();
|
||||
if (MakeAtom("DRAWABLE", 8, 1) != XA_DRAWABLE)
|
||||
AtomError();
|
||||
if (MakeAtom("FONT", 4, 1) != XA_FONT)
|
||||
AtomError();
|
||||
if (MakeAtom("INTEGER", 7, 1) != XA_INTEGER)
|
||||
AtomError();
|
||||
if (MakeAtom("PIXMAP", 6, 1) != XA_PIXMAP)
|
||||
AtomError();
|
||||
if (MakeAtom("POINT", 5, 1) != XA_POINT)
|
||||
AtomError();
|
||||
if (MakeAtom("RECTANGLE", 9, 1) != XA_RECTANGLE)
|
||||
AtomError();
|
||||
if (MakeAtom("RESOURCE_MANAGER", 16, 1) != XA_RESOURCE_MANAGER)
|
||||
AtomError();
|
||||
if (MakeAtom("RGB_COLOR_MAP", 13, 1) != XA_RGB_COLOR_MAP)
|
||||
AtomError();
|
||||
if (MakeAtom("RGB_BEST_MAP", 12, 1) != XA_RGB_BEST_MAP)
|
||||
AtomError();
|
||||
if (MakeAtom("RGB_BLUE_MAP", 12, 1) != XA_RGB_BLUE_MAP)
|
||||
AtomError();
|
||||
if (MakeAtom("RGB_DEFAULT_MAP", 15, 1) != XA_RGB_DEFAULT_MAP)
|
||||
AtomError();
|
||||
if (MakeAtom("RGB_GRAY_MAP", 12, 1) != XA_RGB_GRAY_MAP)
|
||||
AtomError();
|
||||
if (MakeAtom("RGB_GREEN_MAP", 13, 1) != XA_RGB_GREEN_MAP)
|
||||
AtomError();
|
||||
if (MakeAtom("RGB_RED_MAP", 11, 1) != XA_RGB_RED_MAP)
|
||||
AtomError();
|
||||
if (MakeAtom("STRING", 6, 1) != XA_STRING)
|
||||
AtomError();
|
||||
if (MakeAtom("VISUALID", 8, 1) != XA_VISUALID)
|
||||
AtomError();
|
||||
if (MakeAtom("WINDOW", 6, 1) != XA_WINDOW)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_COMMAND", 10, 1) != XA_WM_COMMAND)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_HINTS", 8, 1) != XA_WM_HINTS)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_CLIENT_MACHINE", 17, 1) != XA_WM_CLIENT_MACHINE)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_ICON_NAME", 12, 1) != XA_WM_ICON_NAME)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_ICON_SIZE", 12, 1) != XA_WM_ICON_SIZE)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_NAME", 7, 1) != XA_WM_NAME)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_NORMAL_HINTS", 15, 1) != XA_WM_NORMAL_HINTS)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_SIZE_HINTS", 13, 1) != XA_WM_SIZE_HINTS)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_ZOOM_HINTS", 13, 1) != XA_WM_ZOOM_HINTS)
|
||||
AtomError();
|
||||
if (MakeAtom("MIN_SPACE", 9, 1) != XA_MIN_SPACE)
|
||||
AtomError();
|
||||
if (MakeAtom("NORM_SPACE", 10, 1) != XA_NORM_SPACE)
|
||||
AtomError();
|
||||
if (MakeAtom("MAX_SPACE", 9, 1) != XA_MAX_SPACE)
|
||||
AtomError();
|
||||
if (MakeAtom("END_SPACE", 9, 1) != XA_END_SPACE)
|
||||
AtomError();
|
||||
if (MakeAtom("SUPERSCRIPT_X", 13, 1) != XA_SUPERSCRIPT_X)
|
||||
AtomError();
|
||||
if (MakeAtom("SUPERSCRIPT_Y", 13, 1) != XA_SUPERSCRIPT_Y)
|
||||
AtomError();
|
||||
if (MakeAtom("SUBSCRIPT_X", 11, 1) != XA_SUBSCRIPT_X)
|
||||
AtomError();
|
||||
if (MakeAtom("SUBSCRIPT_Y", 11, 1) != XA_SUBSCRIPT_Y)
|
||||
AtomError();
|
||||
if (MakeAtom("UNDERLINE_POSITION", 18, 1) != XA_UNDERLINE_POSITION)
|
||||
AtomError();
|
||||
if (MakeAtom("UNDERLINE_THICKNESS", 19, 1) != XA_UNDERLINE_THICKNESS)
|
||||
AtomError();
|
||||
if (MakeAtom("STRIKEOUT_ASCENT", 16, 1) != XA_STRIKEOUT_ASCENT)
|
||||
AtomError();
|
||||
if (MakeAtom("STRIKEOUT_DESCENT", 17, 1) != XA_STRIKEOUT_DESCENT)
|
||||
AtomError();
|
||||
if (MakeAtom("ITALIC_ANGLE", 12, 1) != XA_ITALIC_ANGLE)
|
||||
AtomError();
|
||||
if (MakeAtom("X_HEIGHT", 8, 1) != XA_X_HEIGHT)
|
||||
AtomError();
|
||||
if (MakeAtom("QUAD_WIDTH", 10, 1) != XA_QUAD_WIDTH)
|
||||
AtomError();
|
||||
if (MakeAtom("WEIGHT", 6, 1) != XA_WEIGHT)
|
||||
AtomError();
|
||||
if (MakeAtom("POINT_SIZE", 10, 1) != XA_POINT_SIZE)
|
||||
AtomError();
|
||||
if (MakeAtom("RESOLUTION", 10, 1) != XA_RESOLUTION)
|
||||
AtomError();
|
||||
if (MakeAtom("COPYRIGHT", 9, 1) != XA_COPYRIGHT)
|
||||
AtomError();
|
||||
if (MakeAtom("NOTICE", 6, 1) != XA_NOTICE)
|
||||
AtomError();
|
||||
if (MakeAtom("FONT_NAME", 9, 1) != XA_FONT_NAME)
|
||||
AtomError();
|
||||
if (MakeAtom("FAMILY_NAME", 11, 1) != XA_FAMILY_NAME)
|
||||
AtomError();
|
||||
if (MakeAtom("FULL_NAME", 9, 1) != XA_FULL_NAME)
|
||||
AtomError();
|
||||
if (MakeAtom("CAP_HEIGHT", 10, 1) != XA_CAP_HEIGHT)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_CLASS", 8, 1) != XA_WM_CLASS)
|
||||
AtomError();
|
||||
if (MakeAtom("WM_TRANSIENT_FOR", 16, 1) != XA_WM_TRANSIENT_FOR)
|
||||
AtomError();
|
||||
}
|
|
@ -0,0 +1,661 @@
|
|||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/* The panoramix components contained the following notice */
|
||||
/*****************************************************************
|
||||
|
||||
Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
|
||||
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
|
||||
|
||||
Except as contained in this notice, the name of Digital Equipment Corporation
|
||||
shall not be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Software without prior written authorization from Digital
|
||||
Equipment Corporation.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xos.h> /* for unistd.h */
|
||||
#include <X11/Xproto.h>
|
||||
#include "scrnintstr.h"
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "windowstr.h"
|
||||
#include "resource.h"
|
||||
#include "dixstruct.h"
|
||||
#include "gcstruct.h"
|
||||
#include "extension.h"
|
||||
#include "colormap.h"
|
||||
#include "colormapst.h"
|
||||
#include "cursorstr.h"
|
||||
#include <X11/fonts/font.h>
|
||||
#include "opaque.h"
|
||||
#include "servermd.h"
|
||||
#include "site.h"
|
||||
#include "dixfont.h"
|
||||
#include "extnsionst.h"
|
||||
#include "dixevents.h" /* InitEvents() */
|
||||
|
||||
#ifdef DPMSExtension
|
||||
#define DPMS_SERVER
|
||||
#include <X11/extensions/dpms.h>
|
||||
#include "dpmsproc.h"
|
||||
#endif
|
||||
|
||||
extern int InitClientPrivates(ClientPtr client);
|
||||
|
||||
extern void Dispatch(void);
|
||||
|
||||
char *ConnectionInfo;
|
||||
|
||||
xConnSetupPrefix connSetupPrefix;
|
||||
|
||||
extern FontPtr defaultFont;
|
||||
|
||||
extern int screenPrivateCount;
|
||||
|
||||
extern Bool CreateGCperDepthArray(void);
|
||||
|
||||
static
|
||||
Bool CreateConnectionBlock(void);
|
||||
|
||||
static void FreeScreen(ScreenPtr);
|
||||
|
||||
_X_EXPORT PaddingInfo PixmapWidthPaddingInfo[33];
|
||||
|
||||
int connBlockScreenStart;
|
||||
|
||||
_X_EXPORT void
|
||||
NotImplemented(xEvent *from, xEvent *to)
|
||||
{
|
||||
FatalError("Not implemented");
|
||||
}
|
||||
|
||||
/*
|
||||
* Dummy entry for ReplySwapVector[]
|
||||
*/
|
||||
|
||||
void
|
||||
ReplyNotSwappd(ClientPtr pClient, int size, void *pbuf)
|
||||
{
|
||||
FatalError("Not implemented");
|
||||
}
|
||||
|
||||
/*
|
||||
* This array encodes the answer to the question "what is the log base 2
|
||||
* of the number of pixels that fit in a scanline pad unit?"
|
||||
* Note that ~0 is an invalid entry (mostly for the benefit of the reader).
|
||||
*/
|
||||
static int answer[6][4] = {
|
||||
/* pad pad pad pad */
|
||||
/* 8 16 32 64 */
|
||||
|
||||
{3, 4, 5, 6}, /* 1 bit per pixel */
|
||||
{1, 2, 3, 4}, /* 4 bits per pixel */
|
||||
{0, 1, 2, 3}, /* 8 bits per pixel */
|
||||
{~0, 0, 1, 2}, /* 16 bits per pixel */
|
||||
{~0, ~0, 0, 1}, /* 24 bits per pixel */
|
||||
{~0, ~0, 0, 1} /* 32 bits per pixel */
|
||||
};
|
||||
|
||||
/*
|
||||
* This array gives the answer to the question "what is the first index for
|
||||
* the answer array above given the number of bits per pixel?"
|
||||
* Note that ~0 is an invalid entry (mostly for the benefit of the reader).
|
||||
*/
|
||||
static int indexForBitsPerPixel[33] = {
|
||||
~0, 0, ~0, ~0, /* 1 bit per pixel */
|
||||
1, ~0, ~0, ~0, /* 4 bits per pixel */
|
||||
2, ~0, ~0, ~0, /* 8 bits per pixel */
|
||||
~0, ~0, ~0, ~0,
|
||||
3, ~0, ~0, ~0, /* 16 bits per pixel */
|
||||
~0, ~0, ~0, ~0,
|
||||
4, ~0, ~0, ~0, /* 24 bits per pixel */
|
||||
~0, ~0, ~0, ~0,
|
||||
5 /* 32 bits per pixel */
|
||||
};
|
||||
|
||||
/*
|
||||
* This array gives the bytesperPixel value for cases where the number
|
||||
* of bits per pixel is a multiple of 8 but not a power of 2.
|
||||
*/
|
||||
static int answerBytesPerPixel[33] = {
|
||||
~0, 0, ~0, ~0, /* 1 bit per pixel */
|
||||
0, ~0, ~0, ~0, /* 4 bits per pixel */
|
||||
0, ~0, ~0, ~0, /* 8 bits per pixel */
|
||||
~0, ~0, ~0, ~0,
|
||||
0, ~0, ~0, ~0, /* 16 bits per pixel */
|
||||
~0, ~0, ~0, ~0,
|
||||
3, ~0, ~0, ~0, /* 24 bits per pixel */
|
||||
~0, ~0, ~0, ~0,
|
||||
0 /* 32 bits per pixel */
|
||||
};
|
||||
|
||||
/*
|
||||
* This array gives the answer to the question "what is the second index for
|
||||
* the answer array above given the number of bits per scanline pad unit?"
|
||||
* Note that ~0 is an invalid entry (mostly for the benefit of the reader).
|
||||
*/
|
||||
static int indexForScanlinePad[65] = {
|
||||
~0, ~0, ~0, ~0,
|
||||
~0, ~0, ~0, ~0,
|
||||
0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
|
||||
~0, ~0, ~0, ~0,
|
||||
1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
|
||||
~0, ~0, ~0, ~0,
|
||||
~0, ~0, ~0, ~0,
|
||||
~0, ~0, ~0, ~0,
|
||||
2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
|
||||
~0, ~0, ~0, ~0,
|
||||
~0, ~0, ~0, ~0,
|
||||
~0, ~0, ~0, ~0,
|
||||
~0, ~0, ~0, ~0,
|
||||
~0, ~0, ~0, ~0,
|
||||
~0, ~0, ~0, ~0,
|
||||
~0, ~0, ~0, ~0,
|
||||
3 /* 64 bits per scanline pad unit */
|
||||
};
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
int i;
|
||||
|
||||
char *xauthfile;
|
||||
|
||||
HWEventQueueType alwaysCheckForInput[2];
|
||||
|
||||
display = "0";
|
||||
|
||||
/* Quartz support on Mac OS X requires that the Cocoa event loop be in
|
||||
* the main thread. This allows the X server main to be called again
|
||||
* from another thread. */
|
||||
|
||||
CheckUserParameters(argc, argv, envp);
|
||||
|
||||
CheckUserAuthorization();
|
||||
|
||||
|
||||
InitConnectionLimits();
|
||||
|
||||
/* prep X authority file from environment; this can be overriden by a
|
||||
* command line option */
|
||||
xauthfile = getenv("XAUTHORITY");
|
||||
if (xauthfile)
|
||||
InitAuthorization(xauthfile);
|
||||
ProcessCommandLine(argc, argv);
|
||||
|
||||
alwaysCheckForInput[0] = 0;
|
||||
alwaysCheckForInput[1] = 1;
|
||||
while (1) {
|
||||
serverGeneration++;
|
||||
ScreenSaverTime = defaultScreenSaverTime;
|
||||
ScreenSaverInterval = defaultScreenSaverInterval;
|
||||
ScreenSaverBlanking = defaultScreenSaverBlanking;
|
||||
ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
|
||||
#ifdef DPMSExtension
|
||||
DPMSStandbyTime = DEFAULT_SCREEN_SAVER_TIME;
|
||||
DPMSSuspendTime = DEFAULT_SCREEN_SAVER_TIME;
|
||||
DPMSOffTime = DEFAULT_SCREEN_SAVER_TIME;
|
||||
DPMSEnabled = TRUE;
|
||||
DPMSPowerLevel = 0;
|
||||
#endif
|
||||
InitBlockAndWakeupHandlers();
|
||||
/* Perform any operating system dependent initializations you'd like */
|
||||
OsInit();
|
||||
if (serverGeneration == 1) {
|
||||
CreateWellKnownSockets();
|
||||
for (i = 1; i < MAXCLIENTS; i++)
|
||||
clients[i] = NullClient;
|
||||
serverClient = malloc(sizeof(ClientRec));
|
||||
if (!serverClient)
|
||||
FatalError("couldn't create server client");
|
||||
InitClient(serverClient, 0, (pointer) NULL);
|
||||
}
|
||||
else
|
||||
ResetWellKnownSockets();
|
||||
clients[0] = serverClient;
|
||||
currentMaxClients = 1;
|
||||
|
||||
if (!InitClientResources(serverClient)) /* for root resources */
|
||||
FatalError("couldn't init server resources");
|
||||
|
||||
SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
|
||||
screenInfo.numScreens = 0;
|
||||
|
||||
InitAtoms();
|
||||
InitEvents();
|
||||
InitGlyphCaching();
|
||||
ResetExtensionPrivates();
|
||||
ResetClientPrivates();
|
||||
ResetScreenPrivates();
|
||||
ResetWindowPrivates();
|
||||
ResetGCPrivates();
|
||||
ResetPixmapPrivates();
|
||||
ResetColormapPrivates();
|
||||
ResetFontPrivateIndex();
|
||||
ResetDevicePrivateIndex();
|
||||
InitCallbackManager();
|
||||
InitVisualWrap();
|
||||
InitOutput(&screenInfo, argc, argv);
|
||||
|
||||
if (screenInfo.numScreens < 1)
|
||||
FatalError("no screens found");
|
||||
InitExtensions(argc, argv);
|
||||
if (!InitClientPrivates(serverClient))
|
||||
FatalError("failed to allocate serverClient devprivates");
|
||||
for (i = 0; i < screenInfo.numScreens; i++) {
|
||||
ScreenPtr pScreen = screenInfo.screens[i];
|
||||
|
||||
if (!CreateScratchPixmapsForScreen(i))
|
||||
FatalError("failed to create scratch pixmaps");
|
||||
if (pScreen->CreateScreenResources &&
|
||||
!(*pScreen->CreateScreenResources) (pScreen))
|
||||
FatalError("failed to create screen resources");
|
||||
if (!CreateGCperDepth(i))
|
||||
FatalError("failed to create scratch GCs");
|
||||
if (!CreateDefaultStipple(i))
|
||||
FatalError("failed to create default stipple");
|
||||
if (!CreateRootWindow(pScreen))
|
||||
FatalError("failed to create root window");
|
||||
}
|
||||
InitInput(argc, argv);
|
||||
if (InitAndStartDevices() != Success)
|
||||
FatalError("failed to initialize core devices");
|
||||
|
||||
InitFonts();
|
||||
if (SetDefaultFontPath(defaultFontPath) != Success)
|
||||
ErrorF("failed to set default font path '%s'", defaultFontPath);
|
||||
if (!SetDefaultFont(defaultTextFont))
|
||||
FatalError("could not open default font '%s'", defaultTextFont);
|
||||
if (!(rootCursor = CreateRootCursor(defaultCursorFont, 0)))
|
||||
FatalError("could not open default cursor font '%s'",
|
||||
defaultCursorFont);
|
||||
#ifdef DPMSExtension
|
||||
/* check all screens, looking for DPMS Capabilities */
|
||||
DPMSCapableFlag = DPMSSupported();
|
||||
if (!DPMSCapableFlag)
|
||||
DPMSEnabled = FALSE;
|
||||
#endif
|
||||
|
||||
|
||||
for (i = 0; i < screenInfo.numScreens; i++)
|
||||
InitRootWindow(WindowTable[i]);
|
||||
DefineInitialRootWindow(WindowTable[0]);
|
||||
SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
|
||||
|
||||
{
|
||||
if (!CreateConnectionBlock())
|
||||
FatalError("could not create connection block info");
|
||||
}
|
||||
|
||||
Dispatch();
|
||||
|
||||
/* Now free up whatever must be freed */
|
||||
if (screenIsSaved == SCREEN_SAVER_ON)
|
||||
SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
|
||||
FreeScreenSaverTimer();
|
||||
CloseDownExtensions();
|
||||
|
||||
FreeAllResources();
|
||||
|
||||
memset(WindowTable, 0, sizeof(WindowTable));
|
||||
CloseDownDevices();
|
||||
for (i = screenInfo.numScreens - 1; i >= 0; i--) {
|
||||
FreeScratchPixmapsForScreen(i);
|
||||
FreeGCperDepth(i);
|
||||
FreeDefaultStipple(i);
|
||||
(*screenInfo.screens[i]->CloseScreen) (i, screenInfo.screens[i]);
|
||||
FreeScreen(screenInfo.screens[i]);
|
||||
screenInfo.numScreens = i;
|
||||
}
|
||||
CloseDownEvents();
|
||||
FreeFonts();
|
||||
|
||||
free(serverClient->devPrivates);
|
||||
serverClient->devPrivates = NULL;
|
||||
|
||||
if (dispatchException & DE_TERMINATE) {
|
||||
CloseWellKnownConnections();
|
||||
}
|
||||
|
||||
OsCleanup((dispatchException & DE_TERMINATE) != 0);
|
||||
|
||||
if (dispatchException & DE_TERMINATE) {
|
||||
ddxGiveUp();
|
||||
break;
|
||||
}
|
||||
|
||||
free(ConnectionInfo);
|
||||
ConnectionInfo = NULL;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const int VendorRelease = VENDOR_RELEASE;
|
||||
static const char * const VendorString = VENDOR_STRING;
|
||||
|
||||
static const int padlength[4] = { 0, 3, 2, 1 };
|
||||
|
||||
static
|
||||
Bool
|
||||
CreateConnectionBlock()
|
||||
{
|
||||
xConnSetup setup;
|
||||
xWindowRoot root;
|
||||
xDepth depth;
|
||||
xVisualType visual;
|
||||
xPixmapFormat format;
|
||||
unsigned long vid;
|
||||
int i, j, k, lenofblock, sizesofar = 0;
|
||||
char *pBuf;
|
||||
|
||||
memset(&setup, 0, sizeof(xConnSetup));
|
||||
|
||||
/* Leave off the ridBase and ridMask, these must be sent with
|
||||
connection */
|
||||
|
||||
setup.release = VendorRelease;
|
||||
/*
|
||||
* per-server image and bitmap parameters are defined in Xmd.h
|
||||
*/
|
||||
setup.imageByteOrder = screenInfo.imageByteOrder;
|
||||
|
||||
setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
|
||||
setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
|
||||
|
||||
setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
|
||||
setup.motionBufferSize = NumMotionEvents();
|
||||
setup.numRoots = screenInfo.numScreens;
|
||||
setup.nbytesVendor = strlen(VendorString);
|
||||
setup.numFormats = screenInfo.numPixmapFormats;
|
||||
setup.maxRequestSize = MAX_REQUEST_SIZE;
|
||||
QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
|
||||
|
||||
lenofblock = sizeof(xConnSetup) +
|
||||
((setup.nbytesVendor + 3) & ~3) +
|
||||
(setup.numFormats * sizeof(xPixmapFormat)) +
|
||||
(setup.numRoots * sizeof(xWindowRoot));
|
||||
ConnectionInfo = malloc(lenofblock);
|
||||
if (!ConnectionInfo)
|
||||
return FALSE;
|
||||
|
||||
memmove(ConnectionInfo, (char *) &setup, sizeof(xConnSetup));
|
||||
sizesofar = sizeof(xConnSetup);
|
||||
pBuf = ConnectionInfo + sizeof(xConnSetup);
|
||||
|
||||
memmove(pBuf, VendorString, (int) setup.nbytesVendor);
|
||||
sizesofar += setup.nbytesVendor;
|
||||
pBuf += setup.nbytesVendor;
|
||||
i = padlength[setup.nbytesVendor & 3];
|
||||
sizesofar += i;
|
||||
while (--i >= 0)
|
||||
*pBuf++ = 0;
|
||||
|
||||
memset(&format, 0, sizeof(xPixmapFormat));
|
||||
for (i = 0; i < screenInfo.numPixmapFormats; i++) {
|
||||
format.depth = screenInfo.formats[i].depth;
|
||||
format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
|
||||
format.scanLinePad = screenInfo.formats[i].scanlinePad;
|
||||
memmove(pBuf, (char *) &format, sizeof(xPixmapFormat));
|
||||
pBuf += sizeof(xPixmapFormat);
|
||||
sizesofar += sizeof(xPixmapFormat);
|
||||
}
|
||||
|
||||
connBlockScreenStart = sizesofar;
|
||||
memset(&depth, 0, sizeof(xDepth));
|
||||
memset(&visual, 0, sizeof(xVisualType));
|
||||
for (i = 0; i < screenInfo.numScreens; i++) {
|
||||
ScreenPtr pScreen;
|
||||
DepthPtr pDepth;
|
||||
VisualPtr pVisual;
|
||||
|
||||
pScreen = screenInfo.screens[i];
|
||||
root.windowId = WindowTable[i]->drawable.id;
|
||||
root.defaultColormap = pScreen->defColormap;
|
||||
root.whitePixel = pScreen->whitePixel;
|
||||
root.blackPixel = pScreen->blackPixel;
|
||||
root.currentInputMask = 0; /* filled in when sent */
|
||||
root.pixWidth = pScreen->width;
|
||||
root.pixHeight = pScreen->height;
|
||||
root.mmWidth = pScreen->mmWidth;
|
||||
root.mmHeight = pScreen->mmHeight;
|
||||
root.minInstalledMaps = pScreen->minInstalledCmaps;
|
||||
root.maxInstalledMaps = pScreen->maxInstalledCmaps;
|
||||
root.rootVisualID = pScreen->rootVisual;
|
||||
root.backingStore = pScreen->backingStoreSupport;
|
||||
root.saveUnders = FALSE;
|
||||
root.rootDepth = pScreen->rootDepth;
|
||||
root.nDepths = pScreen->numDepths;
|
||||
memmove(pBuf, (char *) &root, sizeof(xWindowRoot));
|
||||
sizesofar += sizeof(xWindowRoot);
|
||||
pBuf += sizeof(xWindowRoot);
|
||||
|
||||
pDepth = pScreen->allowedDepths;
|
||||
for (j = 0; j < pScreen->numDepths; j++, pDepth++) {
|
||||
lenofblock += sizeof(xDepth) +
|
||||
(pDepth->numVids * sizeof(xVisualType));
|
||||
pBuf = (char *) realloc(ConnectionInfo, lenofblock);
|
||||
if (!pBuf) {
|
||||
free(ConnectionInfo);
|
||||
return FALSE;
|
||||
}
|
||||
ConnectionInfo = pBuf;
|
||||
pBuf += sizesofar;
|
||||
depth.depth = pDepth->depth;
|
||||
depth.nVisuals = pDepth->numVids;
|
||||
memmove(pBuf, (char *) &depth, sizeof(xDepth));
|
||||
pBuf += sizeof(xDepth);
|
||||
sizesofar += sizeof(xDepth);
|
||||
for (k = 0; k < pDepth->numVids; k++) {
|
||||
vid = pDepth->vids[k];
|
||||
for (pVisual = pScreen->visuals;
|
||||
pVisual->vid != vid; pVisual++);
|
||||
visual.visualID = vid;
|
||||
visual.class = pVisual->class;
|
||||
visual.bitsPerRGB = pVisual->bitsPerRGBValue;
|
||||
visual.colormapEntries = pVisual->ColormapEntries;
|
||||
visual.redMask = pVisual->redMask;
|
||||
visual.greenMask = pVisual->greenMask;
|
||||
visual.blueMask = pVisual->blueMask;
|
||||
memmove(pBuf, (char *) &visual, sizeof(xVisualType));
|
||||
pBuf += sizeof(xVisualType);
|
||||
sizesofar += sizeof(xVisualType);
|
||||
}
|
||||
}
|
||||
}
|
||||
connSetupPrefix.success = xTrue;
|
||||
connSetupPrefix.length = lenofblock / 4;
|
||||
connSetupPrefix.majorVersion = X_PROTOCOL;
|
||||
connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
grow the array of screenRecs if necessary.
|
||||
call the device-supplied initialization procedure
|
||||
with its screen number, a pointer to its ScreenRec, argc, and argv.
|
||||
return the number of successfully installed screens.
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
AddScreen(Bool (*pfnInit) (int /*index */ ,
|
||||
ScreenPtr /*pScreen */ ,
|
||||
int /*argc */ ,
|
||||
char ** /*argv */
|
||||
), int argc, char **argv)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
int scanlinepad, format, depth, bitsPerPixel, j, k;
|
||||
|
||||
ScreenPtr pScreen;
|
||||
|
||||
#ifdef DEBUG
|
||||
void (**jNI) ();
|
||||
#endif /* DEBUG */
|
||||
|
||||
i = screenInfo.numScreens;
|
||||
if (i == MAXSCREENS)
|
||||
return -1;
|
||||
|
||||
pScreen = calloc(1, sizeof(ScreenRec));
|
||||
if (!pScreen)
|
||||
return -1;
|
||||
|
||||
pScreen->devPrivates = calloc(sizeof(DevUnion),
|
||||
screenPrivateCount);
|
||||
if (!pScreen->devPrivates && screenPrivateCount) {
|
||||
free(pScreen);
|
||||
return -1;
|
||||
}
|
||||
pScreen->myNum = i;
|
||||
pScreen->WindowPrivateLen = 0;
|
||||
pScreen->WindowPrivateSizes = (unsigned *) NULL;
|
||||
pScreen->totalWindowSize =
|
||||
((sizeof(WindowRec) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
|
||||
pScreen->GCPrivateLen = 0;
|
||||
pScreen->GCPrivateSizes = (unsigned *) NULL;
|
||||
pScreen->totalGCSize =
|
||||
((sizeof(GC) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
|
||||
pScreen->PixmapPrivateLen = 0;
|
||||
pScreen->PixmapPrivateSizes = (unsigned *) NULL;
|
||||
pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec) * 8);
|
||||
pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
|
||||
pScreen->CreateScreenResources = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (jNI = &pScreen->QueryBestSize;
|
||||
jNI < (void (**)()) &pScreen->SendGraphicsExpose; jNI++)
|
||||
*jNI = NotImplemented;
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* This loop gets run once for every Screen that gets added,
|
||||
* but thats ok. If the ddx layer initializes the formats
|
||||
* one at a time calling AddScreen() after each, then each
|
||||
* iteration will make it a little more accurate. Worst case
|
||||
* we do this loop N * numPixmapFormats where N is # of screens.
|
||||
* Anyway, this must be called after InitOutput and before the
|
||||
* screen init routine is called.
|
||||
*/
|
||||
for (format = 0; format < screenInfo.numPixmapFormats; format++) {
|
||||
depth = screenInfo.formats[format].depth;
|
||||
bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
|
||||
scanlinepad = screenInfo.formats[format].scanlinePad;
|
||||
j = indexForBitsPerPixel[bitsPerPixel];
|
||||
k = indexForScanlinePad[scanlinepad];
|
||||
PixmapWidthPaddingInfo[depth].padPixelsLog2 = answer[j][k];
|
||||
PixmapWidthPaddingInfo[depth].padRoundUp =
|
||||
(scanlinepad / bitsPerPixel) - 1;
|
||||
j = indexForBitsPerPixel[8]; /* bits per byte */
|
||||
PixmapWidthPaddingInfo[depth].padBytesLog2 = answer[j][k];
|
||||
PixmapWidthPaddingInfo[depth].bitsPerPixel = bitsPerPixel;
|
||||
if (answerBytesPerPixel[bitsPerPixel]) {
|
||||
PixmapWidthPaddingInfo[depth].notPower2 = 1;
|
||||
PixmapWidthPaddingInfo[depth].bytesPerPixel =
|
||||
answerBytesPerPixel[bitsPerPixel];
|
||||
}
|
||||
else {
|
||||
PixmapWidthPaddingInfo[depth].notPower2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is where screen specific stuff gets initialized. Load the
|
||||
screen structure, call the hardware, whatever.
|
||||
This is also where the default colormap should be allocated and
|
||||
also pixel values for blackPixel, whitePixel, and the cursor
|
||||
Note that InitScreen is NOT allowed to modify argc, argv, or
|
||||
any of the strings pointed to by argv. They may be passed to
|
||||
multiple screens.
|
||||
*/
|
||||
pScreen->rgf = ~0L; /* there are no scratch GCs yet */
|
||||
WindowTable[i] = NullWindow;
|
||||
screenInfo.screens[i] = pScreen;
|
||||
screenInfo.numScreens++;
|
||||
if (!(*pfnInit) (i, pScreen, argc, argv)) {
|
||||
FreeScreen(pScreen);
|
||||
screenInfo.numScreens--;
|
||||
return -1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
FreeScreen(ScreenPtr pScreen)
|
||||
{
|
||||
free(pScreen->WindowPrivateSizes);
|
||||
free(pScreen->GCPrivateSizes);
|
||||
free(pScreen->PixmapPrivateSizes);
|
||||
free(pScreen->devPrivates);
|
||||
free(pScreen);
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
|
||||
Copyright 1993, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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 OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include "scrnintstr.h"
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "windowstr.h"
|
||||
#include "resource.h"
|
||||
#include "dixstruct.h"
|
||||
#include "gcstruct.h"
|
||||
#include "servermd.h"
|
||||
#include "site.h"
|
||||
|
||||
/*
|
||||
* Scratch pixmap management and device independent pixmap allocation
|
||||
* function.
|
||||
*/
|
||||
|
||||
/* callable by ddx */
|
||||
_X_EXPORT PixmapPtr
|
||||
GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth,
|
||||
int bitsPerPixel, int devKind, pointer pPixData)
|
||||
{
|
||||
PixmapPtr pPixmap = pScreen->pScratchPixmap;
|
||||
|
||||
if (pPixmap)
|
||||
pScreen->pScratchPixmap = NULL;
|
||||
else
|
||||
/* width and height of 0 means don't allocate any pixmap data */
|
||||
pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth);
|
||||
|
||||
if (pPixmap) {
|
||||
if ((*pScreen->ModifyPixmapHeader) (pPixmap, width, height, depth,
|
||||
bitsPerPixel, devKind, pPixData))
|
||||
return pPixmap;
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
}
|
||||
return NullPixmap;
|
||||
}
|
||||
|
||||
/* callable by ddx */
|
||||
_X_EXPORT void
|
||||
FreeScratchPixmapHeader(PixmapPtr pPixmap)
|
||||
{
|
||||
if (pPixmap) {
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
|
||||
pPixmap->devPrivate.ptr = NULL; /* lest ddx chases bad ptr */
|
||||
if (pScreen->pScratchPixmap)
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
else
|
||||
pScreen->pScratchPixmap = pPixmap;
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
CreateScratchPixmapsForScreen(int scrnum)
|
||||
{
|
||||
/* let it be created on first use */
|
||||
screenInfo.screens[scrnum]->pScratchPixmap = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
FreeScratchPixmapsForScreen(int scrnum)
|
||||
{
|
||||
FreeScratchPixmapHeader(screenInfo.screens[scrnum]->pScratchPixmap);
|
||||
}
|
||||
|
||||
/* callable by ddx */
|
||||
_X_EXPORT PixmapPtr
|
||||
AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
|
||||
{
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
char *ptr;
|
||||
|
||||
DevUnion *ppriv;
|
||||
|
||||
unsigned *sizes;
|
||||
|
||||
unsigned size;
|
||||
|
||||
int i;
|
||||
|
||||
if (pScreen->totalPixmapSize > ((size_t) - 1) - pixDataSize)
|
||||
return NullPixmap;
|
||||
|
||||
pPixmap = calloc(1, pScreen->totalPixmapSize + pixDataSize);
|
||||
if (!pPixmap)
|
||||
return NullPixmap;
|
||||
ppriv = (DevUnion *) (pPixmap + 1);
|
||||
pPixmap->devPrivates = ppriv;
|
||||
sizes = pScreen->PixmapPrivateSizes;
|
||||
ptr = (char *) (ppriv + pScreen->PixmapPrivateLen);
|
||||
for (i = pScreen->PixmapPrivateLen; --i >= 0; ppriv++, sizes++) {
|
||||
if ((size = *sizes) != 0) {
|
||||
ppriv->ptr = (pointer) ptr;
|
||||
ptr += size;
|
||||
}
|
||||
else
|
||||
ppriv->ptr = (pointer) NULL;
|
||||
}
|
||||
|
||||
#ifdef _XSERVER64
|
||||
if (pPixmap) {
|
||||
pPixmap->drawable.pad0 = 0;
|
||||
pPixmap->drawable.pad1 = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return pPixmap;
|
||||
}
|
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
|
||||
Copyright 1993, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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 OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include "scrnintstr.h"
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "windowstr.h"
|
||||
#include "resource.h"
|
||||
#include "dixstruct.h"
|
||||
#include "gcstruct.h"
|
||||
#include "colormapst.h"
|
||||
#include "servermd.h"
|
||||
#include "site.h"
|
||||
#include "inputstr.h"
|
||||
#include "extnsionst.h"
|
||||
|
||||
/*
|
||||
* See the Wrappers and devPrivates section in "Definition of the
|
||||
* Porting Layer for the X v11 Sample Server" (doc/Server/ddx.tbl.ms)
|
||||
* for information on how to use devPrivates.
|
||||
*/
|
||||
|
||||
/*
|
||||
* extension private machinery
|
||||
*/
|
||||
|
||||
static int extensionPrivateCount;
|
||||
|
||||
int extensionPrivateLen;
|
||||
|
||||
unsigned *extensionPrivateSizes;
|
||||
|
||||
unsigned totalExtensionSize;
|
||||
|
||||
void
|
||||
ResetExtensionPrivates()
|
||||
{
|
||||
extensionPrivateCount = 0;
|
||||
extensionPrivateLen = 0;
|
||||
free(extensionPrivateSizes);
|
||||
extensionPrivateSizes = (unsigned *) NULL;
|
||||
totalExtensionSize =
|
||||
((sizeof(ExtensionEntry) + sizeof(long) -
|
||||
1) / sizeof(long)) * sizeof(long);
|
||||
}
|
||||
|
||||
/*
|
||||
* client private machinery
|
||||
*/
|
||||
|
||||
static int clientPrivateCount;
|
||||
|
||||
int clientPrivateLen;
|
||||
|
||||
unsigned *clientPrivateSizes;
|
||||
|
||||
unsigned totalClientSize;
|
||||
|
||||
void
|
||||
ResetClientPrivates()
|
||||
{
|
||||
clientPrivateCount = 0;
|
||||
clientPrivateLen = 0;
|
||||
free(clientPrivateSizes);
|
||||
clientPrivateSizes = (unsigned *) NULL;
|
||||
totalClientSize =
|
||||
((sizeof(ClientRec) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
|
||||
}
|
||||
|
||||
_X_EXPORT int
|
||||
AllocateClientPrivateIndex()
|
||||
{
|
||||
return clientPrivateCount++;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
AllocateClientPrivate(int index2, unsigned amount)
|
||||
{
|
||||
unsigned oldamount;
|
||||
|
||||
/* Round up sizes for proper alignment */
|
||||
amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
|
||||
|
||||
if (index2 >= clientPrivateLen) {
|
||||
unsigned *nsizes;
|
||||
|
||||
nsizes = (unsigned *) realloc(clientPrivateSizes,
|
||||
(index2 + 1) * sizeof(unsigned));
|
||||
if (!nsizes)
|
||||
return FALSE;
|
||||
while (clientPrivateLen <= index2) {
|
||||
nsizes[clientPrivateLen++] = 0;
|
||||
totalClientSize += sizeof(DevUnion);
|
||||
}
|
||||
clientPrivateSizes = nsizes;
|
||||
}
|
||||
oldamount = clientPrivateSizes[index2];
|
||||
if (amount > oldamount) {
|
||||
clientPrivateSizes[index2] = amount;
|
||||
totalClientSize += (amount - oldamount);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* screen private machinery
|
||||
*/
|
||||
|
||||
int screenPrivateCount;
|
||||
|
||||
void
|
||||
ResetScreenPrivates()
|
||||
{
|
||||
screenPrivateCount = 0;
|
||||
}
|
||||
|
||||
/* this can be called after some screens have been created,
|
||||
* so we have to worry about resizing existing devPrivates
|
||||
*/
|
||||
_X_EXPORT int
|
||||
AllocateScreenPrivateIndex()
|
||||
{
|
||||
int idx;
|
||||
|
||||
int i;
|
||||
|
||||
ScreenPtr pScreen;
|
||||
|
||||
DevUnion *nprivs;
|
||||
|
||||
idx = screenPrivateCount++;
|
||||
for (i = 0; i < screenInfo.numScreens; i++) {
|
||||
pScreen = screenInfo.screens[i];
|
||||
nprivs = (DevUnion *) realloc(pScreen->devPrivates,
|
||||
screenPrivateCount * sizeof(DevUnion));
|
||||
if (!nprivs) {
|
||||
screenPrivateCount--;
|
||||
return -1;
|
||||
}
|
||||
/* Zero the new private */
|
||||
bzero(&nprivs[idx], sizeof(DevUnion));
|
||||
pScreen->devPrivates = nprivs;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* window private machinery
|
||||
*/
|
||||
|
||||
static int windowPrivateCount;
|
||||
|
||||
void
|
||||
ResetWindowPrivates()
|
||||
{
|
||||
windowPrivateCount = 0;
|
||||
}
|
||||
|
||||
_X_EXPORT int
|
||||
AllocateWindowPrivateIndex()
|
||||
{
|
||||
return windowPrivateCount++;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
AllocateWindowPrivate(register ScreenPtr pScreen, int index2, unsigned amount)
|
||||
{
|
||||
unsigned oldamount;
|
||||
|
||||
/* Round up sizes for proper alignment */
|
||||
amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
|
||||
|
||||
if (index2 >= pScreen->WindowPrivateLen) {
|
||||
unsigned *nsizes;
|
||||
|
||||
nsizes = (unsigned *) realloc(pScreen->WindowPrivateSizes,
|
||||
(index2 + 1) * sizeof(unsigned));
|
||||
if (!nsizes)
|
||||
return FALSE;
|
||||
while (pScreen->WindowPrivateLen <= index2) {
|
||||
nsizes[pScreen->WindowPrivateLen++] = 0;
|
||||
pScreen->totalWindowSize += sizeof(DevUnion);
|
||||
}
|
||||
pScreen->WindowPrivateSizes = nsizes;
|
||||
}
|
||||
oldamount = pScreen->WindowPrivateSizes[index2];
|
||||
if (amount > oldamount) {
|
||||
pScreen->WindowPrivateSizes[index2] = amount;
|
||||
pScreen->totalWindowSize += (amount - oldamount);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* gc private machinery
|
||||
*/
|
||||
|
||||
static int gcPrivateCount;
|
||||
|
||||
void
|
||||
ResetGCPrivates()
|
||||
{
|
||||
gcPrivateCount = 0;
|
||||
}
|
||||
|
||||
_X_EXPORT int
|
||||
AllocateGCPrivateIndex()
|
||||
{
|
||||
return gcPrivateCount++;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
AllocateGCPrivate(register ScreenPtr pScreen, int index2, unsigned amount)
|
||||
{
|
||||
unsigned oldamount;
|
||||
|
||||
/* Round up sizes for proper alignment */
|
||||
amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
|
||||
|
||||
if (index2 >= pScreen->GCPrivateLen) {
|
||||
unsigned *nsizes;
|
||||
|
||||
nsizes = (unsigned *) realloc(pScreen->GCPrivateSizes,
|
||||
(index2 + 1) * sizeof(unsigned));
|
||||
if (!nsizes)
|
||||
return FALSE;
|
||||
while (pScreen->GCPrivateLen <= index2) {
|
||||
nsizes[pScreen->GCPrivateLen++] = 0;
|
||||
pScreen->totalGCSize += sizeof(DevUnion);
|
||||
}
|
||||
pScreen->GCPrivateSizes = nsizes;
|
||||
}
|
||||
oldamount = pScreen->GCPrivateSizes[index2];
|
||||
if (amount > oldamount) {
|
||||
pScreen->GCPrivateSizes[index2] = amount;
|
||||
pScreen->totalGCSize += (amount - oldamount);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* pixmap private machinery
|
||||
*/
|
||||
static int pixmapPrivateCount;
|
||||
|
||||
void
|
||||
ResetPixmapPrivates()
|
||||
{
|
||||
pixmapPrivateCount = 0;
|
||||
}
|
||||
|
||||
_X_EXPORT int
|
||||
AllocatePixmapPrivateIndex()
|
||||
{
|
||||
return pixmapPrivateCount++;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
AllocatePixmapPrivate(register ScreenPtr pScreen, int index2, unsigned amount)
|
||||
{
|
||||
unsigned oldamount;
|
||||
|
||||
/* Round up sizes for proper alignment */
|
||||
amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
|
||||
|
||||
if (index2 >= pScreen->PixmapPrivateLen) {
|
||||
unsigned *nsizes;
|
||||
|
||||
nsizes = (unsigned *) realloc(pScreen->PixmapPrivateSizes,
|
||||
(index2 + 1) * sizeof(unsigned));
|
||||
if (!nsizes)
|
||||
return FALSE;
|
||||
while (pScreen->PixmapPrivateLen <= index2) {
|
||||
nsizes[pScreen->PixmapPrivateLen++] = 0;
|
||||
pScreen->totalPixmapSize += sizeof(DevUnion);
|
||||
}
|
||||
pScreen->PixmapPrivateSizes = nsizes;
|
||||
}
|
||||
oldamount = pScreen->PixmapPrivateSizes[index2];
|
||||
if (amount > oldamount) {
|
||||
pScreen->PixmapPrivateSizes[index2] = amount;
|
||||
pScreen->totalPixmapSize += (amount - oldamount);
|
||||
}
|
||||
pScreen->totalPixmapSize = BitmapBytePad(pScreen->totalPixmapSize * 8);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* colormap private machinery
|
||||
*/
|
||||
|
||||
int colormapPrivateCount;
|
||||
|
||||
void
|
||||
ResetColormapPrivates()
|
||||
{
|
||||
colormapPrivateCount = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* device private machinery
|
||||
*/
|
||||
|
||||
static int devicePrivateIndex = 0;
|
||||
|
||||
void
|
||||
ResetDevicePrivateIndex(void)
|
||||
{
|
||||
devicePrivateIndex = 0;
|
||||
}
|
|
@ -0,0 +1,610 @@
|
|||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "windowstr.h"
|
||||
#include "propertyst.h"
|
||||
#include "dixstruct.h"
|
||||
#include "dispatch.h"
|
||||
#include "swaprep.h"
|
||||
|
||||
/*****************************************************************
|
||||
* Property Stuff
|
||||
*
|
||||
* ChangeProperty, DeleteProperty, GetProperties,
|
||||
* ListProperties
|
||||
*
|
||||
* Properties below to windows. A allocate slots each time
|
||||
* a property is added. No fancy searching done.
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#ifdef notdef
|
||||
static void
|
||||
PrintPropertys(WindowPtr pWin)
|
||||
{
|
||||
PropertyPtr pProp;
|
||||
|
||||
int j;
|
||||
|
||||
pProp = pWin->userProps;
|
||||
while (pProp) {
|
||||
ErrorF("%x %x\n", pProp->propertyName, pProp->type);
|
||||
ErrorF("property format: %d\n", pProp->format);
|
||||
ErrorF("property data: \n");
|
||||
for (j = 0; j < (pProp->format / 8) * pProp->size; j++)
|
||||
ErrorF("%c\n", pProp->data[j]);
|
||||
pProp = pProp->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ProcRotateProperties(ClientPtr client)
|
||||
{
|
||||
int i, j, delta;
|
||||
|
||||
REQUEST(xRotatePropertiesReq);
|
||||
WindowPtr pWin;
|
||||
|
||||
Atom *atoms;
|
||||
|
||||
PropertyPtr *props; /* array of pointer */
|
||||
|
||||
PropertyPtr pProp;
|
||||
|
||||
xEvent event;
|
||||
|
||||
REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
|
||||
UpdateCurrentTime();
|
||||
pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
|
||||
SecurityWriteAccess);
|
||||
if (!pWin)
|
||||
return (BadWindow);
|
||||
if (!stuff->nAtoms)
|
||||
return (Success);
|
||||
atoms = (Atom *) &stuff[1];
|
||||
props = (PropertyPtr *) ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
|
||||
if (!props)
|
||||
return (BadAlloc);
|
||||
for (i = 0; i < stuff->nAtoms; i++) {
|
||||
if (!ValidAtom(atoms[i])
|
||||
) {
|
||||
DEALLOCATE_LOCAL(props);
|
||||
client->errorValue = atoms[i];
|
||||
return BadAtom;
|
||||
}
|
||||
for (j = i + 1; j < stuff->nAtoms; j++)
|
||||
if (atoms[j] == atoms[i]) {
|
||||
DEALLOCATE_LOCAL(props);
|
||||
return BadMatch;
|
||||
}
|
||||
pProp = wUserProps(pWin);
|
||||
while (pProp) {
|
||||
if (pProp->propertyName == atoms[i])
|
||||
goto found;
|
||||
pProp = pProp->next;
|
||||
}
|
||||
DEALLOCATE_LOCAL(props);
|
||||
return BadMatch;
|
||||
found:
|
||||
props[i] = pProp;
|
||||
}
|
||||
delta = stuff->nPositions;
|
||||
|
||||
/* If the rotation is a complete 360 degrees, then moving the properties
|
||||
around and generating PropertyNotify events should be skipped. */
|
||||
|
||||
if ((stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0) {
|
||||
while (delta < 0) /* faster if abs value is small */
|
||||
delta += stuff->nAtoms;
|
||||
for (i = 0; i < stuff->nAtoms; i++) {
|
||||
/* Generate a PropertyNotify event for each property whose value
|
||||
is changed in the order in which they appear in the request. */
|
||||
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyNewValue;
|
||||
event.u.property.atom = props[i]->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
|
||||
|
||||
props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
|
||||
}
|
||||
}
|
||||
DEALLOCATE_LOCAL(props);
|
||||
return Success;
|
||||
}
|
||||
|
||||
int
|
||||
ProcChangeProperty(ClientPtr client)
|
||||
{
|
||||
WindowPtr pWin;
|
||||
|
||||
char format, mode;
|
||||
|
||||
unsigned long len;
|
||||
|
||||
int sizeInBytes;
|
||||
|
||||
int totalSize;
|
||||
|
||||
int err;
|
||||
|
||||
REQUEST(xChangePropertyReq);
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
|
||||
UpdateCurrentTime();
|
||||
format = stuff->format;
|
||||
mode = stuff->mode;
|
||||
if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
|
||||
(mode != PropModePrepend)) {
|
||||
client->errorValue = mode;
|
||||
return BadValue;
|
||||
}
|
||||
if ((format != 8) && (format != 16) && (format != 32)) {
|
||||
client->errorValue = format;
|
||||
return BadValue;
|
||||
}
|
||||
len = stuff->nUnits;
|
||||
if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
|
||||
return BadLength;
|
||||
sizeInBytes = format >> 3;
|
||||
totalSize = len * sizeInBytes;
|
||||
REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
|
||||
|
||||
pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
|
||||
SecurityWriteAccess);
|
||||
if (!pWin)
|
||||
return (BadWindow);
|
||||
if (!ValidAtom(stuff->property)) {
|
||||
client->errorValue = stuff->property;
|
||||
return (BadAtom);
|
||||
}
|
||||
if (!ValidAtom(stuff->type)) {
|
||||
client->errorValue = stuff->type;
|
||||
return (BadAtom);
|
||||
}
|
||||
|
||||
|
||||
err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int) format,
|
||||
(int) mode, len, (pointer) &stuff[1], TRUE);
|
||||
if (err != Success)
|
||||
return err;
|
||||
else
|
||||
return client->noClientException;
|
||||
}
|
||||
|
||||
_X_EXPORT int
|
||||
ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
|
||||
int mode, unsigned long len, pointer value, Bool sendevent)
|
||||
{
|
||||
PropertyPtr pProp;
|
||||
|
||||
xEvent event;
|
||||
|
||||
int sizeInBytes;
|
||||
|
||||
int totalSize;
|
||||
|
||||
pointer data;
|
||||
|
||||
sizeInBytes = format >> 3;
|
||||
totalSize = len * sizeInBytes;
|
||||
|
||||
/* first see if property already exists */
|
||||
|
||||
pProp = wUserProps(pWin);
|
||||
while (pProp) {
|
||||
if (pProp->propertyName == property)
|
||||
break;
|
||||
pProp = pProp->next;
|
||||
}
|
||||
if (!pProp) { /* just add to list */
|
||||
if (!pWin->optional && !MakeWindowOptional(pWin))
|
||||
return (BadAlloc);
|
||||
pProp = malloc(sizeof(PropertyRec));
|
||||
if (!pProp)
|
||||
return (BadAlloc);
|
||||
data = malloc(totalSize);
|
||||
if (!data && len) {
|
||||
free(pProp);
|
||||
return (BadAlloc);
|
||||
}
|
||||
pProp->propertyName = property;
|
||||
pProp->type = type;
|
||||
pProp->format = format;
|
||||
pProp->data = data;
|
||||
if (len)
|
||||
memmove((char *) data, (char *) value, totalSize);
|
||||
pProp->size = len;
|
||||
pProp->next = pWin->optional->userProps;
|
||||
pWin->optional->userProps = pProp;
|
||||
}
|
||||
else {
|
||||
/* To append or prepend to a property the request format and type
|
||||
must match those of the already defined property. The
|
||||
existing format and type are irrelevant when using the mode
|
||||
"PropModeReplace" since they will be written over. */
|
||||
|
||||
if ((format != pProp->format) && (mode != PropModeReplace))
|
||||
return (BadMatch);
|
||||
if ((pProp->type != type) && (mode != PropModeReplace))
|
||||
return (BadMatch);
|
||||
if (mode == PropModeReplace) {
|
||||
if (totalSize != pProp->size * (pProp->format >> 3)) {
|
||||
data = (pointer) realloc(pProp->data, totalSize);
|
||||
if (!data && len)
|
||||
return (BadAlloc);
|
||||
pProp->data = data;
|
||||
}
|
||||
if (len)
|
||||
memmove((char *) pProp->data, (char *) value, totalSize);
|
||||
pProp->size = len;
|
||||
pProp->type = type;
|
||||
pProp->format = format;
|
||||
}
|
||||
else if (len == 0) {
|
||||
/* do nothing */
|
||||
}
|
||||
else if (mode == PropModeAppend) {
|
||||
data = (pointer) realloc(pProp->data,
|
||||
sizeInBytes * (len + pProp->size));
|
||||
if (!data)
|
||||
return (BadAlloc);
|
||||
pProp->data = data;
|
||||
memmove(&((char *) data)[pProp->size * sizeInBytes],
|
||||
(char *) value, totalSize);
|
||||
pProp->size += len;
|
||||
}
|
||||
else if (mode == PropModePrepend) {
|
||||
data = malloc(sizeInBytes * (len + pProp->size));
|
||||
if (!data)
|
||||
return (BadAlloc);
|
||||
memmove(&((char *) data)[totalSize], (char *) pProp->data,
|
||||
(int) (pProp->size * sizeInBytes));
|
||||
memmove((char *) data, (char *) value, totalSize);
|
||||
free(pProp->data);
|
||||
pProp->data = data;
|
||||
pProp->size += len;
|
||||
}
|
||||
}
|
||||
if (sendevent) {
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyNewValue;
|
||||
event.u.property.atom = pProp->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
|
||||
}
|
||||
return (Success);
|
||||
}
|
||||
|
||||
int
|
||||
DeleteProperty(WindowPtr pWin, Atom propName)
|
||||
{
|
||||
PropertyPtr pProp, prevProp;
|
||||
|
||||
xEvent event;
|
||||
|
||||
if (!(pProp = wUserProps(pWin)))
|
||||
return (Success);
|
||||
prevProp = (PropertyPtr) NULL;
|
||||
while (pProp) {
|
||||
if (pProp->propertyName == propName)
|
||||
break;
|
||||
prevProp = pProp;
|
||||
pProp = pProp->next;
|
||||
}
|
||||
if (pProp) {
|
||||
if (prevProp == (PropertyPtr) NULL) { /* takes care of head */
|
||||
if (!(pWin->optional->userProps = pProp->next))
|
||||
CheckWindowOptionalNeed(pWin);
|
||||
}
|
||||
else {
|
||||
prevProp->next = pProp->next;
|
||||
}
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyDelete;
|
||||
event.u.property.atom = pProp->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
|
||||
free(pProp->data);
|
||||
free(pProp);
|
||||
}
|
||||
return (Success);
|
||||
}
|
||||
|
||||
void
|
||||
DeleteAllWindowProperties(WindowPtr pWin)
|
||||
{
|
||||
PropertyPtr pProp, pNextProp;
|
||||
|
||||
xEvent event;
|
||||
|
||||
pProp = wUserProps(pWin);
|
||||
while (pProp) {
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyDelete;
|
||||
event.u.property.atom = pProp->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
|
||||
pNextProp = pProp->next;
|
||||
free(pProp->data);
|
||||
free(pProp);
|
||||
pProp = pNextProp;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NullPropertyReply(ClientPtr client,
|
||||
ATOM propertyType, int format, xGetPropertyReply * reply)
|
||||
{
|
||||
reply->nItems = 0;
|
||||
reply->length = 0;
|
||||
reply->bytesAfter = 0;
|
||||
reply->propertyType = propertyType;
|
||||
reply->format = format;
|
||||
WriteReplyToClient(client, sizeof(xGenericReply), reply);
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
/*****************
|
||||
* GetProperty
|
||||
* If type Any is specified, returns the property from the specified
|
||||
* window regardless of its type. If a type is specified, returns the
|
||||
* property only if its type equals the specified type.
|
||||
* If delete is True and a property is returned, the property is also
|
||||
* deleted from the window and a PropertyNotify event is generated on the
|
||||
* window.
|
||||
*****************/
|
||||
|
||||
int
|
||||
ProcGetProperty(ClientPtr client)
|
||||
{
|
||||
PropertyPtr pProp, prevProp;
|
||||
|
||||
unsigned long n, len, ind;
|
||||
|
||||
WindowPtr pWin;
|
||||
|
||||
xGetPropertyReply reply = {0};
|
||||
|
||||
REQUEST(xGetPropertyReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xGetPropertyReq);
|
||||
if (stuff->delete)
|
||||
UpdateCurrentTime();
|
||||
pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
|
||||
SecurityReadAccess);
|
||||
if (!pWin)
|
||||
return BadWindow;
|
||||
|
||||
if (!ValidAtom(stuff->property)) {
|
||||
client->errorValue = stuff->property;
|
||||
return (BadAtom);
|
||||
}
|
||||
if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) {
|
||||
client->errorValue = stuff->delete;
|
||||
return (BadValue);
|
||||
}
|
||||
if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) {
|
||||
client->errorValue = stuff->type;
|
||||
return (BadAtom);
|
||||
}
|
||||
|
||||
pProp = wUserProps(pWin);
|
||||
prevProp = (PropertyPtr) NULL;
|
||||
while (pProp) {
|
||||
if (pProp->propertyName == stuff->property)
|
||||
break;
|
||||
prevProp = pProp;
|
||||
pProp = pProp->next;
|
||||
}
|
||||
|
||||
reply.type = X_Reply;
|
||||
reply.sequenceNumber = client->sequence;
|
||||
if (!pProp)
|
||||
return NullPropertyReply(client, None, 0, &reply);
|
||||
|
||||
/* If the request type and actual type don't match. Return the
|
||||
property information, but not the data. */
|
||||
|
||||
if (((stuff->type != pProp->type) && (stuff->type != AnyPropertyType))
|
||||
) {
|
||||
reply.bytesAfter = pProp->size;
|
||||
reply.format = pProp->format;
|
||||
reply.length = 0;
|
||||
reply.nItems = 0;
|
||||
reply.propertyType = pProp->type;
|
||||
WriteReplyToClient(client, sizeof(xGenericReply), &reply);
|
||||
return (Success);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return type, format, value to client
|
||||
*/
|
||||
n = (pProp->format / 8) * pProp->size; /* size (bytes) of prop */
|
||||
ind = stuff->longOffset << 2;
|
||||
|
||||
/* If longOffset is invalid such that it causes "len" to
|
||||
be negative, it's a value error. */
|
||||
|
||||
if (n < ind) {
|
||||
client->errorValue = stuff->longOffset;
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
len = min(n - ind, 4 * stuff->longLength);
|
||||
|
||||
reply.bytesAfter = n - (ind + len);
|
||||
reply.format = pProp->format;
|
||||
reply.length = (len + 3) >> 2;
|
||||
reply.nItems = len / (pProp->format / 8);
|
||||
reply.propertyType = pProp->type;
|
||||
|
||||
if (stuff->delete && (reply.bytesAfter == 0)) { /* send the event */
|
||||
xEvent event;
|
||||
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyDelete;
|
||||
event.u.property.atom = pProp->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
|
||||
}
|
||||
|
||||
WriteReplyToClient(client, sizeof(xGenericReply), &reply);
|
||||
if (len) {
|
||||
switch (reply.format) {
|
||||
case 32:
|
||||
client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
|
||||
break;
|
||||
case 16:
|
||||
client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
|
||||
break;
|
||||
default:
|
||||
client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
|
||||
break;
|
||||
}
|
||||
WriteSwappedDataToClient(client, len, (char *) pProp->data + ind);
|
||||
}
|
||||
|
||||
if (stuff->delete && (reply.bytesAfter == 0)) { /* delete the Property */
|
||||
if (prevProp == (PropertyPtr) NULL) { /* takes care of head */
|
||||
if (!(pWin->optional->userProps = pProp->next))
|
||||
CheckWindowOptionalNeed(pWin);
|
||||
}
|
||||
else
|
||||
prevProp->next = pProp->next;
|
||||
free(pProp->data);
|
||||
free(pProp);
|
||||
}
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
int
|
||||
ProcListProperties(ClientPtr client)
|
||||
{
|
||||
Atom *pAtoms = NULL, *temppAtoms;
|
||||
|
||||
xListPropertiesReply xlpr;
|
||||
|
||||
int numProps = 0;
|
||||
|
||||
WindowPtr pWin;
|
||||
|
||||
PropertyPtr pProp;
|
||||
|
||||
REQUEST(xResourceReq);
|
||||
|
||||
REQUEST_SIZE_MATCH(xResourceReq);
|
||||
pWin = (WindowPtr) SecurityLookupWindow(stuff->id, client,
|
||||
SecurityReadAccess);
|
||||
if (!pWin)
|
||||
return (BadWindow);
|
||||
|
||||
pProp = wUserProps(pWin);
|
||||
while (pProp) {
|
||||
pProp = pProp->next;
|
||||
numProps++;
|
||||
}
|
||||
if (numProps)
|
||||
if (!(pAtoms = (Atom *) ALLOCATE_LOCAL(numProps * sizeof(Atom))))
|
||||
return (BadAlloc);
|
||||
|
||||
xlpr.type = X_Reply;
|
||||
xlpr.nProperties = numProps;
|
||||
xlpr.length = (numProps * sizeof(Atom)) >> 2;
|
||||
xlpr.sequenceNumber = client->sequence;
|
||||
pProp = wUserProps(pWin);
|
||||
temppAtoms = pAtoms;
|
||||
while (pProp) {
|
||||
*temppAtoms++ = pProp->propertyName;
|
||||
pProp = pProp->next;
|
||||
}
|
||||
WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
|
||||
if (numProps) {
|
||||
client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
|
||||
WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
|
||||
DEALLOCATE_LOCAL(pAtoms);
|
||||
}
|
||||
return (client->noClientException);
|
||||
}
|
||||
|
||||
int
|
||||
ProcDeleteProperty(register ClientPtr client)
|
||||
{
|
||||
WindowPtr pWin;
|
||||
|
||||
REQUEST(xDeletePropertyReq);
|
||||
int result;
|
||||
|
||||
REQUEST_SIZE_MATCH(xDeletePropertyReq);
|
||||
UpdateCurrentTime();
|
||||
pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
|
||||
SecurityWriteAccess);
|
||||
if (!pWin)
|
||||
return (BadWindow);
|
||||
if (!ValidAtom(stuff->property)) {
|
||||
client->errorValue = stuff->property;
|
||||
return (BadAtom);
|
||||
}
|
||||
|
||||
|
||||
result = DeleteProperty(pWin, stuff->property);
|
||||
if (client->noClientException != Success)
|
||||
return (client->noClientException);
|
||||
else
|
||||
return (result);
|
||||
}
|
|
@ -0,0 +1,844 @@
|
|||
/************************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
/* The panoramix components contained the following notice */
|
||||
/*****************************************************************
|
||||
|
||||
Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
|
||||
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
|
||||
|
||||
Except as contained in this notice, the name of Digital Equipment Corporation
|
||||
shall not be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Software without prior written authorization from Digital
|
||||
Equipment Corporation.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/* Routines to manage various kinds of resources:
|
||||
*
|
||||
* CreateNewResourceType, InitClientResources,
|
||||
* FakeClientID, AddResource, FreeResource, FreeClientResources,
|
||||
* FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
|
||||
*/
|
||||
|
||||
/*
|
||||
* A resource ID is a 32 bit quantity, the upper 2 bits of which are
|
||||
* off-limits for client-visible resources. The next 8 bits are
|
||||
* used as client ID, and the low 22 bits come from the client.
|
||||
* A resource ID is "hashed" by extracting and xoring subfields
|
||||
* (varying with the size of the hash table).
|
||||
*
|
||||
* It is sometimes necessary for the server to create an ID that looks
|
||||
* like it belongs to a client. This ID, however, must not be one
|
||||
* the client actually can create, or we have the potential for conflict.
|
||||
* The 31st bit of the ID is reserved for the server's use for this
|
||||
* purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to
|
||||
* 1, and an otherwise arbitrary ID in the low 22 bits, we can create a
|
||||
* resource "owned" by the client.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "resource.h"
|
||||
#include "dixstruct.h"
|
||||
#include "opaque.h"
|
||||
#include "windowstr.h"
|
||||
#include "dixfont.h"
|
||||
#include "colormap.h"
|
||||
#include "inputstr.h"
|
||||
#include "dixevents.h"
|
||||
#include "dixgrabs.h"
|
||||
#include "cursor.h"
|
||||
#include <assert.h>
|
||||
|
||||
static void RebuildTable(int /*client */
|
||||
);
|
||||
|
||||
#define SERVER_MINID 32
|
||||
|
||||
#define INITBUCKETS 64
|
||||
#define INITHASHSIZE 6
|
||||
#define MAXHASHSIZE 11
|
||||
|
||||
typedef struct _Resource {
|
||||
struct _Resource *next;
|
||||
XID id;
|
||||
RESTYPE type;
|
||||
pointer value;
|
||||
} ResourceRec, *ResourcePtr;
|
||||
|
||||
#define NullResource ((ResourcePtr)NULL)
|
||||
|
||||
typedef struct _ClientResource {
|
||||
ResourcePtr *resources;
|
||||
int elements;
|
||||
int buckets;
|
||||
int hashsize; /* log(2)(buckets) */
|
||||
XID fakeID;
|
||||
XID endFakeID;
|
||||
XID expectID;
|
||||
} ClientResourceRec;
|
||||
|
||||
_X_EXPORT RESTYPE lastResourceType;
|
||||
|
||||
static RESTYPE lastResourceClass;
|
||||
|
||||
_X_EXPORT RESTYPE TypeMask;
|
||||
|
||||
static DeleteType *DeleteFuncs = (DeleteType *) NULL;
|
||||
|
||||
#ifdef XResExtension
|
||||
|
||||
_X_EXPORT Atom *ResourceNames = NULL;
|
||||
|
||||
_X_EXPORT void
|
||||
RegisterResourceName(RESTYPE type, char *name)
|
||||
{
|
||||
ResourceNames[type & TypeMask] = MakeAtom(name, strlen(name), TRUE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
_X_EXPORT RESTYPE
|
||||
CreateNewResourceType(DeleteType deleteFunc)
|
||||
{
|
||||
RESTYPE next = lastResourceType + 1;
|
||||
|
||||
DeleteType *funcs;
|
||||
|
||||
if (next & lastResourceClass)
|
||||
return 0;
|
||||
funcs = (DeleteType *) realloc(DeleteFuncs,
|
||||
(next + 1) * sizeof(DeleteType));
|
||||
if (!funcs)
|
||||
return 0;
|
||||
|
||||
#ifdef XResExtension
|
||||
{
|
||||
Atom *newnames;
|
||||
|
||||
newnames = realloc(ResourceNames, (next + 1) * sizeof(Atom));
|
||||
if (!newnames)
|
||||
return 0;
|
||||
ResourceNames = newnames;
|
||||
ResourceNames[next] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
lastResourceType = next;
|
||||
DeleteFuncs = funcs;
|
||||
DeleteFuncs[next] = deleteFunc;
|
||||
return next;
|
||||
}
|
||||
|
||||
ClientResourceRec clientTable[MAXCLIENTS];
|
||||
|
||||
/*****************
|
||||
* InitClientResources
|
||||
* When a new client is created, call this to allocate space
|
||||
* in resource table
|
||||
*****************/
|
||||
|
||||
Bool
|
||||
InitClientResources(ClientPtr client)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (client == serverClient) {
|
||||
lastResourceType = RT_LASTPREDEF;
|
||||
lastResourceClass = RC_LASTPREDEF;
|
||||
TypeMask = RC_LASTPREDEF - 1;
|
||||
if (DeleteFuncs)
|
||||
free(DeleteFuncs);
|
||||
DeleteFuncs = malloc((lastResourceType + 1) *
|
||||
sizeof(DeleteType));
|
||||
if (!DeleteFuncs)
|
||||
return FALSE;
|
||||
DeleteFuncs[RT_NONE & TypeMask] = (DeleteType) NoopDDA;
|
||||
DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
|
||||
DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
|
||||
DeleteFuncs[RT_GC & TypeMask] = FreeGC;
|
||||
DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
|
||||
DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
|
||||
DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
|
||||
DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
|
||||
DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
|
||||
DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
|
||||
|
||||
#ifdef XResExtension
|
||||
if (ResourceNames)
|
||||
free(ResourceNames);
|
||||
ResourceNames = malloc((lastResourceType + 1) * sizeof(Atom));
|
||||
if (!ResourceNames)
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
clientTable[i = client->index].resources =
|
||||
malloc(INITBUCKETS * sizeof(ResourcePtr));
|
||||
if (!clientTable[i].resources)
|
||||
return FALSE;
|
||||
clientTable[i].buckets = INITBUCKETS;
|
||||
clientTable[i].elements = 0;
|
||||
clientTable[i].hashsize = INITHASHSIZE;
|
||||
/* Many IDs allocated from the server client are visible to clients,
|
||||
* so we don't use the SERVER_BIT for them, but we have to start
|
||||
* past the magic value constants used in the protocol. For normal
|
||||
* clients, we can start from zero, with SERVER_BIT set.
|
||||
*/
|
||||
clientTable[i].fakeID = client->clientAsMask |
|
||||
(client->index ? SERVER_BIT : SERVER_MINID);
|
||||
clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
|
||||
clientTable[i].expectID = client->clientAsMask;
|
||||
for (j = 0; j < INITBUCKETS; j++) {
|
||||
clientTable[i].resources[j] = NullResource;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
Hash(int client, register XID id)
|
||||
{
|
||||
id &= RESOURCE_ID_MASK;
|
||||
switch (clientTable[client].hashsize) {
|
||||
case 6:
|
||||
return ((int) (0x03F & (id ^ (id >> 6) ^ (id >> 12))));
|
||||
case 7:
|
||||
return ((int) (0x07F & (id ^ (id >> 7) ^ (id >> 13))));
|
||||
case 8:
|
||||
return ((int) (0x0FF & (id ^ (id >> 8) ^ (id >> 16))));
|
||||
case 9:
|
||||
return ((int) (0x1FF & (id ^ (id >> 9))));
|
||||
case 10:
|
||||
return ((int) (0x3FF & (id ^ (id >> 10))));
|
||||
case 11:
|
||||
return ((int) (0x7FF & (id ^ (id >> 11))));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static XID
|
||||
AvailableID(register int client,
|
||||
register XID id, register XID maxid, register XID goodid)
|
||||
{
|
||||
ResourcePtr res;
|
||||
|
||||
if ((goodid >= id) && (goodid <= maxid))
|
||||
return goodid;
|
||||
for (; id <= maxid; id++) {
|
||||
res = clientTable[client].resources[Hash(client, id)];
|
||||
while (res && (res->id != id))
|
||||
res = res->next;
|
||||
if (!res)
|
||||
return id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
|
||||
{
|
||||
XID id, maxid;
|
||||
|
||||
ResourcePtr *resp;
|
||||
|
||||
ResourcePtr res;
|
||||
|
||||
int i;
|
||||
|
||||
XID goodid;
|
||||
|
||||
id = (Mask) client << CLIENTOFFSET;
|
||||
if (server)
|
||||
id |= client ? SERVER_BIT : SERVER_MINID;
|
||||
maxid = id | RESOURCE_ID_MASK;
|
||||
goodid = 0;
|
||||
for (resp = clientTable[client].resources, i = clientTable[client].buckets;
|
||||
--i >= 0;) {
|
||||
for (res = *resp++; res; res = res->next) {
|
||||
if ((res->id < id) || (res->id > maxid))
|
||||
continue;
|
||||
if (((res->id - id) >= (maxid - res->id)) ?
|
||||
(goodid = AvailableID(client, id, res->id - 1, goodid)) :
|
||||
!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
|
||||
maxid = res->id - 1;
|
||||
else
|
||||
id = res->id + 1;
|
||||
}
|
||||
}
|
||||
if (id > maxid)
|
||||
id = maxid = 0;
|
||||
*minp = id;
|
||||
*maxp = maxid;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
|
||||
* This function tries to find count unused XIDs for the given client. It
|
||||
* puts the IDs in the array pids and returns the number found, which should
|
||||
* almost always be the number requested.
|
||||
*
|
||||
* The circumstances that lead to a call to this function are very rare.
|
||||
* Xlib must run out of IDs while trying to generate a request that wants
|
||||
* multiple ID's, like the Multi-buffering CreateImageBuffers request.
|
||||
*
|
||||
* No rocket science in the implementation; just iterate over all
|
||||
* possible IDs for the given client and pick the first count IDs
|
||||
* that aren't in use. A more efficient algorithm could probably be
|
||||
* invented, but this will be used so rarely that this should suffice.
|
||||
*/
|
||||
|
||||
_X_EXPORT unsigned int
|
||||
GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
|
||||
{
|
||||
unsigned int found = 0;
|
||||
|
||||
XID id = pClient->clientAsMask;
|
||||
|
||||
XID maxid;
|
||||
|
||||
maxid = id | RESOURCE_ID_MASK;
|
||||
while ((found < count) && (id <= maxid)) {
|
||||
if (!LookupIDByClass(id, RC_ANY)) {
|
||||
pids[found++] = id;
|
||||
}
|
||||
id++;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the next usable fake client ID.
|
||||
*
|
||||
* Normally this is just the next one in line, but if we've used the last
|
||||
* in the range, we need to find a new range of safe IDs to avoid
|
||||
* over-running another client.
|
||||
*/
|
||||
|
||||
_X_EXPORT XID
|
||||
FakeClientID(register int client)
|
||||
{
|
||||
XID id, maxid;
|
||||
|
||||
id = clientTable[client].fakeID++;
|
||||
if (id != clientTable[client].endFakeID)
|
||||
return id;
|
||||
GetXIDRange(client, TRUE, &id, &maxid);
|
||||
if (!id) {
|
||||
if (!client)
|
||||
FatalError("FakeClientID: server internal ids exhausted\n");
|
||||
MarkClientException(clients[client]);
|
||||
id = ((Mask) client << CLIENTOFFSET) | (SERVER_BIT * 3);
|
||||
maxid = id | RESOURCE_ID_MASK;
|
||||
}
|
||||
clientTable[client].fakeID = id + 1;
|
||||
clientTable[client].endFakeID = maxid + 1;
|
||||
return id;
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
AddResource(XID id, RESTYPE type, pointer value)
|
||||
{
|
||||
int client;
|
||||
|
||||
ClientResourceRec *rrec;
|
||||
|
||||
ResourcePtr res, *head;
|
||||
|
||||
client = CLIENT_ID(id);
|
||||
rrec = &clientTable[client];
|
||||
if (!rrec->buckets) {
|
||||
ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
|
||||
(unsigned long) id, type, (unsigned long) value, client);
|
||||
FatalError("client not in use\n");
|
||||
}
|
||||
if ((rrec->elements >= 4 * rrec->buckets) && (rrec->hashsize < MAXHASHSIZE))
|
||||
RebuildTable(client);
|
||||
head = &rrec->resources[Hash(client, id)];
|
||||
res = malloc(sizeof(ResourceRec));
|
||||
if (!res) {
|
||||
(*DeleteFuncs[type & TypeMask]) (value, id);
|
||||
return FALSE;
|
||||
}
|
||||
res->next = *head;
|
||||
res->id = id;
|
||||
res->type = type;
|
||||
res->value = value;
|
||||
*head = res;
|
||||
rrec->elements++;
|
||||
if (!(id & SERVER_BIT) && (id >= rrec->expectID))
|
||||
rrec->expectID = id + 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
RebuildTable(int client)
|
||||
{
|
||||
int j;
|
||||
|
||||
ResourcePtr res, next;
|
||||
|
||||
ResourcePtr **tails, *resources;
|
||||
|
||||
ResourcePtr **tptr, *rptr;
|
||||
|
||||
/*
|
||||
* For now, preserve insertion order, since some ddx layers depend
|
||||
* on resources being free in the opposite order they are added.
|
||||
*/
|
||||
|
||||
j = 2 * clientTable[client].buckets;
|
||||
tails = (ResourcePtr **) ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
|
||||
if (!tails)
|
||||
return;
|
||||
resources = malloc(j * sizeof(ResourcePtr));
|
||||
if (!resources) {
|
||||
DEALLOCATE_LOCAL(tails);
|
||||
return;
|
||||
}
|
||||
for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++) {
|
||||
*rptr = NullResource;
|
||||
*tptr = rptr;
|
||||
}
|
||||
clientTable[client].hashsize++;
|
||||
for (j = clientTable[client].buckets,
|
||||
rptr = clientTable[client].resources; --j >= 0; rptr++) {
|
||||
for (res = *rptr; res; res = next) {
|
||||
next = res->next;
|
||||
res->next = NullResource;
|
||||
tptr = &tails[Hash(client, res->id)];
|
||||
**tptr = res;
|
||||
*tptr = &res->next;
|
||||
}
|
||||
}
|
||||
DEALLOCATE_LOCAL(tails);
|
||||
clientTable[client].buckets *= 2;
|
||||
free(clientTable[client].resources);
|
||||
clientTable[client].resources = resources;
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
FreeResource(XID id, RESTYPE skipDeleteFuncType)
|
||||
{
|
||||
int cid;
|
||||
|
||||
ResourcePtr res;
|
||||
|
||||
ResourcePtr *prev, *head;
|
||||
|
||||
int *eltptr;
|
||||
|
||||
int elements;
|
||||
|
||||
Bool gotOne = FALSE;
|
||||
|
||||
if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) {
|
||||
head = &clientTable[cid].resources[Hash(cid, id)];
|
||||
eltptr = &clientTable[cid].elements;
|
||||
|
||||
prev = head;
|
||||
while ((res = *prev)) {
|
||||
if (res->id == id) {
|
||||
RESTYPE rtype = res->type;
|
||||
|
||||
*prev = res->next;
|
||||
elements = --*eltptr;
|
||||
if (rtype & RC_CACHED)
|
||||
FlushClientCaches(res->id);
|
||||
if (rtype != skipDeleteFuncType)
|
||||
(*DeleteFuncs[rtype & TypeMask]) (res->value, res->id);
|
||||
free(res);
|
||||
if (*eltptr != elements)
|
||||
prev = head; /* prev may no longer be valid */
|
||||
gotOne = TRUE;
|
||||
}
|
||||
else
|
||||
prev = &res->next;
|
||||
}
|
||||
if (clients[cid] && (id == clients[cid]->lastDrawableID)) {
|
||||
clients[cid]->lastDrawable = (DrawablePtr) WindowTable[0];
|
||||
clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
|
||||
}
|
||||
}
|
||||
if (!gotOne)
|
||||
ErrorF("Freeing resource id=%lX which isn't there.\n",
|
||||
(unsigned long) id);
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
|
||||
{
|
||||
int cid;
|
||||
|
||||
ResourcePtr res;
|
||||
|
||||
ResourcePtr *prev, *head;
|
||||
|
||||
if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) {
|
||||
head = &clientTable[cid].resources[Hash(cid, id)];
|
||||
|
||||
prev = head;
|
||||
while ((res = *prev)) {
|
||||
if (res->id == id && res->type == type) {
|
||||
*prev = res->next;
|
||||
if (type & RC_CACHED)
|
||||
FlushClientCaches(res->id);
|
||||
if (!skipFree)
|
||||
(*DeleteFuncs[type & TypeMask]) (res->value, res->id);
|
||||
free(res);
|
||||
break;
|
||||
}
|
||||
else
|
||||
prev = &res->next;
|
||||
}
|
||||
if (clients[cid] && (id == clients[cid]->lastDrawableID)) {
|
||||
clients[cid]->lastDrawable = (DrawablePtr) WindowTable[0];
|
||||
clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the value associated with a resource id. Caller
|
||||
* is responsible for "doing the right thing" with the old
|
||||
* data
|
||||
*/
|
||||
|
||||
_X_EXPORT Bool
|
||||
ChangeResourceValue(XID id, RESTYPE rtype, pointer value)
|
||||
{
|
||||
int cid;
|
||||
|
||||
ResourcePtr res;
|
||||
|
||||
if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) {
|
||||
res = clientTable[cid].resources[Hash(cid, id)];
|
||||
|
||||
for (; res; res = res->next)
|
||||
if ((res->id == id) && (res->type == rtype)) {
|
||||
if (rtype & RC_CACHED)
|
||||
FlushClientCaches(res->id);
|
||||
res->value = value;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Note: if func adds or deletes resources, then func can get called
|
||||
* more than once for some resources. If func adds new resources,
|
||||
* func might or might not get called for them. func cannot both
|
||||
* add and delete an equal number of resources!
|
||||
*/
|
||||
|
||||
_X_EXPORT void
|
||||
FindClientResourcesByType(ClientPtr client,
|
||||
RESTYPE type, FindResType func, pointer cdata)
|
||||
{
|
||||
ResourcePtr *resources;
|
||||
|
||||
ResourcePtr this, next;
|
||||
|
||||
int i, elements;
|
||||
|
||||
int *eltptr;
|
||||
|
||||
if (!client)
|
||||
client = serverClient;
|
||||
|
||||
resources = clientTable[client->index].resources;
|
||||
eltptr = &clientTable[client->index].elements;
|
||||
for (i = 0; i < clientTable[client->index].buckets; i++) {
|
||||
for (this = resources[i]; this; this = next) {
|
||||
next = this->next;
|
||||
if (!type || this->type == type) {
|
||||
elements = *eltptr;
|
||||
(*func) (this->value, this->id, cdata);
|
||||
if (*eltptr != elements)
|
||||
next = resources[i]; /* start over */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
FindAllClientResources(ClientPtr client, FindAllRes func, pointer cdata)
|
||||
{
|
||||
ResourcePtr *resources;
|
||||
|
||||
ResourcePtr this, next;
|
||||
|
||||
int i, elements;
|
||||
|
||||
int *eltptr;
|
||||
|
||||
if (!client)
|
||||
client = serverClient;
|
||||
|
||||
resources = clientTable[client->index].resources;
|
||||
eltptr = &clientTable[client->index].elements;
|
||||
for (i = 0; i < clientTable[client->index].buckets; i++) {
|
||||
for (this = resources[i]; this; this = next) {
|
||||
next = this->next;
|
||||
elements = *eltptr;
|
||||
(*func) (this->value, this->id, this->type, cdata);
|
||||
if (*eltptr != elements)
|
||||
next = resources[i]; /* start over */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pointer
|
||||
LookupClientResourceComplex(ClientPtr client,
|
||||
RESTYPE type,
|
||||
FindComplexResType func, pointer cdata)
|
||||
{
|
||||
ResourcePtr *resources;
|
||||
|
||||
ResourcePtr this;
|
||||
|
||||
int i;
|
||||
|
||||
if (!client)
|
||||
client = serverClient;
|
||||
|
||||
resources = clientTable[client->index].resources;
|
||||
for (i = 0; i < clientTable[client->index].buckets; i++) {
|
||||
for (this = resources[i]; this; this = this->next) {
|
||||
if (!type || this->type == type) {
|
||||
if ((*func) (this->value, this->id, cdata))
|
||||
return this->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
FreeClientNeverRetainResources(ClientPtr client)
|
||||
{
|
||||
ResourcePtr *resources;
|
||||
|
||||
ResourcePtr this;
|
||||
|
||||
ResourcePtr *prev;
|
||||
|
||||
int j;
|
||||
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
resources = clientTable[client->index].resources;
|
||||
for (j = 0; j < clientTable[client->index].buckets; j++) {
|
||||
prev = &resources[j];
|
||||
while ((this = *prev)) {
|
||||
RESTYPE rtype = this->type;
|
||||
|
||||
if (rtype & RC_NEVERRETAIN) {
|
||||
*prev = this->next;
|
||||
if (rtype & RC_CACHED)
|
||||
FlushClientCaches(this->id);
|
||||
(*DeleteFuncs[rtype & TypeMask]) (this->value, this->id);
|
||||
free(this);
|
||||
}
|
||||
else
|
||||
prev = &this->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FreeClientResources(ClientPtr client)
|
||||
{
|
||||
ResourcePtr *resources;
|
||||
|
||||
ResourcePtr this;
|
||||
|
||||
int j;
|
||||
|
||||
/* This routine shouldn't be called with a null client, but just in
|
||||
case ... */
|
||||
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
HandleSaveSet(client);
|
||||
|
||||
resources = clientTable[client->index].resources;
|
||||
for (j = 0; j < clientTable[client->index].buckets; j++) {
|
||||
/* It may seem silly to update the head of this resource list as
|
||||
we delete the members, since the entire list will be deleted any way,
|
||||
but there are some resource deletion functions "FreeClientPixels" for
|
||||
one which do a LookupID on another resource id (a Colormap id in this
|
||||
case), so the resource list must be kept valid up to the point that
|
||||
it is deleted, so every time we delete a resource, we must update the
|
||||
head, just like in FreeResource. I hope that this doesn't slow down
|
||||
mass deletion appreciably. PRH */
|
||||
|
||||
ResourcePtr *head;
|
||||
|
||||
head = &resources[j];
|
||||
|
||||
for (this = *head; this; this = *head) {
|
||||
RESTYPE rtype = this->type;
|
||||
|
||||
*head = this->next;
|
||||
if (rtype & RC_CACHED)
|
||||
FlushClientCaches(this->id);
|
||||
(*DeleteFuncs[rtype & TypeMask]) (this->value, this->id);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
free(clientTable[client->index].resources);
|
||||
clientTable[client->index].resources = NULL;
|
||||
clientTable[client->index].buckets = 0;
|
||||
}
|
||||
|
||||
void
|
||||
FreeAllResources()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = currentMaxClients; --i >= 0;) {
|
||||
if (clientTable[i].buckets)
|
||||
FreeClientResources(clients[i]);
|
||||
}
|
||||
}
|
||||
|
||||
_X_EXPORT Bool
|
||||
LegalNewID(XID id, register ClientPtr client)
|
||||
{
|
||||
|
||||
return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
|
||||
((clientTable[client->index].expectID <= id) ||
|
||||
!LookupIDByClass(id, RC_ANY)));
|
||||
}
|
||||
|
||||
/* SecurityLookupIDByType and SecurityLookupIDByClass:
|
||||
* These are the heart of the resource ID security system. They take
|
||||
* two additional arguments compared to the old LookupID functions:
|
||||
* the client doing the lookup, and the access mode (see resource.h).
|
||||
* The resource is returned if it exists and the client is allowed access,
|
||||
* else NULL is returned.
|
||||
*/
|
||||
|
||||
_X_EXPORT pointer
|
||||
SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
|
||||
{
|
||||
int cid;
|
||||
|
||||
ResourcePtr res;
|
||||
|
||||
pointer retval = NULL;
|
||||
|
||||
if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) {
|
||||
res = clientTable[cid].resources[Hash(cid, id)];
|
||||
|
||||
for (; res; res = res->next)
|
||||
if ((res->id == id) && (res->type == rtype)) {
|
||||
retval = res->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
_X_EXPORT pointer
|
||||
SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
|
||||
{
|
||||
int cid;
|
||||
|
||||
ResourcePtr res = NULL;
|
||||
|
||||
pointer retval = NULL;
|
||||
|
||||
if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) {
|
||||
res = clientTable[cid].resources[Hash(cid, id)];
|
||||
|
||||
for (; res; res = res->next)
|
||||
if ((res->id == id) && (res->type & classes)) {
|
||||
retval = res->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* We can't replace the LookupIDByType and LookupIDByClass functions with
|
||||
* macros because of compatibility with loadable servers.
|
||||
*/
|
||||
|
||||
_X_EXPORT pointer
|
||||
LookupIDByType(XID id, RESTYPE rtype)
|
||||
{
|
||||
return SecurityLookupIDByType(NullClient, id, rtype, SecurityUnknownAccess);
|
||||
}
|
||||
|
||||
_X_EXPORT pointer
|
||||
LookupIDByClass(XID id, RESTYPE classes)
|
||||
{
|
||||
return SecurityLookupIDByClass(NullClient, id, classes,
|
||||
SecurityUnknownAccess);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/************************************************************
|
||||
Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright
|
||||
notice and this permission notice appear in supporting
|
||||
documentation, and that the name of Silicon Graphics not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific prior written permission.
|
||||
Silicon Graphics makes no representation about the suitability
|
||||
of this software for any purpose. It is provided "as is"
|
||||
without any express or implied warranty.
|
||||
|
||||
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
||||
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include "dix.h"
|
||||
|
||||
#ifdef NEED_STRCASECMP
|
||||
int
|
||||
xstrcasecmp(char *str1, char *str2)
|
||||
{
|
||||
const u_char *us1 = (const u_char *) str1, *us2 = (const u_char *) str2;
|
||||
|
||||
while (tolower(*us1) == tolower(*us2)) {
|
||||
if (*us1++ == '\0')
|
||||
return (0);
|
||||
us2++;
|
||||
}
|
||||
|
||||
return (tolower(*us1) - tolower(*us2));
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,985 @@
|
|||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
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
|
||||
OPEN GROUP 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.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "windowstr.h"
|
||||
#include "extnsionst.h"
|
||||
#include "dixstruct.h"
|
||||
#include "dixevents.h"
|
||||
#include "dispatch.h"
|
||||
#include "swaprep.h"
|
||||
#include "swapreq.h"
|
||||
|
||||
int (* InitialVector[3]) (
|
||||
ClientPtr /* client */
|
||||
) =
|
||||
{
|
||||
0,
|
||||
ProcInitialConnection,
|
||||
ProcEstablishConnection
|
||||
};
|
||||
|
||||
int (* ProcVector[256]) (
|
||||
ClientPtr /* client */
|
||||
) =
|
||||
{
|
||||
ProcBadRequest,
|
||||
ProcCreateWindow,
|
||||
ProcChangeWindowAttributes,
|
||||
ProcGetWindowAttributes,
|
||||
ProcDestroyWindow,
|
||||
ProcDestroySubwindows, /* 5 */
|
||||
ProcChangeSaveSet,
|
||||
ProcReparentWindow,
|
||||
ProcMapWindow,
|
||||
ProcMapSubwindows,
|
||||
ProcUnmapWindow, /* 10 */
|
||||
ProcUnmapSubwindows,
|
||||
ProcConfigureWindow,
|
||||
ProcCirculateWindow,
|
||||
ProcGetGeometry,
|
||||
ProcQueryTree, /* 15 */
|
||||
ProcInternAtom,
|
||||
ProcGetAtomName,
|
||||
ProcChangeProperty,
|
||||
ProcDeleteProperty,
|
||||
ProcGetProperty, /* 20 */
|
||||
ProcListProperties,
|
||||
ProcSetSelectionOwner,
|
||||
ProcGetSelectionOwner,
|
||||
ProcConvertSelection,
|
||||
ProcSendEvent, /* 25 */
|
||||
ProcGrabPointer,
|
||||
ProcUngrabPointer,
|
||||
ProcGrabButton,
|
||||
ProcUngrabButton,
|
||||
ProcChangeActivePointerGrab, /* 30 */
|
||||
ProcGrabKeyboard,
|
||||
ProcUngrabKeyboard,
|
||||
ProcGrabKey,
|
||||
ProcUngrabKey,
|
||||
ProcAllowEvents, /* 35 */
|
||||
ProcGrabServer,
|
||||
ProcUngrabServer,
|
||||
ProcQueryPointer,
|
||||
ProcGetMotionEvents,
|
||||
ProcTranslateCoords, /* 40 */
|
||||
ProcWarpPointer,
|
||||
ProcSetInputFocus,
|
||||
ProcGetInputFocus,
|
||||
ProcQueryKeymap,
|
||||
ProcOpenFont, /* 45 */
|
||||
ProcCloseFont,
|
||||
ProcQueryFont,
|
||||
ProcQueryTextExtents,
|
||||
ProcListFonts,
|
||||
ProcListFontsWithInfo, /* 50 */
|
||||
ProcSetFontPath,
|
||||
ProcGetFontPath,
|
||||
ProcCreatePixmap,
|
||||
ProcFreePixmap,
|
||||
ProcCreateGC, /* 55 */
|
||||
ProcChangeGC,
|
||||
ProcCopyGC,
|
||||
ProcSetDashes,
|
||||
ProcSetClipRectangles,
|
||||
ProcFreeGC, /* 60 */
|
||||
ProcClearToBackground,
|
||||
ProcCopyArea,
|
||||
ProcCopyPlane,
|
||||
ProcPolyPoint,
|
||||
ProcPolyLine, /* 65 */
|
||||
ProcPolySegment,
|
||||
ProcPolyRectangle,
|
||||
ProcPolyArc,
|
||||
ProcFillPoly,
|
||||
ProcPolyFillRectangle, /* 70 */
|
||||
ProcPolyFillArc,
|
||||
ProcPutImage,
|
||||
ProcGetImage,
|
||||
ProcPolyText,
|
||||
ProcPolyText, /* 75 */
|
||||
ProcImageText8,
|
||||
ProcImageText16,
|
||||
ProcCreateColormap,
|
||||
ProcFreeColormap,
|
||||
ProcCopyColormapAndFree, /* 80 */
|
||||
ProcInstallColormap,
|
||||
ProcUninstallColormap,
|
||||
ProcListInstalledColormaps,
|
||||
ProcAllocColor,
|
||||
ProcAllocNamedColor, /* 85 */
|
||||
ProcAllocColorCells,
|
||||
ProcAllocColorPlanes,
|
||||
ProcFreeColors,
|
||||
ProcStoreColors,
|
||||
ProcStoreNamedColor, /* 90 */
|
||||
ProcQueryColors,
|
||||
ProcLookupColor,
|
||||
ProcCreateCursor,
|
||||
ProcCreateGlyphCursor,
|
||||
ProcFreeCursor, /* 95 */
|
||||
ProcRecolorCursor,
|
||||
ProcQueryBestSize,
|
||||
ProcQueryExtension,
|
||||
ProcListExtensions,
|
||||
ProcChangeKeyboardMapping, /* 100 */
|
||||
ProcGetKeyboardMapping,
|
||||
ProcChangeKeyboardControl,
|
||||
ProcGetKeyboardControl,
|
||||
ProcBell,
|
||||
ProcChangePointerControl, /* 105 */
|
||||
ProcGetPointerControl,
|
||||
ProcSetScreenSaver,
|
||||
ProcGetScreenSaver,
|
||||
ProcChangeHosts,
|
||||
ProcListHosts, /* 110 */
|
||||
ProcChangeAccessControl,
|
||||
ProcChangeCloseDownMode,
|
||||
ProcKillClient,
|
||||
ProcRotateProperties,
|
||||
ProcForceScreenSaver, /* 115 */
|
||||
ProcSetPointerMapping,
|
||||
ProcGetPointerMapping,
|
||||
ProcSetModifierMapping,
|
||||
ProcGetModifierMapping,
|
||||
ProcBadRequest, /* 120 */
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest, /* 125 */
|
||||
ProcBadRequest,
|
||||
ProcNoOperation,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest
|
||||
};
|
||||
|
||||
int (* SwappedProcVector[256]) (
|
||||
ClientPtr /* client */
|
||||
) =
|
||||
{
|
||||
ProcBadRequest,
|
||||
SProcCreateWindow,
|
||||
SProcChangeWindowAttributes,
|
||||
SProcResourceReq, /* GetWindowAttributes */
|
||||
SProcResourceReq, /* DestroyWindow */
|
||||
SProcResourceReq, /* 5 DestroySubwindows */
|
||||
SProcResourceReq, /* SProcChangeSaveSet, */
|
||||
SProcReparentWindow,
|
||||
SProcResourceReq, /* MapWindow */
|
||||
SProcResourceReq, /* MapSubwindows */
|
||||
SProcResourceReq, /* 10 UnmapWindow */
|
||||
SProcResourceReq, /* UnmapSubwindows */
|
||||
SProcConfigureWindow,
|
||||
SProcResourceReq, /* SProcCirculateWindow, */
|
||||
SProcResourceReq, /* GetGeometry */
|
||||
SProcResourceReq, /* 15 QueryTree */
|
||||
SProcInternAtom,
|
||||
SProcResourceReq, /* SProcGetAtomName, */
|
||||
SProcChangeProperty,
|
||||
SProcDeleteProperty,
|
||||
SProcGetProperty, /* 20 */
|
||||
SProcResourceReq, /* SProcListProperties, */
|
||||
SProcSetSelectionOwner,
|
||||
SProcResourceReq, /* SProcGetSelectionOwner, */
|
||||
SProcConvertSelection,
|
||||
SProcSendEvent, /* 25 */
|
||||
SProcGrabPointer,
|
||||
SProcResourceReq, /* SProcUngrabPointer, */
|
||||
SProcGrabButton,
|
||||
SProcUngrabButton,
|
||||
SProcChangeActivePointerGrab, /* 30 */
|
||||
SProcGrabKeyboard,
|
||||
SProcResourceReq, /* SProcUngrabKeyboard, */
|
||||
SProcGrabKey,
|
||||
SProcUngrabKey,
|
||||
SProcResourceReq, /* 35 SProcAllowEvents, */
|
||||
SProcSimpleReq, /* SProcGrabServer, */
|
||||
SProcSimpleReq, /* SProcUngrabServer, */
|
||||
SProcResourceReq, /* SProcQueryPointer, */
|
||||
SProcGetMotionEvents,
|
||||
SProcTranslateCoords, /*40 */
|
||||
SProcWarpPointer,
|
||||
SProcSetInputFocus,
|
||||
SProcSimpleReq, /* SProcGetInputFocus, */
|
||||
SProcSimpleReq, /* QueryKeymap, */
|
||||
SProcOpenFont, /* 45 */
|
||||
SProcResourceReq, /* SProcCloseFont, */
|
||||
SProcResourceReq, /* SProcQueryFont, */
|
||||
SProcResourceReq, /* SProcQueryTextExtents, */
|
||||
SProcListFonts,
|
||||
SProcListFontsWithInfo, /* 50 */
|
||||
SProcSetFontPath,
|
||||
SProcSimpleReq, /* GetFontPath, */
|
||||
SProcCreatePixmap,
|
||||
SProcResourceReq, /* SProcFreePixmap, */
|
||||
SProcCreateGC, /* 55 */
|
||||
SProcChangeGC,
|
||||
SProcCopyGC,
|
||||
SProcSetDashes,
|
||||
SProcSetClipRectangles,
|
||||
SProcResourceReq, /* 60 SProcFreeGC, */
|
||||
SProcClearToBackground,
|
||||
SProcCopyArea,
|
||||
SProcCopyPlane,
|
||||
SProcPoly, /* PolyPoint, */
|
||||
SProcPoly, /* 65 PolyLine */
|
||||
SProcPoly, /* PolySegment, */
|
||||
SProcPoly, /* PolyRectangle, */
|
||||
SProcPoly, /* PolyArc, */
|
||||
SProcFillPoly,
|
||||
SProcPoly, /* 70 PolyFillRectangle */
|
||||
SProcPoly, /* PolyFillArc, */
|
||||
SProcPutImage,
|
||||
SProcGetImage,
|
||||
SProcPolyText,
|
||||
SProcPolyText, /* 75 */
|
||||
SProcImageText,
|
||||
SProcImageText,
|
||||
SProcCreateColormap,
|
||||
SProcResourceReq, /* SProcFreeColormap, */
|
||||
SProcCopyColormapAndFree, /* 80 */
|
||||
SProcResourceReq, /* SProcInstallColormap, */
|
||||
SProcResourceReq, /* SProcUninstallColormap, */
|
||||
SProcResourceReq, /* SProcListInstalledColormaps, */
|
||||
SProcAllocColor,
|
||||
SProcAllocNamedColor, /* 85 */
|
||||
SProcAllocColorCells,
|
||||
SProcAllocColorPlanes,
|
||||
SProcFreeColors,
|
||||
SProcStoreColors,
|
||||
SProcStoreNamedColor, /* 90 */
|
||||
SProcQueryColors,
|
||||
SProcLookupColor,
|
||||
SProcCreateCursor,
|
||||
SProcCreateGlyphCursor,
|
||||
SProcResourceReq, /* 95 SProcFreeCursor, */
|
||||
SProcRecolorCursor,
|
||||
SProcQueryBestSize,
|
||||
SProcQueryExtension,
|
||||
SProcSimpleReq, /* ListExtensions, */
|
||||
SProcChangeKeyboardMapping, /* 100 */
|
||||
SProcSimpleReq, /* GetKeyboardMapping, */
|
||||
SProcChangeKeyboardControl,
|
||||
SProcSimpleReq, /* GetKeyboardControl, */
|
||||
SProcSimpleReq, /* Bell, */
|
||||
SProcChangePointerControl, /* 105 */
|
||||
SProcSimpleReq, /* GetPointerControl, */
|
||||
SProcSetScreenSaver,
|
||||
SProcSimpleReq, /* GetScreenSaver, */
|
||||
SProcChangeHosts,
|
||||
SProcSimpleReq, /* 110 ListHosts, */
|
||||
SProcSimpleReq, /* SProcChangeAccessControl, */
|
||||
SProcSimpleReq, /* SProcChangeCloseDownMode, */
|
||||
SProcResourceReq, /* SProcKillClient, */
|
||||
SProcRotateProperties,
|
||||
SProcSimpleReq, /* 115 ForceScreenSaver */
|
||||
SProcSimpleReq, /* SetPointerMapping, */
|
||||
SProcSimpleReq, /* GetPointerMapping, */
|
||||
SProcSimpleReq, /* SetModifierMapping, */
|
||||
SProcSimpleReq, /* GetModifierMapping, */
|
||||
ProcBadRequest, /* 120 */
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest, /* 125 */
|
||||
ProcBadRequest,
|
||||
SProcNoOperation,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest,
|
||||
ProcBadRequest
|
||||
};
|
||||
|
||||
EventSwapPtr EventSwapVector[128] =
|
||||
{
|
||||
(EventSwapPtr)SErrorEvent,
|
||||
NotImplemented,
|
||||
SKeyButtonPtrEvent,
|
||||
SKeyButtonPtrEvent,
|
||||
SKeyButtonPtrEvent,
|
||||
SKeyButtonPtrEvent, /* 5 */
|
||||
SKeyButtonPtrEvent,
|
||||
SEnterLeaveEvent,
|
||||
SEnterLeaveEvent,
|
||||
SFocusEvent,
|
||||
SFocusEvent, /* 10 */
|
||||
SKeymapNotifyEvent,
|
||||
SExposeEvent,
|
||||
SGraphicsExposureEvent,
|
||||
SNoExposureEvent,
|
||||
SVisibilityEvent, /* 15 */
|
||||
SCreateNotifyEvent,
|
||||
SDestroyNotifyEvent,
|
||||
SUnmapNotifyEvent,
|
||||
SMapNotifyEvent,
|
||||
SMapRequestEvent, /* 20 */
|
||||
SReparentEvent,
|
||||
SConfigureNotifyEvent,
|
||||
SConfigureRequestEvent,
|
||||
SGravityEvent,
|
||||
SResizeRequestEvent, /* 25 */
|
||||
SCirculateEvent,
|
||||
SCirculateEvent,
|
||||
SPropertyEvent,
|
||||
SSelectionClearEvent,
|
||||
SSelectionRequestEvent, /* 30 */
|
||||
SSelectionNotifyEvent,
|
||||
SColormapEvent,
|
||||
SClientMessageEvent,
|
||||
SMappingEvent,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented,
|
||||
NotImplemented
|
||||
};
|
||||
|
||||
|
||||
ReplySwapPtr ReplySwapVector[256] =
|
||||
{
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SGetWindowAttributesReply,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 5 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 10 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SGetGeometryReply,
|
||||
(ReplySwapPtr)SQueryTreeReply, /* 15 */
|
||||
(ReplySwapPtr)SInternAtomReply,
|
||||
(ReplySwapPtr)SGetAtomNameReply,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SGetPropertyReply, /* 20 */
|
||||
(ReplySwapPtr)SListPropertiesReply,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SGetSelectionOwnerReply,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 25 */
|
||||
(ReplySwapPtr)SGenericReply, /* SGrabPointerReply, */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 30 */
|
||||
(ReplySwapPtr)SGenericReply, /* SGrabKeyboardReply, */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 35 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SQueryPointerReply,
|
||||
(ReplySwapPtr)SGetMotionEventsReply,
|
||||
(ReplySwapPtr)STranslateCoordsReply, /* 40 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SGetInputFocusReply,
|
||||
(ReplySwapPtr)SQueryKeymapReply,
|
||||
ReplyNotSwappd, /* 45 */
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SQueryFontReply,
|
||||
(ReplySwapPtr)SQueryTextExtentsReply,
|
||||
(ReplySwapPtr)SListFontsReply,
|
||||
(ReplySwapPtr)SListFontsWithInfoReply, /* 50 */
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SGetFontPathReply,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 55 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 60 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 65 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 70 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SGetImageReply,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 75 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 80 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SListInstalledColormapsReply,
|
||||
(ReplySwapPtr)SAllocColorReply,
|
||||
(ReplySwapPtr)SAllocNamedColorReply, /* 85 */
|
||||
(ReplySwapPtr)SAllocColorCellsReply,
|
||||
(ReplySwapPtr)SAllocColorPlanesReply,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 90 */
|
||||
(ReplySwapPtr)SQueryColorsReply,
|
||||
(ReplySwapPtr)SLookupColorReply,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 95 */
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SQueryBestSizeReply,
|
||||
(ReplySwapPtr)SGenericReply, /* SQueryExtensionReply, */
|
||||
(ReplySwapPtr)SListExtensionsReply,
|
||||
ReplyNotSwappd, /* 100 */
|
||||
(ReplySwapPtr)SGetKeyboardMappingReply,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SGetKeyboardControlReply,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 105 */
|
||||
(ReplySwapPtr)SGetPointerControlReply,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SGetScreenSaverReply,
|
||||
ReplyNotSwappd,
|
||||
(ReplySwapPtr)SListHostsReply, /* 110 */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd, /* 115 */
|
||||
(ReplySwapPtr)SGenericReply, /* SetPointerMapping */
|
||||
(ReplySwapPtr)SGetPointerMappingReply,
|
||||
(ReplySwapPtr)SGenericReply, /* SetModifierMapping */
|
||||
(ReplySwapPtr)SGetModifierMappingReply, /* 119 */
|
||||
ReplyNotSwappd, /* 120 */
|
||||
ReplyNotSwappd, /* 121 */
|
||||
ReplyNotSwappd, /* 122 */
|
||||
ReplyNotSwappd, /* 123 */
|
||||
ReplyNotSwappd, /* 124 */
|
||||
ReplyNotSwappd, /* 125 */
|
||||
ReplyNotSwappd, /* 126 */
|
||||
ReplyNotSwappd, /* NoOperation */
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd,
|
||||
ReplyNotSwappd
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,45 @@
|
|||
noinst_LTLIBRARIES = libfb.la
|
||||
|
||||
AM_CFLAGS = $(DIX_CFLAGS)
|
||||
|
||||
libfb_la_SOURCES = \
|
||||
fb.h \
|
||||
fb24_32.c \
|
||||
fb24_32.h \
|
||||
fballpriv.c \
|
||||
fbarc.c \
|
||||
fbbits.c \
|
||||
fbbits.h \
|
||||
fbblt.c \
|
||||
fbbltone.c \
|
||||
fbcompose.c \
|
||||
fbcopy.c \
|
||||
fbfill.c \
|
||||
fbfillrect.c \
|
||||
fbfillsp.c \
|
||||
fbgc.c \
|
||||
fbgetsp.c \
|
||||
fbglyph.c \
|
||||
fbimage.c \
|
||||
fbline.c \
|
||||
fboverlay.c \
|
||||
fboverlay.h \
|
||||
fbpict.c \
|
||||
fbpict.h \
|
||||
fbpixmap.c \
|
||||
fbpoint.c \
|
||||
fbpush.c \
|
||||
fbrop.h \
|
||||
fbscreen.c \
|
||||
fbseg.c \
|
||||
fbsetsp.c \
|
||||
fbsolid.c \
|
||||
fbstipple.c \
|
||||
fbtile.c \
|
||||
fbtrap.c \
|
||||
fbutil.c \
|
||||
fbwindow.c \
|
||||
fbedge.c \
|
||||
fbedgeimp.h
|
||||
|
||||
EXTRA_DIST = fbcmap.c
|
|
@ -0,0 +1,586 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Keith Packard, SuSE, Inc.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
/* X apps don't like 24bpp images, this code exposes 32bpp images */
|
||||
|
||||
/*
|
||||
* These two functions do a full CopyArea while reformatting
|
||||
* the data between 24 and 32bpp. They try to go a bit faster
|
||||
* by reading/writing aligned CARD32s where it's easy
|
||||
*/
|
||||
|
||||
#define Get8(a) ((CARD32) *(a))
|
||||
|
||||
#if BITMAP_BIT_ORDER == MSBFirst
|
||||
#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2))
|
||||
#define Put24(a,p) (((a)[0] = (CARD8) ((p) >> 16)), \
|
||||
((a)[1] = (CARD8) ((p) >> 8)), \
|
||||
((a)[2] = (CARD8) (p)))
|
||||
#else
|
||||
#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16))
|
||||
#define Put24(a,p) (((a)[0] = (CARD8) (p)), \
|
||||
((a)[1] = (CARD8) ((p) >> 8)), \
|
||||
((a)[2] = (CARD8) ((p) >> 16)))
|
||||
#endif
|
||||
|
||||
typedef void (*fb24_32BltFunc) (CARD8 *srcLine,
|
||||
FbStride srcStride,
|
||||
int srcX,
|
||||
CARD8 *dstLine,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int width, int height, int alu, FbBits pm);
|
||||
|
||||
static void
|
||||
fb24_32BltDown(CARD8 *srcLine,
|
||||
FbStride srcStride,
|
||||
int srcX,
|
||||
CARD8 *dstLine,
|
||||
FbStride dstStride,
|
||||
int dstX, int width, int height, int alu, FbBits pm)
|
||||
{
|
||||
CARD32 *src;
|
||||
|
||||
CARD8 *dst;
|
||||
|
||||
int w;
|
||||
|
||||
Bool destInvarient;
|
||||
|
||||
CARD32 pixel, dpixel;
|
||||
|
||||
FbDeclareMergeRop();
|
||||
|
||||
srcLine += srcX * 4;
|
||||
dstLine += dstX * 3;
|
||||
|
||||
FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff));
|
||||
destInvarient = FbDestInvarientMergeRop();
|
||||
|
||||
while (height--) {
|
||||
src = (CARD32 *) srcLine;
|
||||
dst = dstLine;
|
||||
srcLine += srcStride;
|
||||
dstLine += dstStride;
|
||||
w = width;
|
||||
if (destInvarient) {
|
||||
while (((long) dst & 3) && w) {
|
||||
w--;
|
||||
pixel = *src++;
|
||||
pixel = FbDoDestInvarientMergeRop(pixel);
|
||||
Put24(dst, pixel);
|
||||
dst += 3;
|
||||
}
|
||||
/* Do four aligned pixels at a time */
|
||||
while (w >= 4) {
|
||||
CARD32 s0, s1;
|
||||
|
||||
s0 = *src++;
|
||||
s0 = FbDoDestInvarientMergeRop(s0);
|
||||
s1 = *src++;
|
||||
s1 = FbDoDestInvarientMergeRop(s1);
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
*(CARD32 *) (dst) = (s0 & 0xffffff) | (s1 << 24);
|
||||
#else
|
||||
*(CARD32 *) (dst) = (s0 << 8) | ((s1 & 0xffffff) >> 16);
|
||||
#endif
|
||||
s0 = *src++;
|
||||
s0 = FbDoDestInvarientMergeRop(s0);
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
*(CARD32 *) (dst + 4) = ((s1 & 0xffffff) >> 8) | (s0 << 16);
|
||||
#else
|
||||
*(CARD32 *) (dst + 4) = (s1 << 16) | ((s0 & 0xffffff) >> 8);
|
||||
#endif
|
||||
s1 = *src++;
|
||||
s1 = FbDoDestInvarientMergeRop(s1);
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
*(CARD32 *) (dst + 8) = ((s0 & 0xffffff) >> 16) | (s1 << 8);
|
||||
#else
|
||||
*(CARD32 *) (dst + 8) = (s0 << 24) | (s1 & 0xffffff);
|
||||
#endif
|
||||
dst += 12;
|
||||
w -= 4;
|
||||
}
|
||||
while (w--) {
|
||||
pixel = *src++;
|
||||
pixel = FbDoDestInvarientMergeRop(pixel);
|
||||
Put24(dst, pixel);
|
||||
dst += 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (w--) {
|
||||
pixel = *src++;
|
||||
dpixel = Get24(dst);
|
||||
pixel = FbDoMergeRop(pixel, dpixel);
|
||||
Put24(dst, pixel);
|
||||
dst += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fb24_32BltUp(CARD8 *srcLine,
|
||||
FbStride srcStride,
|
||||
int srcX,
|
||||
CARD8 *dstLine,
|
||||
FbStride dstStride,
|
||||
int dstX, int width, int height, int alu, FbBits pm)
|
||||
{
|
||||
CARD8 *src;
|
||||
|
||||
CARD32 *dst;
|
||||
|
||||
int w;
|
||||
|
||||
Bool destInvarient;
|
||||
|
||||
CARD32 pixel;
|
||||
|
||||
FbDeclareMergeRop();
|
||||
|
||||
FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff)));
|
||||
destInvarient = FbDestInvarientMergeRop();
|
||||
|
||||
srcLine += srcX * 3;
|
||||
dstLine += dstX * 4;
|
||||
|
||||
while (height--) {
|
||||
w = width;
|
||||
src = srcLine;
|
||||
dst = (CARD32 *) dstLine;
|
||||
srcLine += srcStride;
|
||||
dstLine += dstStride;
|
||||
if (destInvarient) {
|
||||
while (((long) src & 3) && w) {
|
||||
w--;
|
||||
pixel = Get24(src);
|
||||
src += 3;
|
||||
*dst++ = FbDoDestInvarientMergeRop(pixel);
|
||||
}
|
||||
/* Do four aligned pixels at a time */
|
||||
while (w >= 4) {
|
||||
CARD32 s0, s1;
|
||||
|
||||
s0 = *(CARD32 *) (src);
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
pixel = s0 & 0xffffff;
|
||||
#else
|
||||
pixel = s0 >> 8;
|
||||
#endif
|
||||
*dst++ = FbDoDestInvarientMergeRop(pixel);
|
||||
s1 = *(CARD32 *) (src + 4);
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff);
|
||||
#else
|
||||
pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16);
|
||||
#endif
|
||||
*dst++ = FbDoDestInvarientMergeRop(pixel);
|
||||
s0 = *(CARD32 *) (src + 8);
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff);
|
||||
#else
|
||||
pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24);
|
||||
#endif
|
||||
*dst++ = FbDoDestInvarientMergeRop(pixel);
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
pixel = s0 >> 8;
|
||||
#else
|
||||
pixel = s0 & 0xffffff;
|
||||
#endif
|
||||
*dst++ = FbDoDestInvarientMergeRop(pixel);
|
||||
src += 12;
|
||||
w -= 4;
|
||||
}
|
||||
while (w) {
|
||||
w--;
|
||||
pixel = Get24(src);
|
||||
src += 3;
|
||||
*dst++ = FbDoDestInvarientMergeRop(pixel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (w--) {
|
||||
pixel = Get24(src);
|
||||
src += 3;
|
||||
*dst = FbDoMergeRop(pixel, *dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Spans functions; probably unused.
|
||||
*/
|
||||
void
|
||||
fb24_32GetSpans(DrawablePtr pDrawable,
|
||||
int wMax,
|
||||
DDXPointPtr ppt, int *pwidth, int nspans, char *pchardstStart)
|
||||
{
|
||||
FbBits *srcBits;
|
||||
|
||||
CARD8 *src;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
CARD8 *dst;
|
||||
|
||||
fbGetDrawable(pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
|
||||
src = (CARD8 *) srcBits;
|
||||
srcStride *= sizeof(FbBits);
|
||||
|
||||
while (nspans--) {
|
||||
dst = (CARD8 *) pchardstStart;
|
||||
fb24_32BltUp(src + (ppt->y + srcYoff) * srcStride, srcStride,
|
||||
ppt->x + srcXoff,
|
||||
dst, 1, 0, *pwidth, 1, GXcopy, FB_ALLONES);
|
||||
|
||||
pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth);
|
||||
ppt++;
|
||||
pwidth++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fb24_32SetSpans(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
char *src,
|
||||
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
RegionPtr pClip = fbGetCompositeClip(pGC);
|
||||
|
||||
FbBits *dstBits;
|
||||
|
||||
CARD8 *dst, *d, *s;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
BoxPtr pbox;
|
||||
|
||||
int n;
|
||||
|
||||
int x1, x2;
|
||||
|
||||
fbGetDrawable(pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
dst = (CARD8 *) dstBits;
|
||||
dstStride *= sizeof(FbBits);
|
||||
while (nspans--) {
|
||||
d = dst + (ppt->y + dstYoff) * dstStride;
|
||||
s = (CARD8 *) src;
|
||||
n = REGION_NUM_RECTS(pClip);
|
||||
pbox = REGION_RECTS(pClip);
|
||||
while (n--) {
|
||||
if (pbox->y1 > ppt->y)
|
||||
break;
|
||||
if (pbox->y2 > ppt->y) {
|
||||
x1 = ppt->x;
|
||||
x2 = x1 + *pwidth;
|
||||
if (pbox->x1 > x1)
|
||||
x1 = pbox->x1;
|
||||
if (pbox->x2 < x2)
|
||||
x2 = pbox->x2;
|
||||
if (x1 < x2)
|
||||
fb24_32BltDown(s,
|
||||
0,
|
||||
(x1 - ppt->x),
|
||||
d,
|
||||
dstStride,
|
||||
x1 + dstXoff,
|
||||
(x2 - x1), 1, pGC->alu, pPriv->pm);
|
||||
}
|
||||
}
|
||||
src += PixmapBytePad(*pwidth, pDrawable->depth);
|
||||
ppt++;
|
||||
pwidth++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clip and put 32bpp Z-format images to a 24bpp drawable
|
||||
*/
|
||||
void
|
||||
fb24_32PutZImage(DrawablePtr pDrawable,
|
||||
RegionPtr pClip,
|
||||
int alu,
|
||||
FbBits pm,
|
||||
int x,
|
||||
int y, int width, int height, CARD8 *src, FbStride srcStride)
|
||||
{
|
||||
FbBits *dstBits;
|
||||
|
||||
CARD8 *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
int nbox;
|
||||
|
||||
BoxPtr pbox;
|
||||
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
fbGetDrawable(pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
dstStride *= sizeof(FbBits);
|
||||
dst = (CARD8 *) dstBits;
|
||||
|
||||
for (nbox = REGION_NUM_RECTS(pClip),
|
||||
pbox = REGION_RECTS(pClip); nbox--; pbox++) {
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
x2 = x + width;
|
||||
y2 = y + height;
|
||||
if (x1 < pbox->x1)
|
||||
x1 = pbox->x1;
|
||||
if (y1 < pbox->y1)
|
||||
y1 = pbox->y1;
|
||||
if (x2 > pbox->x2)
|
||||
x2 = pbox->x2;
|
||||
if (y2 > pbox->y2)
|
||||
y2 = pbox->y2;
|
||||
if (x1 >= x2 || y1 >= y2)
|
||||
continue;
|
||||
fb24_32BltDown(src + (y1 - y) * srcStride,
|
||||
srcStride,
|
||||
(x1 - x),
|
||||
dst + (y1 + dstYoff) * dstStride,
|
||||
dstStride, x1 + dstXoff, (x2 - x1), (y2 - y1), alu, pm);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fb24_32GetImage(DrawablePtr pDrawable,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int h, unsigned int format, unsigned long planeMask, char *d)
|
||||
{
|
||||
FbBits *srcBits;
|
||||
|
||||
CARD8 *src;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
FbBits pm;
|
||||
|
||||
fbGetDrawable(pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
|
||||
src = (CARD8 *) srcBits;
|
||||
srcStride *= sizeof(FbBits);
|
||||
|
||||
x += pDrawable->x;
|
||||
y += pDrawable->y;
|
||||
|
||||
pm = fbReplicatePixel(planeMask, 32);
|
||||
dstStride = PixmapBytePad(w, pDrawable->depth);
|
||||
if (pm != FB_ALLONES)
|
||||
memset(d, 0, dstStride * h);
|
||||
fb24_32BltUp(src + (y + srcYoff) * srcStride, srcStride, x + srcXoff,
|
||||
(CARD8 *) d, dstStride, 0, w, h, GXcopy, pm);
|
||||
}
|
||||
|
||||
void
|
||||
fb24_32CopyMtoN(DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
BoxPtr pbox,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
FbBits *srcBits;
|
||||
|
||||
CARD8 *src;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
FbBits *dstBits;
|
||||
|
||||
CARD8 *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
fb24_32BltFunc blt;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
fbGetDrawable(pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
|
||||
src = (CARD8 *) srcBits;
|
||||
srcStride *= sizeof(FbBits);
|
||||
fbGetDrawable(pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
dst = (CARD8 *) dstBits;
|
||||
dstStride *= sizeof(FbBits);
|
||||
if (srcBpp == 24)
|
||||
blt = fb24_32BltUp;
|
||||
else
|
||||
blt = fb24_32BltDown;
|
||||
|
||||
while (nbox--) {
|
||||
(*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride,
|
||||
srcStride,
|
||||
(pbox->x1 + dx + srcXoff),
|
||||
dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff),
|
||||
(pbox->x2 - pbox->x1),
|
||||
(pbox->y2 - pbox->y1), pGC->alu, pPriv->pm);
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
PixmapPtr
|
||||
fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel)
|
||||
{
|
||||
ScreenPtr pScreen = pOldTile->drawable.pScreen;
|
||||
|
||||
PixmapPtr pNewTile;
|
||||
|
||||
FbBits *old, *new;
|
||||
|
||||
FbStride oldStride, newStride;
|
||||
|
||||
int oldBpp, newBpp;
|
||||
|
||||
fb24_32BltFunc blt;
|
||||
|
||||
int oldXoff _X_UNUSED, oldYoff _X_UNUSED;
|
||||
int newXoff _X_UNUSED, newYoff _X_UNUSED;
|
||||
|
||||
pNewTile = fbCreatePixmapBpp(pScreen,
|
||||
pOldTile->drawable.width,
|
||||
pOldTile->drawable.height,
|
||||
pOldTile->drawable.depth, bitsPerPixel);
|
||||
if (!pNewTile)
|
||||
return 0;
|
||||
fbGetDrawable(&pOldTile->drawable,
|
||||
old, oldStride, oldBpp, oldXoff, oldYoff);
|
||||
fbGetDrawable(&pNewTile->drawable,
|
||||
new, newStride, newBpp, newXoff, newYoff);
|
||||
if (oldBpp == 24)
|
||||
blt = fb24_32BltUp;
|
||||
else
|
||||
blt = fb24_32BltDown;
|
||||
|
||||
(*blt) ((CARD8 *) old,
|
||||
oldStride * sizeof(FbBits),
|
||||
0,
|
||||
(CARD8 *) new,
|
||||
newStride * sizeof(FbBits),
|
||||
0,
|
||||
pOldTile->drawable.width,
|
||||
pOldTile->drawable.height, GXcopy, FB_ALLONES);
|
||||
|
||||
return pNewTile;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
pointer pbits;
|
||||
int width;
|
||||
} miScreenInitParmsRec, *miScreenInitParmsPtr;
|
||||
|
||||
Bool
|
||||
fb24_32CreateScreenResources(ScreenPtr pScreen)
|
||||
{
|
||||
miScreenInitParmsPtr pScrInitParms;
|
||||
|
||||
int pitch;
|
||||
|
||||
Bool retval;
|
||||
|
||||
/* get the pitch before mi destroys it */
|
||||
pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
|
||||
pitch = BitmapBytePad(pScrInitParms->width * 24);
|
||||
|
||||
if ((retval = miCreateScreenResources(pScreen))) {
|
||||
/* fix the screen pixmap */
|
||||
PixmapPtr pPix = (PixmapPtr) pScreen->devPrivate;
|
||||
|
||||
pPix->drawable.bitsPerPixel = 24;
|
||||
pPix->devKind = pitch;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
Bool
|
||||
fb24_32ModifyPixmapHeader(PixmapPtr pPixmap,
|
||||
int width,
|
||||
int height,
|
||||
int depth,
|
||||
int bitsPerPixel, int devKind, pointer pPixData)
|
||||
{
|
||||
int bpp, w;
|
||||
|
||||
if (!pPixmap)
|
||||
return FALSE;
|
||||
bpp = bitsPerPixel;
|
||||
if (bpp <= 0)
|
||||
bpp = pPixmap->drawable.bitsPerPixel;
|
||||
if (bpp == 24) {
|
||||
if (devKind < 0) {
|
||||
w = width;
|
||||
if (w <= 0)
|
||||
w = pPixmap->drawable.width;
|
||||
devKind = BitmapBytePad(w * 24);
|
||||
}
|
||||
}
|
||||
return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel,
|
||||
devKind, pPixData);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Keith Packard, SuSE, Inc.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _FB24_32_H_
|
||||
#define _FB24_32_H_
|
||||
|
||||
Bool
|
||||
|
||||
fb24_32FinishScreenInit(ScreenPtr pScreen,
|
||||
pointer pbits,
|
||||
int xsize,
|
||||
int ysize, int dpix, int dpiy, int width, int bpp);
|
||||
|
||||
Bool
|
||||
|
||||
fb24_32ScreenInit(ScreenPtr pScreen,
|
||||
pointer pbits,
|
||||
int xsize, int ysize, int dpix, int dpiy, int width, int bpp);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
int fbScreenPrivateIndex;
|
||||
|
||||
int
|
||||
fbGetScreenPrivateIndex(void)
|
||||
{
|
||||
return fbScreenPrivateIndex;
|
||||
}
|
||||
int fbGCPrivateIndex;
|
||||
|
||||
int
|
||||
fbGetGCPrivateIndex(void)
|
||||
{
|
||||
return fbGCPrivateIndex;
|
||||
}
|
||||
|
||||
int fbWinPrivateIndex;
|
||||
|
||||
int
|
||||
fbGetWinPrivateIndex(void)
|
||||
{
|
||||
return fbWinPrivateIndex;
|
||||
}
|
||||
int fbGeneration;
|
||||
|
||||
|
||||
Bool
|
||||
fbAllocatePrivates(ScreenPtr pScreen, int *pGCIndex)
|
||||
{
|
||||
if (fbGeneration != serverGeneration) {
|
||||
fbGCPrivateIndex = miAllocateGCPrivateIndex();
|
||||
fbWinPrivateIndex = AllocateWindowPrivateIndex();
|
||||
fbScreenPrivateIndex = AllocateScreenPrivateIndex();
|
||||
if (fbScreenPrivateIndex == -1)
|
||||
return FALSE;
|
||||
|
||||
fbGeneration = serverGeneration;
|
||||
}
|
||||
if (pGCIndex)
|
||||
*pGCIndex = fbGCPrivateIndex;
|
||||
if (!AllocateGCPrivate(pScreen, fbGCPrivateIndex, sizeof(FbGCPrivRec)))
|
||||
return FALSE;
|
||||
if (!AllocateWindowPrivate(pScreen, fbWinPrivateIndex, 0))
|
||||
return FALSE;
|
||||
{
|
||||
FbScreenPrivPtr pScreenPriv;
|
||||
|
||||
pScreenPriv = malloc(sizeof(FbScreenPrivRec));
|
||||
if (!pScreenPriv)
|
||||
return FALSE;
|
||||
pScreen->devPrivates[fbScreenPrivateIndex].ptr = (pointer) pScreenPriv;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
#include "mizerarc.h"
|
||||
#include <limits.h>
|
||||
|
||||
typedef void (*FbArc) (FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstBpp,
|
||||
xArc * arc, int dx, int dy, FbBits and, FbBits xor);
|
||||
|
||||
void
|
||||
fbPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs)
|
||||
{
|
||||
FbArc arc;
|
||||
|
||||
if (pGC->lineWidth == 0) {
|
||||
arc = 0;
|
||||
if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid) {
|
||||
switch (pDrawable->bitsPerPixel) {
|
||||
case 8:
|
||||
arc = fbArc8;
|
||||
break;
|
||||
case 16:
|
||||
arc = fbArc16;
|
||||
break;
|
||||
case 24:
|
||||
arc = fbArc24;
|
||||
break;
|
||||
case 32:
|
||||
arc = fbArc32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (arc) {
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
BoxRec box;
|
||||
|
||||
int x2, y2;
|
||||
|
||||
RegionPtr cclip;
|
||||
|
||||
cclip = fbGetCompositeClip(pGC);
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
while (narcs--) {
|
||||
if (miCanZeroArc(parcs)) {
|
||||
box.x1 = parcs->x + pDrawable->x;
|
||||
box.y1 = parcs->y + pDrawable->y;
|
||||
/*
|
||||
* Because box.x2 and box.y2 get truncated to 16 bits, and the
|
||||
* RECT_IN_REGION test treats the resulting number as a signed
|
||||
* integer, the RECT_IN_REGION test alone can go the wrong way.
|
||||
* This can result in a server crash because the rendering
|
||||
* routines in this file deal directly with cpu addresses
|
||||
* of pixels to be stored, and do not clip or otherwise check
|
||||
* that all such addresses are within their respective pixmaps.
|
||||
* So we only allow the RECT_IN_REGION test to be used for
|
||||
* values that can be expressed correctly in a signed short.
|
||||
*/
|
||||
x2 = box.x1 + (int) parcs->width + 1;
|
||||
box.x2 = x2;
|
||||
y2 = box.y1 + (int) parcs->height + 1;
|
||||
box.y2 = y2;
|
||||
if ((x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
|
||||
(RECT_IN_REGION(cclip, &box) ==
|
||||
rgnIN))
|
||||
(*arc) (dst, dstStride, dstBpp, parcs,
|
||||
pDrawable->x + dstXoff, pDrawable->y + dstYoff,
|
||||
pPriv->and, pPriv->xor);
|
||||
else
|
||||
miZeroPolyArc(pDrawable, pGC, 1, parcs);
|
||||
}
|
||||
else
|
||||
miPolyArc(pDrawable, pGC, 1, parcs);
|
||||
parcs++;
|
||||
}
|
||||
}
|
||||
else
|
||||
miZeroPolyArc(pDrawable, pGC, narcs, parcs);
|
||||
}
|
||||
else
|
||||
miPolyArc(pDrawable, pGC, narcs, parcs);
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
#include "miline.h"
|
||||
#include "mizerarc.h"
|
||||
|
||||
#undef BRESSOLID
|
||||
#undef BRESDASH
|
||||
#undef DOTS
|
||||
#undef ARC
|
||||
#undef GLYPH
|
||||
#undef BITS
|
||||
#undef BITS2
|
||||
#undef BITS4
|
||||
|
||||
#define BRESSOLID fbBresSolid8
|
||||
#define BRESDASH fbBresDash8
|
||||
#define DOTS fbDots8
|
||||
#define ARC fbArc8
|
||||
#define GLYPH fbGlyph8
|
||||
#define POLYLINE fbPolyline8
|
||||
#define POLYSEGMENT fbPolySegment8
|
||||
#define BITS BYTE
|
||||
#define BITS2 CARD16
|
||||
#define BITS4 CARD32
|
||||
|
||||
#include "fbbits.h"
|
||||
|
||||
#undef BRESSOLID
|
||||
#undef BRESDASH
|
||||
#undef DOTS
|
||||
#undef ARC
|
||||
#undef GLYPH
|
||||
#undef POLYLINE
|
||||
#undef POLYSEGMENT
|
||||
#undef BITS
|
||||
#undef BITS2
|
||||
#undef BITS4
|
||||
|
||||
#define BRESSOLID fbBresSolid16
|
||||
#define BRESDASH fbBresDash16
|
||||
#define DOTS fbDots16
|
||||
#define ARC fbArc16
|
||||
#define GLYPH fbGlyph16
|
||||
#define POLYLINE fbPolyline16
|
||||
#define POLYSEGMENT fbPolySegment16
|
||||
#define BITS CARD16
|
||||
#define BITS2 CARD32
|
||||
#if FB_SHIFT == 6
|
||||
#define BITS4 FbBits
|
||||
#endif
|
||||
|
||||
#include "fbbits.h"
|
||||
|
||||
#undef BRESSOLID
|
||||
#undef BRESDASH
|
||||
#undef DOTS
|
||||
#undef ARC
|
||||
#undef GLYPH
|
||||
#undef POLYLINE
|
||||
#undef POLYSEGMENT
|
||||
#undef BITS
|
||||
#undef BITS2
|
||||
#if FB_SHIFT == 6
|
||||
#undef BITS4
|
||||
#endif
|
||||
|
||||
#define BRESSOLID fbBresSolid24
|
||||
#define BRESDASH fbBresDash24
|
||||
#define DOTS fbDots24
|
||||
#define ARC fbArc24
|
||||
#define POLYLINE fbPolyline24
|
||||
#define POLYSEGMENT fbPolySegment24
|
||||
|
||||
#define BITS CARD32
|
||||
#define BITSUNIT BYTE
|
||||
#define BITSMUL 3
|
||||
|
||||
#define FbDoTypeStore(b,t,x,s) (*((t *) (b)) = (x) >> (s))
|
||||
#define FbDoTypeRRop(b,t,a,x,s) (*((t *) (b)) = FbDoRRop(*((t *) (b)),\
|
||||
(a) >> (s), \
|
||||
(x) >> (s)))
|
||||
#define FbDoTypeMaskRRop(b,t,a,x,m,s) (*((t *) (b)) = FbDoMaskRRop(*((t *) (b)),\
|
||||
(a) >> (s), \
|
||||
(x) >> (s), \
|
||||
(m) >> (s))
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
#define BITSSTORE(b,x) ((unsigned long) (b) & 1 ? \
|
||||
(FbDoTypeStore (b, CARD8, x, 0), \
|
||||
FbDoTypeStore ((b) + 1, CARD16, x, 8)) : \
|
||||
(FbDoTypeStore (b, CARD16, x, 0), \
|
||||
FbDoTypeStore ((b) + 2, CARD8, x, 16)))
|
||||
#define BITSRROP(b,a,x) ((unsigned long) (b) & 1 ? \
|
||||
(FbDoTypeRRop(b,CARD8,a,x,0), \
|
||||
FbDoTypeRRop((b)+1,CARD16,a,x,8)) : \
|
||||
(FbDoTypeRRop(b,CARD16,a,x,0), \
|
||||
FbDoTypeRRop((b)+2,CARD8,a,x,16)))
|
||||
#else
|
||||
#define BITSSTORE(b,x) ((unsigned long) (b) & 1 ? \
|
||||
(FbDoTypeStore (b, CARD8, x, 16), \
|
||||
FbDoTypeStore ((b) + 1, CARD16, x, 0)) : \
|
||||
(FbDoTypeStore (b, CARD16, x, 8), \
|
||||
FbDoTypeStore ((b) + 2, CARD8, x, 0)))
|
||||
#define BITSRROP(b,a,x) ((unsigned long) (b) & 1 ? \
|
||||
(FbDoTypeRRop (b, CARD8, a, x, 16), \
|
||||
FbDoTypeRRop ((b) + 1, CARD16, a, x, 0)) : \
|
||||
(FbDoTypeRRop (b, CARD16, a, x, 8), \
|
||||
FbDoTypeRRop ((b) + 2, CARD8, a, x, 0)))
|
||||
#endif
|
||||
|
||||
#include "fbbits.h"
|
||||
|
||||
#undef BITSSTORE
|
||||
#undef BITSRROP
|
||||
#undef BITSMUL
|
||||
#undef BITSUNIT
|
||||
#undef BITS
|
||||
|
||||
#undef BRESSOLID
|
||||
#undef BRESDASH
|
||||
#undef DOTS
|
||||
#undef ARC
|
||||
#undef POLYLINE
|
||||
#undef POLYSEGMENT
|
||||
|
||||
#define BRESSOLID fbBresSolid32
|
||||
#define BRESDASH fbBresDash32
|
||||
#define DOTS fbDots32
|
||||
#define ARC fbArc32
|
||||
#define GLYPH fbGlyph32
|
||||
#define POLYLINE fbPolyline32
|
||||
#define POLYSEGMENT fbPolySegment32
|
||||
#define BITS CARD32
|
||||
#if FB_SHIFT == 6
|
||||
#define BITS2 FbBits
|
||||
#endif
|
||||
|
||||
#include "fbbits.h"
|
||||
|
||||
#undef BRESSOLID
|
||||
#undef BRESDASH
|
||||
#undef DOTS
|
||||
#undef ARC
|
||||
#undef GLYPH
|
||||
#undef POLYLINE
|
||||
#undef POLYSEGMENT
|
||||
#undef BITS
|
||||
#if FB_SHIFT == 6
|
||||
#undef BITS2
|
||||
#endif
|
|
@ -0,0 +1,938 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file defines functions for drawing some primitives using
|
||||
* underlying datatypes instead of masks
|
||||
*/
|
||||
|
||||
#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & 0x80008000)
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifdef BITSMUL
|
||||
#define MUL BITSMUL
|
||||
#else
|
||||
#define MUL 1
|
||||
#endif
|
||||
|
||||
#ifdef BITSSTORE
|
||||
#define STORE(b,x) BITSSTORE(b,x)
|
||||
#else
|
||||
#define STORE(b,x) (*(b) = (x))
|
||||
#endif
|
||||
|
||||
#ifdef BITSRROP
|
||||
#define RROP(b,a,x) BITSRROP(b,a,x)
|
||||
#else
|
||||
#define RROP(b,a,x) (*(b) = FbDoRRop (*(b), (a), (x)))
|
||||
#endif
|
||||
|
||||
#ifdef BITSUNIT
|
||||
#define UNIT BITSUNIT
|
||||
#define USE_SOLID
|
||||
#else
|
||||
#define UNIT BITS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the following before including this file:
|
||||
*
|
||||
* BRESSOLID name of function for drawing a solid segment
|
||||
* BRESDASH name of function for drawing a dashed segment
|
||||
* DOTS name of function for drawing dots
|
||||
* ARC name of function for drawing a solid arc
|
||||
* BITS type of underlying unit
|
||||
*/
|
||||
|
||||
#ifdef BRESSOLID
|
||||
void
|
||||
BRESSOLID(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int dashOffset,
|
||||
int signdx,
|
||||
int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len)
|
||||
{
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
UNIT *bits;
|
||||
|
||||
FbStride bitsStride;
|
||||
|
||||
FbStride majorStep, minorStep;
|
||||
|
||||
BITS xor = (BITS) pPriv->xor;
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
bits =
|
||||
((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
|
||||
bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
|
||||
if (signdy < 0)
|
||||
bitsStride = -bitsStride;
|
||||
if (axis == X_AXIS) {
|
||||
majorStep = signdx * MUL;
|
||||
minorStep = bitsStride;
|
||||
}
|
||||
else {
|
||||
majorStep = bitsStride;
|
||||
minorStep = signdx * MUL;
|
||||
}
|
||||
while (len--) {
|
||||
STORE(bits, xor);
|
||||
bits += majorStep;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
bits += minorStep;
|
||||
e += e3;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BRESDASH
|
||||
void
|
||||
BRESDASH(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int dashOffset,
|
||||
int signdx,
|
||||
int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len)
|
||||
{
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
UNIT *bits;
|
||||
|
||||
FbStride bitsStride;
|
||||
|
||||
FbStride majorStep, minorStep;
|
||||
|
||||
BITS xorfg, xorbg;
|
||||
|
||||
FbDashDeclare;
|
||||
int dashlen;
|
||||
|
||||
Bool even;
|
||||
|
||||
Bool doOdd;
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
doOdd = pGC->lineStyle == LineDoubleDash;
|
||||
xorfg = (BITS) pPriv->xor;
|
||||
xorbg = (BITS) pPriv->bgxor;
|
||||
|
||||
FbDashInit(pGC, pPriv, dashOffset, dashlen, even);
|
||||
|
||||
bits =
|
||||
((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
|
||||
bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
|
||||
if (signdy < 0)
|
||||
bitsStride = -bitsStride;
|
||||
if (axis == X_AXIS) {
|
||||
majorStep = signdx * MUL;
|
||||
minorStep = bitsStride;
|
||||
}
|
||||
else {
|
||||
majorStep = bitsStride;
|
||||
minorStep = signdx * MUL;
|
||||
}
|
||||
if (dashlen >= len)
|
||||
dashlen = len;
|
||||
if (doOdd) {
|
||||
if (!even)
|
||||
goto doubleOdd;
|
||||
for (;;) {
|
||||
len -= dashlen;
|
||||
while (dashlen--) {
|
||||
STORE(bits, xorfg);
|
||||
bits += majorStep;
|
||||
if ((e += e1) >= 0) {
|
||||
e += e3;
|
||||
bits += minorStep;
|
||||
}
|
||||
}
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
FbDashNextEven(dashlen);
|
||||
|
||||
if (dashlen >= len)
|
||||
dashlen = len;
|
||||
doubleOdd:
|
||||
len -= dashlen;
|
||||
while (dashlen--) {
|
||||
STORE(bits, xorbg);
|
||||
bits += majorStep;
|
||||
if ((e += e1) >= 0) {
|
||||
e += e3;
|
||||
bits += minorStep;
|
||||
}
|
||||
}
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
FbDashNextOdd(dashlen);
|
||||
|
||||
if (dashlen >= len)
|
||||
dashlen = len;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!even)
|
||||
goto onOffOdd;
|
||||
for (;;) {
|
||||
len -= dashlen;
|
||||
while (dashlen--) {
|
||||
STORE(bits, xorfg);
|
||||
bits += majorStep;
|
||||
if ((e += e1) >= 0) {
|
||||
e += e3;
|
||||
bits += minorStep;
|
||||
}
|
||||
}
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
FbDashNextEven(dashlen);
|
||||
|
||||
if (dashlen >= len)
|
||||
dashlen = len;
|
||||
onOffOdd:
|
||||
len -= dashlen;
|
||||
while (dashlen--) {
|
||||
bits += majorStep;
|
||||
if ((e += e1) >= 0) {
|
||||
e += e3;
|
||||
bits += minorStep;
|
||||
}
|
||||
}
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
FbDashNextOdd(dashlen);
|
||||
|
||||
if (dashlen >= len)
|
||||
dashlen = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DOTS
|
||||
void
|
||||
DOTS(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstBpp,
|
||||
BoxPtr pBox,
|
||||
xPoint * ptsOrig,
|
||||
int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor)
|
||||
{
|
||||
INT32 *pts = (INT32 *) ptsOrig;
|
||||
|
||||
UNIT *bits = (UNIT *) dst;
|
||||
|
||||
UNIT *point;
|
||||
|
||||
BITS bxor = (BITS) xor;
|
||||
|
||||
BITS band = (BITS) and;
|
||||
|
||||
FbStride bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
|
||||
|
||||
INT32 ul, lr;
|
||||
|
||||
INT32 pt;
|
||||
|
||||
ul = coordToInt(pBox->x1 - xorg, pBox->y1 - yorg);
|
||||
lr = coordToInt(pBox->x2 - xorg - 1, pBox->y2 - yorg - 1);
|
||||
|
||||
bits += bitsStride * (yorg + yoff) + (xorg + xoff) * MUL;
|
||||
|
||||
if (and == 0) {
|
||||
while (npt--) {
|
||||
pt = *pts++;
|
||||
if (!isClipped(pt, ul, lr)) {
|
||||
point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
|
||||
STORE(point, bxor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (npt--) {
|
||||
pt = *pts++;
|
||||
if (!isClipped(pt, ul, lr)) {
|
||||
point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
|
||||
RROP(point, band, bxor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ARC
|
||||
|
||||
#define ARCCOPY(d) STORE(d,xorBits)
|
||||
#define ARCRROP(d) RROP(d,andBits,xorBits)
|
||||
|
||||
void
|
||||
ARC(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstBpp, xArc * arc, int drawX, int drawY, FbBits and, FbBits xor)
|
||||
{
|
||||
UNIT *bits;
|
||||
|
||||
FbStride bitsStride;
|
||||
|
||||
miZeroArcRec info;
|
||||
|
||||
Bool do360;
|
||||
|
||||
int x;
|
||||
|
||||
UNIT *yorgp, *yorgop;
|
||||
|
||||
BITS andBits, xorBits;
|
||||
|
||||
int yoffset, dyoffset;
|
||||
|
||||
int y, a, b, d, mask;
|
||||
|
||||
int k1, k3, dx, dy;
|
||||
|
||||
bits = (UNIT *) dst;
|
||||
bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
|
||||
andBits = (BITS) and;
|
||||
xorBits = (BITS) xor;
|
||||
do360 = miZeroArcSetup(arc, &info, TRUE);
|
||||
yorgp = bits + ((info.yorg + drawY) * bitsStride);
|
||||
yorgop = bits + ((info.yorgo + drawY) * bitsStride);
|
||||
info.xorg = (info.xorg + drawX) * MUL;
|
||||
info.xorgo = (info.xorgo + drawX) * MUL;
|
||||
MIARCSETUP();
|
||||
yoffset = y ? bitsStride : 0;
|
||||
dyoffset = 0;
|
||||
mask = info.initialMask;
|
||||
|
||||
if (!(arc->width & 1)) {
|
||||
if (andBits == 0) {
|
||||
if (mask & 2)
|
||||
ARCCOPY(yorgp + info.xorgo);
|
||||
if (mask & 8)
|
||||
ARCCOPY(yorgop + info.xorgo);
|
||||
}
|
||||
else {
|
||||
if (mask & 2)
|
||||
ARCRROP(yorgp + info.xorgo);
|
||||
if (mask & 8)
|
||||
ARCRROP(yorgop + info.xorgo);
|
||||
}
|
||||
}
|
||||
if (!info.end.x || !info.end.y) {
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
|
||||
int xoffset = bitsStride;
|
||||
|
||||
UNIT *yorghb = yorgp + (info.h * bitsStride) + info.xorg;
|
||||
|
||||
UNIT *yorgohb = yorghb - info.h * MUL;
|
||||
|
||||
yorgp += info.xorg;
|
||||
yorgop += info.xorg;
|
||||
yorghb += info.h * MUL;
|
||||
while (1) {
|
||||
if (andBits == 0) {
|
||||
ARCCOPY(yorgp + yoffset + x * MUL);
|
||||
ARCCOPY(yorgp + yoffset - x * MUL);
|
||||
ARCCOPY(yorgop - yoffset - x * MUL);
|
||||
ARCCOPY(yorgop - yoffset + x * MUL);
|
||||
}
|
||||
else {
|
||||
ARCRROP(yorgp + yoffset + x * MUL);
|
||||
ARCRROP(yorgp + yoffset - x * MUL);
|
||||
ARCRROP(yorgop - yoffset - x * MUL);
|
||||
ARCRROP(yorgop - yoffset + x * MUL);
|
||||
}
|
||||
if (a < 0)
|
||||
break;
|
||||
if (andBits == 0) {
|
||||
ARCCOPY(yorghb - xoffset - y * MUL);
|
||||
ARCCOPY(yorgohb - xoffset + y * MUL);
|
||||
ARCCOPY(yorgohb + xoffset + y * MUL);
|
||||
ARCCOPY(yorghb + xoffset - y * MUL);
|
||||
}
|
||||
else {
|
||||
ARCRROP(yorghb - xoffset - y * MUL);
|
||||
ARCRROP(yorgohb - xoffset + y * MUL);
|
||||
ARCRROP(yorgohb + xoffset + y * MUL);
|
||||
ARCRROP(yorghb + xoffset - y * MUL);
|
||||
}
|
||||
xoffset += bitsStride;
|
||||
MIARCCIRCLESTEP(yoffset += bitsStride;
|
||||
);
|
||||
}
|
||||
yorgp -= info.xorg;
|
||||
yorgop -= info.xorg;
|
||||
x = info.w;
|
||||
yoffset = info.h * bitsStride;
|
||||
}
|
||||
else if (do360) {
|
||||
while (y < info.h || x < info.w) {
|
||||
MIARCOCTANTSHIFT(dyoffset = bitsStride;
|
||||
);
|
||||
if (andBits == 0) {
|
||||
ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
|
||||
ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
|
||||
ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
|
||||
ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
|
||||
}
|
||||
else {
|
||||
ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
|
||||
ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
|
||||
ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
|
||||
ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
|
||||
}
|
||||
MIARCSTEP(yoffset += dyoffset;
|
||||
, yoffset += bitsStride;
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (y < info.h || x < info.w) {
|
||||
MIARCOCTANTSHIFT(dyoffset = bitsStride;
|
||||
);
|
||||
if ((x == info.start.x) || (y == info.start.y)) {
|
||||
mask = info.start.mask;
|
||||
info.start = info.altstart;
|
||||
}
|
||||
if (andBits == 0) {
|
||||
if (mask & 1)
|
||||
ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
|
||||
if (mask & 2)
|
||||
ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
|
||||
if (mask & 4)
|
||||
ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
|
||||
if (mask & 8)
|
||||
ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
|
||||
}
|
||||
else {
|
||||
if (mask & 1)
|
||||
ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
|
||||
if (mask & 2)
|
||||
ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
|
||||
if (mask & 4)
|
||||
ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
|
||||
if (mask & 8)
|
||||
ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
|
||||
}
|
||||
if ((x == info.end.x) || (y == info.end.y)) {
|
||||
mask = info.end.mask;
|
||||
info.end = info.altend;
|
||||
}
|
||||
MIARCSTEP(yoffset += dyoffset;
|
||||
, yoffset += bitsStride;
|
||||
);
|
||||
}
|
||||
}
|
||||
if ((x == info.start.x) || (y == info.start.y))
|
||||
mask = info.start.mask;
|
||||
if (andBits == 0) {
|
||||
if (mask & 1)
|
||||
ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
|
||||
if (mask & 4)
|
||||
ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
|
||||
if (arc->height & 1) {
|
||||
if (mask & 2)
|
||||
ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
|
||||
if (mask & 8)
|
||||
ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mask & 1)
|
||||
ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
|
||||
if (mask & 4)
|
||||
ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
|
||||
if (arc->height & 1) {
|
||||
if (mask & 2)
|
||||
ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
|
||||
if (mask & 8)
|
||||
ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef ARCCOPY
|
||||
#undef ARCRROP
|
||||
#endif
|
||||
|
||||
#ifdef GLYPH
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
# define WRITE_ADDR1(n) (n)
|
||||
# define WRITE_ADDR2(n) (n)
|
||||
# define WRITE_ADDR4(n) (n)
|
||||
#else
|
||||
# define WRITE_ADDR1(n) ((n) ^ 3)
|
||||
# define WRITE_ADDR2(n) ((n) ^ 2)
|
||||
# define WRITE_ADDR4(n) ((n))
|
||||
#endif
|
||||
|
||||
#define WRITE1(d,n,fg) ((d)[WRITE_ADDR1(n)] = (BITS) (fg))
|
||||
|
||||
#ifdef BITS2
|
||||
# define WRITE2(d,n,fg) (*((BITS2 *) &((d)[WRITE_ADDR2(n)])) = (BITS2) (fg))
|
||||
#else
|
||||
# define WRITE2(d,n,fg) WRITE1(d,(n)+1,WRITE1(d,n,fg))
|
||||
#endif
|
||||
|
||||
#ifdef BITS4
|
||||
# define WRITE4(d,n,fg) (*((BITS4 *) &((d)[WRITE_ADDR4(n)])) = (BITS4) (fg))
|
||||
#else
|
||||
# define WRITE4(d,n,fg) WRITE2(d,(n)+2,WRITE2(d,n,fg))
|
||||
#endif
|
||||
|
||||
void
|
||||
GLYPH(FbBits * dstBits,
|
||||
FbStride dstStride,
|
||||
int dstBpp, FbStip * stipple, FbBits fg, int x, int height)
|
||||
{
|
||||
int lshift;
|
||||
|
||||
FbStip bits;
|
||||
|
||||
BITS *dstLine;
|
||||
|
||||
BITS *dst;
|
||||
|
||||
int n;
|
||||
|
||||
int shift;
|
||||
|
||||
dstLine = (BITS *) dstBits;
|
||||
dstLine += x & ~3;
|
||||
dstStride *= (sizeof(FbBits) / sizeof(BITS));
|
||||
shift = x & 3;
|
||||
lshift = 4 - shift;
|
||||
while (height--) {
|
||||
bits = *stipple++;
|
||||
dst = (BITS *) dstLine;
|
||||
n = lshift;
|
||||
while (bits) {
|
||||
switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
WRITE1(dst, 0, fg);
|
||||
break;
|
||||
case 2:
|
||||
WRITE1(dst, 1, fg);
|
||||
break;
|
||||
case 3:
|
||||
WRITE2(dst, 0, fg);
|
||||
break;
|
||||
case 4:
|
||||
WRITE1(dst, 2, fg);
|
||||
break;
|
||||
case 5:
|
||||
WRITE1(dst, 0, fg);
|
||||
WRITE1(dst, 2, fg);
|
||||
break;
|
||||
case 6:
|
||||
WRITE1(dst, 1, fg);
|
||||
WRITE1(dst, 2, fg);
|
||||
break;
|
||||
case 7:
|
||||
WRITE2(dst, 0, fg);
|
||||
WRITE1(dst, 2, fg);
|
||||
break;
|
||||
case 8:
|
||||
WRITE1(dst, 3, fg);
|
||||
break;
|
||||
case 9:
|
||||
WRITE1(dst, 0, fg);
|
||||
WRITE1(dst, 3, fg);
|
||||
break;
|
||||
case 10:
|
||||
WRITE1(dst, 1, fg);
|
||||
WRITE1(dst, 3, fg);
|
||||
break;
|
||||
case 11:
|
||||
WRITE2(dst, 0, fg);
|
||||
WRITE1(dst, 3, fg);
|
||||
break;
|
||||
case 12:
|
||||
WRITE2(dst, 2, fg);
|
||||
break;
|
||||
case 13:
|
||||
WRITE1(dst, 0, fg);
|
||||
WRITE2(dst, 2, fg);
|
||||
break;
|
||||
case 14:
|
||||
WRITE1(dst, 1, fg);
|
||||
WRITE2(dst, 2, fg);
|
||||
break;
|
||||
case 15:
|
||||
WRITE4(dst, 0, fg);
|
||||
break;
|
||||
}
|
||||
bits = FbStipLeft(bits, n);
|
||||
n = 4;
|
||||
dst += 4;
|
||||
}
|
||||
dstLine += dstStride;
|
||||
}
|
||||
}
|
||||
|
||||
#undef WRITE_ADDR1
|
||||
#undef WRITE_ADDR2
|
||||
#undef WRITE_ADDR4
|
||||
#undef WRITE1
|
||||
#undef WRITE2
|
||||
#undef WRITE4
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef POLYLINE
|
||||
void
|
||||
POLYLINE(DrawablePtr pDrawable,
|
||||
GCPtr pGC, int mode, int npt, DDXPointPtr ptsOrig)
|
||||
{
|
||||
INT32 *pts = (INT32 *) ptsOrig;
|
||||
|
||||
int xoff = pDrawable->x;
|
||||
|
||||
int yoff = pDrawable->y;
|
||||
|
||||
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
|
||||
|
||||
BoxPtr pBox = REGION_EXTENTS(fbGetCompositeClip(pGC));
|
||||
|
||||
FbBits *dst;
|
||||
|
||||
int dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
UNIT *bits, *bitsBase;
|
||||
|
||||
FbStride bitsStride;
|
||||
|
||||
BITS xor = fbGetGCPrivate(pGC)->xor;
|
||||
|
||||
BITS and = fbGetGCPrivate(pGC)->and;
|
||||
|
||||
int dashoffset = 0;
|
||||
|
||||
INT32 ul, lr;
|
||||
|
||||
INT32 pt1, pt2;
|
||||
|
||||
int e, e1, e3, len;
|
||||
|
||||
int stepmajor, stepminor;
|
||||
|
||||
int octant;
|
||||
|
||||
if (mode == CoordModePrevious)
|
||||
fbFixCoordModePrevious(npt, ptsOrig);
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
|
||||
bitsBase =
|
||||
((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
|
||||
ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
|
||||
lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
|
||||
|
||||
pt1 = *pts++;
|
||||
npt--;
|
||||
pt2 = *pts++;
|
||||
npt--;
|
||||
for (;;) {
|
||||
if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) {
|
||||
fbSegment(pDrawable, pGC,
|
||||
intToX(pt1) + xoff, intToY(pt1) + yoff,
|
||||
intToX(pt2) + xoff, intToY(pt2) + yoff,
|
||||
npt == 0 && pGC->capStyle != CapNotLast, &dashoffset);
|
||||
if (!npt)
|
||||
return;
|
||||
pt1 = pt2;
|
||||
pt2 = *pts++;
|
||||
npt--;
|
||||
}
|
||||
else {
|
||||
bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
|
||||
for (;;) {
|
||||
CalcLineDeltas(intToX(pt1), intToY(pt1),
|
||||
intToX(pt2), intToY(pt2),
|
||||
len, e1, stepmajor, stepminor, 1, bitsStride,
|
||||
octant);
|
||||
stepmajor *= MUL;
|
||||
if (len < e1) {
|
||||
e3 = len;
|
||||
len = e1;
|
||||
e1 = e3;
|
||||
|
||||
e3 = stepminor;
|
||||
stepminor = stepmajor;
|
||||
stepmajor = e3;
|
||||
SetYMajorOctant(octant);
|
||||
}
|
||||
e = -len;
|
||||
e1 <<= 1;
|
||||
e3 = e << 1;
|
||||
FIXUP_ERROR(e, octant, bias);
|
||||
if (and == 0) {
|
||||
while (len--) {
|
||||
STORE(bits, xor);
|
||||
bits += stepmajor;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
bits += stepminor;
|
||||
e += e3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (len--) {
|
||||
RROP(bits, and, xor);
|
||||
bits += stepmajor;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
bits += stepminor;
|
||||
e += e3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!npt) {
|
||||
if (pGC->capStyle != CapNotLast &&
|
||||
pt2 != *((INT32 *) ptsOrig)) {
|
||||
RROP(bits, and, xor);
|
||||
}
|
||||
return;
|
||||
}
|
||||
pt1 = pt2;
|
||||
pt2 = *pts++;
|
||||
--npt;
|
||||
if (isClipped(pt2, ul, lr))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef POLYSEGMENT
|
||||
void
|
||||
POLYSEGMENT(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg)
|
||||
{
|
||||
INT32 *pts = (INT32 *) pseg;
|
||||
|
||||
int xoff = pDrawable->x;
|
||||
|
||||
int yoff = pDrawable->y;
|
||||
|
||||
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
|
||||
|
||||
BoxPtr pBox = REGION_EXTENTS(fbGetCompositeClip(pGC));
|
||||
|
||||
FbBits *dst;
|
||||
|
||||
int dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
UNIT *bits, *bitsBase;
|
||||
|
||||
FbStride bitsStride;
|
||||
|
||||
FbBits xorBits = fbGetGCPrivate(pGC)->xor;
|
||||
|
||||
FbBits andBits = fbGetGCPrivate(pGC)->and;
|
||||
|
||||
BITS xor = xorBits;
|
||||
|
||||
BITS and = andBits;
|
||||
|
||||
int dashoffset = 0;
|
||||
|
||||
INT32 ul, lr;
|
||||
|
||||
INT32 pt1, pt2;
|
||||
|
||||
int e, e1, e3, len;
|
||||
|
||||
int stepmajor, stepminor;
|
||||
|
||||
int octant;
|
||||
|
||||
Bool capNotLast;
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
|
||||
bitsBase =
|
||||
((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
|
||||
ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
|
||||
lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
|
||||
|
||||
capNotLast = pGC->capStyle == CapNotLast;
|
||||
|
||||
while (nseg--) {
|
||||
pt1 = *pts++;
|
||||
pt2 = *pts++;
|
||||
if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) {
|
||||
fbSegment(pDrawable, pGC,
|
||||
intToX(pt1) + xoff, intToY(pt1) + yoff,
|
||||
intToX(pt2) + xoff, intToY(pt2) + yoff,
|
||||
!capNotLast, &dashoffset);
|
||||
}
|
||||
else {
|
||||
CalcLineDeltas(intToX(pt1), intToY(pt1),
|
||||
intToX(pt2), intToY(pt2),
|
||||
len, e1, stepmajor, stepminor, 1, bitsStride,
|
||||
octant);
|
||||
if (e1 == 0 && len > 3
|
||||
#if MUL != 1
|
||||
&& FbCheck24Pix(and) && FbCheck24Pix(xor)
|
||||
#endif
|
||||
) {
|
||||
int x1, x2;
|
||||
|
||||
FbBits *dstLine;
|
||||
|
||||
int dstX, width;
|
||||
|
||||
FbBits startmask, endmask;
|
||||
|
||||
int nmiddle;
|
||||
|
||||
if (stepmajor < 0) {
|
||||
x1 = intToX(pt2);
|
||||
x2 = intToX(pt1) + 1;
|
||||
if (capNotLast)
|
||||
x1++;
|
||||
}
|
||||
else {
|
||||
x1 = intToX(pt1);
|
||||
x2 = intToX(pt2);
|
||||
if (!capNotLast)
|
||||
x2++;
|
||||
}
|
||||
dstX = (x1 + xoff + dstXoff) * (sizeof(UNIT) * 8 * MUL);
|
||||
width = (x2 - x1) * (sizeof(UNIT) * 8 * MUL);
|
||||
|
||||
dstLine = dst + (intToY(pt1) + yoff + dstYoff) * dstStride;
|
||||
dstLine += dstX >> FB_SHIFT;
|
||||
dstX &= FB_MASK;
|
||||
FbMaskBits(dstX, width, startmask, nmiddle, endmask);
|
||||
if (startmask) {
|
||||
*dstLine =
|
||||
FbDoMaskRRop(*dstLine, andBits, xorBits, startmask);
|
||||
dstLine++;
|
||||
}
|
||||
if (!andBits)
|
||||
while (nmiddle--)
|
||||
*dstLine++ = xorBits;
|
||||
else
|
||||
while (nmiddle--) {
|
||||
*dstLine = FbDoRRop(*dstLine, andBits, xorBits);
|
||||
dstLine++;
|
||||
}
|
||||
if (endmask)
|
||||
*dstLine =
|
||||
FbDoMaskRRop(*dstLine, andBits, xorBits, endmask);
|
||||
}
|
||||
else {
|
||||
stepmajor *= MUL;
|
||||
bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
|
||||
if (len < e1) {
|
||||
e3 = len;
|
||||
len = e1;
|
||||
e1 = e3;
|
||||
|
||||
e3 = stepminor;
|
||||
stepminor = stepmajor;
|
||||
stepmajor = e3;
|
||||
SetYMajorOctant(octant);
|
||||
}
|
||||
e = -len;
|
||||
e1 <<= 1;
|
||||
e3 = e << 1;
|
||||
FIXUP_ERROR(e, octant, bias);
|
||||
if (!capNotLast)
|
||||
len++;
|
||||
if (and == 0) {
|
||||
while (len--) {
|
||||
STORE(bits, xor);
|
||||
bits += stepmajor;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
bits += stepminor;
|
||||
e += e3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (len--) {
|
||||
RROP(bits, and, xor);
|
||||
bits += stepmajor;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
bits += stepminor;
|
||||
e += e3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef MUL
|
||||
#undef STORE
|
||||
#undef RROP
|
||||
#undef UNIT
|
||||
#undef USE_SOLID
|
||||
|
||||
#undef isClipped
|
|
@ -0,0 +1,818 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "fb.h"
|
||||
|
||||
#define InitializeShifts(sx,dx,ls,rs) { \
|
||||
if (sx != dx) { \
|
||||
if (sx > dx) { \
|
||||
ls = sx - dx; \
|
||||
rs = FB_UNIT - ls; \
|
||||
} else { \
|
||||
rs = dx - sx; \
|
||||
ls = FB_UNIT - rs; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
fbBlt(FbBits * srcLine,
|
||||
FbStride srcStride,
|
||||
int srcX,
|
||||
FbBits * dstLine,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int width,
|
||||
int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown)
|
||||
{
|
||||
FbBits *src, *dst;
|
||||
int leftShift, rightShift;
|
||||
FbBits startmask, endmask;
|
||||
FbBits bits, bits1;
|
||||
int n, nmiddle;
|
||||
Bool destInvarient;
|
||||
int careful;
|
||||
int startbyte, endbyte;
|
||||
|
||||
FbDeclareMergeRop();
|
||||
|
||||
if (bpp == 24 && !FbCheck24Pix(pm)) {
|
||||
fbBlt24(srcLine, srcStride, srcX, dstLine, dstStride, dstX,
|
||||
width, height, alu, pm, reverse, upsidedown);
|
||||
return;
|
||||
}
|
||||
|
||||
careful = !((srcLine < dstLine && srcLine + width * (bpp>>3) > dstLine) ||
|
||||
(dstLine < srcLine && dstLine + width * (bpp>>3) > srcLine)) ||
|
||||
(bpp & 7);
|
||||
|
||||
if (alu == GXcopy && pm == FB_ALLONES && !careful &&
|
||||
!(srcX & 7) && !(dstX & 7) && !(width & 7)) {
|
||||
int i;
|
||||
CARD8 *tmpsrc = (CARD8 *) srcLine;
|
||||
CARD8 *tmpdst = (CARD8 *) dstLine;
|
||||
|
||||
srcStride *= sizeof(FbBits);
|
||||
dstStride *= sizeof(FbBits);
|
||||
width >>= 3;
|
||||
tmpsrc += (srcX >> 3);
|
||||
tmpdst += (dstX >> 3);
|
||||
|
||||
if (!upsidedown)
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy(tmpdst + i * dstStride, tmpsrc + i * srcStride, width);
|
||||
else
|
||||
for (i = height - 1; i >= 0; i--)
|
||||
memcpy(tmpdst + i * dstStride, tmpsrc + i * srcStride, width);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FbInitializeMergeRop(alu, pm);
|
||||
destInvarient = FbDestInvarientMergeRop();
|
||||
if (upsidedown) {
|
||||
srcLine += (height - 1) * (srcStride);
|
||||
dstLine += (height - 1) * (dstStride);
|
||||
srcStride = -srcStride;
|
||||
dstStride = -dstStride;
|
||||
}
|
||||
FbMaskBitsBytes(dstX, width, destInvarient, startmask, startbyte,
|
||||
nmiddle, endmask, endbyte);
|
||||
if (reverse) {
|
||||
srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
|
||||
dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
|
||||
srcX = (srcX + width - 1) & FB_MASK;
|
||||
dstX = (dstX + width - 1) & FB_MASK;
|
||||
}
|
||||
else {
|
||||
srcLine += srcX >> FB_SHIFT;
|
||||
dstLine += dstX >> FB_SHIFT;
|
||||
srcX &= FB_MASK;
|
||||
dstX &= FB_MASK;
|
||||
}
|
||||
if (srcX == dstX) {
|
||||
while (height--) {
|
||||
src = srcLine;
|
||||
srcLine += srcStride;
|
||||
dst = dstLine;
|
||||
dstLine += dstStride;
|
||||
if (reverse) {
|
||||
if (endmask) {
|
||||
bits = *--src;
|
||||
--dst;
|
||||
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient) {
|
||||
while (n--)
|
||||
*--dst = FbDoDestInvarientMergeRop(*--src);
|
||||
}
|
||||
else {
|
||||
while (n--) {
|
||||
bits = *--src;
|
||||
--dst;
|
||||
*dst = FbDoMergeRop(bits, *dst);
|
||||
}
|
||||
}
|
||||
if (startmask) {
|
||||
bits = *--src;
|
||||
--dst;
|
||||
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (startmask) {
|
||||
bits = *src++;
|
||||
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient) {
|
||||
#if 0
|
||||
/*
|
||||
* This provides some speedup on screen->screen blts
|
||||
* over the PCI bus, usually about 10%. But fb
|
||||
* isn't usually used for this operation...
|
||||
*/
|
||||
if (_ca2 + 1 == 0 && _cx2 == 0) {
|
||||
FbBits t1, t2, t3, t4;
|
||||
|
||||
while (n >= 4) {
|
||||
t1 = *src++;
|
||||
t2 = *src++;
|
||||
t3 = *src++;
|
||||
t4 = *src++;
|
||||
*dst++ = t1;
|
||||
*dst++ = t2;
|
||||
*dst++ = t3;
|
||||
*dst++ = t4;
|
||||
n -= 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while (n--)
|
||||
*dst++ = FbDoDestInvarientMergeRop(*src++);
|
||||
}
|
||||
else {
|
||||
while (n--) {
|
||||
bits = *src++;
|
||||
*dst = FbDoMergeRop(bits, *dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
if (endmask) {
|
||||
bits = *src;
|
||||
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (srcX > dstX) {
|
||||
leftShift = srcX - dstX;
|
||||
rightShift = FB_UNIT - leftShift;
|
||||
}
|
||||
else {
|
||||
rightShift = dstX - srcX;
|
||||
leftShift = FB_UNIT - rightShift;
|
||||
}
|
||||
while (height--) {
|
||||
src = srcLine;
|
||||
srcLine += srcStride;
|
||||
dst = dstLine;
|
||||
dstLine += dstStride;
|
||||
|
||||
bits1 = 0;
|
||||
if (reverse) {
|
||||
if (srcX < dstX)
|
||||
bits1 = *--src;
|
||||
if (endmask) {
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
if (FbScrRight(endmask, leftShift)) {
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
}
|
||||
--dst;
|
||||
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient) {
|
||||
while (n--) {
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
--dst;
|
||||
*dst = FbDoDestInvarientMergeRop(bits);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (n--) {
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
--dst;
|
||||
*dst = FbDoMergeRop(bits, *dst);
|
||||
}
|
||||
}
|
||||
if (startmask) {
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
if (FbScrRight(startmask, leftShift)) {
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
}
|
||||
--dst;
|
||||
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (srcX > dstX)
|
||||
bits1 = *src++;
|
||||
if (startmask) {
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
if (FbScrLeft(startmask, rightShift)) {
|
||||
bits1 = *src++;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
}
|
||||
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient) {
|
||||
while (n--) {
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
bits1 = *src++;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
*dst = FbDoDestInvarientMergeRop(bits);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (n--) {
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
bits1 = *src++;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
*dst = FbDoMergeRop(bits, *dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
if (endmask) {
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
if (FbScrLeft(endmask, rightShift)) {
|
||||
bits1 = *src;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
}
|
||||
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#undef DEBUG_BLT24
|
||||
#ifdef DEBUG_BLT24
|
||||
|
||||
static unsigned long
|
||||
getPixel(char *src, int x)
|
||||
{
|
||||
unsigned long l;
|
||||
|
||||
l = 0;
|
||||
memcpy(&l, src + x * 3, 3);
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
fbBlt24Line(FbBits * src,
|
||||
int srcX,
|
||||
FbBits * dst, int dstX, int width, int alu, FbBits pm, Bool reverse)
|
||||
{
|
||||
#ifdef DEBUG_BLT24
|
||||
char *origDst = (char *) dst;
|
||||
|
||||
FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1);
|
||||
|
||||
int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3;
|
||||
|
||||
int origX = dstX / 24;
|
||||
#endif
|
||||
|
||||
int leftShift, rightShift;
|
||||
|
||||
FbBits startmask, endmask;
|
||||
|
||||
int n;
|
||||
|
||||
FbBits bits, bits1;
|
||||
|
||||
FbBits mask;
|
||||
|
||||
int rot;
|
||||
|
||||
FbDeclareMergeRop();
|
||||
|
||||
FbInitializeMergeRop(alu, FB_ALLONES);
|
||||
FbMaskBits(dstX, width, startmask, n, endmask);
|
||||
#ifdef DEBUG_BLT24
|
||||
ErrorF("dstX %d width %d reverse %d\n", dstX, width, reverse);
|
||||
#endif
|
||||
if (reverse) {
|
||||
src += ((srcX + width - 1) >> FB_SHIFT) + 1;
|
||||
dst += ((dstX + width - 1) >> FB_SHIFT) + 1;
|
||||
rot = FbFirst24Rot(((dstX + width - 8) & FB_MASK));
|
||||
rot = FbPrev24Rot(rot);
|
||||
#ifdef DEBUG_BLT24
|
||||
ErrorF("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK,
|
||||
rot);
|
||||
#endif
|
||||
srcX = (srcX + width - 1) & FB_MASK;
|
||||
dstX = (dstX + width - 1) & FB_MASK;
|
||||
}
|
||||
else {
|
||||
src += srcX >> FB_SHIFT;
|
||||
dst += dstX >> FB_SHIFT;
|
||||
srcX &= FB_MASK;
|
||||
dstX &= FB_MASK;
|
||||
rot = FbFirst24Rot(dstX);
|
||||
#ifdef DEBUG_BLT24
|
||||
ErrorF("dstX: %d rot: %d\n", dstX, rot);
|
||||
#endif
|
||||
}
|
||||
mask = FbRot24(pm, rot);
|
||||
#ifdef DEBUG_BLT24
|
||||
ErrorF("pm 0x%x mask 0x%x\n", pm, mask);
|
||||
#endif
|
||||
if (srcX == dstX) {
|
||||
if (reverse) {
|
||||
if (endmask) {
|
||||
bits = *--src;
|
||||
--dst;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask & endmask);
|
||||
mask = FbPrev24Pix(mask);
|
||||
}
|
||||
while (n--) {
|
||||
bits = *--src;
|
||||
--dst;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask);
|
||||
mask = FbPrev24Pix(mask);
|
||||
}
|
||||
if (startmask) {
|
||||
bits = *--src;
|
||||
--dst;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask & startmask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (startmask) {
|
||||
bits = *src++;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask & startmask);
|
||||
dst++;
|
||||
mask = FbNext24Pix(mask);
|
||||
}
|
||||
while (n--) {
|
||||
bits = *src++;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask);
|
||||
dst++;
|
||||
mask = FbNext24Pix(mask);
|
||||
}
|
||||
if (endmask) {
|
||||
bits = *src;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask & endmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (srcX > dstX) {
|
||||
leftShift = srcX - dstX;
|
||||
rightShift = FB_UNIT - leftShift;
|
||||
}
|
||||
else {
|
||||
rightShift = dstX - srcX;
|
||||
leftShift = FB_UNIT - rightShift;
|
||||
}
|
||||
|
||||
bits1 = 0;
|
||||
if (reverse) {
|
||||
if (srcX < dstX)
|
||||
bits1 = *--src;
|
||||
if (endmask) {
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
if (FbScrRight(endmask, leftShift)) {
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
}
|
||||
--dst;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask & endmask);
|
||||
mask = FbPrev24Pix(mask);
|
||||
}
|
||||
while (n--) {
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
--dst;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask);
|
||||
mask = FbPrev24Pix(mask);
|
||||
}
|
||||
if (startmask) {
|
||||
bits = FbScrRight(bits1, rightShift);
|
||||
if (FbScrRight(startmask, leftShift)) {
|
||||
bits1 = *--src;
|
||||
bits |= FbScrLeft(bits1, leftShift);
|
||||
}
|
||||
--dst;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask & startmask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (srcX > dstX)
|
||||
bits1 = *src++;
|
||||
if (startmask) {
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
bits1 = *src++;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask & startmask);
|
||||
dst++;
|
||||
mask = FbNext24Pix(mask);
|
||||
}
|
||||
while (n--) {
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
bits1 = *src++;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask);
|
||||
dst++;
|
||||
mask = FbNext24Pix(mask);
|
||||
}
|
||||
if (endmask) {
|
||||
bits = FbScrLeft(bits1, leftShift);
|
||||
if (FbScrLeft(endmask, rightShift)) {
|
||||
bits1 = *src;
|
||||
bits |= FbScrRight(bits1, rightShift);
|
||||
}
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, mask & endmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_BLT24
|
||||
{
|
||||
int firstx, lastx, x;
|
||||
|
||||
firstx = origX;
|
||||
if (firstx)
|
||||
firstx--;
|
||||
lastx = origX + width / 24 + 1;
|
||||
for (x = firstx; x <= lastx; x++)
|
||||
ErrorF("%06x ", getPixel(origDst, x));
|
||||
ErrorF("\n");
|
||||
while (origNlw--)
|
||||
ErrorF("%08x ", *origLine++);
|
||||
ErrorF("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
fbBlt24(FbBits * srcLine,
|
||||
FbStride srcStride,
|
||||
int srcX,
|
||||
FbBits * dstLine,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int width,
|
||||
int height, int alu, FbBits pm, Bool reverse, Bool upsidedown)
|
||||
{
|
||||
if (upsidedown) {
|
||||
srcLine += (height - 1) * srcStride;
|
||||
dstLine += (height - 1) * dstStride;
|
||||
srcStride = -srcStride;
|
||||
dstStride = -dstStride;
|
||||
}
|
||||
while (height--) {
|
||||
fbBlt24Line(srcLine, srcX, dstLine, dstX, width, alu, pm, reverse);
|
||||
srcLine += srcStride;
|
||||
dstLine += dstStride;
|
||||
}
|
||||
#ifdef DEBUG_BLT24
|
||||
ErrorF("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if FB_SHIFT == FB_STIP_SHIFT + 1
|
||||
|
||||
/*
|
||||
* Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by
|
||||
* creating an ring of values stepped through for each line
|
||||
*/
|
||||
|
||||
void
|
||||
fbBltOdd(FbBits * srcLine,
|
||||
FbStride srcStrideEven,
|
||||
FbStride srcStrideOdd,
|
||||
int srcXEven,
|
||||
int srcXOdd,
|
||||
FbBits * dstLine,
|
||||
FbStride dstStrideEven,
|
||||
FbStride dstStrideOdd,
|
||||
int dstXEven,
|
||||
int dstXOdd, int width, int height, int alu, FbBits pm, int bpp)
|
||||
{
|
||||
FbBits *src;
|
||||
|
||||
int leftShiftEven, rightShiftEven;
|
||||
|
||||
FbBits startmaskEven, endmaskEven;
|
||||
|
||||
int nmiddleEven;
|
||||
|
||||
FbBits *dst;
|
||||
|
||||
int leftShiftOdd, rightShiftOdd;
|
||||
|
||||
FbBits startmaskOdd, endmaskOdd;
|
||||
|
||||
int nmiddleOdd;
|
||||
|
||||
int leftShift, rightShift;
|
||||
|
||||
FbBits startmask, endmask;
|
||||
|
||||
int nmiddle;
|
||||
|
||||
int srcX, dstX;
|
||||
|
||||
FbBits bits, bits1;
|
||||
|
||||
int n;
|
||||
|
||||
Bool destInvarient;
|
||||
|
||||
Bool even;
|
||||
|
||||
FbDeclareMergeRop();
|
||||
|
||||
FbInitializeMergeRop(alu, pm);
|
||||
destInvarient = FbDestInvarientMergeRop();
|
||||
|
||||
srcLine += srcXEven >> FB_SHIFT;
|
||||
dstLine += dstXEven >> FB_SHIFT;
|
||||
srcXEven &= FB_MASK;
|
||||
dstXEven &= FB_MASK;
|
||||
srcXOdd &= FB_MASK;
|
||||
dstXOdd &= FB_MASK;
|
||||
|
||||
FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven);
|
||||
FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd);
|
||||
|
||||
even = TRUE;
|
||||
InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven);
|
||||
InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd);
|
||||
while (height--) {
|
||||
src = srcLine;
|
||||
dst = dstLine;
|
||||
if (even) {
|
||||
srcX = srcXEven;
|
||||
dstX = dstXEven;
|
||||
startmask = startmaskEven;
|
||||
endmask = endmaskEven;
|
||||
nmiddle = nmiddleEven;
|
||||
leftShift = leftShiftEven;
|
||||
rightShift = rightShiftEven;
|
||||
srcLine += srcStrideEven;
|
||||
dstLine += dstStrideEven;
|
||||
even = FALSE;
|
||||
}
|
||||
else {
|
||||
srcX = srcXOdd;
|
||||
dstX = dstXOdd;
|
||||
startmask = startmaskOdd;
|
||||
endmask = endmaskOdd;
|
||||
nmiddle = nmiddleOdd;
|
||||
leftShift = leftShiftOdd;
|
||||
rightShift = rightShiftOdd;
|
||||
srcLine += srcStrideOdd;
|
||||
dstLine += dstStrideOdd;
|
||||
even = TRUE;
|
||||
}
|
||||
if (srcX == dstX) {
|
||||
if (startmask) {
|
||||
bits = *src++;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, startmask);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient) {
|
||||
while (n--) {
|
||||
bits = *src++;
|
||||
*dst = FbDoDestInvarientMergeRop(bits);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (n--) {
|
||||
bits = *src++;
|
||||
*dst = FbDoMergeRop(bits, *dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
if (endmask) {
|
||||
bits = *src;
|
||||
*dst = FbDoMaskMergeRop(bits, *dst, endmask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
bits = 0;
|
||||
if (srcX > dstX)
|
||||
bits = *src++;
|
||||
if (startmask) {
|
||||
bits1 = FbScrLeft(bits, leftShift);
|
||||
bits = *src++;
|
||||
bits1 |= FbScrRight(bits, rightShift);
|
||||
*dst = FbDoMaskMergeRop(bits1, *dst, startmask);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (destInvarient) {
|
||||
while (n--) {
|
||||
bits1 = FbScrLeft(bits, leftShift);
|
||||
bits = *src++;
|
||||
bits1 |= FbScrRight(bits, rightShift);
|
||||
*dst = FbDoDestInvarientMergeRop(bits1);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (n--) {
|
||||
bits1 = FbScrLeft(bits, leftShift);
|
||||
bits = *src++;
|
||||
bits1 |= FbScrRight(bits, rightShift);
|
||||
*dst = FbDoMergeRop(bits1, *dst);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
if (endmask) {
|
||||
bits1 = FbScrLeft(bits, leftShift);
|
||||
if (FbScrLeft(endmask, rightShift)) {
|
||||
bits = *src;
|
||||
bits1 |= FbScrRight(bits, rightShift);
|
||||
}
|
||||
*dst = FbDoMaskMergeRop(bits1, *dst, endmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbBltOdd24(FbBits * srcLine,
|
||||
FbStride srcStrideEven,
|
||||
FbStride srcStrideOdd,
|
||||
int srcXEven,
|
||||
int srcXOdd,
|
||||
FbBits * dstLine,
|
||||
FbStride dstStrideEven,
|
||||
FbStride dstStrideOdd,
|
||||
int dstXEven, int dstXOdd, int width, int height, int alu, FbBits pm)
|
||||
{
|
||||
Bool even = TRUE;
|
||||
|
||||
while (height--) {
|
||||
if (even) {
|
||||
fbBlt24Line(srcLine, srcXEven, dstLine, dstXEven,
|
||||
width, alu, pm, FALSE);
|
||||
srcLine += srcStrideEven;
|
||||
dstLine += dstStrideEven;
|
||||
even = FALSE;
|
||||
}
|
||||
else {
|
||||
fbBlt24Line(srcLine, srcXOdd, dstLine, dstXOdd,
|
||||
width, alu, pm, FALSE);
|
||||
srcLine += srcStrideOdd;
|
||||
dstLine += dstStrideOdd;
|
||||
even = TRUE;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if FB_STIP_SHIFT != FB_SHIFT
|
||||
void
|
||||
fbSetBltOdd(FbStip * stip,
|
||||
FbStride stipStride,
|
||||
int srcX,
|
||||
FbBits ** bits,
|
||||
FbStride * strideEven,
|
||||
FbStride * strideOdd, int *srcXEven, int *srcXOdd)
|
||||
{
|
||||
int srcAdjust;
|
||||
|
||||
int strideAdjust;
|
||||
|
||||
/*
|
||||
* bytes needed to align source
|
||||
*/
|
||||
srcAdjust = (((int) stip) & (FB_MASK >> 3));
|
||||
/*
|
||||
* FbStip units needed to align stride
|
||||
*/
|
||||
strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT);
|
||||
|
||||
*bits = (FbBits *) ((char *) stip - srcAdjust);
|
||||
if (srcAdjust) {
|
||||
*strideEven = FbStipStrideToBitsStride(stipStride + 1);
|
||||
*strideOdd = FbStipStrideToBitsStride(stipStride);
|
||||
|
||||
*srcXEven = srcX + (srcAdjust << 3);
|
||||
*srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT);
|
||||
}
|
||||
else {
|
||||
*strideEven = FbStipStrideToBitsStride(stipStride);
|
||||
*strideOdd = FbStipStrideToBitsStride(stipStride + 1);
|
||||
|
||||
*srcXEven = srcX;
|
||||
*srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
fbBltStip(FbStip * src, FbStride srcStride, /* in FbStip units, not FbBits units */
|
||||
int srcX, FbStip * dst, FbStride dstStride, /* in FbStip units, not FbBits units */
|
||||
int dstX, int width, int height, int alu, FbBits pm, int bpp)
|
||||
{
|
||||
#if FB_STIP_SHIFT != FB_SHIFT
|
||||
if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) ||
|
||||
FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst)) {
|
||||
FbStride srcStrideEven, srcStrideOdd;
|
||||
|
||||
FbStride dstStrideEven, dstStrideOdd;
|
||||
|
||||
int srcXEven, srcXOdd;
|
||||
|
||||
int dstXEven, dstXOdd;
|
||||
|
||||
FbBits *s, *d;
|
||||
|
||||
int sx, dx;
|
||||
|
||||
src += srcX >> FB_STIP_SHIFT;
|
||||
srcX &= FB_STIP_MASK;
|
||||
dst += dstX >> FB_STIP_SHIFT;
|
||||
dstX &= FB_STIP_MASK;
|
||||
|
||||
fbSetBltOdd(src, srcStride, srcX,
|
||||
&s, &srcStrideEven, &srcStrideOdd, &srcXEven, &srcXOdd);
|
||||
|
||||
fbSetBltOdd(dst, dstStride, dstX,
|
||||
&d, &dstStrideEven, &dstStrideOdd, &dstXEven, &dstXOdd);
|
||||
|
||||
if (bpp == 24 && !FbCheck24Pix(pm)) {
|
||||
fbBltOdd24(s, srcStrideEven, srcStrideOdd,
|
||||
srcXEven, srcXOdd,
|
||||
d, dstStrideEven, dstStrideOdd,
|
||||
dstXEven, dstXOdd, width, height, alu, pm);
|
||||
}
|
||||
else
|
||||
{
|
||||
fbBltOdd(s, srcStrideEven, srcStrideOdd,
|
||||
srcXEven, srcXOdd,
|
||||
d, dstStrideEven, dstStrideOdd,
|
||||
dstXEven, dstXOdd, width, height, alu, pm, bpp);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fbBlt((FbBits *) src, FbStipStrideToBitsStride(srcStride),
|
||||
srcX,
|
||||
(FbBits *) dst, FbStipStrideToBitsStride(dstStride),
|
||||
dstX, width, height, alu, pm, bpp, FALSE, FALSE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,840 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
/*
|
||||
* Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8)
|
||||
*
|
||||
* **** **** **** **** **** **** **** ****
|
||||
* ^
|
||||
* ******** ******** ******** ********
|
||||
* ^
|
||||
* leftShift = 12
|
||||
* rightShift = 20
|
||||
*
|
||||
* Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8)
|
||||
*
|
||||
* **** **** **** **** **** **** **** ****
|
||||
* ^
|
||||
* ******** ******** ******** ********
|
||||
* ^
|
||||
*
|
||||
* leftShift = 24
|
||||
* rightShift = 8
|
||||
*/
|
||||
|
||||
#define LoadBits {\
|
||||
if (leftShift) { \
|
||||
bitsRight = (src < srcEnd ? *src++ : 0); \
|
||||
bits = (FbStipLeft (bitsLeft, leftShift) | \
|
||||
FbStipRight(bitsRight, rightShift)); \
|
||||
bitsLeft = bitsRight; \
|
||||
} else \
|
||||
bits = (src < srcEnd ? *src++ : 0); \
|
||||
}
|
||||
|
||||
|
||||
#define LaneCases1(n,a) case n: (void)FbLaneCase(n,a); break
|
||||
#define LaneCases2(n,a) LaneCases1(n,a); LaneCases1(n+1,a)
|
||||
#define LaneCases4(n,a) LaneCases2(n,a); LaneCases2(n+2,a)
|
||||
#define LaneCases8(n,a) LaneCases4(n,a); LaneCases4(n+4,a)
|
||||
#define LaneCases16(n,a) LaneCases8(n,a); LaneCases8(n+8,a)
|
||||
#define LaneCases32(n,a) LaneCases16(n,a); LaneCases16(n+16,a)
|
||||
#define LaneCases64(n,a) LaneCases32(n,a); LaneCases32(n+32,a)
|
||||
#define LaneCases128(n,a) LaneCases64(n,a); LaneCases64(n+64,a)
|
||||
#define LaneCases256(n,a) LaneCases128(n,a); LaneCases128(n+128,a)
|
||||
|
||||
#if FB_SHIFT == 6
|
||||
#define LaneCases(a) LaneCases256(0,a)
|
||||
#endif
|
||||
|
||||
#if FB_SHIFT == 5
|
||||
#define LaneCases(a) LaneCases16(0,a)
|
||||
#endif
|
||||
|
||||
#if FB_SHIFT == 6
|
||||
static const CARD8 fb8Lane[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||
21,
|
||||
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
|
||||
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
|
||||
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
|
||||
113, 114, 115,
|
||||
116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
|
||||
131, 132, 133,
|
||||
134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
|
||||
149, 150, 151,
|
||||
152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
|
||||
167, 168, 169,
|
||||
170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
|
||||
185, 186, 187,
|
||||
188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
|
||||
203, 204, 205,
|
||||
206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
|
||||
221, 222, 223,
|
||||
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
|
||||
239, 240, 241,
|
||||
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
|
||||
};
|
||||
|
||||
static const CARD8 fb16Lane[256] = {
|
||||
0x00, 0x03, 0x0c, 0x0f,
|
||||
0x30, 0x33, 0x3c, 0x3f,
|
||||
0xc0, 0xc3, 0xcc, 0xcf,
|
||||
0xf0, 0xf3, 0xfc, 0xff,
|
||||
};
|
||||
|
||||
static const CARD8 fb32Lane[16] = {
|
||||
0x00, 0x0f, 0xf0, 0xff,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if FB_SHIFT == 5
|
||||
static const CARD8 fb8Lane[16] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
|
||||
static const CARD8 fb16Lane[16] = {
|
||||
0, 3, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
static const CARD8 fb32Lane[16] = {
|
||||
0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const CARD8 * const fbLaneTable[33] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
fb8Lane, 0, 0, 0, 0, 0, 0, 0,
|
||||
fb16Lane, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
fb32Lane
|
||||
};
|
||||
|
||||
void
|
||||
fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */
|
||||
int srcX, /* bit position of source */
|
||||
FbBits * dst, FbStride dstStride, /* FbBits units per scanline */
|
||||
int dstX, /* bit position of dest */
|
||||
int dstBpp, /* bits per destination unit */
|
||||
int width, /* width in bits of destination */
|
||||
int height, /* height in scanlines */
|
||||
FbBits fgand, /* rrop values */
|
||||
FbBits fgxor, FbBits bgand, FbBits bgxor)
|
||||
{
|
||||
const FbBits *fbBits;
|
||||
|
||||
FbBits *srcEnd;
|
||||
|
||||
int pixelsPerDst; /* dst pixels per FbBits */
|
||||
|
||||
int unitsPerSrc; /* src patterns per FbStip */
|
||||
|
||||
int leftShift, rightShift; /* align source with dest */
|
||||
|
||||
FbBits startmask, endmask; /* dest scanline masks */
|
||||
|
||||
FbStip bits = 0, bitsLeft, bitsRight; /* source bits */
|
||||
|
||||
FbStip left;
|
||||
|
||||
FbBits mask;
|
||||
|
||||
int nDst; /* dest longwords (w.o. end) */
|
||||
|
||||
int w;
|
||||
|
||||
int n, nmiddle;
|
||||
|
||||
int dstS; /* stipple-relative dst X coordinate */
|
||||
|
||||
Bool copy; /* accelerate dest-invariant */
|
||||
|
||||
Bool transparent; /* accelerate 0 nop */
|
||||
|
||||
int srcinc; /* source units consumed */
|
||||
|
||||
Bool endNeedsLoad = FALSE; /* need load for endmask */
|
||||
|
||||
const CARD8 *fbLane;
|
||||
int startbyte, endbyte;
|
||||
|
||||
if (dstBpp == 24) {
|
||||
fbBltOne24(src, srcStride, srcX,
|
||||
dst, dstStride, dstX, dstBpp,
|
||||
width, height, fgand, fgxor, bgand, bgxor);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not read past the end of the buffer!
|
||||
*/
|
||||
srcEnd = src + height * srcStride;
|
||||
|
||||
/*
|
||||
* Number of destination units in FbBits == number of stipple pixels
|
||||
* used each time
|
||||
*/
|
||||
pixelsPerDst = FB_UNIT / dstBpp;
|
||||
|
||||
/*
|
||||
* Number of source stipple patterns in FbStip
|
||||
*/
|
||||
unitsPerSrc = FB_STIP_UNIT / pixelsPerDst;
|
||||
|
||||
copy = FALSE;
|
||||
transparent = FALSE;
|
||||
if (bgand == 0 && fgand == 0)
|
||||
copy = TRUE;
|
||||
else if (bgand == FB_ALLONES && bgxor == 0)
|
||||
transparent = TRUE;
|
||||
|
||||
/*
|
||||
* Adjust source and dest to nearest FbBits boundary
|
||||
*/
|
||||
src += srcX >> FB_STIP_SHIFT;
|
||||
dst += dstX >> FB_SHIFT;
|
||||
srcX &= FB_STIP_MASK;
|
||||
dstX &= FB_MASK;
|
||||
|
||||
FbMaskBitsBytes(dstX, width, copy,
|
||||
startmask, startbyte, nmiddle, endmask, endbyte);
|
||||
|
||||
/*
|
||||
* Compute effective dest alignment requirement for
|
||||
* source -- must align source to dest unit boundary
|
||||
*/
|
||||
dstS = dstX / dstBpp;
|
||||
/*
|
||||
* Compute shift constants for effective alignement
|
||||
*/
|
||||
if (srcX >= dstS) {
|
||||
leftShift = srcX - dstS;
|
||||
rightShift = FB_STIP_UNIT - leftShift;
|
||||
}
|
||||
else {
|
||||
rightShift = dstS - srcX;
|
||||
leftShift = FB_STIP_UNIT - rightShift;
|
||||
}
|
||||
/*
|
||||
* Get pointer to stipple mask array for this depth
|
||||
*/
|
||||
fbBits = 0; /* unused */
|
||||
if (pixelsPerDst <= 8)
|
||||
fbBits = fbStippleTable[pixelsPerDst];
|
||||
fbLane = 0;
|
||||
if (transparent && fgand == 0 && dstBpp >= 8)
|
||||
fbLane = fbLaneTable[dstBpp];
|
||||
|
||||
/*
|
||||
* Compute total number of destination words written, but
|
||||
* don't count endmask
|
||||
*/
|
||||
nDst = nmiddle;
|
||||
if (startmask)
|
||||
nDst++;
|
||||
|
||||
dstStride -= nDst;
|
||||
|
||||
/*
|
||||
* Compute total number of source words consumed
|
||||
*/
|
||||
|
||||
srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc;
|
||||
|
||||
if (srcX > dstS)
|
||||
srcinc++;
|
||||
if (endmask) {
|
||||
endNeedsLoad = nDst % unitsPerSrc == 0;
|
||||
if (endNeedsLoad)
|
||||
srcinc++;
|
||||
}
|
||||
|
||||
srcStride -= srcinc;
|
||||
|
||||
/*
|
||||
* Copy rectangle
|
||||
*/
|
||||
while (height--) {
|
||||
w = nDst; /* total units across scanline */
|
||||
n = unitsPerSrc; /* units avail in single stipple */
|
||||
if (n > w)
|
||||
n = w;
|
||||
|
||||
bitsLeft = 0;
|
||||
if (srcX > dstS)
|
||||
bitsLeft = *src++;
|
||||
if (n) {
|
||||
/*
|
||||
* Load first set of stipple bits
|
||||
*/
|
||||
LoadBits;
|
||||
|
||||
/*
|
||||
* Consume stipple bits for startmask
|
||||
*/
|
||||
if (startmask) {
|
||||
#if FB_UNIT > 32
|
||||
if (pixelsPerDst == 16)
|
||||
mask = FbStipple16Bits(FbLeftStipBits(bits, 16));
|
||||
else
|
||||
#endif
|
||||
mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
|
||||
if (fbLane) {
|
||||
fbTransparentSpan(dst, mask & startmask, fgxor, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mask || !transparent)
|
||||
FbDoLeftMaskByteStippleRRop(dst, mask,
|
||||
fgand, fgxor, bgand, bgxor,
|
||||
startbyte, startmask);
|
||||
}
|
||||
bits = FbStipLeft(bits, pixelsPerDst);
|
||||
dst++;
|
||||
n--;
|
||||
w--;
|
||||
}
|
||||
/*
|
||||
* Consume stipple bits across scanline
|
||||
*/
|
||||
for (;;) {
|
||||
w -= n;
|
||||
if (copy) {
|
||||
while (n--) {
|
||||
#if FB_UNIT > 32
|
||||
if (pixelsPerDst == 16)
|
||||
mask = FbStipple16Bits(FbLeftStipBits(bits, 16));
|
||||
else
|
||||
#endif
|
||||
mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
|
||||
*dst = FbOpaqueStipple(mask, fgxor, bgxor);
|
||||
dst++;
|
||||
bits = FbStipLeft(bits, pixelsPerDst);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (fbLane) {
|
||||
while (bits && n) {
|
||||
switch (fbLane[FbLeftStipBits(bits, pixelsPerDst)]) {
|
||||
LaneCases((CARD8 *) dst);
|
||||
}
|
||||
bits = FbStipLeft(bits, pixelsPerDst);
|
||||
dst++;
|
||||
n--;
|
||||
}
|
||||
dst += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--) {
|
||||
left = FbLeftStipBits(bits, pixelsPerDst);
|
||||
if (left || !transparent) {
|
||||
mask = fbBits[left];
|
||||
*dst = FbStippleRRop(*dst, mask,
|
||||
fgand, fgxor, bgand,
|
||||
bgxor);
|
||||
}
|
||||
dst++;
|
||||
bits = FbStipLeft(bits, pixelsPerDst);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!w)
|
||||
break;
|
||||
/*
|
||||
* Load another set and reset number of available units
|
||||
*/
|
||||
LoadBits;
|
||||
n = unitsPerSrc;
|
||||
if (n > w)
|
||||
n = w;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Consume stipple bits for endmask
|
||||
*/
|
||||
if (endmask) {
|
||||
if (endNeedsLoad) {
|
||||
LoadBits;
|
||||
}
|
||||
#if FB_UNIT > 32
|
||||
if (pixelsPerDst == 16)
|
||||
mask = FbStipple16Bits(FbLeftStipBits(bits, 16));
|
||||
else
|
||||
#endif
|
||||
mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
|
||||
if (fbLane) {
|
||||
fbTransparentSpan(dst, mask & endmask, fgxor, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mask || !transparent)
|
||||
FbDoRightMaskByteStippleRRop(dst, mask,
|
||||
fgand, fgxor, bgand, bgxor,
|
||||
endbyte, endmask);
|
||||
}
|
||||
}
|
||||
dst += dstStride;
|
||||
src += srcStride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Crufty macros to initialize the mask array, most of this
|
||||
* is to avoid compile-time warnings about shift overflow
|
||||
*/
|
||||
|
||||
#if BITMAP_BIT_ORDER == MSBFirst
|
||||
#define Mask24Pos(x,r) ((x)*24-(r))
|
||||
#else
|
||||
#define Mask24Pos(x,r) ((x)*24-((r) ? 24 - (r) : 0))
|
||||
#endif
|
||||
|
||||
#define Mask24Neg(x,r) (Mask24Pos(x,r) < 0 ? -Mask24Pos(x,r) : 0)
|
||||
#define Mask24Check(x,r) (Mask24Pos(x,r) < 0 ? 0 : \
|
||||
Mask24Pos(x,r) >= FB_UNIT ? 0 : Mask24Pos(x,r))
|
||||
|
||||
#define Mask24(x,r) (Mask24Pos(x,r) < FB_UNIT ? \
|
||||
(Mask24Pos(x,r) < 0 ? \
|
||||
0xffffff >> Mask24Neg (x,r) : \
|
||||
0xffffff << Mask24Check(x,r)) : 0)
|
||||
|
||||
#define SelMask24(b,n,r) ((((b) >> n) & 1) * Mask24(n,r))
|
||||
|
||||
/*
|
||||
* Untested for MSBFirst or FB_UNIT == 32
|
||||
*/
|
||||
|
||||
#if FB_UNIT == 64
|
||||
#define C4_24(b,r) \
|
||||
(SelMask24(b,0,r) | \
|
||||
SelMask24(b,1,r) | \
|
||||
SelMask24(b,2,r) | \
|
||||
SelMask24(b,3,r))
|
||||
|
||||
#define FbStip24New(rot) (2 + (rot != 0))
|
||||
#define FbStip24Len 4
|
||||
|
||||
const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
|
||||
/* rotate 0 */
|
||||
{
|
||||
C4_24(0, 0), C4_24(1, 0), C4_24(2, 0), C4_24(3, 0),
|
||||
C4_24(4, 0), C4_24(5, 0), C4_24(6, 0), C4_24(7, 0),
|
||||
C4_24(8, 0), C4_24(9, 0), C4_24(10, 0), C4_24(11, 0),
|
||||
C4_24(12, 0), C4_24(13, 0), C4_24(14, 0), C4_24(15, 0),
|
||||
},
|
||||
/* rotate 8 */
|
||||
{
|
||||
C4_24(0, 8), C4_24(1, 8), C4_24(2, 8), C4_24(3, 8),
|
||||
C4_24(4, 8), C4_24(5, 8), C4_24(6, 8), C4_24(7, 8),
|
||||
C4_24(8, 8), C4_24(9, 8), C4_24(10, 8), C4_24(11, 8),
|
||||
C4_24(12, 8), C4_24(13, 8), C4_24(14, 8), C4_24(15, 8),
|
||||
},
|
||||
/* rotate 16 */
|
||||
{
|
||||
C4_24(0, 16), C4_24(1, 16), C4_24(2, 16), C4_24(3, 16),
|
||||
C4_24(4, 16), C4_24(5, 16), C4_24(6, 16), C4_24(7, 16),
|
||||
C4_24(8, 16), C4_24(9, 16), C4_24(10, 16), C4_24(11, 16),
|
||||
C4_24(12, 16), C4_24(13, 16), C4_24(14, 16), C4_24(15, 16),
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if FB_UNIT == 32
|
||||
#define C2_24(b,r) \
|
||||
(SelMask24(b,0,r) | \
|
||||
SelMask24(b,1,r))
|
||||
|
||||
#define FbStip24Len 2
|
||||
#if BITMAP_BIT_ORDER == MSBFirst
|
||||
#define FbStip24New(rot) (1 + (rot == 0))
|
||||
#else
|
||||
#define FbStip24New(rot) (1 + (rot == 8))
|
||||
#endif
|
||||
|
||||
const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
|
||||
/* rotate 0 */
|
||||
{
|
||||
C2_24(0, 0), C2_24(1, 0), C2_24(2, 0), C2_24(3, 0),
|
||||
},
|
||||
/* rotate 8 */
|
||||
{
|
||||
C2_24(0, 8), C2_24(1, 8), C2_24(2, 8), C2_24(3, 8),
|
||||
},
|
||||
/* rotate 16 */
|
||||
{
|
||||
C2_24(0, 16), C2_24(1, 16), C2_24(2, 16), C2_24(3, 16),
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
|
||||
#define FbMergeStip24Bits(left, right, new) \
|
||||
(FbStipLeft (left, new) | FbStipRight ((right), (FbStip24Len - (new))))
|
||||
|
||||
#define FbMergePartStip24Bits(left, right, llen, rlen) \
|
||||
(left | FbStipRight(right, llen))
|
||||
|
||||
#else
|
||||
|
||||
#define FbMergeStip24Bits(left, right, new) \
|
||||
((FbStipLeft (left, new) & ((1 << FbStip24Len) - 1)) | right)
|
||||
|
||||
#define FbMergePartStip24Bits(left, right, llen, rlen) \
|
||||
(FbStipLeft(left, rlen) | right)
|
||||
|
||||
#endif
|
||||
|
||||
#define fbFirstStipBits(len,stip) {\
|
||||
int __len = (len); \
|
||||
if (len <= remain) { \
|
||||
stip = FbLeftStipBits(bits, len); \
|
||||
} else { \
|
||||
stip = FbLeftStipBits(bits, remain); \
|
||||
bits = (src < srcEnd ? *src++ : 0); \
|
||||
__len = (len) - remain; \
|
||||
stip = FbMergePartStip24Bits(stip, FbLeftStipBits(bits, __len), \
|
||||
remain, __len); \
|
||||
remain = FB_STIP_UNIT; \
|
||||
} \
|
||||
bits = FbStipLeft (bits, __len); \
|
||||
remain -= __len; \
|
||||
}
|
||||
|
||||
#define fbInitStipBits(offset,len,stip) {\
|
||||
bits = FbStipLeft (*src++,offset); \
|
||||
remain = FB_STIP_UNIT - offset; \
|
||||
fbFirstStipBits(len,stip); \
|
||||
stip = FbMergeStip24Bits (0, stip, len); \
|
||||
}
|
||||
|
||||
#define fbNextStipBits(rot,stip) {\
|
||||
int __new = FbStip24New(rot); \
|
||||
FbStip __right; \
|
||||
fbFirstStipBits(__new, __right); \
|
||||
stip = FbMergeStip24Bits (stip, __right, __new); \
|
||||
rot = FbNext24Rot (rot); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Use deep mask tables that incorporate rotation, pull
|
||||
* a variable number of bits out of the stipple and
|
||||
* reuse the right bits as needed for the next write
|
||||
*
|
||||
* Yes, this is probably too much code, but most 24-bpp screens
|
||||
* have no acceleration so this code is used for stipples, copyplane
|
||||
* and text
|
||||
*/
|
||||
void
|
||||
fbBltOne24(FbStip * srcLine, FbStride srcStride, /* FbStip units per scanline */
|
||||
int srcX, /* bit position of source */
|
||||
FbBits * dst, FbStride dstStride, /* FbBits units per scanline */
|
||||
int dstX, /* bit position of dest */
|
||||
int dstBpp, /* bits per destination unit */
|
||||
int width, /* width in bits of destination */
|
||||
int height, /* height in scanlines */
|
||||
FbBits fgand, /* rrop values */
|
||||
FbBits fgxor, FbBits bgand, FbBits bgxor)
|
||||
{
|
||||
FbStip *src, *srcEnd;
|
||||
|
||||
FbBits leftMask, rightMask, mask;
|
||||
|
||||
int nlMiddle, nl;
|
||||
|
||||
FbStip stip, bits;
|
||||
|
||||
int remain;
|
||||
|
||||
int dstS;
|
||||
|
||||
int firstlen;
|
||||
|
||||
int rot0, rot;
|
||||
|
||||
int nDst;
|
||||
|
||||
/*
|
||||
* Do not read past the end of the buffer!
|
||||
*/
|
||||
srcEnd = srcLine + height * srcStride;
|
||||
|
||||
srcLine += srcX >> FB_STIP_SHIFT;
|
||||
dst += dstX >> FB_SHIFT;
|
||||
srcX &= FB_STIP_MASK;
|
||||
dstX &= FB_MASK;
|
||||
rot0 = FbFirst24Rot(dstX);
|
||||
|
||||
FbMaskBits(dstX, width, leftMask, nlMiddle, rightMask);
|
||||
|
||||
dstS = (dstX + 23) / 24;
|
||||
firstlen = FbStip24Len - dstS;
|
||||
|
||||
nDst = nlMiddle;
|
||||
if (leftMask)
|
||||
nDst++;
|
||||
dstStride -= nDst;
|
||||
|
||||
/* opaque copy */
|
||||
if (bgand == 0 && fgand == 0) {
|
||||
while (height--) {
|
||||
rot = rot0;
|
||||
src = srcLine;
|
||||
srcLine += srcStride;
|
||||
fbInitStipBits(srcX, firstlen, stip);
|
||||
if (leftMask) {
|
||||
mask = fbStipple24Bits[rot >> 3][stip];
|
||||
*dst = (*dst & ~leftMask) | (FbOpaqueStipple(mask,
|
||||
FbRot24(fgxor,
|
||||
rot),
|
||||
FbRot24(bgxor,
|
||||
rot))
|
||||
& leftMask);
|
||||
dst++;
|
||||
fbNextStipBits(rot, stip);
|
||||
}
|
||||
nl = nlMiddle;
|
||||
while (nl--) {
|
||||
mask = fbStipple24Bits[rot >> 3][stip];
|
||||
*dst = FbOpaqueStipple(mask,
|
||||
FbRot24(fgxor, rot),
|
||||
FbRot24(bgxor, rot));
|
||||
dst++;
|
||||
fbNextStipBits(rot, stip);
|
||||
}
|
||||
if (rightMask) {
|
||||
mask = fbStipple24Bits[rot >> 3][stip];
|
||||
*dst = (*dst & ~rightMask) | (FbOpaqueStipple(mask,
|
||||
FbRot24(fgxor,
|
||||
rot),
|
||||
FbRot24(bgxor,
|
||||
rot))
|
||||
& rightMask);
|
||||
}
|
||||
dst += dstStride;
|
||||
src += srcStride;
|
||||
}
|
||||
}
|
||||
/* transparent copy */
|
||||
else if (bgand == FB_ALLONES && bgxor == 0 && fgand == 0) {
|
||||
while (height--) {
|
||||
rot = rot0;
|
||||
src = srcLine;
|
||||
srcLine += srcStride;
|
||||
fbInitStipBits(srcX, firstlen, stip);
|
||||
if (leftMask) {
|
||||
if (stip) {
|
||||
mask = fbStipple24Bits[rot >> 3][stip] & leftMask;
|
||||
*dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask);
|
||||
}
|
||||
dst++;
|
||||
fbNextStipBits(rot, stip);
|
||||
}
|
||||
nl = nlMiddle;
|
||||
while (nl--) {
|
||||
if (stip) {
|
||||
mask = fbStipple24Bits[rot >> 3][stip];
|
||||
*dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask);
|
||||
}
|
||||
dst++;
|
||||
fbNextStipBits(rot, stip);
|
||||
}
|
||||
if (rightMask) {
|
||||
if (stip) {
|
||||
mask = fbStipple24Bits[rot >> 3][stip] & rightMask;
|
||||
*dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask);
|
||||
}
|
||||
}
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (height--) {
|
||||
rot = rot0;
|
||||
src = srcLine;
|
||||
srcLine += srcStride;
|
||||
fbInitStipBits(srcX, firstlen, stip);
|
||||
if (leftMask) {
|
||||
mask = fbStipple24Bits[rot >> 3][stip];
|
||||
*dst = FbStippleRRopMask(*dst, mask,
|
||||
FbRot24(fgand, rot),
|
||||
FbRot24(fgxor, rot),
|
||||
FbRot24(bgand, rot),
|
||||
FbRot24(bgxor, rot), leftMask);
|
||||
dst++;
|
||||
fbNextStipBits(rot, stip);
|
||||
}
|
||||
nl = nlMiddle;
|
||||
while (nl--) {
|
||||
mask = fbStipple24Bits[rot >> 3][stip];
|
||||
*dst = FbStippleRRop(*dst, mask,
|
||||
FbRot24(fgand, rot),
|
||||
FbRot24(fgxor, rot),
|
||||
FbRot24(bgand, rot), FbRot24(bgxor, rot));
|
||||
dst++;
|
||||
fbNextStipBits(rot, stip);
|
||||
}
|
||||
if (rightMask) {
|
||||
mask = fbStipple24Bits[rot >> 3][stip];
|
||||
*dst = FbStippleRRopMask(*dst, mask,
|
||||
FbRot24(fgand, rot),
|
||||
FbRot24(fgxor, rot),
|
||||
FbRot24(bgand, rot),
|
||||
FbRot24(bgxor, rot), rightMask);
|
||||
}
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Not very efficient, but simple -- copy a single plane
|
||||
* from an N bit image to a 1 bit image
|
||||
*/
|
||||
|
||||
void
|
||||
fbBltPlane(FbBits * src,
|
||||
FbStride srcStride,
|
||||
int srcX,
|
||||
int srcBpp,
|
||||
FbStip * dst,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int width,
|
||||
int height,
|
||||
FbStip fgand,
|
||||
FbStip fgxor, FbStip bgand, FbStip bgxor, Pixel planeMask)
|
||||
{
|
||||
FbBits *s;
|
||||
|
||||
FbBits pm;
|
||||
|
||||
FbBits srcMask;
|
||||
|
||||
FbBits srcMaskFirst;
|
||||
|
||||
FbBits srcMask0 = 0;
|
||||
|
||||
FbBits srcBits;
|
||||
|
||||
FbStip dstBits;
|
||||
|
||||
FbStip *d;
|
||||
|
||||
FbStip dstMask;
|
||||
|
||||
FbStip dstMaskFirst;
|
||||
|
||||
FbStip dstUnion;
|
||||
|
||||
int w;
|
||||
|
||||
int wt;
|
||||
|
||||
int rot0;
|
||||
|
||||
if (!width)
|
||||
return;
|
||||
|
||||
src += srcX >> FB_SHIFT;
|
||||
srcX &= FB_MASK;
|
||||
|
||||
dst += dstX >> FB_STIP_SHIFT;
|
||||
dstX &= FB_STIP_MASK;
|
||||
|
||||
w = width / srcBpp;
|
||||
|
||||
pm = fbReplicatePixel(planeMask, srcBpp);
|
||||
if (srcBpp == 24) {
|
||||
int tmpw = 24;
|
||||
|
||||
rot0 = FbFirst24Rot(srcX);
|
||||
if (srcX + tmpw > FB_UNIT)
|
||||
tmpw = FB_UNIT - srcX;
|
||||
srcMaskFirst = FbRot24(pm, rot0) & FbBitsMask(srcX, tmpw);
|
||||
}
|
||||
else
|
||||
{
|
||||
rot0 = 0;
|
||||
srcMaskFirst = pm & FbBitsMask(srcX, srcBpp);
|
||||
srcMask0 = pm & FbBitsMask(0, srcBpp);
|
||||
}
|
||||
|
||||
dstMaskFirst = FbStipMask(dstX, 1);
|
||||
while (height--) {
|
||||
d = dst;
|
||||
dst += dstStride;
|
||||
s = src;
|
||||
src += srcStride;
|
||||
|
||||
srcMask = srcMaskFirst;
|
||||
if (srcBpp == 24)
|
||||
srcMask0 = FbRot24(pm, rot0) & FbBitsMask(0, srcBpp);
|
||||
srcBits = *s++;
|
||||
|
||||
dstMask = dstMaskFirst;
|
||||
dstUnion = 0;
|
||||
dstBits = 0;
|
||||
|
||||
wt = w;
|
||||
|
||||
while (wt--) {
|
||||
if (!srcMask) {
|
||||
srcBits = *s++;
|
||||
if (srcBpp == 24)
|
||||
srcMask0 = FbNext24Pix(srcMask0) & FbBitsMask(0, 24);
|
||||
srcMask = srcMask0;
|
||||
}
|
||||
if (!dstMask) {
|
||||
*d = FbStippleRRopMask(*d, dstBits,
|
||||
fgand, fgxor, bgand, bgxor, dstUnion);
|
||||
d++;
|
||||
dstMask = FbStipMask(0, 1);
|
||||
dstUnion = 0;
|
||||
dstBits = 0;
|
||||
}
|
||||
if (srcBits & srcMask)
|
||||
dstBits |= dstMask;
|
||||
dstUnion |= dstMask;
|
||||
if (srcBpp == FB_UNIT)
|
||||
srcMask = 0;
|
||||
else
|
||||
srcMask = FbScrRight(srcMask, srcBpp);
|
||||
dstMask = FbStipRight(dstMask, 1);
|
||||
}
|
||||
if (dstUnion)
|
||||
*d = FbStippleRRopMask(*d, dstBits,
|
||||
fgand, fgxor, bgand, bgxor, dstUnion);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/************************************************************
|
||||
Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright no-
|
||||
tice appear in all copies and that both that copyright no-
|
||||
tice and this permission notice appear in supporting docu-
|
||||
mentation, and that the names of Sun or X Consortium
|
||||
not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific prior
|
||||
written permission. Sun and X Consortium make no
|
||||
representations about the suitability of this software for
|
||||
any purpose. It is provided "as is" without any express or
|
||||
implied warranty.
|
||||
|
||||
SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
|
||||
NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
|
||||
ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
||||
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
********************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include "scrnintstr.h"
|
||||
#include "colormapst.h"
|
||||
#include "resource.h"
|
||||
#include "fb.h"
|
||||
#include "micmap.h"
|
||||
|
||||
int
|
||||
fbListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps)
|
||||
{
|
||||
return miListInstalledColormaps(pScreen, pmaps);
|
||||
}
|
||||
|
||||
void
|
||||
fbInstallColormap(ColormapPtr pmap)
|
||||
{
|
||||
miInstallColormap(pmap);
|
||||
}
|
||||
|
||||
void
|
||||
fbUninstallColormap(ColormapPtr pmap)
|
||||
{
|
||||
miUninstallColormap(pmap);
|
||||
}
|
||||
|
||||
void
|
||||
fbResolveColor(unsigned short *pred,
|
||||
unsigned short *pgreen, unsigned short *pblue, VisualPtr pVisual)
|
||||
{
|
||||
miResolveColor(pred, pgreen, pblue, pVisual);
|
||||
}
|
||||
|
||||
Bool
|
||||
fbInitializeColormap(ColormapPtr pmap)
|
||||
{
|
||||
return miInitializeColormap(pmap);
|
||||
}
|
||||
|
||||
int
|
||||
fbExpandDirectColors(ColormapPtr pmap,
|
||||
int ndef, xColorItem * indefs, xColorItem * outdefs)
|
||||
{
|
||||
return miExpandDirectColors(pmap, ndef, indefs, outdefs);
|
||||
}
|
||||
|
||||
Bool
|
||||
fbCreateDefColormap(ScreenPtr pScreen)
|
||||
{
|
||||
return miCreateDefColormap(pScreen);
|
||||
}
|
||||
|
||||
void
|
||||
fbClearVisualTypes(void)
|
||||
{
|
||||
miClearVisualTypes();
|
||||
}
|
||||
|
||||
Bool
|
||||
fbSetVisualTypes(int depth, int visuals, int bitsPerRGB)
|
||||
{
|
||||
return miSetVisualTypes(depth, visuals, bitsPerRGB, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a list of formats for a screen, create a list
|
||||
* of visuals and depths for the screen which coorespond to
|
||||
* the set which can be used with this version of fb.
|
||||
*/
|
||||
|
||||
Bool
|
||||
fbInitVisuals(VisualPtr * visualp,
|
||||
DepthPtr * depthp,
|
||||
int *nvisualp,
|
||||
int *ndepthp,
|
||||
int *rootDepthp,
|
||||
VisualID * defaultVisp, unsigned long sizes, int bitsPerRGB)
|
||||
{
|
||||
return miInitVisuals(visualp, depthp, nvisualp, ndepthp, rootDepthp,
|
||||
defaultVisp, sizes, bitsPerRGB, -1);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,584 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbCopyNtoN(DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
BoxPtr pbox,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
||||
{
|
||||
CARD8 alu = pGC ? pGC->alu : GXcopy;
|
||||
|
||||
FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES;
|
||||
|
||||
FbBits *src;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
|
||||
fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
while (nbox--) {
|
||||
fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride,
|
||||
srcStride,
|
||||
(pbox->x1 + dx + srcXoff) * srcBpp,
|
||||
dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
(pbox->x2 - pbox->x1) * dstBpp,
|
||||
(pbox->y2 - pbox->y1), alu, pm, dstBpp, reverse, upsidedown);
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbCopy1toN(DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
BoxPtr pbox,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
FbBits *src;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
|
||||
fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
while (nbox--) {
|
||||
if (dstBpp == 1) {
|
||||
fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride,
|
||||
srcStride,
|
||||
(pbox->x1 + dx + srcXoff) * srcBpp,
|
||||
dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
(pbox->x2 - pbox->x1) * dstBpp,
|
||||
(pbox->y2 - pbox->y1),
|
||||
FbOpaqueStipple1Rop(pGC->alu,
|
||||
pGC->fgPixel, pGC->bgPixel),
|
||||
pPriv->pm, dstBpp, reverse, upsidedown);
|
||||
}
|
||||
else {
|
||||
fbBltOne((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride),
|
||||
srcStride * (FB_UNIT / FB_STIP_UNIT),
|
||||
(pbox->x1 + dx + srcXoff),
|
||||
dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
dstBpp,
|
||||
(pbox->x2 - pbox->x1) * dstBpp,
|
||||
(pbox->y2 - pbox->y1),
|
||||
pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor);
|
||||
}
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbCopyNto1(DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
BoxPtr pbox,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
while (nbox--) {
|
||||
if (pDstDrawable->bitsPerPixel == 1) {
|
||||
FbBits *src;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
FbStip *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff,
|
||||
srcYoff);
|
||||
fbGetStipDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff,
|
||||
dstYoff);
|
||||
fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride,
|
||||
(pbox->x1 + dx + srcXoff) * srcBpp, srcBpp,
|
||||
dst + (pbox->y1 + dstYoff) * dstStride, dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
(pbox->x2 - pbox->x1) * srcBpp, (pbox->y2 - pbox->y1),
|
||||
(FbStip) pPriv->and, (FbStip) pPriv->xor,
|
||||
(FbStip) pPriv->bgand, (FbStip) pPriv->bgxor, bitplane);
|
||||
}
|
||||
else {
|
||||
FbBits *src;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbStip *tmp;
|
||||
|
||||
FbStride tmpStride;
|
||||
|
||||
int width, height;
|
||||
|
||||
width = pbox->x2 - pbox->x1;
|
||||
height = pbox->y2 - pbox->y1;
|
||||
|
||||
tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
|
||||
tmp = malloc(tmpStride * height * sizeof(FbStip));
|
||||
if (!tmp)
|
||||
return;
|
||||
|
||||
fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff,
|
||||
srcYoff);
|
||||
fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff,
|
||||
dstYoff);
|
||||
|
||||
fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride,
|
||||
srcStride,
|
||||
(pbox->x1 + dx + srcXoff) * srcBpp,
|
||||
srcBpp,
|
||||
tmp,
|
||||
tmpStride,
|
||||
0,
|
||||
width * srcBpp,
|
||||
height,
|
||||
fbAndStip(GXcopy, FB_ALLONES, FB_ALLONES),
|
||||
fbXorStip(GXcopy, FB_ALLONES, FB_ALLONES),
|
||||
fbAndStip(GXcopy, 0, FB_ALLONES),
|
||||
fbXorStip(GXcopy, 0, FB_ALLONES), bitplane);
|
||||
fbBltOne(tmp,
|
||||
tmpStride,
|
||||
0,
|
||||
dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
dstBpp,
|
||||
width * dstBpp,
|
||||
height,
|
||||
pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor);
|
||||
free(tmp);
|
||||
}
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbCopyRegion(DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
RegionPtr pDstRegion,
|
||||
int dx, int dy, fbCopyProc copyProc, Pixel bitPlane, void *closure)
|
||||
{
|
||||
int careful;
|
||||
|
||||
Bool reverse;
|
||||
|
||||
Bool upsidedown;
|
||||
|
||||
BoxPtr pbox;
|
||||
|
||||
int nbox;
|
||||
|
||||
BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp;
|
||||
|
||||
pbox = REGION_RECTS(pDstRegion);
|
||||
nbox = REGION_NUM_RECTS(pDstRegion);
|
||||
|
||||
/* XXX we have to err on the side of safety when both are windows,
|
||||
* because we don't know if IncludeInferiors is being used.
|
||||
*/
|
||||
careful = ((pSrcDrawable == pDstDrawable) ||
|
||||
((pSrcDrawable->type == DRAWABLE_WINDOW) &&
|
||||
(pDstDrawable->type == DRAWABLE_WINDOW)));
|
||||
|
||||
pboxNew1 = NULL;
|
||||
pboxNew2 = NULL;
|
||||
if (careful && dy < 0) {
|
||||
upsidedown = TRUE;
|
||||
|
||||
if (nbox > 1) {
|
||||
/* keep ordering in each band, reverse order of bands */
|
||||
pboxNew1 = (BoxPtr) ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
|
||||
if (!pboxNew1)
|
||||
return;
|
||||
pboxBase = pboxNext = pbox + nbox - 1;
|
||||
while (pboxBase >= pbox) {
|
||||
while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
|
||||
pboxNext--;
|
||||
pboxTmp = pboxNext + 1;
|
||||
while (pboxTmp <= pboxBase) {
|
||||
*pboxNew1++ = *pboxTmp++;
|
||||
}
|
||||
pboxBase = pboxNext;
|
||||
}
|
||||
pboxNew1 -= nbox;
|
||||
pbox = pboxNew1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* walk source top to bottom */
|
||||
upsidedown = FALSE;
|
||||
}
|
||||
|
||||
if (careful && dx < 0) {
|
||||
/* walk source right to left */
|
||||
if (dy <= 0)
|
||||
reverse = TRUE;
|
||||
else
|
||||
reverse = FALSE;
|
||||
|
||||
if (nbox > 1) {
|
||||
/* reverse order of rects in each band */
|
||||
pboxNew2 = (BoxPtr) ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
|
||||
if (!pboxNew2) {
|
||||
if (pboxNew1)
|
||||
DEALLOCATE_LOCAL(pboxNew1);
|
||||
return;
|
||||
}
|
||||
pboxBase = pboxNext = pbox;
|
||||
while (pboxBase < pbox + nbox) {
|
||||
while ((pboxNext < pbox + nbox) &&
|
||||
(pboxNext->y1 == pboxBase->y1))
|
||||
pboxNext++;
|
||||
pboxTmp = pboxNext;
|
||||
while (pboxTmp != pboxBase) {
|
||||
*pboxNew2++ = *--pboxTmp;
|
||||
}
|
||||
pboxBase = pboxNext;
|
||||
}
|
||||
pboxNew2 -= nbox;
|
||||
pbox = pboxNew2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* walk source left to right */
|
||||
reverse = FALSE;
|
||||
}
|
||||
|
||||
(*copyProc) (pSrcDrawable,
|
||||
pDstDrawable,
|
||||
pGC,
|
||||
pbox, nbox, dx, dy, reverse, upsidedown, bitPlane, closure);
|
||||
|
||||
if (pboxNew1)
|
||||
DEALLOCATE_LOCAL(pboxNew1);
|
||||
if (pboxNew2)
|
||||
DEALLOCATE_LOCAL(pboxNew2);
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
fbDoCopy(DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
int xIn,
|
||||
int yIn,
|
||||
int widthSrc,
|
||||
int heightSrc,
|
||||
int xOut, int yOut, fbCopyProc copyProc, Pixel bitPlane, void *closure)
|
||||
{
|
||||
RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
|
||||
|
||||
Bool freeSrcClip = FALSE;
|
||||
|
||||
RegionPtr prgnExposed = NULL;
|
||||
|
||||
RegionRec rgnDst;
|
||||
|
||||
int dx;
|
||||
|
||||
int dy;
|
||||
|
||||
int numRects;
|
||||
|
||||
int box_x1;
|
||||
|
||||
int box_y1;
|
||||
|
||||
int box_x2;
|
||||
|
||||
int box_y2;
|
||||
|
||||
Bool fastSrc = FALSE; /* for fast clipping with pixmap source */
|
||||
|
||||
Bool fastDst = FALSE; /* for fast clipping with one rect dest */
|
||||
|
||||
Bool fastExpose = FALSE; /* for fast exposures with pixmap source */
|
||||
|
||||
/* Short cut for unmapped windows */
|
||||
|
||||
if (pDstDrawable->type == DRAWABLE_WINDOW &&
|
||||
!((WindowPtr) pDstDrawable)->realized) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((pSrcDrawable != pDstDrawable) && pSrcDrawable->pScreen->SourceValidate) {
|
||||
(*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn,
|
||||
widthSrc, heightSrc);
|
||||
}
|
||||
|
||||
/* Compute source clip region */
|
||||
if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
|
||||
if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
|
||||
prgnSrcClip = fbGetCompositeClip(pGC);
|
||||
else
|
||||
fastSrc = TRUE;
|
||||
}
|
||||
else {
|
||||
if (pGC->subWindowMode == IncludeInferiors) {
|
||||
/*
|
||||
* XFree86 DDX empties the border clip when the
|
||||
* VT is inactive, make sure the region isn't empty
|
||||
*/
|
||||
if (!((WindowPtr) pSrcDrawable)->parent &&
|
||||
REGION_NOTEMPTY(
|
||||
&((WindowPtr) pSrcDrawable)->borderClip)) {
|
||||
/*
|
||||
* special case bitblt from root window in
|
||||
* IncludeInferiors mode; just like from a pixmap
|
||||
*/
|
||||
fastSrc = TRUE;
|
||||
}
|
||||
else if ((pSrcDrawable == pDstDrawable) &&
|
||||
(pGC->clientClipType == CT_NONE)) {
|
||||
prgnSrcClip = fbGetCompositeClip(pGC);
|
||||
}
|
||||
else {
|
||||
prgnSrcClip = NotClippedByChildren((WindowPtr) pSrcDrawable);
|
||||
freeSrcClip = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
prgnSrcClip = &((WindowPtr) pSrcDrawable)->clipList;
|
||||
}
|
||||
}
|
||||
|
||||
xIn += pSrcDrawable->x;
|
||||
yIn += pSrcDrawable->y;
|
||||
|
||||
xOut += pDstDrawable->x;
|
||||
yOut += pDstDrawable->y;
|
||||
|
||||
box_x1 = xIn;
|
||||
box_y1 = yIn;
|
||||
box_x2 = xIn + widthSrc;
|
||||
box_y2 = yIn + heightSrc;
|
||||
|
||||
dx = xIn - xOut;
|
||||
dy = yIn - yOut;
|
||||
|
||||
/* Don't create a source region if we are doing a fast clip */
|
||||
if (fastSrc) {
|
||||
RegionPtr cclip;
|
||||
|
||||
fastExpose = TRUE;
|
||||
/*
|
||||
* clip the source; if regions extend beyond the source size,
|
||||
* make sure exposure events get sent
|
||||
*/
|
||||
if (box_x1 < pSrcDrawable->x) {
|
||||
box_x1 = pSrcDrawable->x;
|
||||
fastExpose = FALSE;
|
||||
}
|
||||
if (box_y1 < pSrcDrawable->y) {
|
||||
box_y1 = pSrcDrawable->y;
|
||||
fastExpose = FALSE;
|
||||
}
|
||||
if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width) {
|
||||
box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
|
||||
fastExpose = FALSE;
|
||||
}
|
||||
if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height) {
|
||||
box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
|
||||
fastExpose = FALSE;
|
||||
}
|
||||
|
||||
/* Translate and clip the dst to the destination composite clip */
|
||||
box_x1 -= dx;
|
||||
box_x2 -= dx;
|
||||
box_y1 -= dy;
|
||||
box_y2 -= dy;
|
||||
|
||||
/* If the destination composite clip is one rectangle we can
|
||||
do the clip directly. Otherwise we have to create a full
|
||||
blown region and call intersect */
|
||||
|
||||
cclip = fbGetCompositeClip(pGC);
|
||||
if (REGION_NUM_RECTS(cclip) == 1) {
|
||||
BoxPtr pBox = REGION_RECTS(cclip);
|
||||
|
||||
if (box_x1 < pBox->x1)
|
||||
box_x1 = pBox->x1;
|
||||
if (box_x2 > pBox->x2)
|
||||
box_x2 = pBox->x2;
|
||||
if (box_y1 < pBox->y1)
|
||||
box_y1 = pBox->y1;
|
||||
if (box_y2 > pBox->y2)
|
||||
box_y2 = pBox->y2;
|
||||
fastDst = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if the region is empty */
|
||||
if (box_x1 >= box_x2 || box_y1 >= box_y2) {
|
||||
REGION_NULL(&rgnDst);
|
||||
}
|
||||
else {
|
||||
BoxRec box;
|
||||
|
||||
box.x1 = box_x1;
|
||||
box.y1 = box_y1;
|
||||
box.x2 = box_x2;
|
||||
box.y2 = box_y2;
|
||||
REGION_INIT(&rgnDst, &box, 1);
|
||||
}
|
||||
|
||||
/* Clip against complex source if needed */
|
||||
if (!fastSrc) {
|
||||
REGION_INTERSECT(&rgnDst, &rgnDst, prgnSrcClip);
|
||||
REGION_TRANSLATE(&rgnDst, -dx, -dy);
|
||||
}
|
||||
|
||||
/* Clip against complex dest if needed */
|
||||
if (!fastDst) {
|
||||
REGION_INTERSECT(&rgnDst, &rgnDst,
|
||||
fbGetCompositeClip(pGC));
|
||||
}
|
||||
|
||||
/* Do bit blitting */
|
||||
numRects = REGION_NUM_RECTS(&rgnDst);
|
||||
if (numRects && widthSrc && heightSrc)
|
||||
fbCopyRegion(pSrcDrawable, pDstDrawable, pGC,
|
||||
&rgnDst, dx, dy, copyProc, bitPlane, closure);
|
||||
|
||||
/* Pixmap sources generate a NoExposed (we return NULL to do this) */
|
||||
if (!fastExpose && pGC->fExpose)
|
||||
prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
|
||||
xIn - pSrcDrawable->x,
|
||||
yIn - pSrcDrawable->y,
|
||||
widthSrc, heightSrc,
|
||||
xOut - pDstDrawable->x,
|
||||
yOut - pDstDrawable->y,
|
||||
(unsigned long) bitPlane);
|
||||
REGION_UNINIT(&rgnDst);
|
||||
if (freeSrcClip)
|
||||
REGION_DESTROY(prgnSrcClip);
|
||||
fbValidateDrawable(pDstDrawable);
|
||||
return prgnExposed;
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
fbCopyArea(DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut)
|
||||
{
|
||||
fbCopyProc copy;
|
||||
|
||||
if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
|
||||
copy = fb24_32CopyMtoN;
|
||||
else
|
||||
copy = fbCopyNtoN;
|
||||
return fbDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
|
||||
widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
fbCopyPlane(DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
int xIn,
|
||||
int yIn,
|
||||
int widthSrc,
|
||||
int heightSrc, int xOut, int yOut, unsigned long bitplane)
|
||||
{
|
||||
if (pSrcDrawable->bitsPerPixel > 1)
|
||||
return fbDoCopy(pSrcDrawable, pDstDrawable, pGC,
|
||||
xIn, yIn, widthSrc, heightSrc,
|
||||
xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
|
||||
else if (bitplane & 1)
|
||||
return fbDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
|
||||
widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
|
||||
(Pixel) bitplane, 0);
|
||||
else
|
||||
return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
|
||||
xIn, yIn,
|
||||
widthSrc, heightSrc, xOut, yOut, bitplane);
|
||||
}
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
|
||||
#include "picturestr.h"
|
||||
#include "mipict.h"
|
||||
#include "renderedge.h"
|
||||
#include "fbpict.h"
|
||||
|
||||
/*
|
||||
* 4 bit alpha
|
||||
*/
|
||||
|
||||
#define N_BITS 4
|
||||
#define rasterizeEdges fbRasterizeEdges4
|
||||
|
||||
#if BITMAP_BIT_ORDER == LSBFirst
|
||||
#define Shift4(o) ((o) << 2)
|
||||
#else
|
||||
#define Shift4(o) ((1-(o)) << 2)
|
||||
#endif
|
||||
|
||||
#define Get4(x,o) (((x) >> Shift4(o)) & 0xf)
|
||||
#define Put4(x,o,v) (((x) & ~(0xf << Shift4(o))) | (((v) & 0xf) << Shift4(o)))
|
||||
|
||||
#define DefineAlpha(line,x) \
|
||||
CARD8 *__ap = (CARD8 *) line + ((x) >> 1); \
|
||||
int __ao = (x) & 1
|
||||
|
||||
#define StepAlpha ((__ap += __ao), (__ao ^= 1))
|
||||
|
||||
#define AddAlpha(a) { \
|
||||
CARD8 __o = *__ap; \
|
||||
CARD8 __a = (a) + Get4(__o, __ao); \
|
||||
*__ap = Put4 (__o, __ao, __a | (0 - ((__a) >> 4))); \
|
||||
}
|
||||
|
||||
#include "fbedgeimp.h"
|
||||
|
||||
#undef AddAlpha
|
||||
#undef StepAlpha
|
||||
#undef DefineAlpha
|
||||
#undef rasterizeEdges
|
||||
#undef N_BITS
|
||||
|
||||
/*
|
||||
* 1 bit alpha
|
||||
*/
|
||||
|
||||
#define N_BITS 1
|
||||
#define rasterizeEdges fbRasterizeEdges1
|
||||
|
||||
#include "fbedgeimp.h"
|
||||
|
||||
#undef rasterizeEdges
|
||||
#undef N_BITS
|
||||
|
||||
/*
|
||||
* 8 bit alpha
|
||||
*/
|
||||
|
||||
static INLINE CARD8
|
||||
clip255(int x)
|
||||
{
|
||||
if (x > 255)
|
||||
return 255;
|
||||
return x;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
add_saturate_8(CARD8 *buf, int value, int length)
|
||||
{
|
||||
while (length--) {
|
||||
*buf = clip255(*buf + value);
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We want to detect the case where we add the same value to a long
|
||||
* span of pixels. The triangles on the end are filled in while we
|
||||
* count how many sub-pixel scanlines contribute to the middle section.
|
||||
*
|
||||
* +--------------------------+
|
||||
* fill_height =| \ /
|
||||
* +------------------+
|
||||
* |================|
|
||||
* fill_start fill_end
|
||||
*/
|
||||
static void
|
||||
fbRasterizeEdges8(FbBits * buf,
|
||||
int width,
|
||||
int stride,
|
||||
RenderEdge * l, RenderEdge * r, xFixed t, xFixed b)
|
||||
{
|
||||
xFixed y = t;
|
||||
|
||||
FbBits *line;
|
||||
|
||||
int fill_start = -1, fill_end = -1;
|
||||
|
||||
int fill_size = 0;
|
||||
|
||||
line = buf + xFixedToInt(y) * stride;
|
||||
|
||||
for (;;) {
|
||||
CARD8 *ap = (CARD8 *) line;
|
||||
|
||||
xFixed lx, rx;
|
||||
|
||||
int lxi, rxi;
|
||||
|
||||
/* clip X */
|
||||
lx = l->x;
|
||||
if (lx < 0)
|
||||
lx = 0;
|
||||
rx = r->x;
|
||||
if (xFixedToInt(rx) >= width)
|
||||
rx = IntToxFixed(width);
|
||||
|
||||
/* Skip empty (or backwards) sections */
|
||||
if (rx > lx) {
|
||||
int lxs, rxs;
|
||||
|
||||
/* Find pixel bounds for span. */
|
||||
lxi = xFixedToInt(lx);
|
||||
rxi = xFixedToInt(rx);
|
||||
|
||||
/* Sample coverage for edge pixels */
|
||||
lxs = RenderSamplesX(lx, 8);
|
||||
rxs = RenderSamplesX(rx, 8);
|
||||
|
||||
/* Add coverage across row */
|
||||
if (lxi == rxi) {
|
||||
ap[lxi] = clip255(ap[lxi] + rxs - lxs);
|
||||
}
|
||||
else {
|
||||
ap[lxi] = clip255(ap[lxi] + N_X_FRAC(8) - lxs);
|
||||
|
||||
/* Move forward so that lxi/rxi is the pixel span */
|
||||
lxi++;
|
||||
|
||||
/* Don't bother trying to optimize the fill unless
|
||||
* the span is longer than 4 pixels. */
|
||||
if (rxi - lxi > 4) {
|
||||
if (fill_start < 0) {
|
||||
fill_start = lxi;
|
||||
fill_end = rxi;
|
||||
fill_size++;
|
||||
}
|
||||
else {
|
||||
if (lxi >= fill_end || rxi < fill_start) {
|
||||
/* We're beyond what we saved, just fill it */
|
||||
add_saturate_8(ap + fill_start,
|
||||
fill_size * N_X_FRAC(8),
|
||||
fill_end - fill_start);
|
||||
fill_start = lxi;
|
||||
fill_end = rxi;
|
||||
fill_size = 1;
|
||||
}
|
||||
else {
|
||||
/* Update fill_start */
|
||||
if (lxi > fill_start) {
|
||||
add_saturate_8(ap + fill_start,
|
||||
fill_size * N_X_FRAC(8),
|
||||
lxi - fill_start);
|
||||
fill_start = lxi;
|
||||
}
|
||||
else if (lxi < fill_start) {
|
||||
add_saturate_8(ap + lxi, N_X_FRAC(8),
|
||||
fill_start - lxi);
|
||||
}
|
||||
|
||||
/* Update fill_end */
|
||||
if (rxi < fill_end) {
|
||||
add_saturate_8(ap + rxi,
|
||||
fill_size * N_X_FRAC(8),
|
||||
fill_end - rxi);
|
||||
fill_end = rxi;
|
||||
}
|
||||
else if (fill_end < rxi) {
|
||||
add_saturate_8(ap + fill_end,
|
||||
N_X_FRAC(8), rxi - fill_end);
|
||||
}
|
||||
fill_size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
add_saturate_8(ap + lxi, N_X_FRAC(8), rxi - lxi);
|
||||
}
|
||||
|
||||
/* Do not add in a 0 alpha here. This check is
|
||||
* necessary to avoid a buffer overrun, (when rx
|
||||
* is exactly on a pixel boundary). */
|
||||
if (rxs)
|
||||
ap[rxi] = clip255(ap[rxi] + rxs);
|
||||
}
|
||||
}
|
||||
|
||||
if (y == b) {
|
||||
/* We're done, make sure we clean up any remaining fill. */
|
||||
if (fill_start != fill_end) {
|
||||
if (fill_size == N_Y_FRAC(8)) {
|
||||
memset(ap + fill_start, 0xff, fill_end - fill_start);
|
||||
}
|
||||
else {
|
||||
add_saturate_8(ap + fill_start, fill_size * N_X_FRAC(8),
|
||||
fill_end - fill_start);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (xFixedFrac(y) != Y_FRAC_LAST(8)) {
|
||||
RenderEdgeStepSmall(l);
|
||||
RenderEdgeStepSmall(r);
|
||||
y += STEP_Y_SMALL(8);
|
||||
}
|
||||
else {
|
||||
RenderEdgeStepBig(l);
|
||||
RenderEdgeStepBig(r);
|
||||
y += STEP_Y_BIG(8);
|
||||
if (fill_start != fill_end) {
|
||||
if (fill_size == N_Y_FRAC(8)) {
|
||||
memset(ap + fill_start, 0xff, fill_end - fill_start);
|
||||
}
|
||||
else {
|
||||
add_saturate_8(ap + fill_start, fill_size * N_X_FRAC(8),
|
||||
fill_end - fill_start);
|
||||
}
|
||||
fill_start = fill_end = -1;
|
||||
fill_size = 0;
|
||||
}
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbRasterizeEdges(FbBits * buf,
|
||||
int bpp,
|
||||
int width,
|
||||
int stride, RenderEdge * l, RenderEdge * r, xFixed t, xFixed b)
|
||||
{
|
||||
switch (bpp) {
|
||||
case 1:
|
||||
fbRasterizeEdges1(buf, width, stride, l, r, t, b);
|
||||
break;
|
||||
case 4:
|
||||
fbRasterizeEdges4(buf, width, stride, l, r, t, b);
|
||||
break;
|
||||
case 8:
|
||||
fbRasterizeEdges8(buf, width, stride, l, r, t, b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef rasterizeSpan
|
||||
#endif
|
||||
|
||||
static void
|
||||
rasterizeEdges(FbBits * buf,
|
||||
int width,
|
||||
int stride, RenderEdge * l, RenderEdge * r, xFixed t, xFixed b)
|
||||
{
|
||||
xFixed y = t;
|
||||
|
||||
FbBits *line;
|
||||
|
||||
line = buf + xFixedToInt(y) * stride;
|
||||
|
||||
for (;;) {
|
||||
xFixed lx, rx;
|
||||
|
||||
int lxi, rxi;
|
||||
|
||||
/* clip X */
|
||||
lx = l->x;
|
||||
if (lx < 0)
|
||||
lx = 0;
|
||||
rx = r->x;
|
||||
if (xFixedToInt(rx) >= width)
|
||||
rx = IntToxFixed(width);
|
||||
|
||||
/* Skip empty (or backwards) sections */
|
||||
if (rx > lx) {
|
||||
|
||||
/* Find pixel bounds for span */
|
||||
lxi = xFixedToInt(lx);
|
||||
rxi = xFixedToInt(rx);
|
||||
|
||||
#if N_BITS == 1
|
||||
{
|
||||
FbBits *a = line;
|
||||
|
||||
FbBits startmask, endmask;
|
||||
|
||||
int nmiddle;
|
||||
|
||||
int width = rxi - lxi;
|
||||
|
||||
int x = lxi;
|
||||
|
||||
a += x >> FB_SHIFT;
|
||||
x &= FB_MASK;
|
||||
|
||||
FbMaskBits(x, width, startmask, nmiddle, endmask);
|
||||
if (startmask)
|
||||
*a++ |= startmask;
|
||||
while (nmiddle--)
|
||||
*a++ = FB_ALLONES;
|
||||
if (endmask)
|
||||
*a |= endmask;
|
||||
}
|
||||
#else
|
||||
{
|
||||
DefineAlpha(line, lxi);
|
||||
int lxs, rxs;
|
||||
|
||||
/* Sample coverage for edge pixels */
|
||||
lxs = RenderSamplesX(lx, N_BITS);
|
||||
rxs = RenderSamplesX(rx, N_BITS);
|
||||
|
||||
/* Add coverage across row */
|
||||
if (lxi == rxi) {
|
||||
AddAlpha(rxs - lxs);
|
||||
}
|
||||
else {
|
||||
int xi;
|
||||
|
||||
AddAlpha(N_X_FRAC(N_BITS) - lxs);
|
||||
StepAlpha;
|
||||
for (xi = lxi + 1; xi < rxi; xi++) {
|
||||
AddAlpha(N_X_FRAC(N_BITS));
|
||||
StepAlpha;
|
||||
}
|
||||
/* Do not add in a 0 alpha here. This check is necessary
|
||||
* to avoid a buffer overrun when rx is exactly on a pixel
|
||||
* boundary.
|
||||
*/
|
||||
if (rxs != 0)
|
||||
AddAlpha(rxs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (y == b)
|
||||
break;
|
||||
|
||||
#if N_BITS > 1
|
||||
if (xFixedFrac(y) != Y_FRAC_LAST(N_BITS)) {
|
||||
RenderEdgeStepSmall(l);
|
||||
RenderEdgeStepSmall(r);
|
||||
y += STEP_Y_SMALL(N_BITS);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RenderEdgeStepBig(l);
|
||||
RenderEdgeStepBig(r);
|
||||
y += STEP_Y_BIG(N_BITS);
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef rasterizeSpan
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height)
|
||||
{
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
switch (pGC->fillStyle) {
|
||||
case FillSolid:
|
||||
fbSolid(dst + (y + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(x + dstXoff) * dstBpp,
|
||||
dstBpp, width * dstBpp, height, pPriv->and, pPriv->xor);
|
||||
break;
|
||||
case FillStippled:
|
||||
case FillOpaqueStippled:{
|
||||
PixmapPtr pStip = pGC->stipple;
|
||||
|
||||
int stipWidth = pStip->drawable.width;
|
||||
|
||||
int stipHeight = pStip->drawable.height;
|
||||
|
||||
if (dstBpp == 1) {
|
||||
int alu;
|
||||
|
||||
FbBits *stip;
|
||||
|
||||
FbStride stipStride;
|
||||
|
||||
int stipBpp;
|
||||
|
||||
int stipXoff _X_UNUSED, stipYoff _X_UNUSED;
|
||||
|
||||
if (pGC->fillStyle == FillStippled)
|
||||
alu = FbStipple1Rop(pGC->alu, pGC->fgPixel);
|
||||
else
|
||||
alu = FbOpaqueStipple1Rop(pGC->alu, pGC->fgPixel, pGC->bgPixel);
|
||||
fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff,
|
||||
stipYoff);
|
||||
fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff,
|
||||
width, height, stip, stipStride, stipWidth, stipHeight, alu,
|
||||
pPriv->pm, dstBpp, (pGC->patOrg.x + pDrawable->x + dstXoff),
|
||||
pGC->patOrg.y + pDrawable->y - y);
|
||||
}
|
||||
else {
|
||||
FbStip *stip;
|
||||
|
||||
FbStride stipStride;
|
||||
|
||||
int stipBpp;
|
||||
|
||||
int stipXoff _X_UNUSED, stipYoff _X_UNUSED;
|
||||
|
||||
FbBits fgand, fgxor, bgand, bgxor;
|
||||
|
||||
fgand = pPriv->and;
|
||||
fgxor = pPriv->xor;
|
||||
if (pGC->fillStyle == FillStippled) {
|
||||
bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES);
|
||||
bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES);
|
||||
}
|
||||
else {
|
||||
bgand = pPriv->bgand;
|
||||
bgxor = pPriv->bgxor;
|
||||
}
|
||||
|
||||
fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp,
|
||||
stipXoff, stipYoff);
|
||||
fbStipple(dst + (y + dstYoff) * dstStride, dstStride,
|
||||
(x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height,
|
||||
stip, stipStride, stipWidth, stipHeight,
|
||||
pPriv->evenStipple, fgand, fgxor, bgand, bgxor,
|
||||
pGC->patOrg.x + pDrawable->x + dstXoff,
|
||||
pGC->patOrg.y + pDrawable->y - y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FillTiled:{
|
||||
PixmapPtr pTile = pGC->tile.pixmap;
|
||||
|
||||
FbBits *tile;
|
||||
|
||||
FbStride tileStride;
|
||||
|
||||
int tileBpp;
|
||||
|
||||
int tileWidth;
|
||||
|
||||
int tileHeight;
|
||||
|
||||
int tileXoff _X_UNUSED, tileYoff _X_UNUSED; /* XXX assumed to be zero */
|
||||
|
||||
fbGetDrawable(&pTile->drawable, tile, tileStride, tileBpp, tileXoff,
|
||||
tileYoff);
|
||||
tileWidth = pTile->drawable.width;
|
||||
tileHeight = pTile->drawable.height;
|
||||
fbTile(dst + (y + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(x + dstXoff) * dstBpp,
|
||||
width * dstBpp, height,
|
||||
tile,
|
||||
tileStride,
|
||||
tileWidth * tileBpp,
|
||||
tileHeight,
|
||||
pGC->alu,
|
||||
pPriv->pm,
|
||||
dstBpp,
|
||||
(pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
|
||||
pGC->patOrg.y + pDrawable->y - y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fbValidateDrawable(pDrawable);
|
||||
}
|
||||
|
||||
void
|
||||
fbSolidBoxClipped(DrawablePtr pDrawable,
|
||||
RegionPtr pClip,
|
||||
int x1, int y1, int x2, int y2, FbBits and, FbBits xor)
|
||||
{
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
BoxPtr pbox;
|
||||
|
||||
int nbox;
|
||||
|
||||
int partX1, partX2, partY1, partY2;
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
|
||||
nbox--; pbox++) {
|
||||
partX1 = pbox->x1;
|
||||
if (partX1 < x1)
|
||||
partX1 = x1;
|
||||
|
||||
partX2 = pbox->x2;
|
||||
if (partX2 > x2)
|
||||
partX2 = x2;
|
||||
|
||||
if (partX2 <= partX1)
|
||||
continue;
|
||||
|
||||
partY1 = pbox->y1;
|
||||
if (partY1 < y1)
|
||||
partY1 = y1;
|
||||
|
||||
partY2 = pbox->y2;
|
||||
if (partY2 > y2)
|
||||
partY2 = y2;
|
||||
|
||||
if (partY2 <= partY1)
|
||||
continue;
|
||||
|
||||
fbSolid(dst + (partY1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(partX1 + dstXoff) * dstBpp,
|
||||
dstBpp,
|
||||
(partX2 - partX1) * dstBpp, (partY2 - partY1), and, xor);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect)
|
||||
{
|
||||
RegionPtr pClip = fbGetCompositeClip(pGC);
|
||||
BoxPtr pbox;
|
||||
BoxPtr pextent;
|
||||
int extentX1, extentX2, extentY1, extentY2;
|
||||
int fullX1, fullX2, fullY1, fullY2;
|
||||
int partX1, partX2, partY1, partY2;
|
||||
int xorg, yorg;
|
||||
int n;
|
||||
|
||||
xorg = pDrawable->x;
|
||||
yorg = pDrawable->y;
|
||||
|
||||
pextent = REGION_EXTENTS(pClip);
|
||||
extentX1 = pextent->x1;
|
||||
extentY1 = pextent->y1;
|
||||
extentX2 = pextent->x2;
|
||||
extentY2 = pextent->y2;
|
||||
while (nrect--) {
|
||||
fullX1 = prect->x + xorg;
|
||||
fullY1 = prect->y + yorg;
|
||||
fullX2 = fullX1 + (int) prect->width;
|
||||
fullY2 = fullY1 + (int) prect->height;
|
||||
prect++;
|
||||
|
||||
if (fullX1 < extentX1)
|
||||
fullX1 = extentX1;
|
||||
|
||||
if (fullY1 < extentY1)
|
||||
fullY1 = extentY1;
|
||||
|
||||
if (fullX2 > extentX2)
|
||||
fullX2 = extentX2;
|
||||
|
||||
if (fullY2 > extentY2)
|
||||
fullY2 = extentY2;
|
||||
|
||||
if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
|
||||
continue;
|
||||
n = REGION_NUM_RECTS(pClip);
|
||||
if (n == 1) {
|
||||
fbFill(pDrawable,
|
||||
pGC, fullX1, fullY1, fullX2 - fullX1, fullY2 - fullY1);
|
||||
}
|
||||
else {
|
||||
pbox = REGION_RECTS(pClip);
|
||||
/*
|
||||
* clip the rectangle to each box in the clip region
|
||||
* this is logically equivalent to calling Intersect()
|
||||
*/
|
||||
while (n--) {
|
||||
partX1 = pbox->x1;
|
||||
if (partX1 < fullX1)
|
||||
partX1 = fullX1;
|
||||
partY1 = pbox->y1;
|
||||
if (partY1 < fullY1)
|
||||
partY1 = fullY1;
|
||||
partX2 = pbox->x2;
|
||||
if (partX2 > fullX2)
|
||||
partX2 = fullX2;
|
||||
partY2 = pbox->y2;
|
||||
if (partY2 > fullY2)
|
||||
partY2 = fullY2;
|
||||
|
||||
pbox++;
|
||||
|
||||
if (partX1 < partX2 && partY1 < partY2)
|
||||
fbFill(pDrawable, pGC,
|
||||
partX1, partY1, partX2 - partX1, partY2 - partY1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbFillSpans(DrawablePtr pDrawable,
|
||||
GCPtr pGC, int n, DDXPointPtr ppt, int *pwidth, int fSorted)
|
||||
{
|
||||
RegionPtr pClip = fbGetCompositeClip(pGC);
|
||||
|
||||
BoxPtr pextent, pbox;
|
||||
|
||||
int nbox;
|
||||
|
||||
int extentX1, extentX2, extentY1, extentY2;
|
||||
|
||||
int fullX1, fullX2, fullY1;
|
||||
|
||||
int partX1, partX2;
|
||||
|
||||
pextent = REGION_EXTENTS(pClip);
|
||||
extentX1 = pextent->x1;
|
||||
extentY1 = pextent->y1;
|
||||
extentX2 = pextent->x2;
|
||||
extentY2 = pextent->y2;
|
||||
while (n--) {
|
||||
fullX1 = ppt->x;
|
||||
fullY1 = ppt->y;
|
||||
fullX2 = fullX1 + (int) *pwidth;
|
||||
ppt++;
|
||||
pwidth++;
|
||||
|
||||
if (fullY1 < extentY1 || extentY2 <= fullY1)
|
||||
continue;
|
||||
|
||||
if (fullX1 < extentX1)
|
||||
fullX1 = extentX1;
|
||||
|
||||
if (fullX2 > extentX2)
|
||||
fullX2 = extentX2;
|
||||
|
||||
if (fullX1 >= fullX2)
|
||||
continue;
|
||||
|
||||
nbox = REGION_NUM_RECTS(pClip);
|
||||
if (nbox == 1) {
|
||||
fbFill(pDrawable, pGC, fullX1, fullY1, fullX2 - fullX1, 1);
|
||||
}
|
||||
else {
|
||||
pbox = REGION_RECTS(pClip);
|
||||
while (nbox--) {
|
||||
if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) {
|
||||
partX1 = pbox->x1;
|
||||
if (partX1 < fullX1)
|
||||
partX1 = fullX1;
|
||||
partX2 = pbox->x2;
|
||||
if (partX2 > fullX2)
|
||||
partX2 = fullX2;
|
||||
if (partX2 > partX1) {
|
||||
fbFill(pDrawable, pGC,
|
||||
partX1, fullY1, partX2 - partX1, 1);
|
||||
}
|
||||
}
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
const GCFuncs fbGCFuncs = {
|
||||
fbValidateGC,
|
||||
miChangeGC,
|
||||
miCopyGC,
|
||||
miDestroyGC,
|
||||
miChangeClip,
|
||||
miDestroyClip,
|
||||
miCopyClip,
|
||||
};
|
||||
|
||||
const GCOps fbGCOps = {
|
||||
fbFillSpans,
|
||||
fbSetSpans,
|
||||
fbPutImage,
|
||||
fbCopyArea,
|
||||
fbCopyPlane,
|
||||
fbPolyPoint,
|
||||
fbPolyLine,
|
||||
fbPolySegment,
|
||||
fbPolyRectangle,
|
||||
fbPolyArc,
|
||||
miFillPolygon,
|
||||
fbPolyFillRect,
|
||||
fbPolyFillArc,
|
||||
miPolyText8,
|
||||
miPolyText16,
|
||||
miImageText8,
|
||||
miImageText16,
|
||||
fbImageGlyphBlt,
|
||||
fbPolyGlyphBlt,
|
||||
fbPushPixels
|
||||
};
|
||||
|
||||
Bool
|
||||
fbCreateGC(GCPtr pGC)
|
||||
{
|
||||
pGC->clientClip = NULL;
|
||||
pGC->clientClipType = CT_NONE;
|
||||
|
||||
pGC->ops = (GCOps *) & fbGCOps;
|
||||
pGC->funcs = (GCFuncs *) & fbGCFuncs;
|
||||
|
||||
/* fb wants to translate before scan conversion */
|
||||
pGC->miTranslate = 1;
|
||||
|
||||
fbGetRotatedPixmap(pGC) = 0;
|
||||
fbGetExpose(pGC) = 1;
|
||||
fbGetFreeCompClip(pGC) = 0;
|
||||
fbGetCompositeClip(pGC) = 0;
|
||||
fbGetGCPrivate(pGC)->bpp = BitsPerPixel(pGC->depth);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pad pixmap to FB_UNIT bits wide
|
||||
*/
|
||||
void
|
||||
fbPadPixmap(PixmapPtr pPixmap)
|
||||
{
|
||||
int width;
|
||||
|
||||
FbBits *bits;
|
||||
|
||||
FbBits b;
|
||||
|
||||
FbBits mask;
|
||||
|
||||
int height;
|
||||
|
||||
int w;
|
||||
|
||||
int stride;
|
||||
|
||||
int bpp;
|
||||
|
||||
int xOff _X_UNUSED, yOff _X_UNUSED;
|
||||
|
||||
fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff);
|
||||
|
||||
width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
|
||||
height = pPixmap->drawable.height;
|
||||
mask = FbBitsMask(0, width);
|
||||
while (height--) {
|
||||
b = *bits & mask;
|
||||
w = width;
|
||||
while (w < FB_UNIT) {
|
||||
b = b | FbScrRight(b, w);
|
||||
w <<= 1;
|
||||
}
|
||||
*bits = b;
|
||||
bits += stride;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that 'bits' repeats every 'len' bits
|
||||
*/
|
||||
static Bool
|
||||
fbBitsRepeat(FbBits bits, int len, int width)
|
||||
{
|
||||
FbBits mask = FbBitsMask(0, len);
|
||||
|
||||
FbBits orig = bits & mask;
|
||||
|
||||
int i;
|
||||
|
||||
if (width > FB_UNIT)
|
||||
width = FB_UNIT;
|
||||
for (i = 0; i < width / len; i++) {
|
||||
if ((bits & mask) != orig)
|
||||
return FALSE;
|
||||
bits = FbScrLeft(bits, len);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether an entire bitmap line is a repetition of
|
||||
* the first 'len' bits
|
||||
*/
|
||||
static Bool
|
||||
fbLineRepeat(FbBits * bits, int len, int width)
|
||||
{
|
||||
FbBits first = bits[0];
|
||||
|
||||
if (!fbBitsRepeat(first, len, width))
|
||||
return FALSE;
|
||||
width = (width + FB_UNIT - 1) >> FB_SHIFT;
|
||||
bits++;
|
||||
while (--width)
|
||||
if (*bits != first)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The even stipple code wants the first FB_UNIT/bpp bits on
|
||||
* each scanline to represent the entire stipple
|
||||
*/
|
||||
static Bool
|
||||
fbCanEvenStipple(PixmapPtr pStipple, int bpp)
|
||||
{
|
||||
int len = FB_UNIT / bpp;
|
||||
|
||||
FbBits *bits;
|
||||
|
||||
int stride;
|
||||
|
||||
int stip_bpp;
|
||||
|
||||
int stipXoff _X_UNUSED, stipYoff _X_UNUSED;
|
||||
|
||||
int h;
|
||||
|
||||
/* can't even stipple 24bpp drawables */
|
||||
if ((bpp & (bpp - 1)) != 0)
|
||||
return FALSE;
|
||||
/* make sure the stipple width is a multiple of the even stipple width */
|
||||
if (pStipple->drawable.width % len != 0)
|
||||
return FALSE;
|
||||
fbGetDrawable(&pStipple->drawable, bits, stride, stip_bpp, stipXoff,
|
||||
stipYoff);
|
||||
h = pStipple->drawable.height;
|
||||
/* check to see that the stipple repeats horizontally */
|
||||
while (h--) {
|
||||
if (!fbLineRepeat(bits, len, pStipple->drawable.width))
|
||||
return FALSE;
|
||||
bits += stride;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
FbBits mask;
|
||||
|
||||
pGC->lastWinOrg.x = pDrawable->x;
|
||||
pGC->lastWinOrg.y = pDrawable->y;
|
||||
|
||||
/*
|
||||
* if the client clip is different or moved OR the subwindowMode has
|
||||
* changed OR the window's clip has changed since the last validation
|
||||
* we need to recompute the composite clip
|
||||
*/
|
||||
|
||||
if ((changes &
|
||||
(GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) ||
|
||||
(pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
|
||||
) {
|
||||
miComputeCompositeClip(pGC, pDrawable);
|
||||
pPriv->oneRect = REGION_NUM_RECTS(fbGetCompositeClip(pGC)) == 1;
|
||||
}
|
||||
|
||||
if (pPriv->bpp != pDrawable->bitsPerPixel) {
|
||||
changes |= GCStipple | GCForeground | GCBackground | GCPlaneMask;
|
||||
pPriv->bpp = pDrawable->bitsPerPixel;
|
||||
}
|
||||
if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) {
|
||||
(*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
|
||||
fbGetRotatedPixmap(pGC) = 0;
|
||||
}
|
||||
|
||||
if (pGC->fillStyle == FillTiled) {
|
||||
PixmapPtr pOldTile, pNewTile;
|
||||
|
||||
pOldTile = pGC->tile.pixmap;
|
||||
if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
|
||||
pNewTile = fbGetRotatedPixmap(pGC);
|
||||
if (!pNewTile ||
|
||||
pNewTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
|
||||
if (pNewTile)
|
||||
(*pGC->pScreen->DestroyPixmap) (pNewTile);
|
||||
pNewTile =
|
||||
fb24_32ReformatTile(pOldTile, pDrawable->bitsPerPixel);
|
||||
}
|
||||
if (pNewTile) {
|
||||
fbGetRotatedPixmap(pGC) = pOldTile;
|
||||
pGC->tile.pixmap = pNewTile;
|
||||
changes |= GCTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changes & GCTile) {
|
||||
if (!pGC->tileIsPixel &&
|
||||
FbEvenTile(pGC->tile.pixmap->drawable.width *
|
||||
pDrawable->bitsPerPixel))
|
||||
fbPadPixmap(pGC->tile.pixmap);
|
||||
}
|
||||
if (changes & GCStipple) {
|
||||
pPriv->evenStipple = FALSE;
|
||||
|
||||
if (pGC->stipple) {
|
||||
|
||||
/* can we do an even stipple ?? */
|
||||
if (FbEvenStip(pGC->stipple->drawable.width,
|
||||
pDrawable->bitsPerPixel) &&
|
||||
(fbCanEvenStipple(pGC->stipple, pDrawable->bitsPerPixel)))
|
||||
pPriv->evenStipple = TRUE;
|
||||
|
||||
if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel <
|
||||
FB_UNIT)
|
||||
fbPadPixmap(pGC->stipple);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Recompute reduced rop values
|
||||
*/
|
||||
if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) {
|
||||
int s;
|
||||
|
||||
FbBits depthMask;
|
||||
|
||||
mask = FbFullMask(pDrawable->bitsPerPixel);
|
||||
depthMask = FbFullMask(pDrawable->depth);
|
||||
|
||||
pPriv->fg = pGC->fgPixel & mask;
|
||||
pPriv->bg = pGC->bgPixel & mask;
|
||||
|
||||
if ((pGC->planemask & depthMask) == depthMask)
|
||||
pPriv->pm = mask;
|
||||
else
|
||||
pPriv->pm = pGC->planemask & mask;
|
||||
|
||||
s = pDrawable->bitsPerPixel;
|
||||
while (s < FB_UNIT) {
|
||||
pPriv->fg |= pPriv->fg << s;
|
||||
pPriv->bg |= pPriv->bg << s;
|
||||
pPriv->pm |= pPriv->pm << s;
|
||||
s <<= 1;
|
||||
}
|
||||
pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
|
||||
pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
|
||||
pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
|
||||
pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
|
||||
}
|
||||
if (changes & GCDashList) {
|
||||
unsigned short n = pGC->numInDashList;
|
||||
|
||||
unsigned char *dash = pGC->dash;
|
||||
|
||||
unsigned int dashLength = 0;
|
||||
|
||||
while (n--)
|
||||
dashLength += (unsigned int) *dash++;
|
||||
pPriv->dashLength = dashLength;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbGetSpans(DrawablePtr pDrawable,
|
||||
int wMax,
|
||||
DDXPointPtr ppt, int *pwidth, int nspans, char *pchardstStart)
|
||||
{
|
||||
FbBits *src, *dst;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
int xoff;
|
||||
|
||||
/*
|
||||
* XFree86 DDX empties the root borderClip when the VT is
|
||||
* switched away; this checks for that case
|
||||
*/
|
||||
if (!fbDrawableEnabled(pDrawable))
|
||||
return;
|
||||
|
||||
if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
|
||||
fb24_32GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart);
|
||||
return;
|
||||
}
|
||||
|
||||
fbGetDrawable(pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
|
||||
|
||||
while (nspans--) {
|
||||
xoff = (int) (((long) pchardstStart) & (FB_MASK >> 3));
|
||||
dst = (FbBits *) (pchardstStart - xoff);
|
||||
xoff <<= 3;
|
||||
fbBlt(src + (ppt->y + srcYoff) * srcStride, srcStride,
|
||||
(ppt->x + srcXoff) * srcBpp,
|
||||
dst,
|
||||
1,
|
||||
xoff,
|
||||
*pwidth * srcBpp, 1, GXcopy, FB_ALLONES, srcBpp, FALSE, FALSE);
|
||||
pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth);
|
||||
ppt++;
|
||||
pwidth++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,451 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
#include <X11/fonts/fontstruct.h>
|
||||
#include "dixfontstr.h"
|
||||
|
||||
#define dummyScreen screenInfo.screens[0]
|
||||
|
||||
Bool
|
||||
fbGlyphIn(RegionPtr pRegion, int x, int y, int width, int height)
|
||||
{
|
||||
BoxRec box;
|
||||
|
||||
BoxPtr pExtents = REGION_EXTENTS(pRegion);
|
||||
|
||||
/*
|
||||
* Check extents by hand to avoid 16 bit overflows
|
||||
*/
|
||||
if (x < (int) pExtents->x1)
|
||||
return FALSE;
|
||||
if ((int) pExtents->x2 < x + width)
|
||||
return FALSE;
|
||||
if (y < (int) pExtents->y1)
|
||||
return FALSE;
|
||||
if ((int) pExtents->y2 < y + height)
|
||||
return FALSE;
|
||||
box.x1 = x;
|
||||
box.x2 = x + width;
|
||||
box.y1 = y;
|
||||
box.y2 = y + height;
|
||||
return RECT_IN_REGION(pRegion, &box) == rgnIN;
|
||||
}
|
||||
|
||||
|
||||
#define WRITE1(d,n,fg) ((d)[n] = (CARD8) fg)
|
||||
#define WRITE2(d,n,fg) (*(CARD16 *) &(d[n]) = (CARD16) fg)
|
||||
#define WRITE4(d,n,fg) (*(CARD32 *) &(d[n]) = (CARD32) fg)
|
||||
#if FB_UNIT == 6 && IMAGE_BYTE_ORDER == LSBFirst
|
||||
#define WRITE8(d) (*(FbBits *) &(d[0]) = fg)
|
||||
#else
|
||||
#define WRITE8(d) WRITE4(d,0,_ABCA), WRITE4(d,4,_BCAB)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is a bit tricky, but it's brief. Write 12 bytes worth
|
||||
* of dest, which is four pixels, at a time. This gives constant
|
||||
* code for each pattern as they're always aligned the same
|
||||
*
|
||||
* a b c d a b c d a b c d bytes
|
||||
* A B C A B C A B C A B C pixels
|
||||
*
|
||||
* f0 f1 f2
|
||||
* A B C A B C A B C A B C pixels LSB
|
||||
* C A B C A B C A B C A B pixels MSB
|
||||
*
|
||||
* LSB MSB
|
||||
* A f0 f1
|
||||
* B f1 f2
|
||||
* C f2 f0
|
||||
* A B f0 f2
|
||||
* B C f1 f0
|
||||
* C A f2 f1
|
||||
* A B C A f0 f1
|
||||
* B C A B f1 f2
|
||||
* C A B C f2 f0
|
||||
*/
|
||||
|
||||
#undef _A
|
||||
#undef _B
|
||||
#undef _C
|
||||
#undef _AB
|
||||
#undef _BC
|
||||
#undef _CA
|
||||
#undef _ABCA
|
||||
#undef _BCAB
|
||||
#undef _CABC
|
||||
|
||||
#if IMAGE_BYTE_ORDER == MSBFirst
|
||||
#define _A f1
|
||||
#define _B f2
|
||||
#define _C f0
|
||||
#define _AB f2
|
||||
#define _BC f0
|
||||
#define _CA f1
|
||||
#define _ABCA f1
|
||||
#define _BCAB f2
|
||||
#define _CABC f0
|
||||
#define CASE(a,b,c,d) ((a << 3) | (b << 2) | (c << 1) | d)
|
||||
#else
|
||||
#define _A f0
|
||||
#define _B f1
|
||||
#define _C f2
|
||||
#define _AB f0
|
||||
#define _BC f1
|
||||
#define _CA f2
|
||||
#define _ABCA f0
|
||||
#define _BCAB f1
|
||||
#define _CABC f2
|
||||
#define CASE(a,b,c,d) (a | (b << 1) | (c << 2) | (d << 3))
|
||||
#endif
|
||||
|
||||
void
|
||||
fbGlyph24(FbBits * dstBits,
|
||||
FbStride dstStride,
|
||||
int dstBpp, FbStip * stipple, FbBits fg, int x, int height)
|
||||
{
|
||||
int lshift;
|
||||
|
||||
FbStip bits;
|
||||
|
||||
CARD8 *dstLine;
|
||||
|
||||
CARD8 *dst;
|
||||
|
||||
FbStip f0, f1, f2;
|
||||
|
||||
int n;
|
||||
|
||||
int shift;
|
||||
|
||||
f0 = fg;
|
||||
f1 = FbRot24(f0, 16);
|
||||
f2 = FbRot24(f0, 8);
|
||||
|
||||
dstLine = (CARD8 *) dstBits;
|
||||
dstLine += (x & ~3) * 3;
|
||||
dstStride *= (sizeof(FbBits) / sizeof(CARD8));
|
||||
shift = x & 3;
|
||||
lshift = 4 - shift;
|
||||
while (height--) {
|
||||
bits = *stipple++;
|
||||
n = lshift;
|
||||
dst = dstLine;
|
||||
while (bits) {
|
||||
switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) {
|
||||
case CASE(0, 0, 0, 0):
|
||||
break;
|
||||
case CASE(1, 0, 0, 0):
|
||||
WRITE2(dst, 0, _AB);
|
||||
WRITE1(dst, 2, _C);
|
||||
break;
|
||||
case CASE(0, 1, 0, 0):
|
||||
WRITE1(dst, 3, _A);
|
||||
WRITE2(dst, 4, _BC);
|
||||
break;
|
||||
case CASE(1, 1, 0, 0):
|
||||
WRITE4(dst, 0, _ABCA);
|
||||
WRITE2(dst, 4, _BC);
|
||||
break;
|
||||
case CASE(0, 0, 1, 0):
|
||||
WRITE2(dst, 6, _AB);
|
||||
WRITE1(dst, 8, _C);
|
||||
break;
|
||||
case CASE(1, 0, 1, 0):
|
||||
WRITE2(dst, 0, _AB);
|
||||
WRITE1(dst, 2, _C);
|
||||
|
||||
WRITE2(dst, 6, _AB);
|
||||
WRITE1(dst, 8, _C);
|
||||
break;
|
||||
case CASE(0, 1, 1, 0):
|
||||
WRITE1(dst, 3, _A);
|
||||
WRITE4(dst, 4, _BCAB);
|
||||
WRITE1(dst, 8, _C);
|
||||
break;
|
||||
case CASE(1, 1, 1, 0):
|
||||
WRITE8(dst);
|
||||
WRITE1(dst, 8, _C);
|
||||
break;
|
||||
case CASE(0, 0, 0, 1):
|
||||
WRITE1(dst, 9, _A);
|
||||
WRITE2(dst, 10, _BC);
|
||||
break;
|
||||
case CASE(1, 0, 0, 1):
|
||||
WRITE2(dst, 0, _AB);
|
||||
WRITE1(dst, 2, _C);
|
||||
|
||||
WRITE1(dst, 9, _A);
|
||||
WRITE2(dst, 10, _BC);
|
||||
break;
|
||||
case CASE(0, 1, 0, 1):
|
||||
WRITE1(dst, 3, _A);
|
||||
WRITE2(dst, 4, _BC);
|
||||
|
||||
WRITE1(dst, 9, _A);
|
||||
WRITE2(dst, 10, _BC);
|
||||
break;
|
||||
case CASE(1, 1, 0, 1):
|
||||
WRITE4(dst, 0, _ABCA);
|
||||
WRITE2(dst, 4, _BC);
|
||||
|
||||
WRITE1(dst, 9, _A);
|
||||
WRITE2(dst, 10, _BC);
|
||||
break;
|
||||
case CASE(0, 0, 1, 1):
|
||||
WRITE2(dst, 6, _AB);
|
||||
WRITE4(dst, 8, _CABC);
|
||||
break;
|
||||
case CASE(1, 0, 1, 1):
|
||||
WRITE2(dst, 0, _AB);
|
||||
WRITE1(dst, 2, _C);
|
||||
|
||||
WRITE2(dst, 6, _AB);
|
||||
WRITE4(dst, 8, _CABC);
|
||||
break;
|
||||
case CASE(0, 1, 1, 1):
|
||||
WRITE1(dst, 3, _A);
|
||||
WRITE4(dst, 4, _BCAB);
|
||||
WRITE4(dst, 8, _CABC);
|
||||
break;
|
||||
case CASE(1, 1, 1, 1):
|
||||
WRITE8(dst);
|
||||
WRITE4(dst, 8, _CABC);
|
||||
break;
|
||||
}
|
||||
bits = FbStipLeft(bits, n);
|
||||
n = 4;
|
||||
dst += 12;
|
||||
}
|
||||
dstLine += dstStride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbPolyGlyphBlt(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
CharInfoPtr pci;
|
||||
|
||||
unsigned char *pglyph; /* pointer bits in glyph */
|
||||
|
||||
int gx, gy;
|
||||
|
||||
int gWidth, gHeight; /* width and height of glyph */
|
||||
|
||||
FbStride gStride; /* stride of glyph */
|
||||
|
||||
void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int);
|
||||
|
||||
FbBits *dst = 0;
|
||||
|
||||
FbStride dstStride = 0;
|
||||
|
||||
int dstBpp = 0;
|
||||
|
||||
int dstXoff = 0, dstYoff = 0;
|
||||
|
||||
glyph = 0;
|
||||
if (pGC->fillStyle == FillSolid && pPriv->and == 0) {
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
switch (dstBpp) {
|
||||
case 8:
|
||||
glyph = fbGlyph8;
|
||||
break;
|
||||
case 16:
|
||||
glyph = fbGlyph16;
|
||||
break;
|
||||
case 24:
|
||||
glyph = fbGlyph24;
|
||||
break;
|
||||
case 32:
|
||||
glyph = fbGlyph32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
x += pDrawable->x;
|
||||
y += pDrawable->y;
|
||||
|
||||
while (nglyph--) {
|
||||
pci = *ppci++;
|
||||
pglyph = FONTGLYPHBITS(pglyphBase, pci);
|
||||
gWidth = GLYPHWIDTHPIXELS(pci);
|
||||
gHeight = GLYPHHEIGHTPIXELS(pci);
|
||||
if (gWidth && gHeight) {
|
||||
gx = x + pci->metrics.leftSideBearing;
|
||||
gy = y - pci->metrics.ascent;
|
||||
if (glyph && gWidth <= sizeof(FbStip) * 8 &&
|
||||
fbGlyphIn(fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) {
|
||||
(*glyph) (dst + (gy + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
dstBpp,
|
||||
(FbStip *) pglyph, pPriv->xor, gx + dstXoff, gHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip);
|
||||
fbPushImage(pDrawable,
|
||||
pGC,
|
||||
(FbStip *) pglyph,
|
||||
gStride, 0, gx, gy, gWidth, gHeight);
|
||||
}
|
||||
}
|
||||
x += pci->metrics.characterWidth;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbImageGlyphBlt(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int nglyph, CharInfoPtr * ppciInit, pointer pglyphBase)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
CharInfoPtr *ppci;
|
||||
|
||||
CharInfoPtr pci;
|
||||
|
||||
unsigned char *pglyph; /* pointer bits in glyph */
|
||||
|
||||
int gWidth, gHeight; /* width and height of glyph */
|
||||
|
||||
FbStride gStride; /* stride of glyph */
|
||||
|
||||
Bool opaque;
|
||||
|
||||
int n;
|
||||
|
||||
int gx, gy;
|
||||
|
||||
void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int);
|
||||
|
||||
FbBits *dst = 0;
|
||||
|
||||
FbStride dstStride = 0;
|
||||
|
||||
int dstBpp = 0;
|
||||
|
||||
int dstXoff = 0, dstYoff = 0;
|
||||
|
||||
glyph = 0;
|
||||
if (pPriv->and == 0) {
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
switch (dstBpp) {
|
||||
case 8:
|
||||
glyph = fbGlyph8;
|
||||
break;
|
||||
case 16:
|
||||
glyph = fbGlyph16;
|
||||
break;
|
||||
case 24:
|
||||
glyph = fbGlyph24;
|
||||
break;
|
||||
case 32:
|
||||
glyph = fbGlyph32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
x += pDrawable->x;
|
||||
y += pDrawable->y;
|
||||
|
||||
if (TERMINALFONT(pGC->font)
|
||||
&& !glyph
|
||||
) {
|
||||
opaque = TRUE;
|
||||
}
|
||||
else {
|
||||
int xBack, widthBack;
|
||||
|
||||
int yBack, heightBack;
|
||||
|
||||
ppci = ppciInit;
|
||||
n = nglyph;
|
||||
widthBack = 0;
|
||||
while (n--)
|
||||
widthBack += (*ppci++)->metrics.characterWidth;
|
||||
|
||||
xBack = x;
|
||||
if (widthBack < 0) {
|
||||
xBack += widthBack;
|
||||
widthBack = -widthBack;
|
||||
}
|
||||
yBack = y - FONTASCENT(pGC->font);
|
||||
heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
|
||||
fbSolidBoxClipped(pDrawable,
|
||||
fbGetCompositeClip(pGC),
|
||||
xBack,
|
||||
yBack,
|
||||
xBack + widthBack,
|
||||
yBack + heightBack,
|
||||
fbAnd(GXcopy, pPriv->bg, pPriv->pm),
|
||||
fbXor(GXcopy, pPriv->bg, pPriv->pm));
|
||||
opaque = FALSE;
|
||||
}
|
||||
|
||||
ppci = ppciInit;
|
||||
while (nglyph--) {
|
||||
pci = *ppci++;
|
||||
pglyph = FONTGLYPHBITS(pglyphBase, pci);
|
||||
gWidth = GLYPHWIDTHPIXELS(pci);
|
||||
gHeight = GLYPHHEIGHTPIXELS(pci);
|
||||
if (gWidth && gHeight) {
|
||||
gx = x + pci->metrics.leftSideBearing;
|
||||
gy = y - pci->metrics.ascent;
|
||||
if (glyph && gWidth <= sizeof(FbStip) * 8 &&
|
||||
fbGlyphIn(fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) {
|
||||
(*glyph) (dst + (gy + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
dstBpp,
|
||||
(FbStip *) pglyph, pPriv->fg, gx + dstXoff, gHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip);
|
||||
fbPutXYImage(pDrawable,
|
||||
fbGetCompositeClip(pGC),
|
||||
pPriv->fg,
|
||||
pPriv->bg,
|
||||
pPriv->pm,
|
||||
GXcopy,
|
||||
opaque,
|
||||
gx,
|
||||
gy,
|
||||
gWidth, gHeight, (FbStip *) pglyph, gStride, 0);
|
||||
}
|
||||
}
|
||||
x += pci->metrics.characterWidth;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbPutImage(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int depth,
|
||||
int x, int y, int w, int h, int leftPad, int format, char *pImage)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
unsigned long i;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
FbStip *src = (FbStip *) pImage;
|
||||
|
||||
x += pDrawable->x;
|
||||
y += pDrawable->y;
|
||||
|
||||
switch (format) {
|
||||
case XYBitmap:
|
||||
srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip);
|
||||
fbPutXYImage(pDrawable,
|
||||
fbGetCompositeClip(pGC),
|
||||
pPriv->fg,
|
||||
pPriv->bg,
|
||||
pPriv->pm,
|
||||
pGC->alu, TRUE, x, y, w, h, src, srcStride, leftPad);
|
||||
break;
|
||||
case XYPixmap:
|
||||
srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip);
|
||||
for (i = (unsigned long) 1 << (pDrawable->depth - 1); i; i >>= 1) {
|
||||
if (i & pGC->planemask) {
|
||||
fbPutXYImage(pDrawable,
|
||||
fbGetCompositeClip(pGC),
|
||||
FB_ALLONES,
|
||||
0,
|
||||
fbReplicatePixel(i, pDrawable->bitsPerPixel),
|
||||
pGC->alu,
|
||||
TRUE, x, y, w, h, src, srcStride, leftPad);
|
||||
src += srcStride * h;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZPixmap:
|
||||
if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
|
||||
srcStride = PixmapBytePad(w, pDrawable->depth);
|
||||
fb24_32PutZImage(pDrawable,
|
||||
fbGetCompositeClip(pGC),
|
||||
pGC->alu,
|
||||
(FbBits) pGC->planemask,
|
||||
x, y, w, h, (CARD8 *) pImage, srcStride);
|
||||
}
|
||||
else
|
||||
{
|
||||
srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof(FbStip);
|
||||
fbPutZImage(pDrawable,
|
||||
fbGetCompositeClip(pGC),
|
||||
pGC->alu, pPriv->pm, x, y, w, h, src, srcStride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbPutZImage(DrawablePtr pDrawable,
|
||||
RegionPtr pClip,
|
||||
int alu,
|
||||
FbBits pm,
|
||||
int x,
|
||||
int y, int width, int height, FbStip * src, FbStride srcStride)
|
||||
{
|
||||
FbStip *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
int nbox;
|
||||
|
||||
BoxPtr pbox;
|
||||
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
for (nbox = REGION_NUM_RECTS(pClip),
|
||||
pbox = REGION_RECTS(pClip); nbox--; pbox++) {
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
x2 = x + width;
|
||||
y2 = y + height;
|
||||
if (x1 < pbox->x1)
|
||||
x1 = pbox->x1;
|
||||
if (y1 < pbox->y1)
|
||||
y1 = pbox->y1;
|
||||
if (x2 > pbox->x2)
|
||||
x2 = pbox->x2;
|
||||
if (y2 > pbox->y2)
|
||||
y2 = pbox->y2;
|
||||
if (x1 >= x2 || y1 >= y2)
|
||||
continue;
|
||||
fbBltStip(src + (y1 - y) * srcStride,
|
||||
srcStride,
|
||||
(x1 - x) * dstBpp,
|
||||
dst + (y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(x1 + dstXoff) * dstBpp,
|
||||
(x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbPutXYImage(DrawablePtr pDrawable,
|
||||
RegionPtr pClip,
|
||||
FbBits fg,
|
||||
FbBits bg,
|
||||
FbBits pm,
|
||||
int alu,
|
||||
Bool opaque,
|
||||
int x,
|
||||
int y,
|
||||
int width, int height, FbStip * src, FbStride srcStride, int srcX)
|
||||
{
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
int nbox;
|
||||
|
||||
BoxPtr pbox;
|
||||
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
FbBits fgand = 0, fgxor = 0, bgand = 0, bgxor = 0;
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
if (dstBpp == 1) {
|
||||
if (opaque)
|
||||
alu = FbOpaqueStipple1Rop(alu, fg, bg);
|
||||
else
|
||||
alu = FbStipple1Rop(alu, fg);
|
||||
}
|
||||
else {
|
||||
fgand = fbAnd(alu, fg, pm);
|
||||
fgxor = fbXor(alu, fg, pm);
|
||||
if (opaque) {
|
||||
bgand = fbAnd(alu, bg, pm);
|
||||
bgxor = fbXor(alu, bg, pm);
|
||||
}
|
||||
else {
|
||||
bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES);
|
||||
bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES);
|
||||
}
|
||||
}
|
||||
|
||||
for (nbox = REGION_NUM_RECTS(pClip),
|
||||
pbox = REGION_RECTS(pClip); nbox--; pbox++) {
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
x2 = x + width;
|
||||
y2 = y + height;
|
||||
if (x1 < pbox->x1)
|
||||
x1 = pbox->x1;
|
||||
if (y1 < pbox->y1)
|
||||
y1 = pbox->y1;
|
||||
if (x2 > pbox->x2)
|
||||
x2 = pbox->x2;
|
||||
if (y2 > pbox->y2)
|
||||
y2 = pbox->y2;
|
||||
if (x1 >= x2 || y1 >= y2)
|
||||
continue;
|
||||
if (dstBpp == 1) {
|
||||
fbBltStip(src + (y1 - y) * srcStride,
|
||||
srcStride,
|
||||
(x1 - x) + srcX,
|
||||
(FbStip *) (dst + (y1 + dstYoff) * dstStride),
|
||||
FbBitsStrideToStipStride(dstStride),
|
||||
(x1 + dstXoff) * dstBpp,
|
||||
(x2 - x1) * dstBpp, (y2 - y1), alu, pm, dstBpp);
|
||||
}
|
||||
else {
|
||||
fbBltOne(src + (y1 - y) * srcStride,
|
||||
srcStride,
|
||||
(x1 - x) + srcX,
|
||||
dst + (y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(x1 + dstXoff) * dstBpp,
|
||||
dstBpp,
|
||||
(x2 - x1) * dstBpp, (y2 - y1), fgand, fgxor, bgand, bgxor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbGetImage(DrawablePtr pDrawable,
|
||||
int x,
|
||||
int y,
|
||||
int w, int h, unsigned int format, unsigned long planeMask, char *d)
|
||||
{
|
||||
FbBits *src;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
FbStip *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
/*
|
||||
* XFree86 DDX empties the root borderClip when the VT is
|
||||
* switched away; this checks for that case
|
||||
*/
|
||||
if (!fbDrawableEnabled(pDrawable))
|
||||
return;
|
||||
|
||||
if (format == ZPixmap &&
|
||||
pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
|
||||
fb24_32GetImage(pDrawable, x, y, w, h, format, planeMask, d);
|
||||
return;
|
||||
}
|
||||
|
||||
fbGetDrawable(pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
|
||||
|
||||
x += pDrawable->x;
|
||||
y += pDrawable->y;
|
||||
|
||||
dst = (FbStip *) d;
|
||||
if (format == ZPixmap || srcBpp == 1) {
|
||||
FbBits pm;
|
||||
|
||||
pm = fbReplicatePixel(planeMask, srcBpp);
|
||||
dstStride = PixmapBytePad(w, pDrawable->depth);
|
||||
if (pm != FB_ALLONES)
|
||||
memset(d, 0, dstStride * h);
|
||||
dstStride /= sizeof(FbStip);
|
||||
fbBltStip((FbStip *) (src + (y + srcYoff) * srcStride),
|
||||
FbBitsStrideToStipStride(srcStride),
|
||||
(x + srcXoff) * srcBpp,
|
||||
dst, dstStride, 0, w * srcBpp, h, GXcopy, pm, srcBpp);
|
||||
}
|
||||
else {
|
||||
dstStride = BitmapBytePad(w) / sizeof(FbStip);
|
||||
fbBltPlane(src + (y + srcYoff) * srcStride,
|
||||
srcStride,
|
||||
(x + srcXoff) * srcBpp,
|
||||
srcBpp,
|
||||
dst,
|
||||
dstStride,
|
||||
0,
|
||||
w * srcBpp, h,
|
||||
fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES),
|
||||
fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES),
|
||||
fbAndStip(GXcopy, 0, FB_STIP_ALLONES),
|
||||
fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbZeroLine(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
|
||||
{
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
int x, y;
|
||||
|
||||
int dashOffset;
|
||||
|
||||
x = pDrawable->x;
|
||||
y = pDrawable->y;
|
||||
x1 = ppt->x;
|
||||
y1 = ppt->y;
|
||||
dashOffset = pGC->dashOffset;
|
||||
while (--npt) {
|
||||
++ppt;
|
||||
x2 = ppt->x;
|
||||
y2 = ppt->y;
|
||||
if (mode == CoordModePrevious) {
|
||||
x2 += x1;
|
||||
y2 += y1;
|
||||
}
|
||||
fbSegment(pDrawable, pGC, x1 + x, y1 + y,
|
||||
x2 + x, y2 + y,
|
||||
npt == 1 && pGC->capStyle != CapNotLast, &dashOffset);
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbZeroSegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSegs)
|
||||
{
|
||||
int dashOffset;
|
||||
|
||||
int x, y;
|
||||
|
||||
Bool drawLast = pGC->capStyle != CapNotLast;
|
||||
|
||||
x = pDrawable->x;
|
||||
y = pDrawable->y;
|
||||
while (nseg--) {
|
||||
dashOffset = pGC->dashOffset;
|
||||
fbSegment(pDrawable, pGC,
|
||||
pSegs->x1 + x, pSegs->y1 + y,
|
||||
pSegs->x2 + x, pSegs->y2 + y, drawLast, &dashOffset);
|
||||
pSegs++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbFixCoordModePrevious(int npt, DDXPointPtr ppt)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
x = ppt->x;
|
||||
y = ppt->y;
|
||||
npt--;
|
||||
while (npt--) {
|
||||
ppt++;
|
||||
x = (ppt->x += x);
|
||||
y = (ppt->y += y);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbPolyLine(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
|
||||
{
|
||||
void (*line) (DrawablePtr, GCPtr, int mode, int npt, DDXPointPtr ppt);
|
||||
|
||||
if (pGC->lineWidth == 0) {
|
||||
line = fbZeroLine;
|
||||
if (pGC->fillStyle == FillSolid &&
|
||||
pGC->lineStyle == LineSolid &&
|
||||
REGION_NUM_RECTS(fbGetCompositeClip(pGC)) == 1) {
|
||||
switch (pDrawable->bitsPerPixel) {
|
||||
case 8:
|
||||
line = fbPolyline8;
|
||||
break;
|
||||
case 16:
|
||||
line = fbPolyline16;
|
||||
break;
|
||||
case 24:
|
||||
line = fbPolyline24;
|
||||
break;
|
||||
case 32:
|
||||
line = fbPolyline32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (pGC->lineStyle != LineSolid)
|
||||
line = miWideDash;
|
||||
else
|
||||
line = miWideLine;
|
||||
}
|
||||
(*line) (pDrawable, pGC, mode, npt, ppt);
|
||||
}
|
||||
|
||||
void
|
||||
fbPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg)
|
||||
{
|
||||
void (*seg) (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg);
|
||||
|
||||
if (pGC->lineWidth == 0) {
|
||||
seg = fbZeroSegment;
|
||||
if (pGC->fillStyle == FillSolid &&
|
||||
pGC->lineStyle == LineSolid &&
|
||||
REGION_NUM_RECTS(fbGetCompositeClip(pGC)) == 1) {
|
||||
switch (pDrawable->bitsPerPixel) {
|
||||
case 8:
|
||||
seg = fbPolySegment8;
|
||||
break;
|
||||
case 16:
|
||||
seg = fbPolySegment16;
|
||||
break;
|
||||
case 24:
|
||||
seg = fbPolySegment24;
|
||||
break;
|
||||
case 32:
|
||||
seg = fbPolySegment32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
seg = miPolySegment;
|
||||
}
|
||||
(*seg) (pDrawable, pGC, nseg, pseg);
|
||||
}
|
|
@ -0,0 +1,424 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Keith Packard, SuSE, Inc.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fb.h"
|
||||
#include "fboverlay.h"
|
||||
#include "shmint.h"
|
||||
|
||||
int fbOverlayGeneration;
|
||||
|
||||
static int fbOverlayScreenPrivateIndex = -1;
|
||||
|
||||
int
|
||||
fbOverlayGetScreenPrivateIndex(void)
|
||||
{
|
||||
return fbOverlayScreenPrivateIndex;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace this if you want something supporting
|
||||
* multiple overlays with the same depth
|
||||
*/
|
||||
Bool
|
||||
fbOverlayCreateWindow(WindowPtr pWin)
|
||||
{
|
||||
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen);
|
||||
|
||||
int i;
|
||||
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
if (pWin->drawable.class != InputOutput)
|
||||
return TRUE;
|
||||
|
||||
if (pWin->drawable.bitsPerPixel == 32)
|
||||
pWin->drawable.bitsPerPixel =
|
||||
fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp;
|
||||
|
||||
for (i = 0; i < pScrPriv->nlayers; i++) {
|
||||
pPixmap = pScrPriv->layer[i].u.run.pixmap;
|
||||
if (pWin->drawable.depth == pPixmap->drawable.depth) {
|
||||
pWin->devPrivates[fbWinPrivateIndex].ptr = (pointer) pPixmap;
|
||||
/*
|
||||
* Make sure layer keys are written correctly by
|
||||
* having non-root layers set to full while the
|
||||
* root layer is set to empty. This will cause
|
||||
* all of the layers to get painted when the root
|
||||
* is mapped
|
||||
*/
|
||||
if (!pWin->parent) {
|
||||
REGION_EMPTY(
|
||||
&pScrPriv->layer[i].u.run.region);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbOverlayCloseScreen(int iScreen, ScreenPtr pScreen)
|
||||
{
|
||||
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pScrPriv->nlayers; i++) {
|
||||
(*pScreen->DestroyPixmap) (pScrPriv->layer[i].u.run.pixmap);
|
||||
REGION_UNINIT(&pScrPriv->layer[i].u.run.region);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return layer containing this window
|
||||
*/
|
||||
int
|
||||
fbOverlayWindowLayer(WindowPtr pWin)
|
||||
{
|
||||
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen);
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pScrPriv->nlayers; i++)
|
||||
if (pWin->devPrivates[fbWinPrivateIndex].ptr ==
|
||||
(pointer) pScrPriv->layer[i].u.run.pixmap)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbOverlayCreateScreenResources(ScreenPtr pScreen)
|
||||
{
|
||||
int i;
|
||||
|
||||
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
|
||||
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
pointer pbits;
|
||||
|
||||
int width;
|
||||
|
||||
int depth;
|
||||
|
||||
BoxRec box;
|
||||
|
||||
if (!miCreateScreenResources(pScreen))
|
||||
return FALSE;
|
||||
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = pScreen->width;
|
||||
box.y2 = pScreen->height;
|
||||
for (i = 0; i < pScrPriv->nlayers; i++) {
|
||||
pbits = pScrPriv->layer[i].u.init.pbits;
|
||||
width = pScrPriv->layer[i].u.init.width;
|
||||
depth = pScrPriv->layer[i].u.init.depth;
|
||||
pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth);
|
||||
if (!pPixmap)
|
||||
return FALSE;
|
||||
if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
|
||||
pScreen->height, depth,
|
||||
BitsPerPixel(depth),
|
||||
PixmapBytePad(width, depth),
|
||||
pbits))
|
||||
return FALSE;
|
||||
pScrPriv->layer[i].u.run.pixmap = pPixmap;
|
||||
REGION_INIT(&pScrPriv->layer[i].u.run.region, &box, 0);
|
||||
}
|
||||
pScreen->devPrivate = pScrPriv->layer[0].u.run.pixmap;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fbOverlayPaintKey(DrawablePtr pDrawable,
|
||||
RegionPtr pRegion, CARD32 pixel, int layer)
|
||||
{
|
||||
fbFillRegionSolid(pDrawable, pRegion, 0,
|
||||
fbReplicatePixel(pixel, pDrawable->bitsPerPixel));
|
||||
}
|
||||
|
||||
/*
|
||||
* Track visible region for each layer
|
||||
*/
|
||||
void
|
||||
fbOverlayUpdateLayerRegion(ScreenPtr pScreen, int layer, RegionPtr prgn)
|
||||
{
|
||||
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
|
||||
|
||||
int i;
|
||||
|
||||
RegionRec rgnNew;
|
||||
|
||||
if (!prgn || !REGION_NOTEMPTY(prgn))
|
||||
return;
|
||||
for (i = 0; i < pScrPriv->nlayers; i++) {
|
||||
if (i == layer) {
|
||||
/* add new piece to this fb */
|
||||
REGION_UNION(&pScrPriv->layer[i].u.run.region,
|
||||
&pScrPriv->layer[i].u.run.region, prgn);
|
||||
}
|
||||
else if (REGION_NOTEMPTY(&pScrPriv->layer[i].u.run.region)) {
|
||||
/* paint new piece with chroma key */
|
||||
REGION_NULL(&rgnNew);
|
||||
REGION_INTERSECT(&rgnNew, prgn, &pScrPriv->layer[i].u.run.region);
|
||||
(*pScrPriv->PaintKey) (&pScrPriv->layer[i].u.run.pixmap->drawable,
|
||||
&rgnNew, pScrPriv->layer[i].key, i);
|
||||
REGION_UNINIT(&rgnNew);
|
||||
/* remove piece from other fbs */
|
||||
REGION_SUBTRACT(
|
||||
&pScrPriv->layer[i].u.run.region,
|
||||
&pScrPriv->layer[i].u.run.region, prgn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy only areas in each layer containing real bits
|
||||
*/
|
||||
void
|
||||
fbOverlayCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
|
||||
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen);
|
||||
|
||||
RegionRec rgnDst;
|
||||
|
||||
int dx, dy;
|
||||
|
||||
int i;
|
||||
|
||||
RegionRec layerRgn[FB_OVERLAY_MAX];
|
||||
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
dx = ptOldOrg.x - pWin->drawable.x;
|
||||
dy = ptOldOrg.y - pWin->drawable.y;
|
||||
|
||||
/*
|
||||
* Clip to existing bits
|
||||
*/
|
||||
REGION_TRANSLATE(prgnSrc, -dx, -dy);
|
||||
REGION_NULL(&rgnDst);
|
||||
REGION_INTERSECT(&rgnDst, &pWin->borderClip, prgnSrc);
|
||||
REGION_TRANSLATE(&rgnDst, dx, dy);
|
||||
/*
|
||||
* Compute the portion of each fb affected by this copy
|
||||
*/
|
||||
for (i = 0; i < pScrPriv->nlayers; i++) {
|
||||
REGION_NULL(&layerRgn[i]);
|
||||
REGION_INTERSECT(&layerRgn[i], &rgnDst,
|
||||
&pScrPriv->layer[i].u.run.region);
|
||||
if (REGION_NOTEMPTY(&layerRgn[i])) {
|
||||
REGION_TRANSLATE(&layerRgn[i], -dx, -dy);
|
||||
pPixmap = pScrPriv->layer[i].u.run.pixmap;
|
||||
fbCopyRegion(&pPixmap->drawable, &pPixmap->drawable,
|
||||
0,
|
||||
&layerRgn[i], dx, dy, pScrPriv->CopyWindow, 0,
|
||||
(void *) (long) i);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Update regions
|
||||
*/
|
||||
for (i = 0; i < pScrPriv->nlayers; i++) {
|
||||
if (REGION_NOTEMPTY(&layerRgn[i]))
|
||||
fbOverlayUpdateLayerRegion(pScreen, i, &layerRgn[i]);
|
||||
|
||||
REGION_UNINIT(&layerRgn[i]);
|
||||
}
|
||||
REGION_UNINIT(&rgnDst);
|
||||
}
|
||||
|
||||
void
|
||||
fbOverlayWindowExposures(WindowPtr pWin,
|
||||
RegionPtr prgn, RegionPtr other_exposed)
|
||||
{
|
||||
fbOverlayUpdateLayerRegion(pWin->drawable.pScreen,
|
||||
fbOverlayWindowLayer(pWin), prgn);
|
||||
miWindowExposures(pWin, prgn, other_exposed);
|
||||
}
|
||||
|
||||
void
|
||||
fbOverlayPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
|
||||
{
|
||||
if (what == PW_BORDER)
|
||||
fbOverlayUpdateLayerRegion(pWin->drawable.pScreen,
|
||||
fbOverlayWindowLayer(pWin), pRegion);
|
||||
fbPaintWindow(pWin, pRegion, what);
|
||||
}
|
||||
|
||||
Bool
|
||||
fbOverlaySetupScreen(ScreenPtr pScreen,
|
||||
pointer pbits1,
|
||||
pointer pbits2,
|
||||
int xsize,
|
||||
int ysize,
|
||||
int dpix,
|
||||
int dpiy, int width1, int width2, int bpp1, int bpp2)
|
||||
{
|
||||
return fbSetupScreen(pScreen,
|
||||
pbits1, xsize, ysize, dpix, dpiy, width1, bpp1);
|
||||
}
|
||||
|
||||
static Bool
|
||||
fb24_32OverlayCreateScreenResources(ScreenPtr pScreen)
|
||||
{
|
||||
FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
|
||||
|
||||
int pitch;
|
||||
|
||||
Bool retval;
|
||||
|
||||
int i;
|
||||
|
||||
if ((retval = fbOverlayCreateScreenResources(pScreen))) {
|
||||
for (i = 0; i < pScrPriv->nlayers; i++) {
|
||||
/* fix the screen pixmap */
|
||||
PixmapPtr pPix = (PixmapPtr) pScrPriv->layer[i].u.run.pixmap;
|
||||
|
||||
if (pPix->drawable.bitsPerPixel == 32) {
|
||||
pPix->drawable.bitsPerPixel = 24;
|
||||
pitch = BitmapBytePad(pPix->drawable.width * 24);
|
||||
pPix->devKind = pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbOverlayFinishScreenInit(ScreenPtr pScreen,
|
||||
pointer pbits1,
|
||||
pointer pbits2,
|
||||
int xsize,
|
||||
int ysize,
|
||||
int dpix,
|
||||
int dpiy,
|
||||
int width1,
|
||||
int width2,
|
||||
int bpp1, int bpp2, int depth1, int depth2)
|
||||
{
|
||||
VisualPtr visuals;
|
||||
|
||||
DepthPtr depths;
|
||||
|
||||
int nvisuals;
|
||||
|
||||
int ndepths;
|
||||
|
||||
int bpp = 0, imagebpp = 32;
|
||||
|
||||
VisualID defaultVisual;
|
||||
|
||||
FbOverlayScrPrivPtr pScrPriv;
|
||||
|
||||
if (fbOverlayGeneration != serverGeneration) {
|
||||
fbOverlayScreenPrivateIndex = AllocateScreenPrivateIndex();
|
||||
fbOverlayGeneration = serverGeneration;
|
||||
}
|
||||
|
||||
pScrPriv = malloc(sizeof(FbOverlayScrPrivRec));
|
||||
if (!pScrPriv)
|
||||
return FALSE;
|
||||
|
||||
if (bpp1 == 32 || bpp2 == 32)
|
||||
bpp = 32;
|
||||
else if (bpp1 == 24 || bpp2 == 24)
|
||||
bpp = 24;
|
||||
|
||||
if (bpp == 24) {
|
||||
int f;
|
||||
|
||||
imagebpp = 32;
|
||||
/*
|
||||
* Check to see if we're advertising a 24bpp image format,
|
||||
* in which case windows will use it in preference to a 32 bit
|
||||
* format.
|
||||
*/
|
||||
for (f = 0; f < screenInfo.numPixmapFormats; f++) {
|
||||
if (screenInfo.formats[f].bitsPerPixel == 24) {
|
||||
imagebpp = 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (imagebpp == 32) {
|
||||
fbGetScreenPrivate(pScreen)->win32bpp = bpp;
|
||||
fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
|
||||
}
|
||||
else {
|
||||
fbGetScreenPrivate(pScreen)->win32bpp = 32;
|
||||
fbGetScreenPrivate(pScreen)->pix32bpp = 32;
|
||||
}
|
||||
|
||||
if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &depth1,
|
||||
&defaultVisual, ((unsigned long) 1 << (bpp1 - 1)) |
|
||||
((unsigned long) 1 << (bpp2 - 1)), 8))
|
||||
return FALSE;
|
||||
if (!miScreenInit(pScreen, 0, xsize, ysize, dpix, dpiy, 0,
|
||||
depth1, ndepths, depths, defaultVisual, nvisuals, visuals
|
||||
))
|
||||
return FALSE;
|
||||
/* MI thinks there's no frame buffer */
|
||||
ShmRegisterFbFuncs(pScreen);
|
||||
pScreen->minInstalledCmaps = 1;
|
||||
pScreen->maxInstalledCmaps = 2;
|
||||
|
||||
pScrPriv->nlayers = 2;
|
||||
pScrPriv->PaintKey = fbOverlayPaintKey;
|
||||
pScrPriv->CopyWindow = fbCopyWindowProc;
|
||||
pScrPriv->layer[0].u.init.pbits = pbits1;
|
||||
pScrPriv->layer[0].u.init.width = width1;
|
||||
pScrPriv->layer[0].u.init.depth = depth1;
|
||||
|
||||
pScrPriv->layer[1].u.init.pbits = pbits2;
|
||||
pScrPriv->layer[1].u.init.width = width2;
|
||||
pScrPriv->layer[1].u.init.depth = depth2;
|
||||
|
||||
pScreen->devPrivates[fbOverlayScreenPrivateIndex].ptr = (pointer) pScrPriv;
|
||||
|
||||
/* overwrite miCloseScreen with our own */
|
||||
pScreen->CloseScreen = fbOverlayCloseScreen;
|
||||
pScreen->CreateScreenResources = fbOverlayCreateScreenResources;
|
||||
pScreen->CreateWindow = fbOverlayCreateWindow;
|
||||
pScreen->WindowExposures = fbOverlayWindowExposures;
|
||||
pScreen->CopyWindow = fbOverlayCopyWindow;
|
||||
pScreen->PaintWindowBorder = fbOverlayPaintWindow;
|
||||
if (bpp == 24 && imagebpp == 32) {
|
||||
pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
|
||||
pScreen->CreateScreenResources = fb24_32OverlayCreateScreenResources;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Keith Packard, SuSE, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _FBOVERLAY_H_
|
||||
#define _FBOVERLAY_H_
|
||||
|
||||
extern int fbOverlayGeneration;
|
||||
|
||||
extern int fbOverlayGetScreenPrivateIndex(void);
|
||||
|
||||
#ifndef FB_OVERLAY_MAX
|
||||
#define FB_OVERLAY_MAX 2
|
||||
#endif
|
||||
|
||||
typedef void (*fbOverlayPaintKeyProc) (DrawablePtr, RegionPtr, CARD32, int);
|
||||
|
||||
typedef struct _fbOverlayLayer {
|
||||
union {
|
||||
struct {
|
||||
pointer pbits;
|
||||
int width;
|
||||
int depth;
|
||||
} init;
|
||||
struct {
|
||||
PixmapPtr pixmap;
|
||||
RegionRec region;
|
||||
} run;
|
||||
} u;
|
||||
CARD32 key; /* special pixel value */
|
||||
} FbOverlayLayer;
|
||||
|
||||
typedef struct _fbOverlayScrPriv {
|
||||
int nlayers;
|
||||
fbOverlayPaintKeyProc PaintKey;
|
||||
fbCopyProc CopyWindow;
|
||||
FbOverlayLayer layer[FB_OVERLAY_MAX];
|
||||
} FbOverlayScrPrivRec, *FbOverlayScrPrivPtr;
|
||||
|
||||
#define fbOverlayGetScrPriv(s) \
|
||||
((fbOverlayGetScreenPrivateIndex() != -1) ? \
|
||||
(s)->devPrivates[fbOverlayGetScreenPrivateIndex()].ptr : NULL)
|
||||
Bool
|
||||
fbOverlayCreateWindow(WindowPtr pWin);
|
||||
|
||||
Bool
|
||||
fbOverlayCloseScreen(int iScreen, ScreenPtr pScreen);
|
||||
|
||||
int
|
||||
fbOverlayWindowLayer(WindowPtr pWin);
|
||||
|
||||
Bool
|
||||
fbOverlayCreateScreenResources(ScreenPtr pScreen);
|
||||
|
||||
void
|
||||
|
||||
fbOverlayPaintKey(DrawablePtr pDrawable,
|
||||
RegionPtr pRegion, CARD32 pixel, int layer);
|
||||
void
|
||||
fbOverlayUpdateLayerRegion(ScreenPtr pScreen, int layer, RegionPtr prgn);
|
||||
|
||||
void
|
||||
fbOverlayCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||
|
||||
void
|
||||
|
||||
fbOverlayWindowExposures(WindowPtr pWin,
|
||||
RegionPtr prgn, RegionPtr other_exposed);
|
||||
|
||||
void
|
||||
fbOverlayPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
|
||||
|
||||
Bool
|
||||
|
||||
fbOverlaySetupScreen(ScreenPtr pScreen,
|
||||
pointer pbits1,
|
||||
pointer pbits2,
|
||||
int xsize,
|
||||
int ysize,
|
||||
int dpix,
|
||||
int dpiy, int width1, int width2, int bpp1, int bpp2);
|
||||
|
||||
Bool
|
||||
|
||||
fbOverlayFinishScreenInit(ScreenPtr pScreen,
|
||||
pointer pbits1,
|
||||
pointer pbits2,
|
||||
int xsize,
|
||||
int ysize,
|
||||
int dpix,
|
||||
int dpiy,
|
||||
int width1,
|
||||
int width2,
|
||||
int bpp1, int bpp2, int depth1, int depth2);
|
||||
|
||||
#endif /* _FBOVERLAY_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,610 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _FBPICT_H_
|
||||
#define _FBPICT_H_
|
||||
|
||||
#include "renderedge.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define INLINE __inline__
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
#define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
|
||||
#define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b))
|
||||
|
||||
#define FbGet8(v,i) ((CARD16) (CARD8) ((v) >> i))
|
||||
|
||||
/*
|
||||
* There are two ways of handling alpha -- either as a single unified value or
|
||||
* a separate value for each component, hence each macro must have two
|
||||
* versions. The unified alpha version has a 'U' at the end of the name,
|
||||
* the component version has a 'C'. Similarly, functions which deal with
|
||||
* this difference will have two versions using the same convention.
|
||||
*/
|
||||
|
||||
#define FbOverU(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),(a),(t)) + FbGet8(x,i),\
|
||||
(CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
|
||||
|
||||
#define FbOverC(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),FbGet8(a,i),(t)) + FbGet8(x,i),\
|
||||
(CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
|
||||
|
||||
#define FbInU(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),(a),(t)) << (i))
|
||||
|
||||
#define FbInC(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),FbGet8(a,i),(t)) << (i))
|
||||
|
||||
#define FbGen(x,y,i,ax,ay,t,u,v) ((t) = (FbIntMult(FbGet8(y,i),ay,(u)) + \
|
||||
FbIntMult(FbGet8(x,i),ax,(v))),\
|
||||
(CARD32) ((CARD8) ((t) | \
|
||||
(0 - ((t) >> 8)))) << (i))
|
||||
|
||||
#define FbAdd(x,y,i,t) ((t) = FbGet8(x,i) + FbGet8(y,i), \
|
||||
(CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
|
||||
|
||||
#define Alpha(x) ((x) >> 24)
|
||||
#define Red(x) (((x) >> 16) & 0xff)
|
||||
#define Green(x) (((x) >> 8) & 0xff)
|
||||
#define Blue(x) ((x) & 0xff)
|
||||
|
||||
/**
|
||||
* Returns TRUE if the fbComposeGetSolid can be used to get a single solid
|
||||
* color representing every source sampling location of the picture.
|
||||
*/
|
||||
static INLINE Bool
|
||||
fbCanGetSolid(PicturePtr pict)
|
||||
{
|
||||
if (pict->pDrawable == NULL ||
|
||||
pict->pDrawable->width != 1 || pict->pDrawable->height != 1) {
|
||||
return FALSE;
|
||||
}
|
||||
if (pict->repeat != RepeatNormal)
|
||||
return FALSE;
|
||||
|
||||
switch (pict->format) {
|
||||
case PICT_a8r8g8b8:
|
||||
case PICT_x8r8g8b8:
|
||||
case PICT_a8b8g8r8:
|
||||
case PICT_x8b8g8r8:
|
||||
case PICT_r8g8b8:
|
||||
case PICT_b8g8r8:
|
||||
case PICT_r5g6b5:
|
||||
case PICT_b5g6r5:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#define fbComposeGetSolid(pict, bits, fmt) { \
|
||||
FbBits *__bits__; \
|
||||
FbStride __stride__; \
|
||||
int __bpp__; \
|
||||
int __xoff__ _X_UNUSED,__yoff__ _X_UNUSED; \
|
||||
\
|
||||
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
|
||||
switch (__bpp__) { \
|
||||
case 32: \
|
||||
(bits) = *(CARD32 *) __bits__; \
|
||||
break; \
|
||||
case 24: \
|
||||
(bits) = Fetch24 ((CARD8 *) __bits__); \
|
||||
break; \
|
||||
case 16: \
|
||||
(bits) = *(CARD16 *) __bits__; \
|
||||
(bits) = cvt0565to8888(bits); \
|
||||
break; \
|
||||
default: \
|
||||
return; \
|
||||
} \
|
||||
/* If necessary, convert RGB <--> BGR. */ \
|
||||
if (PICT_FORMAT_TYPE((pict)->format) != PICT_FORMAT_TYPE(fmt)) \
|
||||
{ \
|
||||
(bits) = (((bits) & 0xff000000) | \
|
||||
(((bits) & 0x00ff0000) >> 16) | \
|
||||
(((bits) & 0x0000ff00) >> 0) | \
|
||||
(((bits) & 0x000000ff) << 16)); \
|
||||
} \
|
||||
/* manage missing src alpha */ \
|
||||
if ((pict)->pFormat->direct.alphaMask == 0) \
|
||||
(bits) |= 0xff000000; \
|
||||
}
|
||||
|
||||
#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
|
||||
FbBits *__bits__; \
|
||||
FbStride __stride__; \
|
||||
int __bpp__; \
|
||||
int __xoff__,__yoff__; \
|
||||
\
|
||||
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
|
||||
(stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
|
||||
(line) = ((type *) __bits__) + (stride) * ((y) + __yoff__) + (mul) * ((x) + __xoff__); \
|
||||
}
|
||||
#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
|
||||
(((s) >> 5) & 0x07e0) | \
|
||||
(((s) >> 8) & 0xf800))
|
||||
#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
|
||||
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
|
||||
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
|
||||
|
||||
#if IMAGE_BYTE_ORDER == MSBFirst
|
||||
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
|
||||
((*(a) << 16) | *((CARD16 *) ((a)+1))) : \
|
||||
((*((CARD16 *) (a)) << 8) | *((a)+2)))
|
||||
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
|
||||
((*(a) = (CARD8) ((v) >> 16)), \
|
||||
(*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \
|
||||
((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \
|
||||
(*((a)+2) = (CARD8) (v))))
|
||||
#else
|
||||
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
|
||||
((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \
|
||||
((*((CARD16 *) (a))) | (*((a)+2) << 16)))
|
||||
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
|
||||
((*(a) = (CARD8) (v)), \
|
||||
(*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \
|
||||
((*((CARD16 *) (a)) = (CARD16) (v)),\
|
||||
(*((a)+2) = (CARD8) ((v) >> 16))))
|
||||
#endif
|
||||
|
||||
/*
|
||||
The methods below use some tricks to be able to do two color
|
||||
components at the same time.
|
||||
*/
|
||||
|
||||
/*
|
||||
x_c = (x_c * a) / 255
|
||||
*/
|
||||
#define FbByteMul(x, a) do { \
|
||||
CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
|
||||
t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
|
||||
t &= 0xff00ff; \
|
||||
\
|
||||
x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
|
||||
x = (x + ((x >> 8) & 0xff00ff)); \
|
||||
x &= 0xff00ff00; \
|
||||
x += t; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = (x_c * a) / 255 + y
|
||||
*/
|
||||
#define FbByteMulAdd(x, a, y) do { \
|
||||
CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
|
||||
t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
|
||||
t &= 0xff00ff; \
|
||||
t += y & 0xff00ff; \
|
||||
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
|
||||
t &= 0xff00ff; \
|
||||
\
|
||||
x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
|
||||
x = (x + ((x >> 8) & 0xff00ff)) >> 8; \
|
||||
x &= 0xff00ff; \
|
||||
x += (y >> 8) & 0xff00ff; \
|
||||
x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
|
||||
x &= 0xff00ff; \
|
||||
x <<= 8; \
|
||||
x += t; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = (x_c * a + y_c * b) / 255
|
||||
*/
|
||||
#define FbByteAddMul(x, a, y, b) do { \
|
||||
CARD32 t; \
|
||||
CARD32 r = (x >> 24) * a + (y >> 24) * b + 0x80; \
|
||||
r += (r >> 8); \
|
||||
r >>= 8; \
|
||||
\
|
||||
t = (x & 0xff00) * a + (y & 0xff00) * b; \
|
||||
t += (t >> 8) + 0x8000; \
|
||||
t >>= 16; \
|
||||
\
|
||||
t |= r << 16; \
|
||||
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
|
||||
t &= 0xff00ff; \
|
||||
t <<= 8; \
|
||||
\
|
||||
r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b + 0x80; \
|
||||
r += (r >> 8); \
|
||||
r >>= 8; \
|
||||
\
|
||||
x = (x & 0xff) * a + (y & 0xff) * b + 0x80; \
|
||||
x += (x >> 8); \
|
||||
x >>= 8; \
|
||||
x |= r << 16; \
|
||||
x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
|
||||
x &= 0xff00ff; \
|
||||
x |= t; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = (x_c * a + y_c *b) / 256
|
||||
*/
|
||||
#define FbByteAddMul_256(x, a, y, b) do { \
|
||||
CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; \
|
||||
t >>= 8; \
|
||||
t &= 0xff00ff; \
|
||||
\
|
||||
x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; \
|
||||
x &= 0xff00ff00; \
|
||||
x += t; \
|
||||
} while (0)
|
||||
/*
|
||||
x_c = (x_c * a_c) / 255
|
||||
*/
|
||||
#define FbByteMulC(x, a) do { \
|
||||
CARD32 t; \
|
||||
CARD32 r = (x & 0xff) * (a & 0xff); \
|
||||
r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
|
||||
r += 0x800080; \
|
||||
r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
|
||||
r &= 0xff00ff; \
|
||||
\
|
||||
x >>= 8; \
|
||||
t = (x & 0xff) * ((a >> 8) & 0xff); \
|
||||
t |= (x & 0xff0000) * (a >> 24); \
|
||||
t += 0x800080; \
|
||||
t = t + ((t >> 8) & 0xff00ff); \
|
||||
x = r | (t & 0xff00ff00); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = (x_c * a) / 255 + y
|
||||
*/
|
||||
#define FbByteMulAddC(x, a, y) do { \
|
||||
CARD32 t; \
|
||||
CARD32 r = (x & 0xff) * (a & 0xff); \
|
||||
r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
|
||||
r += 0x800080; \
|
||||
r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
|
||||
r &= 0xff00ff; \
|
||||
r += y & 0xff00ff; \
|
||||
r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
|
||||
r &= 0xff00ff; \
|
||||
\
|
||||
x >>= 8; \
|
||||
t = (x & 0xff) * ((a >> 8) & 0xff); \
|
||||
t |= (x & 0xff0000) * (a >> 24); \
|
||||
t += 0x800080; \
|
||||
t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
|
||||
t &= 0xff00ff; \
|
||||
t += (y >> 8) & 0xff00ff; \
|
||||
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
|
||||
t &= 0xff00ff; \
|
||||
x = r | (t << 8); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = (x_c * a_c + y_c * b) / 255
|
||||
*/
|
||||
#define FbByteAddMulC(x, a, y, b) do { \
|
||||
CARD32 t; \
|
||||
CARD32 r = (x >> 24) * (a >> 24) + (y >> 24) * b; \
|
||||
r += (r >> 8) + 0x80; \
|
||||
r >>= 8; \
|
||||
\
|
||||
t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b; \
|
||||
t += (t >> 8) + 0x8000; \
|
||||
t >>= 16; \
|
||||
\
|
||||
t |= r << 16; \
|
||||
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
|
||||
t &= 0xff00ff; \
|
||||
t <<= 8; \
|
||||
\
|
||||
r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b + 0x80; \
|
||||
r += (r >> 8); \
|
||||
r >>= 8; \
|
||||
\
|
||||
x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b + 0x80; \
|
||||
x += (x >> 8); \
|
||||
x >>= 8; \
|
||||
x |= r << 16; \
|
||||
x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
|
||||
x &= 0xff00ff; \
|
||||
x |= t; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = min(x_c + y_c, 255)
|
||||
*/
|
||||
#define FbByteAdd(x, y) do { \
|
||||
CARD32 t; \
|
||||
CARD32 r = (x & 0xff00ff) + (y & 0xff00ff); \
|
||||
r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
|
||||
r &= 0xff00ff; \
|
||||
\
|
||||
t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff); \
|
||||
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
|
||||
r |= (t & 0xff00ff) << 8; \
|
||||
x = r; \
|
||||
} while (0)
|
||||
|
||||
#define div_255(x) (((x) + 0x80 + (((x) + 0x80) >> 8)) >> 8)
|
||||
|
||||
#if defined(__i386__) && defined(__GNUC__)
|
||||
#define FASTCALL __attribute__((regparm(3)))
|
||||
#else
|
||||
#define FASTCALL
|
||||
#endif
|
||||
|
||||
typedef struct _FbComposeData {
|
||||
CARD8 op;
|
||||
PicturePtr src;
|
||||
PicturePtr mask;
|
||||
PicturePtr dest;
|
||||
INT16 xSrc;
|
||||
INT16 ySrc;
|
||||
INT16 xMask;
|
||||
INT16 yMask;
|
||||
INT16 xDest;
|
||||
INT16 yDest;
|
||||
CARD16 width;
|
||||
CARD16 height;
|
||||
} FbComposeData;
|
||||
|
||||
typedef FASTCALL void (*CombineMaskU) (CARD32 *src, const CARD32 *mask,
|
||||
int width);
|
||||
typedef FASTCALL void (*CombineFuncU) (CARD32 *dest, const CARD32 *src,
|
||||
int width);
|
||||
typedef FASTCALL void (*CombineFuncC) (CARD32 *dest, CARD32 *src, CARD32 *mask,
|
||||
int width);
|
||||
|
||||
typedef struct _FbComposeFunctions {
|
||||
const CombineFuncU *combineU;
|
||||
const CombineFuncC *combineC;
|
||||
CombineMaskU combineMaskU;
|
||||
} FbComposeFunctions;
|
||||
|
||||
/* fbcompose.c */
|
||||
|
||||
void
|
||||
|
||||
fbCompositeGeneral(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
/* fbedge.c */
|
||||
void
|
||||
|
||||
fbRasterizeEdges(FbBits * buf,
|
||||
int bpp,
|
||||
int width,
|
||||
int stride,
|
||||
RenderEdge * l, RenderEdge * r, xFixed t, xFixed b);
|
||||
|
||||
/* fbpict.c */
|
||||
CARD32
|
||||
fbOver(CARD32 x, CARD32 y);
|
||||
|
||||
CARD32
|
||||
fbOver24(CARD32 x, CARD32 y);
|
||||
|
||||
CARD32
|
||||
fbIn(CARD32 x, CARD8 y);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSolidMask_nx8x8888(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSolidMask_nx8x0888(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSolidMask_nx8888x8888C(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSolidMask_nx8x0565(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSolidMask_nx8888x0565C(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSrc_8888x8888(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSrc_8888x0888(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSrc_8888x0565(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSrc_0565x0565(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSrcAdd_8000x8000(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSrcAdd_8888x8888(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSrcAdd_1000x1000(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbCompositeSolidMask_nx1xn(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
void
|
||||
|
||||
fbComposite(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
|
||||
|
||||
/* fbtrap.c */
|
||||
|
||||
void
|
||||
|
||||
fbAddTraps(PicturePtr pPicture,
|
||||
INT16 xOff, INT16 yOff, int ntrap, xTrap * traps);
|
||||
|
||||
void
|
||||
|
||||
fbRasterizeTrapezoid(PicturePtr alpha, xTrapezoid * trap, int x_off, int y_off);
|
||||
|
||||
void
|
||||
|
||||
fbAddTriangles(PicturePtr pPicture,
|
||||
INT16 xOff, INT16 yOff, int ntri, xTriangle * tris);
|
||||
|
||||
#endif /* _FBPICT_H_ */
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
PixmapPtr
|
||||
fbCreatePixmapBpp(ScreenPtr pScreen, int width, int height, int depth, int bpp)
|
||||
{
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
size_t datasize;
|
||||
|
||||
size_t paddedWidth;
|
||||
|
||||
int adjust;
|
||||
|
||||
int base;
|
||||
|
||||
paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
|
||||
if (paddedWidth / 4 > 32767 || height > 32767)
|
||||
return NullPixmap;
|
||||
datasize = height * paddedWidth;
|
||||
base = pScreen->totalPixmapSize;
|
||||
adjust = 0;
|
||||
if (base & 7)
|
||||
adjust = 8 - (base & 7);
|
||||
datasize += adjust;
|
||||
#ifdef FB_DEBUG
|
||||
datasize += 2 * paddedWidth;
|
||||
#endif
|
||||
pPixmap = AllocatePixmap(pScreen, datasize);
|
||||
if (!pPixmap)
|
||||
return NullPixmap;
|
||||
pPixmap->drawable.type = DRAWABLE_PIXMAP;
|
||||
pPixmap->drawable.class = 0;
|
||||
pPixmap->drawable.pScreen = pScreen;
|
||||
pPixmap->drawable.depth = depth;
|
||||
pPixmap->drawable.bitsPerPixel = bpp;
|
||||
pPixmap->drawable.id = 0;
|
||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
pPixmap->drawable.x = 0;
|
||||
pPixmap->drawable.y = 0;
|
||||
pPixmap->drawable.width = width;
|
||||
pPixmap->drawable.height = height;
|
||||
pPixmap->devKind = paddedWidth;
|
||||
pPixmap->refcnt = 1;
|
||||
pPixmap->devPrivate.ptr = (pointer) ((char *) pPixmap + base + adjust);
|
||||
#ifdef FB_DEBUG
|
||||
pPixmap->devPrivate.ptr =
|
||||
(void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth);
|
||||
fbInitializeDrawable(&pPixmap->drawable);
|
||||
#endif
|
||||
|
||||
|
||||
return pPixmap;
|
||||
}
|
||||
|
||||
PixmapPtr
|
||||
fbCreatePixmap(ScreenPtr pScreen, int width, int height, int depth)
|
||||
{
|
||||
int bpp;
|
||||
|
||||
bpp = BitsPerPixel(depth);
|
||||
if (bpp == 32 && depth <= 24)
|
||||
bpp = fbGetScreenPrivate(pScreen)->pix32bpp;
|
||||
return fbCreatePixmapBpp(pScreen, width, height, depth, bpp);
|
||||
}
|
||||
|
||||
Bool
|
||||
fbDestroyPixmap(PixmapPtr pPixmap)
|
||||
{
|
||||
if (--pPixmap->refcnt)
|
||||
return TRUE;
|
||||
free(pPixmap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
|
||||
if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
|
||||
(!((reg)->data->numRects && \
|
||||
((r-1)->y1 == (ry1)) && \
|
||||
((r-1)->y2 == (ry2)) && \
|
||||
((r-1)->x1 <= (rx1)) && \
|
||||
((r-1)->x2 >= (rx2))))) \
|
||||
{ \
|
||||
if ((reg)->data->numRects == (reg)->data->size) \
|
||||
{ \
|
||||
miRectAlloc(reg, 1); \
|
||||
fr = REGION_BOXPTR(reg); \
|
||||
r = fr + (reg)->data->numRects; \
|
||||
} \
|
||||
r->x1 = (rx1); \
|
||||
r->y1 = (ry1); \
|
||||
r->x2 = (rx2); \
|
||||
r->y2 = (ry2); \
|
||||
(reg)->data->numRects++; \
|
||||
if(r->x1 < (reg)->extents.x1) \
|
||||
(reg)->extents.x1 = r->x1; \
|
||||
if(r->x2 > (reg)->extents.x2) \
|
||||
(reg)->extents.x2 = r->x2; \
|
||||
r++; \
|
||||
}
|
||||
|
||||
/* Convert bitmap clip mask into clipping region.
|
||||
* First, goes through each line and makes boxes by noting the transitions
|
||||
* from 0 to 1 and 1 to 0.
|
||||
* Then it coalesces the current line with the previous if they have boxes
|
||||
* at the same X coordinates.
|
||||
*/
|
||||
RegionPtr
|
||||
fbPixmapToRegion(PixmapPtr pPix)
|
||||
{
|
||||
RegionPtr pReg;
|
||||
|
||||
FbBits *pw, w;
|
||||
|
||||
int ib;
|
||||
|
||||
int width, h, base, rx1 = 0, crects;
|
||||
|
||||
FbBits *pwLineEnd;
|
||||
|
||||
int irectPrevStart, irectLineStart;
|
||||
|
||||
BoxPtr prectO, prectN;
|
||||
|
||||
BoxPtr FirstRect, rects, prectLineStart;
|
||||
|
||||
Bool fInBox, fSame;
|
||||
|
||||
FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1);
|
||||
|
||||
FbBits *pwLine;
|
||||
|
||||
int nWidth;
|
||||
|
||||
pReg = REGION_CREATE(NULL, 1);
|
||||
if (!pReg)
|
||||
return NullRegion;
|
||||
FirstRect = REGION_BOXPTR(pReg);
|
||||
rects = FirstRect;
|
||||
|
||||
pwLine = (FbBits *) pPix->devPrivate.ptr;
|
||||
nWidth = pPix->devKind >> (FB_SHIFT - 3);
|
||||
|
||||
width = pPix->drawable.width;
|
||||
pReg->extents.x1 = width - 1;
|
||||
pReg->extents.x2 = 0;
|
||||
irectPrevStart = -1;
|
||||
for (h = 0; h < pPix->drawable.height; h++) {
|
||||
pw = pwLine;
|
||||
pwLine += nWidth;
|
||||
irectLineStart = rects - FirstRect;
|
||||
/* If the Screen left most bit of the word is set, we're starting in
|
||||
* a box */
|
||||
if (*pw & mask0) {
|
||||
fInBox = TRUE;
|
||||
rx1 = 0;
|
||||
}
|
||||
else
|
||||
fInBox = FALSE;
|
||||
/* Process all words which are fully in the pixmap */
|
||||
pwLineEnd = pw + (width >> FB_SHIFT);
|
||||
for (base = 0; pw < pwLineEnd; base += FB_UNIT) {
|
||||
w = *pw++;
|
||||
if (fInBox) {
|
||||
if (!~w)
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if (!w)
|
||||
continue;
|
||||
}
|
||||
for (ib = 0; ib < FB_UNIT; ib++) {
|
||||
/* If the Screen left most bit of the word is set, we're
|
||||
* starting a box */
|
||||
if (w & mask0) {
|
||||
if (!fInBox) {
|
||||
rx1 = base + ib;
|
||||
/* start new box */
|
||||
fInBox = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (fInBox) {
|
||||
/* end box */
|
||||
ADDRECT(pReg, rects, FirstRect,
|
||||
rx1, h, base + ib, h + 1);
|
||||
fInBox = FALSE;
|
||||
}
|
||||
}
|
||||
/* Shift the word VISUALLY left one. */
|
||||
w = FbScrLeft(w, 1);
|
||||
}
|
||||
}
|
||||
if (width & FB_MASK) {
|
||||
/* Process final partial word on line */
|
||||
w = *pw++;
|
||||
for (ib = 0; ib < (width & FB_MASK); ib++) {
|
||||
/* If the Screen left most bit of the word is set, we're
|
||||
* starting a box */
|
||||
if (w & mask0) {
|
||||
if (!fInBox) {
|
||||
rx1 = base + ib;
|
||||
/* start new box */
|
||||
fInBox = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (fInBox) {
|
||||
/* end box */
|
||||
ADDRECT(pReg, rects, FirstRect,
|
||||
rx1, h, base + ib, h + 1);
|
||||
fInBox = FALSE;
|
||||
}
|
||||
}
|
||||
/* Shift the word VISUALLY left one. */
|
||||
w = FbScrLeft(w, 1);
|
||||
}
|
||||
}
|
||||
/* If scanline ended with last bit set, end the box */
|
||||
if (fInBox) {
|
||||
ADDRECT(pReg, rects, FirstRect,
|
||||
rx1, h, base + (width & FB_MASK), h + 1);
|
||||
}
|
||||
/* if all rectangles on this line have the same x-coords as
|
||||
* those on the previous line, then add 1 to all the previous y2s and
|
||||
* throw away all the rectangles from this line
|
||||
*/
|
||||
fSame = FALSE;
|
||||
if (irectPrevStart != -1) {
|
||||
crects = irectLineStart - irectPrevStart;
|
||||
if (crects == ((rects - FirstRect) - irectLineStart)) {
|
||||
prectO = FirstRect + irectPrevStart;
|
||||
prectN = prectLineStart = FirstRect + irectLineStart;
|
||||
fSame = TRUE;
|
||||
while (prectO < prectLineStart) {
|
||||
if ((prectO->x1 != prectN->x1) ||
|
||||
(prectO->x2 != prectN->x2)) {
|
||||
fSame = FALSE;
|
||||
break;
|
||||
}
|
||||
prectO++;
|
||||
prectN++;
|
||||
}
|
||||
if (fSame) {
|
||||
prectO = FirstRect + irectPrevStart;
|
||||
while (prectO < prectLineStart) {
|
||||
prectO->y2 += 1;
|
||||
prectO++;
|
||||
}
|
||||
rects -= crects;
|
||||
pReg->data->numRects -= crects;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fSame)
|
||||
irectPrevStart = irectLineStart;
|
||||
}
|
||||
if (!pReg->data->numRects)
|
||||
pReg->extents.x1 = pReg->extents.x2 = 0;
|
||||
else {
|
||||
pReg->extents.y1 = REGION_BOXPTR(pReg)->y1;
|
||||
pReg->extents.y2 = REGION_END(pReg)->y2;
|
||||
if (pReg->data->numRects == 1) {
|
||||
free(pReg->data);
|
||||
pReg->data = (RegDataPtr) NULL;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (!miValidRegion(pReg))
|
||||
FatalError("Assertion failed file %s, line %d: expr\n", __FILE__,
|
||||
__LINE__);
|
||||
#endif
|
||||
return (pReg);
|
||||
}
|
||||
|
||||
#ifdef FB_DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static Bool
|
||||
fbValidateBits(FbStip * bits, int stride, FbStip data)
|
||||
{
|
||||
while (stride--) {
|
||||
if (*bits != data) {
|
||||
fprintf(stderr, "fbValidateBits failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
bits++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbValidateDrawable(DrawablePtr pDrawable)
|
||||
{
|
||||
FbStip *bits, *first, *last;
|
||||
|
||||
int stride, bpp;
|
||||
|
||||
int xoff, yoff;
|
||||
|
||||
int height;
|
||||
|
||||
Bool failed;
|
||||
|
||||
if (pDrawable->type != DRAWABLE_PIXMAP)
|
||||
pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable);
|
||||
fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
|
||||
first = bits - stride;
|
||||
last = bits + stride * pDrawable->height;
|
||||
if (!fbValidateBits(first, stride, FB_HEAD_BITS) ||
|
||||
!fbValidateBits(last, stride, FB_TAIL_BITS))
|
||||
fbInitializeDrawable(pDrawable);
|
||||
}
|
||||
|
||||
void
|
||||
fbSetBits(FbStip * bits, int stride, FbStip data)
|
||||
{
|
||||
while (stride--)
|
||||
*bits++ = data;
|
||||
}
|
||||
|
||||
void
|
||||
fbInitializeDrawable(DrawablePtr pDrawable)
|
||||
{
|
||||
FbStip *bits, *first, *last;
|
||||
|
||||
int stride, bpp;
|
||||
|
||||
int xoff, yoff;
|
||||
|
||||
fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
|
||||
first = bits - stride;
|
||||
last = bits + stride * pDrawable->height;
|
||||
fbSetBits(first, stride, FB_HEAD_BITS);
|
||||
fbSetBits(last, stride, FB_TAIL_BITS);
|
||||
}
|
||||
#endif /* FB_DEBUG */
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
typedef void (*FbDots) (FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstBpp,
|
||||
BoxPtr pBox,
|
||||
xPoint * pts,
|
||||
int npt,
|
||||
int xorg,
|
||||
int yorg, int xoff, int yoff, FbBits and, FbBits xor);
|
||||
|
||||
void
|
||||
fbDots(FbBits * dstOrig,
|
||||
FbStride dstStride,
|
||||
int dstBpp,
|
||||
BoxPtr pBox,
|
||||
xPoint * pts,
|
||||
int npt,
|
||||
int xorg, int yorg, int xoff, int yoff, FbBits andOrig, FbBits xorOrig)
|
||||
{
|
||||
FbStip *dst = (FbStip *) dstOrig;
|
||||
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
int x, y;
|
||||
|
||||
FbStip *d;
|
||||
|
||||
FbStip and = andOrig;
|
||||
|
||||
FbStip xor = xorOrig;
|
||||
|
||||
dstStride = FbBitsStrideToStipStride(dstStride);
|
||||
x1 = pBox->x1;
|
||||
y1 = pBox->y1;
|
||||
x2 = pBox->x2;
|
||||
y2 = pBox->y2;
|
||||
while (npt--) {
|
||||
x = pts->x + xorg;
|
||||
y = pts->y + yorg;
|
||||
pts++;
|
||||
if (x1 <= x && x < x2 && y1 <= y && y < y2) {
|
||||
x = (x + xoff) * dstBpp;
|
||||
d = dst + ((y + yoff) * dstStride) + (x >> FB_STIP_SHIFT);
|
||||
x &= FB_STIP_MASK;
|
||||
if (dstBpp == 24) {
|
||||
FbStip leftMask, rightMask;
|
||||
|
||||
int n, rot;
|
||||
|
||||
FbStip andT, xorT;
|
||||
|
||||
rot = FbFirst24Rot(x);
|
||||
andT = FbRot24Stip(and, rot);
|
||||
xorT = FbRot24Stip(xor, rot);
|
||||
FbMaskStip(x, 24, leftMask, n, rightMask);
|
||||
if (leftMask) {
|
||||
*d = FbDoMaskRRop(*d, andT, xorT, leftMask);
|
||||
andT = FbNext24Stip(andT);
|
||||
xorT = FbNext24Stip(xorT);
|
||||
d++;
|
||||
}
|
||||
if (rightMask)
|
||||
*d = FbDoMaskRRop(*d, andT, xorT, rightMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
FbStip mask;
|
||||
|
||||
mask = FbStipMask(x, dstBpp);
|
||||
*d = FbDoMaskRRop(*d, and, xor, mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbPolyPoint(DrawablePtr pDrawable,
|
||||
GCPtr pGC, int mode, int nptInit, xPoint * pptInit)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
RegionPtr pClip = fbGetCompositeClip(pGC);
|
||||
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbDots dots;
|
||||
|
||||
FbBits and, xor;
|
||||
|
||||
xPoint *ppt;
|
||||
|
||||
int npt;
|
||||
|
||||
BoxPtr pBox;
|
||||
|
||||
int nBox;
|
||||
|
||||
/* make pointlist origin relative */
|
||||
ppt = pptInit;
|
||||
npt = nptInit;
|
||||
if (mode == CoordModePrevious) {
|
||||
npt--;
|
||||
while (npt--) {
|
||||
ppt++;
|
||||
ppt->x += (ppt - 1)->x;
|
||||
ppt->y += (ppt - 1)->y;
|
||||
}
|
||||
}
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
and = pPriv->and;
|
||||
xor = pPriv->xor;
|
||||
dots = fbDots;
|
||||
switch (dstBpp) {
|
||||
case 8:
|
||||
dots = fbDots8;
|
||||
break;
|
||||
case 16:
|
||||
dots = fbDots16;
|
||||
break;
|
||||
case 24:
|
||||
dots = fbDots24;
|
||||
break;
|
||||
case 32:
|
||||
dots = fbDots32;
|
||||
break;
|
||||
}
|
||||
for (nBox = REGION_NUM_RECTS(pClip), pBox = REGION_RECTS(pClip);
|
||||
nBox--; pBox++)
|
||||
(*dots) (dst, dstStride, dstBpp, pBox, pptInit, nptInit,
|
||||
pDrawable->x, pDrawable->y, dstXoff, dstYoff, and, xor);
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbPushPattern(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
FbStip * src,
|
||||
FbStride srcStride, int srcX, int x, int y, int width, int height)
|
||||
{
|
||||
FbStip *s, bitsMask, bitsMask0, bits;
|
||||
|
||||
int xspan;
|
||||
|
||||
int w;
|
||||
|
||||
int lenspan;
|
||||
|
||||
src += srcX >> FB_STIP_SHIFT;
|
||||
srcX &= FB_STIP_MASK;
|
||||
|
||||
bitsMask0 = FbStipMask(srcX, 1);
|
||||
|
||||
while (height--) {
|
||||
bitsMask = bitsMask0;
|
||||
w = width;
|
||||
s = src;
|
||||
src += srcStride;
|
||||
bits = *s++;
|
||||
xspan = x;
|
||||
while (w) {
|
||||
if (bits & bitsMask) {
|
||||
lenspan = 0;
|
||||
do {
|
||||
lenspan++;
|
||||
if (lenspan == w)
|
||||
break;
|
||||
bitsMask = FbStipRight(bitsMask, 1);
|
||||
if (!bitsMask) {
|
||||
bits = *s++;
|
||||
bitsMask = FbBitsMask(0, 1);
|
||||
}
|
||||
} while (bits & bitsMask);
|
||||
fbFill(pDrawable, pGC, xspan, y, lenspan, 1);
|
||||
xspan += lenspan;
|
||||
w -= lenspan;
|
||||
}
|
||||
else {
|
||||
do {
|
||||
w--;
|
||||
xspan++;
|
||||
if (!w)
|
||||
break;
|
||||
bitsMask = FbStipRight(bitsMask, 1);
|
||||
if (!bitsMask) {
|
||||
bits = *s++;
|
||||
bitsMask = FbBitsMask(0, 1);
|
||||
}
|
||||
} while (!(bits & bitsMask));
|
||||
}
|
||||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbPushFill(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
FbStip * src,
|
||||
FbStride srcStride, int srcX, int x, int y, int width, int height)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
if (pGC->fillStyle == FillSolid) {
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
int dstX;
|
||||
|
||||
int dstWidth;
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
dst = dst + (y + dstYoff) * dstStride;
|
||||
dstX = (x + dstXoff) * dstBpp;
|
||||
dstWidth = width * dstBpp;
|
||||
if (dstBpp == 1) {
|
||||
fbBltStip(src,
|
||||
srcStride,
|
||||
srcX,
|
||||
(FbStip *) dst,
|
||||
FbBitsStrideToStipStride(dstStride),
|
||||
dstX,
|
||||
dstWidth,
|
||||
height,
|
||||
FbStipple1Rop(pGC->alu, pGC->fgPixel), pPriv->pm, dstBpp);
|
||||
}
|
||||
else {
|
||||
fbBltOne(src,
|
||||
srcStride,
|
||||
srcX,
|
||||
dst,
|
||||
dstStride,
|
||||
dstX,
|
||||
dstBpp,
|
||||
dstWidth,
|
||||
height,
|
||||
pPriv->and, pPriv->xor,
|
||||
fbAnd(GXnoop, (FbBits) 0, FB_ALLONES),
|
||||
fbXor(GXnoop, (FbBits) 0, FB_ALLONES));
|
||||
}
|
||||
}
|
||||
else {
|
||||
fbPushPattern(pDrawable, pGC, src, srcStride, srcX,
|
||||
x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbPushImage(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
FbStip * src,
|
||||
FbStride srcStride, int srcX, int x, int y, int width, int height)
|
||||
{
|
||||
RegionPtr pClip = fbGetCompositeClip(pGC);
|
||||
|
||||
int nbox;
|
||||
|
||||
BoxPtr pbox;
|
||||
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
for (nbox = REGION_NUM_RECTS(pClip),
|
||||
pbox = REGION_RECTS(pClip); nbox--; pbox++) {
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
x2 = x + width;
|
||||
y2 = y + height;
|
||||
if (x1 < pbox->x1)
|
||||
x1 = pbox->x1;
|
||||
if (y1 < pbox->y1)
|
||||
y1 = pbox->y1;
|
||||
if (x2 > pbox->x2)
|
||||
x2 = pbox->x2;
|
||||
if (y2 > pbox->y2)
|
||||
y2 = pbox->y2;
|
||||
if (x1 >= x2 || y1 >= y2)
|
||||
continue;
|
||||
fbPushFill(pDrawable,
|
||||
pGC,
|
||||
src + (y1 - y) * srcStride,
|
||||
srcStride, srcX + (x1 - x), x1, y1, x2 - x1, y2 - y1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbPushPixels(GCPtr pGC,
|
||||
PixmapPtr pBitmap,
|
||||
DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg)
|
||||
{
|
||||
FbStip *stip;
|
||||
|
||||
FbStride stipStride;
|
||||
|
||||
int stipBpp;
|
||||
|
||||
int stipXoff _X_UNUSED, stipYoff _X_UNUSED; /* Assumed to be zero */
|
||||
|
||||
fbGetStipDrawable(&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff,
|
||||
stipYoff);
|
||||
|
||||
fbPushImage(pDrawable, pGC, stip, stipStride, 0, xOrg, yOrg, dx, dy);
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _FBROP_H_
|
||||
#define _FBROP_H_
|
||||
|
||||
typedef struct _mergeRopBits {
|
||||
FbBits ca1, cx1, ca2, cx2;
|
||||
} FbMergeRopRec, *FbMergeRopPtr;
|
||||
|
||||
extern _X_EXPORT const FbMergeRopRec FbMergeRopBits[16];
|
||||
|
||||
#define FbDeclareMergeRop() FbBits _ca1, _cx1, _ca2, _cx2;
|
||||
#define FbDeclarePrebuiltMergeRop() FbBits _cca, _ccx;
|
||||
|
||||
#define FbInitializeMergeRop(alu,pm) {\
|
||||
const FbMergeRopRec *_bits; \
|
||||
_bits = &FbMergeRopBits[alu]; \
|
||||
_ca1 = _bits->ca1 & pm; \
|
||||
_cx1 = _bits->cx1 | ~pm; \
|
||||
_ca2 = _bits->ca2 & pm; \
|
||||
_cx2 = _bits->cx2 & pm; \
|
||||
}
|
||||
|
||||
#define FbDestInvarientRop(alu,pm) ((pm) == FB_ALLONES && \
|
||||
(((alu) >> 1 & 5) == ((alu) & 5)))
|
||||
|
||||
#define FbDestInvarientMergeRop() (_ca1 == 0 && _cx1 == 0)
|
||||
|
||||
/* AND has higher precedence than XOR */
|
||||
|
||||
#define FbDoMergeRop(src, dst) \
|
||||
(((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2))
|
||||
|
||||
#define FbDoDestInvarientMergeRop(src) (((src) & _ca2) ^ _cx2)
|
||||
|
||||
#define FbDoMaskMergeRop(src, dst, mask) \
|
||||
(((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask)))
|
||||
|
||||
#define FbDoLeftMaskByteMergeRop(dst, src, lb, l) { \
|
||||
FbBits __xor = ((src) & _ca2) ^ _cx2; \
|
||||
FbDoLeftMaskByteRRop(dst,lb,l,((src) & _ca1) ^ _cx1,__xor); \
|
||||
}
|
||||
|
||||
#define FbDoRightMaskByteMergeRop(dst, src, rb, r) { \
|
||||
FbBits __xor = ((src) & _ca2) ^ _cx2; \
|
||||
FbDoRightMaskByteRRop(dst,rb,r,((src) & _ca1) ^ _cx1,__xor); \
|
||||
}
|
||||
|
||||
#define FbDoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
|
||||
|
||||
#define FbDoMaskRRop(dst, and, xor, mask) \
|
||||
(((dst) & ((and) | ~(mask))) ^ (xor & mask))
|
||||
|
||||
/*
|
||||
* Take a single bit (0 or 1) and generate a full mask
|
||||
*/
|
||||
#define fbFillFromBit(b,t) (~((t) ((b) & 1)-1))
|
||||
|
||||
#define fbXorT(rop,fg,pm,t) ((((fg) & fbFillFromBit((rop) >> 1,t)) | \
|
||||
(~(fg) & fbFillFromBit((rop) >> 3,t))) & (pm))
|
||||
|
||||
#define fbAndT(rop,fg,pm,t) ((((fg) & fbFillFromBit (rop ^ (rop>>1),t)) | \
|
||||
(~(fg) & fbFillFromBit((rop>>2) ^ (rop>>3),t))) | \
|
||||
~(pm))
|
||||
|
||||
#define fbXor(rop,fg,pm) fbXorT(rop,fg,pm,FbBits)
|
||||
|
||||
#define fbAnd(rop,fg,pm) fbAndT(rop,fg,pm,FbBits)
|
||||
|
||||
#define fbXorStip(rop,fg,pm) fbXorT(rop,fg,pm,FbStip)
|
||||
|
||||
#define fbAndStip(rop,fg,pm) fbAndT(rop,fg,pm,FbStip)
|
||||
|
||||
/*
|
||||
* Stippling operations;
|
||||
*/
|
||||
|
||||
extern _X_EXPORT const FbBits fbStipple16Bits[256]; /* half of table */
|
||||
|
||||
#define FbStipple16Bits(b) \
|
||||
(fbStipple16Bits[(b)&0xff] | fbStipple16Bits[(b) >> 8] << FB_HALFUNIT)
|
||||
extern _X_EXPORT const FbBits fbStipple8Bits[256];
|
||||
extern _X_EXPORT const FbBits fbStipple4Bits[16];
|
||||
extern _X_EXPORT const FbBits fbStipple2Bits[4];
|
||||
extern _X_EXPORT const FbBits fbStipple1Bits[2];
|
||||
extern _X_EXPORT const FbBits *const fbStippleTable[];
|
||||
|
||||
#define FbStippleRRop(dst, b, fa, fx, ba, bx) \
|
||||
(FbDoRRop(dst, fa, fx) & b) | (FbDoRRop(dst, ba, bx) & ~b)
|
||||
|
||||
#define FbStippleRRopMask(dst, b, fa, fx, ba, bx, m) \
|
||||
(FbDoMaskRRop(dst, fa, fx, m) & (b)) | (FbDoMaskRRop(dst, ba, bx, m) & ~(b))
|
||||
|
||||
#define FbDoLeftMaskByteStippleRRop(dst, b, fa, fx, ba, bx, lb, l) { \
|
||||
FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \
|
||||
FbDoLeftMaskByteRRop(dst, lb, l, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
|
||||
}
|
||||
|
||||
#define FbDoRightMaskByteStippleRRop(dst, b, fa, fx, ba, bx, rb, r) { \
|
||||
FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \
|
||||
FbDoRightMaskByteRRop(dst, rb, r, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
|
||||
}
|
||||
|
||||
#define FbOpaqueStipple(b, fg, bg) (((fg) & (b)) | ((bg) & ~(b)))
|
||||
|
||||
/*
|
||||
* Compute rop for using tile code for 1-bit dest stipples; modifies
|
||||
* existing rop to flip depending on pixel values
|
||||
*/
|
||||
#define FbStipple1RopPick(alu,b) (((alu) >> (2 - (((b) & 1) << 1))) & 3)
|
||||
|
||||
#define FbOpaqueStipple1Rop(alu,fg,bg) (FbStipple1RopPick(alu,fg) | \
|
||||
(FbStipple1RopPick(alu,bg) << 2))
|
||||
|
||||
#define FbStipple1Rop(alu,fg) (FbStipple1RopPick(alu,fg) | 4)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
Bool
|
||||
fbCloseScreen(int index, ScreenPtr pScreen)
|
||||
{
|
||||
int d;
|
||||
|
||||
DepthPtr depths = pScreen->allowedDepths;
|
||||
|
||||
for (d = 0; d < pScreen->numDepths; d++)
|
||||
free(depths[d].vids);
|
||||
free(depths);
|
||||
free(pScreen->visuals);
|
||||
free(pScreen->devPrivate);
|
||||
free(pScreen->devPrivates[fbScreenPrivateIndex].ptr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbRealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
Bool
|
||||
fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
fbQueryBestSize(int class,
|
||||
unsigned short *width, unsigned short *height,
|
||||
ScreenPtr pScreen)
|
||||
{
|
||||
unsigned short w;
|
||||
|
||||
switch (class) {
|
||||
case CursorShape:
|
||||
if (*width > pScreen->width)
|
||||
*width = pScreen->width;
|
||||
if (*height > pScreen->height)
|
||||
*height = pScreen->height;
|
||||
break;
|
||||
case TileShape:
|
||||
case StippleShape:
|
||||
w = *width;
|
||||
if ((w & (w - 1)) && w < FB_UNIT) {
|
||||
for (w = 1; w < *width; w <<= 1);
|
||||
*width = w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PixmapPtr
|
||||
_fbGetWindowPixmap(WindowPtr pWindow)
|
||||
{
|
||||
return fbGetWindowPixmap(pWindow);
|
||||
}
|
||||
|
||||
void
|
||||
_fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap)
|
||||
{
|
||||
pWindow->devPrivates[fbWinPrivateIndex].ptr = (pointer) pPixmap;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbSetupScreen(ScreenPtr pScreen, pointer pbits, /* pointer to screen bitmap */
|
||||
int xsize, /* in pixels */
|
||||
int ysize, int dpix, /* dots per inch */
|
||||
int dpiy, int width, /* pixel width of frame buffer */
|
||||
int bpp)
|
||||
{ /* bits per pixel for screen */
|
||||
if (!fbAllocatePrivates(pScreen, (int *) 0))
|
||||
return FALSE;
|
||||
pScreen->defColormap = FakeClientID(0);
|
||||
/* let CreateDefColormap do whatever it wants for pixels */
|
||||
pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
|
||||
pScreen->QueryBestSize = fbQueryBestSize;
|
||||
/* SaveScreen */
|
||||
pScreen->GetImage = fbGetImage;
|
||||
pScreen->GetSpans = fbGetSpans;
|
||||
pScreen->CreateWindow = fbCreateWindow;
|
||||
pScreen->DestroyWindow = fbDestroyWindow;
|
||||
pScreen->PositionWindow = fbPositionWindow;
|
||||
pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
|
||||
pScreen->RealizeWindow = fbMapWindow;
|
||||
pScreen->UnrealizeWindow = fbUnmapWindow;
|
||||
pScreen->PaintWindowBackground = fbPaintWindow;
|
||||
pScreen->PaintWindowBorder = fbPaintWindow;
|
||||
pScreen->CopyWindow = fbCopyWindow;
|
||||
pScreen->CreatePixmap = fbCreatePixmap;
|
||||
pScreen->DestroyPixmap = fbDestroyPixmap;
|
||||
pScreen->RealizeFont = fbRealizeFont;
|
||||
pScreen->UnrealizeFont = fbUnrealizeFont;
|
||||
pScreen->CreateGC = fbCreateGC;
|
||||
pScreen->CreateColormap = fbInitializeColormap;
|
||||
pScreen->DestroyColormap = (void (*)(ColormapPtr)) NoopDDA;
|
||||
pScreen->InstallColormap = fbInstallColormap;
|
||||
pScreen->UninstallColormap = fbUninstallColormap;
|
||||
pScreen->ListInstalledColormaps = fbListInstalledColormaps;
|
||||
pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *)) NoopDDA;
|
||||
pScreen->ResolveColor = fbResolveColor;
|
||||
pScreen->BitmapToRegion = fbPixmapToRegion;
|
||||
|
||||
pScreen->GetWindowPixmap = _fbGetWindowPixmap;
|
||||
pScreen->SetWindowPixmap = _fbSetWindowPixmap;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbFinishScreenInit(ScreenPtr pScreen,
|
||||
pointer pbits,
|
||||
int xsize, int ysize, int dpix, int dpiy, int width, int bpp)
|
||||
{
|
||||
VisualPtr visuals;
|
||||
|
||||
DepthPtr depths;
|
||||
|
||||
int nvisuals;
|
||||
|
||||
int ndepths;
|
||||
|
||||
int rootdepth;
|
||||
|
||||
VisualID defaultVisual;
|
||||
|
||||
int imagebpp = bpp;
|
||||
|
||||
#ifdef FB_DEBUG
|
||||
int stride;
|
||||
|
||||
ysize -= 2;
|
||||
stride = (width * bpp) / 8;
|
||||
fbSetBits((FbStip *) pbits, stride / sizeof(FbStip), FB_HEAD_BITS);
|
||||
pbits = (void *) ((char *) pbits + stride);
|
||||
fbSetBits((FbStip *) ((char *) pbits + stride * ysize),
|
||||
stride / sizeof(FbStip), FB_TAIL_BITS);
|
||||
#endif
|
||||
/*
|
||||
* By default, a 24bpp screen will use 32bpp images, this avoids
|
||||
* problems with many applications which just can't handle packed
|
||||
* pixels. If you want real 24bit images, include a 24bpp
|
||||
* format in the pixmap formats
|
||||
*/
|
||||
if (bpp == 24) {
|
||||
int f;
|
||||
|
||||
imagebpp = 32;
|
||||
/*
|
||||
* Check to see if we're advertising a 24bpp image format,
|
||||
* in which case windows will use it in preference to a 32 bit
|
||||
* format.
|
||||
*/
|
||||
for (f = 0; f < screenInfo.numPixmapFormats; f++) {
|
||||
if (screenInfo.formats[f].bitsPerPixel == 24) {
|
||||
imagebpp = 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (imagebpp == 32) {
|
||||
fbGetScreenPrivate(pScreen)->win32bpp = bpp;
|
||||
fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
|
||||
}
|
||||
else {
|
||||
fbGetScreenPrivate(pScreen)->win32bpp = 32;
|
||||
fbGetScreenPrivate(pScreen)->pix32bpp = 32;
|
||||
}
|
||||
rootdepth = 0;
|
||||
if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
|
||||
&defaultVisual, ((unsigned long) 1 << (imagebpp - 1)),
|
||||
8))
|
||||
return FALSE;
|
||||
if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
|
||||
rootdepth, ndepths, depths,
|
||||
defaultVisual, nvisuals, visuals
|
||||
))
|
||||
return FALSE;
|
||||
/* overwrite miCloseScreen with our own */
|
||||
pScreen->CloseScreen = fbCloseScreen;
|
||||
if (bpp == 24 && imagebpp == 32) {
|
||||
pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
|
||||
pScreen->CreateScreenResources = fb24_32CreateScreenResources;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,677 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fb.h"
|
||||
#include "miline.h"
|
||||
|
||||
#define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \
|
||||
((dir < 0) ? FbStipLeft(mask,bpp) : \
|
||||
FbStipRight(mask,bpp)))
|
||||
|
||||
void
|
||||
fbBresSolid(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int dashOffset,
|
||||
int signdx,
|
||||
int signdy,
|
||||
int axis, int x1, int y1, int e, int e1, int e3, int len)
|
||||
{
|
||||
FbStip *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
FbStip and = (FbStip) pPriv->and;
|
||||
|
||||
FbStip xor = (FbStip) pPriv->xor;
|
||||
|
||||
FbStip mask, mask0;
|
||||
|
||||
FbStip bits;
|
||||
|
||||
fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
dst += ((y1 + dstYoff) * dstStride);
|
||||
x1 = (x1 + dstXoff) * dstBpp;
|
||||
dst += x1 >> FB_STIP_SHIFT;
|
||||
x1 &= FB_STIP_MASK;
|
||||
mask0 = FbStipMask(0, dstBpp);
|
||||
mask = FbStipRight(mask0, x1);
|
||||
if (signdx < 0)
|
||||
mask0 = FbStipRight(mask0, FB_STIP_UNIT - dstBpp);
|
||||
if (signdy < 0)
|
||||
dstStride = -dstStride;
|
||||
if (axis == X_AXIS) {
|
||||
bits = 0;
|
||||
while (len--) {
|
||||
bits |= mask;
|
||||
mask = fbBresShiftMask(mask, signdx, dstBpp);
|
||||
if (!mask) {
|
||||
*dst = FbDoMaskRRop(*dst, and, xor, bits);
|
||||
bits = 0;
|
||||
dst += signdx;
|
||||
mask = mask0;
|
||||
}
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
*dst = FbDoMaskRRop(*dst, and, xor, bits);
|
||||
bits = 0;
|
||||
dst += dstStride;
|
||||
e += e3;
|
||||
}
|
||||
}
|
||||
if (bits)
|
||||
*dst = FbDoMaskRRop(*dst, and, xor, bits);
|
||||
}
|
||||
else {
|
||||
while (len--) {
|
||||
*dst = FbDoMaskRRop(*dst, and, xor, mask);
|
||||
dst += dstStride;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
mask = fbBresShiftMask(mask, signdx, dstBpp);
|
||||
if (!mask) {
|
||||
dst += signdx;
|
||||
mask = mask0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbBresDash(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int dashOffset,
|
||||
int signdx,
|
||||
int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len)
|
||||
{
|
||||
FbStip *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
FbStip and = (FbStip) pPriv->and;
|
||||
|
||||
FbStip xor = (FbStip) pPriv->xor;
|
||||
|
||||
FbStip bgand = (FbStip) pPriv->bgand;
|
||||
|
||||
FbStip bgxor = (FbStip) pPriv->bgxor;
|
||||
|
||||
FbStip mask, mask0;
|
||||
|
||||
FbDashDeclare;
|
||||
int dashlen;
|
||||
|
||||
Bool even;
|
||||
|
||||
Bool doOdd;
|
||||
|
||||
fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
doOdd = pGC->lineStyle == LineDoubleDash;
|
||||
|
||||
FbDashInit(pGC, pPriv, dashOffset, dashlen, even);
|
||||
|
||||
dst += ((y1 + dstYoff) * dstStride);
|
||||
x1 = (x1 + dstXoff) * dstBpp;
|
||||
dst += x1 >> FB_STIP_SHIFT;
|
||||
x1 &= FB_STIP_MASK;
|
||||
mask0 = FbStipMask(0, dstBpp);
|
||||
mask = FbStipRight(mask0, x1);
|
||||
if (signdx < 0)
|
||||
mask0 = FbStipRight(mask0, FB_STIP_UNIT - dstBpp);
|
||||
if (signdy < 0)
|
||||
dstStride = -dstStride;
|
||||
while (len--) {
|
||||
if (even)
|
||||
*dst = FbDoMaskRRop(*dst, and, xor, mask);
|
||||
else if (doOdd)
|
||||
*dst = FbDoMaskRRop(*dst, bgand, bgxor, mask);
|
||||
if (axis == X_AXIS) {
|
||||
mask = fbBresShiftMask(mask, signdx, dstBpp);
|
||||
if (!mask) {
|
||||
dst += signdx;
|
||||
mask = mask0;
|
||||
}
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
dst += dstStride;
|
||||
e += e3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dst += dstStride;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
mask = fbBresShiftMask(mask, signdx, dstBpp);
|
||||
if (!mask) {
|
||||
dst += signdx;
|
||||
mask = mask0;
|
||||
}
|
||||
}
|
||||
}
|
||||
FbDashStep(dashlen, even);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbBresFill(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int dashOffset,
|
||||
int signdx,
|
||||
int signdy, int axis, int x1, int y1, int e, int e1, int e3, int len)
|
||||
{
|
||||
while (len--) {
|
||||
fbFill(pDrawable, pGC, x1, y1, 1, 1);
|
||||
if (axis == X_AXIS) {
|
||||
x1 += signdx;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
y1 += signdy;
|
||||
}
|
||||
}
|
||||
else {
|
||||
y1 += signdy;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
x1 += signdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fbSetFg(DrawablePtr pDrawable, GCPtr pGC, Pixel fg)
|
||||
{
|
||||
if (fg != pGC->fgPixel) {
|
||||
DoChangeGC(pGC, GCForeground, (XID *) &fg, FALSE);
|
||||
ValidateGC(pDrawable, pGC);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbBresFillDash(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int dashOffset,
|
||||
int signdx,
|
||||
int signdy,
|
||||
int axis, int x1, int y1, int e, int e1, int e3, int len)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
FbDashDeclare;
|
||||
int dashlen;
|
||||
|
||||
Bool even;
|
||||
|
||||
Bool doOdd;
|
||||
|
||||
Bool doBg;
|
||||
|
||||
Pixel fg, bg;
|
||||
|
||||
fg = pGC->fgPixel;
|
||||
bg = pGC->bgPixel;
|
||||
|
||||
/* whether to fill the odd dashes */
|
||||
doOdd = pGC->lineStyle == LineDoubleDash;
|
||||
/* whether to switch fg to bg when filling odd dashes */
|
||||
doBg = doOdd && (pGC->fillStyle == FillSolid ||
|
||||
pGC->fillStyle == FillStippled);
|
||||
|
||||
/* compute current dash position */
|
||||
FbDashInit(pGC, pPriv, dashOffset, dashlen, even);
|
||||
|
||||
while (len--) {
|
||||
if (even || doOdd) {
|
||||
if (doBg) {
|
||||
if (even)
|
||||
fbSetFg(pDrawable, pGC, fg);
|
||||
else
|
||||
fbSetFg(pDrawable, pGC, bg);
|
||||
}
|
||||
fbFill(pDrawable, pGC, x1, y1, 1, 1);
|
||||
}
|
||||
if (axis == X_AXIS) {
|
||||
x1 += signdx;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
y1 += signdy;
|
||||
}
|
||||
}
|
||||
else {
|
||||
y1 += signdy;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
x1 += signdx;
|
||||
}
|
||||
}
|
||||
FbDashStep(dashlen, even);
|
||||
}
|
||||
if (doBg)
|
||||
fbSetFg(pDrawable, pGC, fg);
|
||||
}
|
||||
|
||||
static void
|
||||
fbBresSolid24RRop(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int dashOffset,
|
||||
int signdx,
|
||||
int signdy,
|
||||
int axis, int x1, int y1, int e, int e1, int e3, int len)
|
||||
{
|
||||
FbStip *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
FbStip and = pPriv->and;
|
||||
|
||||
FbStip xor = pPriv->xor;
|
||||
|
||||
FbStip leftMask, rightMask;
|
||||
|
||||
int nl;
|
||||
|
||||
FbStip *d;
|
||||
|
||||
int x;
|
||||
|
||||
int rot;
|
||||
|
||||
FbStip andT, xorT;
|
||||
|
||||
fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
dst += ((y1 + dstYoff) * dstStride);
|
||||
x1 = (x1 + dstXoff) * 24;
|
||||
if (signdy < 0)
|
||||
dstStride = -dstStride;
|
||||
signdx *= 24;
|
||||
while (len--) {
|
||||
d = dst + (x1 >> FB_STIP_SHIFT);
|
||||
x = x1 & FB_STIP_MASK;
|
||||
rot = FbFirst24Rot(x);
|
||||
andT = FbRot24Stip(and, rot);
|
||||
xorT = FbRot24Stip(xor, rot);
|
||||
FbMaskStip(x, 24, leftMask, nl, rightMask);
|
||||
if (leftMask) {
|
||||
*d = FbDoMaskRRop(*d, andT, xorT, leftMask);
|
||||
d++;
|
||||
andT = FbNext24Stip(andT);
|
||||
xorT = FbNext24Stip(xorT);
|
||||
}
|
||||
if (rightMask)
|
||||
*d = FbDoMaskRRop(*d, andT, xorT, rightMask);
|
||||
if (axis == X_AXIS) {
|
||||
x1 += signdx;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dst += dstStride;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
x1 += signdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fbBresDash24RRop(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int dashOffset,
|
||||
int signdx,
|
||||
int signdy,
|
||||
int axis, int x1, int y1, int e, int e1, int e3, int len)
|
||||
{
|
||||
FbStip *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
FbStip andT, xorT;
|
||||
|
||||
FbStip fgand = pPriv->and;
|
||||
|
||||
FbStip fgxor = pPriv->xor;
|
||||
|
||||
FbStip bgand = pPriv->bgand;
|
||||
|
||||
FbStip bgxor = pPriv->bgxor;
|
||||
|
||||
FbStip leftMask, rightMask;
|
||||
|
||||
int nl;
|
||||
|
||||
FbStip *d;
|
||||
|
||||
int x;
|
||||
|
||||
int rot;
|
||||
|
||||
FbDashDeclare;
|
||||
int dashlen;
|
||||
|
||||
Bool even;
|
||||
|
||||
Bool doOdd;
|
||||
|
||||
fbGetStipDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
doOdd = pGC->lineStyle == LineDoubleDash;
|
||||
|
||||
/* compute current dash position */
|
||||
FbDashInit(pGC, pPriv, dashOffset, dashlen, even);
|
||||
|
||||
dst += ((y1 + dstYoff) * dstStride);
|
||||
x1 = (x1 + dstXoff) * 24;
|
||||
if (signdy < 0)
|
||||
dstStride = -dstStride;
|
||||
signdx *= 24;
|
||||
while (len--) {
|
||||
if (even || doOdd) {
|
||||
if (even) {
|
||||
andT = fgand;
|
||||
xorT = fgxor;
|
||||
}
|
||||
else {
|
||||
andT = bgand;
|
||||
xorT = bgxor;
|
||||
}
|
||||
d = dst + (x1 >> FB_STIP_SHIFT);
|
||||
x = x1 & FB_STIP_MASK;
|
||||
rot = FbFirst24Rot(x);
|
||||
andT = FbRot24Stip(andT, rot);
|
||||
xorT = FbRot24Stip(xorT, rot);
|
||||
FbMaskStip(x, 24, leftMask, nl, rightMask);
|
||||
if (leftMask) {
|
||||
*d = FbDoMaskRRop(*d, andT, xorT, leftMask);
|
||||
d++;
|
||||
andT = FbNext24Stip(andT);
|
||||
xorT = FbNext24Stip(xorT);
|
||||
}
|
||||
if (rightMask)
|
||||
*d = FbDoMaskRRop(*d, andT, xorT, rightMask);
|
||||
}
|
||||
if (axis == X_AXIS) {
|
||||
x1 += signdx;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dst += dstStride;
|
||||
e += e1;
|
||||
if (e >= 0) {
|
||||
e += e3;
|
||||
x1 += signdx;
|
||||
}
|
||||
}
|
||||
FbDashStep(dashlen, even);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For drivers that want to bail drawing some lines, this
|
||||
* function takes care of selecting the appropriate rasterizer
|
||||
* based on the contents of the specified GC.
|
||||
*/
|
||||
|
||||
FbBres *
|
||||
fbSelectBres(DrawablePtr pDrawable, GCPtr pGC)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
int dstBpp = pDrawable->bitsPerPixel;
|
||||
|
||||
FbBres *bres;
|
||||
|
||||
if (pGC->lineStyle == LineSolid) {
|
||||
bres = fbBresFill;
|
||||
if (pGC->fillStyle == FillSolid) {
|
||||
bres = fbBresSolid;
|
||||
if (dstBpp == 24)
|
||||
bres = fbBresSolid24RRop;
|
||||
if (pPriv->and == 0) {
|
||||
switch (dstBpp) {
|
||||
case 8:
|
||||
bres = fbBresSolid8;
|
||||
break;
|
||||
case 16:
|
||||
bres = fbBresSolid16;
|
||||
break;
|
||||
case 24:
|
||||
bres = fbBresSolid24;
|
||||
break;
|
||||
case 32:
|
||||
bres = fbBresSolid32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
bres = fbBresFillDash;
|
||||
if (pGC->fillStyle == FillSolid) {
|
||||
bres = fbBresDash;
|
||||
if (dstBpp == 24)
|
||||
bres = fbBresDash24RRop;
|
||||
if (pPriv->and == 0 &&
|
||||
(pGC->lineStyle == LineOnOffDash || pPriv->bgand == 0)) {
|
||||
switch (dstBpp) {
|
||||
case 8:
|
||||
bres = fbBresDash8;
|
||||
break;
|
||||
case 16:
|
||||
bres = fbBresDash16;
|
||||
break;
|
||||
case 24:
|
||||
bres = fbBresDash24;
|
||||
break;
|
||||
case 32:
|
||||
bres = fbBresDash32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bres;
|
||||
}
|
||||
|
||||
void
|
||||
fbSegment(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
int x1, int y1, int x2, int y2, Bool drawLast, int *dashOffset)
|
||||
{
|
||||
FbBres *bres;
|
||||
|
||||
RegionPtr pClip = fbGetCompositeClip(pGC);
|
||||
|
||||
BoxPtr pBox;
|
||||
|
||||
int nBox;
|
||||
|
||||
int adx; /* abs values of dx and dy */
|
||||
|
||||
int ady;
|
||||
|
||||
int signdx; /* sign of dx and dy */
|
||||
|
||||
int signdy;
|
||||
|
||||
int e, e1, e2, e3; /* bresenham error and increments */
|
||||
|
||||
int len; /* length of segment */
|
||||
|
||||
int axis; /* major axis */
|
||||
|
||||
int octant;
|
||||
|
||||
int dashoff;
|
||||
|
||||
int doff;
|
||||
|
||||
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
|
||||
|
||||
unsigned int oc1; /* outcode of point 1 */
|
||||
|
||||
unsigned int oc2; /* outcode of point 2 */
|
||||
|
||||
nBox = REGION_NUM_RECTS(pClip);
|
||||
pBox = REGION_RECTS(pClip);
|
||||
|
||||
bres = fbSelectBres(pDrawable, pGC);
|
||||
|
||||
CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
|
||||
|
||||
if (adx > ady) {
|
||||
axis = X_AXIS;
|
||||
e1 = ady << 1;
|
||||
e2 = e1 - (adx << 1);
|
||||
e = e1 - adx;
|
||||
len = adx;
|
||||
}
|
||||
else {
|
||||
axis = Y_AXIS;
|
||||
e1 = adx << 1;
|
||||
e2 = e1 - (ady << 1);
|
||||
e = e1 - ady;
|
||||
SetYMajorOctant(octant);
|
||||
len = ady;
|
||||
}
|
||||
|
||||
FIXUP_ERROR(e, octant, bias);
|
||||
|
||||
/*
|
||||
* Adjust error terms to compare against zero
|
||||
*/
|
||||
e3 = e2 - e1;
|
||||
e = e - e1;
|
||||
|
||||
/* we have bresenham parameters and two points.
|
||||
all we have to do now is clip and draw.
|
||||
*/
|
||||
|
||||
if (drawLast)
|
||||
len++;
|
||||
dashoff = *dashOffset;
|
||||
*dashOffset = dashoff + len;
|
||||
while (nBox--) {
|
||||
oc1 = 0;
|
||||
oc2 = 0;
|
||||
OUTCODES(oc1, x1, y1, pBox);
|
||||
OUTCODES(oc2, x2, y2, pBox);
|
||||
if ((oc1 | oc2) == 0) {
|
||||
(*bres) (pDrawable, pGC, dashoff,
|
||||
signdx, signdy, axis, x1, y1, e, e1, e3, len);
|
||||
break;
|
||||
}
|
||||
else if (oc1 & oc2) {
|
||||
pBox++;
|
||||
}
|
||||
else {
|
||||
int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
|
||||
|
||||
int clip1 = 0, clip2 = 0;
|
||||
|
||||
int clipdx, clipdy;
|
||||
|
||||
int err;
|
||||
|
||||
if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2 - 1,
|
||||
pBox->y2 - 1,
|
||||
&new_x1, &new_y1, &new_x2, &new_y2,
|
||||
adx, ady, &clip1, &clip2,
|
||||
octant, bias, oc1, oc2) == -1) {
|
||||
pBox++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (axis == X_AXIS)
|
||||
len = abs(new_x2 - new_x1);
|
||||
else
|
||||
len = abs(new_y2 - new_y1);
|
||||
if (clip2 != 0 || drawLast)
|
||||
len++;
|
||||
if (len) {
|
||||
/* unwind bresenham error term to first point */
|
||||
doff = dashoff;
|
||||
err = e;
|
||||
if (clip1) {
|
||||
clipdx = abs(new_x1 - x1);
|
||||
clipdy = abs(new_y1 - y1);
|
||||
if (axis == X_AXIS) {
|
||||
doff += clipdx;
|
||||
err += e3 * clipdy + e1 * clipdx;
|
||||
}
|
||||
else {
|
||||
doff += clipdy;
|
||||
err += e3 * clipdx + e1 * clipdy;
|
||||
}
|
||||
}
|
||||
(*bres) (pDrawable, pGC, doff,
|
||||
signdx, signdy, axis, new_x1, new_y1,
|
||||
err, e1, e3, len);
|
||||
}
|
||||
pBox++;
|
||||
}
|
||||
} /* while (nBox--) */
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbSetSpans(DrawablePtr pDrawable,
|
||||
GCPtr pGC,
|
||||
char *src, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
|
||||
{
|
||||
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
||||
|
||||
RegionPtr pClip = fbGetCompositeClip(pGC);
|
||||
|
||||
FbBits *dst, *d, *s;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
BoxPtr pbox;
|
||||
|
||||
int n;
|
||||
|
||||
int xoff;
|
||||
|
||||
int x1, x2;
|
||||
|
||||
if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
|
||||
fb24_32SetSpans(pDrawable, pGC, src, ppt, pwidth, nspans, fSorted);
|
||||
return;
|
||||
}
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
while (nspans--) {
|
||||
d = dst + (ppt->y + dstYoff) * dstStride;
|
||||
xoff = (int) (((long) src) & (FB_MASK >> 3));
|
||||
s = (FbBits *) (src - xoff);
|
||||
xoff <<= 3;
|
||||
n = REGION_NUM_RECTS(pClip);
|
||||
pbox = REGION_RECTS(pClip);
|
||||
while (n--) {
|
||||
if (pbox->y1 > ppt->y)
|
||||
break;
|
||||
if (pbox->y2 > ppt->y) {
|
||||
x1 = ppt->x;
|
||||
x2 = x1 + *pwidth;
|
||||
if (pbox->x1 > x1)
|
||||
x1 = pbox->x1;
|
||||
if (pbox->x2 < x2)
|
||||
x2 = pbox->x2;
|
||||
if (x1 < x2)
|
||||
fbBlt((FbBits *) s,
|
||||
0,
|
||||
(x1 - ppt->x) * dstBpp + xoff,
|
||||
d,
|
||||
dstStride,
|
||||
(x1 + dstXoff) * dstBpp,
|
||||
(x2 - x1) * dstBpp,
|
||||
1, pGC->alu, pPriv->pm, dstBpp, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
src += PixmapBytePad(*pwidth, pDrawable->depth);
|
||||
ppt++;
|
||||
pwidth++;
|
||||
}
|
||||
fbValidateDrawable(pDrawable);
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define FbSelectPart(xor,o,t) xor
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
void
|
||||
fbSolid(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstX, int bpp, int width, int height, FbBits and, FbBits xor)
|
||||
{
|
||||
FbBits startmask, endmask;
|
||||
|
||||
int n, nmiddle;
|
||||
|
||||
int startbyte, endbyte;
|
||||
|
||||
if (bpp == 24 && (!FbCheck24Pix(and) || !FbCheck24Pix(xor))) {
|
||||
fbSolid24(dst, dstStride, dstX, width, height, and, xor);
|
||||
return;
|
||||
}
|
||||
dst += dstX >> FB_SHIFT;
|
||||
dstX &= FB_MASK;
|
||||
FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte,
|
||||
nmiddle, endmask, endbyte);
|
||||
if (startmask)
|
||||
dstStride--;
|
||||
dstStride -= nmiddle;
|
||||
while (height--) {
|
||||
if (startmask) {
|
||||
FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (!and)
|
||||
while (n--)
|
||||
*dst++ = xor;
|
||||
else
|
||||
while (n--) {
|
||||
*dst = FbDoRRop(*dst, and, xor);
|
||||
dst++;
|
||||
}
|
||||
if (endmask)
|
||||
FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbSolid24(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstX, int width, int height, FbBits and, FbBits xor)
|
||||
{
|
||||
FbBits startmask, endmask;
|
||||
|
||||
FbBits xor0 = 0, xor1 = 0, xor2 = 0;
|
||||
|
||||
FbBits and0 = 0, and1 = 0, and2 = 0;
|
||||
|
||||
FbBits xorS = 0, andS = 0, xorE = 0, andE = 0;
|
||||
|
||||
int n, nmiddle;
|
||||
|
||||
int rotS, rot;
|
||||
|
||||
dst += dstX >> FB_SHIFT;
|
||||
dstX &= FB_MASK;
|
||||
/*
|
||||
* Rotate pixel values this far across the word to align on
|
||||
* screen pixel boundaries
|
||||
*/
|
||||
rot = FbFirst24Rot(dstX);
|
||||
FbMaskBits(dstX, width, startmask, nmiddle, endmask);
|
||||
if (startmask)
|
||||
dstStride--;
|
||||
dstStride -= nmiddle;
|
||||
|
||||
/*
|
||||
* Precompute rotated versions of the rasterop values
|
||||
*/
|
||||
rotS = rot;
|
||||
xor = FbRot24(xor, rotS);
|
||||
and = FbRot24(and, rotS);
|
||||
if (startmask) {
|
||||
xorS = xor;
|
||||
andS = and;
|
||||
xor = FbNext24Pix(xor);
|
||||
and = FbNext24Pix(and);
|
||||
}
|
||||
|
||||
if (nmiddle) {
|
||||
xor0 = xor;
|
||||
and0 = and;
|
||||
xor1 = FbNext24Pix(xor0);
|
||||
and1 = FbNext24Pix(and0);
|
||||
xor2 = FbNext24Pix(xor1);
|
||||
and2 = FbNext24Pix(and1);
|
||||
}
|
||||
|
||||
if (endmask) {
|
||||
switch (nmiddle % 3) {
|
||||
case 0:
|
||||
xorE = xor;
|
||||
andE = and;
|
||||
break;
|
||||
case 1:
|
||||
xorE = xor1;
|
||||
andE = and1;
|
||||
break;
|
||||
case 2:
|
||||
xorE = xor2;
|
||||
andE = and2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (height--) {
|
||||
if (startmask) {
|
||||
*dst = FbDoMaskRRop(*dst, andS, xorS, startmask);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (!and0) {
|
||||
while (n >= 3) {
|
||||
*dst++ = xor0;
|
||||
*dst++ = xor1;
|
||||
*dst++ = xor2;
|
||||
n -= 3;
|
||||
}
|
||||
if (n) {
|
||||
*dst++ = xor0;
|
||||
n--;
|
||||
if (n) {
|
||||
*dst++ = xor1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (n >= 3) {
|
||||
*dst = FbDoRRop(*dst, and0, xor0);
|
||||
dst++;
|
||||
*dst = FbDoRRop(*dst, and1, xor1);
|
||||
dst++;
|
||||
*dst = FbDoRRop(*dst, and2, xor2);
|
||||
dst++;
|
||||
n -= 3;
|
||||
}
|
||||
if (n) {
|
||||
*dst = FbDoRRop(*dst, and0, xor0);
|
||||
dst++;
|
||||
n--;
|
||||
if (n) {
|
||||
*dst = FbDoRRop(*dst, and1, xor1);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (endmask)
|
||||
*dst = FbDoMaskRRop(*dst, andE, xorE, endmask);
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
/*
|
||||
* This is a slight abuse of the preprocessor to generate repetitive
|
||||
* code, the idea is to generate code for each case of a copy-mode
|
||||
* transparent stipple
|
||||
*/
|
||||
#define LaneCases1(c,a) case c: \
|
||||
while (n--) { (void)FbLaneCase(c,a); a++; } \
|
||||
break
|
||||
#define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a)
|
||||
#define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a)
|
||||
#define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a)
|
||||
#define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a)
|
||||
#define LaneCases32(c,a) LaneCases16(c,a); LaneCases16(c+16,a)
|
||||
#define LaneCases64(c,a) LaneCases32(c,a); LaneCases32(c+32,a)
|
||||
#define LaneCases128(c,a) LaneCases64(c,a); LaneCases64(c+64,a)
|
||||
#define LaneCases256(c,a) LaneCases128(c,a); LaneCases128(c+128,a)
|
||||
|
||||
#if FB_SHIFT == 6
|
||||
#define LaneCases(a) LaneCases256(0,a)
|
||||
#endif
|
||||
|
||||
#if FB_SHIFT == 5
|
||||
#define LaneCases(a) LaneCases16(0,a)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Repeat a transparent stipple across a scanline n times
|
||||
*/
|
||||
|
||||
void
|
||||
fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n)
|
||||
{
|
||||
FbStip s;
|
||||
|
||||
s = ((FbStip) (stip) & 0x01);
|
||||
s |= ((FbStip) (stip >> 8) & 0x02);
|
||||
s |= ((FbStip) (stip >> 16) & 0x04);
|
||||
s |= ((FbStip) (stip >> 24) & 0x08);
|
||||
#if FB_SHIFT > 5
|
||||
s |= ((FbStip) (stip >> 32) & 0x10);
|
||||
s |= ((FbStip) (stip >> 40) & 0x20);
|
||||
s |= ((FbStip) (stip >> 48) & 0x40);
|
||||
s |= ((FbStip) (stip >> 56) & 0x80);
|
||||
#endif
|
||||
switch (s) {
|
||||
LaneCases(dst);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbEvenStipple(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int dstBpp,
|
||||
int width,
|
||||
int height,
|
||||
FbStip * stip,
|
||||
FbStride stipStride,
|
||||
int stipHeight,
|
||||
FbBits fgand,
|
||||
FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
|
||||
{
|
||||
FbBits startmask, endmask;
|
||||
|
||||
FbBits mask, and, xor;
|
||||
|
||||
int nmiddle, n;
|
||||
|
||||
FbStip *s, *stipEnd, bits;
|
||||
|
||||
int rot, stipX, stipY;
|
||||
|
||||
int pixelsPerDst;
|
||||
|
||||
const FbBits *fbBits;
|
||||
|
||||
Bool transparent;
|
||||
|
||||
int startbyte, endbyte;
|
||||
|
||||
/*
|
||||
* Check for a transparent stipple (stencil)
|
||||
*/
|
||||
transparent = FALSE;
|
||||
if (dstBpp >= 8 && fgand == 0 && bgand == FB_ALLONES && bgxor == 0)
|
||||
transparent = TRUE;
|
||||
|
||||
pixelsPerDst = FB_UNIT / dstBpp;
|
||||
/*
|
||||
* Adjust dest pointers
|
||||
*/
|
||||
dst += dstX >> FB_SHIFT;
|
||||
dstX &= FB_MASK;
|
||||
FbMaskBitsBytes(dstX, width, fgand == 0 && bgand == 0,
|
||||
startmask, startbyte, nmiddle, endmask, endbyte);
|
||||
|
||||
if (startmask)
|
||||
dstStride--;
|
||||
dstStride -= nmiddle;
|
||||
|
||||
xRot *= dstBpp;
|
||||
/*
|
||||
* Compute stip start scanline and rotation parameters
|
||||
*/
|
||||
stipEnd = stip + stipStride * stipHeight;
|
||||
modulus(-yRot, stipHeight, stipY);
|
||||
s = stip + stipStride * stipY;
|
||||
modulus(-xRot, FB_UNIT, stipX);
|
||||
rot = stipX;
|
||||
|
||||
/*
|
||||
* Get pointer to stipple mask array for this depth
|
||||
*/
|
||||
/* fbStippleTable covers all valid bpp (4,8,16,32) */
|
||||
fbBits = fbStippleTable[pixelsPerDst];
|
||||
|
||||
while (height--) {
|
||||
/*
|
||||
* Extract stipple bits for this scanline;
|
||||
*/
|
||||
bits = *s;
|
||||
s += stipStride;
|
||||
if (s == stipEnd)
|
||||
s = stip;
|
||||
#if FB_UNIT > 32
|
||||
if (pixelsPerDst == 16)
|
||||
mask = FbStipple16Bits(FbLeftStipBits(bits, 16));
|
||||
else
|
||||
#endif
|
||||
mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
|
||||
/*
|
||||
* Rotate into position and compute reduced rop values
|
||||
*/
|
||||
mask = FbRotLeft(mask, rot);
|
||||
and = (fgand & mask) | (bgand & ~mask);
|
||||
xor = (fgxor & mask) | (bgxor & ~mask);
|
||||
|
||||
if (transparent) {
|
||||
if (startmask) {
|
||||
fbTransparentSpan(dst, mask & startmask, fgxor, 1);
|
||||
dst++;
|
||||
}
|
||||
fbTransparentSpan(dst, mask, fgxor, nmiddle);
|
||||
dst += nmiddle;
|
||||
if (endmask)
|
||||
fbTransparentSpan(dst, mask & endmask, fgxor, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Fill scanline
|
||||
*/
|
||||
if (startmask) {
|
||||
FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (!and)
|
||||
while (n--)
|
||||
*dst++ = xor;
|
||||
else {
|
||||
while (n--) {
|
||||
*dst = FbDoRRop(*dst, and, xor);
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
if (endmask)
|
||||
FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
|
||||
}
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbOddStipple(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int dstBpp,
|
||||
int width,
|
||||
int height,
|
||||
FbStip * stip,
|
||||
FbStride stipStride,
|
||||
int stipWidth,
|
||||
int stipHeight,
|
||||
FbBits fgand,
|
||||
FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
|
||||
{
|
||||
int stipX, stipY, sx;
|
||||
|
||||
int widthTmp;
|
||||
|
||||
int h, w;
|
||||
|
||||
int x, y;
|
||||
|
||||
modulus(-yRot, stipHeight, stipY);
|
||||
modulus(dstX / dstBpp - xRot, stipWidth, stipX);
|
||||
y = 0;
|
||||
while (height) {
|
||||
h = stipHeight - stipY;
|
||||
if (h > height)
|
||||
h = height;
|
||||
height -= h;
|
||||
widthTmp = width;
|
||||
x = dstX;
|
||||
sx = stipX;
|
||||
while (widthTmp) {
|
||||
w = (stipWidth - sx) * dstBpp;
|
||||
if (w > widthTmp)
|
||||
w = widthTmp;
|
||||
widthTmp -= w;
|
||||
fbBltOne(stip + stipY * stipStride,
|
||||
stipStride,
|
||||
sx,
|
||||
dst + y * dstStride,
|
||||
dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor);
|
||||
x += w;
|
||||
sx = 0;
|
||||
}
|
||||
y += h;
|
||||
stipY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbStipple(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int dstBpp,
|
||||
int width,
|
||||
int height,
|
||||
FbStip * stip,
|
||||
FbStride stipStride,
|
||||
int stipWidth,
|
||||
int stipHeight,
|
||||
Bool even,
|
||||
FbBits fgand,
|
||||
FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
|
||||
{
|
||||
if (even)
|
||||
fbEvenStipple(dst, dstStride, dstX, dstBpp, width, height,
|
||||
stip, stipStride, stipHeight,
|
||||
fgand, fgxor, bgand, bgxor, xRot, yRot);
|
||||
else
|
||||
fbOddStipple(dst, dstStride, dstX, dstBpp, width, height,
|
||||
stip, stipStride, stipWidth, stipHeight,
|
||||
fgand, fgxor, bgand, bgxor, xRot, yRot);
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
/*
|
||||
* Accelerated tile fill -- tile width is a power of two not greater
|
||||
* than FB_UNIT
|
||||
*/
|
||||
|
||||
void
|
||||
fbEvenTile(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int width,
|
||||
int height,
|
||||
FbBits * tile,
|
||||
int tileHeight, int alu, FbBits pm, int xRot, int yRot)
|
||||
{
|
||||
FbBits *t, *tileEnd, bits;
|
||||
FbBits startmask, endmask;
|
||||
FbBits and, xor;
|
||||
int n, nmiddle;
|
||||
int tileX, tileY;
|
||||
int rot;
|
||||
int startbyte, endbyte;
|
||||
|
||||
dst += dstX >> FB_SHIFT;
|
||||
dstX &= FB_MASK;
|
||||
FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm),
|
||||
startmask, startbyte, nmiddle, endmask, endbyte);
|
||||
if (startmask)
|
||||
dstStride--;
|
||||
dstStride -= nmiddle;
|
||||
|
||||
/*
|
||||
* Compute tile start scanline and rotation parameters
|
||||
*/
|
||||
tileEnd = tile + tileHeight;
|
||||
modulus(-yRot, tileHeight, tileY);
|
||||
t = tile + tileY;
|
||||
modulus(-xRot, FB_UNIT, tileX);
|
||||
rot = tileX;
|
||||
|
||||
while (height--) {
|
||||
|
||||
/*
|
||||
* Pick up bits for this scanline
|
||||
*/
|
||||
bits = *t++;
|
||||
if (t == tileEnd)
|
||||
t = tile;
|
||||
bits = FbRotLeft(bits, rot);
|
||||
and = fbAnd(alu, bits, pm);
|
||||
xor = fbXor(alu, bits, pm);
|
||||
|
||||
if (startmask) {
|
||||
FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
|
||||
dst++;
|
||||
}
|
||||
n = nmiddle;
|
||||
if (!and)
|
||||
while (n--)
|
||||
*dst++ = xor;
|
||||
else
|
||||
while (n--) {
|
||||
*dst = FbDoRRop(*dst, and, xor);
|
||||
dst++;
|
||||
}
|
||||
if (endmask)
|
||||
FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
|
||||
dst += dstStride;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbOddTile(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int width,
|
||||
int height,
|
||||
FbBits * tile,
|
||||
FbStride tileStride,
|
||||
int tileWidth,
|
||||
int tileHeight, int alu, FbBits pm, int bpp, int xRot, int yRot)
|
||||
{
|
||||
int tileX, tileY;
|
||||
int widthTmp;
|
||||
int h, w;
|
||||
int x, y;
|
||||
|
||||
modulus(-yRot, tileHeight, tileY);
|
||||
y = 0;
|
||||
while (height) {
|
||||
h = tileHeight - tileY;
|
||||
if (h > height)
|
||||
h = height;
|
||||
height -= h;
|
||||
widthTmp = width;
|
||||
x = dstX;
|
||||
modulus(dstX - xRot, tileWidth, tileX);
|
||||
while (widthTmp) {
|
||||
w = tileWidth - tileX;
|
||||
if (w > widthTmp)
|
||||
w = widthTmp;
|
||||
widthTmp -= w;
|
||||
fbBlt(tile + tileY * tileStride,
|
||||
tileStride,
|
||||
tileX,
|
||||
dst + y * dstStride,
|
||||
dstStride, x, w, h, alu, pm, bpp, FALSE, FALSE);
|
||||
x += w;
|
||||
tileX = 0;
|
||||
}
|
||||
y += h;
|
||||
tileY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbTile(FbBits * dst,
|
||||
FbStride dstStride,
|
||||
int dstX,
|
||||
int width,
|
||||
int height,
|
||||
FbBits * tile,
|
||||
FbStride tileStride,
|
||||
int tileWidth,
|
||||
int tileHeight, int alu, FbBits pm, int bpp, int xRot, int yRot)
|
||||
{
|
||||
if (FbEvenTile(tileWidth))
|
||||
fbEvenTile(dst, dstStride, dstX, width, height,
|
||||
tile, tileHeight, alu, pm, xRot, yRot);
|
||||
else
|
||||
fbOddTile(dst, dstStride, dstX, width, height,
|
||||
tile, tileStride, tileWidth, tileHeight,
|
||||
alu, pm, bpp, xRot, yRot);
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
|
||||
#include "picturestr.h"
|
||||
#include "mipict.h"
|
||||
#include "renderedge.h"
|
||||
#include "fbpict.h"
|
||||
|
||||
void
|
||||
fbAddTraps(PicturePtr pPicture,
|
||||
INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
|
||||
{
|
||||
FbBits *buf;
|
||||
|
||||
int bpp;
|
||||
int width;
|
||||
int stride;
|
||||
int height;
|
||||
int pxoff, pyoff;
|
||||
|
||||
xFixed x_off_fixed;
|
||||
xFixed y_off_fixed;
|
||||
|
||||
RenderEdge l, r;
|
||||
|
||||
xFixed t, b;
|
||||
|
||||
fbGetDrawable(pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
|
||||
|
||||
width = pPicture->pDrawable->width;
|
||||
height = pPicture->pDrawable->height;
|
||||
x_off += pxoff;
|
||||
y_off += pyoff;
|
||||
|
||||
x_off_fixed = IntToxFixed(x_off);
|
||||
y_off_fixed = IntToxFixed(y_off);
|
||||
|
||||
while (ntrap--) {
|
||||
t = traps->top.y + y_off_fixed;
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
t = RenderSampleCeilY(t, bpp);
|
||||
|
||||
b = traps->bot.y + y_off_fixed;
|
||||
if (xFixedToInt(b) >= height)
|
||||
b = IntToxFixed(height) - 1;
|
||||
b = RenderSampleFloorY(b, bpp);
|
||||
|
||||
if (b >= t) {
|
||||
/* initialize edge walkers */
|
||||
RenderEdgeInit(&l, bpp, t,
|
||||
traps->top.l + x_off_fixed,
|
||||
traps->top.y + y_off_fixed,
|
||||
traps->bot.l + x_off_fixed,
|
||||
traps->bot.y + y_off_fixed);
|
||||
|
||||
RenderEdgeInit(&r, bpp, t,
|
||||
traps->top.r + x_off_fixed,
|
||||
traps->top.y + y_off_fixed,
|
||||
traps->bot.r + x_off_fixed,
|
||||
traps->bot.y + y_off_fixed);
|
||||
|
||||
fbRasterizeEdges(buf, bpp, width, stride, &l, &r, t, b);
|
||||
}
|
||||
traps++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbRasterizeTrapezoid(PicturePtr pPicture,
|
||||
xTrapezoid * trap, int x_off, int y_off)
|
||||
{
|
||||
FbBits *buf;
|
||||
|
||||
int bpp;
|
||||
|
||||
int width;
|
||||
|
||||
int stride;
|
||||
|
||||
int height;
|
||||
|
||||
int pxoff, pyoff;
|
||||
|
||||
xFixed x_off_fixed _X_UNUSED;
|
||||
xFixed y_off_fixed;
|
||||
|
||||
RenderEdge l, r;
|
||||
|
||||
xFixed t, b;
|
||||
|
||||
fbGetDrawable(pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
|
||||
|
||||
width = pPicture->pDrawable->width;
|
||||
height = pPicture->pDrawable->height;
|
||||
x_off += pxoff;
|
||||
y_off += pyoff;
|
||||
|
||||
x_off_fixed = IntToxFixed(x_off);
|
||||
y_off_fixed = IntToxFixed(y_off);
|
||||
t = trap->top + y_off_fixed;
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
t = RenderSampleCeilY(t, bpp);
|
||||
|
||||
b = trap->bottom + y_off_fixed;
|
||||
if (xFixedToInt(b) >= height)
|
||||
b = IntToxFixed(height) - 1;
|
||||
b = RenderSampleFloorY(b, bpp);
|
||||
|
||||
if (b >= t) {
|
||||
/* initialize edge walkers */
|
||||
RenderLineFixedEdgeInit(&l, bpp, t, &trap->left, x_off, y_off);
|
||||
RenderLineFixedEdgeInit(&r, bpp, t, &trap->right, x_off, y_off);
|
||||
|
||||
fbRasterizeEdges(buf, bpp, width, stride, &l, &r, t, b);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_GreaterY(xPointFixed * a, xPointFixed * b)
|
||||
{
|
||||
if (a->y == b->y)
|
||||
return a->x > b->x;
|
||||
return a->y > b->y;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the definition of this function is a bit odd because
|
||||
* of the X coordinate space (y increasing downwards).
|
||||
*/
|
||||
static int
|
||||
_Clockwise(xPointFixed * ref, xPointFixed * a, xPointFixed * b)
|
||||
{
|
||||
xPointFixed ad, bd;
|
||||
|
||||
ad.x = a->x - ref->x;
|
||||
ad.y = a->y - ref->y;
|
||||
bd.x = b->x - ref->x;
|
||||
bd.y = b->y - ref->y;
|
||||
|
||||
return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0;
|
||||
}
|
||||
|
||||
/* FIXME -- this could be made more efficient */
|
||||
void
|
||||
fbAddTriangles(PicturePtr pPicture,
|
||||
INT16 x_off, INT16 y_off, int ntri, xTriangle * tris)
|
||||
{
|
||||
xPointFixed *top, *left, *right, *tmp;
|
||||
|
||||
xTrapezoid trap;
|
||||
|
||||
for (; ntri; ntri--, tris++) {
|
||||
top = &tris->p1;
|
||||
left = &tris->p2;
|
||||
right = &tris->p3;
|
||||
if (_GreaterY(top, left)) {
|
||||
tmp = left;
|
||||
left = top;
|
||||
top = tmp;
|
||||
}
|
||||
if (_GreaterY(top, right)) {
|
||||
tmp = right;
|
||||
right = top;
|
||||
top = tmp;
|
||||
}
|
||||
if (_Clockwise(top, right, left)) {
|
||||
tmp = right;
|
||||
right = left;
|
||||
left = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Two cases:
|
||||
*
|
||||
* + +
|
||||
* / \ / \
|
||||
* / \ / \
|
||||
* / + + \
|
||||
* / -- -- \
|
||||
* / -- -- \
|
||||
* / --- --- \
|
||||
* +-- --+
|
||||
*/
|
||||
|
||||
trap.top = top->y;
|
||||
trap.left.p1 = *top;
|
||||
trap.left.p2 = *left;
|
||||
trap.right.p1 = *top;
|
||||
trap.right.p2 = *right;
|
||||
if (right->y < left->y)
|
||||
trap.bottom = right->y;
|
||||
else
|
||||
trap.bottom = left->y;
|
||||
fbRasterizeTrapezoid(pPicture, &trap, x_off, y_off);
|
||||
if (right->y < left->y) {
|
||||
trap.top = right->y;
|
||||
trap.bottom = left->y;
|
||||
trap.right.p1 = *right;
|
||||
trap.right.p2 = *left;
|
||||
}
|
||||
else {
|
||||
trap.top = left->y;
|
||||
trap.bottom = right->y;
|
||||
trap.left.p1 = *left;
|
||||
trap.left.p2 = *right;
|
||||
}
|
||||
fbRasterizeTrapezoid(pPicture, &trap, x_off, y_off);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
FbBits
|
||||
fbReplicatePixel(Pixel p, int bpp)
|
||||
{
|
||||
FbBits b = p;
|
||||
|
||||
b &= FbFullMask(bpp);
|
||||
while (bpp < FB_UNIT) {
|
||||
b |= b << bpp;
|
||||
bpp <<= 1;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
#define O 0
|
||||
#define I FB_ALLONES
|
||||
|
||||
const FbMergeRopRec FbMergeRopBits[16] = {
|
||||
{O, O, O, O}, /* clear 0x0 0 */
|
||||
{I, O, O, O}, /* and 0x1 src AND dst */
|
||||
{I, O, I, O}, /* andReverse 0x2 src AND NOT dst */
|
||||
{O, O, I, O}, /* copy 0x3 src */
|
||||
{I, I, O, O}, /* andInverted 0x4 NOT src AND dst */
|
||||
{O, I, O, O}, /* noop 0x5 dst */
|
||||
{O, I, I, O}, /* xor 0x6 src XOR dst */
|
||||
{I, I, I, O}, /* or 0x7 src OR dst */
|
||||
{I, I, I, I}, /* nor 0x8 NOT src AND NOT dst */
|
||||
{O, I, I, I}, /* equiv 0x9 NOT src XOR dst */
|
||||
{O, I, O, I}, /* invert 0xa NOT dst */
|
||||
{I, I, O, I}, /* orReverse 0xb src OR NOT dst */
|
||||
{O, O, I, I}, /* copyInverted 0xc NOT src */
|
||||
{I, O, I, I}, /* orInverted 0xd NOT src OR dst */
|
||||
{I, O, O, I}, /* nand 0xe NOT src OR NOT dst */
|
||||
{O, O, O, I}, /* set 0xf 1 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Stipple masks are independent of bit/byte order as long
|
||||
* as bitorder == byteorder. FB doesn't handle the case
|
||||
* where these differ
|
||||
*/
|
||||
#define BitsMask(x,w) ((FB_ALLONES << ((x) & FB_MASK)) & \
|
||||
(FB_ALLONES >> ((FB_UNIT - ((x) + (w))) & FB_MASK)))
|
||||
|
||||
#define Mask(x,w) BitsMask((x)*(w),(w))
|
||||
|
||||
#define SelMask(b,n,w) ((((b) >> n) & 1) * Mask(n,w))
|
||||
|
||||
#define C1(b,w) \
|
||||
(SelMask(b,0,w))
|
||||
|
||||
#define C2(b,w) \
|
||||
(SelMask(b,0,w) | \
|
||||
SelMask(b,1,w))
|
||||
|
||||
#define C4(b,w) \
|
||||
(SelMask(b,0,w) | \
|
||||
SelMask(b,1,w) | \
|
||||
SelMask(b,2,w) | \
|
||||
SelMask(b,3,w))
|
||||
|
||||
#define C8(b,w) \
|
||||
(SelMask(b,0,w) | \
|
||||
SelMask(b,1,w) | \
|
||||
SelMask(b,2,w) | \
|
||||
SelMask(b,3,w) | \
|
||||
SelMask(b,4,w) | \
|
||||
SelMask(b,5,w) | \
|
||||
SelMask(b,6,w) | \
|
||||
SelMask(b,7,w))
|
||||
|
||||
#if FB_UNIT == 16
|
||||
#define fbStipple16Bits 0
|
||||
#define fbStipple8Bits 0
|
||||
const FbBits fbStipple4Bits[16] = {
|
||||
C4(0, 4), C4(1, 4), C4(2, 4), C4(3, 4), C4(4, 4), C4(5, 4),
|
||||
C4(6, 4), C4(7, 4), C4(8, 4), C4(9, 4), C4(10, 4), C4(11, 4),
|
||||
C4(12, 4), C4(13, 4), C4(14, 4), C4(15, 4),
|
||||
};
|
||||
|
||||
const FbBits fbStipple2Bits[4] = {
|
||||
C2(0, 8), C2(1, 8), C2(2, 8), C2(3, 8),
|
||||
};
|
||||
|
||||
const FbBits fbStipple1Bits[2] = {
|
||||
C1(0, 16), C1(1, 16),
|
||||
};
|
||||
#endif
|
||||
#if FB_UNIT == 32
|
||||
#define fbStipple16Bits 0
|
||||
const FbBits fbStipple8Bits[256] = {
|
||||
C8(0, 4), C8(1, 4), C8(2, 4), C8(3, 4), C8(4, 4), C8(5, 4),
|
||||
C8(6, 4), C8(7, 4), C8(8, 4), C8(9, 4), C8(10, 4), C8(11, 4),
|
||||
C8(12, 4), C8(13, 4), C8(14, 4), C8(15, 4), C8(16, 4), C8(17, 4),
|
||||
C8(18, 4), C8(19, 4), C8(20, 4), C8(21, 4), C8(22, 4), C8(23, 4),
|
||||
C8(24, 4), C8(25, 4), C8(26, 4), C8(27, 4), C8(28, 4), C8(29, 4),
|
||||
C8(30, 4), C8(31, 4), C8(32, 4), C8(33, 4), C8(34, 4), C8(35, 4),
|
||||
C8(36, 4), C8(37, 4), C8(38, 4), C8(39, 4), C8(40, 4), C8(41, 4),
|
||||
C8(42, 4), C8(43, 4), C8(44, 4), C8(45, 4), C8(46, 4), C8(47, 4),
|
||||
C8(48, 4), C8(49, 4), C8(50, 4), C8(51, 4), C8(52, 4), C8(53, 4),
|
||||
C8(54, 4), C8(55, 4), C8(56, 4), C8(57, 4), C8(58, 4), C8(59, 4),
|
||||
C8(60, 4), C8(61, 4), C8(62, 4), C8(63, 4), C8(64, 4), C8(65, 4),
|
||||
C8(66, 4), C8(67, 4), C8(68, 4), C8(69, 4), C8(70, 4), C8(71, 4),
|
||||
C8(72, 4), C8(73, 4), C8(74, 4), C8(75, 4), C8(76, 4), C8(77, 4),
|
||||
C8(78, 4), C8(79, 4), C8(80, 4), C8(81, 4), C8(82, 4), C8(83, 4),
|
||||
C8(84, 4), C8(85, 4), C8(86, 4), C8(87, 4), C8(88, 4), C8(89, 4),
|
||||
C8(90, 4), C8(91, 4), C8(92, 4), C8(93, 4), C8(94, 4), C8(95, 4),
|
||||
C8(96, 4), C8(97, 4), C8(98, 4), C8(99, 4), C8(100, 4), C8(101, 4),
|
||||
C8(102, 4), C8(103, 4), C8(104, 4), C8(105, 4), C8(106, 4), C8(107, 4),
|
||||
C8(108, 4), C8(109, 4), C8(110, 4), C8(111, 4), C8(112, 4), C8(113, 4),
|
||||
C8(114, 4), C8(115, 4), C8(116, 4), C8(117, 4), C8(118, 4), C8(119, 4),
|
||||
C8(120, 4), C8(121, 4), C8(122, 4), C8(123, 4), C8(124, 4), C8(125, 4),
|
||||
C8(126, 4), C8(127, 4), C8(128, 4), C8(129, 4), C8(130, 4), C8(131, 4),
|
||||
C8(132, 4), C8(133, 4), C8(134, 4), C8(135, 4), C8(136, 4), C8(137, 4),
|
||||
C8(138, 4), C8(139, 4), C8(140, 4), C8(141, 4), C8(142, 4), C8(143, 4),
|
||||
C8(144, 4), C8(145, 4), C8(146, 4), C8(147, 4), C8(148, 4), C8(149, 4),
|
||||
C8(150, 4), C8(151, 4), C8(152, 4), C8(153, 4), C8(154, 4), C8(155, 4),
|
||||
C8(156, 4), C8(157, 4), C8(158, 4), C8(159, 4), C8(160, 4), C8(161, 4),
|
||||
C8(162, 4), C8(163, 4), C8(164, 4), C8(165, 4), C8(166, 4), C8(167, 4),
|
||||
C8(168, 4), C8(169, 4), C8(170, 4), C8(171, 4), C8(172, 4), C8(173, 4),
|
||||
C8(174, 4), C8(175, 4), C8(176, 4), C8(177, 4), C8(178, 4), C8(179, 4),
|
||||
C8(180, 4), C8(181, 4), C8(182, 4), C8(183, 4), C8(184, 4), C8(185, 4),
|
||||
C8(186, 4), C8(187, 4), C8(188, 4), C8(189, 4), C8(190, 4), C8(191, 4),
|
||||
C8(192, 4), C8(193, 4), C8(194, 4), C8(195, 4), C8(196, 4), C8(197, 4),
|
||||
C8(198, 4), C8(199, 4), C8(200, 4), C8(201, 4), C8(202, 4), C8(203, 4),
|
||||
C8(204, 4), C8(205, 4), C8(206, 4), C8(207, 4), C8(208, 4), C8(209, 4),
|
||||
C8(210, 4), C8(211, 4), C8(212, 4), C8(213, 4), C8(214, 4), C8(215, 4),
|
||||
C8(216, 4), C8(217, 4), C8(218, 4), C8(219, 4), C8(220, 4), C8(221, 4),
|
||||
C8(222, 4), C8(223, 4), C8(224, 4), C8(225, 4), C8(226, 4), C8(227, 4),
|
||||
C8(228, 4), C8(229, 4), C8(230, 4), C8(231, 4), C8(232, 4), C8(233, 4),
|
||||
C8(234, 4), C8(235, 4), C8(236, 4), C8(237, 4), C8(238, 4), C8(239, 4),
|
||||
C8(240, 4), C8(241, 4), C8(242, 4), C8(243, 4), C8(244, 4), C8(245, 4),
|
||||
C8(246, 4), C8(247, 4), C8(248, 4), C8(249, 4), C8(250, 4), C8(251, 4),
|
||||
C8(252, 4), C8(253, 4), C8(254, 4), C8(255, 4),
|
||||
};
|
||||
|
||||
const FbBits fbStipple4Bits[16] = {
|
||||
C4(0, 8), C4(1, 8), C4(2, 8), C4(3, 8), C4(4, 8), C4(5, 8),
|
||||
C4(6, 8), C4(7, 8), C4(8, 8), C4(9, 8), C4(10, 8), C4(11, 8),
|
||||
C4(12, 8), C4(13, 8), C4(14, 8), C4(15, 8),
|
||||
};
|
||||
|
||||
const FbBits fbStipple2Bits[4] = {
|
||||
C2(0, 16), C2(1, 16), C2(2, 16), C2(3, 16),
|
||||
};
|
||||
|
||||
const FbBits fbStipple1Bits[2] = {
|
||||
C1(0, 32), C1(1, 32),
|
||||
};
|
||||
#endif
|
||||
#if FB_UNIT == 64
|
||||
const FbBits fbStipple16Bits[256] = {
|
||||
C8(0, 4), C8(1, 4), C8(2, 4), C8(3, 4), C8(4, 4), C8(5, 4),
|
||||
C8(6, 4), C8(7, 4), C8(8, 4), C8(9, 4), C8(10, 4), C8(11, 4),
|
||||
C8(12, 4), C8(13, 4), C8(14, 4), C8(15, 4), C8(16, 4), C8(17, 4),
|
||||
C8(18, 4), C8(19, 4), C8(20, 4), C8(21, 4), C8(22, 4), C8(23, 4),
|
||||
C8(24, 4), C8(25, 4), C8(26, 4), C8(27, 4), C8(28, 4), C8(29, 4),
|
||||
C8(30, 4), C8(31, 4), C8(32, 4), C8(33, 4), C8(34, 4), C8(35, 4),
|
||||
C8(36, 4), C8(37, 4), C8(38, 4), C8(39, 4), C8(40, 4), C8(41, 4),
|
||||
C8(42, 4), C8(43, 4), C8(44, 4), C8(45, 4), C8(46, 4), C8(47, 4),
|
||||
C8(48, 4), C8(49, 4), C8(50, 4), C8(51, 4), C8(52, 4), C8(53, 4),
|
||||
C8(54, 4), C8(55, 4), C8(56, 4), C8(57, 4), C8(58, 4), C8(59, 4),
|
||||
C8(60, 4), C8(61, 4), C8(62, 4), C8(63, 4), C8(64, 4), C8(65, 4),
|
||||
C8(66, 4), C8(67, 4), C8(68, 4), C8(69, 4), C8(70, 4), C8(71, 4),
|
||||
C8(72, 4), C8(73, 4), C8(74, 4), C8(75, 4), C8(76, 4), C8(77, 4),
|
||||
C8(78, 4), C8(79, 4), C8(80, 4), C8(81, 4), C8(82, 4), C8(83, 4),
|
||||
C8(84, 4), C8(85, 4), C8(86, 4), C8(87, 4), C8(88, 4), C8(89, 4),
|
||||
C8(90, 4), C8(91, 4), C8(92, 4), C8(93, 4), C8(94, 4), C8(95, 4),
|
||||
C8(96, 4), C8(97, 4), C8(98, 4), C8(99, 4), C8(100, 4), C8(101, 4),
|
||||
C8(102, 4), C8(103, 4), C8(104, 4), C8(105, 4), C8(106, 4), C8(107, 4),
|
||||
C8(108, 4), C8(109, 4), C8(110, 4), C8(111, 4), C8(112, 4), C8(113, 4),
|
||||
C8(114, 4), C8(115, 4), C8(116, 4), C8(117, 4), C8(118, 4), C8(119, 4),
|
||||
C8(120, 4), C8(121, 4), C8(122, 4), C8(123, 4), C8(124, 4), C8(125, 4),
|
||||
C8(126, 4), C8(127, 4), C8(128, 4), C8(129, 4), C8(130, 4), C8(131, 4),
|
||||
C8(132, 4), C8(133, 4), C8(134, 4), C8(135, 4), C8(136, 4), C8(137, 4),
|
||||
C8(138, 4), C8(139, 4), C8(140, 4), C8(141, 4), C8(142, 4), C8(143, 4),
|
||||
C8(144, 4), C8(145, 4), C8(146, 4), C8(147, 4), C8(148, 4), C8(149, 4),
|
||||
C8(150, 4), C8(151, 4), C8(152, 4), C8(153, 4), C8(154, 4), C8(155, 4),
|
||||
C8(156, 4), C8(157, 4), C8(158, 4), C8(159, 4), C8(160, 4), C8(161, 4),
|
||||
C8(162, 4), C8(163, 4), C8(164, 4), C8(165, 4), C8(166, 4), C8(167, 4),
|
||||
C8(168, 4), C8(169, 4), C8(170, 4), C8(171, 4), C8(172, 4), C8(173, 4),
|
||||
C8(174, 4), C8(175, 4), C8(176, 4), C8(177, 4), C8(178, 4), C8(179, 4),
|
||||
C8(180, 4), C8(181, 4), C8(182, 4), C8(183, 4), C8(184, 4), C8(185, 4),
|
||||
C8(186, 4), C8(187, 4), C8(188, 4), C8(189, 4), C8(190, 4), C8(191, 4),
|
||||
C8(192, 4), C8(193, 4), C8(194, 4), C8(195, 4), C8(196, 4), C8(197, 4),
|
||||
C8(198, 4), C8(199, 4), C8(200, 4), C8(201, 4), C8(202, 4), C8(203, 4),
|
||||
C8(204, 4), C8(205, 4), C8(206, 4), C8(207, 4), C8(208, 4), C8(209, 4),
|
||||
C8(210, 4), C8(211, 4), C8(212, 4), C8(213, 4), C8(214, 4), C8(215, 4),
|
||||
C8(216, 4), C8(217, 4), C8(218, 4), C8(219, 4), C8(220, 4), C8(221, 4),
|
||||
C8(222, 4), C8(223, 4), C8(224, 4), C8(225, 4), C8(226, 4), C8(227, 4),
|
||||
C8(228, 4), C8(229, 4), C8(230, 4), C8(231, 4), C8(232, 4), C8(233, 4),
|
||||
C8(234, 4), C8(235, 4), C8(236, 4), C8(237, 4), C8(238, 4), C8(239, 4),
|
||||
C8(240, 4), C8(241, 4), C8(242, 4), C8(243, 4), C8(244, 4), C8(245, 4),
|
||||
C8(246, 4), C8(247, 4), C8(248, 4), C8(249, 4), C8(250, 4), C8(251, 4),
|
||||
C8(252, 4), C8(253, 4), C8(254, 4), C8(255, 4),
|
||||
};
|
||||
|
||||
const FbBits fbStipple8Bits[256] = {
|
||||
C8(0, 8), C8(1, 8), C8(2, 8), C8(3, 8), C8(4, 8), C8(5, 8),
|
||||
C8(6, 8), C8(7, 8), C8(8, 8), C8(9, 8), C8(10, 8), C8(11, 8),
|
||||
C8(12, 8), C8(13, 8), C8(14, 8), C8(15, 8), C8(16, 8), C8(17, 8),
|
||||
C8(18, 8), C8(19, 8), C8(20, 8), C8(21, 8), C8(22, 8), C8(23, 8),
|
||||
C8(24, 8), C8(25, 8), C8(26, 8), C8(27, 8), C8(28, 8), C8(29, 8),
|
||||
C8(30, 8), C8(31, 8), C8(32, 8), C8(33, 8), C8(34, 8), C8(35, 8),
|
||||
C8(36, 8), C8(37, 8), C8(38, 8), C8(39, 8), C8(40, 8), C8(41, 8),
|
||||
C8(42, 8), C8(43, 8), C8(44, 8), C8(45, 8), C8(46, 8), C8(47, 8),
|
||||
C8(48, 8), C8(49, 8), C8(50, 8), C8(51, 8), C8(52, 8), C8(53, 8),
|
||||
C8(54, 8), C8(55, 8), C8(56, 8), C8(57, 8), C8(58, 8), C8(59, 8),
|
||||
C8(60, 8), C8(61, 8), C8(62, 8), C8(63, 8), C8(64, 8), C8(65, 8),
|
||||
C8(66, 8), C8(67, 8), C8(68, 8), C8(69, 8), C8(70, 8), C8(71, 8),
|
||||
C8(72, 8), C8(73, 8), C8(74, 8), C8(75, 8), C8(76, 8), C8(77, 8),
|
||||
C8(78, 8), C8(79, 8), C8(80, 8), C8(81, 8), C8(82, 8), C8(83, 8),
|
||||
C8(84, 8), C8(85, 8), C8(86, 8), C8(87, 8), C8(88, 8), C8(89, 8),
|
||||
C8(90, 8), C8(91, 8), C8(92, 8), C8(93, 8), C8(94, 8), C8(95, 8),
|
||||
C8(96, 8), C8(97, 8), C8(98, 8), C8(99, 8), C8(100, 8), C8(101, 8),
|
||||
C8(102, 8), C8(103, 8), C8(104, 8), C8(105, 8), C8(106, 8), C8(107, 8),
|
||||
C8(108, 8), C8(109, 8), C8(110, 8), C8(111, 8), C8(112, 8), C8(113, 8),
|
||||
C8(114, 8), C8(115, 8), C8(116, 8), C8(117, 8), C8(118, 8), C8(119, 8),
|
||||
C8(120, 8), C8(121, 8), C8(122, 8), C8(123, 8), C8(124, 8), C8(125, 8),
|
||||
C8(126, 8), C8(127, 8), C8(128, 8), C8(129, 8), C8(130, 8), C8(131, 8),
|
||||
C8(132, 8), C8(133, 8), C8(134, 8), C8(135, 8), C8(136, 8), C8(137, 8),
|
||||
C8(138, 8), C8(139, 8), C8(140, 8), C8(141, 8), C8(142, 8), C8(143, 8),
|
||||
C8(144, 8), C8(145, 8), C8(146, 8), C8(147, 8), C8(148, 8), C8(149, 8),
|
||||
C8(150, 8), C8(151, 8), C8(152, 8), C8(153, 8), C8(154, 8), C8(155, 8),
|
||||
C8(156, 8), C8(157, 8), C8(158, 8), C8(159, 8), C8(160, 8), C8(161, 8),
|
||||
C8(162, 8), C8(163, 8), C8(164, 8), C8(165, 8), C8(166, 8), C8(167, 8),
|
||||
C8(168, 8), C8(169, 8), C8(170, 8), C8(171, 8), C8(172, 8), C8(173, 8),
|
||||
C8(174, 8), C8(175, 8), C8(176, 8), C8(177, 8), C8(178, 8), C8(179, 8),
|
||||
C8(180, 8), C8(181, 8), C8(182, 8), C8(183, 8), C8(184, 8), C8(185, 8),
|
||||
C8(186, 8), C8(187, 8), C8(188, 8), C8(189, 8), C8(190, 8), C8(191, 8),
|
||||
C8(192, 8), C8(193, 8), C8(194, 8), C8(195, 8), C8(196, 8), C8(197, 8),
|
||||
C8(198, 8), C8(199, 8), C8(200, 8), C8(201, 8), C8(202, 8), C8(203, 8),
|
||||
C8(204, 8), C8(205, 8), C8(206, 8), C8(207, 8), C8(208, 8), C8(209, 8),
|
||||
C8(210, 8), C8(211, 8), C8(212, 8), C8(213, 8), C8(214, 8), C8(215, 8),
|
||||
C8(216, 8), C8(217, 8), C8(218, 8), C8(219, 8), C8(220, 8), C8(221, 8),
|
||||
C8(222, 8), C8(223, 8), C8(224, 8), C8(225, 8), C8(226, 8), C8(227, 8),
|
||||
C8(228, 8), C8(229, 8), C8(230, 8), C8(231, 8), C8(232, 8), C8(233, 8),
|
||||
C8(234, 8), C8(235, 8), C8(236, 8), C8(237, 8), C8(238, 8), C8(239, 8),
|
||||
C8(240, 8), C8(241, 8), C8(242, 8), C8(243, 8), C8(244, 8), C8(245, 8),
|
||||
C8(246, 8), C8(247, 8), C8(248, 8), C8(249, 8), C8(250, 8), C8(251, 8),
|
||||
C8(252, 8), C8(253, 8), C8(254, 8), C8(255, 8),
|
||||
};
|
||||
|
||||
const FbBits fbStipple4Bits[16] = {
|
||||
C4(0, 16), C4(1, 16), C4(2, 16), C4(3, 16), C4(4, 16), C4(5, 16),
|
||||
C4(6, 16), C4(7, 16), C4(8, 16), C4(9, 16), C4(10, 16), C4(11, 16),
|
||||
C4(12, 16), C4(13, 16), C4(14, 16), C4(15, 16),
|
||||
};
|
||||
|
||||
const FbBits fbStipple2Bits[4] = {
|
||||
C2(0, 32), C2(1, 32), C2(2, 32), C2(3, 32),
|
||||
};
|
||||
|
||||
#define fbStipple1Bits 0
|
||||
#endif
|
||||
const FbBits *const fbStippleTable[] = {
|
||||
0,
|
||||
fbStipple1Bits,
|
||||
fbStipple2Bits,
|
||||
0,
|
||||
fbStipple4Bits,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
fbStipple8Bits,
|
||||
};
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
*
|
||||
* Copyright © 1998 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
|
||||
Bool
|
||||
fbCreateWindow(WindowPtr pWin)
|
||||
{
|
||||
pWin->devPrivates[fbWinPrivateIndex].ptr =
|
||||
(pointer) fbGetScreenPixmap(pWin->drawable.pScreen);
|
||||
if (pWin->drawable.bitsPerPixel == 32)
|
||||
pWin->drawable.bitsPerPixel =
|
||||
fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbDestroyWindow(WindowPtr pWin)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbMapWindow(WindowPtr pWindow)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbPositionWindow(WindowPtr pWin, int x, int y)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
fbUnmapWindow(WindowPtr pWindow)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fbCopyWindowProc(DrawablePtr pSrcDrawable,
|
||||
DrawablePtr pDstDrawable,
|
||||
GCPtr pGC,
|
||||
BoxPtr pbox,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy,
|
||||
Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
||||
{
|
||||
FbBits *src;
|
||||
|
||||
FbStride srcStride;
|
||||
|
||||
int srcBpp;
|
||||
|
||||
int srcXoff, srcYoff;
|
||||
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
|
||||
fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
while (nbox--) {
|
||||
fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride,
|
||||
srcStride,
|
||||
(pbox->x1 + dx + srcXoff) * srcBpp,
|
||||
dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
(pbox->x2 - pbox->x1) * dstBpp,
|
||||
(pbox->y2 - pbox->y1),
|
||||
GXcopy, FB_ALLONES, dstBpp, reverse, upsidedown);
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||
{
|
||||
RegionRec rgnDst;
|
||||
|
||||
int dx, dy;
|
||||
|
||||
PixmapPtr pPixmap = fbGetWindowPixmap(pWin);
|
||||
|
||||
DrawablePtr pDrawable = &pPixmap->drawable;
|
||||
|
||||
dx = ptOldOrg.x - pWin->drawable.x;
|
||||
dy = ptOldOrg.y - pWin->drawable.y;
|
||||
REGION_TRANSLATE(prgnSrc, -dx, -dy);
|
||||
|
||||
REGION_NULL(&rgnDst);
|
||||
|
||||
REGION_INTERSECT(&rgnDst, &pWin->borderClip,
|
||||
prgnSrc);
|
||||
|
||||
|
||||
fbCopyRegion(pDrawable, pDrawable,
|
||||
0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
|
||||
|
||||
REGION_UNINIT(&rgnDst);
|
||||
fbValidateDrawable(&pWin->drawable);
|
||||
}
|
||||
|
||||
Bool
|
||||
fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
||||
{
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
if (mask & CWBackPixmap) {
|
||||
if (pWin->backgroundState == BackgroundPixmap) {
|
||||
pPixmap = pWin->background.pixmap;
|
||||
if (pPixmap->drawable.bitsPerPixel != pWin->drawable.bitsPerPixel) {
|
||||
pPixmap = fb24_32ReformatTile(pPixmap,
|
||||
pWin->drawable.bitsPerPixel);
|
||||
if (pPixmap) {
|
||||
(*pWin->drawable.pScreen->DestroyPixmap) (pWin->background.
|
||||
pixmap);
|
||||
pWin->background.pixmap = pPixmap;
|
||||
}
|
||||
}
|
||||
if (FbEvenTile(pPixmap->drawable.width *
|
||||
pPixmap->drawable.bitsPerPixel))
|
||||
fbPadPixmap(pPixmap);
|
||||
}
|
||||
}
|
||||
if (mask & CWBorderPixmap) {
|
||||
if (pWin->borderIsPixel == FALSE) {
|
||||
pPixmap = pWin->border.pixmap;
|
||||
if (pPixmap->drawable.bitsPerPixel != pWin->drawable.bitsPerPixel) {
|
||||
pPixmap = fb24_32ReformatTile(pPixmap,
|
||||
pWin->drawable.bitsPerPixel);
|
||||
if (pPixmap) {
|
||||
(*pWin->drawable.pScreen->DestroyPixmap) (pWin->border.
|
||||
pixmap);
|
||||
pWin->border.pixmap = pPixmap;
|
||||
}
|
||||
}
|
||||
if (FbEvenTile(pPixmap->drawable.width *
|
||||
pPixmap->drawable.bitsPerPixel))
|
||||
fbPadPixmap(pPixmap);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fbFillRegionSolid(DrawablePtr pDrawable,
|
||||
RegionPtr pRegion, FbBits and, FbBits xor)
|
||||
{
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
int n = REGION_NUM_RECTS(pRegion);
|
||||
|
||||
BoxPtr pbox = REGION_RECTS(pRegion);
|
||||
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
|
||||
while (n--) {
|
||||
fbSolid(dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
dstBpp,
|
||||
(pbox->x2 - pbox->x1) * dstBpp,
|
||||
pbox->y2 - pbox->y1, and, xor);
|
||||
fbValidateDrawable(pDrawable);
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fbFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile)
|
||||
{
|
||||
FbBits *dst;
|
||||
|
||||
FbStride dstStride;
|
||||
|
||||
int dstBpp;
|
||||
|
||||
int dstXoff, dstYoff;
|
||||
|
||||
FbBits *tile;
|
||||
|
||||
FbStride tileStride;
|
||||
|
||||
int tileBpp;
|
||||
|
||||
int tileXoff _X_UNUSED, tileYoff _X_UNUSED; /* XXX assumed to be zero */
|
||||
|
||||
int tileWidth, tileHeight;
|
||||
|
||||
int n = REGION_NUM_RECTS(pRegion);
|
||||
|
||||
BoxPtr pbox = REGION_RECTS(pRegion);
|
||||
|
||||
int xRot = pDrawable->x;
|
||||
|
||||
int yRot = pDrawable->y;
|
||||
|
||||
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||
fbGetDrawable(&pTile->drawable, tile, tileStride, tileBpp, tileXoff,
|
||||
tileYoff);
|
||||
tileWidth = pTile->drawable.width;
|
||||
tileHeight = pTile->drawable.height;
|
||||
xRot += dstXoff;
|
||||
yRot += dstYoff;
|
||||
|
||||
while (n--) {
|
||||
fbTile(dst + (pbox->y1 + dstYoff) * dstStride,
|
||||
dstStride,
|
||||
(pbox->x1 + dstXoff) * dstBpp,
|
||||
(pbox->x2 - pbox->x1) * dstBpp,
|
||||
pbox->y2 - pbox->y1,
|
||||
tile,
|
||||
tileStride,
|
||||
tileWidth * dstBpp,
|
||||
tileHeight,
|
||||
GXcopy,
|
||||
FB_ALLONES, dstBpp, xRot * dstBpp, yRot - (pbox->y1 + dstYoff));
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fbPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
|
||||
{
|
||||
WindowPtr pBgWin;
|
||||
|
||||
switch (what) {
|
||||
case PW_BACKGROUND:
|
||||
switch (pWin->backgroundState) {
|
||||
case None:
|
||||
break;
|
||||
case ParentRelative:
|
||||
do {
|
||||
pWin = pWin->parent;
|
||||
} while (pWin->backgroundState == ParentRelative);
|
||||
(*pWin->drawable.pScreen->PaintWindowBackground) (pWin, pRegion,
|
||||
what);
|
||||
break;
|
||||
case BackgroundPixmap:
|
||||
fbFillRegionTiled(&pWin->drawable,
|
||||
pRegion, pWin->background.pixmap);
|
||||
break;
|
||||
case BackgroundPixel:
|
||||
fbFillRegionSolid(&pWin->drawable,
|
||||
pRegion,
|
||||
0,
|
||||
fbReplicatePixel(pWin->background.pixel,
|
||||
pWin->drawable.bitsPerPixel));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PW_BORDER:
|
||||
if (pWin->borderIsPixel) {
|
||||
fbFillRegionSolid(&pWin->drawable,
|
||||
pRegion,
|
||||
0,
|
||||
fbReplicatePixel(pWin->border.pixel,
|
||||
pWin->drawable.bitsPerPixel));
|
||||
}
|
||||
else {
|
||||
for (pBgWin = pWin;
|
||||
pBgWin->backgroundState == ParentRelative;
|
||||
pBgWin = pBgWin->parent);
|
||||
|
||||
fbFillRegionTiled(&pBgWin->drawable, pRegion, pWin->border.pixmap);
|
||||
}
|
||||
break;
|
||||
}
|
||||
fbValidateDrawable(&pWin->drawable);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
AM_CFLAGS = $(DIX_CFLAGS)
|
||||
|
||||
EXTRA_DIST = do-not-use-config.h dix-config.h \
|
||||
closestr.h closure.h colormap.h colormapst.h cursor.h cursorstr.h \
|
||||
dix-config.h dix-config.h.in dixevents.h dixfont.h dixfontstr.h dixgrabs.h \
|
||||
dix.h dixstruct.h do-not-use-config.h do-not-use-config.h.in exevents.h \
|
||||
extension.h extinit.h extnsionst.h gc.h gcstruct.h globals.h input.h \
|
||||
inputstr.h kdrive-config.h kdrive-config.h.in Makefile Makefile.am \
|
||||
Makefile.in misc.h misc.h.orig miscstruct.h opaque.h os.h pixmap.h \
|
||||
pixmapstr.h property.h propertyst.h region.h regionstr.h resource.h \
|
||||
screenint.h scrnintstr.h selection.h servermd.h site.h stamp-h1 stamp-h2 \
|
||||
stamp-h3 swaprep.h swapreq.h validate.h window.h windowstr.h
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue