diff options
317 files changed, 13196 insertions, 3343 deletions
diff --git a/LGPL_EXCEPTION.txt b/LGPL_EXCEPTION.txt new file mode 100644 index 00000000..7e2e30ff --- /dev/null +++ b/LGPL_EXCEPTION.txt @@ -0,0 +1,22 @@ +Digia Qt LGPL Exception version 1.1 + +As an additional permission to the GNU Lesser General Public License version +2.1, the object code form of a "work that uses the Library" may incorporate +material from a header file that is part of the Library. You may distribute +such object code under terms of your choice, provided that: + (i) the header files of the Library have not been modified; and + (ii) the incorporated material is limited to numerical parameters, data + structure layouts, accessors, macros, inline functions and + templates; and + (iii) you comply with the terms of Section 6 of the GNU Lesser General + Public License version 2.1. + +Moreover, you may apply this exception to a modified version of the Library, +provided that such modification does not involve copying material from the +Library into the modified Library's header files unless such material is +limited to (i) numerical parameters; (ii) data structure layouts; +(iii) accessors; and (iv) small macros, templates and inline functions of +five lines or less in length. + +Furthermore, you are not required to apply this additional permission to a +modified version of the Library. diff --git a/LICENSE.FDL b/LICENSE.FDL new file mode 100644 index 00000000..938bb8da --- /dev/null +++ b/LICENSE.FDL @@ -0,0 +1,450 @@ + GNU Free Documentation License + Version 1.3, 3 November 2008 + + + Copyright (C) 2000, 2001, 2002, 2007, 2008 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. + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The "Document", below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "you". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The "publisher" means any person or entity that distributes copies of +the Document to the public. + +A section "Entitled XYZ" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "Acknowledgements", +"Dedications", "Endorsements", or "History".) To "Preserve the Title" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no +other conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to +give them a chance to provide you with an updated version of the +Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other +documents released under this License, and replace the individual +copies of this License in the various documents with a single copy +that is included in the collection, provided that you follow the rules +of this License for verbatim copying of each of the documents in all +other respects. + +You may extract a single document from such a collection, and +distribute it individually under this License, provided you insert a +copy of this License into the extracted document, and follow this +License in all other respects regarding verbatim copying of that +document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +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, receipt of a copy of some or all of the same material does +not give you any rights to use it. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions of the +GNU Free Documentation 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. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +11. RELICENSING + +"Massive Multiauthor Collaboration Site" (or "MMC Site") means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +"Massive Multiauthor Collaboration" (or "MMC") contained in the site +means any set of copyrightable works thus published on the MMC site. + +"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +"Incorporate" means to publish or republish a Document, in whole or in +part, as part of another Document. + +An MMC is "eligible for relicensing" if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole or +in part into the MMC, (1) had no cover texts or invariant sections, and +(2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/LICENSE.GPL b/LICENSE.GPL new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/LICENSE.GPL @@ -0,0 +1,674 @@ + 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>. diff --git a/LICENSE.LGPL b/LICENSE.LGPL new file mode 100644 index 00000000..3788d79e --- /dev/null +++ b/LICENSE.LGPL @@ -0,0 +1,514 @@ + GNU LESSER GENERAL PUBLIC LICENSE + + The Qt Toolkit is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). + Contact: http://www.qt-project.org/legal + + You may use, distribute and copy the Qt GUI Toolkit under the terms of + GNU Lesser General Public License version 2.1, which is displayed below. + +------------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey 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 library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/config.tests/drm_egl_server/drm_egl_server.pro b/config.tests/drm_egl_server/drm_egl_server.pro new file mode 100644 index 00000000..328354eb --- /dev/null +++ b/config.tests/drm_egl_server/drm_egl_server.pro @@ -0,0 +1,14 @@ +TARGET = drm_egl_server +QT = core + +!contains(QT_CONFIG, opengl): error("drm_egl_server support requires Qt configured with OpenGL") + +!contains(QT_CONFIG, no-pkg-config) { + CONFIG += link_pkgconfig + PKGCONFIG += egl +} else { + LIBS += -legl +} + +# Input +SOURCES += main.cpp diff --git a/config.tests/drm_egl_server/main.cpp b/config.tests/drm_egl_server/main.cpp new file mode 100644 index 00000000..7ac62bd6 --- /dev/null +++ b/config.tests/drm_egl_server/main.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +int main() +{ +#ifdef EGL_MESA_drm_image + return 0; +#else +#error Requires EGL_MESA_drm_image to be defined + return 1; +#endif +} diff --git a/config.tests/egl/egl.pro b/config.tests/egl/egl.pro index e96672e5..402477db 100644 --- a/config.tests/egl/egl.pro +++ b/config.tests/egl/egl.pro @@ -1,7 +1,8 @@ TARGET = egl QT = core -!contains(QT_CONFIG, opengles2):error("wayland_egl support currently requires Qt configured with OpenGL ES2") +!contains(QT_CONFIG, opengl): error("egl support requires Qt configured with OpenGL") +!contains(QT_CONFIG, egl): error("egl support requires Qt configured with EGL") !contains(QT_CONFIG, no-pkg-config) { CONFIG += link_pkgconfig diff --git a/config.tests/wayland_egl/wayland_egl.pro b/config.tests/wayland_egl/wayland_egl.pro index 0db9b04f..42d6b131 100644 --- a/config.tests/wayland_egl/wayland_egl.pro +++ b/config.tests/wayland_egl/wayland_egl.pro @@ -1,7 +1,8 @@ TARGET = wayland_egl QT = core -!contains(QT_CONFIG, opengles2):error("wayland_egl support currently requires Qt configured with OpenGL ES2") +!contains(QT_CONFIG, opengl): error("wayland_egl support requires Qt configured with OpenGL") +!contains(QT_CONFIG, egl): error("wayland_egl support requires Qt configured with EGL") !contains(QT_CONFIG, no-pkg-config) { CONFIG += link_pkgconfig diff --git a/config.tests/xkbcommon/main.cpp b/config.tests/xkbcommon/main.cpp index 926a3a1a..801394c8 100644 --- a/config.tests/xkbcommon/main.cpp +++ b/config.tests/xkbcommon/main.cpp @@ -39,8 +39,7 @@ ****************************************************************************/ #include <xkbcommon/xkbcommon.h> -#include <X11/keysym.h> - +#include <xkbcommon/xkbcommon-keysyms.h> #include <string.h> int main() diff --git a/examples/examples.pro b/examples/examples.pro index 35459b0a..2d4cd1bb 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -12,4 +12,6 @@ contains(CONFIG, wayland-compositor) { qtHaveModule(quick) { SUBDIRS += qml-compositor } + + SUBDIRS += server-buffer } diff --git a/examples/qml-compositor/ContrastEffect.qml b/examples/qml-compositor/ContrastEffect.qml index 5159950d..c284b290 100644 --- a/examples/qml-compositor/ContrastEffect.qml +++ b/examples/qml-compositor/ContrastEffect.qml @@ -75,15 +75,15 @@ ShaderEffect { vertexShader: source && source.isYInverted ? vShaderInvertedY : vShader fragmentShader: " - uniform sampler2D source; - uniform float qt_Opacity; - uniform vec4 color; - uniform float blend; + uniform lowp sampler2D source; + uniform highp float qt_Opacity; + uniform highp vec4 color; + uniform highp float blend; varying highp vec2 qt_TexCoord0; void main() { - vec4 sourceColor = texture2D(source, qt_TexCoord0); - vec3 delta = sourceColor.rgb - vec3(0.5); - vec3 lowerContrast = vec3(0.5) + 0.4 * delta; + highp vec4 sourceColor = texture2D(source, qt_TexCoord0); + highp vec3 delta = sourceColor.rgb - vec3(0.5); + highp vec3 lowerContrast = vec3(0.5) + 0.4 * delta; gl_FragColor = qt_Opacity * mix(sourceColor, color * sourceColor.a * dot(lowerContrast, vec3(11, 16, 5) * (1. / 32.)), blend); } " diff --git a/examples/qml-compositor/main.cpp b/examples/qml-compositor/main.cpp index d481a252..88bab787 100644 --- a/examples/qml-compositor/main.cpp +++ b/examples/qml-compositor/main.cpp @@ -59,10 +59,9 @@ class QmlCompositor : public QQuickView, public QWaylandCompositor public: QmlCompositor() - : QWaylandCompositor(this) + : QWaylandCompositor(this, 0, DefaultExtensions | SubSurfaceExtension) , m_fullscreenSurface(0) { - enableSubSurfaceExtension(); setSource(QUrl("main.qml")); setResizeMode(QQuickView::SizeRootObjectToView); setColor(Qt::black); diff --git a/examples/qwidget-compositor/main.cpp b/examples/qwidget-compositor/main.cpp index 0c115166..2c58fe98 100644 --- a/examples/qwidget-compositor/main.cpp +++ b/examples/qwidget-compositor/main.cpp @@ -69,7 +69,7 @@ class QWidgetCompositor : public QWidget, public WaylandCompositor Q_OBJECT public: QWidgetCompositor() - : QWaylandCompositor(windowHandle()) + : QWaylandCompositor(windowHandle(), 0, DefaultExtensions | SubSurfaceExtension) #ifdef QT_COMPOSITOR_WAYLAND_GL , m_surfaceCompositorFbo(0) , m_textureBlitter(0) @@ -79,7 +79,6 @@ public: , m_dragSourceSurface(0) , m_cursorSurface(0) { - enableSubSurfaceExtension(); setMouseTracking(true); setRetainedSelectionEnabled(true); m_background = QImage(QLatin1String(":/background.jpg")); @@ -148,7 +147,7 @@ protected: if (surface->type() == QWaylandSurface::Shm) { texture = m_textureCache->bindTexture(context()->contextHandle(), surface->image()); } else { - texture = surface->texture(QOpenGLContext::currentContext()); + texture = surface->texture(); } functions->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, @@ -174,7 +173,7 @@ protected: if (size.isValid()) { GLuint texture = 0; if (subSurface->type() == QWaylandSurface::Texture) { - texture = subSurface->texture(QOpenGLContext::currentContext()); + texture = subSurface->texture(); } else if (surface->type() == QWaylandSurface::Shm ) { texture = m_textureCache->bindTexture(context()->contextHandle(), surface->image()); } diff --git a/examples/qwindow-compositor/main.cpp b/examples/qwindow-compositor/main.cpp index bcb66a92..e82ec6eb 100644 --- a/examples/qwindow-compositor/main.cpp +++ b/examples/qwindow-compositor/main.cpp @@ -58,6 +58,7 @@ int main(int argc, char *argv[]) QSurfaceFormat format; format.setDepthBufferSize(16); + format.setStencilBufferSize(8); QRect geom = screenGeometry; if (QCoreApplication::arguments().contains(QLatin1String("-nofullscreen"))) diff --git a/examples/qwindow-compositor/qwindowcompositor.cpp b/examples/qwindow-compositor/qwindowcompositor.cpp index 30b4ceb9..8e71ef06 100644 --- a/examples/qwindow-compositor/qwindowcompositor.cpp +++ b/examples/qwindow-compositor/qwindowcompositor.cpp @@ -54,7 +54,7 @@ #include <QtCompositor/qwaylandinput.h> QWindowCompositor::QWindowCompositor(QOpenGLWindow *window) - : QWaylandCompositor(window) + : QWaylandCompositor(window, 0, DefaultExtensions | SubSurfaceExtension) , m_window(window) , m_textureBlitter(0) , m_renderScheduler(this) @@ -65,7 +65,6 @@ QWindowCompositor::QWindowCompositor(QOpenGLWindow *window) , m_cursorHotspotY(0) , m_modifiers(Qt::NoModifier) { - enableSubSurfaceExtension(); m_window->makeCurrent(); m_textureCache = new QOpenGLTextureCache(m_window->context()); @@ -248,7 +247,7 @@ GLuint QWindowCompositor::composeSurface(QWaylandSurface *surface) if (surface->type() == QWaylandSurface::Shm) { texture = m_textureCache->bindTexture(QOpenGLContext::currentContext(),surface->image()); } else if (surface->type() == QWaylandSurface::Texture) { - texture = surface->texture(QOpenGLContext::currentContext()); + texture = surface->texture(); } functions->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, @@ -273,7 +272,7 @@ void QWindowCompositor::paintChildren(QWaylandSurface *surface, QWaylandSurface if (subSurface->size().isValid()) { GLuint texture = 0; if (subSurface->type() == QWaylandSurface::Texture) { - texture = subSurface->texture(QOpenGLContext::currentContext()); + texture = subSurface->texture(); } else if (surface->type() == QWaylandSurface::Shm ) { texture = m_textureCache->bindTexture(QOpenGLContext::currentContext(),surface->image()); } diff --git a/examples/server-buffer/README b/examples/server-buffer/README new file mode 100644 index 00000000..762db423 --- /dev/null +++ b/examples/server-buffer/README @@ -0,0 +1,17 @@ +This is the example to demonstrate the server buffer interfaces + +Compile up both compositor and client. + +If you have the drm-egl-server buffer integration (and your running Mesa) +then start the compositor with: + +# QT_WAYLAND_SERVER_BUFFER_INTEGRATION=drm-egl-server ./compositor + +The compositor is using the hardware integration extension to boradcast +to all clients to use the same server buffer integration, so all you need +to do is to start the client with + +# ./client -platform wayland + +You should then see a red box in top left corner, with a black cross and +a horisontal line in the top half (centered). diff --git a/examples/server-buffer/client/client.pro b/examples/server-buffer/client/client.pro new file mode 100644 index 00000000..1296ed18 --- /dev/null +++ b/examples/server-buffer/client/client.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +TARGET = client +INCLUDEPATH += . + +QT += waylandclient-private + +CONFIG += wayland-scanner +WAYLANDCLIENTSOURCES += ../share-buffer.xml + +SOURCES += \ + main.cpp \ + serverbufferrenderer.cpp + +HEADERS += \ + serverbufferrenderer.h diff --git a/examples/server-buffer/client/main.cpp b/examples/server-buffer/client/main.cpp new file mode 100644 index 00000000..b5ce8aec --- /dev/null +++ b/examples/server-buffer/client/main.cpp @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "serverbufferrenderer.h" + +#include <QtGui/QWindow> +#include <QtGui/QGuiApplication> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformnativeinterface.h> +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLVertexArrayObject> +#include <QtGui/QOpenGLShaderProgram> +#include <QtGui/QOpenGLTexture> +#include <QtCore/QTimer> + +#include "qwayland-share-buffer.h" +#include <QtWaylandClient/private/qwayland-wayland.h> +#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> +#include <QtWaylandClient/private/qwaylanddisplay_p.h> +#include <QtWaylandClient/private/qwaylandintegration_p.h> + + +class Window + : public QWindow + , public QtWayland::wl_registry + , public QtWayland::qt_share_buffer +{ + Q_OBJECT +public: + Window(QWindow *parent = 0) + : QWindow(parent) + , m_context(0) + { + setSurfaceType(QSurface::OpenGLSurface); + QSurfaceFormat sformat = format(); + sformat.setAlphaBufferSize(8); + sformat.setRedBufferSize(8); + sformat.setGreenBufferSize(8); + sformat.setBlueBufferSize(8); + setFormat(sformat); + create(); + + if (!QGuiApplication::platformNativeInterface() || !QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display")) { + qDebug() << "This application requires a wayland plugin"; + QCoreApplication::quit(); + return; + } + + QWaylandIntegration *wayland_integration = static_cast<QWaylandIntegration *>(QGuiApplicationPrivate::platformIntegration()); + + m_server_buffer_integration = wayland_integration->serverBufferIntegration(); + if (!m_server_buffer_integration) { + qDebug() << "This application requires a working serverBufferIntegration"; + QCoreApplication::quit(); + return; + } + + + QWaylandDisplay *wayland_display = wayland_integration->display(); + struct ::wl_registry *registry = wl_display_get_registry(wayland_display->wl_display()); + wl_proxy_set_queue(reinterpret_cast<struct wl_proxy *>(registry), wayland_display->wl_event_queue()); + QtWayland::wl_registry::init(registry); + } + +public slots: + void render() + { + if (m_server_buffer_list.isEmpty()) + return; + + if (!m_context) { + m_context = new QOpenGLContext(this); + m_context->setFormat(format()); + m_context->create(); + } + + m_context->makeCurrent(this); + + glBindFramebuffer(GL_FRAMEBUFFER, m_context->defaultFramebufferObject()); + + glViewport(0, 0, width() * devicePixelRatio(), height() * devicePixelRatio()); + glClearColor(0.f, 0.f, 0.0f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + + qreal x = 0; + for (int i = 0; i < m_server_buffer_list.size(); i++) { + ServerBufferRenderer *renderer = static_cast<ServerBufferRenderer *>(m_server_buffer_list[i]->userData()); + if (!renderer) { + renderer = new ServerBufferRenderer(m_server_buffer_list.at(i)); + } + + const QSizeF buffer_size = m_server_buffer_list.at(i)->size(); + qreal scale_x = buffer_size.width() / width(); + qreal scale_y = buffer_size.height() / height(); + qreal translate_left = (((buffer_size.width() / 2) / width()) * 2) - 1; + qreal translate_top = -(((buffer_size.height() / 2) / height()) * 2) + 1; + qreal translate_x = translate_left + ((x / width())*2); + + QMatrix4x4 transform; + transform.translate(translate_x, translate_top); + transform.scale(scale_x, scale_y); + renderer->render(transform); + + x += buffer_size.width(); + } + + m_context->swapBuffers(this); + } + +protected: + void registry_global(uint32_t name, const QString &interface, uint32_t version) Q_DECL_OVERRIDE + { + Q_UNUSED(version); + if (interface == QStringLiteral("qt_share_buffer")) { + QtWayland::qt_share_buffer::init(QtWayland::wl_registry::object(), name); + } + } + + void share_buffer_cross_buffer(struct ::qt_server_buffer *buffer) Q_DECL_OVERRIDE + { + QWaylandServerBuffer *serverBuffer = m_server_buffer_integration->serverBuffer(buffer); + if (m_server_buffer_list.isEmpty()) { + setWidth(serverBuffer->size().width()); + setHeight(serverBuffer->size().height()); + } else { + setWidth(width() + serverBuffer->size().width()); + setHeight(std::max(serverBuffer->size().height(), height())); + } + m_server_buffer_list.append(serverBuffer); + render(); + } + +private: + QWaylandServerBufferIntegration *m_server_buffer_integration; + QList<QWaylandServerBuffer *>m_server_buffer_list; + GLuint m_server_buffer_texture; + QOpenGLContext *m_context; + QOpenGLVertexArrayObject *m_vao; + GLuint m_vertexbuffer; + GLuint m_texture_coords; + QOpenGLShaderProgram *m_shader_program; + QOpenGLTexture *m_image_texture; +}; + +int main (int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + Window window; + window.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/examples/server-buffer/client/serverbufferrenderer.cpp b/examples/server-buffer/client/serverbufferrenderer.cpp new file mode 100644 index 00000000..b9aa7a01 --- /dev/null +++ b/examples/server-buffer/client/serverbufferrenderer.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "serverbufferrenderer.h" + +#include <QtGui/QOpenGLVertexArrayObject> +#include <QtGui/QOpenGLShaderProgram> +static const GLfloat uv_coords[] = { + 1,1, + 1,0, + 0,1, + 0,0, +}; + +static const GLfloat vertex_coords[] = { + -1,-1,0, + -1,1,0, + 1,-1,0, + 1,1,0, +}; + +static const char vertex_shader[] = + "attribute vec3 vertexCoord;" + "attribute vec2 textureCoord;" + "uniform mat4 transform;" + "varying mediump vec2 uv;" + "void main() {" + " uv = textureCoord;" + " gl_Position = transform * vec4(vertexCoord,1);" + "}"; + +static const char fragment_shader[] = + "varying mediump vec2 uv;" + "uniform sampler2D textureSampler;" + "void main() {" + " gl_FragColor = texture2D(textureSampler, uv);" + "}"; + +ServerBufferRenderer::ServerBufferRenderer(QWaylandServerBuffer *serverBuffer) + : m_server_buffer(serverBuffer) + , m_texture(0) + , m_vao(new QOpenGLVertexArrayObject()) + , m_program(new QOpenGLShaderProgram()) + , m_vertexbuffer(0) + , m_texture_coords(0) + +{ + Q_ASSERT(serverBuffer); + if (serverBuffer->userData()) { + qWarning("ServerBufferRenderer: Will over QWaylandServerBuffers %p userdata %p", serverBuffer, serverBuffer->userData()); + } + serverBuffer->setUserData(this); + m_vao->create(); + m_vao->bind(); + + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader); + if (!m_program->link()) { + qDebug() << m_program->log(); + } + + glGenTextures(1,&m_texture); + glBindTexture(GL_TEXTURE_2D, m_texture); + serverBuffer->bindTextureToBuffer(); + + glGenBuffers(1, &m_vertexbuffer); + glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_coords), vertex_coords, GL_STATIC_DRAW); + m_program->setAttributeBuffer("vertexCoord", GL_FLOAT, 0, 3, 0); + + glGenBuffers(1, &m_texture_coords); + glBindBuffer(GL_ARRAY_BUFFER, m_texture_coords); + glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); + m_program->setAttributeBuffer("textureCoord", GL_FLOAT, 0, 2, 0); + + m_program->enableAttributeArray("vertexCoord"); + m_program->enableAttributeArray("textureCoord"); + + m_vao->release(); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void ServerBufferRenderer::render(const QMatrix4x4 &transform) +{ + m_vao->bind(); + + m_program->bind(); + m_program->setUniformValue("transform", transform); + + glBindTexture(GL_TEXTURE_2D, m_texture); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + m_vao->release(); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} diff --git a/examples/server-buffer/client/serverbufferrenderer.h b/examples/server-buffer/client/serverbufferrenderer.h new file mode 100644 index 00000000..58f0c704 --- /dev/null +++ b/examples/server-buffer/client/serverbufferrenderer.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SERVERBUFFERRENDERER_H +#define SERVERBUFFERRENDERER_H + +#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> + +#include <QMatrix4x4> +QT_BEGIN_NAMESPACE + +class QOpenGLVertexArrayObject; +class QOpenGLShaderProgram; + +class ServerBufferRenderer +{ +public: + ServerBufferRenderer(QWaylandServerBuffer *serverBuffer); + + void render(const QMatrix4x4 &transform); +private: + QWaylandServerBuffer *m_server_buffer; + GLuint m_texture; + + QOpenGLVertexArrayObject *m_vao; + QOpenGLShaderProgram *m_program; + + GLuint m_vertexbuffer; + GLuint m_texture_coords; +}; + +QT_END_NAMESPACE +#endif diff --git a/examples/server-buffer/compositor/compositor.pro b/examples/server-buffer/compositor/compositor.pro new file mode 100644 index 00000000..8d7f4882 --- /dev/null +++ b/examples/server-buffer/compositor/compositor.pro @@ -0,0 +1,20 @@ +QT += core-private gui-private quick-private compositor-private + +LIBS += -lwayland-server + +SOURCES += \ + main.cpp \ + serverbufferitem.cpp +HEADERS += \ + serverbufferitem.h \ + +OTHER_FILES = \ + qml/main.qml \ + images/background.jpg \ + +RESOURCES += compositor.qrc + +CONFIG +=wayland-scanner +WAYLANDSERVERSOURCES += ../share-buffer.xml + +DEFINES += QT_COMPOSITOR_QUICK diff --git a/examples/server-buffer/compositor/compositor.qrc b/examples/server-buffer/compositor/compositor.qrc new file mode 100644 index 00000000..dbbbfb1c --- /dev/null +++ b/examples/server-buffer/compositor/compositor.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>images/background.jpg</file> + <file>qml/main.qml</file> + <file>qml/ServerBufferContainer.qml</file> + </qresource> +</RCC> diff --git a/examples/server-buffer/compositor/images/background.jpg b/examples/server-buffer/compositor/images/background.jpg Binary files differnew file mode 100644 index 00000000..445567fb --- /dev/null +++ b/examples/server-buffer/compositor/images/background.jpg diff --git a/examples/server-buffer/compositor/main.cpp b/examples/server-buffer/compositor/main.cpp new file mode 100644 index 00000000..c266b224 --- /dev/null +++ b/examples/server-buffer/compositor/main.cpp @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandcompositor.h" +#include "qwaylandsurface.h" +#include "qwaylandsurfaceitem.h" + +#include <QGuiApplication> +#include <QTimer> +#include <QPainter> +#include <QMouseEvent> +#include <QOpenGLContext> + +#include <QQmlContext> + +#include <QQuickItem> +#include <QQuickView> + +#include "qwayland-server-share-buffer.h" +#include <QtCompositor/private/qwlcompositor_p.h> +#include <QtCompositor/qwaylandserverbufferintegration.h> + +#include "serverbufferitem.h" + +#include <QtGui/private/qdistancefield_p.h> + +class QmlCompositor + : public QQuickView + , public QWaylandCompositor + , public QtWaylandServer::qt_share_buffer +{ + Q_OBJECT + +public: + QmlCompositor() + : QWaylandCompositor(this, 0, DefaultExtensions | SubSurfaceExtension) + , QtWaylandServer::qt_share_buffer(QWaylandCompositor::handle()->wl_display()) + , m_server_buffer_32_bit(0) + , m_server_buffer_item_32_bit(0) + , m_server_buffer_8_bit(0) + , m_server_buffer_item_8_bit(0) + { + setSource(QUrl("qrc:/qml/main.qml")); + setResizeMode(QQuickView::SizeRootObjectToView); + setColor(Qt::black); + create(); + grabWindow(); + + connect(this, SIGNAL(frameSwapped()), this, SLOT(frameSwappedSlot())); + + connect(this, SIGNAL(sceneGraphInitialized()), this, SLOT(initiateServerBuffer()),Qt::DirectConnection); + connect(this, SIGNAL(serverBuffersCreated()), this, SLOT(createServerBufferItems())); + } + +signals: + void windowAdded(QVariant window); + void windowDestroyed(QVariant window); + void windowResized(QVariant window); + void serverBufferItemCreated(QVariant); + void serverBuffersCreated(); + +public slots: + void destroyWindow(QVariant window) + { + qvariant_cast<QObject *>(window)->deleteLater(); + } + + void destroyClientForWindow(QVariant window) + { + QWaylandSurface *surface = qobject_cast<QWaylandSurfaceItem *>(qvariant_cast<QObject *>(window))->surface(); + destroyClientForSurface(surface); + } + +private slots: + void surfaceMapped() { + QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); + + QWaylandSurfaceItem *item = surface->surfaceItem(); + if (!item) { + item = new QWaylandSurfaceItem(surface, rootObject()); + item->setUseTextureAlpha(true); + } + + item->setTouchEventsEnabled(true); + emit windowAdded(QVariant::fromValue(static_cast<QQuickItem *>(item))); + } + + void surfaceUnmapped() { + QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); + QQuickItem *item = surface->surfaceItem(); + emit windowDestroyed(QVariant::fromValue(item)); + } + + void surfaceDestroyed(QObject *object) { + QWaylandSurface *surface = static_cast<QWaylandSurface *>(object); + QQuickItem *item = surface->surfaceItem(); + emit windowDestroyed(QVariant::fromValue(item)); + } + + void frameSwappedSlot() { + frameFinished(); + } + + void initiateServerBuffer() + { + if (!QWaylandCompositor::handle()->serverBufferIntegration()) + return; + + openglContext()->makeCurrent(this); + + QWaylandServerBufferIntegration *sbi = QWaylandCompositor::handle()->serverBufferIntegration(); + if (!sbi) { + qWarning("Could not find a Server Buffer Integration"); + return; + } + if (sbi->supportsFormat(QWaylandServerBuffer::RGBA32)) { + QImage image(100,100,QImage::Format_ARGB32_Premultiplied); + image.fill(QColor(0x55,0x0,0x55,0x01)); + { + QPainter p(&image); + QPen pen = p.pen(); + pen.setWidthF(3); + pen.setColor(Qt::red); + p.setPen(pen); + p.drawLine(0,0,100,100); + pen.setColor(Qt::green); + p.setPen(pen); + p.drawLine(100,0,0,100); + pen.setColor(Qt::blue); + p.setPen(pen); + p.drawLine(25,15,75,15); + } + image = image.convertToFormat(QImage::Format_RGBA8888); + + m_server_buffer_32_bit = sbi->createServerBuffer(image.size(),QWaylandServerBuffer::RGBA32); + + GLuint texture_32_bit; + glGenTextures(1, &texture_32_bit); + glBindTexture(GL_TEXTURE_2D, texture_32_bit); + m_server_buffer_32_bit->bindTextureToBuffer(); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width(), image.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); + glBindTexture(GL_TEXTURE_2D, 0); + + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &texture_32_bit); + + } + + if (sbi->supportsFormat(QWaylandServerBuffer::A8)) { + QRawFont defaultRaw = QRawFont::fromFont(QFont(), QFontDatabase::Latin); + QVector<quint32> index = defaultRaw.glyphIndexesForString(QStringLiteral("A")); + QDistanceField distanceField(defaultRaw, index.front(), true); + QImage img = distanceField.toImage(QImage::Format_Indexed8); + + m_server_buffer_8_bit = sbi->createServerBuffer(img.size(), QWaylandServerBuffer::A8); + GLuint texture_8_bit; + glGenTextures(1, &texture_8_bit); + glBindTexture(GL_TEXTURE_2D, texture_8_bit); + m_server_buffer_8_bit->bindTextureToBuffer(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.width(), img.height(), GL_ALPHA, GL_UNSIGNED_BYTE, img.constBits()); + } + emit serverBuffersCreated(); + } + + void createServerBufferItems() + { + if (m_server_buffer_32_bit) { + m_server_buffer_item_32_bit = new ServerBufferItem(m_server_buffer_32_bit); + m_server_buffer_item_32_bit->setUseTextureAlpha(true); + emit serverBufferItemCreated(QVariant::fromValue(m_server_buffer_item_32_bit)); + } + if (m_server_buffer_8_bit) { + m_server_buffer_item_8_bit = new ServerBufferItem(m_server_buffer_8_bit); + m_server_buffer_item_8_bit->setUseTextureAlpha(true); + emit serverBufferItemCreated(QVariant::fromValue(m_server_buffer_item_8_bit)); + } + } +protected: + void resizeEvent(QResizeEvent *event) + { + QQuickView::resizeEvent(event); + QWaylandCompositor::setOutputGeometry(QRect(0, 0, width(), height())); + } + + void surfaceCreated(QWaylandSurface *surface) { + connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *))); + connect(surface, SIGNAL(mapped()), this, SLOT(surfaceMapped())); + connect(surface,SIGNAL(unmapped()), this,SLOT(surfaceUnmapped())); + } + + void share_buffer_bind_resource(Resource *resource) Q_DECL_OVERRIDE + { + if (m_server_buffer_32_bit) { + struct ::wl_client *client = resource->handle->client; + struct ::wl_resource *buffer = m_server_buffer_32_bit->resourceForClient(client); + send_cross_buffer(resource->handle, buffer); + + } + if (m_server_buffer_8_bit) { + struct ::wl_client *client = resource->handle->client; + struct ::wl_resource *buffer = m_server_buffer_8_bit->resourceForClient(client); + send_cross_buffer(resource->handle, buffer); + + } + } + +private: + QWaylandServerBuffer *m_server_buffer_32_bit; + ServerBufferItem *m_server_buffer_item_32_bit; + QWaylandServerBuffer *m_server_buffer_8_bit; + ServerBufferItem *m_server_buffer_item_8_bit; +}; + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + if (!app.arguments().contains(QStringLiteral("--invert"))) { + qDebug() << "iverting"; + qputenv("QT_COMPOSITOR_NEGATE_INVERTED_Y", "1"); + } + + qmlRegisterType<ServerBufferItem>(); + + QmlCompositor compositor; + compositor.setTitle(QLatin1String("QML Compositor")); + compositor.setGeometry(0, 0, 1024, 768); + compositor.show(); + + compositor.rootContext()->setContextProperty("compositor", &compositor); + + QObject::connect(&compositor, SIGNAL(windowAdded(QVariant)), compositor.rootObject(), SLOT(windowAdded(QVariant))); + QObject::connect(&compositor, SIGNAL(windowDestroyed(QVariant)), compositor.rootObject(), SLOT(windowDestroyed(QVariant))); + QObject::connect(&compositor, SIGNAL(windowResized(QVariant)), compositor.rootObject(), SLOT(windowResized(QVariant))); + QObject::connect(&compositor, SIGNAL(serverBufferItemCreated(QVariant)), compositor.rootObject(), SLOT(serverBufferItemCreated(QVariant))); + + app.exec(); + qDebug() << "ending" << glGetError(); +} + +#include "main.moc" diff --git a/examples/server-buffer/compositor/qml/ServerBufferContainer.qml b/examples/server-buffer/compositor/qml/ServerBufferContainer.qml new file mode 100644 index 00000000..7c7306e3 --- /dev/null +++ b/examples/server-buffer/compositor/qml/ServerBufferContainer.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: container + + Item { + id: bufferContainer + property var serverBuffer + property int depth: serverBuffer == null ? 0 : serverBuffer.depth + width: serverBuffer == null ? 0 : serverBuffer.width + height: serverBuffer == null ? 0 : serverBuffer.height + } + + width: bufferContainer.width + height: bufferContainer.height + text.height + + Rectangle { + anchors.top: bufferContainer.bottom + width: parent.width + height: text.paintedHeight + color: "light grey" + Text { + id: text + anchors.fill: parent + text: bufferContainer.depth == 8 ? "8 bit Server Side buffer" : "32 bit Server Side buffer\nHorizontal line should be blue" + z: bufferContainer.z + 1 + wrapMode: Text.WordWrap + } + } + + function setServerBuffer(serverBuffer) { + serverBuffer.parent = bufferContainer; + bufferContainer.serverBuffer = serverBuffer + } +} diff --git a/examples/server-buffer/compositor/qml/main.qml b/examples/server-buffer/compositor/qml/main.qml new file mode 100644 index 00000000..231fb516 --- /dev/null +++ b/examples/server-buffer/compositor/qml/main.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: root + + property var serverBufferContainerComponent : Qt.createComponent("qrc:/qml/ServerBufferContainer.qml") + + Image { + id: background + anchors.fill: parent + fillMode: Image.Tile + source: "qrc:/images/background.jpg" + smooth: true + } + + Row { + id: row + anchors.fill: parent + } + + function windowAdded(window) { + window.parent = root; + } + + function windowResized(window) { + } + + function windowDestroyed(window) { + compositor.destroyWindow(window); + } + + function removeWindow(window) { + } + + function serverBufferItemCreated(serverBufferItem) { + console.log("ServerBuffer item" + serverBufferItem); + if (serverBufferContainerComponent.status != Component.Ready) { + console.log("Error loading component:", component.errorString()); + return; + } + var container = serverBufferContainerComponent.createObject(row); + container.setServerBuffer(serverBufferItem); + } +} diff --git a/examples/server-buffer/compositor/serverbufferitem.cpp b/examples/server-buffer/compositor/serverbufferitem.cpp new file mode 100644 index 00000000..8227b871 --- /dev/null +++ b/examples/server-buffer/compositor/serverbufferitem.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "serverbufferitem.h" + +#include "serverbuffertextureprovider.h" + +#include <QtQuick/QSGSimpleTextureNode> +#include <QtQuick/QQuickWindow> + +#include <QtCompositor/qwaylandserverbufferintegration.h> + +QT_BEGIN_NAMESPACE + +ServerBufferItem::ServerBufferItem(QWaylandServerBuffer *serverBuffer, QQuickItem *parent) + : QQuickItem(parent) + , m_server_buffer(serverBuffer) + , m_provider(new ServerBufferTextureProvider) + , m_useTextureAlpha(false) +{ + setFlag(QQuickItem::ItemHasContents); + setWidth(serverBuffer->size().width()); + setHeight(serverBuffer->size().height()); + update(); +} + +ServerBufferItem::~ServerBufferItem() +{ +} + +bool ServerBufferItem::isYInverted() const +{ + return m_server_buffer->isYInverted(); +} + +int ServerBufferItem::depth() const +{ + return m_server_buffer->format() == QWaylandServerBuffer::RGBA32 ? 32 : 8; +} + +QSGTextureProvider *ServerBufferItem::textureProvider() const +{ + return m_provider; +} + +void ServerBufferItem::updateTexture() +{ + if (m_provider->texture()) + return; + + QQuickWindow::CreateTextureOptions opt = QQuickWindow::TextureHasAlphaChannel; + GLuint texture; + glGenTextures(1,&texture); + glBindTexture(GL_TEXTURE_2D, texture); + m_server_buffer->bindTextureToBuffer(); + m_provider->setTexture(window()->createTextureFromId(texture, m_server_buffer->size(), opt)); +} + +QSGNode *ServerBufferItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + updateTexture(); + QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode); + + if (!node) { + node = new QSGSimpleTextureNode(); + } + + node->setTexture(m_provider->texture()); + + if (isYInverted()) { + node->setRect(0, height(), width(), -height()); + } else { + node->setRect(0, 0, width(), height()); + } + + return node; +} + +void ServerBufferItem::setUseTextureAlpha(bool useTextureAlpha) +{ + m_useTextureAlpha = useTextureAlpha; + + if ((flags() & ItemHasContents) != 0) { + update(); + } +} + +QT_END_NAMESPACE + diff --git a/examples/server-buffer/compositor/serverbufferitem.h b/examples/server-buffer/compositor/serverbufferitem.h new file mode 100644 index 00000000..9391cb94 --- /dev/null +++ b/examples/server-buffer/compositor/serverbufferitem.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SERVERBUFFERITEM_H +#define SERVERBUFFERITEM_H + +#include <QtQuick/QQuickItem> +#include <QtQuick/qsgtexture.h> + +#include <QtQuick/qsgtextureprovider.h> + +QT_BEGIN_NAMESPACE + +class ServerBufferTextureProvider; +class QWaylandServerBuffer; + +class ServerBufferItem : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QWaylandServerBuffer *serverBuffer READ serverBuffer CONSTANT) + Q_PROPERTY(bool useTextureAlpha READ useTextureAlpha WRITE setUseTextureAlpha NOTIFY useTextureAlphaChanged) + Q_PROPERTY(bool isYInverted READ isYInverted NOTIFY yInvertedChanged) + Q_PROPERTY(int depth READ depth CONSTANT) + +public: + ServerBufferItem(QWaylandServerBuffer *serverBuffer, QQuickItem *parent = 0); + ~ServerBufferItem(); + + QWaylandServerBuffer *serverBuffer() const { return m_server_buffer; } + + bool isYInverted() const; + int depth() const; + + bool isTextureProvider() const { return true; } + QSGTextureProvider *textureProvider() const; + + bool useTextureAlpha() const { return m_useTextureAlpha; } + void setUseTextureAlpha(bool useTextureAlpha); + + void setDamagedFlag(bool on); + +signals: + void useTextureAlphaChanged(); + void yInvertedChanged(); + void serverBufferChanged(); + +protected: + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *); + +private: + void updateTexture(); + QWaylandServerBuffer *m_server_buffer; + ServerBufferTextureProvider *m_provider; + bool m_useTextureAlpha; +}; + +QT_END_NAMESPACE + +#endif diff --git a/examples/server-buffer/compositor/serverbuffertextureprovider.h b/examples/server-buffer/compositor/serverbuffertextureprovider.h new file mode 100644 index 00000000..76ff5a4a --- /dev/null +++ b/examples/server-buffer/compositor/serverbuffertextureprovider.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SERVERBUFFERTEXTUREPROVIDER_H +#define SERVERBUFFERTEXTUREPROVIDER_H + +#include <QtQuick/QSGTextureProvider> + +QT_BEGIN_NAMESPACE + +class ServerBufferTextureProvider : public QSGTextureProvider +{ +public: + ServerBufferTextureProvider() : t(0) { } + ~ServerBufferTextureProvider() { delete t; } + + QSGTexture *texture() const { + if (t) { + t->setHorizontalWrapMode(QSGTexture::ClampToEdge); + t->setVerticalWrapMode(QSGTexture::ClampToEdge); + t->setFiltering(QSGTexture::Linear); + } + return t; + } + + void setTexture(QSGTexture *texture) { + if (texture != t) { + t = texture; + emit textureChanged(); + } + } + + bool smooth; +private: + QSGTexture *t; +}; + +QT_END_NAMESPACE + +#endif //SERVERBUFFERTEXTUREPROVIDER_H diff --git a/examples/server-buffer/server-buffer.pro b/examples/server-buffer/server-buffer.pro new file mode 100644 index 00000000..16c55625 --- /dev/null +++ b/examples/server-buffer/server-buffer.pro @@ -0,0 +1,3 @@ +TEMPLATE=subdirs + +SUBDIRS += client compositor diff --git a/examples/server-buffer/share-buffer.xml b/examples/server-buffer/share-buffer.xml new file mode 100644 index 00000000..57a1fd2c --- /dev/null +++ b/examples/server-buffer/share-buffer.xml @@ -0,0 +1,46 @@ +<protocol name="share_buffer"> + + <copyright> + Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). + Contact: http://www.qt-project.org/legal + + This file is part of the plugins of the Qt Toolkit. + + $QT_BEGIN_LICENSE:BSD$ + You may use this file under the terms of the BSD license as follows: + + "Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + + $QT_END_LICENSE$ + </copyright> + + <interface name="qt_share_buffer" version="1"> + <event name="cross_buffer"> + <arg name="buffer" type="object" interface="qt_server_buffer"/> + </event> + </interface> +</protocol> diff --git a/qtwayland.pro b/qtwayland.pro index a995ab3c..d6971baa 100644 --- a/qtwayland.pro +++ b/qtwayland.pro @@ -8,6 +8,7 @@ qtCompileTest(egl) qtCompileTest(brcm_egl) qtCompileTest(glx) qtCompileTest(xcomposite) +qtCompileTest(drm_egl_server) load(qt_parts) diff --git a/src/3rdparty/patches/0001-Add-a-EGL_DRM_BUFFER_FORMAT_A8_MESA.patch b/src/3rdparty/patches/0001-Add-a-EGL_DRM_BUFFER_FORMAT_A8_MESA.patch new file mode 100644 index 00000000..46fac714 --- /dev/null +++ b/src/3rdparty/patches/0001-Add-a-EGL_DRM_BUFFER_FORMAT_A8_MESA.patch @@ -0,0 +1,112 @@ +From 52dbed7516b79459d1c8f2ed3ea4a5e71734c969 Mon Sep 17 00:00:00 2001 +From: Jorgen Lind <jorgen.lind@digia.com> +Date: Thu, 2 Jan 2014 12:28:54 +0100 +Subject: [PATCH] Add a EGL_DRM_BUFFER_FORMAT_A8_MESA + +This is to allow us to share A8 DRM buffers between processes +--- + include/EGL/eglext.h | 1 + + include/GL/internal/dri_interface.h | 1 + + src/egl/drivers/dri2/egl_dri2.c | 7 +++++++ + src/mesa/drivers/dri/i915/intel_screen.c | 5 +++++ + src/mesa/drivers/dri/i965/intel_screen.c | 5 +++++ + 5 files changed, 19 insertions(+) + +diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h +index 1d68178..6c4fb7e 100644 +--- a/include/EGL/eglext.h ++++ b/include/EGL/eglext.h +@@ -271,6 +271,7 @@ typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dp + #define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* CreateDRMImageMESA attribute */ + #define EGL_DRM_BUFFER_USE_MESA 0x31D1 /* CreateDRMImageMESA attribute */ + #define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 /* EGL_IMAGE_FORMAT_MESA attribute value */ ++#define EGL_DRM_BUFFER_FORMAT_A8_MESA 0x31D5 /* EGL_IMAGE_FORMAT_MESA attribute value */ + #define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */ + #define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 + #define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 /* EGL_DRM_BUFFER_USE_MESA bits */ +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 5c99d55..565f1fb 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -964,6 +964,7 @@ struct __DRIdri2ExtensionRec { + #define __DRI_IMAGE_FORMAT_R8 0x1006 /* Since version 5 */ + #define __DRI_IMAGE_FORMAT_GR88 0x1007 + #define __DRI_IMAGE_FORMAT_NONE 0x1008 ++#define __DRI_IMAGE_FORMAT_A8 0x1009 /* Patch */ + + #define __DRI_IMAGE_USE_SHARE 0x0001 + #define __DRI_IMAGE_USE_SCANOUT 0x0002 +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index a8584b7..1cb6967 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -1152,6 +1152,10 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, + format = __DRI_IMAGE_FORMAT_ARGB8888; + pitch = attrs.DRMBufferStrideMESA; + break; ++ case EGL_DRM_BUFFER_FORMAT_A8_MESA: ++ format = __DRI_IMAGE_FORMAT_A8; ++ pitch = attrs.DRMBufferStrideMESA; ++ break; + default: + _eglError(EGL_BAD_PARAMETER, + "dri2_create_image_khr: unsupported pixmap depth"); +@@ -1427,6 +1431,9 @@ dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, + case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: + format = __DRI_IMAGE_FORMAT_ARGB8888; + break; ++ case EGL_DRM_BUFFER_FORMAT_A8_MESA: ++ format = __DRI_IMAGE_FORMAT_A8; ++ break; + default: + _eglLog(_EGL_WARNING, "bad image format value 0x%04x", + attrs.DRMBufferFormatMESA); +diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c +index 30a867e..3e1909b 100644 +--- a/src/mesa/drivers/dri/i915/intel_screen.c ++++ b/src/mesa/drivers/dri/i915/intel_screen.c +@@ -261,6 +261,9 @@ intel_allocate_image(int dri_format, void *loaderPrivate) + case __DRI_IMAGE_FORMAT_R8: + image->format = MESA_FORMAT_R8; + break; ++ case __DRI_IMAGE_FORMAT_A8: ++ image->format = MESA_FORMAT_A8; ++ break; + case __DRI_IMAGE_FORMAT_GR88: + image->format = MESA_FORMAT_GR88; + break; +@@ -330,6 +333,8 @@ intel_dri_format(GLuint format) + return __DRI_IMAGE_FORMAT_ABGR8888; + case MESA_FORMAT_R8: + return __DRI_IMAGE_FORMAT_R8; ++ case MESA_FORMAT_A8: ++ return __DRI_IMAGE_FORMAT_A8; + case MESA_FORMAT_RG88: + return __DRI_IMAGE_FORMAT_GR88; + } +diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c +index f913c42..68ee33b 100644 +--- a/src/mesa/drivers/dri/i965/intel_screen.c ++++ b/src/mesa/drivers/dri/i965/intel_screen.c +@@ -262,6 +262,9 @@ intel_allocate_image(int dri_format, void *loaderPrivate) + case __DRI_IMAGE_FORMAT_R8: + image->format = MESA_FORMAT_R8; + break; ++ case __DRI_IMAGE_FORMAT_A8: ++ image->format = MESA_FORMAT_A8; ++ break; + case __DRI_IMAGE_FORMAT_GR88: + image->format = MESA_FORMAT_GR88; + break; +@@ -334,6 +337,8 @@ intel_dri_format(GLuint format) + return __DRI_IMAGE_FORMAT_ABGR8888; + case MESA_FORMAT_R8: + return __DRI_IMAGE_FORMAT_R8; ++ case MESA_FORMAT_A8: ++ return __DRI_IMAGE_FORMAT_A8; + case MESA_FORMAT_RG88: + return __DRI_IMAGE_FORMAT_GR88; + } +-- +1.8.5.1 + diff --git a/src/3rdparty/protocol/input-method.xml b/src/3rdparty/protocol/input-method.xml new file mode 100644 index 00000000..70afdcb1 --- /dev/null +++ b/src/3rdparty/protocol/input-method.xml @@ -0,0 +1,273 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="input_method"> + <copyright> + Copyright © 2012, 2013 Intel Corporation + + 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 + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. + </copyright> + + + <interface name="wl_input_method_context" version="1"> + <description summary="input method context"> + Corresponds to a text model on input method side. An input method context + is created on text mode activation on the input method side. It allows to + receive information about the text model from the application via events. + Input method contexts do not keep state after deactivation and should be + destroyed after deactivation is handled. + + Text is generally UTF-8 encoded, indices and lengths are in bytes. + + Serials are used to synchronize the state between the text input and + an input method. New serials are sent by the text input in the + commit_state request and are used by the input method to indicate + the known text input state in events like preedit_string, commit_string, + and keysym. The text input can then ignore events from the input method + which are based on an outdated state (for example after a reset). + </description> + <request name="destroy" type="destructor"/> + <request name="commit_string"> + <description summary="commit string"> + Send the commit string text for insertion to the application. + + The text to commit could be either just a single character after a key + press or the result of some composing (pre-edit). It could be also an + empty text when some text should be removed (see + delete_surrounding_text) or when the input cursor should be moved (see + cursor_position). + + Any previously set composing text will be removed. + </description> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="text" type="string"/> + </request> + <request name="preedit_string"> + <description summary="pre-edit string"> + Send the pre-edit string text to the application text input. + + The commit text can be used to replace the preedit text on reset (for + example on unfocus). + + Also previously sent preedit_style and preedit_cursor requests are + processed bt the text_input also. + </description> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="text" type="string"/> + <arg name="commit" type="string"/> + </request> + <request name="preedit_styling"> + <description summary="pre-edit styling"> + Sets styling information on composing text. The style is applied for + length in bytes from index relative to the beginning of + the composing text (as byte offset). Multiple styles can + be applied to a composing text. + + This request should be sent before sending preedit_string request. + </description> + <arg name="index" type="uint"/> + <arg name="length" type="uint"/> + <arg name="style" type="uint"/> + </request> + <request name="preedit_cursor"> + <description summary="pre-edit cursor"> + Sets the cursor position inside the composing text (as byte offset) + relative to the start of the composing text. + + When index is negative no cursor should be displayed. + + This request should be sent before sending preedit_string request. + </description> + <arg name="index" type="int"/> + </request> + <request name="delete_surrounding_text"> + <description summary="delete text"> + + + This request will be handled on text_input side as part of a directly + following commit_string request. + </description> + <arg name="index" type="int"/> + <arg name="length" type="uint"/> + </request> + <request name="cursor_position"> + <description summary="set cursor to a new position"> + Sets the cursor and anchor to a new position. Index is the new cursor + position in bytess (when >= 0 relative to the end of inserted text + else relative to beginning of inserted text). Anchor is the new anchor + position in bytes (when >= 0 relative to the end of inserted text, else + relative to beginning of inserted text). When there should be no + selected text anchor should be the same as index. + + This request will be handled on text_input side as part of a directly + following commit_string request. + </description> + <arg name="index" type="int"/> + <arg name="anchor" type="int"/> + </request> + <request name="modifiers_map"> + <arg name="map" type="array"/> + </request> + <request name="keysym"> + <description summary="keysym"> + Notify when a key event was sent. Key events should not be used for + normal text input operations, which should be done with commit_string, + delete_surrounfing_text, etc. The key event follows the wl_keyboard key + event convention. Sym is a XKB keysym, state a wl_keyboard key_state. + </description> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="time" type="uint"/> + <arg name="sym" type="uint"/> + <arg name="state" type="uint"/> + <arg name="modifiers" type="uint"/> + </request> + <request name="grab_keyboard"> + <description summary="grab hardware keyboard"> + Allows an input method to receive hardware keyboard input and process + key events to generate text events (with pre-edit) over the wire. This + allows input methods which compose multiple key events for inputting + text like it is done for CJK languages. + </description> + <arg name="keyboard" type="new_id" interface="wl_keyboard"/> + </request> + <request name="key"> + <description summary="forward key event"> + Should be used when filtering key events with grab_keyboard. + + When the wl_keyboard::key event is not processed by the input + method itself and should be sent to the client instead, forward it + with this request. The arguments should be the ones from the + wl_keyboard::key event. + + For generating custom key events use the keysym request instead. + </description> + <arg name="serial" type="uint" summary="serial from wl_keyboard::key"/> + <arg name="time" type="uint" summary="time from wl_keyboard::key"/> + <arg name="key" type="uint" summary="key from wl_keyboard::key"/> + <arg name="state" type="uint" summary="state from wl_keyboard::key"/> + </request> + <request name="modifiers"> + <description summary="forward modifiers event"> + Should be used when filtering key events with grab_keyboard. + + When the wl_keyboard::modifiers event should be also send to the + client, forward it with this request. The arguments should be the ones + from the wl_keyboard::modifiers event. + </description> + <arg name="serial" type="uint" summary="serial from wl_keyboard::modifiers"/> + <arg name="mods_depressed" type="uint" summary="mods_depressed from wl_keyboard::modifiers"/> + <arg name="mods_latched" type="uint" summary="mods_latched from wl_keyboard::modifiers"/> + <arg name="mods_locked" type="uint" summary="mods_locked from wl_keyboard::modifiers"/> + <arg name="group" type="uint" summary="group from wl_keyboard::modifiers"/> + </request> + <request name="language"> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="language" type="string"/> + </request> + <request name="text_direction"> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="direction" type="uint"/> + </request> + <event name="surrounding_text"> + <description summary="surrounding text event"> + The plain surrounding text around the input position. Cursor is the + position in bytes within the surrounding text relative to the beginning + of the text. Anchor is the position in bytes of the selection anchor + within the surrounding text relative to the beginning of the text. If + there is no selected text anchor is the same as cursor. + </description> + <arg name="text" type="string"/> + <arg name="cursor" type="uint"/> + <arg name="anchor" type="uint"/> + </event> + <event name="reset"> + </event> + <event name="content_type"> + <arg name="hint" type="uint"/> + <arg name="purpose" type="uint"/> + </event> + <event name="invoke_action"> + <arg name="button" type="uint"/> + <arg name="index" type="uint"/> + </event> + <event name="commit_state"> + <arg name="serial" type="uint" summary="serial of text input state"/> + </event> + <event name="preferred_language"> + <arg name="language" type="string"/> + </event> + </interface> + + <interface name="wl_input_method" version="1"> + <description summary="input method"> + An input method object is responsible to compose text in response to + input from hardware or virtual keyboards. There is one input method + object per seat. On activate there is a new input method context object + created which allows the input method to communicate with the text model. + </description> + <event name="activate"> + <description summary="activate event"> + A text model was activated. Creates an input method context object + which allows communication with the text model. + </description> + <arg name="id" type="new_id" interface="wl_input_method_context"/> + </event> + <event name="deactivate"> + <description summary="activate event"> + The text model corresponding to the context argument was deactivated. + The input method context should be destroyed after deactivation is + handled. + </description> + <arg name="context" type="object" interface="wl_input_method_context"/> + </event> + </interface> + + <interface name="wl_input_panel" version="1"> + <description summary="interface for implementing keyboards"> + Only one client can bind this interface at a time. + </description> + + <request name="get_input_panel_surface"> + <arg name="id" type="new_id" interface="wl_input_panel_surface"/> + <arg name="surface" type="object" interface="wl_surface"/> + </request> + </interface> + + <interface name="wl_input_panel_surface" version="1"> + <enum name="position"> + <entry name="center_bottom" value="0"/> + </enum> + + <request name="set_toplevel"> + <description summary="set the surface type as a keyboard"> + A keybaord surface is only shown, when a text model is active + </description> + <arg name="output" type="object" interface="wl_output"/> + <arg name="position" type="uint"/> + </request> + + <request name="set_overlay_panel"> + <description summary="set the surface type as an overlay panel"> + An overlay panel is shown near the input cursor above the application + window when a text model is active. + </description> + </request> + </interface> +</protocol> diff --git a/src/3rdparty/protocol/text.xml b/src/3rdparty/protocol/text.xml new file mode 100644 index 00000000..1b5284dc --- /dev/null +++ b/src/3rdparty/protocol/text.xml @@ -0,0 +1,346 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="text"> + + <copyright> + Copyright © 2012, 2013 Intel Corporation + + 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 + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. + </copyright> + + <interface name="wl_text_input" version="1"> + <description summary="text input"> + An object used for text input. Adds support for text input and input + methods to applications. A text-input object is created from a + wl_text_input_manager and corresponds typically to a text entry in an + application. + Requests are used to activate/deactivate the text-input object and set + state information like surrounding and selected text or the content type. + The information about entered text is sent to the text-input object via + the pre-edit and commit events. Using this interface removes the need + for applications to directly process hardware key events and compose text + out of them. + + Text is generally UTF-8 encoded, indices and lengths are in bytes. + + Serials are used to synchronize the state between the text input and + an input method. New serials are sent by the text input in the + commit_state request and are used by the input method to indicate + the known text input state in events like preedit_string, commit_string, + and keysym. The text input can then ignore events from the input method + which are based on an outdated state (for example after a reset). + </description> + <request name="activate"> + <description summary="request activation"> + Requests the text-input object to be activated (typically when the + text entry gets focus). + The seat argument is a wl_seat which maintains the focus for this + activation. The surface argument is a wl_surface assigned to the + text-input object and tracked for focus lost. The enter event + is emitted on successful activation. + </description> + <arg name="seat" type="object" interface="wl_seat"/> + <arg name="surface" type="object" interface="wl_surface"/> + </request> + <request name="deactivate"> + <description summary="request deactivation"> + Requests the text-input object to be deactivated (typically when the + text entry lost focus). The seat argument is a wl_seat which was used + for activation. + </description> + <arg name="seat" type="object" interface="wl_seat"/> + </request> + <request name="show_input_panel"> + <description summary="show input panels"> + Requests input panels (virtual keyboard) to show. + </description> + </request> + <request name="hide_input_panel"> + <description summary="hide input panels"> + Requests input panels (virtual keyboard) to hide. + </description> + </request> + <request name="reset"> + <description summary="reset"> + Should be called by an editor widget when the input state should be + reset, for example after the text was changed outside of the normal + input method flow. + </description> + </request> + <request name="set_surrounding_text"> + <description summary="sets the surrounding text"> + Sets the plain surrounding text around the input position. Text is + UTF-8 encoded. Cursor is the byte offset within the + surrounding text. Anchor is the byte offset of the + selection anchor within the surrounding text. If there is no selected + text anchor is the same as cursor. + </description> + <arg name="text" type="string"/> + <arg name="cursor" type="uint"/> + <arg name="anchor" type="uint"/> + </request> + <enum name="content_hint"> + <description summary="content hint"> + Content hint is a bitmask to allow to modify the behavior of the text + input. + </description> + <entry name="none" value="0x0" summary="no special behaviour"/> + <entry name="default" value="0x7" summary="auto completion, correction and capitalization"/> + <entry name="password" value="0xc0" summary="hidden and sensitive text"/> + <entry name="auto_completion" value="0x1" summary="suggest word completions"/> + <entry name="auto_correction" value="0x2" summary="suggest word corrections"/> + <entry name="auto_capitalization" value="0x4" summary="switch to uppercase letters at the start of a sentence"/> + <entry name="lowercase" value="0x8" summary="prefer lowercase letters"/> + <entry name="uppercase" value="0x10" summary="prefer uppercase letters"/> + <entry name="titlecase" value="0x20" summary="prefer casing for titles and headings (can be language dependent)"/> + <entry name="hidden_text" value="0x40" summary="characters should be hidden"/> + <entry name="sensitive_data" value="0x80" summary="typed text should not be stored"/> + <entry name="latin" value="0x100" summary="just latin characters should be entered"/> + <entry name="multiline" value="0x200" summary="the text input is multiline"/> + </enum> + <enum name="content_purpose"> + <description summary="content purpose"> + The content purpose allows to specify the primary purpose of a text + input. + + This allows an input method to show special purpose input panels with + extra characters or to disallow some characters. + </description> + <entry name="normal" value="0" summary="default input, allowing all characters"/> + <entry name="alpha" value="1" summary="allow only alphabetic characters"/> + <entry name="digits" value="2" summary="allow only digits"/> + <entry name="number" value="3" summary="input a number (including decimal separator and sign)"/> + <entry name="phone" value="4" summary="input a phone number"/> + <entry name="url" value="5" summary="input an URL"/> + <entry name="email" value="6" summary="input an email address"/> + <entry name="name" value="7" summary="input a name of a person"/> + <entry name="password" value="8" summary="input a password (combine with password or sensitive_data hint)"/> + <entry name="date" value="9" summary="input a date"/> + <entry name="time" value="10" summary="input a time"/> + <entry name="datetime" value="11" summary="input a date and time"/> + <entry name="terminal" value="12" summary="input for a terminal"/> + </enum> + <request name="set_content_type"> + <description summary="set content purpose and hint"> + Sets the content purpose and content hint. While the purpose is the + basic purpose of an input field, the hint flags allow to modify some + of the behavior. + + When no content type is explicitly set, a normal content purpose with + default hints (auto completion, auto correction, auto capitalization) + should be assumed. + </description> + <arg name="hint" type="uint"/> + <arg name="purpose" type="uint"/> + </request> + <request name="set_cursor_rectangle"> + <arg name="x" type="int"/> + <arg name="y" type="int"/> + <arg name="width" type="int"/> + <arg name="height" type="int"/> + </request> + <request name="set_preferred_language"> + <description summary="sets preferred language"> + Sets a specific language. This allows for example a virtual keyboard to + show a language specific layout. The "language" argument is a RFC-3066 + format language tag. + + It could be used for example in a word processor to indicate language of + currently edited document or in an instant message application which tracks + languages of contacts. + </description> + <arg name="language" type="string"/> + </request> + <request name="commit_state"> + <arg name="serial" type="uint" summary="used to identify the known state"/> + </request> + <request name="invoke_action"> + <arg name="button" type="uint"/> + <arg name="index" type="uint"/> + </request> + <event name="enter"> + <description summary="enter event"> + Notify the text-input object when it received focus. Typically in + response to an activate request. + </description> + <arg name="surface" type="object" interface="wl_surface"/> + </event> + <event name="leave"> + <description summary="leave event"> + Notify the text-input object when it lost focus. Either in response + to a deactivate request or when the assigned surface lost focus or was + destroyed. + </description> + </event> + <event name="modifiers_map"> + <description summary="modifiers map"> + Transfer an array of 0-terminated modifiers names. The position in + the array is the index of the modifier as used in the modifiers + bitmask in the keysym event. + </description> + <arg name="map" type="array"/> + </event> + <event name="input_panel_state"> + <description summary="state of the input panel"> + Notify when the visibility state of the input panel changed. + </description> + <arg name="state" type="uint"/> + </event> + <event name="preedit_string"> + <description summary="pre-edit"> + Notify when a new composing text (pre-edit) should be set around the + current cursor position. Any previously set composing text should + be removed. + + The commit text can be used to replace the preedit text on reset + (for example on unfocus). + + The text input should also handle all preedit_style and preedit_cursor + events occuring directly before preedit_string. + </description> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="text" type="string"/> + <arg name="commit" type="string"/> + </event> + <enum name="preedit_style"> + <entry name="default" value="0" summary="default style for composing text"/> + <entry name="none" value="1" summary="style should be the same as in non-composing text"/> + <entry name="active" value="2"/> + <entry name="inactive" value="3"/> + <entry name="highlight" value="4"/> + <entry name="underline" value="5"/> + <entry name="selection" value="6"/> + <entry name="incorrect" value="7"/> + </enum> + <event name="preedit_styling"> + <description summary="pre-edit styling"> + Sets styling information on composing text. The style is applied for + length bytes from index relative to the beginning of the composing + text (as byte offset). Multiple styles can + be applied to a composing text by sending multiple preedit_styling + events. + + This event is handled as part of a following preedit_string event. + </description> + <arg name="index" type="uint"/> + <arg name="length" type="uint"/> + <arg name="style" type="uint"/> + </event> + <event name="preedit_cursor"> + <description summary="pre-edit cursor"> + Sets the cursor position inside the composing text (as byte + offset) relative to the start of the composing text. When index is a + negative number no cursor is shown. + + This event is handled as part of a following preedit_string event. + </description> + <arg name="index" type="int"/> + </event> + <event name="commit_string"> + <description summary="commit"> + Notify when text should be inserted into the editor widget. The text to + commit could be either just a single character after a key press or the + result of some composing (pre-edit). It could be also an empty text + when some text should be removed (see delete_surrounding_text) or when + the input cursor should be moved (see cursor_position). + + Any previously set composing text should be removed. + </description> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="text" type="string"/> + </event> + <event name="cursor_position"> + <description summary="set cursor to new position"> + Notify when the cursor or anchor position should be modified. + + This event should be handled as part of a following commit_string + event. + </description> + <arg name="index" type="int"/> + <arg name="anchor" type="int"/> + </event> + <event name="delete_surrounding_text"> + <description summary="delete surrounding text"> + Notify when the text around the current cursor position should be + deleted. + + Index is relative to the current cursor (in bytes). + Length is the length of deleted text (in bytes). + + This event should be handled as part of a following commit_string + event. + </description> + <arg name="index" type="int"/> + <arg name="length" type="uint"/> + </event> + <event name="keysym"> + <description summary="keysym"> + Notify when a key event was sent. Key events should not be used + for normal text input operations, which should be done with + commit_string, delete_surrounding_text, etc. The key event follows + the wl_keyboard key event convention. Sym is a XKB keysym, state a + wl_keyboard key_state. Modifiers are a mask for effective modifiers + (where the modifier indices are set by the modifiers_map event) + </description> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="time" type="uint"/> + <arg name="sym" type="uint"/> + <arg name="state" type="uint"/> + <arg name="modifiers" type="uint"/> + </event> + <event name="language"> + <description summary="language"> + Sets the language of the input text. The "language" argument is a RFC-3066 + format language tag. + </description> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="language" type="string"/> + </event> + <enum name="text_direction"> + <entry name="auto" value="0" summary="automatic text direction based on text and language"/> + <entry name="ltr" value="1" summary="left-to-right"/> + <entry name="rtl" value="2" summary="right-to-left"/> + </enum> + <event name="text_direction"> + <description summary="text direction"> + Sets the text direction of input text. + + It is mainly needed for showing input cursor on correct side of the + editor when there is no input yet done and making sure neutral + direction text is laid out properly. + </description> + <arg name="serial" type="uint" summary="serial of the latest known text input state"/> + <arg name="direction" type="uint"/> + </event> + </interface> + + <interface name="wl_text_input_manager" version="1"> + <description summary="text input manager"> + A factory for text-input objects. This object is a global singleton. + </description> + <request name="create_text_input"> + <description summary="create text input"> + Creates a new text-input object. + </description> + <arg name="id" type="new_id" interface="wl_text_input"/> + </request> + </interface> +</protocol> diff --git a/src/client/client.pro b/src/client/client.pro new file mode 100644 index 00000000..01d704a9 --- /dev/null +++ b/src/client/client.pro @@ -0,0 +1,98 @@ +TARGET = QtWaylandClient +QT += core-private gui-private +QT_FOR_PRIVATE += platformsupport-private + +MODULE=waylandclient +load(qt_module) + +CONFIG += link_pkgconfig qpa/genericunixfontdatabase wayland-scanner + +!equals(QT_WAYLAND_GL_CONFIG, nogl) { + DEFINES += QT_WAYLAND_GL_SUPPORT +} + +config_xkbcommon { + !contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += xkbcommon + } else { + LIBS += -lxkbcommon + } +} else { + DEFINES += QT_NO_WAYLAND_XKB +} + +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += wayland-client wayland-cursor + contains(QT_CONFIG, glib): PKGCONFIG_PRIVATE += glib-2.0 +} else { + LIBS += -lwayland-client -lwayland-cursor $$QT_LIBS_GLIB +} + +INCLUDEPATH += $$PWD/../shared + +WAYLANDCLIENTSOURCES += \ + ../3rdparty/protocol/wayland.xml \ + ../extensions/surface-extension.xml \ + ../extensions/sub-surface-extension.xml \ + ../extensions/output-extension.xml \ + ../extensions/touch-extension.xml \ + ../extensions/qtkey-extension.xml \ + ../extensions/windowmanager.xml \ + ../3rdparty/protocol/text.xml \ + +SOURCES += qwaylandintegration.cpp \ + qwaylandnativeinterface.cpp \ + qwaylandshmbackingstore.cpp \ + qwaylandinputdevice.cpp \ + qwaylandcursor.cpp \ + qwaylanddisplay.cpp \ + qwaylandwindow.cpp \ + qwaylandscreen.cpp \ + qwaylandshmwindow.cpp \ + qwaylandclipboard.cpp \ + qwaylanddnd.cpp \ + qwaylanddataoffer.cpp \ + qwaylanddatadevicemanager.cpp \ + qwaylanddatasource.cpp \ + qwaylandshellsurface.cpp \ + qwaylandextendedoutput.cpp \ + qwaylandextendedsurface.cpp \ + qwaylandsubsurface.cpp \ + qwaylandtouch.cpp \ + qwaylandqtkey.cpp \ + ../shared/qwaylandmimehelper.cpp \ + qwaylanddecoration.cpp \ + qwaylandeventthread.cpp\ + qwaylandwindowmanagerintegration.cpp \ + qwaylandinputcontext.cpp \ + qwaylanddatadevice.cpp \ + +HEADERS += qwaylandintegration_p.h \ + qwaylandnativeinterface_p.h \ + qwaylandcursor_p.h \ + qwaylanddisplay_p.h \ + qwaylandwindow_p.h \ + qwaylandscreen_p.h \ + qwaylandshmbackingstore_p.h \ + qwaylandinputdevice_p.h \ + qwaylandbuffer_p.h \ + qwaylandshmwindow_p.h \ + qwaylandclipboard_p.h \ + qwaylanddnd_p.h \ + qwaylanddataoffer_p.h \ + qwaylanddatadevicemanager_p.h \ + qwaylanddatasource_p.h \ + qwaylandshellsurface_p.h \ + qwaylandextendedoutput_p.h \ + qwaylandextendedsurface_p.h \ + qwaylandsubsurface_p.h \ + qwaylandtouch_p.h \ + qwaylandqtkey_p.h \ + ../shared/qwaylandmimehelper.h \ + qwaylanddecoration_p.h \ + qwaylandeventthread_p.h \ + qwaylandwindowmanagerintegration_p.h \ + qwaylandinputcontext_p.h \ + qwaylanddatadevice_p.h \ + +include(hardwareintegration/hardwareintegration.pri) diff --git a/src/client/hardwareintegration/hardwareintegration.pri b/src/client/hardwareintegration/hardwareintegration.pri new file mode 100644 index 00000000..bb4fe76d --- /dev/null +++ b/src/client/hardwareintegration/hardwareintegration.pri @@ -0,0 +1,24 @@ +WAYLANDCLIENTSOURCES += \ + $$PWD/../../extensions/server-buffer-extension.xml \ + $$PWD/../../extensions/hardware-integration.xml + +INCLUDEPATH += $$PWD + +SOURCES += \ + $$PWD/qwaylandclientbufferintegration.cpp \ + $$PWD/qwaylandclientbufferintegrationplugin.cpp \ + $$PWD/qwaylandclientbufferintegrationfactory.cpp \ + $$PWD/qwaylandserverbufferintegration.cpp \ + $$PWD/qwaylandserverbufferintegrationplugin.cpp \ + $$PWD/qwaylandserverbufferintegrationfactory.cpp \ + $$PWD/qwaylandhardwareintegration.cpp + +HEADERS += \ + $$PWD/qwaylandclientbufferintegration_p.h \ + $$PWD/qwaylandclientbufferintegrationplugin_p.h \ + $$PWD/qwaylandclientbufferintegrationfactory_p.h \ + $$PWD/qwaylandserverbufferintegration_p.h \ + $$PWD/qwaylandserverbufferintegrationplugin_p.h \ + $$PWD/qwaylandserverbufferintegrationfactory_p.h \ + $$PWD/qwaylandhardwareintegration_p.h + diff --git a/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp b/src/client/hardwareintegration/qwaylandclientbufferintegration.cpp index bafb9944..2c4d8ff1 100644 --- a/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp +++ b/src/client/hardwareintegration/qwaylandclientbufferintegration.cpp @@ -39,16 +39,16 @@ ** ****************************************************************************/ -#include "qwaylandglintegration.h" +#include "qwaylandclientbufferintegration_p.h" QT_BEGIN_NAMESPACE -QWaylandGLIntegration::QWaylandGLIntegration() +QWaylandClientBufferIntegration::QWaylandClientBufferIntegration() { } -QWaylandGLIntegration::~QWaylandGLIntegration() +QWaylandClientBufferIntegration::~QWaylandClientBufferIntegration() { } diff --git a/src/plugins/platforms/wayland_common/qwaylandglintegration.h b/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h index 4055790b..153b3f59 100644 --- a/src/plugins/platforms/wayland_common/qwaylandglintegration.h +++ b/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h @@ -39,10 +39,11 @@ ** ****************************************************************************/ -#ifndef QWAYLANDGLINTEGRATION_H -#define QWAYLANDGLINTEGRATION_H +#ifndef QWAYLANDCLIENTBUFFERINTEGRATION_H +#define QWAYLANDCLIENTBUFFERINTEGRATION_H #include <QtCore/qglobal.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> QT_BEGIN_NAMESPACE @@ -53,23 +54,21 @@ class QWindow; class QPlatformOpenGLContext; class QSurfaceFormat; -class QWaylandGLIntegration +class Q_WAYLAND_CLIENT_EXPORT QWaylandClientBufferIntegration { public: - QWaylandGLIntegration(); - virtual ~QWaylandGLIntegration(); + QWaylandClientBufferIntegration(); + virtual ~QWaylandClientBufferIntegration(); - virtual void initialize() = 0; + virtual void initialize(QWaylandDisplay *display) = 0; virtual bool waitingForEvents() { return false; } virtual bool supportsThreadedOpenGL() const { return false; } virtual QWaylandWindow *createEglWindow(QWindow *window) = 0; virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0; - - static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay); }; QT_END_NAMESPACE -#endif // QWAYLANDGLINTEGRATION_H +#endif // QWAYLANDCLIENTBUFFERINTEGRATION_H diff --git a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegrationfactory.cpp b/src/client/hardwareintegration/qwaylandclientbufferintegrationfactory.cpp index 17e2dbdb..e168f612 100644 --- a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegrationfactory.cpp +++ b/src/client/hardwareintegration/qwaylandclientbufferintegrationfactory.cpp @@ -39,9 +39,9 @@ ** ****************************************************************************/ -#include "qwaylandgraphicshardwareintegrationfactory.h" -#include "qwaylandgraphicshardwareintegrationplugin.h" -#include "qwaylandgraphicshardwareintegration.h" +#include "qwaylandclientbufferintegrationfactory_p.h" +#include "qwaylandclientbufferintegrationplugin_p.h" +#include "qwaylandclientbufferintegration_p.h" #include <QtCore/private/qfactoryloader_p.h> #include <QtCore/QCoreApplication> #include <QtCore/QDir> @@ -50,12 +50,12 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QWaylandGraphicsHardwareIntegrationFactoryInterface_iid, QLatin1String("/waylandcompositors"), Qt::CaseInsensitive)) + (QWaylandClientBufferIntegrationFactoryInterface_iid, QLatin1String("/wayland-graphics-integration/client"), Qt::CaseInsensitive)) Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, - (QWaylandGraphicsHardwareIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) + (QWaylandClientBufferIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) #endif -QStringList QWaylandGraphicsHardwareIntegrationFactory::keys(const QString &pluginPath) +QStringList QWaylandClientBufferIntegrationFactory::keys(const QString &pluginPath) { #ifndef QT_NO_LIBRARY QStringList list; @@ -78,16 +78,16 @@ QStringList QWaylandGraphicsHardwareIntegrationFactory::keys(const QString &plug #endif } -QWaylandGraphicsHardwareIntegration *QWaylandGraphicsHardwareIntegrationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath) +QWaylandClientBufferIntegration *QWaylandClientBufferIntegrationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath) { #ifndef QT_NO_LIBRARY // Try loading the plugin from platformPluginPath first: if (!pluginPath.isEmpty()) { QCoreApplication::addLibraryPath(pluginPath); - if (QWaylandGraphicsHardwareIntegration *ret = qLoadPlugin1<QWaylandGraphicsHardwareIntegration, QWaylandGraphicsHardwareIntegrationPlugin>(directLoader(), name, args)) + if (QWaylandClientBufferIntegration *ret = qLoadPlugin1<QWaylandClientBufferIntegration, QWaylandClientBufferIntegrationPlugin>(directLoader(), name, args)) return ret; } - if (QWaylandGraphicsHardwareIntegration *ret = qLoadPlugin1<QWaylandGraphicsHardwareIntegration, QWaylandGraphicsHardwareIntegrationPlugin>(loader(), name, args)) + if (QWaylandClientBufferIntegration *ret = qLoadPlugin1<QWaylandClientBufferIntegration, QWaylandClientBufferIntegrationPlugin>(loader(), name, args)) return ret; #endif return 0; diff --git a/src/client/hardwareintegration/qwaylandclientbufferintegrationfactory_p.h b/src/client/hardwareintegration/qwaylandclientbufferintegrationfactory_p.h new file mode 100644 index 00000000..4a1c4128 --- /dev/null +++ b/src/client/hardwareintegration/qwaylandclientbufferintegrationfactory_p.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDCLIENTBUFFERINTEGRATIONFACTORY_H +#define QWAYLANDCLIENTBUFFERINTEGRATIONFACTORY_H + +#include <QtWaylandClient/private/qwaylandclientexport_p.h> +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE + +class QWaylandClientBufferIntegration; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandClientBufferIntegrationFactory +{ +public: + static QStringList keys(const QString &pluginPath = QString()); + static QWaylandClientBufferIntegration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString()); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDCLIENTBUFFERINTEGRATIONFACTORY_H diff --git a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegrationplugin.cpp b/src/client/hardwareintegration/qwaylandclientbufferintegrationplugin.cpp index 66e07352..afc10510 100644 --- a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegrationplugin.cpp +++ b/src/client/hardwareintegration/qwaylandclientbufferintegrationplugin.cpp @@ -39,16 +39,16 @@ ** ****************************************************************************/ -#include "qwaylandgraphicshardwareintegrationplugin.h" +#include "qwaylandclientbufferintegrationplugin_p.h" QT_BEGIN_NAMESPACE -QWaylandGraphicsHardwareIntegrationPlugin::QWaylandGraphicsHardwareIntegrationPlugin(QObject *parent) : +QWaylandClientBufferIntegrationPlugin::QWaylandClientBufferIntegrationPlugin(QObject *parent) : QObject(parent) { } -QWaylandGraphicsHardwareIntegrationPlugin::~QWaylandGraphicsHardwareIntegrationPlugin() +QWaylandClientBufferIntegrationPlugin::~QWaylandClientBufferIntegrationPlugin() { } diff --git a/src/client/hardwareintegration/qwaylandclientbufferintegrationplugin_p.h b/src/client/hardwareintegration/qwaylandclientbufferintegrationplugin_p.h new file mode 100644 index 00000000..476e31a7 --- /dev/null +++ b/src/client/hardwareintegration/qwaylandclientbufferintegrationplugin_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDCLIENTBUFFERINTEGRATIONPLUGIN_H +#define QWAYLANDCLIENTBUFFERINTEGRATIONPLUGIN_H + +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + +#include <QtCore/qplugin.h> +#include <QtCore/qfactoryinterface.h> +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE + +class QWaylandClientBufferIntegration; + +#define QWaylandClientBufferIntegrationFactoryInterface_iid "org.qt-project.Qt.WaylandClient.QWaylandClientBufferIntegrationFactoryInterface.5.1" + +class Q_WAYLAND_CLIENT_EXPORT QWaylandClientBufferIntegrationPlugin : public QObject +{ + Q_OBJECT +public: + explicit QWaylandClientBufferIntegrationPlugin(QObject *parent = 0); + ~QWaylandClientBufferIntegrationPlugin(); + + virtual QWaylandClientBufferIntegration *create(const QString &key, const QStringList ¶mList) = 0; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDCLIENTBUFFERINTEGRATIONPLUGIN_H diff --git a/src/client/hardwareintegration/qwaylandhardwareintegration.cpp b/src/client/hardwareintegration/qwaylandhardwareintegration.cpp new file mode 100644 index 00000000..a7269ce9 --- /dev/null +++ b/src/client/hardwareintegration/qwaylandhardwareintegration.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandhardwareintegration_p.h" + +#include "qwaylanddisplay_p.h" +QT_BEGIN_NAMESPACE + +QWaylandHardwareIntegration::QWaylandHardwareIntegration(struct ::wl_registry *registry, int id) + : qt_hardware_integration(registry, id) +{ +} + +QString QWaylandHardwareIntegration::clientBufferIntegration() +{ + return m_client_buffer; +} + +QString QWaylandHardwareIntegration::serverBufferIntegration() +{ + return m_server_buffer; +} + +void QWaylandHardwareIntegration::hardware_integration_client_backend(const QString &name) +{ + m_client_buffer = name; +} + +void QWaylandHardwareIntegration::hardware_integration_server_backend(const QString &name) +{ + m_server_buffer = name; +} + +QT_END_NAMESPACE diff --git a/src/client/hardwareintegration/qwaylandhardwareintegration_p.h b/src/client/hardwareintegration/qwaylandhardwareintegration_p.h new file mode 100644 index 00000000..84aa18ac --- /dev/null +++ b/src/client/hardwareintegration/qwaylandhardwareintegration_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDHARDWAREINTEGRATION_H +#define QWAYLANDHARDWAREINTEGRATION_H + +#include <QtWaylandClient/private/qwayland-hardware-integration.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + +QT_BEGIN_NAMESPACE + +class QWaylandDisplay; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandHardwareIntegration : public QtWayland::qt_hardware_integration +{ +public: + QWaylandHardwareIntegration(struct ::wl_registry *registry, int id); + + QString clientBufferIntegration(); + QString serverBufferIntegration(); + +protected: + void hardware_integration_client_backend(const QString &name); + void hardware_integration_server_backend(const QString &name); + +private: + QString m_client_buffer; + QString m_server_buffer; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/client/hardwareintegration/qwaylandserverbufferintegration.cpp b/src/client/hardwareintegration/qwaylandserverbufferintegration.cpp new file mode 100644 index 00000000..6e3abe91 --- /dev/null +++ b/src/client/hardwareintegration/qwaylandserverbufferintegration.cpp @@ -0,0 +1,41 @@ +#include "qwaylandserverbufferintegration_p.h" + +QT_BEGIN_NAMESPACE + +QWaylandServerBuffer::QWaylandServerBuffer() + : m_user_data(0) +{ +} + +QWaylandServerBuffer::~QWaylandServerBuffer() +{ +} + +QWaylandServerBuffer::Format QWaylandServerBuffer::format() const +{ + return m_format; +} + +QSize QWaylandServerBuffer::size() const +{ + return m_size; +} + +void QWaylandServerBuffer::setUserData(void *userData) +{ + m_user_data = userData; +} + +void *QWaylandServerBuffer::userData() const +{ + return m_user_data; +} + +QWaylandServerBufferIntegration::QWaylandServerBufferIntegration() +{ +} +QWaylandServerBufferIntegration::~QWaylandServerBufferIntegration() +{ +} + +QT_END_NAMESPACE diff --git a/src/client/hardwareintegration/qwaylandserverbufferintegration_p.h b/src/client/hardwareintegration/qwaylandserverbufferintegration_p.h new file mode 100644 index 00000000..18090a79 --- /dev/null +++ b/src/client/hardwareintegration/qwaylandserverbufferintegration_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSERVERBUFFERINTEGRATION_H +#define QWAYLANDSERVERBUFFERINTEGRATION_H + +#include <QtCore/QSize> +#include <QtGui/qopengl.h> + +#include <QtWaylandClient/private/qwayland-server-buffer-extension.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + +QT_BEGIN_NAMESPACE + +class QWaylandDisplay; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandServerBuffer +{ +public: + enum Format { + RGBA32, + A8 + }; + + QWaylandServerBuffer(); + virtual ~QWaylandServerBuffer(); + + virtual void bindTextureToBuffer() = 0; + + Format format() const; + QSize size() const; + + void setUserData(void *userData); + void *userData() const; + +protected: + Format m_format; + QSize m_size; + +private: + void *m_user_data; +}; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandServerBufferIntegration +{ +public: + QWaylandServerBufferIntegration(); + virtual ~QWaylandServerBufferIntegration(); + + virtual void initialize(QWaylandDisplay *display) = 0; + + virtual QWaylandServerBuffer *serverBuffer(struct qt_server_buffer *buffer) = 0; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/client/hardwareintegration/qwaylandserverbufferintegrationfactory.cpp b/src/client/hardwareintegration/qwaylandserverbufferintegrationfactory.cpp new file mode 100644 index 00000000..bd7661c2 --- /dev/null +++ b/src/client/hardwareintegration/qwaylandserverbufferintegrationfactory.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandserverbufferintegrationfactory_p.h" +#include "qwaylandserverbufferintegrationplugin_p.h" + +#include <QtCore/private/qfactoryloader_p.h> +#include <QtCore/QCoreApplication> +#include <QtCore/QDir> + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + (QWaylandServerBufferIntegrationFactoryInterface_iid, QLatin1String("/wayland-graphics-integration/client"), Qt::CaseInsensitive)) +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, + (QWaylandServerBufferIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) +#endif + +QStringList QWaylandServerBufferIntegrationFactory::keys(const QString &pluginPath) +{ +#ifndef QT_NO_LIBRARY + QStringList list; + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + list = directLoader()->keyMap().values(); + if (!list.isEmpty()) { + const QString postFix = QStringLiteral(" (from ") + + QDir::toNativeSeparators(pluginPath) + + QLatin1Char(')'); + const QStringList::iterator end = list.end(); + for (QStringList::iterator it = list.begin(); it != end; ++it) + (*it).append(postFix); + } + } + list.append(loader()->keyMap().values()); + return list; +#else + return QStringList(); +#endif +} + +QWaylandServerBufferIntegration *QWaylandServerBufferIntegrationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath) +{ +#ifndef QT_NO_LIBRARY + // Try loading the plugin from platformPluginPath first: + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + if (QWaylandServerBufferIntegration *ret = qLoadPlugin1<QWaylandServerBufferIntegration, QWaylandServerBufferIntegrationPlugin>(directLoader(), name, args)) + return ret; + } + if (QWaylandServerBufferIntegration *ret = qLoadPlugin1<QWaylandServerBufferIntegration, QWaylandServerBufferIntegrationPlugin>(loader(), name, args)) + return ret; +#endif + return 0; +} + +QT_END_NAMESPACE diff --git a/src/client/hardwareintegration/qwaylandserverbufferintegrationfactory_p.h b/src/client/hardwareintegration/qwaylandserverbufferintegrationfactory_p.h new file mode 100644 index 00000000..48e5e13d --- /dev/null +++ b/src/client/hardwareintegration/qwaylandserverbufferintegrationfactory_p.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSERVERBUFFERINTEGRATIONFACTORY_H +#define QWAYLANDSERVERBUFFERINTEGRATIONFACTORY_H + +#include <QtWaylandClient/private/qwaylandclientexport_p.h> +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE + +class QWaylandServerBufferIntegration; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandServerBufferIntegrationFactory +{ +public: + static QStringList keys(const QString &pluginPath = QString()); + static QWaylandServerBufferIntegration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString()); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDSERVERBUFFERINTEGRATIONFACTORY_H diff --git a/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin.cpp b/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin.cpp new file mode 100644 index 00000000..8fc31a88 --- /dev/null +++ b/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandserverbufferintegrationplugin_p.h" + +QT_BEGIN_NAMESPACE + +QWaylandServerBufferIntegrationPlugin::QWaylandServerBufferIntegrationPlugin(QObject *parent) + : QObject(parent) +{ +} +QWaylandServerBufferIntegrationPlugin::~QWaylandServerBufferIntegrationPlugin() +{ +} + +QT_END_NAMESPACE diff --git a/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin_p.h b/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin_p.h new file mode 100644 index 00000000..39d9a8ba --- /dev/null +++ b/src/client/hardwareintegration/qwaylandserverbufferintegrationplugin_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSERVERBUFFERINTEGRATIONPLUGIN_H +#define QWAYLANDSERVERBUFFERINTEGRATIONPLUGIN_H + +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + +#include <QtCore/qplugin.h> +#include <QtCore/qfactoryinterface.h> +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE + +class QWaylandServerBufferIntegration; + +#define QWaylandServerBufferIntegrationFactoryInterface_iid "org.qt-project.Qt.WaylandClient.QWaylandServerBufferIntegrationFactoryInterface.5.1" + +class Q_WAYLAND_CLIENT_EXPORT QWaylandServerBufferIntegrationPlugin : public QObject +{ + Q_OBJECT +public: + explicit QWaylandServerBufferIntegrationPlugin(QObject *parent = 0); + ~QWaylandServerBufferIntegrationPlugin(); + + virtual QWaylandServerBufferIntegration *create(const QString &key, const QStringList ¶mList) = 0; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDSERVERBUFFERINTEGRATIONPLUGIN_H diff --git a/src/plugins/platforms/wayland_common/qwaylandbuffer.h b/src/client/qwaylandbuffer_p.h index eee64856..2bb9990f 100644 --- a/src/plugins/platforms/wayland_common/qwaylandbuffer.h +++ b/src/client/qwaylandbuffer_p.h @@ -42,6 +42,8 @@ #ifndef QWAYLANDBUFFER_H #define QWAYLANDBUFFER_H +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + #include <QtCore/QSize> #include <QtCore/QRect> @@ -50,7 +52,7 @@ QT_BEGIN_NAMESPACE -class QWaylandBuffer { +class Q_WAYLAND_CLIENT_EXPORT QWaylandBuffer { public: QWaylandBuffer() { } virtual ~QWaylandBuffer() { } diff --git a/src/client/qwaylandclientexport_p.h b/src/client/qwaylandclientexport_p.h new file mode 100644 index 00000000..d9d6d7f7 --- /dev/null +++ b/src/client/qwaylandclientexport_p.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDCLIENTEXPORT_H +#define QWAYLANDCLIENTEXPORT_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +#if !defined(Q_WAYLAND_CLIENT_EXPORT) +# if defined(QT_SHARED) +# define Q_WAYLAND_CLIENT_EXPORT Q_DECL_EXPORT +# else +# define Q_WAYLAND_CLIENT_EXPORT +# endif +#endif + +QT_END_NAMESPACE + +#endif //QWAYLANDCLIENTEXPORT_H + diff --git a/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp b/src/client/qwaylandclipboard.cpp index 4cf055d3..c40f023b 100644 --- a/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp +++ b/src/client/qwaylandclipboard.cpp @@ -39,12 +39,12 @@ ** ****************************************************************************/ -#include "qwaylandclipboard.h" -#include "qwaylanddisplay.h" -#include "qwaylandinputdevice.h" -#include "qwaylanddataoffer.h" -#include "qwaylanddatasource.h" -#include "qwaylanddatadevicemanager.h" +#include "qwaylandclipboard_p.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandinputdevice_p.h" +#include "qwaylanddataoffer_p.h" +#include "qwaylanddatasource_p.h" +#include "qwaylanddatadevice_p.h" QT_BEGIN_NAMESPACE @@ -59,22 +59,36 @@ QWaylandClipboard::~QWaylandClipboard() QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode) { - Q_ASSERT(mode == QClipboard::Clipboard); - if (!mDisplay->dndSelectionHandler()) + if (mode != QClipboard::Clipboard) return 0; - QWaylandDataSource *transfer_source = mDisplay->dndSelectionHandler()->selectionTransferSource(); - if (transfer_source) { //if we have the keyboard focus and selectionTransferSource then we own the clipboard - return transfer_source->mimeData(); + QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice(); + if (!inputDevice || !inputDevice->dataDevice()) + return 0; + + QWaylandDataSource *source = inputDevice->dataDevice()->selectionSource(); + if (source) { + return source->mimeData(); } - return mDisplay->dndSelectionHandler()->selectionTransfer(); + + if (inputDevice->dataDevice()->selectionOffer()) + return inputDevice->dataDevice()->selectionOffer()->mimeData(); + + return 0; } void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) { - Q_ASSERT(mode == QClipboard::Clipboard); - if (mDisplay->dndSelectionHandler()) - mDisplay->dndSelectionHandler()->createAndSetSelectionSource(data,mode); + if (mode != QClipboard::Clipboard) + return; + + QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice(); + if (!inputDevice || !inputDevice->dataDevice()) + return; + + inputDevice->dataDevice()->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(), data) : 0); + + emitChanged(mode); } bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const @@ -82,4 +96,16 @@ bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const return mode == QClipboard::Clipboard; } +bool QWaylandClipboard::ownsMode(QClipboard::Mode mode) const +{ + if (mode != QClipboard::Clipboard) + return false; + + QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice(); + if (!inputDevice || !inputDevice->dataDevice()) + return false; + + return inputDevice->dataDevice()->selectionSource() != 0; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandclipboard.h b/src/client/qwaylandclipboard_p.h index a8f52e10..0dea3371 100644 --- a/src/plugins/platforms/wayland_common/qwaylandclipboard.h +++ b/src/client/qwaylandclipboard_p.h @@ -45,22 +45,23 @@ #include <qpa/qplatformclipboard.h> #include <QtCore/QVariant> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + QT_BEGIN_NAMESPACE class QWaylandDisplay; -class QWaylandClipboard : public QPlatformClipboard +class Q_WAYLAND_CLIENT_EXPORT QWaylandClipboard : public QPlatformClipboard { public: QWaylandClipboard(QWaylandDisplay *display); ~QWaylandClipboard(); - QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); - void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); - bool supportsMode(QClipboard::Mode mode) const; - - QVariant retrieveData(const QString &mimeType, QVariant::Type type) const; + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; private: QWaylandDisplay *mDisplay; diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp index e0abba30..90789b0d 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp +++ b/src/client/qwaylandcursor.cpp @@ -39,12 +39,12 @@ ** ****************************************************************************/ -#include "qwaylandcursor.h" +#include "qwaylandcursor_p.h" -#include "qwaylanddisplay.h" -#include "qwaylandinputdevice.h" -#include "qwaylandscreen.h" -#include "qwaylandshmbackingstore.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandinputdevice_p.h" +#include "qwaylandscreen_p.h" +#include "qwaylandshmbackingstore_p.h" #include <QtGui/QImageReader> #include <QDebug> @@ -133,6 +133,11 @@ void QWaylandDisplay::setCursor(struct wl_buffer *buffer, struct wl_cursor_image } } +QWaylandInputDevice *QWaylandDisplay::defaultInputDevice() const +{ + return mInputDevices.isEmpty() ? 0 : mInputDevices.first(); +} + void QWaylandCursor::pointerEvent(const QMouseEvent &event) { mLastPos = event.globalPos(); diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.h b/src/client/qwaylandcursor_p.h index ceb6d748..282ac685 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.h +++ b/src/client/qwaylandcursor_p.h @@ -43,7 +43,8 @@ #define QWAYLANDCURSOR_H #include <qpa/qplatformcursor.h> -#include <QMap> +#include <QtCore/QMap> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> struct wl_cursor; struct wl_cursor_image; @@ -54,7 +55,7 @@ QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandScreen; -class QWaylandCursor : public QPlatformCursor +class Q_WAYLAND_CLIENT_EXPORT QWaylandCursor : public QPlatformCursor { public: QWaylandCursor(QWaylandScreen *screen); diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp new file mode 100644 index 00000000..2d6a6f4b --- /dev/null +++ b/src/client/qwaylanddatadevice.cpp @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylanddatadevice_p.h" + +#include "qwaylanddatadevicemanager_p.h" +#include "qwaylanddataoffer_p.h" +#include "qwaylanddatasource_p.h" +#include "qwaylanddnd_p.h" +#include "qwaylandinputdevice_p.h" + +#include <QtCore/QMimeData> +#include <QtGui/QGuiApplication> +#include <QtGui/private/qguiapplication_p.h> + +#include <qpa/qplatformclipboard.h> +#include <qpa/qplatformdrag.h> +#include <qpa/qwindowsysteminterface.h> + +#include <QDebug> + +QWaylandDataDevice::QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWaylandInputDevice *inputDevice) + : QtWayland::wl_data_device(manager->get_data_device(inputDevice->wl_seat())) + , m_display(manager->display()) + , m_enterSerial(0) + , m_dragWindow(0) + , m_dragPoint() + , m_dragOffer() + , m_selectionOffer() +{ +} + +QWaylandDataDevice::~QWaylandDataDevice() +{ +} + +QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const +{ + return m_selectionOffer.data(); +} + +QWaylandDataSource *QWaylandDataDevice::selectionSource() const +{ + return m_selectionSource.data(); +} + +void QWaylandDataDevice::setSelectionSource(QWaylandDataSource *source) +{ + m_selectionSource.reset(source); + set_selection(source ? source->object() : 0, 0 /* TODO m_display->serial() */); +} + +QWaylandDataOffer *QWaylandDataDevice::dragOffer() const +{ + return m_dragOffer.data(); +} + +void QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) +{ + m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData)); + + QWaylandWindow *origin = m_display->currentInputDevice()->pointerFocus(); + + start_drag(m_dragSource->object(), origin->object(), icon->object(), m_display->currentInputDevice()->serial()); +} + +void QWaylandDataDevice::cancelDrag() +{ + m_dragSource.reset(); +} + +void QWaylandDataDevice::data_device_data_offer(struct ::wl_data_offer *id) +{ + new QWaylandDataOffer(m_display, id); +} + +void QWaylandDataDevice::data_device_drop() +{ + QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag(); + + qDebug() << Q_FUNC_INFO << drag << m_dragOffer.data(); + + QMimeData *dragData; + Qt::DropActions supportedActions; + if (drag) { + dragData = drag->mimeData(); + supportedActions = drag->supportedActions(); + } else if (m_dragOffer) { + dragData = m_dragOffer->mimeData(); + supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; + } else { + return; + } + + QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(m_dragWindow, dragData, m_dragPoint, supportedActions); + + if (drag) { + static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag(response); + } +} + +void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer *id) +{ + m_enterSerial = serial; + m_dragWindow = QWaylandWindow::fromWlSurface(surface)->window(); + m_dragPoint = QPoint(wl_fixed_to_int(x), wl_fixed_to_int(y)); + + QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag(); + + QMimeData *dragData; + Qt::DropActions supportedActions; + if (drag) { + dragData = drag->mimeData(); + supportedActions = drag->supportedActions(); + } else { + m_dragOffer.reset(static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id))); + if (m_dragOffer) { + dragData = m_dragOffer->mimeData(); + supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; + } + } + + const QPlatformDragQtResponse &response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions); + + if (drag) { + static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); + } else { + if (response.isAccepted()) { + wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData()); + } else { + wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, 0); + } + } +} + +void QWaylandDataDevice::data_device_leave() +{ + QWindowSystemInterface::handleDrag(m_dragWindow, 0, QPoint(), Qt::IgnoreAction); + + QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag(); + if (!drag) { + m_dragOffer.reset(); + } +} + +void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixed_t y) +{ + Q_UNUSED(time); + + QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag(); + + if (!drag && !m_dragOffer) + return; + + m_dragPoint = QPoint(wl_fixed_to_int(x), wl_fixed_to_int(y)); + + QMimeData *dragData; + Qt::DropActions supportedActions; + if (drag) { + dragData = drag->mimeData(); + supportedActions = drag->supportedActions(); + } else { + dragData = m_dragOffer->mimeData(); + supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; + } + + QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions); + + if (drag) { + static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response); + } else { + if (response.isAccepted()) { + wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, m_dragOffer->firstFormat().toUtf8().constData()); + } else { + wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, 0); + } + } +} + +void QWaylandDataDevice::data_device_selection(wl_data_offer *id) +{ + if (id) + m_selectionOffer.reset(static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id))); + else + m_selectionOffer.reset(); + + QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard); +} + +void QWaylandDataDevice::selectionSourceCancelled() +{ + m_selectionSource.reset(); + QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard); +} + +void QWaylandDataDevice::dragSourceCancelled() +{ + m_dragSource.reset(); + +} + +void QWaylandDataDevice::dragSourceTargetChanged(const QString &mimeType) +{ + static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->updateTarget(mimeType); +} diff --git a/src/client/qwaylanddatadevice_p.h b/src/client/qwaylanddatadevice_p.h new file mode 100644 index 00000000..4e98424e --- /dev/null +++ b/src/client/qwaylanddatadevice_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDDATADEVICE_H +#define QWAYLANDDATADEVICE_H + +#include "qwaylanddisplay_p.h" + +QT_BEGIN_NAMESPACE + +class QMimeData; +class QWaylandDataDeviceManager; +class QWaylandDataOffer; +class QWaylandDataSource; +class QWindow; + +class QWaylandDataDevice : public QObject, public QtWayland::wl_data_device +{ + Q_OBJECT +public: + QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWaylandInputDevice *inputDevice); + ~QWaylandDataDevice(); + + QWaylandDataOffer *selectionOffer() const; + QWaylandDataSource *selectionSource() const; + void setSelectionSource(QWaylandDataSource *source); + + QWaylandDataOffer *dragOffer() const; + void startDrag(QMimeData *mimeData, QWaylandWindow *icon); + void cancelDrag(); + +protected: + void data_device_data_offer(struct ::wl_data_offer *id) Q_DECL_OVERRIDE; + void data_device_drop() Q_DECL_OVERRIDE; + void data_device_enter(uint32_t serial, struct ::wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct ::wl_data_offer *id) Q_DECL_OVERRIDE; + void data_device_leave() Q_DECL_OVERRIDE; + void data_device_motion(uint32_t time, wl_fixed_t x, wl_fixed_t y) Q_DECL_OVERRIDE; + void data_device_selection(struct ::wl_data_offer *id) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void selectionSourceCancelled(); + void dragSourceCancelled(); + void dragSourceTargetChanged(const QString &mimeType); + +private: + QWaylandDisplay *m_display; + + uint32_t m_enterSerial; + QWindow *m_dragWindow; + QPoint m_dragPoint; + QScopedPointer<QWaylandDataOffer> m_dragOffer; + QScopedPointer<QWaylandDataOffer> m_selectionOffer; + QScopedPointer<QWaylandDataSource> m_selectionSource; + + QScopedPointer<QWaylandDataSource> m_dragSource; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDDATADEVICE_H diff --git a/src/plugins/platforms/wayland_common/qwaylanddnd.cpp b/src/client/qwaylanddatadevicemanager.cpp index 0dc80e63..5de28c00 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddnd.cpp +++ b/src/client/qwaylanddatadevicemanager.cpp @@ -39,59 +39,42 @@ ** ****************************************************************************/ -#include "qwaylanddnd.h" +#include "qwaylanddatadevicemanager_p.h" -#include "qwaylanddatadevicemanager.h" +#include "qwaylandinputdevice_p.h" +#include "qwaylanddatadevice_p.h" +#include "qwaylanddataoffer_p.h" -QT_BEGIN_NAMESPACE - -QWaylandDrag::QWaylandDrag(QWaylandDisplay *display) - : m_display(display) -{ - -} - -QWaylandDrag::~QWaylandDrag() -{ - -} +#include <QtCore/QDebug> -QMimeData * QWaylandDrag::platformDropData() -{ - return m_display->dndSelectionHandler()->dragMime(); -} - -Qt::DropAction QWaylandDrag::drag(QDrag *m_drag) -{ - Q_UNUSED(m_drag); -// m_display->dndSelectionHandler()->createAndSetDrag(drag); - return Qt::IgnoreAction; -} +QT_BEGIN_NAMESPACE -void QWaylandDrag::move(const QMouseEvent *me) +QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id) + : wl_data_device_manager(display->wl_registry(), id) + , m_display(display) { - Q_UNUSED(me); - qFatal("This function should not be called"); + // Create transfer devices for all input devices. + // ### This only works if we get the global before all devices and is surely wrong when hotplugging. + QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices(); + for (int i = 0; i < inputDevices.size();i++) { + inputDevices.at(i)->setDataDevice(getDataDevice(inputDevices.at(i))); + } } -bool QWaylandDrag::canDrop() const +QWaylandDataDeviceManager::~QWaylandDataDeviceManager() { - return false; + wl_data_device_manager_destroy(object()); } -void QWaylandDrag::drop(const QMouseEvent *me) +QWaylandDataDevice *QWaylandDataDeviceManager::getDataDevice(QWaylandInputDevice *inputDevice) { - Q_UNUSED(me); + return new QWaylandDataDevice(this, inputDevice); } -void QWaylandDrag::cancel() +QWaylandDisplay *QWaylandDataDeviceManager::display() const { - m_display->dndSelectionHandler()->cancelDrag(); + return m_display; } -Qt::DropAction QWaylandDrag::executedDropAction() const -{ - return Qt::CopyAction; -} QT_END_NAMESPACE diff --git a/src/client/qwaylanddatadevicemanager_p.h b/src/client/qwaylanddatadevicemanager_p.h new file mode 100644 index 00000000..6e2beafb --- /dev/null +++ b/src/client/qwaylanddatadevicemanager_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDDATADEVICEMANAGER_H +#define QWAYLANDDATADEVICEMANAGER_H + +#include <QtWaylandClient/private/qwaylanddisplay_p.h> + +QT_BEGIN_NAMESPACE + +class QWaylandDataDevice; +class QWaylandDataSource; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandDataDeviceManager : public QtWayland::wl_data_device_manager +{ +public: + QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id); + ~QWaylandDataDeviceManager(); + + QWaylandDataDevice *getDataDevice(QWaylandInputDevice *inputDevice); + + QWaylandDisplay *display() const; + +private: + struct wl_data_device_manager *m_data_device_manager; + QWaylandDisplay *m_display; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDDATADEVICEMANAGER_H diff --git a/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp index d98cfc2a..adaeb521 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp +++ b/src/client/qwaylanddataoffer.cpp @@ -39,9 +39,10 @@ ** ****************************************************************************/ -#include "qwaylanddataoffer.h" -#include "qwaylanddatadevicemanager.h" +#include "qwaylanddataoffer_p.h" +#include "qwaylanddatadevicemanager_p.h" +#include <QtCore/private/qcore_unix_p.h> #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformclipboard.h> @@ -49,99 +50,90 @@ QT_BEGIN_NAMESPACE -void QWaylandDataOffer::offer_sync_callback(void *data, - struct wl_callback *callback, - uint32_t time) +QWaylandDataOffer::QWaylandDataOffer(QWaylandDisplay *display, struct ::wl_data_offer *offer) + : QtWayland::wl_data_offer(offer) + , m_mimeData(new QWaylandMimeData(this, display)) { - Q_UNUSED(time); - QWaylandDataOffer *mime = static_cast<QWaylandDataOffer *>(data); - if (mime->m_receiveSyncCallback == callback) { - mime->m_receiveSyncCallback = 0; - wl_callback_destroy(callback); - } } -const struct wl_callback_listener QWaylandDataOffer::offer_sync_callback_listener = { - QWaylandDataOffer::offer_sync_callback -}; +QWaylandDataOffer::~QWaylandDataOffer() +{ + destroy(); +} + -void QWaylandDataOffer::offer(void *data, - struct wl_data_offer *wl_data_offer, - const char *type) +QString QWaylandDataOffer::firstFormat() const { - Q_UNUSED(wl_data_offer); + if (m_mimeData->formats().isEmpty()) + return QString(); - QWaylandDataOffer *data_offer = static_cast<QWaylandDataOffer *>(data); + return m_mimeData->formats().first(); +} - if (!data_offer->m_receiveSyncCallback) { - data_offer->m_receiveSyncCallback = wl_display_sync(data_offer->m_display->wl_display()); - wl_callback_add_listener(data_offer->m_receiveSyncCallback, &offer_sync_callback_listener, data_offer); - } +QMimeData *QWaylandDataOffer::mimeData() +{ + return m_mimeData.data(); +} - data_offer->m_offered_mime_types.append(QString::fromLocal8Bit(type)); -// qDebug() << data_offer->m_offered_mime_types; +void QWaylandDataOffer::data_offer_offer(const QString &mime_type) +{ + m_mimeData->appendFormat(mime_type); } -const struct wl_data_offer_listener QWaylandDataOffer::data_offer_listener = { - QWaylandDataOffer::offer -}; +QWaylandMimeData::QWaylandMimeData(QWaylandDataOffer *dataOffer, QWaylandDisplay *display) + : QInternalMimeData() + , m_dataOffer(dataOffer) + , m_display(display) + , m_offered_mime_types() +{ +} -QWaylandDataOffer::QWaylandDataOffer(QWaylandDisplay *display, struct wl_data_offer *data_offer) - : m_display(display) - , m_receiveSyncCallback(0) +QWaylandMimeData::~QWaylandMimeData() { - m_data_offer = data_offer; - wl_data_offer_set_user_data(m_data_offer,this); - wl_data_offer_add_listener(m_data_offer,&data_offer_listener,this); } -QWaylandDataOffer::~QWaylandDataOffer() +void QWaylandMimeData::appendFormat(const QString &mimeType) { - wl_data_offer_destroy(m_data_offer); + m_offered_mime_types.append(mimeType); } -bool QWaylandDataOffer::hasFormat_sys(const QString &mimeType) const +bool QWaylandMimeData::hasFormat_sys(const QString &mimeType) const { return m_offered_mime_types.contains(mimeType); } -QStringList QWaylandDataOffer::formats_sys() const +QStringList QWaylandMimeData::formats_sys() const { return m_offered_mime_types; } -QVariant QWaylandDataOffer::retrieveData_sys(const QString &mimeType, QVariant::Type type) const +QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const { Q_UNUSED(type); + if (m_offered_mime_types.isEmpty()) return QVariant(); int pipefd[2]; - if (pipe(pipefd) == -1) { + if (qt_safe_pipe(pipefd, O_CLOEXEC) == -1) { qWarning("QWaylandMimeData: pipe() failed"); return QVariant(); } - QByteArray mimeTypeBa = mimeType.toLatin1(); - wl_data_offer_receive(m_data_offer,mimeTypeBa.constData(),pipefd[1]); - - m_display->forceRoundTrip(); + m_dataOffer->receive(mimeType, pipefd[1]); close(pipefd[1]); +// m_display->forceRoundTrip(); + QByteArray content; - char buf[256]; + char buf[4096]; int n; while ((n = QT_READ(pipefd[0], &buf, sizeof buf)) > 0) { content.append(buf, n); } - close(pipefd[0]); - return content; -} -struct wl_data_offer *QWaylandDataOffer::handle() const -{ - return m_data_offer; + return content; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddataoffer.h b/src/client/qwaylanddataoffer_p.h index abc7c690..ab34e177 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddataoffer.h +++ b/src/client/qwaylanddataoffer_p.h @@ -42,47 +42,49 @@ #ifndef QWAYLANDDATAOFFER_H #define QWAYLANDDATAOFFER_H -#include <QString> -#include <QByteArray> -#include <QMimeData> +#include "qwaylanddisplay_p.h" #include <QtGui/private/qdnd_p.h> -#include <QtGui/QClipboard> - -#include <stdint.h> - -struct wl_callback; -struct wl_callback_listener; -struct wl_data_offer; -struct wl_data_offer_listener; QT_BEGIN_NAMESPACE class QWaylandDisplay; +class QWaylandMimeData; -class QWaylandDataOffer : public QInternalMimeData +class Q_WAYLAND_CLIENT_EXPORT QWaylandDataOffer : public QtWayland::wl_data_offer { public: - QWaylandDataOffer(QWaylandDisplay *display, struct wl_data_offer *offer); + explicit QWaylandDataOffer(QWaylandDisplay *display, struct ::wl_data_offer *offer); ~QWaylandDataOffer(); - bool hasFormat_sys(const QString &mimeType) const; - QStringList formats_sys() const; - QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const; + QString firstFormat() const; + + QMimeData *mimeData(); + +protected: + void data_offer_offer(const QString &mime_type) Q_DECL_OVERRIDE; - struct wl_data_offer *handle() const; private: + QScopedPointer<QWaylandMimeData> m_mimeData; +}; - struct wl_data_offer *m_data_offer; - QWaylandDisplay *m_display; - QStringList m_offered_mime_types; - wl_callback *m_receiveSyncCallback; - static void offer(void *data, struct wl_data_offer *wl_data_offer, const char *type); - static const struct wl_data_offer_listener data_offer_listener; +class QWaylandMimeData : public QInternalMimeData { +public: + explicit QWaylandMimeData(QWaylandDataOffer *dataOffer, QWaylandDisplay *display); + ~QWaylandMimeData(); + + void appendFormat(const QString &mimeType); + +protected: + bool hasFormat_sys(const QString &mimeType) const Q_DECL_OVERRIDE; + QStringList formats_sys() const Q_DECL_OVERRIDE; + QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const Q_DECL_OVERRIDE; - static void offer_sync_callback(void *data, struct wl_callback *wl_callback, uint32_t time); - static const struct wl_callback_listener offer_sync_callback_listener; +private: + mutable QWaylandDataOffer *m_dataOffer; + QWaylandDisplay *m_display; + QStringList m_offered_mime_types; }; QT_END_NAMESPACE diff --git a/src/client/qwaylanddatasource.cpp b/src/client/qwaylanddatasource.cpp new file mode 100644 index 00000000..3376db56 --- /dev/null +++ b/src/client/qwaylanddatasource.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylanddatasource_p.h" +#include "qwaylanddataoffer_p.h" +#include "qwaylanddatadevicemanager_p.h" +#include "qwaylandinputdevice_p.h" +#include "qwaylandmimehelper.h" + +#include <QtCore/QFile> + +#include <QtCore/QDebug> + +#include <unistd.h> + +QT_BEGIN_NAMESPACE + +QWaylandDataSource::QWaylandDataSource(QWaylandDataDeviceManager *dataDeviceManager, QMimeData *mimeData) + : QtWayland::wl_data_source(dataDeviceManager->create_data_source()) + , m_mime_data(mimeData) +{ + if (!mimeData) + return; + Q_FOREACH (const QString &format, mimeData->formats()) { + offer(format); + } +} + +QWaylandDataSource::~QWaylandDataSource() +{ + destroy(); +} + +QMimeData * QWaylandDataSource::mimeData() const +{ + return m_mime_data; +} + +void QWaylandDataSource::data_source_cancelled() +{ + Q_EMIT cancelled(); +} + +void QWaylandDataSource::data_source_send(const QString &mime_type, int32_t fd) +{ + QByteArray content = QWaylandMimeHelper::getByteArray(m_mime_data, mime_type); + if (!content.isEmpty()) { + write(fd, content.constData(), content.size()); + } + close(fd); +} + +void QWaylandDataSource::data_source_target(const QString &mime_type) +{ + Q_EMIT targetChanged(mime_type); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddatasource.h b/src/client/qwaylanddatasource_p.h index 8fdf0636..9568f507 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddatasource.h +++ b/src/client/qwaylanddatasource_p.h @@ -42,36 +42,36 @@ #ifndef QWAYLANDDATASOURCE_H #define QWAYLANDDATASOURCE_H -#include "qwaylanddatadevicemanager.h" +#include <QtWaylandClient/private/qwaylanddatadevicemanager_p.h> -#include <wayland-client-protocol.h> +#include <QtWaylandClient/private/wayland-wayland-client-protocol.h> QT_BEGIN_NAMESPACE -class QWaylandDataSource +class QMimeData; +class QWaylandDataDeviceManager; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandDataSource : public QObject, public QtWayland::wl_data_source { + Q_OBJECT public: - QWaylandDataSource(QWaylandDataDeviceManager *dndSelectionHandler, QMimeData *mimeData); + QWaylandDataSource(QWaylandDataDeviceManager *dataDeviceManager, QMimeData *mimeData); ~QWaylandDataSource(); QMimeData *mimeData() const; - struct wl_data_source *handle() const; +Q_SIGNALS: + void targetChanged(const QString &mime_type); + void cancelled(); + +protected: + void data_source_cancelled() Q_DECL_OVERRIDE; + void data_source_send(const QString &mime_type, int32_t fd) Q_DECL_OVERRIDE; + void data_source_target(const QString &mime_type) Q_DECL_OVERRIDE; + private: - struct wl_data_source *m_data_source; QWaylandDisplay *m_display; QMimeData *m_mime_data; - - static void data_source_target(void *data, - struct wl_data_source *data_source, - const char *mime_type); - static void data_source_send(void *data, - struct wl_data_source *data_source, - const char *mime_type, - int32_t fd); - static void data_source_cancelled(void *data, - struct wl_data_source *data_source); - static const struct wl_data_source_listener data_source_listener; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp b/src/client/qwaylanddecoration.cpp index a4b97833..8e7d0314 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp +++ b/src/client/qwaylanddecoration.cpp @@ -39,12 +39,12 @@ ** ****************************************************************************/ -#include "qwaylanddecoration.h" +#include "qwaylanddecoration_p.h" -#include "qwaylandwindow.h" -#include "qwaylandshellsurface.h" -#include "qwaylandinputdevice.h" -#include "qwaylandscreen.h" +#include "qwaylandwindow_p.h" +#include "qwaylandshellsurface_p.h" +#include "qwaylandinputdevice_p.h" +#include "qwaylandscreen_p.h" #include <QtGui/QGuiApplication> #include <QtGui/QImage> @@ -327,6 +327,7 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo processMouseRight(inputDevice,local,b,mods); } else { m_wayland_window->restoreMouseCursor(inputDevice); + m_mouseButtons = b; return false; } diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.h b/src/client/qwaylanddecoration_p.h index 5efeab22..3f53721f 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.h +++ b/src/client/qwaylanddecoration_p.h @@ -49,6 +49,7 @@ #include <QtGui/QColor> #include <QtGui/QStaticText> #include <QtGui/QImage> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> #include <wayland-client.h> @@ -64,7 +65,7 @@ class QWaylandScreen; class QWaylandWindow; class QWaylandInputDevice; -class QWaylandDecoration +class Q_WAYLAND_CLIENT_EXPORT QWaylandDecoration { public: QWaylandDecoration(QWaylandWindow *window); diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index 6cc01d0e..ec439b5d 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -39,33 +39,36 @@ ** ****************************************************************************/ -#include "qwaylanddisplay.h" +#include "qwaylanddisplay_p.h" -#include "qwaylandeventthread.h" -#include "qwaylandwindow.h" -#include "qwaylandscreen.h" -#include "qwaylandcursor.h" -#include "qwaylandinputdevice.h" -#include "qwaylandclipboard.h" -#include "qwaylanddatadevicemanager.h" +#include "qwaylandeventthread_p.h" +#include "qwaylandintegration_p.h" +#include "qwaylandwindow_p.h" +#include "qwaylandscreen_p.h" +#include "qwaylandcursor_p.h" +#include "qwaylandinputdevice_p.h" +#include "qwaylandclipboard_p.h" +#include "qwaylanddatadevicemanager_p.h" +#include "qwaylandhardwareintegration_p.h" -#ifdef QT_WAYLAND_GL_SUPPORT -#include "qwaylandglintegration.h" -#endif -#include "qwaylandwindowmanagerintegration.h" +#include "qwaylandwindowmanagerintegration_p.h" -#include "qwaylandextendedoutput.h" -#include "qwaylandextendedsurface.h" -#include "qwaylandsubsurface.h" -#include "qwaylandtouch.h" -#include "qwaylandqtkey.h" +#include "qwaylandextendedoutput_p.h" +#include "qwaylandextendedsurface_p.h" +#include "qwaylandsubsurface_p.h" +#include "qwaylandtouch_p.h" +#include "qwaylandqtkey_p.h" + +#include <QtWaylandClient/private/qwayland-text.h> #include <QtCore/QAbstractEventDispatcher> #include <QtGui/private/qguiapplication_p.h> #include <QtCore/QDebug> +#include <errno.h> + QT_BEGIN_NAMESPACE struct wl_surface *QWaylandDisplay::createSurface(void *handle) @@ -75,16 +78,14 @@ struct wl_surface *QWaylandDisplay::createSurface(void *handle) return surface; } -#ifdef QT_WAYLAND_GL_SUPPORT -QWaylandGLIntegration * QWaylandDisplay::eglIntegration() +QWaylandClientBufferIntegration * QWaylandDisplay::clientBufferIntegration() const { - return mEglIntegration; + return mWaylandIntegration->clientBufferIntegration(); } -#endif -QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() +QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() const { - return mWindowManagerIntegration; + return mWindowManagerIntegration.data(); } QWaylandInputDevice *QWaylandDisplay::lastKeyboardFocusInputDevice() const @@ -99,14 +100,17 @@ void QWaylandDisplay::setLastKeyboardFocusInputDevice(QWaylandInputDevice *devic static QWaylandDisplay *display = 0; -QWaylandDisplay::QWaylandDisplay() - : mLastKeyboardFocusInputDevice(0) +QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) + : mWaylandIntegration(waylandIntegration) + , mLastKeyboardFocusInputDevice(0) , mDndSelectionHandler(0) , mWindowExtension(0) , mSubSurfaceExtension(0) , mOutputExtension(0) , mTouchExtension(0) , mQtKeyExtension(0) + , mTextInputManager(0) + , mHardwareIntegration(0) { display = this; qRegisterMetaType<uint32_t>("uint32_t"); @@ -127,34 +131,17 @@ QWaylandDisplay::QWaylandDisplay() init(registry); - QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; - connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(flushRequests())); connect(mEventThreadObject, SIGNAL(newEventsRead()), this, SLOT(flushRequests())); -#ifdef QT_WAYLAND_GL_SUPPORT - mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); -#endif - - mWindowManagerIntegration = new QWaylandWindowManagerIntegration(this); + mWindowManagerIntegration.reset(new QWaylandWindowManagerIntegration(this)); blockingReadEvents(); -#ifdef QT_WAYLAND_GL_SUPPORT - mEglIntegration->initialize(); - - flushRequests(); - while (mEglIntegration->waitingForEvents()) - blockingReadEvents(); -#endif - waitForScreens(); } QWaylandDisplay::~QWaylandDisplay(void) { -#ifdef QT_WAYLAND_GL_SUPPORT - delete mEglIntegration; -#endif mEventThread->quit(); mEventThread->wait(); delete mEventThreadObject; @@ -162,15 +149,20 @@ QWaylandDisplay::~QWaylandDisplay(void) void QWaylandDisplay::flushRequests() { - if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) == -1 && errno == EPIPE) - QCoreApplication::quit(); + if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) == -1 && errno == EPIPE) { + qWarning("The Wayland connection broke. Did the Wayland compositor die?"); + ::exit(1); + } wl_display_flush(mDisplay); } + void QWaylandDisplay::blockingReadEvents() { - if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1 && errno == EPIPE) - QCoreApplication::quit(); + if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1 && errno == EPIPE) { + qWarning("The Wayland connection broke. Did the Wayland compositor die?"); + ::exit(1); + } } QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const @@ -214,31 +206,35 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin struct ::wl_registry *registry = object(); - if (interface == "wl_output") { + if (interface == QStringLiteral("wl_output")) { mScreens.append(new QWaylandScreen(this, id)); - } else if (interface == "wl_compositor") { + } else if (interface == QStringLiteral("wl_compositor")) { mCompositor.init(registry, id); - } else if (interface == "wl_shm") { + } else if (interface == QStringLiteral("wl_shm")) { mShm = static_cast<struct wl_shm *>(wl_registry_bind(registry, id, &wl_shm_interface,1)); - } else if (interface == "wl_shell"){ - mShell = new QtWayland::wl_shell(registry, id); - } else if (interface == "wl_seat") { + } else if (interface == QStringLiteral("wl_shell")){ + mShell.reset(new QtWayland::wl_shell(registry, id)); + } else if (interface == QStringLiteral("wl_seat")) { QWaylandInputDevice *inputDevice = new QWaylandInputDevice(this, id); mInputDevices.append(inputDevice); - } else if (interface == "wl_data_device_manager") { - mDndSelectionHandler = new QWaylandDataDeviceManager(this, id); - } else if (interface == "qt_output_extension") { - mOutputExtension = new QtWayland::qt_output_extension(registry, id); + } else if (interface == QStringLiteral("wl_data_device_manager")) { + mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this, id)); + } else if (interface == QStringLiteral("qt_output_extension")) { + mOutputExtension.reset(new QtWayland::qt_output_extension(registry, id)); foreach (QPlatformScreen *screen, screens()) static_cast<QWaylandScreen *>(screen)->createExtendedOutput(); - } else if (interface == "qt_surface_extension") { - mWindowExtension = new QtWayland::qt_surface_extension(registry, id); - } else if (interface == "qt_sub_surface_extension") { - mSubSurfaceExtension = new QtWayland::qt_sub_surface_extension(registry, id); - } else if (interface == "qt_touch_extension") { - mTouchExtension = new QWaylandTouchExtension(this, id); - } else if (interface == "qt_key_extension") { - mQtKeyExtension = new QWaylandQtKeyExtension(this, id); + } else if (interface == QStringLiteral("qt_surface_extension")) { + mWindowExtension.reset(new QtWayland::qt_surface_extension(registry, id)); + } else if (interface == QStringLiteral("qt_sub_surface_extension")) { + mSubSurfaceExtension.reset(new QtWayland::qt_sub_surface_extension(registry, id)); + } else if (interface == QStringLiteral("qt_touch_extension")) { + mTouchExtension.reset(new QWaylandTouchExtension(this, id)); + } else if (interface == QStringLiteral("qt_key_extension")) { + mQtKeyExtension.reset(new QWaylandQtKeyExtension(this, id)); + } else if (interface == QStringLiteral("wl_text_input_manager")) { + mTextInputManager.reset(new QtWayland::wl_text_input_manager(registry, id)); + } else if (interface == QStringLiteral("qt_hardware_integration")) { + mHardwareIntegration.reset(new QWaylandHardwareIntegration(registry, id)); } foreach (Listener l, mRegistryListeners) diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.h b/src/client/qwaylanddisplay_p.h index 6b2cc89d..5ba4f51b 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.h +++ b/src/client/qwaylanddisplay_p.h @@ -48,7 +48,9 @@ #include <QtCore/QWaitCondition> #include <wayland-client.h> -#include <qwayland-wayland.h> + +#include <QtWaylandClient/private/qwayland-wayland.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> struct wl_cursor_image; @@ -60,19 +62,22 @@ class QSocketNotifier; class QWaylandBuffer; class QPlatformScreen; class QWaylandScreen; -class QWaylandGLIntegration; +class QWaylandClientBufferIntegration; class QWaylandWindowManagerIntegration; class QWaylandDataDeviceManager; class QWaylandTouchExtension; class QWaylandQtKeyExtension; class QWaylandWindow; class QWaylandEventThread; +class QWaylandIntegration; +class QWaylandHardwareIntegration; namespace QtWayland { class qt_output_extension; class qt_shell; class qt_sub_surface_extension; class qt_surface_extension; + class wl_text_input_manager; } typedef void (*RegistryListener)(void *data, @@ -81,11 +86,11 @@ typedef void (*RegistryListener)(void *data, const QString &interface, uint32_t version); -class QWaylandDisplay : public QObject, public QtWayland::wl_registry { +class Q_WAYLAND_CLIENT_EXPORT QWaylandDisplay : public QObject, public QtWayland::wl_registry { Q_OBJECT public: - QWaylandDisplay(void); + QWaylandDisplay(QWaylandIntegration *waylandIntegration); ~QWaylandDisplay(void); QList<QPlatformScreen *> screens() const { return mScreens; } @@ -94,11 +99,9 @@ public: struct wl_surface *createSurface(void *handle); -#ifdef QT_WAYLAND_GL_SUPPORT - QWaylandGLIntegration *eglIntegration(); -#endif + QWaylandClientBufferIntegration *clientBufferIntegration() const; - QWaylandWindowManagerIntegration *windowManagerIntegration(); + QWaylandWindowManagerIntegration *windowManagerIntegration() const; void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); @@ -109,19 +112,23 @@ public: const struct wl_compositor *wl_compositor() const { return mCompositor.object(); } QtWayland::wl_compositor *compositor() { return &mCompositor; } - QtWayland::wl_shell *shell() { return mShell; } + QtWayland::wl_shell *shell() { return mShell.data(); } QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; } + QWaylandInputDevice *defaultInputDevice() const; + QWaylandInputDevice *currentInputDevice() const { return defaultInputDevice(); } QWaylandInputDevice *lastKeyboardFocusInputDevice() const; void setLastKeyboardFocusInputDevice(QWaylandInputDevice *device); - QWaylandDataDeviceManager *dndSelectionHandler() const { return mDndSelectionHandler; } + QWaylandDataDeviceManager *dndSelectionHandler() const { return mDndSelectionHandler.data(); } - QtWayland::qt_surface_extension *windowExtension() const { return mWindowExtension; } - QtWayland::qt_sub_surface_extension *subSurfaceExtension() const { return mSubSurfaceExtension; } - QtWayland::qt_output_extension *outputExtension() const { return mOutputExtension; } - QWaylandTouchExtension *touchExtension() const { return mTouchExtension; } + QtWayland::qt_surface_extension *windowExtension() const { return mWindowExtension.data(); } + QtWayland::qt_sub_surface_extension *subSurfaceExtension() const { return mSubSurfaceExtension.data(); } + QtWayland::qt_output_extension *outputExtension() const { return mOutputExtension.data(); } + QWaylandTouchExtension *touchExtension() const { return mTouchExtension.data(); } + QtWayland::wl_text_input_manager *textInputManager() const { return mTextInputManager.data(); } + QWaylandHardwareIntegration *hardwareIntegration() const { return mHardwareIntegration.data(); } /* wl_registry_add_listener does not add but rather sets a listener, so this function is used * to enable many listeners at once. */ @@ -151,18 +158,21 @@ private: struct wl_shm *mShm; QThread *mEventThread; QWaylandEventThread *mEventThreadObject; - QtWayland::wl_shell *mShell; + QScopedPointer<QtWayland::wl_shell> mShell; QList<QPlatformScreen *> mScreens; QList<QWaylandInputDevice *> mInputDevices; QList<Listener> mRegistryListeners; + QWaylandIntegration *mWaylandIntegration; QWaylandInputDevice *mLastKeyboardFocusInputDevice; - QWaylandDataDeviceManager *mDndSelectionHandler; - QtWayland::qt_surface_extension *mWindowExtension; - QtWayland::qt_sub_surface_extension *mSubSurfaceExtension; - QtWayland::qt_output_extension *mOutputExtension; - QWaylandTouchExtension *mTouchExtension; - QWaylandQtKeyExtension *mQtKeyExtension; - QWaylandWindowManagerIntegration *mWindowManagerIntegration; + QScopedPointer<QWaylandDataDeviceManager> mDndSelectionHandler; + QScopedPointer<QtWayland::qt_surface_extension> mWindowExtension; + QScopedPointer<QtWayland::qt_sub_surface_extension> mSubSurfaceExtension; + QScopedPointer<QtWayland::qt_output_extension> mOutputExtension; + QScopedPointer<QWaylandTouchExtension> mTouchExtension; + QScopedPointer<QWaylandQtKeyExtension> mQtKeyExtension; + QScopedPointer<QWaylandWindowManagerIntegration> mWindowManagerIntegration; + QScopedPointer<QtWayland::wl_text_input_manager> mTextInputManager; + QScopedPointer<QWaylandHardwareIntegration> mHardwareIntegration; QSocketNotifier *mReadNotifier; int mFd; @@ -171,10 +181,6 @@ private: void registry_global(uint32_t id, const QString &interface, uint32_t version) Q_DECL_OVERRIDE; -#ifdef QT_WAYLAND_GL_SUPPORT - QWaylandGLIntegration *mEglIntegration; -#endif - static void shellHandleConfigure(void *data, struct wl_shell *shell, uint32_t time, uint32_t edges, struct wl_surface *surface, diff --git a/src/client/qwaylanddnd.cpp b/src/client/qwaylanddnd.cpp new file mode 100644 index 00000000..0d5eddf5 --- /dev/null +++ b/src/client/qwaylanddnd.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylanddnd_p.h" + +#include "qwaylanddatadevice_p.h" +#include "qwaylanddatadevicemanager_p.h" +#include "qwaylanddataoffer_p.h" +#include "qwaylandinputdevice_p.h" + +#include <QtGui/private/qshapedpixmapdndwindow_p.h> + +#include <QDebug> + +QT_BEGIN_NAMESPACE + +QWaylandDrag::QWaylandDrag(QWaylandDisplay *display) + : m_display(display) +{ +} + +QWaylandDrag::~QWaylandDrag() +{ +} + +QMimeData * QWaylandDrag::platformDropData() +{ + if (drag()) + return drag()->mimeData(); + return 0; +} + +void QWaylandDrag::startDrag() +{ + if (!shapedPixmapWindow()) { + QBasicDrag::startDrag(); + QBasicDrag::cancel(); + } + + QWaylandWindow *icon = static_cast<QWaylandWindow *>(shapedPixmapWindow()->handle()); + m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), icon); + QBasicDrag::startDrag(); +} + +void QWaylandDrag::cancel() +{ + QBasicDrag::cancel(); + + m_display->currentInputDevice()->dataDevice()->cancelDrag(); +} + +void QWaylandDrag::move(const QMouseEvent *me) +{ + Q_UNUSED(me); + // Do nothing +} + +void QWaylandDrag::drop(const QMouseEvent *me) +{ + Q_UNUSED(me); + // Do nothing +} + +void QWaylandDrag::endDrag() +{ + // Do nothing +} + +void QWaylandDrag::updateTarget(const QString &mimeType) +{ + setCanDrop(!mimeType.isEmpty()); + + if (canDrop()) { + updateCursor(defaultAction(drag()->supportedActions(), m_display->currentInputDevice()->modifiers())); + } else { + updateCursor(Qt::IgnoreAction); + } +} + +void QWaylandDrag::setResponse(const QPlatformDragQtResponse &response) +{ + setCanDrop(response.isAccepted()); + + if (canDrop()) { + updateCursor(defaultAction(drag()->supportedActions(), m_display->currentInputDevice()->modifiers())); + } else { + updateCursor(Qt::IgnoreAction); + } +} + +void QWaylandDrag::finishDrag(const QPlatformDropQtResponse &response) +{ + setExecutedDropAction(response.acceptedAction()); + QKeyEvent event(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier); + eventFilter(shapedPixmapWindow(), &event); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddnd.h b/src/client/qwaylanddnd_p.h index fa8f5b63..22b00471 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddnd.h +++ b/src/client/qwaylanddnd_p.h @@ -43,27 +43,33 @@ #define QWAYLANDDND_H #include <qpa/qplatformdrag.h> +#include <QtGui/private/qsimpledrag_p.h> + #include <QtGui/QDrag> #include <QtCore/QMimeData> -#include "qwaylanddisplay.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> QT_BEGIN_NAMESPACE -class QWaylandDrag : public QPlatformDrag +class Q_WAYLAND_CLIENT_EXPORT QWaylandDrag : public QBasicDrag { public: QWaylandDrag(QWaylandDisplay *display); ~QWaylandDrag(); - QMimeData *platformDropData(); + QMimeData *platformDropData() Q_DECL_OVERRIDE; + + void updateTarget(const QString &mimeType); + void setResponse(const QPlatformDragQtResponse &response); + void finishDrag(const QPlatformDropQtResponse &response); - Qt::DropAction drag(QDrag *m_drag); - void move(const QMouseEvent *me); - bool canDrop() const; - void drop(const QMouseEvent *me); - void cancel(); +protected: + void startDrag() Q_DECL_OVERRIDE; + void cancel() Q_DECL_OVERRIDE; + void move(const QMouseEvent *me) Q_DECL_OVERRIDE; + void drop(const QMouseEvent *me) Q_DECL_OVERRIDE; + void endDrag() Q_DECL_OVERRIDE; - virtual Qt::DropAction executedDropAction() const; private: QWaylandDisplay *m_display; diff --git a/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp b/src/client/qwaylandeventthread.cpp index ca968a2d..b94110c2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp +++ b/src/client/qwaylandeventthread.cpp @@ -1,4 +1,4 @@ -#include "qwaylandeventthread.h" +#include "qwaylandeventthread_p.h" #include <QtCore/QSocketNotifier> #include <QCoreApplication> @@ -32,8 +32,10 @@ void QWaylandEventThread::displayConnect() void QWaylandEventThread::readWaylandEvents() { - if (wl_display_dispatch(m_display) == -1 && errno == EPIPE) - QCoreApplication::quit(); + if (wl_display_dispatch(m_display) == -1 && errno == EPIPE) { + qWarning("The Wayland connection broke. Did the Wayland compositor die?"); + ::exit(1); + } emit newEventsRead(); } @@ -42,7 +44,7 @@ void QWaylandEventThread::waylandDisplayConnect() m_display = wl_display_connect(NULL); if (m_display == NULL) { qErrnoWarning(errno, "Failed to create display"); - qFatal("No wayland connection available."); + ::exit(1); } m_displayLock->unlock(); diff --git a/src/plugins/platforms/wayland_common/qwaylandeventthread.h b/src/client/qwaylandeventthread_p.h index f4aec744..4174c96c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandeventthread.h +++ b/src/client/qwaylandeventthread_p.h @@ -5,11 +5,13 @@ #include <QMutex> #include <wayland-client.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + QT_BEGIN_NAMESPACE class QSocketNotifier; -class QWaylandEventThread : public QObject +class Q_WAYLAND_CLIENT_EXPORT QWaylandEventThread : public QObject { Q_OBJECT public: diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp b/src/client/qwaylandextendedoutput.cpp index d7c684be..c79685af 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp +++ b/src/client/qwaylandextendedoutput.cpp @@ -39,9 +39,9 @@ ** ****************************************************************************/ -#include "qwaylandextendedoutput.h" +#include "qwaylandextendedoutput_p.h" -#include "qwaylandscreen.h" +#include "qwaylandscreen_p.h" #include <qpa/qwindowsysteminterface.h> diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h b/src/client/qwaylandextendedoutput_p.h index dd9ce6a8..f18fb8e5 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h +++ b/src/client/qwaylandextendedoutput_p.h @@ -42,14 +42,14 @@ #ifndef QWAYLANDEXTENDEDOUTPUT_H #define QWAYLANDEXTENDEDOUTPUT_H -#include "qwaylanddisplay.h" -#include "qwayland-output-extension.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> +#include <QtWaylandClient/private/qwayland-output-extension.h> QT_BEGIN_NAMESPACE class QWaylandExtendedOutput; -class QWaylandExtendedOutput : public QtWayland::qt_extended_output +class Q_WAYLAND_CLIENT_EXPORT QWaylandExtendedOutput : public QtWayland::qt_extended_output { public: QWaylandExtendedOutput(QWaylandScreen *screen, struct ::qt_extended_output *extended_output); diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp b/src/client/qwaylandextendedsurface.cpp index 58eb0a83..fe280416 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp +++ b/src/client/qwaylandextendedsurface.cpp @@ -39,15 +39,13 @@ ** ****************************************************************************/ -#include "qwaylandextendedsurface.h" +#include "qwaylandextendedsurface_p.h" -#include "qwaylandwindow.h" +#include "qwaylandwindow_p.h" -#include "wayland-client.h" +#include "qwaylanddisplay_p.h" -#include "qwaylanddisplay.h" - -#include "qwaylandnativeinterface.h" +#include "qwaylandnativeinterface_p.h" #include <QtGui/QGuiApplication> #include <qpa/qplatformnativeinterface.h> @@ -142,10 +140,11 @@ Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) if (flags & Qt::WindowStaysOnTopHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP; if (flags & Qt::WindowOverridesSystemGestures) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES; + if (flags & Qt::BypassWindowManagerHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER; set_window_flags(wlFlags); - return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures); + return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures | Qt::BypassWindowManagerHint); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h b/src/client/qwaylandextendedsurface_p.h index 4bef5e07..00b961d3 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h +++ b/src/client/qwaylandextendedsurface_p.h @@ -45,15 +45,17 @@ #include <QtCore/QString> #include <QtCore/QVariant> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + #include <wayland-client.h> -#include <qwayland-surface-extension.h> +#include <QtWaylandClient/private/qwayland-surface-extension.h> QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandWindow; -class QWaylandExtendedSurface : public QtWayland::qt_extended_surface +class Q_WAYLAND_CLIENT_EXPORT QWaylandExtendedSurface : public QtWayland::qt_extended_surface { public: QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface); diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp new file mode 100644 index 00000000..8a711955 --- /dev/null +++ b/src/client/qwaylandinputcontext.cpp @@ -0,0 +1,265 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandinputcontext_p.h" + +#include <QGuiApplication> +#include <QWindow> +#ifndef QT_NO_WAYLAND_XKB +#include <xkbcommon/xkbcommon.h> +#endif + +#include "qwaylanddisplay_p.h" +#include "qwaylandinputdevice_p.h" +#include "qwaylandwindow_p.h" + +QT_BEGIN_NAMESPACE + +static Qt::Key toQtKey(uint32_t sym) +{ +#ifndef QT_NO_WAYLAND_XKB + switch (static_cast<xkb_keysym_t>(sym)) { + case XKB_KEY_BackSpace: + return Qt::Key_Backspace; + case XKB_KEY_Return: + return Qt::Key_Return; + case XKB_KEY_Left: + return Qt::Key_Left; + case XKB_KEY_Up: + return Qt::Key_Up; + case XKB_KEY_Right: + return Qt::Key_Right; + case XKB_KEY_Down: + return Qt::Key_Down; + default: + return Qt::Key_unknown; + } +#else + return Qt::Key_unknown; +#endif +} + +static QEvent::Type toQEventType(uint32_t state) +{ + switch (static_cast<wl_keyboard_key_state>(state)) { + default: + case WL_KEYBOARD_KEY_STATE_PRESSED: + return QEvent::KeyPress; + case WL_KEYBOARD_KEY_STATE_RELEASED: + return QEvent::KeyRelease; + } +} + +QWaylandTextInput::QWaylandTextInput(struct ::wl_text_input *text_input) + : QtWayland::wl_text_input(text_input) + , m_commit() + , m_serial(0) + , m_resetSerial(0) +{ +} + +QString QWaylandTextInput::commitString() const +{ + return m_commit; +} + +void QWaylandTextInput::reset() +{ + wl_text_input::reset(); + updateState(); + m_resetSerial = m_serial; +} + +void QWaylandTextInput::updateState() +{ + if (!QGuiApplication::focusObject()) + return; + + QInputMethodQueryEvent event(Qt::ImQueryAll); + QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event); + + const QString &text = event.value(Qt::ImSurroundingText).toString(); + const int cursor = event.value(Qt::ImCursorPosition).toInt(); + const int anchor = event.value(Qt::ImAnchorPosition).toInt(); + + set_surrounding_text(text, text.leftRef(cursor).toUtf8().size(), text.leftRef(anchor).toUtf8().size()); + + commit_state(++m_serial); +} + +void QWaylandTextInput::text_input_commit_string(uint32_t serial, const QString &text) +{ + Q_UNUSED(serial); + if (!QGuiApplication::focusObject()) + return; + + QInputMethodEvent event; + event.setCommitString(text); + QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event); +} + +void QWaylandTextInput::text_input_enter(wl_surface *) +{ + updateState(); + m_resetSerial = m_serial; +} + +void QWaylandTextInput::text_input_leave() +{ +} + +void QWaylandTextInput::text_input_keysym(uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers) +{ + Q_UNUSED(serial); + Q_UNUSED(time); + Q_UNUSED(modifiers); + if (!QGuiApplication::focusObject()) + return; + + // TODO: Convert modifiers to Qt::KeyboardModifiers. + QKeyEvent event(toQEventType(state), toQtKey(sym), Qt::NoModifier); + QCoreApplication::sendEvent(qGuiApp->focusWindow(), &event); +} + +QWaylandInputContext::QWaylandInputContext(QWaylandDisplay *display) + : QPlatformInputContext() + , mDisplay(display) + , mTextInput() +{ +} + +bool QWaylandInputContext::isValid() const +{ + return mDisplay->textInputManager() != 0; +} + +void QWaylandInputContext::reset() +{ + if (!ensureTextInput()) + return; + + mTextInput->reset(); +} + +void QWaylandInputContext::commit() +{ + if (!ensureTextInput()) + return; + + if (!QGuiApplication::focusObject()) + return; + + QInputMethodEvent event; + event.setCommitString(mTextInput->commitString()); + QCoreApplication::sendEvent(QGuiApplication::focusObject(), &event); + + mTextInput->reset(); +} + +void QWaylandInputContext::update(Qt::InputMethodQueries queries) +{ + Q_UNUSED(queries); + if (!ensureTextInput()) + return; + + mTextInput->updateState(); +} + +void QWaylandInputContext::invokeAction(QInputMethod::Action, int cursorPosition) +{ + if (!ensureTextInput()) + return; + + mTextInput->invoke_action(0, cursorPosition); // FIXME button, to UTF8 cursor position +} + +void QWaylandInputContext::showInputPanel() +{ + if (!ensureTextInput()) + return; + + mTextInput->show_input_panel(); +} + +void QWaylandInputContext::hideInputPanel() +{ + if (!ensureTextInput()) + return; + + mTextInput->hide_input_panel(); +} + +bool QWaylandInputContext::isInputPanelVisible() const +{ + return false; +} + +void QWaylandInputContext::setFocusObject(QObject *object) +{ + if (!ensureTextInput()) + return; + + if (!object) { + mTextInput->deactivate(mDisplay->defaultInputDevice()->wl_seat()); + return; + } + + QWindow *window = QGuiApplication::focusWindow(); + if (!window || !window->handle()) + return; + + struct ::wl_surface *surface = static_cast<QWaylandWindow *>(window->handle())->object(); + mTextInput->activate(mDisplay->defaultInputDevice()->wl_seat(), surface); +} + +bool QWaylandInputContext::ensureTextInput() +{ + if (mTextInput) + return true; + + if (!isValid()) + return false; + + mTextInput.reset(new QWaylandTextInput(mDisplay->textInputManager()->create_text_input())); + return true; +} + +QT_END_NAMESPACE + diff --git a/src/client/qwaylandinputcontext_p.h b/src/client/qwaylandinputcontext_p.h new file mode 100644 index 00000000..1f7e4e36 --- /dev/null +++ b/src/client/qwaylandinputcontext_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDINPUTCONTEXT_H +#define QWAYLANDINPUTCONTEXT_H + +#include <qpa/qplatforminputcontext.h> + +#include <QtWaylandClient/private/qwayland-text.h> + +QT_BEGIN_NAMESPACE + +class QWaylandDisplay; + +class QWaylandTextInput : public QtWayland::wl_text_input +{ +public: + QWaylandTextInput(struct ::wl_text_input *text_input); + + QString commitString() const; + + void reset(); + void updateState(); + +protected: + void text_input_commit_string(uint32_t serial, const QString &text) Q_DECL_OVERRIDE; + void text_input_enter(wl_surface *surface) Q_DECL_OVERRIDE; + void text_input_leave() Q_DECL_OVERRIDE; + void text_input_keysym(uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers); + +private: + QString m_commit; + + uint32_t m_serial; + uint32_t m_resetSerial; +}; + +class QWaylandInputContext : public QPlatformInputContext +{ + Q_OBJECT +public: + explicit QWaylandInputContext(QWaylandDisplay *display); + + bool isValid() const Q_DECL_OVERRIDE; + + void reset() Q_DECL_OVERRIDE; + void commit() Q_DECL_OVERRIDE; + void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; + void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE; + + void showInputPanel() Q_DECL_OVERRIDE; + void hideInputPanel() Q_DECL_OVERRIDE; + bool isInputPanelVisible() const Q_DECL_OVERRIDE; + + void setFocusObject(QObject *object) Q_DECL_OVERRIDE; + +private: + bool ensureTextInput(); + + QWaylandDisplay *mDisplay; + QScopedPointer<QWaylandTextInput> mTextInput; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDINPUTCONTEXT_H diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp new file mode 100644 index 00000000..c03647e5 --- /dev/null +++ b/src/client/qwaylandinputdevice.cpp @@ -0,0 +1,946 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandinputdevice_p.h" + +#include "qwaylandintegration_p.h" +#include "qwaylandwindow_p.h" +#include "qwaylandbuffer_p.h" +#include "qwaylanddatadevice_p.h" +#include "qwaylanddatadevicemanager_p.h" +#include "qwaylandtouch_p.h" +#include "qwaylandscreen_p.h" +#include "qwaylandcursor_p.h" + +#include <QtGui/private/qpixmap_raster_p.h> +#include <qpa/qplatformwindow.h> +#include <QDebug> + +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> + +#include <wayland-cursor.h> + +#include <QtGui/QGuiApplication> + +#ifndef QT_NO_WAYLAND_XKB +#include <xkbcommon/xkbcommon.h> +#include <xkbcommon/xkbcommon-keysyms.h> +#endif + +QT_BEGIN_NAMESPACE + +class QWaylandInputDevice::Keyboard : public QtWayland::wl_keyboard +{ +public: + Keyboard(QWaylandInputDevice *p) + : mParent(p) + , mFocus(0) +#ifndef QT_NO_WAYLAND_XKB + , mXkbContext(0) + , mXkbMap(0) + , mXkbState(0) +#endif + , mFocusCallback(0) + { +#ifndef QT_NO_WAYLAND_XKB + xkb_rule_names names; + names.rules = strdup("evdev"); + names.model = strdup("pc105"); + names.layout = strdup("us"); + names.variant = strdup(""); + names.options = strdup(""); + + mXkbContext = xkb_context_new(xkb_context_flags(0)); + if (mXkbContext) { + mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0)); + if (mXkbMap) { + mXkbState = xkb_state_new(mXkbMap); + } + } + + if (!mXkbContext || !mXkbMap || !mXkbState) + qWarning() << "xkb_map_new_from_names failed, no key input"; +#endif + } + ~Keyboard() + { +#ifndef QT_NO_WAYLAND_XKB + if (mXkbState) + xkb_state_unref(mXkbState); + if (mXkbMap) + xkb_map_unref(mXkbMap); + if (mXkbContext) + xkb_context_unref(mXkbContext); +#endif + } + + void keyboard_keymap(uint32_t format, + int32_t fd, + uint32_t size) Q_DECL_OVERRIDE; + void keyboard_enter(uint32_t time, + struct wl_surface *surface, + struct wl_array *keys) Q_DECL_OVERRIDE; + void keyboard_leave(uint32_t time, + struct wl_surface *surface) Q_DECL_OVERRIDE; + void keyboard_key(uint32_t serial, uint32_t time, + uint32_t key, uint32_t state) Q_DECL_OVERRIDE; + void keyboard_modifiers(uint32_t serial, + uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group) Q_DECL_OVERRIDE; + + QWaylandInputDevice *mParent; + QWaylandWindow *mFocus; +#ifndef QT_NO_WAYLAND_XKB + xkb_context *mXkbContext; + xkb_keymap *mXkbMap; + xkb_state *mXkbState; +#endif + struct wl_callback *mFocusCallback; + + int mRepeatKey; + uint32_t mRepeatCode; + uint32_t mRepeatTime; + QString mRepeatText; + + static const wl_callback_listener callback; + static void focusCallback(void *data, struct wl_callback *callback, uint32_t time); +}; + +class QWaylandInputDevice::Pointer : public QtWayland::wl_pointer +{ +public: + Pointer(QWaylandInputDevice *p) + : mParent(p) + , mFocus(0) + , mEnterSerial(0) + , mCursorSerial(0) + , mButtons(0) + { + } + ~Pointer() + { + } + + void pointer_enter(uint32_t serial, struct wl_surface *surface, + wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE; + void pointer_leave(uint32_t time, struct wl_surface *surface); + void pointer_motion(uint32_t time, + wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE; + void pointer_button(uint32_t serial, uint32_t time, + uint32_t button, uint32_t state) Q_DECL_OVERRIDE; + void pointer_axis(uint32_t time, + uint32_t axis, + wl_fixed_t value) Q_DECL_OVERRIDE; + + QWaylandInputDevice *mParent; + QWaylandWindow *mFocus; + uint32_t mEnterSerial; + uint32_t mCursorSerial; + QPointF mSurfacePos; + QPointF mGlobalPos; + Qt::MouseButtons mButtons; +}; + +class QWaylandInputDevice::Touch : public QtWayland::wl_touch +{ +public: + Touch(QWaylandInputDevice *p) + : mParent(p) + , mFocus(0) + { + } + ~Touch() + { + } + + void touch_down(uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) Q_DECL_OVERRIDE; + void touch_up(uint32_t serial, + uint32_t time, + int32_t id) Q_DECL_OVERRIDE; + void touch_motion(uint32_t time, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) Q_DECL_OVERRIDE; + void touch_frame() Q_DECL_OVERRIDE; + void touch_cancel() Q_DECL_OVERRIDE; + + QWaylandInputDevice *mParent; + QWaylandWindow *mFocus; + QList<QWindowSystemInterface::TouchPoint> mTouchPoints; + QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints; +}; + +QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) + : QObject() + , QtWayland::wl_seat(display->wl_registry(), id) + , mQDisplay(display) + , mDisplay(display->wl_display()) + , mCaps(0) + , mDataDevice(0) + , mKeyboard(0) + , mPointer(0) + , mTouch(0) + , mTime(0) + , mSerial(0) +{ + if (mQDisplay->dndSelectionHandler()) { + mDataDevice = mQDisplay->dndSelectionHandler()->getDataDevice(this); + } + + connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey())); +} + +QWaylandInputDevice::~QWaylandInputDevice() +{ + delete mPointer; + delete mKeyboard; + delete mTouch; +} + +void QWaylandInputDevice::seat_capabilities(uint32_t caps) +{ + mCaps = caps; + + if (caps & WL_SEAT_CAPABILITY_KEYBOARD && !mKeyboard) { + mKeyboard = new Keyboard(this); + mKeyboard->init(get_keyboard()); + } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && mKeyboard) { + delete mKeyboard; + mKeyboard = 0; + mRepeatTimer.stop(); + } + + if (caps & WL_SEAT_CAPABILITY_POINTER && !mPointer) { + mPointer = new Pointer(this); + mPointer->init(get_pointer()); + pointerSurface = mQDisplay->createSurface(this); + } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && mPointer) { + delete mPointer; + mPointer = 0; + } + + if (caps & WL_SEAT_CAPABILITY_TOUCH && !mTouch) { + mTouch = new Touch(this); + mTouch->init(get_touch()); + + if (!mTouchDevice) { + mTouchDevice = new QTouchDevice; + mTouchDevice->setType(QTouchDevice::TouchScreen); + mTouchDevice->setCapabilities(QTouchDevice::Position); + QWindowSystemInterface::registerTouchDevice(mTouchDevice); + } + } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && mTouch) { + delete mTouch; + mTouch = 0; + } +} + +void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window) +{ + if (mPointer && window == mPointer->mFocus) + mPointer->mFocus = 0; + if (mKeyboard && window == mKeyboard->mFocus) { + mKeyboard->mFocus = 0; + mRepeatTimer.stop(); + } +} + +void QWaylandInputDevice::setDataDevice(QWaylandDataDevice *device) +{ + mDataDevice = device; +} + +QWaylandDataDevice *QWaylandInputDevice::dataDevice() const +{ + Q_ASSERT(mDataDevice); + return mDataDevice; +} + +void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) +{ + if (mPointer) + mPointer->mButtons = mPointer->mButtons & !button; +} + +QWaylandWindow *QWaylandInputDevice::pointerFocus() const +{ + return mPointer ? mPointer->mFocus : 0; +} + +QWaylandWindow *QWaylandInputDevice::keyboardFocus() const +{ + return mKeyboard ? mKeyboard->mFocus : 0; +} + +QWaylandWindow *QWaylandInputDevice::touchFocus() const +{ + return mTouch ? mTouch->mFocus : 0; +} + +Qt::KeyboardModifiers QWaylandInputDevice::modifiers() const +{ + if (!mKeyboard) + return Qt::NoModifier; + + Qt::KeyboardModifiers ret = Qt::NoModifier; + +#ifndef QT_NO_WAYLAND_XKB + xkb_state_component cstate = static_cast<xkb_state_component>(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED); + + if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Shift", cstate)) + ret |= Qt::ShiftModifier; + if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Control", cstate)) + ret |= Qt::ControlModifier; + if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Alt", cstate)) + ret |= Qt::AltModifier; + if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Mod1", cstate)) + ret |= Qt::AltModifier; + if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Mod4", cstate)) + ret |= Qt::MetaModifier; +#endif + + return ret; +} + +uint32_t QWaylandInputDevice::cursorSerial() const +{ + if (mPointer) + return mPointer->mCursorSerial; + return 0; +} + +void QWaylandInputDevice::setCursor(Qt::CursorShape newShape, QWaylandScreen *screen) +{ + struct wl_cursor_image *image = screen->waylandCursor()->cursorImage(newShape); + if (!image) { + return; + } + + struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); + setCursor(buffer, image); +} + +void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image) +{ + if (mCaps & WL_SEAT_CAPABILITY_POINTER) { + mPointer->mCursorSerial = mPointer->mEnterSerial; + /* Hide cursor */ + if (!buffer) + { + mPointer->set_cursor(mPointer->mEnterSerial, NULL, 0, 0); + return; + } + + mPointer->set_cursor(mPointer->mEnterSerial, pointerSurface, + image->hotspot_x, image->hotspot_y); + wl_surface_attach(pointerSurface, buffer, 0, 0); + wl_surface_damage(pointerSurface, 0, 0, image->width, image->height); + wl_surface_commit(pointerSurface); + } +} + +void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surface *surface, + wl_fixed_t sx, wl_fixed_t sy) +{ + Q_UNUSED(sx); + Q_UNUSED(sy); + + if (!surface) + return; + + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); + window->window()->setCursor(window->window()->cursor()); + + mFocus = window; + + mParent->mTime = QWaylandDisplay::currentTimeMillisec(); + mParent->mSerial = serial; + mEnterSerial = serial; + + QWaylandWindow *grab = QWaylandWindow::mouseGrab(); + if (!grab) { + window->handleMouseEnter(mParent); + window->handleMouse(mParent, mParent->mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + } +} + +void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surface *surface) +{ + // The event may arrive after destroying the window, indicated by + // a null surface. + if (!surface) + return; + + if (!QWaylandWindow::mouseGrab()) { + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); + window->handleMouseLeave(mParent); + } + mFocus = 0; + mButtons = Qt::NoButton; + + mParent->mTime = time; +} + +void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) +{ + Q_UNUSED(surface_x); + Q_UNUSED(surface_y); + + QWaylandWindow *window = mFocus; + + if (window == NULL) { + // We destroyed the pointer focus surface, but the server + // didn't get the message yet. + return; + } + + QPointF pos(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)); + QPointF delta = pos - pos.toPoint(); + QPointF global = window->window()->mapToGlobal(pos.toPoint()); + global += delta; + + mSurfacePos = pos; + mGlobalPos = global; + mParent->mTime = time; + + QWaylandWindow *grab = QWaylandWindow::mouseGrab(); + if (grab && grab != window) { + // We can't know the true position since we're getting events for another surface, + // so we just set it outside of the window boundaries. + pos = QPointF(-1, -1); + global = grab->window()->mapToGlobal(pos.toPoint()); + grab->handleMouse(mParent, time, pos, global, mButtons, Qt::NoModifier); + } else + window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); +} + +void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time, + uint32_t button, uint32_t state) +{ + Q_UNUSED(serial); + QWaylandWindow *window = mFocus; + Qt::MouseButton qt_button; + + // translate from kernel (input.h) 'button' to corresponding Qt:MouseButton. + // The range of mouse values is 0x110 <= mouse_button < 0x120, the first Joystick button. + switch (button) { + case 0x110: qt_button = Qt::LeftButton; break; // kernel BTN_LEFT + case 0x111: qt_button = Qt::RightButton; break; + case 0x112: qt_button = Qt::MiddleButton; break; + case 0x113: qt_button = Qt::ExtraButton1; break; // AKA Qt::BackButton + case 0x114: qt_button = Qt::ExtraButton2; break; // AKA Qt::ForwardButton + case 0x115: qt_button = Qt::ExtraButton3; break; // AKA Qt::TaskButton + case 0x116: qt_button = Qt::ExtraButton4; break; + case 0x117: qt_button = Qt::ExtraButton5; break; + case 0x118: qt_button = Qt::ExtraButton6; break; + case 0x119: qt_button = Qt::ExtraButton7; break; + case 0x11a: qt_button = Qt::ExtraButton8; break; + case 0x11b: qt_button = Qt::ExtraButton9; break; + case 0x11c: qt_button = Qt::ExtraButton10; break; + case 0x11d: qt_button = Qt::ExtraButton11; break; + case 0x11e: qt_button = Qt::ExtraButton12; break; + case 0x11f: qt_button = Qt::ExtraButton13; break; + default: return; // invalid button number (as far as Qt is concerned) + } + + if (state) + mButtons |= qt_button; + else + mButtons &= ~qt_button; + + mParent->mTime = time; + mParent->mSerial = serial; + + QWaylandWindow *grab = QWaylandWindow::mouseGrab(); + if (grab && grab != mFocus) { + QPointF pos = QPointF(-1, -1); + QPointF global = grab->window()->mapToGlobal(pos.toPoint()); + grab->handleMouse(mParent, time, pos, global, mButtons, Qt::NoModifier); + } else if (window) + window->handleMouse(mParent, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); +} + +void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, int32_t value) +{ + QWaylandWindow *window = mFocus; + QPoint pixelDelta; + QPoint angleDelta; + + //normalize value and inverse axis + int valueDelta = wl_fixed_to_int(value) * -12; + + if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) { + pixelDelta = QPoint(); + angleDelta.setX(valueDelta); + } else { + pixelDelta = QPoint(); + angleDelta.setY(valueDelta); + } + + QWindowSystemInterface::handleWheelEvent(window->window(), + time, mSurfacePos, + mGlobalPos, pixelDelta, + angleDelta); +} + +#ifndef QT_NO_WAYLAND_XKB + +static const uint32_t KeyTbl[] = { + XKB_KEY_Escape, Qt::Key_Escape, + XKB_KEY_Tab, Qt::Key_Tab, + XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab, + XKB_KEY_BackSpace, Qt::Key_Backspace, + XKB_KEY_Return, Qt::Key_Return, + XKB_KEY_Insert, Qt::Key_Insert, + XKB_KEY_Delete, Qt::Key_Delete, + XKB_KEY_Clear, Qt::Key_Delete, + XKB_KEY_Pause, Qt::Key_Pause, + XKB_KEY_Print, Qt::Key_Print, + + XKB_KEY_Home, Qt::Key_Home, + XKB_KEY_End, Qt::Key_End, + XKB_KEY_Left, Qt::Key_Left, + XKB_KEY_Up, Qt::Key_Up, + XKB_KEY_Right, Qt::Key_Right, + XKB_KEY_Down, Qt::Key_Down, + XKB_KEY_Prior, Qt::Key_PageUp, + XKB_KEY_Next, Qt::Key_PageDown, + + XKB_KEY_Shift_L, Qt::Key_Shift, + XKB_KEY_Shift_R, Qt::Key_Shift, + XKB_KEY_Shift_Lock, Qt::Key_Shift, + XKB_KEY_Control_L, Qt::Key_Control, + XKB_KEY_Control_R, Qt::Key_Control, + XKB_KEY_Meta_L, Qt::Key_Meta, + XKB_KEY_Meta_R, Qt::Key_Meta, + XKB_KEY_Alt_L, Qt::Key_Alt, + XKB_KEY_Alt_R, Qt::Key_Alt, + XKB_KEY_Caps_Lock, Qt::Key_CapsLock, + XKB_KEY_Num_Lock, Qt::Key_NumLock, + XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock, + XKB_KEY_Super_L, Qt::Key_Super_L, + XKB_KEY_Super_R, Qt::Key_Super_R, + XKB_KEY_Menu, Qt::Key_Menu, + XKB_KEY_Hyper_L, Qt::Key_Hyper_L, + XKB_KEY_Hyper_R, Qt::Key_Hyper_R, + XKB_KEY_Help, Qt::Key_Help, + + XKB_KEY_KP_Space, Qt::Key_Space, + XKB_KEY_KP_Tab, Qt::Key_Tab, + XKB_KEY_KP_Enter, Qt::Key_Enter, + XKB_KEY_KP_Home, Qt::Key_Home, + XKB_KEY_KP_Left, Qt::Key_Left, + XKB_KEY_KP_Up, Qt::Key_Up, + XKB_KEY_KP_Right, Qt::Key_Right, + XKB_KEY_KP_Down, Qt::Key_Down, + XKB_KEY_KP_Prior, Qt::Key_PageUp, + XKB_KEY_KP_Next, Qt::Key_PageDown, + XKB_KEY_KP_End, Qt::Key_End, + XKB_KEY_KP_Begin, Qt::Key_Clear, + XKB_KEY_KP_Insert, Qt::Key_Insert, + XKB_KEY_KP_Delete, Qt::Key_Delete, + XKB_KEY_KP_Equal, Qt::Key_Equal, + XKB_KEY_KP_Multiply, Qt::Key_Asterisk, + XKB_KEY_KP_Add, Qt::Key_Plus, + XKB_KEY_KP_Separator, Qt::Key_Comma, + XKB_KEY_KP_Subtract, Qt::Key_Minus, + XKB_KEY_KP_Decimal, Qt::Key_Period, + XKB_KEY_KP_Divide, Qt::Key_Slash, + + XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr, + XKB_KEY_Multi_key, Qt::Key_Multi_key, + XKB_KEY_Codeinput, Qt::Key_Codeinput, + XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate, + XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate, + XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate, + + XKB_KEY_Mode_switch, Qt::Key_Mode_switch, + XKB_KEY_script_switch, Qt::Key_Mode_switch, + + 0, 0 +}; + +static int keysymToQtKey(xkb_keysym_t key) +{ + int code = 0; + int i = 0; + while (KeyTbl[i]) { + if (key == KeyTbl[i]) { + code = (int)KeyTbl[i+1]; + break; + } + i += 2; + } + + return code; +} + +static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, const QString &text) +{ + int code = 0; + + if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) { + code = Qt::Key_F1 + (int(keysym) - XKB_KEY_F1); + } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) { + if (keysym >= XKB_KEY_KP_0) { + // numeric keypad keys + code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0); + } else { + code = keysymToQtKey(keysym); + } + modifiers |= Qt::KeypadModifier; + } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f + && text.unicode()->unicode() != 0x7f + && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_currency)) { + code = text.unicode()->toUpper().unicode(); + } else { + // any other keys + code = keysymToQtKey(keysym); + } + + return code; +} + +#endif // QT_NO_WAYLAND_XKB + +void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size) +{ +#ifndef QT_NO_WAYLAND_XKB + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + close(fd); + return; + } + + char *map_str = (char *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map_str == MAP_FAILED) { + close(fd); + return; + } + + mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, (xkb_keymap_compile_flags)0); + munmap(map_str, size); + close(fd); + + mXkbState = xkb_state_new(mXkbMap); +#else + Q_UNUSED(format); + Q_UNUSED(fd); + Q_UNUSED(size); +#endif +} + +void QWaylandInputDevice::Keyboard::keyboard_enter(uint32_t time, struct wl_surface *surface, struct wl_array *keys) +{ + Q_UNUSED(time); + Q_UNUSED(keys); + + if (!surface) + return; + + + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); + mFocus = window; + + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mParent->mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::Keyboard::callback, this); + } +} + +void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surface *surface) +{ + Q_UNUSED(time); + Q_UNUSED(surface); + + mFocus = NULL; + + // Use a callback to set the focus because we may get a leave/enter pair, and + // the latter one would be lost in the QWindowSystemInterface queue, if + // we issue the handleWindowActivated() calls immediately. + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mParent->mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::Keyboard::callback, this); + } + mParent->mRepeatTimer.stop(); +} + +const wl_callback_listener QWaylandInputDevice::Keyboard::callback = { + QWaylandInputDevice::Keyboard::focusCallback +}; + +void QWaylandInputDevice::Keyboard::focusCallback(void *data, struct wl_callback *callback, uint32_t time) +{ + Q_UNUSED(time); + Q_UNUSED(callback); + QWaylandInputDevice::Keyboard *self = static_cast<QWaylandInputDevice::Keyboard *>(data); + if (self->mFocusCallback) { + wl_callback_destroy(self->mFocusCallback); + self->mFocusCallback = 0; + } + + self->mParent->mQDisplay->setLastKeyboardFocusInputDevice(self->mFocus ? self->mParent : 0); + QWindowSystemInterface::handleWindowActivated(self->mFocus ? self->mFocus->window() : 0); +} + +void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) +{ + Q_UNUSED(serial); + QWaylandWindow *window = mFocus; +#ifndef QT_NO_WAYLAND_XKB + if (!mXkbMap) + return; + + uint32_t code = key + 8; + bool isDown = state != 0; + const xkb_keysym_t *syms; + uint32_t numSyms = xkb_key_get_syms(mXkbState, code, &syms); + xkb_state_update_key(mXkbState, code, + isDown ? XKB_KEY_DOWN : XKB_KEY_UP); + QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; + + if (!window) { + // We destroyed the keyboard focus surface, but the server + // didn't get the message yet. + return; + } + + int qtkey = key + 8; // qt-compositor substracts 8 for some reason + QString text; + + if (numSyms == 1) { + xkb_keysym_t sym = syms[0]; + Qt::KeyboardModifiers modifiers = mParent->modifiers(); + + uint utf32 = xkb_keysym_to_utf32(sym); + text = QString::fromUcs4(&utf32, 1); + + qtkey = keysymToQtKey(sym, modifiers, text); + + QWindowSystemInterface::handleExtendedKeyEvent(window->window(), + time, type, qtkey, + modifiers, + code, 0, 0, text); + } +#else + // Generic fallback for single hard keys: Assume 'key' is a Qt key code. + if (window) { + QWindowSystemInterface::handleExtendedKeyEvent(window->window(), + time, type, + qtkey, + Qt::NoModifier, + code, 0, 0); + } +#endif + + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { + mRepeatKey = qtkey; + mRepeatCode = code; + mRepeatTime = time; + mRepeatText = text; + mParent->mRepeatTimer.setInterval(400); + mParent->mRepeatTimer.start(); + } else if (mRepeatCode == code) { + mParent->mRepeatTimer.stop(); + } +} + +void QWaylandInputDevice::repeatKey() +{ + mRepeatTimer.setInterval(25); + QWindowSystemInterface::handleExtendedKeyEvent(mKeyboard->mFocus->window(), + mKeyboard->mRepeatTime, QEvent::KeyPress, mKeyboard->mRepeatKey, + modifiers(), + mKeyboard->mRepeatCode, 0, 0, mKeyboard->mRepeatText); +} + +void QWaylandInputDevice::Keyboard::keyboard_modifiers(uint32_t serial, + uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group) +{ + Q_UNUSED(serial); +#ifndef QT_NO_WAYLAND_XKB + if (mXkbState) + xkb_state_update_mask(mXkbState, + mods_depressed, mods_latched, mods_locked, + 0, 0, group); +#else + Q_UNUSED(serial); + Q_UNUSED(mods_depressed); + Q_UNUSED(mods_latched); + Q_UNUSED(mods_locked); + Q_UNUSED(group); +#endif +} + +void QWaylandInputDevice::Touch::touch_down(uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) +{ + Q_UNUSED(serial); + Q_UNUSED(time); + mFocus = QWaylandWindow::fromWlSurface(surface); + mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); +} + +void QWaylandInputDevice::Touch::touch_up(uint32_t serial, uint32_t time, int32_t id) +{ + Q_UNUSED(serial); + Q_UNUSED(time); + mFocus = 0; + mParent->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); +} + +void QWaylandInputDevice::Touch::touch_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) +{ + Q_UNUSED(time); + mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved); +} + +void QWaylandInputDevice::Touch::touch_cancel() +{ + mPrevTouchPoints.clear(); + mTouchPoints.clear(); + + QWaylandTouchExtension *touchExt = mParent->mQDisplay->touchExtension(); + if (touchExt) + touchExt->touchCanceled(); + + QWindowSystemInterface::handleTouchCancelEvent(0, mParent->mTouchDevice); +} + +void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state) +{ + QWindowSystemInterface::TouchPoint tp; + + // Find out the coordinates for Released events. + bool coordsOk = false; + if (state == Qt::TouchPointReleased) + for (int i = 0; i < mTouch->mPrevTouchPoints.count(); ++i) + if (mTouch->mPrevTouchPoints.at(i).id == id) { + tp.area = mTouch->mPrevTouchPoints.at(i).area; + coordsOk = true; + break; + } + + if (!coordsOk) { + // x and y are surface relative. + // We need a global (screen) position. + QWaylandWindow *win = mTouch->mFocus; + + //is it possible that mTouchFocus is null; + if (!win && mPointer) + win = mPointer->mFocus; + if (!win && mKeyboard) + win = mKeyboard->mFocus; + if (!win || !win->window()) + return; + + tp.area = QRectF(0, 0, 8, 8); + QMargins margins = win->frameMargins(); + tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x+margins.left(), y+margins.top()))); + } + + tp.state = state; + tp.id = id; + tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1; + mTouch->mTouchPoints.append(tp); +} + +void QWaylandInputDevice::Touch::touch_frame() +{ + // Copy all points, that are in the previous but not in the current list, as stationary. + for (int i = 0; i < mPrevTouchPoints.count(); ++i) { + const QWindowSystemInterface::TouchPoint &prevPoint(mPrevTouchPoints.at(i)); + if (prevPoint.state == Qt::TouchPointReleased) + continue; + bool found = false; + for (int j = 0; j < mTouchPoints.count(); ++j) + if (mTouchPoints.at(j).id == prevPoint.id) { + found = true; + break; + } + if (!found) { + QWindowSystemInterface::TouchPoint p = prevPoint; + p.state = Qt::TouchPointStationary; + mTouchPoints.append(p); + } + } + + if (mTouchPoints.isEmpty()) { + mPrevTouchPoints.clear(); + return; + } + + QWindow *window = mFocus ? mFocus->window() : 0; + + QWindowSystemInterface::handleTouchEvent(window, mParent->mTouchDevice, mTouchPoints); + + bool allReleased = true; + for (int i = 0; i < mTouchPoints.count(); ++i) + if (mTouchPoints.at(i).state != Qt::TouchPointReleased) { + allReleased = false; + break; + } + + mPrevTouchPoints = mTouchPoints; + mTouchPoints.clear(); + + if (allReleased) { + QWindowSystemInterface::handleTouchEvent(window, mParent->mTouchDevice, mTouchPoints); + mPrevTouchPoints.clear(); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h b/src/client/qwaylandinputdevice_p.h index c9202684..867258ad 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h +++ b/src/client/qwaylandinputdevice_p.h @@ -42,17 +42,18 @@ #ifndef QWAYLANDINPUTDEVICE_H #define QWAYLANDINPUTDEVICE_H -#include "qwaylandwindow.h" +#include <QtWaylandClient/private/qwaylandwindow_p.h> #include <QSocketNotifier> #include <QObject> +#include <QTimer> #include <qpa/qplatformintegration.h> #include <qpa/qplatformscreen.h> #include <qpa/qwindowsysteminterface.h> #include <wayland-client.h> -#include "qwayland-wayland.h" +#include <QtWaylandClient/private/qwayland-wayland.h> #ifndef QT_NO_WAYLAND_XKB struct xkb_context; @@ -64,9 +65,13 @@ QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandDisplay; +class QWaylandDataDevice; -class QWaylandInputDevice : public QtWayland::wl_pointer, public QtWayland::wl_keyboard, public QtWayland::wl_touch, public QtWayland::wl_seat +class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDevice + : public QObject + , public QtWayland::wl_seat { + Q_OBJECT public: QWaylandInputDevice(QWaylandDisplay *display, uint32_t id); ~QWaylandInputDevice(); @@ -79,96 +84,50 @@ public: void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); void handleWindowDestroyed(QWaylandWindow *window); - void setTransferDevice(struct wl_data_device *device); - struct wl_data_device *transferDevice() const; + void setDataDevice(QWaylandDataDevice *device); + QWaylandDataDevice *dataDevice() const; void removeMouseButtonFromState(Qt::MouseButton button); + QWaylandWindow *pointerFocus() const; + QWaylandWindow *keyboardFocus() const; + QWaylandWindow *touchFocus() const; + + Qt::KeyboardModifiers modifiers() const; + uint32_t serial() const; - uint32_t cursorSerial() const { return mCursorSerial; } + uint32_t cursorSerial() const; + +private slots: + void repeatKey(); private: + class Keyboard; + class Pointer; + class Touch; + QWaylandDisplay *mQDisplay; struct wl_display *mDisplay; - struct wl_callback *mFocusCallback; uint32_t mCaps; struct wl_surface *pointerSurface; - struct wl_data_device *mTransferDevice; - QWaylandWindow *mPointerFocus; - QWaylandWindow *mKeyboardFocus; - QWaylandWindow *mTouchFocus; + QWaylandDataDevice *mDataDevice; + + Keyboard *mKeyboard; + Pointer *mPointer; + Touch *mTouch; - Qt::MouseButtons mButtons; - QPointF mSurfacePos; - QPointF mGlobalPos; uint32_t mTime; uint32_t mSerial; - uint32_t mEnterSerial; - uint32_t mCursorSerial; + QTimer mRepeatTimer; void seat_capabilities(uint32_t caps) Q_DECL_OVERRIDE; - - void pointer_enter(uint32_t serial, struct wl_surface *surface, - wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE; - void pointer_leave(uint32_t time, struct wl_surface *surface); - void pointer_motion(uint32_t time, - wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE; - void pointer_button(uint32_t serial, uint32_t time, - uint32_t button, uint32_t state) Q_DECL_OVERRIDE; - void pointer_axis(uint32_t time, - uint32_t axis, - wl_fixed_t value) Q_DECL_OVERRIDE; - - void keyboard_keymap(uint32_t format, - int32_t fd, - uint32_t size) Q_DECL_OVERRIDE; - void keyboard_enter(uint32_t time, - struct wl_surface *surface, - struct wl_array *keys) Q_DECL_OVERRIDE; - void keyboard_leave(uint32_t time, - struct wl_surface *surface) Q_DECL_OVERRIDE; - void keyboard_key(uint32_t serial, uint32_t time, - uint32_t key, uint32_t state) Q_DECL_OVERRIDE; - void keyboard_modifiers(uint32_t serial, - uint32_t mods_depressed, - uint32_t mods_latched, - uint32_t mods_locked, - uint32_t group) Q_DECL_OVERRIDE; - - void touch_down(uint32_t serial, - uint32_t time, - struct wl_surface *surface, - int32_t id, - wl_fixed_t x, - wl_fixed_t y) Q_DECL_OVERRIDE; - void touch_up(uint32_t serial, - uint32_t time, - int32_t id) Q_DECL_OVERRIDE; - void touch_motion(uint32_t time, - int32_t id, - wl_fixed_t x, - wl_fixed_t y) Q_DECL_OVERRIDE; - void touch_frame() Q_DECL_OVERRIDE; - void touch_cancel() Q_DECL_OVERRIDE; - void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state); - static const wl_callback_listener callback; - static void focusCallback(void *data, struct wl_callback *callback, uint32_t time); - - QList<QWindowSystemInterface::TouchPoint> mTouchPoints; - QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints; QTouchDevice *mTouchDevice; -#ifndef QT_NO_WAYLAND_XKB - xkb_context *mXkbContext; - xkb_keymap *mXkbMap; - xkb_state *mXkbState; -#endif - friend class QWaylandTouchExtension; friend class QWaylandQtKeyExtension; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index b0d5b271..2e36a16d 100644 --- a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -39,15 +39,16 @@ ** ****************************************************************************/ -#include "qwaylandintegration.h" +#include "qwaylandintegration_p.h" -#include "qwaylanddisplay.h" -#include "qwaylandshmbackingstore.h" -#include "qwaylandshmwindow.h" -#include "qwaylandnativeinterface.h" -#include "qwaylandclipboard.h" -#include "qwaylanddnd.h" -#include "qwaylandwindowmanagerintegration.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandinputcontext_p.h" +#include "qwaylandshmbackingstore_p.h" +#include "qwaylandshmwindow_p.h" +#include "qwaylandnativeinterface_p.h" +#include "qwaylandclipboard_p.h" +#include "qwaylanddnd_p.h" +#include "qwaylandwindowmanagerintegration_p.h" #include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h" #include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> @@ -64,10 +65,12 @@ #include <qpa/qplatformaccessibility.h> #include <qpa/qplatforminputcontext.h> -#ifdef QT_WAYLAND_GL_SUPPORT -#include "qwaylandglintegration.h" -#endif +#include "qwaylandhardwareintegration_p.h" +#include "qwaylandclientbufferintegration_p.h" +#include "qwaylandclientbufferintegrationfactory_p.h" +#include "qwaylandserverbufferintegration_p.h" +#include "qwaylandserverbufferintegrationfactory_p.h" QT_BEGIN_NAMESPACE @@ -90,7 +93,7 @@ public: desktopEnvironment != QByteArrayLiteral("MATE") && desktopEnvironment != QByteArrayLiteral("XFCE") && desktopEnvironment != QByteArrayLiteral("LXDE")) - result.push_back(desktopEnvironment.toLower()); + result.push_back(QString::fromLocal8Bit(desktopEnvironment.toLower())); } if (result.isEmpty()) @@ -101,24 +104,25 @@ public: }; QWaylandIntegration::QWaylandIntegration() - : mFontDb(new QGenericUnixFontDatabase()) - , mEventDispatcher(createUnixEventDispatcher()) + : mClientBufferIntegration(0) + , mFontDb(new QGenericUnixFontDatabase()) , mNativeInterface(new QWaylandNativeInterface(this)) #ifndef QT_NO_ACCESSIBILITY , mAccessibility(new QPlatformAccessibility()) #else , mAccessibility(0) #endif + , mClientBufferIntegrationInitialized(false) + , mServerBufferIntegrationInitialized(false) { - QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); - mDisplay = new QWaylandDisplay(); + mDisplay = new QWaylandDisplay(this); mClipboard = new QWaylandClipboard(mDisplay); mDrag = new QWaylandDrag(mDisplay); foreach (QPlatformScreen *screen, mDisplay->screens()) screenAdded(screen); - mInputContext = QPlatformInputContextFactory::create(); + mInputContext.reset(new QWaylandInputContext(mDisplay)); } QWaylandIntegration::~QWaylandIntegration() @@ -142,40 +146,30 @@ bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) co switch (cap) { case ThreadedPixmaps: return true; case OpenGL: -#ifdef QT_WAYLAND_GL_SUPPORT - return true; -#else - return false; -#endif + return mDisplay->clientBufferIntegration(); case ThreadedOpenGL: -#ifdef QT_WAYLAND_GL_SUPPORT - return mDisplay->eglIntegration()->supportsThreadedOpenGL(); -#else - return false; -#endif + return mDisplay->clientBufferIntegration() && mDisplay->clientBufferIntegration()->supportsThreadedOpenGL(); case BufferQueueingOpenGL: return true; + case MultipleWindows: + case NonFullScreenWindows: + return true; default: return QPlatformIntegration::hasCapability(cap); } } QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const { -#ifdef QT_WAYLAND_GL_SUPPORT - if (window->surfaceType() == QWindow::OpenGLSurface) - return mDisplay->eglIntegration()->createEglWindow(window); -#endif + if (window->surfaceType() == QWindow::OpenGLSurface && mDisplay->clientBufferIntegration()) + return mDisplay->clientBufferIntegration()->createEglWindow(window); return new QWaylandShmWindow(window); } QPlatformOpenGLContext *QWaylandIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { -#ifdef QT_WAYLAND_GL_SUPPORT - return mDisplay->eglIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle()); -#else - Q_UNUSED(context); + if (mDisplay->clientBufferIntegration()) + return mDisplay->clientBufferIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle()); return 0; -#endif } QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow *window) const @@ -183,9 +177,15 @@ QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow * return new QWaylandShmBackingStore(window); } -QAbstractEventDispatcher *QWaylandIntegration::guiThreadEventDispatcher() const +QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const { - return mEventDispatcher; + return createUnixEventDispatcher(); +} + +void QWaylandIntegration::initialize() +{ + QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; + QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay, SLOT(flushRequests())); } QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const @@ -205,7 +205,7 @@ QPlatformDrag *QWaylandIntegration::drag() const QPlatformInputContext *QWaylandIntegration::inputContext() const { - return mInputContext; + return mInputContext.data(); } QVariant QWaylandIntegration::styleHint(StyleHint hint) const @@ -241,4 +241,81 @@ QPlatformTheme *QWaylandIntegration::createPlatformTheme(const QString &name) co return GenericWaylandTheme::createUnixTheme(name); } +QWaylandClientBufferIntegration *QWaylandIntegration::clientBufferIntegration() const +{ + if (!mClientBufferIntegrationInitialized) + const_cast<QWaylandIntegration *>(this)->initializeClientBufferIntegration(); + + return mClientBufferIntegration; +} + +QWaylandServerBufferIntegration *QWaylandIntegration::serverBufferIntegration() const +{ + if (!mServerBufferIntegrationInitialized) + const_cast<QWaylandIntegration *>(this)->initializeServerBufferIntegration(); + + return mServerBufferIntegration; +} + +void QWaylandIntegration::initializeClientBufferIntegration() +{ + mClientBufferIntegrationInitialized = true; + + QString targetKey; + bool disableHardwareIntegration = qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_HW_INTEGRATION"); + disableHardwareIntegration = disableHardwareIntegration || !mDisplay->hardwareIntegration(); + if (disableHardwareIntegration) { + QByteArray clientBufferIntegrationName = qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"); + if (clientBufferIntegrationName.isEmpty()) + clientBufferIntegrationName = QByteArrayLiteral("wayland-egl"); + targetKey = QString::fromLocal8Bit(clientBufferIntegrationName); + } else { + targetKey = mDisplay->hardwareIntegration()->clientBufferIntegration(); + } + + if (targetKey.isEmpty()) { + qWarning("Failed to determin what client buffer integration to use"); + return; + } + + QStringList keys = QWaylandClientBufferIntegrationFactory::keys(); + if (keys.contains(targetKey)) { + mClientBufferIntegration = QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList()); + } + if (mClientBufferIntegration) + mClientBufferIntegration->initialize(mDisplay); + else + qWarning("Failed to load client buffer intgration: %s\n", qPrintable(targetKey)); +} + +void QWaylandIntegration::initializeServerBufferIntegration() +{ + mServerBufferIntegrationInitialized = true; + + QString targetKey; + + bool disableHardwareIntegration = qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_HW_INTEGRATION"); + disableHardwareIntegration = disableHardwareIntegration || !mDisplay->hardwareIntegration(); + if (disableHardwareIntegration) { + QByteArray serverBufferIntegrationName = qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"); + QString targetKey = QString::fromLocal8Bit(serverBufferIntegrationName); + } else { + targetKey = mDisplay->hardwareIntegration()->serverBufferIntegration(); + } + + if (targetKey.isEmpty()) { + qWarning("Failed to determin what server buffer integration to use"); + return; + } + + QStringList keys = QWaylandServerBufferIntegrationFactory::keys(); + if (keys.contains(targetKey)) { + mServerBufferIntegration = QWaylandServerBufferIntegrationFactory::create(targetKey, QStringList()); + } + if (mServerBufferIntegration) + mServerBufferIntegration->initialize(mDisplay); + else + qWarning("Failed to load server buffer integration %s\n", qPrintable(targetKey)); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandintegration.h b/src/client/qwaylandintegration_p.h index fe9b113e..7c062c0e 100644 --- a/src/plugins/platforms/wayland_common/qwaylandintegration.h +++ b/src/client/qwaylandintegration_p.h @@ -44,13 +44,15 @@ #include <qpa/qplatformintegration.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> QT_BEGIN_NAMESPACE class QWaylandBuffer; class QWaylandDisplay; -class QAbstractEventDispatcher; +class QWaylandClientBufferIntegration; +class QWaylandServerBufferIntegration; -class QWaylandIntegration : public QPlatformIntegration +class Q_WAYLAND_CLIENT_EXPORT QWaylandIntegration : public QPlatformIntegration { public: QWaylandIntegration(); @@ -61,7 +63,8 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAbstractEventDispatcher *createEventDispatcher() const; + void initialize(); QPlatformFontDatabase *fontDatabase() const; @@ -85,15 +88,23 @@ public: QPlatformTheme *createPlatformTheme(const QString &name) const; + virtual QWaylandClientBufferIntegration *clientBufferIntegration() const; + virtual QWaylandServerBufferIntegration *serverBufferIntegration() const; +protected: + QWaylandClientBufferIntegration *mClientBufferIntegration; + QWaylandServerBufferIntegration *mServerBufferIntegration; private: + void initializeClientBufferIntegration(); + void initializeServerBufferIntegration(); QPlatformFontDatabase *mFontDb; - QAbstractEventDispatcher *mEventDispatcher; QPlatformClipboard *mClipboard; QPlatformDrag *mDrag; QWaylandDisplay *mDisplay; QPlatformNativeInterface *mNativeInterface; - QPlatformInputContext *mInputContext; + QScopedPointer<QPlatformInputContext> mInputContext; QPlatformAccessibility *mAccessibility; + bool mClientBufferIntegrationInitialized; + bool mServerBufferIntegrationInitialized; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp index 354e8dba..f8d95bb2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp +++ b/src/client/qwaylandnativeinterface.cpp @@ -39,13 +39,13 @@ ** ****************************************************************************/ -#include "qwaylandnativeinterface.h" -#include "qwaylanddisplay.h" -#include "qwaylandwindow.h" -#include "qwaylandextendedsurface.h" -#include "qwaylandintegration.h" -#include "qwaylanddisplay.h" -#include "qwaylandwindowmanagerintegration.h" +#include "qwaylandnativeinterface_p.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandwindow_p.h" +#include "qwaylandextendedsurface_p.h" +#include "qwaylandintegration_p.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandwindowmanagerintegration_p.h" #include <QtGui/private/qguiapplication_p.h> #include <QtGui/QScreen> @@ -60,10 +60,12 @@ void *QWaylandNativeInterface::nativeResourceForIntegration(const QByteArray &re { QByteArray lowerCaseResource = resourceString.toLower(); - if (lowerCaseResource == "display") + if (lowerCaseResource == "display" || lowerCaseResource == "wl_display") return m_integration->display()->wl_display(); if (lowerCaseResource == "compositor") return const_cast<wl_compositor *>(m_integration->display()->wl_compositor()); + if (lowerCaseResource == "server_buffer_integration") + return m_integration->serverBufferIntegration(); return 0; } diff --git a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.h b/src/client/qwaylandnativeinterface_p.h index 5c1fe601..b9ee2d0e 100644 --- a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.h +++ b/src/client/qwaylandnativeinterface_p.h @@ -42,7 +42,7 @@ #ifndef QWAYLANDNATIVEINTERFACE_H #define QWAYLANDNATIVEINTERFACE_H -#include "qwaylandscreen.h" +#include <QtWaylandClient/private/qwaylandscreen_p.h> #include <QVariantMap> #include <qpa/qplatformnativeinterface.h> @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE class QWaylandIntegration; -class QWaylandNativeInterface : public QPlatformNativeInterface +class Q_WAYLAND_CLIENT_EXPORT QWaylandNativeInterface : public QPlatformNativeInterface { public: QWaylandNativeInterface(QWaylandIntegration *integration); diff --git a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp b/src/client/qwaylandqtkey.cpp index e723078c..263390a1 100644 --- a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp +++ b/src/client/qwaylandqtkey.cpp @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#include "qwaylandqtkey.h" -#include "qwaylandinputdevice.h" +#include "qwaylandqtkey_p.h" +#include "qwaylandinputdevice_p.h" QT_BEGIN_NAMESPACE @@ -50,25 +50,26 @@ QWaylandQtKeyExtension::QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_ { } -void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, - uint32_t type, - uint32_t key, - uint32_t modifiers, - uint32_t nativeScanCode, - uint32_t nativeVirtualKey, - uint32_t nativeModifiers, - const QString &text, - uint32_t autorep, - uint32_t count) +void QWaylandQtKeyExtension::key_extension_qtkey(struct wl_surface *surface, + uint32_t time, + uint32_t type, + uint32_t key, + uint32_t modifiers, + uint32_t nativeScanCode, + uint32_t nativeVirtualKey, + uint32_t nativeModifiers, + const QString &text, + uint32_t autorep, + uint32_t count) { QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices(); - if (inputDevices.isEmpty()) { + if (!surface && inputDevices.isEmpty()) { qWarning("qt_key_extension: handle_qtkey: No input device"); return; } QWaylandInputDevice *dev = inputDevices.first(); - QWaylandWindow *win = dev->mKeyboardFocus; + QWaylandWindow *win = surface ? QWaylandWindow::fromWlSurface(surface) : dev->keyboardFocus(); if (!win || !win->window()) { qWarning("qt_key_extension: handle_qtkey: No keyboard focus"); diff --git a/src/plugins/platforms/wayland_common/qwaylandqtkey.h b/src/client/qwaylandqtkey_p.h index 17b758cf..a9c4e99f 100644 --- a/src/plugins/platforms/wayland_common/qwaylandqtkey.h +++ b/src/client/qwaylandqtkey_p.h @@ -42,14 +42,14 @@ #ifndef QWAYLANDQTKEY_H #define QWAYLANDQTKEY_H -#include "qwaylanddisplay.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <qpa/qwindowsysteminterface.h> -#include "qwayland-qtkey-extension.h" +#include <QtWaylandClient/private/qwayland-qtkey-extension.h> QT_BEGIN_NAMESPACE -class QWaylandQtKeyExtension : public QtWayland::qt_key_extension +class Q_WAYLAND_CLIENT_EXPORT QWaylandQtKeyExtension : public QtWayland::qt_key_extension { public: QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id); @@ -57,16 +57,18 @@ public: private: QWaylandDisplay *m_display; - void key_extension_qtkey(uint32_t time, - uint32_t type, - uint32_t key, - uint32_t modifiers, - uint32_t nativeScanCode, - uint32_t nativeVirtualKey, - uint32_t nativeModifiers, - const QString &text, - uint32_t autorep, - uint32_t count) Q_DECL_OVERRIDE; + void key_extension_qtkey(struct wl_surface *surface, + uint32_t time, + uint32_t type, + uint32_t key, + uint32_t modifiers, + uint32_t nativeScanCode, + uint32_t nativeVirtualKey, + uint32_t nativeModifiers, + const QString &text, + uint32_t autorep, + uint32_t count) Q_DECL_OVERRIDE; + }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp index 5956c2fd..416b320a 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp +++ b/src/client/qwaylandscreen.cpp @@ -39,11 +39,11 @@ ** ****************************************************************************/ -#include "qwaylandscreen.h" +#include "qwaylandscreen_p.h" -#include "qwaylanddisplay.h" -#include "qwaylandcursor.h" -#include "qwaylandextendedoutput.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandcursor_p.h" +#include "qwaylandextendedoutput_p.h" #include <qpa/qwindowsysteminterface.h> @@ -88,6 +88,15 @@ QImage::Format QWaylandScreen::format() const return mFormat; } +QDpi QWaylandScreen::logicalDpi() const +{ + static int force_dpi = !qgetenv("QT_WAYLAND_FORCE_DPI").isEmpty() ? qgetenv("QT_WAYLAND_FORCE_DPI").toInt() : -1; + if (force_dpi > 0) + return QDpi(force_dpi, force_dpi); + + return QPlatformScreen::logicalDpi(); +} + void QWaylandScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) { if (mExtendedOutput) diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.h b/src/client/qwaylandscreen_p.h index 91848ad0..42408acf 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.h +++ b/src/client/qwaylandscreen_p.h @@ -43,8 +43,9 @@ #define QWAYLANDSCREEN_H #include <qpa/qplatformscreen.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> -#include <qwayland-wayland.h> +#include <QtWaylandClient/private/qwayland-wayland.h> QT_BEGIN_NAMESPACE @@ -52,7 +53,7 @@ class QWaylandDisplay; class QWaylandCursor; class QWaylandExtendedOutput; -class QWaylandScreen : public QPlatformScreen, QtWayland::wl_output +class Q_WAYLAND_CLIENT_EXPORT QWaylandScreen : public QPlatformScreen, QtWayland::wl_output { public: QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id); @@ -64,6 +65,8 @@ public: int depth() const; QImage::Format format() const; + QDpi logicalDpi() const Q_DECL_OVERRIDE; + void setOrientationUpdateMask(Qt::ScreenOrientations mask); Qt::ScreenOrientation orientation() const; diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp b/src/client/qwaylandshellsurface.cpp index 6e638e6b..b7a819fd 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp +++ b/src/client/qwaylandshellsurface.cpp @@ -39,13 +39,13 @@ ** ****************************************************************************/ -#include "qwaylandshellsurface.h" +#include "qwaylandshellsurface_p.h" -#include "qwaylanddisplay.h" -#include "qwaylandwindow.h" -#include "qwaylandinputdevice.h" -#include "qwaylanddecoration.h" -#include "qwaylandscreen.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandwindow_p.h" +#include "qwaylandinputdevice_p.h" +#include "qwaylanddecoration_p.h" +#include "qwaylandscreen_p.h" #include <QtCore/QDebug> @@ -88,7 +88,7 @@ void QWaylandShellSurface::setFullscreen() { m_fullscreen = true; m_size = m_window->window()->geometry().size(); - set_fullscreen(0, 0, 0); + set_fullscreen(WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, 0); } void QWaylandShellSurface::setNormal() diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h b/src/client/qwaylandshellsurface_p.h index 172a0f96..2477c3f0 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h +++ b/src/client/qwaylandshellsurface_p.h @@ -46,7 +46,8 @@ #include <wayland-client.h> -#include "qwayland-wayland.h" +#include <QtWaylandClient/private/qwayland-wayland.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> QT_BEGIN_NAMESPACE @@ -54,7 +55,7 @@ class QWaylandWindow; class QWaylandInputDevice; class QWindow; -class QWaylandShellSurface : public QtWayland::wl_shell_surface +class Q_WAYLAND_CLIENT_EXPORT QWaylandShellSurface : public QtWayland::wl_shell_surface { public: QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window); diff --git a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp index 00a4b13a..41f7da20 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp +++ b/src/client/qwaylandshmbackingstore.cpp @@ -38,14 +38,14 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "qwaylandshmbackingstore.h" +#include "qwaylandshmbackingstore_p.h" #include <QtCore/qdebug.h> -#include "qwaylanddisplay.h" -#include "qwaylandshmwindow.h" -#include "qwaylandscreen.h" -#include "qwaylanddecoration.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandshmwindow_p.h" +#include "qwaylandscreen_p.h" +#include "qwaylanddecoration_p.h" #include <QtGui/QPainter> diff --git a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h b/src/client/qwaylandshmbackingstore_p.h index 60117342..1affafab 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h +++ b/src/client/qwaylandshmbackingstore_p.h @@ -42,10 +42,10 @@ #ifndef QWAYLANDSHMBACKINGSTORE_H #define QWAYLANDSHMBACKINGSTORE_H -#include "qwaylandbuffer.h" +#include <QtWaylandClient/private/qwaylandbuffer_p.h> -#include "qwaylanddecoration.h" -#include "qwaylandshmwindow.h" +#include <QtWaylandClient/private/qwaylanddecoration_p.h> +#include <QtWaylandClient/private/qwaylandshmwindow_p.h> #include <qpa/qplatformbackingstore.h> #include <QtGui/QImage> @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE class QWaylandDisplay; -class QWaylandShmBuffer : public QWaylandBuffer { +class Q_WAYLAND_CLIENT_EXPORT QWaylandShmBuffer : public QWaylandBuffer { public: QWaylandShmBuffer(QWaylandDisplay *display, const QSize &size, QImage::Format format); @@ -71,7 +71,7 @@ private: QImage *mMarginsImage; }; -class QWaylandShmBackingStore : public QPlatformBackingStore +class Q_WAYLAND_CLIENT_EXPORT QWaylandShmBackingStore : public QPlatformBackingStore { public: QWaylandShmBackingStore(QWindow *window); diff --git a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp b/src/client/qwaylandshmwindow.cpp index 48a1bfd5..de87682c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp +++ b/src/client/qwaylandshmwindow.cpp @@ -39,9 +39,9 @@ ** ****************************************************************************/ -#include "qwaylandshmwindow.h" +#include "qwaylandshmwindow_p.h" -#include "qwaylandbuffer.h" +#include "qwaylandbuffer_p.h" #include <QtCore/QVector> diff --git a/src/plugins/platforms/wayland_common/qwaylandshmwindow.h b/src/client/qwaylandshmwindow_p.h index ffd11c94..83479f31 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmwindow.h +++ b/src/client/qwaylandshmwindow_p.h @@ -42,14 +42,14 @@ #ifndef QWAYLANDSHMWINDOW_H #define QWAYLANDSHMWINDOW_H -#include "qwaylandwindow.h" +#include <QtWaylandClient/private/qwaylandwindow_p.h> #include <QtGui/QRegion> QT_BEGIN_NAMESPACE class QWaylandShmBackingStore; -class QWaylandShmWindow : public QWaylandWindow +class Q_WAYLAND_CLIENT_EXPORT QWaylandShmWindow : public QWaylandWindow { public: QWaylandShmWindow(QWindow *window); diff --git a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp b/src/client/qwaylandsubsurface.cpp index 0e9d575a..6db59fa2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp +++ b/src/client/qwaylandsubsurface.cpp @@ -39,9 +39,9 @@ ** ****************************************************************************/ -#include "qwaylandsubsurface.h" +#include "qwaylandsubsurface_p.h" -#include "qwaylandwindow.h" +#include "qwaylandwindow_p.h" #include <QtCore/QDebug> diff --git a/src/plugins/platforms/wayland_common/qwaylandsubsurface.h b/src/client/qwaylandsubsurface_p.h index 10290d8c..bd0da96d 100644 --- a/src/plugins/platforms/wayland_common/qwaylandsubsurface.h +++ b/src/client/qwaylandsubsurface_p.h @@ -46,7 +46,9 @@ #include <QtCore/qglobal.h> -#include <qwayland-sub-surface-extension.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + +#include <QtWaylandClient/private/qwayland-sub-surface-extension.h> QT_BEGIN_NAMESPACE @@ -54,7 +56,7 @@ class QWaylandDisplay; class QWaylandWindow; class QWaylandSubSurface; -class QWaylandSubSurface : public QtWayland::qt_sub_surface +class Q_WAYLAND_CLIENT_EXPORT QWaylandSubSurface : public QtWayland::qt_sub_surface { public: QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface); diff --git a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp b/src/client/qwaylandtouch.cpp index 5835d9d3..01a19926 100644 --- a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp +++ b/src/client/qwaylandtouch.cpp @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#include "qwaylandtouch.h" -#include "qwaylandinputdevice.h" +#include "qwaylandtouch_p.h" +#include "qwaylandinputdevice_p.h" QT_BEGIN_NAMESPACE @@ -83,11 +83,11 @@ void QWaylandTouchExtension::touch_extension_touch(uint32_t time, } mInputDevice = inputDevices.first(); } - QWaylandWindow *win = mInputDevice->mTouchFocus; + QWaylandWindow *win = mInputDevice->touchFocus(); if (!win) - win = mInputDevice->mPointerFocus; + win = mInputDevice->pointerFocus(); if (!win) - win = mInputDevice->mKeyboardFocus; + win = mInputDevice->keyboardFocus(); if (!win || !win->window()) { qWarning("qt_touch_extension: handle_touch: No pointer focus"); return; diff --git a/src/plugins/platforms/wayland_common/qwaylandtouch.h b/src/client/qwaylandtouch_p.h index 3762209d..c00c7c0d 100644 --- a/src/plugins/platforms/wayland_common/qwaylandtouch.h +++ b/src/client/qwaylandtouch_p.h @@ -42,14 +42,14 @@ #ifndef QWAYLANDTOUCh_H #define QWAYLANDTOUCH_H -#include "qwaylanddisplay.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <qpa/qwindowsysteminterface.h> -#include <qwayland-touch-extension.h> +#include <QtWaylandClient/private/qwayland-touch-extension.h> QT_BEGIN_NAMESPACE -class QWaylandTouchExtension : public QtWayland::qt_touch_extension +class Q_WAYLAND_CLIENT_EXPORT QWaylandTouchExtension : public QtWayland::qt_touch_extension { public: QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id); diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 27b624fb..810239a7 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -39,17 +39,17 @@ ** ****************************************************************************/ -#include "qwaylandwindow.h" - -#include "qwaylandbuffer.h" -#include "qwaylanddisplay.h" -#include "qwaylandinputdevice.h" -#include "qwaylandscreen.h" -#include "qwaylandshellsurface.h" -#include "qwaylandextendedsurface.h" -#include "qwaylandsubsurface.h" -#include "qwaylanddecoration.h" -#include "qwaylandwindowmanagerintegration.h" +#include "qwaylandwindow_p.h" + +#include "qwaylandbuffer_p.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandinputdevice_p.h" +#include "qwaylandscreen_p.h" +#include "qwaylandshellsurface_p.h" +#include "qwaylandextendedsurface_p.h" +#include "qwaylandsubsurface_p.h" +#include "qwaylanddecoration_p.h" +#include "qwaylandwindowmanagerintegration_p.h" #include <QtCore/QFileInfo> #include <QtGui/QWindow> @@ -61,6 +61,8 @@ QT_BEGIN_NAMESPACE +QWaylandWindow *QWaylandWindow::mMouseGrab = 0; + QWaylandWindow::QWaylandWindow(QWindow *window) : QObject() , QPlatformWindow(window) @@ -72,6 +74,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mWindowDecoration(0) , mMouseEventsInContentArea(false) , mMousePressedInContentArea(Qt::NoButton) + , m_cursorShape(Qt::ArrowCursor) , mBuffer(0) , mWaitingForFrameSync(false) , mFrameCallback(0) @@ -95,6 +98,9 @@ QWaylandWindow::QWaylandWindow(QWindow *window) mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(object())); if (mShellSurface) { + // Set initial surface title + mShellSurface->set_title(window->title()); + // Set surface class to the .desktop file name (obtained from executable name) QFileInfo exeFileInfo(qApp->applicationFilePath()); QString className = exeFileInfo.baseName() + QLatin1String(".desktop"); @@ -113,7 +119,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window) setWindowFlags(window->flags()); setGeometry(window->geometry()); - + setWindowState(window->windowState()); } QWaylandWindow::~QWaylandWindow() @@ -135,6 +141,10 @@ QWaylandWindow::~QWaylandWindow() if (w->transientParent() == parent) QWindowSystemInterface::handleCloseEvent(w); } + + if (mMouseGrab == this) { + mMouseGrab = 0; + } } QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) @@ -175,17 +185,19 @@ void QWaylandWindow::setWindowIcon(const QIcon &icon) void QWaylandWindow::setGeometry(const QRect &rect) { - QPlatformWindow::setGeometry(rect); + QPlatformWindow::setGeometry(QRect(rect.x(), rect.y(), + qBound(window()->minimumWidth(), rect.width(), window()->maximumWidth()), + qBound(window()->minimumHeight(), rect.height(), window()->maximumHeight()))); - if (shellSurface() && window()->transientParent()) + if (shellSurface() && window()->transientParent() && window()->type() != Qt::Popup) shellSurface()->updateTransientParent(window()->transientParent()); if (mWindowDecoration && window()->isVisible()) mWindowDecoration->update(); if (mConfigure.isEmpty()) { - QWindowSystemInterface::handleGeometryChange(window(), rect); - QWindowSystemInterface::handleExposeEvent(window(), QRegion(rect)); + QWindowSystemInterface::handleGeometryChange(window(), geometry()); + QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); } } @@ -200,7 +212,8 @@ void QWaylandWindow::setVisible(bool visible) mMouseDevice = parent->mMouseDevice; mMouseSerial = parent->mMouseSerial; - mShellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial); + if (mMouseDevice) + mShellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial); } if (!mSentInitialResize) { @@ -575,4 +588,21 @@ void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device) setMouseCursor(device, window()->cursor().shape()); } +void QWaylandWindow::requestActivateWindow() +{ + // no-op. Wayland does not have activation protocol, + // we rely on compositor setting keyboard focus based on window stacking. +} + +bool QWaylandWindow::setMouseGrabEnabled(bool grab) +{ + if (window()->type() != Qt::Popup) { + qWarning("This plugin supports grabbing the mouse only for popup windows"); + return false; + } + + mMouseGrab = grab ? this : 0; + return true; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.h b/src/client/qwaylandwindow_p.h index 8fd104d0..6078dab7 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.h +++ b/src/client/qwaylandwindow_p.h @@ -48,9 +48,9 @@ #include <qpa/qplatformwindow.h> -#include "qwaylanddisplay.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> -#include "qwayland-wayland.h" +#include <QtWaylandClient/private/qwayland-wayland.h> struct wl_egl_window; @@ -63,7 +63,7 @@ class QWaylandExtendedSurface; class QWaylandSubSurface; class QWaylandDecoration; -class QWaylandWindowConfigure +class Q_WAYLAND_CLIENT_EXPORT QWaylandWindowConfigure { public: QWaylandWindowConfigure() @@ -83,7 +83,7 @@ public: uint32_t edges; }; -class QWaylandWindow : public QObject, public QPlatformWindow, public QtWayland::wl_surface +class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow, public QtWayland::wl_surface { Q_OBJECT public: @@ -136,6 +136,8 @@ public: void raise() Q_DECL_OVERRIDE; void lower() Q_DECL_OVERRIDE; + void requestActivateWindow() Q_DECL_OVERRIDE; + QWaylandDecoration *decoration() const; void setDecoration(QWaylandDecoration *decoration); @@ -162,6 +164,10 @@ public: QMutex *resizeMutex() { return &mResizeLock; } void doResize(); void setCanResize(bool canResize); + + bool setMouseGrabEnabled(bool grab); + static QWaylandWindow *mouseGrab() { return mMouseGrab; } + public slots: void requestResize(); @@ -209,6 +215,7 @@ private: static void frameCallback(void *data, struct wl_callback *wl_callback, uint32_t time); static QMutex mFrameSyncMutex; + static QWaylandWindow *mMouseGrab; }; inline QIcon QWaylandWindow::windowIcon() const diff --git a/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.cpp b/src/client/qwaylandwindowmanagerintegration.cpp index 7543ba13..9e8ce88c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.cpp +++ b/src/client/qwaylandwindowmanagerintegration.cpp @@ -39,9 +39,9 @@ ** ****************************************************************************/ -#include "qwaylandwindowmanagerintegration.h" -#include "qwaylandscreen.h" -#include "qwaylandwindow.h" +#include "qwaylandwindowmanagerintegration_p.h" +#include "qwaylandscreen_p.h" +#include "qwaylandwindow_p.h" #include <stdint.h> #include <QtCore/QEvent> @@ -93,7 +93,7 @@ bool QWaylandWindowManagerIntegration::showIsFullScreen() const void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "qt_windowmanager") + if (interface == QStringLiteral("qt_windowmanager")) static_cast<QWaylandWindowManagerIntegration *>(data)->init(registry, id); } diff --git a/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.h b/src/client/qwaylandwindowmanagerintegration_p.h index 4524ce12..844b122a 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.h +++ b/src/client/qwaylandwindowmanagerintegration_p.h @@ -45,19 +45,18 @@ #include <QtCore/QObject> #include <QtCore/QScopedPointer> -#include "wayland-client.h" -#include "qwaylanddisplay.h" +#include <wayland-client.h> +#include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <qpa/qplatformservices.h> -#include "qwayland-windowmanager.h" +#include <QtWaylandClient/private/qwayland-windowmanager.h> QT_BEGIN_NAMESPACE class QWaylandWindow; - class QWaylandWindowManagerIntegrationPrivate; -class QWaylandWindowManagerIntegration : public QObject, public QPlatformServices, public QtWayland::qt_windowmanager +class Q_WAYLAND_CLIENT_EXPORT QWaylandWindowManagerIntegration : public QObject, public QPlatformServices, public QtWayland::qt_windowmanager { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandWindowManagerIntegration) diff --git a/src/compositor/compositor.pro b/src/compositor/compositor.pro index 8dc485ff..74c955dd 100644 --- a/src/compositor/compositor.pro +++ b/src/compositor/compositor.pro @@ -10,7 +10,7 @@ CONFIG += link_pkgconfig DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT !contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += wayland-server + PKGCONFIG_PRIVATE += wayland-server } else { LIBS += -lwayland-server } @@ -18,7 +18,6 @@ DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT INCLUDEPATH += ../shared HEADERS += ../shared/qwaylandmimehelper.h SOURCES += ../shared/qwaylandmimehelper.cpp -HEADERS += qwayland-server-wayland.h include ($$PWD/global/global.pri) include ($$PWD/wayland_wrapper/wayland_wrapper.pri) diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri index f0bbe764..06d89554 100644 --- a/src/compositor/compositor_api/compositor_api.pri +++ b/src/compositor/compositor_api/compositor_api.pri @@ -3,25 +3,27 @@ INCLUDEPATH += compositor_api HEADERS += \ compositor_api/qwaylandcompositor.h \ compositor_api/qwaylandsurface.h \ - compositor_api/qwaylandinput.h + compositor_api/qwaylandinput.h \ + compositor_api/qwaylandinputpanel.h \ + compositor_api/qwaylanddrag.h SOURCES += \ compositor_api/qwaylandcompositor.cpp \ compositor_api/qwaylandsurface.cpp \ - compositor_api/qwaylandinput.cpp + compositor_api/qwaylandinput.cpp \ + compositor_api/qwaylandinputpanel.cpp \ + compositor_api/qwaylanddrag.cpp QT += core-private qtHaveModule(quick) { SOURCES += \ compositor_api/qwaylandsurfaceitem.cpp \ - compositor_api/qwaylandsurfacenode.cpp \ - compositor_api/qwaylandsurfacetexturematerial.cpp + compositor_api/qwaylandsurfacenode.cpp HEADERS += \ compositor_api/qwaylandsurfaceitem.h \ - compositor_api/qwaylandsurfacenode_p.h \ - compositor_api/qwaylandsurfacetexturematerial_p.h + compositor_api/qwaylandsurfacenode_p.h DEFINES += QT_COMPOSITOR_QUICK diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index c1300994..916dad91 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -43,8 +43,10 @@ #include "qwaylandinput.h" #include "wayland_wrapper/qwlcompositor_p.h" +#include "wayland_wrapper/qwldatadevice_p.h" #include "wayland_wrapper/qwlsurface_p.h" #include "wayland_wrapper/qwlinputdevice_p.h" +#include "wayland_wrapper/qwlinputpanel_p.h" #include <QtCore/QCoreApplication> #include <QtCore/QStringList> @@ -59,7 +61,7 @@ QT_BEGIN_NAMESPACE -QWaylandCompositor::QWaylandCompositor(QWindow *window, const char *socketName) +QWaylandCompositor::QWaylandCompositor(QWindow *window, const char *socketName, ExtensionFlags extensions) : m_compositor(0) , m_toplevel_window(window) , m_socket_name(socketName) @@ -70,7 +72,7 @@ QWaylandCompositor::QWaylandCompositor(QWindow *window, const char *socketName) if (socketArg != -1 && socketArg + 1 < arguments.size()) m_socket_name = arguments.at(socketArg + 1).toLocal8Bit(); - m_compositor = new QtWayland::Compositor(this); + m_compositor = new QtWayland::Compositor(this, extensions); #ifdef QT_COMPOSITOR_QUICK qmlRegisterType<QWaylandSurfaceItem>("WaylandCompositor", 1, 0, "WaylandSurfaceItem"); qmlRegisterType<QWaylandSurface>("WaylandCompositor", 1, 0, "WaylandSurface"); @@ -145,6 +147,21 @@ void QWaylandCompositor::surfaceAboutToBeDestroyed(QWaylandSurface *surface) Q_UNUSED(surface); } +QWaylandSurface *QWaylandCompositor::pickSurface(const QPointF &globalPosition) const +{ + Q_FOREACH (QtWayland::Surface *surface, m_compositor->surfaces()) { + if (QRectF(surface->pos(), surface->size()).contains(globalPosition)) + return surface->waylandSurface(); + } + + return 0; +} + +QPointF QWaylandCompositor::mapToSurface(QWaylandSurface *surface, const QPointF &globalPosition) const +{ + return globalPosition - surface->pos(); +} + /*! Override this to handle QDesktopServices::openUrl() requests from the clients. @@ -161,25 +178,21 @@ QtWayland::Compositor * QWaylandCompositor::handle() const return m_compositor; } -void QWaylandCompositor::setRetainedSelectionEnabled(bool enable) +void QWaylandCompositor::setRetainedSelectionEnabled(bool enabled) { - if (enable) - m_compositor->setRetainedSelectionWatcher(retainedSelectionChanged, this); - else - m_compositor->setRetainedSelectionWatcher(0, 0); + m_compositor->setRetainedSelectionEnabled(enabled); } -void QWaylandCompositor::retainedSelectionChanged(QMimeData *mimeData, void *param) +bool QWaylandCompositor::retainedSelectionEnabled() const { - QWaylandCompositor *self = static_cast<QWaylandCompositor *>(param); - self->retainedSelectionReceived(mimeData); + return m_compositor->retainedSelectionEnabled(); } void QWaylandCompositor::retainedSelectionReceived(QMimeData *) { } -void QWaylandCompositor::overrideSelection(QMimeData *data) +void QWaylandCompositor::overrideSelection(const QMimeData *data) { m_compositor->overrideSelection(data); } @@ -229,6 +242,16 @@ QWaylandInputDevice *QWaylandCompositor::defaultInputDevice() const return m_compositor->defaultInputDevice()->handle(); } +QWaylandInputPanel *QWaylandCompositor::inputPanel() const +{ + return m_compositor->inputPanel()->handle(); +} + +QWaylandDrag *QWaylandCompositor::drag() const +{ + return m_compositor->defaultInputDevice()->dragHandle(); +} + bool QWaylandCompositor::isDragging() const { return m_compositor->isDragging(); @@ -250,17 +273,6 @@ void QWaylandCompositor::setCursorSurface(QWaylandSurface *surface, int hotspotX Q_UNUSED(surface); Q_UNUSED(hotspotX); Q_UNUSED(hotspotY); - qDebug() << "changeCursor" << surface->size() << hotspotX << hotspotY; -} - -void QWaylandCompositor::enableSubSurfaceExtension() -{ - m_compositor->enableSubSurfaceExtension(); -} - -void QWaylandCompositor::enableTouchExtension() -{ - // nothing to do here } void QWaylandCompositor::configureTouchExtension(TouchExtensionFlags flags) diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index cd1f9bd3..40a151c5 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -54,6 +54,8 @@ class QUrl; class QOpenGLContext; class QWaylandSurface; class QWaylandInputDevice; +class QWaylandInputPanel; +class QWaylandDrag; namespace QtWayland { @@ -63,7 +65,21 @@ namespace QtWayland class Q_COMPOSITOR_EXPORT QWaylandCompositor { public: - QWaylandCompositor(QWindow *window = 0, const char *socketName = 0); + enum ExtensionFlag { + WindowManagerExtension = 0x01, + OutputExtension = 0x02, + SurfaceExtension = 0x04, + QtKeyExtension = 0x08, + TouchExtension = 0x10, + SubSurfaceExtension = 0x20, + TextInputExtension = 0x40, + HardwareIntegrationExtension = 0x80, + + DefaultExtensions = WindowManagerExtension | OutputExtension | SurfaceExtension | QtKeyExtension | TouchExtension | HardwareIntegrationExtension + }; + Q_DECLARE_FLAGS(ExtensionFlags, ExtensionFlag) + + QWaylandCompositor(QWindow *window = 0, const char *socketName = 0, ExtensionFlags extensions = DefaultExtensions); virtual ~QWaylandCompositor(); struct wl_display *waylandDisplay() const; @@ -83,13 +99,16 @@ public: virtual void surfaceCreated(QWaylandSurface *surface) = 0; virtual void surfaceAboutToBeDestroyed(QWaylandSurface *surface); + virtual QWaylandSurface *pickSurface(const QPointF &globalPosition) const; + virtual QPointF mapToSurface(QWaylandSurface *surface, const QPointF &surfacePosition) const; + virtual void openUrl(WaylandClient *client, const QUrl &url); QtWayland::Compositor *handle() const; - void setRetainedSelectionEnabled(bool enable); - virtual void retainedSelectionReceived(QMimeData *mimeData); - void overrideSelection(QMimeData *data); + void setRetainedSelectionEnabled(bool enabled); + bool retainedSelectionEnabled() const; + void overrideSelection(const QMimeData *data); void setClientFullScreenHint(bool value); @@ -105,29 +124,32 @@ public: QWaylandInputDevice *defaultInputDevice() const; + QWaylandInputPanel *inputPanel() const; + QWaylandDrag *drag() const; + bool isDragging() const; void sendDragMoveEvent(const QPoint &global, const QPoint &local, QWaylandSurface *surface); void sendDragEndEvent(); virtual void setCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY); - void enableSubSurfaceExtension(); - - void enableTouchExtension(); enum TouchExtensionFlag { TouchExtMouseFromTouch = 0x01 }; Q_DECLARE_FLAGS(TouchExtensionFlags, TouchExtensionFlag) void configureTouchExtension(TouchExtensionFlags flags); -private: - static void retainedSelectionChanged(QMimeData *mimeData, void *param); +protected: + virtual void retainedSelectionReceived(QMimeData *mimeData); +private: + friend class QtWayland::Compositor; QtWayland::Compositor *m_compositor; QWindow *m_toplevel_window; QByteArray m_socket_name; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandCompositor::ExtensionFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandCompositor::TouchExtensionFlags) QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylanddrag.cpp b/src/compositor/compositor_api/qwaylanddrag.cpp new file mode 100644 index 00000000..def76392 --- /dev/null +++ b/src/compositor/compositor_api/qwaylanddrag.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylanddrag.h" + +#include <private/qobject_p.h> + +#include "qwlcompositor_p.h" +#include "qwlinputdevice_p.h" +#include "qwldatadevice_p.h" +#include "qwlsurface_p.h" + +QT_BEGIN_NAMESPACE + +class QWaylandDragPrivate : public QObjectPrivate +{ +public: + QWaylandDragPrivate(QtWayland::InputDevice *id) + : inputDevice(id) + { + } + + QtWayland::InputDevice *inputDevice; +}; + + +QWaylandDrag::QWaylandDrag(QtWayland::InputDevice *inputDevice) + : QObject(* new QWaylandDragPrivate(inputDevice)) +{ +} + +QWaylandSurface *QWaylandDrag::icon() const +{ + Q_D(const QWaylandDrag); + + const QtWayland::DataDevice *dataDevice = d->inputDevice->dataDevice(); + if (!dataDevice) + return 0; + + return dataDevice->dragIcon() ? dataDevice->dragIcon()->waylandSurface() : 0; +} + +bool QWaylandDrag::visible() const +{ + Q_D(const QWaylandDrag); + + const QtWayland::DataDevice *dataDevice = d->inputDevice->dataDevice(); + if (!dataDevice) + return false; + + return dataDevice->dragIcon() != 0; +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylanddrag.h b/src/compositor/compositor_api/qwaylanddrag.h new file mode 100644 index 00000000..888a48a9 --- /dev/null +++ b/src/compositor/compositor_api/qwaylanddrag.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDDRAG_H +#define QWAYLANDDRAG_H + +#include <QtCompositor/qwaylandexport.h> + +#include <QObject> + +QT_BEGIN_NAMESPACE + +class QWaylandDragPrivate; +class QWaylandSurface; + +namespace QtWayland { +class InputDevice; +} +class Q_COMPOSITOR_EXPORT QWaylandDrag : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandDrag) + + Q_PROPERTY(QWaylandSurface* icon READ icon NOTIFY iconChanged) + Q_PROPERTY(bool visible READ visible NOTIFY iconChanged) + +public: + explicit QWaylandDrag(QtWayland::InputDevice *inputDevice); + + QWaylandSurface *icon() const; + bool visible() const; + +Q_SIGNALS: + void iconChanged(); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDDRAG_H diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandinput.cpp index 76e83030..c2b7c510 100644 --- a/src/compositor/compositor_api/qwaylandinput.cpp +++ b/src/compositor/compositor_api/qwaylandinput.cpp @@ -122,6 +122,11 @@ void QWaylandInputDevice::sendFullKeyEvent(QKeyEvent *event) d->sendFullKeyEvent(event); } +void QWaylandInputDevice::sendFullKeyEvent(QWaylandSurface *surface, QKeyEvent *event) +{ + d->sendFullKeyEvent(surface->handle(), event); +} + QWaylandSurface *QWaylandInputDevice::keyboardFocus() const { QtWayland::Surface *wlsurface = d->keyboardFocus(); diff --git a/src/compositor/compositor_api/qwaylandinput.h b/src/compositor/compositor_api/qwaylandinput.h index b9d66178..8e453af4 100644 --- a/src/compositor/compositor_api/qwaylandinput.h +++ b/src/compositor/compositor_api/qwaylandinput.h @@ -73,6 +73,7 @@ public: void sendKeyReleaseEvent(uint code); void sendFullKeyEvent(QKeyEvent *event); + void sendFullKeyEvent(QWaylandSurface *surface, QKeyEvent *event); void sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state); void sendTouchFrameEvent(); diff --git a/src/compositor/compositor_api/qwaylandinputpanel.cpp b/src/compositor/compositor_api/qwaylandinputpanel.cpp new file mode 100644 index 00000000..03084262 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandinputpanel.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandinputpanel.h" + +#include <private/qobject_p.h> + +#include "qwlinputpanel_p.h" +#include "qwlsurface_p.h" + +QT_BEGIN_NAMESPACE + +class QWaylandInputPanelPrivate : public QObjectPrivate +{ +public: + QWaylandInputPanelPrivate(QtWayland::InputPanel *panel) + : inputPanel(panel) + { + } + + QtWayland::InputPanel *inputPanel; +}; + + +QWaylandInputPanel::QWaylandInputPanel(QtWayland::InputPanel *inputPanel) + : QObject(*new QWaylandInputPanelPrivate(inputPanel)) +{ +} + +QtWayland::InputPanel *QWaylandInputPanel::handle() const +{ + Q_D(const QWaylandInputPanel); + + return d->inputPanel; +} + +QWaylandSurface *QWaylandInputPanel::focus() const +{ + Q_D(const QWaylandInputPanel); + + QtWayland::Surface *surface = d->inputPanel->focus(); + if (surface) + return surface->waylandSurface(); + return 0; +} + +bool QWaylandInputPanel::visible() const +{ + Q_D(const QWaylandInputPanel); + + return d->inputPanel->inputPanelVisible(); +} + +QRect QWaylandInputPanel::cursorRectangle() const +{ + Q_D(const QWaylandInputPanel); + + return d->inputPanel->cursorRectangle(); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandinputpanel.h b/src/compositor/compositor_api/qwaylandinputpanel.h new file mode 100644 index 00000000..735756ba --- /dev/null +++ b/src/compositor/compositor_api/qwaylandinputpanel.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDINPUTPANEL_H +#define QWAYLANDINPUTPANEL_H + +#include <QtCompositor/qwaylandexport.h> + +#include <QObject> +#include <QRect> + +QT_BEGIN_NAMESPACE + +class QWaylandCompositor; +class QWaylandInputPanelPrivate; +class QWaylandSurface; + +namespace QtWayland { +class InputPanel; +} + +class Q_COMPOSITOR_EXPORT QWaylandInputPanel : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandInputPanel) + + Q_PROPERTY(QWaylandSurface* focus READ focus NOTIFY focusChanged) + Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged) + Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) + +public: + explicit QWaylandInputPanel(QtWayland::InputPanel *inputPanel); + + QtWayland::InputPanel *handle() const; + + QWaylandSurface *focus() const; + bool visible() const; + QRect cursorRectangle() const; + +Q_SIGNALS: + void focusChanged(); + void visibleChanged(); + void cursorRectangleChanged(); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDINPUTPANEL_H diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 88b68ebd..293ff932 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -47,6 +47,9 @@ #include "wayland_wrapper/qwlsubsurface_p.h" #include "wayland_wrapper/qwlcompositor_p.h" #include "wayland_wrapper/qwlshellsurface_p.h" +#include "wayland_wrapper/qwlinputdevice_p.h" +#include "wayland_wrapper/qwldatadevice_p.h" +#include "wayland_wrapper/qwldatadevicemanager_p.h" #include "qwaylandcompositor.h" #include "waylandwindowmanagerintegration.h" @@ -56,6 +59,7 @@ #ifdef QT_COMPOSITOR_QUICK #include "qwaylandsurfaceitem.h" +#include <QtQml/QQmlPropertyMap> #endif QT_BEGIN_NAMESPACE @@ -67,6 +71,7 @@ public: : surface(srfc) #ifdef QT_COMPOSITOR_QUICK , surface_item(0) + , windowPropertyMap(new QQmlPropertyMap) #endif {} @@ -75,18 +80,28 @@ public: #ifdef QT_COMPOSITOR_QUICK if (surface_item) surface_item->setSurface(0); + if (windowPropertyMap) + windowPropertyMap->deleteLater(); #endif } QtWayland::Surface *surface; #ifdef QT_COMPOSITOR_QUICK QWaylandSurfaceItem *surface_item; + QQmlPropertyMap *windowPropertyMap; #endif }; QWaylandSurface::QWaylandSurface(QtWayland::Surface *surface) : QObject(*new QWaylandSurfacePrivate(surface)) { +#ifdef QT_COMPOSITOR_QUICK + Q_D(QWaylandSurface); + connect(this, &QWaylandSurface::windowPropertyChanged, + d->windowPropertyMap, &QQmlPropertyMap::insert); + connect(d->windowPropertyMap, &QQmlPropertyMap::valueChanged, + this, &QWaylandSurface::setWindowProperty); +#endif } WaylandClient *QWaylandSurface::client() const @@ -178,6 +193,13 @@ QWaylandSurface::WindowFlags QWaylandSurface::windowFlags() const return d->surface->extendedSurface()->windowFlags(); } +QWaylandSurface::WindowType QWaylandSurface::windowType() const +{ + Q_D(const QWaylandSurface); + if (d->surface->shellSurface()) + return d->surface->shellSurface()->windowType(); + return QWaylandSurface::None; +} QImage QWaylandSurface::image() const { @@ -186,13 +208,13 @@ QImage QWaylandSurface::image() const } #ifdef QT_COMPOSITOR_WAYLAND_GL -GLuint QWaylandSurface::texture(QOpenGLContext *context) const +GLuint QWaylandSurface::texture() const { Q_D(const QWaylandSurface); - return d->surface->textureId(context); + return d->surface->textureId(); } #else //QT_COMPOSITOR_WAYLAND_GL -uint QWaylandSurface::texture(QOpenGLContext *) const +uint QWaylandSurface::texture() const { return 0; } @@ -216,6 +238,13 @@ void QWaylandSurface::setSurfaceItem(QWaylandSurfaceItem *surfaceItem) Q_D(QWaylandSurface); d->surface_item = surfaceItem; } + +QObject *QWaylandSurface::windowPropertyMap() const +{ + Q_D(const QWaylandSurface); + return d->windowPropertyMap; +} + #endif //QT_COMPOSITOR_QUICK qint64 QWaylandSurface::processId() const @@ -326,6 +355,13 @@ bool QWaylandSurface::hasShellSurface() const return false; } +bool QWaylandSurface::hasInputPanelSurface() const +{ + Q_D(const QWaylandSurface); + + return d->surface->inputPanelSurface() != 0; +} + /*! * \return True if WL_SHELL_SURFACE_TRANSIENT_INACTIVE was set for this surface, meaning it should not receive keyboard focus. */ @@ -352,4 +388,29 @@ void QWaylandSurface::destroySurfaceByForce() wl_resource_destroy(surface_resource); } +void QWaylandSurface::ping() +{ + Q_D(QWaylandSurface); + if (d->surface->shellSurface()) + d->surface->shellSurface()->ping(); +} + +/*! + Updates the surface with the compositor's retained clipboard selection. While this + is done automatically when the surface receives keyboard focus, this function is + useful for updating clients which do not have keyboard focus. +*/ +void QWaylandSurface::updateSelection() +{ + Q_D(QWaylandSurface); + const QtWayland::InputDevice *inputDevice = d->surface->compositor()->defaultInputDevice(); + if (inputDevice) { + const QtWayland::DataDevice *dataDevice = inputDevice->dataDevice(); + if (dataDevice) { + d->surface->compositor()->dataDeviceManager()->offerRetainedSelection( + dataDevice->resourceMap().value(d->surface->resource()->client())->handle); + } + } +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index 308e8d54..18d4e7e7 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -48,7 +48,6 @@ #include <QtGui/QWindow> #include <QtCore/QVariantMap> -#include <QtGui/QOpenGLContext> #ifdef QT_COMPOSITOR_WAYLAND_GL #include <QtGui/qopengl.h> #endif @@ -76,22 +75,34 @@ class Q_COMPOSITOR_EXPORT QWaylandSurface : public QObject Q_PROPERTY(QSize size READ size NOTIFY sizeChanged) Q_PROPERTY(QPointF pos READ pos WRITE setPos NOTIFY posChanged) Q_PROPERTY(QWaylandSurface::WindowFlags windowFlags READ windowFlags NOTIFY windowFlagsChanged) + Q_PROPERTY(QWaylandSurface::WindowType windowType READ windowType NOTIFY windowTypeChanged) Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation NOTIFY contentOrientationChanged) Q_PROPERTY(QString className READ className NOTIFY classNameChanged) Q_PROPERTY(QString title READ title NOTIFY titleChanged) Q_PROPERTY(Qt::ScreenOrientations orientationUpdateMask READ orientationUpdateMask NOTIFY orientationUpdateMaskChanged) Q_PROPERTY(QWindow::Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) +#ifdef QT_COMPOSITOR_QUICK + Q_PROPERTY(QObject * windowProperties READ windowPropertyMap CONSTANT) +#endif - Q_ENUMS(WindowFlag) + Q_ENUMS(WindowFlag WindowType) Q_FLAGS(WindowFlag WindowFlags) public: enum WindowFlag { OverridesSystemGestures = 0x0001, - StaysOnTop = 0x0002 + StaysOnTop = 0x0002, + BypassWindowManager = 0x0004 }; Q_DECLARE_FLAGS(WindowFlags, WindowFlag) + enum WindowType { + None, + Toplevel, + Transient, + Popup + }; + enum Type { Invalid, Shm, @@ -120,11 +131,13 @@ public: WindowFlags windowFlags() const; + WindowType windowType() const; + QImage image() const; #ifdef QT_COMPOSITOR_WAYLAND_GL - GLuint texture(QOpenGLContext *context) const; + GLuint texture() const; #else - uint texture(QOpenGLContext *context) const; + uint texture() const; #endif QWindow::Visibility visibility() const; @@ -140,6 +153,8 @@ public: #ifdef QT_COMPOSITOR_QUICK QWaylandSurfaceItem *surfaceItem() const; void setSurfaceItem(QWaylandSurfaceItem *surfaceItem); + + QObject *windowPropertyMap() const; #endif qint64 processId() const; @@ -157,11 +172,17 @@ public: QString title() const; bool hasShellSurface() const; + bool hasInputPanelSurface() const; bool transientInactive() const; Q_INVOKABLE void destroySurface(); Q_INVOKABLE void destroySurfaceByForce(); + Q_INVOKABLE void ping(); + +public slots: + void updateSelection(); + signals: void mapped(); void unmapped(); @@ -171,6 +192,7 @@ signals: void posChanged(); void windowPropertyChanged(const QString &name, const QVariant &value); void windowFlagsChanged(WindowFlags flags); + void windowTypeChanged(WindowType type); void contentOrientationChanged(); void orientationUpdateMaskChanged(); void extendedSurfaceReady(); @@ -179,6 +201,7 @@ signals: void raiseRequested(); void lowerRequested(); void visibilityChanged(); + void pong(); }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp index dde6848b..55765c75 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp @@ -126,7 +126,6 @@ void QWaylandSurfaceItem::init(QWaylandSurface *surface) m_surface = surface; m_surface->setSurfaceItem(this); - m_surface->sendOnScreenVisibilityChange(m_clientRenderingEnabled); if (m_resizeSurfaceToItem) { updateSurfaceSize(); @@ -135,6 +134,8 @@ void QWaylandSurfaceItem::init(QWaylandSurface *surface) setHeight(surface->size().height()); } + updatePosition(); + setSmooth(true); setFlag(ItemHasContents); setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton | @@ -287,6 +288,9 @@ void QWaylandSurfaceItem::surfaceUnmapped() void QWaylandSurfaceItem::surfaceDestroyed(QObject *) { + if (m_surface) + m_surface->setSurfaceItem(0); + m_surface = 0; } @@ -361,12 +365,11 @@ void QWaylandSurfaceItem::updateTexture() m_damaged = false; QSGTexture *oldTexture = texture; if (m_surface->type() == QWaylandSurface::Texture) { - QOpenGLContext *context = QOpenGLContext::currentContext(); QQuickWindow::CreateTextureOptions opt = 0; if (useTextureAlpha()) { opt |= QQuickWindow::TextureHasAlphaChannel; } - texture = window()->createTextureFromId(m_surface->texture(context), m_surface->size(), opt); + texture = window()->createTextureFromId(m_surface->texture(), m_surface->size(), opt); } else { texture = window()->createTextureFromImage(m_surface->image()); } diff --git a/src/compositor/compositor_api/qwaylandsurfacenode.cpp b/src/compositor/compositor_api/qwaylandsurfacenode.cpp index 513704f1..d13b970d 100644 --- a/src/compositor/compositor_api/qwaylandsurfacenode.cpp +++ b/src/compositor/compositor_api/qwaylandsurfacenode.cpp @@ -52,17 +52,7 @@ QT_BEGIN_NAMESPACE QWaylandSurfaceNode::QWaylandSurfaceNode(QWaylandSurfaceItem *item) : m_item(item) , m_textureUpdated(false) - , m_useTextureAlpha(false) - , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) { - m_textureMaterial = QWaylandSurfaceTextureMaterial::createMaterial(); - m_opaqueTextureMaterial = QWaylandSurfaceTextureOpaqueMaterial::createMaterial(); - - m_currentMaterial = m_opaqueTextureMaterial; - - setGeometry(&m_geometry); - setMaterial(m_currentMaterial); - if (m_item) m_item->m_node = this; setFlag(UsePreprocess,true); @@ -74,8 +64,6 @@ QWaylandSurfaceNode::~QWaylandSurfaceNode() QMutexLocker locker(QWaylandSurfaceItem::mutex); if (m_item) m_item->m_node = 0; - delete m_textureMaterial; - delete m_opaqueTextureMaterial; } void QWaylandSurfaceNode::preprocess() @@ -96,53 +84,10 @@ void QWaylandSurfaceNode::preprocess() void QWaylandSurfaceNode::updateTexture() { Q_ASSERT(m_item && m_item->textureProvider()); - - //If m_item->useTextureAlpha has changed to true use m_texureMaterial - //otherwise use m_opaqueTextureMaterial. - if (m_item->useTextureAlpha() != m_useTextureAlpha) { - m_useTextureAlpha = m_item->useTextureAlpha(); - if (m_useTextureAlpha) { - m_currentMaterial = m_textureMaterial; - } else { - m_currentMaterial = m_opaqueTextureMaterial; - } - setMaterial(m_currentMaterial); - } - QSGTexture *texture = m_item->textureProvider()->texture(); setTexture(texture); } -void QWaylandSurfaceNode::setRect(const QRectF &rect) -{ - if (m_rect == rect) - return; - m_rect = rect; - - if (texture()) { - QSize ts = texture()->textureSize(); - QRectF sourceRect(0, 0, ts.width(), ts.height()); - QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_rect, texture()->convertToNormalizedSourceRect(sourceRect)); - } -} - -void QWaylandSurfaceNode::setTexture(QSGTexture *texture) -{ - if (m_currentMaterial->state()->texture() == texture) - return; - m_currentMaterial->state()->setTexture(texture); - - QSize ts = texture->textureSize(); - QRectF sourceRect(0, 0, ts.width(), ts.height()); - QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_rect, texture->convertToNormalizedSourceRect(sourceRect)); - markDirty(DirtyMaterial); -} - -QSGTexture *QWaylandSurfaceNode::texture() const -{ - return m_currentMaterial->state()->texture(); -} - void QWaylandSurfaceNode::setItem(QWaylandSurfaceItem *item) { m_item = item; diff --git a/src/compositor/compositor_api/qwaylandsurfacenode_p.h b/src/compositor/compositor_api/qwaylandsurfacenode_p.h index 99bca039..1c71acf1 100644 --- a/src/compositor/compositor_api/qwaylandsurfacenode_p.h +++ b/src/compositor/compositor_api/qwaylandsurfacenode_p.h @@ -42,9 +42,7 @@ #ifndef QWAYLANDSURFACENODE_H #define QWAYLANDSURFACENODE_H -#include "qwaylandsurfacetexturematerial_p.h" - -#include <QtQuick/QSGGeometryNode> +#include <QtQuick/QSGSimpleTextureNode> #include <QtQuick/QSGOpaqueTextureMaterial> QT_BEGIN_NAMESPACE @@ -52,7 +50,7 @@ QT_BEGIN_NAMESPACE class QWaylandSurfaceItem; class QSGTexture; -class QWaylandSurfaceNode : public QSGGeometryNode +class QWaylandSurfaceNode : public QSGSimpleTextureNode { public: QWaylandSurfaceNode(QWaylandSurfaceItem *item = 0); @@ -61,12 +59,6 @@ public: void preprocess(); void updateTexture(); - void setRect(const QRectF &rect); - inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } - - void setTexture(QSGTexture *texture); - QSGTexture *texture() const; - bool isTextureUpdated() const { return m_textureUpdated; } void setTextureUpdated(bool textureUpdated) { m_textureUpdated = textureUpdated; } @@ -77,14 +69,6 @@ private: QWaylandSurfaceItem *m_item; bool m_textureUpdated; - bool m_useTextureAlpha; - - QSGGeometry m_geometry; - QSGSimpleMaterial<QWaylandSurfaceTextureState> *m_textureMaterial; - QSGSimpleMaterial<QWaylandSurfaceTextureState> *m_opaqueTextureMaterial; - QSGSimpleMaterial<QWaylandSurfaceTextureState> *m_currentMaterial; - - QRectF m_rect; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfacetexturematerial.cpp b/src/compositor/compositor_api/qwaylandsurfacetexturematerial.cpp deleted file mode 100644 index 9562457e..00000000 --- a/src/compositor/compositor_api/qwaylandsurfacetexturematerial.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandsurfacetexturematerial_p.h" -#include <QtGui/QOpenGLContext> - -QT_BEGIN_NAMESPACE - -static const char wayland_surface_texture_material_vertex[] = - "uniform highp mat4 qt_Matrix; \n" - "attribute highp vec4 qt_VertexPosition; \n" - "attribute highp vec2 qt_VertexTexCoord; \n" - "varying highp vec2 qt_TexCoord; \n" - "void main() { \n" - " qt_TexCoord = qt_VertexTexCoord; \n" - " gl_Position = qt_Matrix * qt_VertexPosition; \n" - "}"; - - -static const char wayland_surface_texture_opaque_material_fragment[] = - "varying highp vec2 qt_TexCoord; \n" - "uniform sampler2D qt_Texture; \n" - "uniform lowp float qt_Opacity; \n" - "void main() { \n" - " gl_FragColor = vec4(texture2D(qt_Texture, qt_TexCoord).rgb, 1.0) * qt_Opacity; \n" - "}"; - -static const char wayland_surface_texture_material_fragment[] = - "varying highp vec2 qt_TexCoord; \n" - "uniform sampler2D qt_Texture; \n" - "uniform lowp float qt_Opacity; \n" - "void main() { \n" - " gl_FragColor = texture2D(qt_Texture, qt_TexCoord) * qt_Opacity; \n" - "}"; - -QList<QByteArray> QWaylandSurfaceTextureMaterial::attributes() const -{ - QList<QByteArray> attributeList; - attributeList << "qt_VertexPosition"; - attributeList << "qt_VertexTexCoord"; - return attributeList; -} - -void QWaylandSurfaceTextureMaterial::updateState(const QWaylandSurfaceTextureState *newState, const QWaylandSurfaceTextureState *oldState) -{ - Q_UNUSED(oldState); - newState->texture()->bind(); -} - -const char *QWaylandSurfaceTextureMaterial::vertexShader() const -{ - return wayland_surface_texture_material_vertex; -} - -const char *QWaylandSurfaceTextureMaterial::fragmentShader() const -{ - return wayland_surface_texture_material_fragment; -} - -QList<QByteArray> QWaylandSurfaceTextureOpaqueMaterial::attributes() const -{ - QList<QByteArray> attributeList; - attributeList << "qt_VertexPosition"; - attributeList << "qt_VertexTexCoord"; - return attributeList; -} - -void QWaylandSurfaceTextureOpaqueMaterial::updateState(const QWaylandSurfaceTextureState *newState, const QWaylandSurfaceTextureState *oldState) -{ - Q_UNUSED(oldState); - newState->texture()->bind(); -} - -const char *QWaylandSurfaceTextureOpaqueMaterial::vertexShader() const -{ - return wayland_surface_texture_material_vertex; -} - -const char *QWaylandSurfaceTextureOpaqueMaterial::fragmentShader() const -{ - return wayland_surface_texture_opaque_material_fragment; -} - -QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfacetexturematerial_p.h b/src/compositor/compositor_api/qwaylandsurfacetexturematerial_p.h deleted file mode 100644 index 4cf3df09..00000000 --- a/src/compositor/compositor_api/qwaylandsurfacetexturematerial_p.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDSURFACETEXTUREMATERIAL_H -#define QWAYLANDSURFACETEXTUREMATERIAL_H - -#include <QtQuick/QSGSimpleMaterial> -#include <QtQuick/QSGTexture> -#include <QtGui/QOpenGLFunctions> - -QT_BEGIN_NAMESPACE - -class QWaylandSurfaceTextureState { -public: - QWaylandSurfaceTextureState() - : m_texture(0) - {} - void setTexture(QSGTexture *texture) { m_texture = texture; } - QSGTexture *texture() const { return m_texture; } - -private: - QSGTexture *m_texture; -}; - -class QWaylandSurfaceTextureMaterial : public QSGSimpleMaterialShader<QWaylandSurfaceTextureState> -{ - QSG_DECLARE_SIMPLE_SHADER(QWaylandSurfaceTextureMaterial, QWaylandSurfaceTextureState) - public: - - QList<QByteArray> attributes() const; - - void updateState(const QWaylandSurfaceTextureState *newState, const QWaylandSurfaceTextureState *oldState); -protected: - const char *vertexShader() const; - const char *fragmentShader() const; -}; - -class QWaylandSurfaceTextureOpaqueMaterial : public QSGSimpleMaterialShader<QWaylandSurfaceTextureState> -{ - QSG_DECLARE_SIMPLE_SHADER(QWaylandSurfaceTextureOpaqueMaterial, QWaylandSurfaceTextureState) - public: - - QList<QByteArray> attributes() const; - - void updateState(const QWaylandSurfaceTextureState *newState, const QWaylandSurfaceTextureState *oldState); -protected: - const char *vertexShader() const; - const char *fragmentShader() const; -}; - -QT_END_NAMESPACE - -#endif // QWAYLANDSURFACETEXTUREMATERIAL_H diff --git a/src/compositor/hardware_integration/hardware_integration.pri b/src/compositor/hardware_integration/hardware_integration.pri index 8477243f..999434d9 100644 --- a/src/compositor/hardware_integration/hardware_integration.pri +++ b/src/compositor/hardware_integration/hardware_integration.pri @@ -1,17 +1,28 @@ -QT += core - isEmpty(QT_WAYLAND_GL_CONFIG):QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG) !isEqual(QT_WAYLAND_GL_CONFIG,nogl) { + CONFIG += wayland-scanner + WAYLANDSERVERSOURCES += \ + ../extensions/server-buffer-extension.xml \ + ../extensions/hardware-integration.xml + HEADERS += \ - hardware_integration/qwaylandgraphicshardwareintegration.h \ - hardware_integration/qwaylandgraphicshardwareintegrationfactory.h \ - hardware_integration/qwaylandgraphicshardwareintegrationplugin.h + hardware_integration/qwaylandclientbufferintegration.h \ + hardware_integration/qwaylandclientbufferintegrationfactory.h \ + hardware_integration/qwaylandclientbufferintegrationplugin.h \ + hardware_integration/qwaylandserverbufferintegration.h \ + hardware_integration/qwaylandserverbufferintegrationfactory.h \ + hardware_integration/qwaylandserverbufferintegrationplugin.h \ + hardware_integration/qwlhwintegration_p.h SOURCES += \ - hardware_integration/qwaylandgraphicshardwareintegration.cpp \ - hardware_integration/qwaylandgraphicshardwareintegrationfactory.cpp \ - hardware_integration/qwaylandgraphicshardwareintegrationplugin.cpp + hardware_integration/qwaylandclientbufferintegration.cpp \ + hardware_integration/qwaylandclientbufferintegrationfactory.cpp \ + hardware_integration/qwaylandclientbufferintegrationplugin.cpp \ + hardware_integration/qwaylandserverbufferintegration.cpp \ + hardware_integration/qwaylandserverbufferintegrationfactory.cpp \ + hardware_integration/qwaylandserverbufferintegrationplugin.cpp \ + hardware_integration/qwlhwintegration.cpp DEFINES += QT_COMPOSITOR_WAYLAND_GL } else { diff --git a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegration.cpp b/src/compositor/hardware_integration/qwaylandclientbufferintegration.cpp index 7b213bfa..ff463429 100644 --- a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegration.cpp +++ b/src/compositor/hardware_integration/qwaylandclientbufferintegration.cpp @@ -38,11 +38,11 @@ ** ****************************************************************************/ -#include "qwaylandgraphicshardwareintegration.h" +#include "qwaylandclientbufferintegration.h" QT_BEGIN_NAMESPACE -QWaylandGraphicsHardwareIntegration::QWaylandGraphicsHardwareIntegration() +QWaylandClientBufferIntegration::QWaylandClientBufferIntegration() : m_compositor(0) { } diff --git a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegration.h b/src/compositor/hardware_integration/qwaylandclientbufferintegration.h index b8cc90fb..b3f30500 100644 --- a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegration.h +++ b/src/compositor/hardware_integration/qwaylandclientbufferintegration.h @@ -38,8 +38,8 @@ ** ****************************************************************************/ -#ifndef GRAPHICSHARDWAREINTEGRATION_H -#define GRAPHICSHARDWAREINTEGRATION_H +#ifndef QWAYLANDCLIENTBUFFERINTEGRATION_H +#define QWAYLANDCLIENTBUFFERINTEGRATION_H #include <QtGui/qopengl.h> #include <QtGui/QOpenGLContext> @@ -53,20 +53,24 @@ namespace QtWayland { class Display; } -class Q_COMPOSITOR_EXPORT QWaylandGraphicsHardwareIntegration +class Q_COMPOSITOR_EXPORT QWaylandClientBufferIntegration { public: - QWaylandGraphicsHardwareIntegration(); - virtual ~QWaylandGraphicsHardwareIntegration() { } + QWaylandClientBufferIntegration(); + virtual ~QWaylandClientBufferIntegration() { } void setCompositor(QWaylandCompositor *compositor) { m_compositor = compositor; } virtual void initializeHardware(QtWayland::Display *waylandDisplay) = 0; - /** Bind the Wayland buffer to the textureId. The correct context is the current context, - so there is no need to do makeCurrent in this function. - **/ - virtual GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) = 0; + // Used when the hardware integration wants to provide its own texture for a given buffer. + // In most cases the compositor creates and manages the texture so this is not needed. + virtual GLuint textureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); return 0; } + virtual void destroyTextureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); } + + // Called with the texture bound. + virtual void bindTextureToBuffer(struct ::wl_resource *buffer) = 0; + virtual bool isYInverted(struct ::wl_resource *) const { return true; } virtual bool setDirectRenderSurface(QWaylandSurface *) {return false;} @@ -82,4 +86,4 @@ protected: QT_END_NAMESPACE -#endif // GRAPHICSHARDWAREINTEGRATION_H +#endif // QWAYLANDCLIENTBUFFERINTEGRATION_H diff --git a/src/compositor/hardware_integration/qwaylandclientbufferintegrationfactory.cpp b/src/compositor/hardware_integration/qwaylandclientbufferintegrationfactory.cpp new file mode 100644 index 00000000..71ea9ec4 --- /dev/null +++ b/src/compositor/hardware_integration/qwaylandclientbufferintegrationfactory.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandclientbufferintegrationfactory.h" +#include "qwaylandclientbufferintegrationplugin.h" +#include "qwaylandclientbufferintegration.h" +#include <QtCore/private/qfactoryloader_p.h> +#include <QtCore/QCoreApplication> +#include <QtCore/QDir> + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + (QWaylandClientBufferIntegrationFactoryInterface_iid, QLatin1String("/wayland-graphics-integration/server"), Qt::CaseInsensitive)) +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, + (QWaylandClientBufferIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) +#endif + +QStringList QWaylandClientBufferIntegrationFactory::keys(const QString &pluginPath) +{ +#ifndef QT_NO_LIBRARY + QStringList list; + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + list = directLoader()->keyMap().values(); + if (!list.isEmpty()) { + const QString postFix = QStringLiteral(" (from ") + + QDir::toNativeSeparators(pluginPath) + + QLatin1Char(')'); + const QStringList::iterator end = list.end(); + for (QStringList::iterator it = list.begin(); it != end; ++it) + (*it).append(postFix); + } + } + list.append(loader()->keyMap().values()); + return list; +#else + return QStringList(); +#endif +} + +QWaylandClientBufferIntegration *QWaylandClientBufferIntegrationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath) +{ +#ifndef QT_NO_LIBRARY + // Try loading the plugin from platformPluginPath first: + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + if (QWaylandClientBufferIntegration *ret = qLoadPlugin1<QWaylandClientBufferIntegration, QWaylandClientBufferIntegrationPlugin>(directLoader(), name, args)) + return ret; + } + if (QWaylandClientBufferIntegration *ret = qLoadPlugin1<QWaylandClientBufferIntegration, QWaylandClientBufferIntegrationPlugin>(loader(), name, args)) + return ret; +#endif + return 0; +} + +QT_END_NAMESPACE diff --git a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegrationfactory.h b/src/compositor/hardware_integration/qwaylandclientbufferintegrationfactory.h index 74e5dda0..c9d95f8f 100644 --- a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegrationfactory.h +++ b/src/compositor/hardware_integration/qwaylandclientbufferintegrationfactory.h @@ -39,23 +39,23 @@ ** ****************************************************************************/ -#ifndef GRAPHICSHARDWAREINTEGRATIONFACTORY_H -#define GRAPHICSHARDWAREINTEGRATIONFACTORY_H +#ifndef QWAYLANDCLIENTBUFFERINTEGRATIONFACTORY_H +#define QWAYLANDCLIENTBUFFERINTEGRATIONFACTORY_H #include <QtCompositor/qwaylandexport.h> #include <QtCore/QStringList> QT_BEGIN_NAMESPACE -class QWaylandGraphicsHardwareIntegration; +class QWaylandClientBufferIntegration; -class Q_COMPOSITOR_EXPORT QWaylandGraphicsHardwareIntegrationFactory +class Q_COMPOSITOR_EXPORT QWaylandClientBufferIntegrationFactory { public: static QStringList keys(const QString &pluginPath = QString()); - static QWaylandGraphicsHardwareIntegration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString()); + static QWaylandClientBufferIntegration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString()); }; QT_END_NAMESPACE -#endif // GRAPHICSHARDWAREINTEGRATIONFACTORY_H +#endif // QWAYLANDCLIENTBUFFERINTEGRATIONFACTORY_H diff --git a/src/compositor/hardware_integration/qwaylandclientbufferintegrationplugin.cpp b/src/compositor/hardware_integration/qwaylandclientbufferintegrationplugin.cpp new file mode 100644 index 00000000..58bb26d1 --- /dev/null +++ b/src/compositor/hardware_integration/qwaylandclientbufferintegrationplugin.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandclientbufferintegrationplugin.h" + +QT_BEGIN_NAMESPACE + +QWaylandClientBufferIntegrationPlugin::QWaylandClientBufferIntegrationPlugin(QObject *parent) : + QObject(parent) +{ +} + +QWaylandClientBufferIntegrationPlugin::~QWaylandClientBufferIntegrationPlugin() +{ +} + +QT_END_NAMESPACE diff --git a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegrationplugin.h b/src/compositor/hardware_integration/qwaylandclientbufferintegrationplugin.h index 2deb3a6c..2296b9df 100644 --- a/src/compositor/hardware_integration/qwaylandgraphicshardwareintegrationplugin.h +++ b/src/compositor/hardware_integration/qwaylandclientbufferintegrationplugin.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef GRAPHICSHARDWAREINTEGRATIONPLUGIN_H -#define GRAPHICSHARDWAREINTEGRATIONPLUGIN_H +#ifndef QWAYLANDCLIENTBUFFERINTEGRATIONPLUGIN_H +#define QWAYLANDCLIENTBUFFERINTEGRATIONPLUGIN_H #include <QtCompositor/qwaylandexport.h> @@ -49,20 +49,20 @@ QT_BEGIN_NAMESPACE -class QWaylandGraphicsHardwareIntegration; +class QWaylandClientBufferIntegration; -#define QWaylandGraphicsHardwareIntegrationFactoryInterface_iid "org.qt-project.Qt.Compositor.QWaylandGraphicsHardwareIntegrationFactoryInterface.5.3" +#define QWaylandClientBufferIntegrationFactoryInterface_iid "org.qt-project.Qt.Compositor.QWaylandClientBufferIntegrationFactoryInterface.5.3" -class Q_COMPOSITOR_EXPORT QWaylandGraphicsHardwareIntegrationPlugin : public QObject +class Q_COMPOSITOR_EXPORT QWaylandClientBufferIntegrationPlugin : public QObject { Q_OBJECT public: - explicit QWaylandGraphicsHardwareIntegrationPlugin(QObject *parent = 0); - ~QWaylandGraphicsHardwareIntegrationPlugin(); + explicit QWaylandClientBufferIntegrationPlugin(QObject *parent = 0); + ~QWaylandClientBufferIntegrationPlugin(); - virtual QWaylandGraphicsHardwareIntegration *create(const QString &key, const QStringList ¶mList) = 0; + virtual QWaylandClientBufferIntegration *create(const QString &key, const QStringList ¶mList) = 0; }; QT_END_NAMESPACE -#endif // GRAPHICSHARDWAREINTEGRATIONPLUGIN_H +#endif // QWAYLANDCLIENTBUFFERINTEGRATIONPLUGIN_H diff --git a/src/compositor/hardware_integration/qwaylandserverbufferintegration.cpp b/src/compositor/hardware_integration/qwaylandserverbufferintegration.cpp new file mode 100644 index 00000000..520f9307 --- /dev/null +++ b/src/compositor/hardware_integration/qwaylandserverbufferintegration.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandserverbufferintegration.h" + +QT_BEGIN_NAMESPACE + +QWaylandServerBuffer::QWaylandServerBuffer(const QSize &size, QWaylandServerBuffer::Format format) + : m_size(size) + , m_format(format) +{ } +QWaylandServerBuffer::~QWaylandServerBuffer() +{ } + + +bool QWaylandServerBuffer::isYInverted() const +{ + return false; +} + +QSize QWaylandServerBuffer::size() const +{ return m_size; } + +QWaylandServerBuffer::Format QWaylandServerBuffer::format() const +{ return m_format; } + +QWaylandServerBufferIntegration::QWaylandServerBufferIntegration() +{ } + +QWaylandServerBufferIntegration::~QWaylandServerBufferIntegration() +{ } + +void QWaylandServerBufferIntegration::initializeHardware(QWaylandCompositor *compositor) +{ + Q_UNUSED(compositor); +} + +QT_END_NAMESPACE diff --git a/src/compositor/hardware_integration/qwaylandserverbufferintegration.h b/src/compositor/hardware_integration/qwaylandserverbufferintegration.h new file mode 100644 index 00000000..7033cd75 --- /dev/null +++ b/src/compositor/hardware_integration/qwaylandserverbufferintegration.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSERVERBUFFERINTEGRATION_H +#define QWAYLANDSERVERBUFFERINTEGRATION_H + +#include <QtCore/qglobal.h> +#include <QtCore/QSize> +#include <QtGui/qopengl.h> + +#include <QtCompositor/qwaylandexport.h> + +QT_BEGIN_NAMESPACE + +class QWaylandCompositor; +class QOpenGLContext; +struct wl_client; +struct wl_resource; + +namespace QtWayland { + class Display; +} + +class Q_COMPOSITOR_EXPORT QWaylandServerBuffer +{ +public: + enum Format { + RGBA32, + A8 + }; + + QWaylandServerBuffer(const QSize &size, QWaylandServerBuffer::Format format); + virtual ~QWaylandServerBuffer(); + + virtual struct ::wl_resource *resourceForClient(struct ::wl_client *) = 0; + + virtual void bindTextureToBuffer() = 0; + + virtual bool isYInverted() const; + + QSize size() const; + Format format() const; +protected: + QSize m_size; + Format m_format; +}; + +class Q_COMPOSITOR_EXPORT QWaylandServerBufferIntegration +{ +public: + QWaylandServerBufferIntegration(); + virtual ~QWaylandServerBufferIntegration(); + + virtual void initializeHardware(QWaylandCompositor *); + + virtual bool supportsFormat(QWaylandServerBuffer::Format format) const = 0; + virtual QWaylandServerBuffer *createServerBuffer(const QSize &size, QWaylandServerBuffer::Format format) = 0; +}; + +QT_END_NAMESPACE + +#endif //QWAYLANDSERVERBUFFERINTEGRATION_H diff --git a/src/compositor/hardware_integration/qwaylandserverbufferintegrationfactory.cpp b/src/compositor/hardware_integration/qwaylandserverbufferintegrationfactory.cpp new file mode 100644 index 00000000..2a99bda9 --- /dev/null +++ b/src/compositor/hardware_integration/qwaylandserverbufferintegrationfactory.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandserverbufferintegrationfactory.h" +#include "qwaylandserverbufferintegrationplugin.h" +#include "qwaylandserverbufferintegration.h" +#include <QtCore/private/qfactoryloader_p.h> +#include <QtCore/QCoreApplication> +#include <QtCore/QDir> + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + (QWaylandServerBufferIntegrationFactoryInterface_iid, QLatin1String("/wayland-graphics-integration/server"), Qt::CaseInsensitive)) +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, + (QWaylandServerBufferIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) +#endif + +QStringList QWaylandServerBufferIntegrationFactory::keys(const QString &pluginPath) +{ +#ifndef QT_NO_LIBRARY + QStringList list; + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + list = directLoader()->keyMap().values(); + if (!list.isEmpty()) { + const QString postFix = QStringLiteral(" (from ") + + QDir::toNativeSeparators(pluginPath) + + QLatin1Char(')'); + const QStringList::iterator end = list.end(); + for (QStringList::iterator it = list.begin(); it != end; ++it) + (*it).append(postFix); + } + } + list.append(loader()->keyMap().values()); + return list; +#else + return QStringList(); +#endif +} + +QWaylandServerBufferIntegration *QWaylandServerBufferIntegrationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath) +{ +#ifndef QT_NO_LIBRARY + // Try loading the plugin from platformPluginPath first: + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + if (QWaylandServerBufferIntegration *ret = qLoadPlugin1<QWaylandServerBufferIntegration, QWaylandServerBufferIntegrationPlugin>(directLoader(), name, args)) + return ret; + } + if (QWaylandServerBufferIntegration *ret = qLoadPlugin1<QWaylandServerBufferIntegration, QWaylandServerBufferIntegrationPlugin>(loader(), name, args)) + return ret; +#endif + return 0; +} + +QT_END_NAMESPACE diff --git a/src/compositor/hardware_integration/qwaylandserverbufferintegrationfactory.h b/src/compositor/hardware_integration/qwaylandserverbufferintegrationfactory.h new file mode 100644 index 00000000..c7fe384c --- /dev/null +++ b/src/compositor/hardware_integration/qwaylandserverbufferintegrationfactory.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSERVERBUFFERINTEGRATIONFACTORY_H +#define QWAYLANDSERVERBUFFERINTEGRATIONFACTORY_H + +#include <QtCompositor/qwaylandexport.h> +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE + +class QWaylandServerBufferIntegration; + +class Q_COMPOSITOR_EXPORT QWaylandServerBufferIntegrationFactory +{ +public: + static QStringList keys(const QString &pluginPath = QString()); + static QWaylandServerBufferIntegration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString()); +}; + +QT_END_NAMESPACE + +#endif //QWAYLANDSERVERBUFFERINTEGRATIONFACTORY_H + diff --git a/src/compositor/hardware_integration/qwaylandserverbufferintegrationplugin.cpp b/src/compositor/hardware_integration/qwaylandserverbufferintegrationplugin.cpp new file mode 100644 index 00000000..ebe860b4 --- /dev/null +++ b/src/compositor/hardware_integration/qwaylandserverbufferintegrationplugin.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandserverbufferintegrationplugin.h" + +QT_BEGIN_NAMESPACE + +QWaylandServerBufferIntegrationPlugin::QWaylandServerBufferIntegrationPlugin(QObject *parent) : + QObject(parent) +{ +} + +QWaylandServerBufferIntegrationPlugin::~QWaylandServerBufferIntegrationPlugin() +{ +} + +QT_END_NAMESPACE + diff --git a/src/compositor/hardware_integration/qwaylandserverbufferintegrationplugin.h b/src/compositor/hardware_integration/qwaylandserverbufferintegrationplugin.h new file mode 100644 index 00000000..6910880e --- /dev/null +++ b/src/compositor/hardware_integration/qwaylandserverbufferintegrationplugin.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSERVERBUFFERINTEGRATIONPLUGIN_H +#define QWAYLANDSERVERBUFFERINTEGRATIONPLUGIN_H + +#include <QtCompositor/qwaylandexport.h> + +#include <QtCore/qplugin.h> +#include <QtCore/qfactoryinterface.h> + +QT_BEGIN_NAMESPACE + +class QWaylandServerBufferIntegration; + +#define QWaylandServerBufferIntegrationFactoryInterface_iid "org.qt-project.Qt.Compositor.QWaylandServerBufferIntegrationFactoryInterface.5.1" + +class Q_COMPOSITOR_EXPORT QWaylandServerBufferIntegrationPlugin : public QObject +{ + Q_OBJECT +public: + explicit QWaylandServerBufferIntegrationPlugin(QObject *parent = 0); + ~QWaylandServerBufferIntegrationPlugin(); + + virtual QWaylandServerBufferIntegration *create(const QString &key, const QStringList ¶mList) = 0; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDSERVERBUFFERINTEGRATIONPLUGIN_H diff --git a/src/compositor/hardware_integration/qwlhwintegration.cpp b/src/compositor/hardware_integration/qwlhwintegration.cpp new file mode 100644 index 00000000..62614c4d --- /dev/null +++ b/src/compositor/hardware_integration/qwlhwintegration.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwlhwintegration_p.h" + +#include "qwlcompositor_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +HardwareIntegration::HardwareIntegration(Compositor *compositor) + : qt_hardware_integration(compositor->wl_display()) +{ +} +void HardwareIntegration::setClientBufferIntegration(const QString &name) +{ + m_client_buffer_integration = name; +} +void HardwareIntegration::setServerBufferIntegration(const QString &name) +{ + m_server_buffer_integration = name; +} + +void HardwareIntegration::hardware_integration_bind_resource(Resource *resource) +{ + if (m_client_buffer_integration.size()) + send_client_backend(resource->handle, m_client_buffer_integration); + if (m_server_buffer_integration.size()) + send_server_backend(resource->handle, m_server_buffer_integration); +} + +} + +QT_END_NAMESPACE diff --git a/src/compositor/hardware_integration/qwlhwintegration_p.h b/src/compositor/hardware_integration/qwlhwintegration_p.h new file mode 100644 index 00000000..70128eb0 --- /dev/null +++ b/src/compositor/hardware_integration/qwlhwintegration_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWLHWINTEGRATION_P_H +#define QWLHWINTEGRATION_P_H + +#include <QtCompositor/private/qwayland-server-hardware-integration.h> + +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class Compositor; + +class HardwareIntegration : public QtWaylandServer::qt_hardware_integration +{ +public: + HardwareIntegration(Compositor *compositor); + + void setClientBufferIntegration(const QString &name); + void setServerBufferIntegration(const QString &name); + +protected: + void hardware_integration_bind_resource(Resource *resource); + +private: + QString m_client_buffer_integration; + QString m_server_buffer_integration; +}; + +} + +QT_END_NAMESPACE +#endif diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp index 4f0e6ced..3c606d21 100644 --- a/src/compositor/wayland_wrapper/qwlcompositor.cpp +++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp @@ -54,8 +54,10 @@ #include "qwlqttouch_p.h" #include "qwlqtkey_p.h" #include "qwlinputdevice_p.h" +#include "qwlinputpanel_p.h" #include "qwlregion_p.h" #include "qwlpointer_p.h" +#include "qwltextinputmanager_p.h" #include <QWindow> #include <QSocketNotifier> @@ -82,10 +84,13 @@ #include <wayland-server.h> -#include "hardware_integration/qwaylandgraphicshardwareintegration.h" +#include "hardware_integration/qwlhwintegration_p.h" +#include "hardware_integration/qwaylandclientbufferintegration.h" +#include "hardware_integration/qwaylandserverbufferintegration.h" #include "waylandwindowmanagerintegration.h" -#include "hardware_integration/qwaylandgraphicshardwareintegrationfactory.h" +#include "hardware_integration/qwaylandclientbufferintegrationfactory.h" +#include "hardware_integration/qwaylandserverbufferintegrationfactory.h" QT_BEGIN_NAMESPACE @@ -123,8 +128,9 @@ Compositor *Compositor::instance() return compositor; } -Compositor::Compositor(QWaylandCompositor *qt_compositor) - : m_display(new Display) +Compositor::Compositor(QWaylandCompositor *qt_compositor, QWaylandCompositor::ExtensionFlags extensions) + : m_extensions(extensions) + , m_display(new Display) , m_default_input_device(0) , m_pageFlipper(0) , m_current_frame(0) @@ -135,41 +141,25 @@ Compositor::Compositor(QWaylandCompositor *qt_compositor) , m_directRenderContext(0) , m_directRenderActive(false) #if defined (QT_COMPOSITOR_WAYLAND_GL) - , m_graphics_hw_integration(0) + , m_hw_integration(0) + , m_client_buffer_integration(0) + , m_server_buffer_integration(0) #endif + , m_windowManagerIntegration(0) , m_outputExtension(0) , m_surfaceExtension(0) , m_subSurfaceExtension(0) , m_touchExtension(0) - , m_retainNotify(0) + , m_qtkeyExtension(0) + , m_textInputManager() + , m_inputPanel() + , m_retainSelection(false) { + m_timer.start(); compositor = this; -#if defined (QT_COMPOSITOR_WAYLAND_GL) - QWindow *window = qt_compositor->window(); - if (window && window->surfaceType() != QWindow::RasterSurface) { - QStringList keys = QWaylandGraphicsHardwareIntegrationFactory::keys(); - QString targetKey; - QByteArray hardwareIntegration = qgetenv("QT_WAYLAND_HARDWARE_INTEGRATION"); - if (keys.contains(QString::fromLocal8Bit(hardwareIntegration.constData()))) { - targetKey = QString::fromLocal8Bit(hardwareIntegration.constData()); - } else if (keys.contains(QString::fromLatin1("wayland-egl"))) { - targetKey = QString::fromLatin1("wayland-egl"); - } else if (!keys.isEmpty()) { - targetKey = keys.first(); - } - - if (!targetKey.isEmpty()) { - m_graphics_hw_integration = QWaylandGraphicsHardwareIntegrationFactory::create(targetKey, QStringList()); - if (m_graphics_hw_integration) { - m_graphics_hw_integration->setCompositor(qt_compositor); - } - } - //BUG: if there is no hw_integration, bad things will probably happen - - } -#endif - m_windowManagerIntegration = new WindowManagerServerIntegration(qt_compositor, this); + if (extensions & QWaylandCompositor::WindowManagerExtension) + m_windowManagerIntegration = new WindowManagerServerIntegration(qt_compositor, this); wl_display_add_global(m_display->handle(),&wl_compositor_interface,this,Compositor::bind_func); @@ -182,10 +172,30 @@ Compositor::Compositor(QWaylandCompositor *qt_compositor) m_shell = new Shell(); wl_display_add_global(m_display->handle(), &wl_shell_interface, m_shell, Shell::bind_func); - m_outputExtension = new OutputExtensionGlobal(this); - m_surfaceExtension = new SurfaceExtensionGlobal(this); - m_qtkeyExtension = new QtKeyExtensionGlobal(this); - m_touchExtension = new TouchExtensionGlobal(this); +#if defined (QT_COMPOSITOR_WAYLAND_GL) + if (extensions & QWaylandCompositor::HardwareIntegrationExtension) + m_hw_integration.reset(new HardwareIntegration(this)); + QWindow *window = qt_compositor->window(); + if (window && window->surfaceType() != QWindow::RasterSurface) { + loadClientBufferIntegration(); + loadServerBufferIntegration(); + } +#endif + + if (extensions & QWaylandCompositor::OutputExtension) + m_outputExtension = new OutputExtensionGlobal(this); + if (extensions & QWaylandCompositor::SurfaceExtension) + m_surfaceExtension = new SurfaceExtensionGlobal(this); + if (extensions & QWaylandCompositor::SubSurfaceExtension) + m_subSurfaceExtension = new SubSurfaceExtensionGlobal(this); + if (extensions & QWaylandCompositor::TouchExtension) + m_touchExtension = new TouchExtensionGlobal(this); + if (extensions & QWaylandCompositor::QtKeyExtension) + m_qtkeyExtension = new QtKeyExtensionGlobal(this); + if (extensions & QWaylandCompositor::TextInputExtension) { + m_textInputManager.reset(new TextInputManager(this)); + m_inputPanel.reset(new InputPanel(this)); + } if (wl_display_add_socket(m_display->handle(), qt_compositor->socketName())) { fprintf(stderr, "Fatal: Failed to open server socket\n"); @@ -218,9 +228,6 @@ Compositor::~Compositor() delete m_default_wayland_input_device; delete m_data_device_manager; -#ifdef QT_COMPOSITOR_WAYLAND_GL - delete m_graphics_hw_integration; -#endif delete m_output_global; delete m_display; } @@ -247,14 +254,9 @@ void Compositor::createSurface(struct wl_client *client, uint32_t id) m_qt_compositor->surfaceCreated(surface->waylandSurface()); } -uint Compositor::currentTimeMsecs() +uint Compositor::currentTimeMsecs() const { - //### we throw away the time information - struct timeval tv; - int ret = gettimeofday(&tv, 0); - if (ret == 0) - return tv.tv_sec*1000 + tv.tv_usec/1000; - return 0; + return m_timer.elapsed(); } void Compositor::releaseBuffer(QPlatformScreenBuffer *screenBuffer) @@ -305,7 +307,8 @@ void Compositor::destroyClient(WaylandClient *c) if (!client) return; - m_windowManagerIntegration->sendQuitMessage(client); + if (m_windowManagerIntegration) + m_windowManagerIntegration->sendQuitMessage(client); wl_client_destroy(client); } @@ -315,10 +318,19 @@ QWindow *Compositor::window() const return m_qt_compositor->window(); } -QWaylandGraphicsHardwareIntegration * Compositor::graphicsHWIntegration() const +QWaylandClientBufferIntegration * Compositor::clientBufferIntegration() const { #ifdef QT_COMPOSITOR_WAYLAND_GL - return m_graphics_hw_integration; + return m_client_buffer_integration.data(); +#else + return 0; +#endif +} + +QWaylandServerBufferIntegration * Compositor::serverBufferIntegration() const +{ +#ifdef QT_COMPOSITOR_WAYLAND_GL + return m_server_buffer_integration.data(); #else return 0; #endif @@ -327,8 +339,10 @@ QWaylandGraphicsHardwareIntegration * Compositor::graphicsHWIntegration() const void Compositor::initializeHardwareIntegration() { #ifdef QT_COMPOSITOR_WAYLAND_GL - if (m_graphics_hw_integration) - m_graphics_hw_integration->initializeHardware(m_display); + if (m_client_buffer_integration) + m_client_buffer_integration->initializeHardware(m_display); + if (m_server_buffer_integration) + m_server_buffer_integration->initializeHardware(m_qt_compositor); #endif } @@ -340,14 +354,8 @@ void Compositor::initializeDefaultInputDevice() void Compositor::initializeWindowManagerProtocol() { - m_windowManagerIntegration->initialize(m_display); -} - -void Compositor::enableSubSurfaceExtension() -{ - if (!m_subSurfaceExtension) { - m_subSurfaceExtension = new SubSurfaceExtensionGlobal(this); - } + if (m_windowManagerIntegration) + m_windowManagerIntegration->initialize(m_display); } bool Compositor::setDirectRenderSurface(Surface *surface, QOpenGLContext *context) @@ -360,7 +368,7 @@ bool Compositor::setDirectRenderSurface(Surface *surface, QOpenGLContext *contex if (!surface) setDirectRenderingActive(false); - if (m_graphics_hw_integration && m_graphics_hw_integration->setDirectRenderSurface(surface ? surface->waylandSurface() : 0)) { + if (m_client_buffer_integration && m_client_buffer_integration->setDirectRenderSurface(surface ? surface->waylandSurface() : 0)) { m_directRenderSurface = surface; m_directRenderContext = context; return true; @@ -409,8 +417,7 @@ void Compositor::setScreenOrientation(Qt::ScreenOrientation orientation) for (int i = 0; i < clientList.length(); ++i) { struct wl_client *client = clientList.at(i); Output *output = m_output_global->outputForClient(client); - Q_ASSERT(output); - if (output->extendedOutput) + if (output && output->extendedOutput) output->extendedOutput->sendOutputOrientation(orientation); } } @@ -448,7 +455,13 @@ int Compositor::outputRefreshRate() const void Compositor::setClientFullScreenHint(bool value) { - m_windowManagerIntegration->setShowIsFullScreen(value); + if (m_windowManagerIntegration) + m_windowManagerIntegration->setShowIsFullScreen(value); +} + +QWaylandCompositor::ExtensionFlags Compositor::extensions() const +{ + return m_extensions; } InputDevice* Compositor::defaultInputDevice() @@ -468,28 +481,47 @@ QList<QtWayland::Surface *> Compositor::surfacesForClient(wl_client *client) return ret; } +Surface *Compositor::pickSurface(const QPointF &globalPosition) +{ + QWaylandSurface *surface = m_qt_compositor->pickSurface(globalPosition); + return surface ? surface->handle() : 0; +} + +QPointF Compositor::mapToSurface(Surface *surface, const QPointF &globalPosition) +{ + return m_qt_compositor->mapToSurface(surface->waylandSurface(), globalPosition); +} + void Compositor::configureTouchExtension(int flags) { if (m_touchExtension) m_touchExtension->setFlags(flags); } -void Compositor::setRetainedSelectionWatcher(RetainedSelectionFunc func, void *param) +InputPanel *Compositor::inputPanel() const +{ + return m_inputPanel.data(); +} + +DataDeviceManager *Compositor::dataDeviceManager() const +{ + return m_data_device_manager; +} + +void Compositor::setRetainedSelectionEnabled(bool enabled) { - m_retainNotify = func; - m_retainNotifyParam = param; + m_retainSelection = enabled; } -bool Compositor::wantsRetainedSelection() const +bool Compositor::retainedSelectionEnabled() const { - return m_retainNotify != 0; + return m_retainSelection; } void Compositor::feedRetainedSelectionData(QMimeData *data) { - if (m_retainNotify) { - m_retainNotify(data, m_retainNotifyParam); - } + if (m_retainSelection) + m_qt_compositor->retainedSelectionReceived(data); } void Compositor::scheduleReleaseBuffer(SurfaceBuffer *screenBuffer) @@ -497,7 +529,7 @@ void Compositor::scheduleReleaseBuffer(SurfaceBuffer *screenBuffer) QMetaObject::invokeMethod(this,"releaseBuffer",Q_ARG(QPlatformScreenBuffer*,screenBuffer)); } -void Compositor::overrideSelection(QMimeData *data) +void Compositor::overrideSelection(const QMimeData *data) { m_data_device_manager->overrideSelection(*data); } @@ -521,6 +553,47 @@ void Compositor::sendDragEndEvent() // Drag::instance()->dragEnd(); } +void Compositor::loadClientBufferIntegration() +{ + QStringList keys = QWaylandClientBufferIntegrationFactory::keys(); + QString targetKey; + QByteArray clientBufferIntegration = qgetenv("QT_WAYLAND_HARDWARE_INTEGRATION"); + if (clientBufferIntegration.isEmpty()) + clientBufferIntegration = qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"); + if (keys.contains(QString::fromLocal8Bit(clientBufferIntegration.constData()))) { + targetKey = QString::fromLocal8Bit(clientBufferIntegration.constData()); + } else if (keys.contains(QString::fromLatin1("wayland-egl"))) { + targetKey = QString::fromLatin1("wayland-egl"); + } else if (!keys.isEmpty()) { + targetKey = keys.first(); + } + + if (!targetKey.isEmpty()) { + m_client_buffer_integration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList())); + if (m_client_buffer_integration) { + m_client_buffer_integration->setCompositor(m_qt_compositor); + if (m_hw_integration) + m_hw_integration->setClientBufferIntegration(targetKey); + } + } + //BUG: if there is no client buffer integration, bad things will when opengl is used +} + +void Compositor::loadServerBufferIntegration() +{ + QStringList keys = QWaylandServerBufferIntegrationFactory::keys(); + QString targetKey; + QByteArray serverBufferIntegration = qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"); + if (keys.contains(QString::fromLocal8Bit(serverBufferIntegration.constData()))) { + targetKey = QString::fromLocal8Bit(serverBufferIntegration.constData()); + } + if (!targetKey.isEmpty()) { + m_server_buffer_integration.reset(QWaylandServerBufferIntegrationFactory::create(targetKey, QStringList())); + if (m_hw_integration) + m_hw_integration->setServerBufferIntegration(targetKey); + } +} + } // namespace Wayland QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h index 5e3c7be4..e223b03f 100644 --- a/src/compositor/wayland_wrapper/qwlcompositor_p.h +++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h @@ -42,7 +42,10 @@ #define WL_COMPOSITOR_H #include <QtCompositor/qwaylandexport.h> +#include <QtCompositor/qwaylandcompositor.h> + +#include <QtCore/QElapsedTimer> #include <QtCore/QSet> #include <QtGui/QWindow> @@ -54,7 +57,8 @@ QT_BEGIN_NAMESPACE class QWaylandCompositor; class QWaylandInputDevice; -class QWaylandGraphicsHardwareIntegration; +class QWaylandClientBufferIntegration; +class QWaylandServerBufferIntegration; class WindowManagerServerIntegration; class QMimeData; class QPlatformScreenPageFlipper; @@ -73,13 +77,16 @@ class SubSurfaceExtensionGlobal; class Shell; class TouchExtensionGlobal; class QtKeyExtensionGlobal; +class TextInputManager; +class InputPanel; +class HardwareIntegration; class Q_COMPOSITOR_EXPORT Compositor : public QObject { Q_OBJECT public: - Compositor(QWaylandCompositor *qt_compositor); + Compositor(QWaylandCompositor *qt_compositor, QWaylandCompositor::ExtensionFlags extensions); ~Compositor(); void frameFinished(Surface *surface = 0); @@ -92,15 +99,15 @@ public: void destroyClient(WaylandClient *client); - static uint currentTimeMsecs(); + uint currentTimeMsecs() const; QWindow *window() const; - QWaylandGraphicsHardwareIntegration *graphicsHWIntegration() const; + QWaylandClientBufferIntegration *clientBufferIntegration() const; + QWaylandServerBufferIntegration *serverBufferIntegration() const; void initializeHardwareIntegration(); void initializeDefaultInputDevice(); void initializeWindowManagerProtocol(); - void enableSubSurfaceExtension(); bool setDirectRenderSurface(Surface *surface, QOpenGLContext *context); Surface *directRenderSurface() const {return m_directRenderSurface;} QOpenGLContext *directRenderContext() const {return m_directRenderContext;} @@ -111,7 +118,11 @@ public: QList<Surface*> surfacesForClient(wl_client* client); QWaylandCompositor *waylandCompositor() const { return m_qt_compositor; } + Surface *pickSurface(const QPointF &globalPosition); + QPointF mapToSurface(Surface *surface, const QPointF &globalPosition); + struct wl_display *wl_display() const { return m_display->handle(); } + Display *display() const { return m_display; } static Compositor *instance(); @@ -130,20 +141,24 @@ public: void setClientFullScreenHint(bool value); + QWaylandCompositor::ExtensionFlags extensions() const; + TouchExtensionGlobal *touchExtension() { return m_touchExtension; } void configureTouchExtension(int flags); QtKeyExtensionGlobal *qtkeyExtension() { return m_qtkeyExtension; } + InputPanel *inputPanel() const; + + DataDeviceManager *dataDeviceManager() const; + bool isDragging() const; void sendDragMoveEvent(const QPoint &global, const QPoint &local, Surface *surface); void sendDragEndEvent(); - typedef void (*RetainedSelectionFunc)(QMimeData *, void *); - void setRetainedSelectionWatcher(RetainedSelectionFunc func, void *param); - void overrideSelection(QMimeData *data); - - bool wantsRetainedSelection() const; + void setRetainedSelectionEnabled(bool enabled); + bool retainedSelectionEnabled() const; + void overrideSelection(const QMimeData *data); void feedRetainedSelectionData(QMimeData *data); void scheduleReleaseBuffer(SurfaceBuffer *screenBuffer); @@ -154,6 +169,11 @@ private slots: void processWaylandEvents(); private: + void loadClientBufferIntegration(); + void loadServerBufferIntegration(); + + QWaylandCompositor::ExtensionFlags m_extensions; + Display *m_display; /* Input */ @@ -168,6 +188,7 @@ private: DataDeviceManager *m_data_device_manager; + QElapsedTimer m_timer; QList<Surface *> m_surfaces; QSet<Surface *> m_dirty_surfaces; @@ -185,7 +206,9 @@ private: bool m_directRenderActive; #ifdef QT_COMPOSITOR_WAYLAND_GL - QWaylandGraphicsHardwareIntegration *m_graphics_hw_integration; + QScopedPointer<HardwareIntegration> m_hw_integration; + QScopedPointer<QWaylandClientBufferIntegration> m_client_buffer_integration; + QScopedPointer<QWaylandServerBufferIntegration> m_server_buffer_integration; #endif //extensions @@ -197,12 +220,13 @@ private: SubSurfaceExtensionGlobal *m_subSurfaceExtension; TouchExtensionGlobal *m_touchExtension; QtKeyExtensionGlobal *m_qtkeyExtension; + QScopedPointer<TextInputManager> m_textInputManager; + QScopedPointer<InputPanel> m_inputPanel; static void bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id); - RetainedSelectionFunc m_retainNotify; - void *m_retainNotifyParam; + bool m_retainSelection; }; } diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp index 89fa7a08..f7ba9c4e 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp @@ -40,11 +40,17 @@ #include "qwldatadevice_p.h" +#include "qwlcompositor_p.h" #include "qwldatasource_p.h" #include "qwldataoffer_p.h" +#include "qwlinputdevice_p.h" +#include "qwlkeyboard_p.h" +#include "qwlpointer_p.h" +#include "qwlsurface_p.h" +#include "qwltouch_p.h" #include "qwldatadevicemanager_p.h" -#include <stdlib.h> +#include "qwaylanddrag.h" #include <QDebug> @@ -52,78 +58,164 @@ QT_BEGIN_NAMESPACE namespace QtWayland { -void DataDevice::start_drag(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *source, - struct wl_resource *surface, - struct wl_resource *icon, - uint32_t time) +DataDevice::DataDevice(InputDevice *inputDevice) + : wl_data_device() + , m_compositor(inputDevice->compositor()) + , m_inputDevice(inputDevice) + , m_selectionSource(0) + , m_dragClient(0) + , m_dragDataSource(0) + , m_dragFocus(0) + , m_dragFocusResource(0) + , m_dragIcon(0) { - Q_UNUSED(client); - Q_UNUSED(surface); - Q_UNUSED(icon); - Q_UNUSED(time); - DataDevice *data_device = static_cast<DataDevice *>(resource->data); - DataSource *data_source = static_cast<DataSource *>(source->data); - Q_UNUSED(data_device); - Q_UNUSED(data_source); } -void DataDevice::set_selection(struct wl_client *client, - struct wl_resource *data_device_resource, - struct wl_resource *source, - uint32_t time) +void DataDevice::setFocus(QtWaylandServer::wl_keyboard::Resource *focusResource) { - Q_UNUSED(client); - Q_UNUSED(time); - DataDevice *data_device = static_cast<DataDevice *>(data_device_resource->data); - DataSource *data_source = static_cast<DataSource *>(source->data); + if (!focusResource) + return; - data_device->m_data_device_manager->setCurrentSelectionSource(data_source); + Resource *resource = resourceMap().value(focusResource->client()); + if (!resource) + return; + + if (m_selectionSource) { + DataOffer *offer = new DataOffer(m_selectionSource, resource); + send_selection(resource->handle, offer->resource()->handle); + } } -const struct wl_data_device_interface DataDevice::data_device_interface = { - DataDevice::start_drag, - DataDevice::set_selection -}; +void DataDevice::setDragFocus(Surface *focus, const QPointF &localPosition) +{ + if (m_dragFocusResource) { + send_leave(m_dragFocusResource->handle); + m_dragFocus = 0; + m_dragFocusResource = 0; + } + + if (!focus) + return; + + if (!m_dragDataSource && m_dragClient != focus->resource()->client()) + return; + + Resource *resource = resourceMap().value(focus->resource()->client()); -DataDevice::DataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id) - : m_data_device_manager(data_device_manager) - , m_sent_selection_time(0) + if (!resource) + return; + + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + + DataOffer *offer = m_dragDataSource ? new DataOffer(m_dragDataSource, resource) : 0; + + if (m_dragDataSource && !offer) + return; + + send_enter(resource->handle, serial, focus->resource()->handle, + wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()), + offer->resource()->handle); + + m_dragFocus = focus; + m_dragFocusResource = resource; +} + +Surface *DataDevice::dragIcon() const { + return m_dragIcon; +} - //static int i = 0; - //qDebug() << "data device" << ++i; - m_data_device_resource = - wl_client_add_object(client,&wl_data_device_interface,&data_device_interface,id, this); +void DataDevice::sourceDestroyed(DataSource *source) +{ + if (m_selectionSource == source) + m_selectionSource = 0; } -void DataDevice::sendSelectionFocus() +void DataDevice::focus() { - if (m_data_device_manager->offerFromCompositorToClient(m_data_device_resource)) - return; + Surface *focus = m_compositor->pickSurface(m_pointer->currentPosition()); - DataSource *source = m_data_device_manager->currentSelectionSource(); - if (!source || !source->client()) { - m_data_device_manager->offerRetainedSelection(m_data_device_resource); - return; + if (focus != m_dragFocus) + setDragFocus(focus, m_compositor->mapToSurface(focus, m_pointer->currentPosition())); +} + +void DataDevice::motion(uint32_t time) +{ + if (m_dragIcon) { + m_dragIcon->setPos(m_pointer->currentPosition()); + } + + if (m_dragFocusResource && m_dragFocus) { + const QPointF &surfacePoint = m_compositor->mapToSurface(m_dragFocus, m_pointer->currentPosition()); + qDebug() << Q_FUNC_INFO << m_pointer->currentPosition() << surfacePoint; + send_motion(m_dragFocusResource->handle, time, + wl_fixed_from_double(surfacePoint.x()), wl_fixed_from_double(surfacePoint.y())); } - if (source->time() > m_sent_selection_time) { //this makes sure we don't resend - if (source->client() != m_data_device_resource->client) { //don't send selection to the client that owns the selection - DataOffer *data_offer = source->dataOffer(); - wl_resource *client_resource = - data_offer->addDataDeviceResource(m_data_device_resource); - //qDebug() << "sending data_offer for source" << source; - wl_data_device_send_selection(m_data_device_resource,client_resource); - m_sent_selection_time = source->time(); +} + +void DataDevice::button(uint32_t time, Qt::MouseButton button, uint32_t state) +{ + Q_UNUSED(time); + + if (m_dragFocusResource && + m_pointer->grabButton() == button && + state == Pointer::button_state_released) + send_drop(m_dragFocusResource->handle); + + if (!m_pointer->buttonPressed() && + state == Pointer::button_state_released) { + + if (m_dragIcon) { + m_dragIcon = 0; + Q_EMIT m_inputDevice->dragHandle()->iconChanged(); } + + setDragFocus(0, QPointF()); + m_pointer->endGrab(); + } +} + +void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial) +{ + if (m_inputDevice->pointerDevice()->grabSerial() == serial) { + if (!m_inputDevice->pointerDevice()->buttonPressed() || + m_inputDevice->pointerDevice()->focusSurface() != Surface::fromResource(origin)) + return; + + m_dragClient = resource->client(); + m_dragDataSource = source != 0 ? DataSource::fromResource(source) : 0; + m_dragIcon = icon != 0 ? Surface::fromResource(icon) : 0; + Q_EMIT m_inputDevice->dragHandle()->iconChanged(); + + m_inputDevice->pointerDevice()->setFocus(0, QPointF()); + m_inputDevice->pointerDevice()->startGrab(this); } } -struct wl_resource *DataDevice::dataDeviceResource() const +void DataDevice::data_device_set_selection(Resource *, struct ::wl_resource *source, uint32_t serial) { - return m_data_device_resource; + Q_UNUSED(serial); + + DataSource *dataSource = source ? DataSource::fromResource(source) : 0; + + if (m_selectionSource) + m_selectionSource->cancel(); + + m_selectionSource = dataSource; + m_compositor->dataDeviceManager()->setCurrentSelectionSource(m_selectionSource); + if (m_selectionSource) + m_selectionSource->setDevice(this); + + QtWaylandServer::wl_keyboard::Resource *focusResource = m_inputDevice->keyboardDevice()->focusResource(); + Resource *resource = focusResource ? resourceMap().value(focusResource->client()) : 0; + + if (resource && m_selectionSource) { + DataOffer *offer = new DataOffer(m_selectionSource, resource); + send_selection(resource->handle, offer->resource()->handle); + } else if (resource) { + send_selection(resource->handle, 0); + } } } diff --git a/src/compositor/wayland_wrapper/qwldatadevice_p.h b/src/compositor/wayland_wrapper/qwldatadevice_p.h index 2b4acdc9..fb4bbcdb 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice_p.h +++ b/src/compositor/wayland_wrapper/qwldatadevice_p.h @@ -41,42 +41,51 @@ #ifndef WLDATADEVICE_H #define WLDATADEVICE_H -#include <private/qwldatadevicemanager_p.h> +#include <QtCompositor/private/qwayland-server-wayland.h> +#include <qwlpointer_p.h> QT_BEGIN_NAMESPACE namespace QtWayland { +class Compositor; class DataSource; -class DataDeviceManager; +class InputDevice; +class Surface; -class DataDevice +class DataDevice : public QtWaylandServer::wl_data_device, public PointerGrabber { public: - DataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id); + DataDevice(InputDevice *inputDevice); - void createAndSetSelectionSource(struct wl_client *client, uint32_t id, const char *name, uint32_t time); - void sendSelectionFocus(); + void setFocus(QtWaylandServer::wl_keyboard::Resource *focusResource); - struct wl_resource *dataDeviceResource() const; + void setDragFocus(Surface *focus, const QPointF &localPosition); + + Surface *dragIcon() const; + + void sourceDestroyed(DataSource *source); + + void focus() Q_DECL_OVERRIDE; + void motion(uint32_t time) Q_DECL_OVERRIDE; + void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; +protected: + void data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial) Q_DECL_OVERRIDE; + void data_device_set_selection(Resource *resource, struct ::wl_resource *source, uint32_t serial) Q_DECL_OVERRIDE; - struct wl_display *display() const { return m_data_device_manager->display(); } private: - DataDeviceManager *m_data_device_manager; - uint32_t m_sent_selection_time; - struct wl_resource *m_data_device_resource; - - static const struct wl_data_device_interface data_device_interface; - static void start_drag(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *source, - struct wl_resource *surface, - struct wl_resource *icon, - uint32_t time); - static void set_selection(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *source, - uint32_t time); + Compositor *m_compositor; + InputDevice *m_inputDevice; + + DataSource *m_selectionSource; + + struct ::wl_client *m_dragClient; + DataSource *m_dragDataSource; + + Surface *m_dragFocus; + Resource *m_dragFocusResource; + + Surface *m_dragIcon; }; } diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp index c27aa514..7730e034 100644 --- a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp @@ -59,12 +59,13 @@ QT_BEGIN_NAMESPACE namespace QtWayland { DataDeviceManager::DataDeviceManager(Compositor *compositor) - : m_compositor(compositor) + : QObject(0) + , wl_data_device_manager(compositor->wl_display()) + , m_compositor(compositor) , m_current_selection_source(0) , m_retainedReadNotifier(0) , m_compositorOwnsSelection(false) { - wl_display_add_global(compositor->wl_display(), &wl_data_device_manager_interface, this, DataDeviceManager::bind_func_drag); } void DataDeviceManager::setCurrentSelectionSource(DataSource *source) @@ -88,7 +89,7 @@ void DataDeviceManager::setCurrentSelectionSource(DataSource *source) // 2. make it possible for the compositor to participate in copy-paste // The downside is decreased performance, therefore this mode has to be enabled // explicitly in the compositors. - if (m_compositor->wantsRetainedSelection()) { + if (m_compositor->retainedSelectionEnabled()) { m_retainedData.clear(); m_retainedReadIndex = 0; retain(); @@ -97,20 +98,19 @@ void DataDeviceManager::setCurrentSelectionSource(DataSource *source) void DataDeviceManager::sourceDestroyed(DataSource *source) { - Q_UNUSED(source); if (m_current_selection_source == source) finishReadFromClient(); } void DataDeviceManager::retain() { - QList<QByteArray> offers = m_current_selection_source->offerList(); + QList<QString> offers = m_current_selection_source->mimeTypes(); finishReadFromClient(); if (m_retainedReadIndex >= offers.count()) { m_compositor->feedRetainedSelectionData(&m_retainedData); return; } - QByteArray mimeType = offers.at(m_retainedReadIndex); + QString mimeType = offers.at(m_retainedReadIndex); m_retainedReadBuf.clear(); int fd[2]; if (pipe(fd) == -1) { @@ -118,8 +118,7 @@ void DataDeviceManager::retain() return; } fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL, 0) | O_NONBLOCK); - m_current_selection_source->postSendEvent(mimeType, fd[1]); - close(fd[1]); + m_current_selection_source->send(mimeType, fd[1]); m_retainedReadNotifier = new QSocketNotifier(fd[0], QSocketNotifier::Read, this); connect(m_retainedReadNotifier, SIGNAL(activated(int)), SLOT(readFromClient(int))); } @@ -167,8 +166,8 @@ void DataDeviceManager::readFromClient(int fd) if (n <= 0) { if (n != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) { finishReadFromClient(true); - QList<QByteArray> offers = m_current_selection_source->offerList(); - QString mimeType = QString::fromLatin1(offers.at(m_retainedReadIndex)); + QList<QString> offers = m_current_selection_source->mimeTypes(); + QString mimeType = offers.at(m_retainedReadIndex); m_retainedData.setData(mimeType, m_retainedReadBuf); ++m_retainedReadIndex; retain(); @@ -188,43 +187,6 @@ struct wl_display *DataDeviceManager::display() const return m_compositor->wl_display(); } -void DataDeviceManager::bind_func_drag(struct wl_client *client, void *data, uint32_t version, uint32_t id) -{ - Q_UNUSED(version); - wl_client_add_object(client,&wl_data_device_manager_interface,&drag_interface,id,data); -} - -void DataDeviceManager::bind_func_data(struct wl_client *client, void *data, uint32_t version, uint32_t id) -{ - Q_UNUSED(client); - Q_UNUSED(data); - Q_UNUSED(version); - Q_UNUSED(id); -} - -void DataDeviceManager::get_data_device(struct wl_client *client, - struct wl_resource *data_device_manager_resource, - uint32_t id, - struct wl_resource *input_device_resource) -{ - DataDeviceManager *data_device_manager = static_cast<DataDeviceManager *>(data_device_manager_resource->data); - InputDevice *input_device = InputDevice::fromSeatResource(input_device_resource); - input_device->clientRequestedDataDevice(data_device_manager,client,id); -} - -void DataDeviceManager::create_data_source(struct wl_client *client, - struct wl_resource *data_device_manager_resource, - uint32_t id) -{ - Q_UNUSED(data_device_manager_resource); - new DataSource(client,id, Compositor::currentTimeMsecs()); -} - -struct wl_data_device_manager_interface DataDeviceManager::drag_interface = { - DataDeviceManager::create_data_source, - DataDeviceManager::get_data_device -}; - void DataDeviceManager::overrideSelection(const QMimeData &mimeData) { QStringList formats = mimeData.formats(); @@ -243,7 +205,7 @@ void DataDeviceManager::overrideSelection(const QMimeData &mimeData) Surface *focusSurface = dev->keyboardFocus(); if (focusSurface) offerFromCompositorToClient( - dev->dataDevice(focusSurface->resource()->client())->dataDeviceResource()); + dev->dataDevice()->resourceMap().value(focusSurface->resource()->client())->handle); } bool DataDeviceManager::offerFromCompositorToClient(wl_resource *clientDataDeviceResource) @@ -275,6 +237,17 @@ void DataDeviceManager::offerRetainedSelection(wl_resource *clientDataDeviceReso offerFromCompositorToClient(clientDataDeviceResource); } +void DataDeviceManager::data_device_manager_create_data_source(Resource *resource, uint32_t id) +{ + new DataSource(resource->client(), id, m_compositor->currentTimeMsecs()); +} + +void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) +{ + InputDevice *input_device = InputDevice::fromSeatResource(seat); + input_device->clientRequestedDataDevice(this, resource->client(), id); +} + void DataDeviceManager::comp_accept(wl_client *, wl_resource *, uint32_t, const char *) { } diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h b/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h index 11510e63..e21a9567 100644 --- a/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h +++ b/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h @@ -48,6 +48,8 @@ #include <QtGui/QClipboard> #include <QtCore/QMimeData> +#include <QtCompositor/private/qwayland-server-wayland.h> + QT_BEGIN_NAMESPACE class QSocketNotifier; @@ -59,7 +61,7 @@ class Compositor; class DataDevice; class DataSource; -class DataDeviceManager : public QObject +class DataDeviceManager : public QObject, public QtWaylandServer::wl_data_device_manager { Q_OBJECT @@ -77,6 +79,10 @@ public: bool offerFromCompositorToClient(wl_resource *clientDataDeviceResource); void offerRetainedSelection(wl_resource *clientDataDeviceResource); +protected: + void data_device_manager_create_data_source(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + void data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE; + private slots: void readFromClient(int fd); @@ -89,19 +95,6 @@ private: DataSource *m_current_selection_source; - static void bind_func_drag(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - static void bind_func_data(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - static void get_data_device(struct wl_client *client, - struct wl_resource *resource, - uint32_t id, - struct wl_resource *input_device); - static void create_data_source(struct wl_client *client, - struct wl_resource *resource, - uint32_t id); - static struct wl_data_device_manager_interface drag_interface; - QMimeData m_retainedData; QSocketNotifier *m_retainedReadNotifier; QList<QSocketNotifier *> m_obsoleteRetainedReadNotifiers; diff --git a/src/compositor/wayland_wrapper/qwldataoffer.cpp b/src/compositor/wayland_wrapper/qwldataoffer.cpp index c2bfea35..88bf48fa 100644 --- a/src/compositor/wayland_wrapper/qwldataoffer.cpp +++ b/src/compositor/wayland_wrapper/qwldataoffer.cpp @@ -41,78 +41,55 @@ #include "qwldataoffer_p.h" #include "qwldatadevice_p.h" +#include "qwldatasource_p.h" -#include <wayland-server.h> - -#include <sys/time.h> #include <unistd.h> -#include <QtCore/QDebug> - QT_BEGIN_NAMESPACE namespace QtWayland { -DataOffer::DataOffer(DataSource *data_source) - : m_data_source(data_source) +DataOffer::DataOffer(DataSource *dataSource, QtWaylandServer::wl_data_device::Resource *target) + : QtWaylandServer::wl_data_offer(dataSource->resource()->client(), 0) + , m_dataSource(dataSource) { - + // FIXME: connect to dataSource and reset m_dataSource on destroy + target->data_device->send_data_offer(target->handle, resource()->handle); + Q_FOREACH (const QString &mimeType, dataSource->mimeTypes()) { + send_offer(mimeType); + } } DataOffer::~DataOffer() { } -struct wl_resource *DataOffer::addDataDeviceResource(struct wl_resource *data_device_resource) +void DataOffer::data_offer_accept(Resource *resource, uint32_t serial, const QString &mimeType) { - if (resourceForClient(data_device_resource->client)) { - qDebug() << "This should not happen, the client tries to add twice to a data offer"; - return 0; - } - struct wl_resource *new_object = - wl_client_new_object(data_device_resource->client,&wl_data_offer_interface,&data_interface,this); - wl_data_device_send_data_offer(data_device_resource, new_object); - - registerResource(new_object); - QList<QByteArray> offer_list = m_data_source->offerList(); - for (int i = 0; i < offer_list.size(); i++) { - wl_data_offer_send_offer(new_object, offer_list.at(i).constData()); - } - return new_object; + Q_UNUSED(resource); + Q_UNUSED(serial); + if (m_dataSource) + m_dataSource->accept(mimeType); } -const struct wl_data_offer_interface DataOffer::data_interface = { - DataOffer::accept, - DataOffer::receive, - DataOffer::destroy -}; - -void DataOffer::accept(wl_client *client, wl_resource *resource, uint32_t time, const char *type) +void DataOffer::data_offer_receive(Resource *resource, const QString &mimeType, int32_t fd) { - Q_UNUSED(client); Q_UNUSED(resource); - Q_UNUSED(time); - Q_UNUSED(type); + if (m_dataSource) + m_dataSource->send(mimeType, fd); + else + close(fd); } -void DataOffer::receive(wl_client *client, wl_resource *resource, const char *mime_type, int32_t fd) +void DataOffer::data_offer_destroy(Resource *resource) { - Q_UNUSED(client); - - DataOffer *offer = static_cast<DataOffer *>(resource->data); - offer->m_data_source->postSendEvent(mime_type,fd); - close(fd); + wl_resource_destroy(resource->handle); } -void DataOffer::destroy(wl_client *client, wl_resource *resource) +void DataOffer::data_offer_destroy_resource(Resource *) { - Q_UNUSED(client); - DataOffer *data_offer = static_cast<DataOffer *>(resource->data); - - if (data_offer->resourceListIsEmpty()) { - delete data_offer; - } + delete this; } } diff --git a/src/compositor/wayland_wrapper/qwldataoffer_p.h b/src/compositor/wayland_wrapper/qwldataoffer_p.h index 57943445..5911819d 100644 --- a/src/compositor/wayland_wrapper/qwldataoffer_p.h +++ b/src/compositor/wayland_wrapper/qwldataoffer_p.h @@ -41,37 +41,29 @@ #ifndef WLDATAOFFER_H #define WLDATAOFFER_H -#include <private/qwldatasource_p.h> -#include <QtCompositor/qwaylandresourcecollection.h> +#include <QtCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE namespace QtWayland { -class DataOffer : public ResourceCollection +class DataSource; + +class DataOffer : public QtWaylandServer::wl_data_offer { public: - DataOffer(DataSource *data_source); + DataOffer(DataSource *data_source, QtWaylandServer::wl_data_device::Resource *target); ~DataOffer(); - struct wl_resource *addDataDeviceResource(struct wl_resource *client_resource); -private: - DataSource *m_data_source; - - static void accept(struct wl_client *client, - struct wl_resource *resource, - uint32_t time, - const char *type); - static void receive(struct wl_client *client, - struct wl_resource *resource, - const char *mime_type, - int32_t fd); - static void destroy(struct wl_client *client, - struct wl_resource *resource); - - static const struct wl_data_offer_interface data_interface; +protected: + void data_offer_accept(Resource *resource, uint32_t serial, const QString &mime_type) Q_DECL_OVERRIDE; + void data_offer_receive(Resource *resource, const QString &mime_type, int32_t fd) Q_DECL_OVERRIDE; + void data_offer_destroy(Resource *resource) Q_DECL_OVERRIDE; + void data_offer_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; +private: + DataSource *m_dataSource; }; } diff --git a/src/compositor/wayland_wrapper/qwldatasource.cpp b/src/compositor/wayland_wrapper/qwldatasource.cpp index d60ec510..c0791d41 100644 --- a/src/compositor/wayland_wrapper/qwldatasource.cpp +++ b/src/compositor/wayland_wrapper/qwldatasource.cpp @@ -40,95 +40,88 @@ #include "qwldatasource_p.h" #include "qwldataoffer_p.h" +#include "qwldatadevice_p.h" #include "qwldatadevicemanager_p.h" #include "qwlcompositor_p.h" -#include <wayland-wayland-server-protocol.h> - -#include <QtCore/QDebug> +#include <unistd.h> +#include <QtCompositor/private/wayland-wayland-server-protocol.h> QT_BEGIN_NAMESPACE namespace QtWayland { DataSource::DataSource(struct wl_client *client, uint32_t id, uint32_t time) - : m_time(time) + : QtWaylandServer::wl_data_source(client, id) + , m_time(time) + , m_device(0) + , m_manager(0) { - m_data_source_resource = wl_client_add_object(client, &wl_data_source_interface, &DataSource::data_source_interface,id,this); - m_data_source_resource->destroy = resource_destroy; - m_data_offer = new DataOffer(this); - m_manager = 0; } DataSource::~DataSource() { if (m_manager) m_manager->sourceDestroyed(this); - wl_resource_destroy(m_data_source_resource); + if (m_device) + m_device->sourceDestroyed(this); } -void DataSource::resource_destroy(wl_resource *resource) +uint32_t DataSource::time() const { - DataSource *source = static_cast<DataSource *>(resource->data); - if (source && source->m_data_source_resource == resource) - source->m_data_source_resource = 0; - free(resource); + return m_time; } -uint32_t DataSource::time() const +QList<QString> DataSource::mimeTypes() const { - return m_time; + return m_mimeTypes; +} + +void DataSource::accept(const QString &mimeType) +{ + send_target(mimeType); } -QList<QByteArray> DataSource::offerList() const +void DataSource::send(const QString &mimeType, int fd) { - return m_offers; + send_send(mimeType, fd); + close(fd); } -struct wl_data_source_interface DataSource::data_source_interface = { - DataSource::offer, - DataSource::destroy -}; +void DataSource::cancel() +{ + send_cancelled(); +} -void DataSource::offer(struct wl_client *client, - struct wl_resource *resource, - const char *type) +void DataSource::setManager(DataDeviceManager *mgr) { - Q_UNUSED(client); - //qDebug() << "received offer" << type; - static_cast<DataSource *>(resource->data)->m_offers.append(type); + m_manager = mgr; } -void DataSource::destroy(struct wl_client *client, - struct wl_resource *resource) +void DataSource::setDevice(DataDevice *device) { - Q_UNUSED(client); - DataSource *self = static_cast<DataSource *>(resource->data); - delete self; + m_device = device; } -DataOffer * DataSource::dataOffer() const +DataSource *DataSource::fromResource(struct ::wl_resource *resource) { - return m_data_offer; + return static_cast<DataSource *>(Resource::fromResource(resource)->data_source); } -void DataSource::postSendEvent(const QByteArray &mimeType, int fd) +void DataSource::data_source_offer(Resource *, const QString &mime_type) { - if (m_data_source_resource) { - wl_data_source_send_send(m_data_source_resource, mimeType.constData(), fd); - } + m_mimeTypes.append(mime_type); } -struct wl_client *DataSource::client() const +void DataSource::data_source_destroy(Resource *resource) { - if (m_data_source_resource) - return m_data_source_resource->client; - return 0; + wl_resource_destroy(resource->handle); } -void DataSource::setManager(DataDeviceManager *mgr) +void DataSource::data_source_destroy_resource(QtWaylandServer::wl_data_source::Resource *resource) { - m_manager = mgr; + Q_UNUSED(resource); + delete this; } } diff --git a/src/compositor/wayland_wrapper/qwldatasource_p.h b/src/compositor/wayland_wrapper/qwldatasource_p.h index be855d8d..01ac4cbd 100644 --- a/src/compositor/wayland_wrapper/qwldatasource_p.h +++ b/src/compositor/wayland_wrapper/qwldatasource_p.h @@ -41,9 +41,8 @@ #ifndef WLDATASOURCE_H #define WLDATASOURCE_H -#include <wayland-server.h> +#include <QtCompositor/private/qwayland-server-wayland.h> -#include <QtCore/QByteArray> #include <QtCore/QList> QT_BEGIN_NAMESPACE @@ -51,40 +50,37 @@ QT_BEGIN_NAMESPACE namespace QtWayland { class DataOffer; +class DataDevice; class DataDeviceManager; -class DataSource +class DataSource : public QtWaylandServer::wl_data_source { public: DataSource(struct wl_client *client, uint32_t id, uint32_t time); ~DataSource(); uint32_t time() const; - QList<QByteArray> offerList() const; + QList<QString> mimeTypes() const; - DataOffer *dataOffer() const; - - void postSendEvent(const QByteArray &mimeType,int fd); - struct wl_client *client() const; + void accept(const QString &mimeType); + void send(const QString &mimeType,int fd); + void cancel(); void setManager(DataDeviceManager *mgr); + void setDevice(DataDevice *device); + + static DataSource *fromResource(struct ::wl_resource *resource); + +protected: + void data_source_offer(Resource *resource, const QString &mime_type) Q_DECL_OVERRIDE; + void data_source_destroy(Resource *resource) Q_DECL_OVERRIDE; + void data_source_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; private: uint32_t m_time; - QList<QByteArray> m_offers; - struct wl_resource *m_data_source_resource; - - DataOffer *m_data_offer; + QList<QString> m_mimeTypes; + DataDevice *m_device; DataDeviceManager *m_manager; - - static struct wl_data_source_interface data_source_interface; - static void offer(struct wl_client *client, - struct wl_resource *resource, - const char *type); - static void destroy(struct wl_client *client, - struct wl_resource *resource); - - static void resource_destroy(struct wl_resource *resource); }; } diff --git a/src/compositor/wayland_wrapper/qwldisplay.cpp b/src/compositor/wayland_wrapper/qwldisplay.cpp index 5dd6e382..affb0d17 100644 --- a/src/compositor/wayland_wrapper/qwldisplay.cpp +++ b/src/compositor/wayland_wrapper/qwldisplay.cpp @@ -42,7 +42,7 @@ #include <QtCore/QDebug> -#include <wayland-wayland-server-protocol.h> +#include <QtCompositor/private/wayland-wayland-server-protocol.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlextendedoutput_p.h b/src/compositor/wayland_wrapper/qwlextendedoutput_p.h index d1704b8c..f3625ed4 100644 --- a/src/compositor/wayland_wrapper/qwlextendedoutput_p.h +++ b/src/compositor/wayland_wrapper/qwlextendedoutput_p.h @@ -47,7 +47,7 @@ #include <QtCore/qnamespace.h> -#include <qwayland-server-output-extension.h> +#include <QtCompositor/private/qwayland-server-output-extension.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h index ecf2f49d..3b572108 100644 --- a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h @@ -43,7 +43,7 @@ #include <wayland-server.h> -#include "qwayland-server-surface-extension.h" +#include <QtCompositor/private/qwayland-server-surface-extension.h> #include <private/qwlsurface_p.h> #include <QtCompositor/qwaylandsurface.h> diff --git a/src/compositor/wayland_wrapper/qwlinputdevice.cpp b/src/compositor/wayland_wrapper/qwlinputdevice.cpp index d9a91bfa..abc20843 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice.cpp +++ b/src/compositor/wayland_wrapper/qwlinputdevice.cpp @@ -42,10 +42,12 @@ #include "qwlcompositor_p.h" #include "qwldatadevice_p.h" +#include "qwlinputmethod_p.h" #include "qwlsurface_p.h" #include "qwlqttouch_p.h" #include "qwlqtkey_p.h" #include "qwaylandcompositor.h" +#include "qwaylanddrag.h" #include "qwlpointer_p.h" #include "qwlkeyboard_p.h" #include "qwltouch_p.h" @@ -59,16 +61,18 @@ namespace QtWayland { InputDevice::InputDevice(QWaylandInputDevice *handle, Compositor *compositor) : QtWaylandServer::wl_seat(compositor->wl_display()) , m_handle(handle) + , m_dragHandle(new QWaylandDrag(this)) , m_compositor(compositor) , m_pointer(new Pointer(m_compositor, this)) , m_keyboard(new Keyboard(m_compositor, this)) , m_touch(new Touch(m_compositor)) + , m_inputMethod(m_compositor->extensions() & QWaylandCompositor::TextInputExtension ? new InputMethod(m_compositor, this) : 0) + , m_data_device() { } InputDevice::~InputDevice() { - qDeleteAll(m_data_devices); } Pointer *InputDevice::pointerDevice() @@ -86,6 +90,11 @@ Touch *InputDevice::touchDevice() return m_touch.data(); } +InputMethod *InputDevice::inputMethod() +{ + return m_inputMethod.data(); +} + const Pointer *InputDevice::pointerDevice() const { return m_pointer.data(); @@ -101,9 +110,9 @@ const Touch *InputDevice::touchDevice() const return m_touch.data(); } -void InputDevice::seat_destroy_resource(wl_seat::Resource *resource) +void InputDevice::seat_destroy_resource(wl_seat::Resource *) { - cleanupDataDeviceForClient(resource->client(), true); +// cleanupDataDeviceForClient(resource->client(), true); } void InputDevice::seat_bind_resource(wl_seat::Resource *resource) @@ -203,6 +212,13 @@ void InputDevice::sendFullKeyEvent(QKeyEvent *event) m_keyboard->sendKeyReleaseEvent(event->nativeScanCode()); } +void InputDevice::sendFullKeyEvent(Surface *surface, QKeyEvent *event) +{ + QtKeyExtensionGlobal *ext = m_compositor->qtkeyExtension(); + if (ext) + ext->postQtKeyEvent(event, surface); +} + void InputDevice::sendFullTouchEvent(QTouchEvent *event) { if (!mouseFocus()) { @@ -247,8 +263,8 @@ bool InputDevice::setKeyboardFocus(Surface *surface) if (surface && surface->transientInactive()) return false; - sendSelectionFocus(surface); m_keyboard->setFocus(surface); + m_data_device->setFocus(m_keyboard->focusResource()); return true; } @@ -266,35 +282,11 @@ void InputDevice::setMouseFocus(Surface *surface, const QPointF &localPos, const m_touch->setFocus(surface); } -void InputDevice::cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev) -{ - for (int i = 0; i < m_data_devices.size(); i++) { - struct wl_resource *data_device_resource = - m_data_devices.at(i)->dataDeviceResource(); - if (data_device_resource->client == client) { - if (destroyDev) - delete m_data_devices.at(i); - m_data_devices.removeAt(i); - break; - } - } -} - -void InputDevice::clientRequestedDataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id) +void InputDevice::clientRequestedDataDevice(DataDeviceManager *, struct wl_client *client, uint32_t id) { - cleanupDataDeviceForClient(client, false); - DataDevice *dataDevice = new DataDevice(data_device_manager,client,id); - m_data_devices.append(dataDevice); -} - -void InputDevice::sendSelectionFocus(Surface *surface) -{ - if (!surface) - return; - DataDevice *device = dataDevice(surface->resource()->client()); - if (device) { - device->sendSelectionFocus(); - } + if (!m_data_device) + m_data_device.reset(new DataDevice(this)); + m_data_device->add(client, id); } Compositor *InputDevice::compositor() const @@ -307,14 +299,14 @@ QWaylandInputDevice *InputDevice::handle() const return m_handle; } -DataDevice *InputDevice::dataDevice(struct wl_client *client) const +QWaylandDrag *InputDevice::dragHandle() const { - for (int i = 0; i < m_data_devices.size();i++) { - if (m_data_devices.at(i)->dataDeviceResource()->client == client) { - return m_data_devices.at(i); - } - } - return 0; + return m_dragHandle; +} + +const DataDevice *InputDevice::dataDevice() const +{ + return m_data_device.data(); } } diff --git a/src/compositor/wayland_wrapper/qwlinputdevice_p.h b/src/compositor/wayland_wrapper/qwlinputdevice_p.h index 8ad8a0a7..01f68c3f 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice_p.h +++ b/src/compositor/wayland_wrapper/qwlinputdevice_p.h @@ -43,6 +43,8 @@ #include <stdint.h> +#include <QtCompositor/qwaylandexport.h> + #include <QtCore/QList> #include <QtCore/QPoint> #include <QtCore/QScopedPointer> @@ -51,13 +53,14 @@ #include <xkbcommon/xkbcommon.h> #endif -#include <qwayland-server-wayland.h> +#include <QtCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE class QKeyEvent; class QTouchEvent; class QWaylandInputDevice; +class QWaylandDrag; namespace QtWayland { @@ -68,8 +71,9 @@ class DataDeviceManager; class Pointer; class Keyboard; class Touch; +class InputMethod; -class InputDevice : public QtWaylandServer::wl_seat, public QtWaylandServer::wl_touch +class Q_COMPOSITOR_EXPORT InputDevice : public QtWaylandServer::wl_seat { public: InputDevice(QWaylandInputDevice *handle, Compositor *compositor); @@ -86,6 +90,8 @@ public: void sendTouchCancelEvent(); void sendFullKeyEvent(QKeyEvent *event); + void sendFullKeyEvent(Surface *surface, QKeyEvent *event); + void sendFullTouchEvent(QTouchEvent *event); Surface *keyboardFocus() const; @@ -95,15 +101,16 @@ public: void setMouseFocus(Surface *surface, const QPointF &localPos, const QPointF &globalPos); void clientRequestedDataDevice(DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id); - DataDevice *dataDevice(struct wl_client *client) const; - void sendSelectionFocus(Surface *surface); + const DataDevice *dataDevice() const; Compositor *compositor() const; QWaylandInputDevice *handle() const; + QWaylandDrag *dragHandle() const; Pointer *pointerDevice(); Keyboard *keyboardDevice(); Touch *touchDevice(); + InputMethod *inputMethod(); const Pointer *pointerDevice() const; const Keyboard *keyboardDevice() const; @@ -115,15 +122,15 @@ public: } private: - void cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev); - QWaylandInputDevice *m_handle; + QWaylandDrag *m_dragHandle; Compositor *m_compositor; - QList<DataDevice *> m_data_devices; QScopedPointer<Pointer> m_pointer; QScopedPointer<Keyboard> m_keyboard; - QScopedPointer<Touch> m_touch; + QScopedPointer<Touch> m_touch; + QScopedPointer<InputMethod> m_inputMethod; + QScopedPointer<DataDevice> m_data_device; void seat_bind_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE; diff --git a/src/compositor/wayland_wrapper/qwlinputmethod.cpp b/src/compositor/wayland_wrapper/qwlinputmethod.cpp new file mode 100644 index 00000000..7a3c073c --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlinputmethod.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwlinputmethod_p.h" + +#include <QDebug> + +#include "qwlcompositor_p.h" +#include "qwlinputdevice_p.h" +#include "qwlinputmethodcontext_p.h" +#include "qwlinputpanel_p.h" +#include "qwlkeyboard_p.h" +#include "qwltextinput_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +InputMethod::InputMethod(Compositor *compositor, InputDevice *seat) + : QtWaylandServer::wl_input_method(seat->compositor()->wl_display()) + , m_compositor(compositor) + , m_seat(seat) + , m_resource(0) + , m_textInput() + , m_context() +{ + connect(seat->keyboardDevice(), SIGNAL(focusChanged(Surface*)), this, SLOT(focusChanged(Surface*))); +} + +InputMethod::~InputMethod() +{ +} + +void InputMethod::activate(TextInput *textInput) +{ + if (!m_resource) { + qDebug() << "Cannout activate no input method running."; + return; + } + + if (m_textInput) { + Q_ASSERT(m_textInput != textInput); + m_textInput->deactivate(this); + } + m_textInput = textInput; + m_context = new InputMethodContext(m_resource->client(), textInput); + + send_activate(m_resource->handle, m_context->resource()->handle); + + m_compositor->inputPanel()->setFocus(textInput->focus()); + m_compositor->inputPanel()->setCursorRectangle(textInput->cursorRectangle()); + m_compositor->inputPanel()->setInputPanelVisible(textInput->inputPanelVisible()); +} + +void InputMethod::deactivate() +{ + if (!m_resource) { + qDebug() << "Cannout deactivate no input method running."; + return; + } + + send_deactivate(m_resource->handle, m_context->resource()->handle); + m_textInput = 0; + m_context = 0; + + m_compositor->inputPanel()->setFocus(0); + m_compositor->inputPanel()->setCursorRectangle(QRect()); + m_compositor->inputPanel()->setInputPanelVisible(false); +} + +void InputMethod::focusChanged(Surface *surface) +{ + if (!m_textInput) + return; + + if (!surface || m_textInput->focus() != surface) { + m_textInput->deactivate(this); + } +} + +bool InputMethod::isBound() const +{ + return m_resource != 0; +} + +InputMethodContext *InputMethod::context() const +{ + return m_context; +} + +TextInput *InputMethod::textInput() const +{ + return m_textInput; +} + +void InputMethod::input_method_bind_resource(Resource *resource) +{ + if (m_resource) { + wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "interface object already bound"); + wl_resource_destroy(resource->handle); + return; + } + + m_resource = resource; +} + +void InputMethod::input_method_destroy_resource(Resource *resource) +{ + Q_ASSERT(resource == m_resource); + m_resource = 0; +} + +} // namespace QtWayland + +QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlinputmethod_p.h b/src/compositor/wayland_wrapper/qwlinputmethod_p.h new file mode 100644 index 00000000..2cfa14b9 --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlinputmethod_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTWAYLAND_QWLINPUTMETHOD_H +#define QTWAYLAND_QWLINPUTMETHOD_H + +#include <QtCompositor/private/qwayland-server-input-method.h> + +#include <QObject> +#include <QScopedPointer> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class Compositor; +class InputDevice; +class InputMethodContext; +class TextInput; +class Surface; + +class InputMethod : public QObject, public QtWaylandServer::wl_input_method +{ + Q_OBJECT + +public: + explicit InputMethod(Compositor *compositor, InputDevice *seat); + ~InputMethod(); + + void activate(TextInput *textInput); + void deactivate(); + + bool isBound() const; + + InputMethodContext *context() const; + TextInput *textInput() const; + +protected: + void input_method_bind_resource(Resource *resource); + void input_method_destroy_resource(Resource *resource); + +private slots: + void focusChanged(Surface *surface); + +private: + Compositor *m_compositor; + InputDevice *m_seat; + Resource *m_resource; + TextInput *m_textInput; + InputMethodContext *m_context; +}; + +} // namespace QtWayland + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLINPUTMETHOD_H diff --git a/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp b/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp new file mode 100644 index 00000000..b8a7859f --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwlinputmethodcontext_p.h" + +#include "qwltextinput_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +InputMethodContext::InputMethodContext(wl_client *client, TextInput *textInput) + : QtWaylandServer::wl_input_method_context(client, 0) + , m_textInput(textInput) +{ +} + +InputMethodContext::~InputMethodContext() +{ +} + +void InputMethodContext::input_method_context_destroy_resource(Resource *) +{ + delete this; +} + +void InputMethodContext::input_method_context_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void InputMethodContext::input_method_context_commit_string(Resource *, uint32_t serial, const QString &text) +{ + m_textInput->send_commit_string(serial, text); +} + +void InputMethodContext::input_method_context_cursor_position(Resource *, int32_t index, int32_t anchor) +{ + m_textInput->send_cursor_position(index, anchor); +} + +void InputMethodContext::input_method_context_delete_surrounding_text(Resource *, int32_t index, uint32_t length) +{ + m_textInput->send_delete_surrounding_text(index, length); +} + +void InputMethodContext::input_method_context_language(Resource *, uint32_t serial, const QString &language) +{ + m_textInput->send_language(serial, language); +} + +void InputMethodContext::input_method_context_keysym(Resource *, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers) +{ + m_textInput->send_keysym(serial, time, sym, state, modifiers); +} + +void InputMethodContext::input_method_context_modifiers_map(Resource *, wl_array *map) +{ + QByteArray modifiersArray(static_cast<char *>(map->data), map->size); + m_textInput->send_modifiers_map(modifiersArray); +} + +void InputMethodContext::input_method_context_preedit_cursor(Resource *, int32_t index) +{ + m_textInput->send_preedit_cursor(index); +} + +void InputMethodContext::input_method_context_preedit_string(Resource *, uint32_t serial, const QString &text, const QString &commit) +{ + m_textInput->send_preedit_string(serial, text, commit); +} + +void InputMethodContext::input_method_context_preedit_styling(Resource *, uint32_t index, uint32_t length, uint32_t style) +{ + m_textInput->send_preedit_styling(index, length, style); +} + +void InputMethodContext::input_method_context_grab_keyboard(Resource *, uint32_t keyboard) +{ + Q_UNUSED(keyboard); +} + +void InputMethodContext::input_method_context_key(Resource *, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) +{ + Q_UNUSED(serial); + Q_UNUSED(time); + Q_UNUSED(key); + Q_UNUSED(state); +} + +void InputMethodContext::input_method_context_modifiers(Resource *, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) +{ + Q_UNUSED(serial); + Q_UNUSED(mods_depressed); + Q_UNUSED(mods_latched); + Q_UNUSED(mods_locked); + Q_UNUSED(group); +} + +} // namespace QtWayland + +QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlinputmethodcontext_p.h b/src/compositor/wayland_wrapper/qwlinputmethodcontext_p.h new file mode 100644 index 00000000..5060d4d6 --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlinputmethodcontext_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTWAYLAND_QWLINPUTMETHODCONTEXT_P_H +#define QTWAYLAND_QWLINPUTMETHODCONTEXT_P_H + +#include <QtCompositor/private/qwayland-server-input-method.h> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class TextInput; + +class InputMethodContext : public QtWaylandServer::wl_input_method_context +{ +public: + explicit InputMethodContext(struct ::wl_client *client, TextInput *textInput); + ~InputMethodContext(); + +protected: + void input_method_context_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + void input_method_context_destroy(Resource *resource) Q_DECL_OVERRIDE; + + void input_method_context_commit_string(Resource *resource, uint32_t serial, const QString &text) Q_DECL_OVERRIDE; + void input_method_context_cursor_position(Resource *resource, int32_t index, int32_t anchor) Q_DECL_OVERRIDE; + void input_method_context_delete_surrounding_text(Resource *resource, int32_t index, uint32_t length) Q_DECL_OVERRIDE; + void input_method_context_language(Resource *resource, uint32_t serial, const QString &language) Q_DECL_OVERRIDE; + void input_method_context_keysym(Resource *resource, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers) Q_DECL_OVERRIDE; + void input_method_context_modifiers_map(Resource *resource, wl_array *map) Q_DECL_OVERRIDE; + void input_method_context_preedit_cursor(Resource *resource, int32_t index) Q_DECL_OVERRIDE; + void input_method_context_preedit_string(Resource *resource, uint32_t serial, const QString &text, const QString &commit) Q_DECL_OVERRIDE; + void input_method_context_preedit_styling(Resource *resource, uint32_t index, uint32_t length, uint32_t style) Q_DECL_OVERRIDE; + void input_method_context_grab_keyboard(Resource *resource, uint32_t keyboard) Q_DECL_OVERRIDE; + void input_method_context_key(Resource *resource, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) Q_DECL_OVERRIDE; + void input_method_context_modifiers(Resource *resource, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) Q_DECL_OVERRIDE; + +private: + TextInput *m_textInput; +}; + +} // namespace QtWayland + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLINPUTMETHODCONTEXT_P_H diff --git a/src/compositor/wayland_wrapper/qwlinputpanel.cpp b/src/compositor/wayland_wrapper/qwlinputpanel.cpp new file mode 100644 index 00000000..3848543d --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlinputpanel.cpp @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwlinputpanel_p.h" + +#include <QtCompositor/qwaylandinputpanel.h> + +#include "qwlcompositor_p.h" +#include "qwlinputdevice_p.h" +#include "qwlinputmethod_p.h" +#include "qwlinputpanelsurface_p.h" +#include "qwlsurface_p.h" +#include "qwltextinput_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +InputPanel::InputPanel(Compositor *compositor) + : QtWaylandServer::wl_input_panel(compositor->wl_display()) + , m_compositor(compositor) + , m_handle(new QWaylandInputPanel(this)) + , m_focus() + , m_inputPanelVisible(false) + , m_cursorRectangle() +{ +} + +InputPanel::~InputPanel() +{ +} + +QWaylandInputPanel *InputPanel::handle() const +{ + return m_handle.data(); +} + +Surface *InputPanel::focus() const +{ + return m_focus; +} + +void InputPanel::setFocus(Surface *focus) +{ + if (m_focus == focus) + return; + + m_focus = focus; + + Q_EMIT handle()->focusChanged(); +} + +bool InputPanel::inputPanelVisible() const +{ + return m_inputPanelVisible; +} + +void InputPanel::setInputPanelVisible(bool inputPanelVisible) +{ + if (m_inputPanelVisible == inputPanelVisible) + return; + + m_inputPanelVisible = inputPanelVisible; + + Q_EMIT handle()->visibleChanged(); +} + +QRect InputPanel::cursorRectangle() const +{ + return m_cursorRectangle; +} + +void InputPanel::setCursorRectangle(const QRect &cursorRectangle) +{ + if (m_cursorRectangle == cursorRectangle) + return; + + m_cursorRectangle = cursorRectangle; + + Q_EMIT handle()->cursorRectangleChanged(); +} + +void InputPanel::input_panel_get_input_panel_surface(Resource *resource, uint32_t id, wl_resource *surface) +{ + new InputPanelSurface(resource->client(), id, Surface::fromResource(surface)); +} + +} // namespace QtWayland + +QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlinputpanel_p.h b/src/compositor/wayland_wrapper/qwlinputpanel_p.h new file mode 100644 index 00000000..75d795e4 --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlinputpanel_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTWAYLAND_QWLINPUTPANEL_P_H +#define QTWAYLAND_QWLINPUTPANEL_P_H + +#include <QtCompositor/qwaylandexport.h> + +#include <QtCompositor/private/qwayland-server-input-method.h> + +#include <QRect> +#include <QScopedPointer> + +QT_BEGIN_NAMESPACE + +class QWaylandInputPanel; + +namespace QtWayland { + +class Compositor; +class Surface; +class TextInput; + +class Q_COMPOSITOR_EXPORT InputPanel : public QtWaylandServer::wl_input_panel +{ +public: + InputPanel(Compositor *compositor); + ~InputPanel(); + + QWaylandInputPanel *handle() const; + + Surface *focus() const; + void setFocus(Surface *focus); + + bool inputPanelVisible() const; + void setInputPanelVisible(bool inputPanelVisible); + + QRect cursorRectangle() const; + void setCursorRectangle(const QRect &cursorRectangle); + +protected: + void input_panel_get_input_panel_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE; + +private: + Compositor *m_compositor; + QScopedPointer<QWaylandInputPanel> m_handle; + + Surface *m_focus; + bool m_inputPanelVisible; + QRect m_cursorRectangle; +}; + +} // namespace QtWayland + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLINPUTPANEL_P_H diff --git a/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp b/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp new file mode 100644 index 00000000..fd258bcb --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwlinputpanelsurface_p.h" + +#include "qwloutput_p.h" +#include "qwlsurface_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +InputPanelSurface::InputPanelSurface(wl_client *client, int id, Surface *surface) + : QtWaylandServer::wl_input_panel_surface(client, id) + , m_surface(surface) + , m_type(Invalid) + , m_output(0) + , m_position() +{ + surface->setInputPanelSurface(this); +} + +InputPanelSurface::Type InputPanelSurface::type() const +{ + return m_type; +} + +Output *InputPanelSurface::output() const +{ + return m_output; +} + +QtWaylandServer::wl_input_panel_surface::position InputPanelSurface::position() const +{ + return m_position; +} + +void InputPanelSurface::input_panel_surface_set_overlay_panel(Resource *) +{ + m_type = OverlayPanel; +} + +void InputPanelSurface::input_panel_surface_set_toplevel(Resource *, wl_resource *output, uint32_t position) +{ + m_type = Toplevel; + m_output = static_cast<Output *>(Output::Resource::fromResource(output)); + m_position = static_cast<wl_input_panel_surface::position>(position); +} + +QT_END_NAMESPACE + +} // namespace QtWayland diff --git a/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h b/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h new file mode 100644 index 00000000..89c85895 --- /dev/null +++ b/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTWAYLAND_QWLINPUTPANELSURFACE_P_H +#define QTWAYLAND_QWLINPUTPANELSURFACE_P_H + +#include <QtCompositor/private/qwayland-server-input-method.h> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class Output; +class Surface; + +class InputPanelSurface : public QtWaylandServer::wl_input_panel_surface +{ +public: + enum Type { + Invalid, + Toplevel, + OverlayPanel + }; + + InputPanelSurface(struct ::wl_client *client, int id, Surface *surface); + + Type type() const; + + Output *output() const; + wl_input_panel_surface::position position() const; + +protected: + void input_panel_surface_set_overlay_panel(Resource *resource) Q_DECL_OVERRIDE; + void input_panel_surface_set_toplevel(Resource *resource, wl_resource *output, uint32_t position) Q_DECL_OVERRIDE; + +private: + Surface *m_surface; + + Type m_type; + + Output *m_output; + wl_input_panel_surface::position m_position; +}; + +} // namespace QtWayland + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLINPUTPANELSURFACE_P_H diff --git a/src/compositor/wayland_wrapper/qwlkeyboard.cpp b/src/compositor/wayland_wrapper/qwlkeyboard.cpp index 54349e30..8e74a779 100644 --- a/src/compositor/wayland_wrapper/qwlkeyboard.cpp +++ b/src/compositor/wayland_wrapper/qwlkeyboard.cpp @@ -100,6 +100,7 @@ void Keyboard::setFocus(Surface *surface) m_focusResource = resource; m_focus = surface; + Q_EMIT focusChanged(m_focus); } void Keyboard::sendKeyModifiers(wl_keyboard::Resource *resource, uint32_t serial) @@ -122,6 +123,11 @@ Surface *Keyboard::focus() const return m_focus; } +QtWaylandServer::wl_keyboard::Resource *Keyboard::focusResource() const +{ + return m_focusResource; +} + void Keyboard::keyboard_bind_resource(wl_keyboard::Resource *resource) { #ifndef QT_NO_WAYLAND_XKB diff --git a/src/compositor/wayland_wrapper/qwlkeyboard_p.h b/src/compositor/wayland_wrapper/qwlkeyboard_p.h index 80b21106..4d783f77 100644 --- a/src/compositor/wayland_wrapper/qwlkeyboard_p.h +++ b/src/compositor/wayland_wrapper/qwlkeyboard_p.h @@ -42,7 +42,10 @@ #ifndef QTWAYLAND_QWLKEYBOARD_P_H #define QTWAYLAND_QWLKEYBOARD_P_H -#include <qwayland-server-wayland.h> +#include <QtCompositor/qwaylandexport.h> + +#include <QObject> +#include <QtCompositor/private/qwayland-server-wayland.h> #include <QtCore/QByteArray> @@ -58,8 +61,10 @@ class Compositor; class InputDevice; class Surface; -class Keyboard : public QtWaylandServer::wl_keyboard +class Q_COMPOSITOR_EXPORT Keyboard : public QObject, public QtWaylandServer::wl_keyboard { + Q_OBJECT + public: Keyboard(Compositor *compositor, InputDevice *seat); ~Keyboard(); @@ -71,6 +76,10 @@ public: void sendKeyReleaseEvent(uint code); Surface *focus() const; + Resource *focusResource() const; + +Q_SIGNALS: + void focusChanged(Surface *surface); protected: void keyboard_bind_resource(Resource *resource); diff --git a/src/compositor/wayland_wrapper/qwloutput_p.h b/src/compositor/wayland_wrapper/qwloutput_p.h index 514d3e9f..738a73fc 100644 --- a/src/compositor/wayland_wrapper/qwloutput_p.h +++ b/src/compositor/wayland_wrapper/qwloutput_p.h @@ -44,7 +44,7 @@ #include <QtCore/QRect> #include <QtCore/QList> -#include <qwayland-server-wayland.h> +#include <QtCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlpointer.cpp b/src/compositor/wayland_wrapper/qwlpointer.cpp index e1e1305e..b459472a 100644 --- a/src/compositor/wayland_wrapper/qwlpointer.cpp +++ b/src/compositor/wayland_wrapper/qwlpointer.cpp @@ -86,6 +86,9 @@ Pointer::Pointer(Compositor *compositor, InputDevice *seat) , m_compositor(compositor) , m_seat(seat) , m_grab(this) + , m_grabButton() + , m_grabTime() + , m_grabSerial() , m_position(100, 100) , m_focus() , m_focusResource() @@ -146,6 +149,26 @@ bool Pointer::buttonPressed() const return m_buttonCount > 0; } +PointerGrabber *Pointer::currentGrab() const +{ + return m_grab; +} + +Qt::MouseButton Pointer::grabButton() const +{ + return m_grabButton; +} + +uint32_t Pointer::grabTime() const +{ + return m_grabTime; +} + +uint32_t Pointer::grabSerial() const +{ + return m_grabSerial; +} + Surface *Pointer::focusSurface() const { return m_focus; @@ -161,6 +184,16 @@ QPointF Pointer::position() const return m_position; } +QPointF Pointer::currentPosition() const +{ + return m_currentPoint; +} + +QtWaylandServer::wl_pointer::Resource *Pointer::focusResource() const +{ + return m_focusResource; +} + void Pointer::pointer_destroy_resource(wl_pointer::Resource *resource) { if (m_focusResource == resource) @@ -177,20 +210,36 @@ void Pointer::setMouseFocus(Surface *surface, const QPointF &localPos, const QPo m_grab->focus(); } +void Pointer::sendButton(uint32_t time, Qt::MouseButton button, uint32_t state) +{ + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + send_button(m_focusResource->handle, serial, time, toWaylandButton(button), state); +} + void Pointer::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) { sendMouseMoveEvent(localPos, globalPos); - m_buttonCount++; uint32_t time = m_compositor->currentTimeMsecs(); + if (m_buttonCount == 0) { + m_grabButton = button; + m_grabTime = time; + } + m_buttonCount++; m_grab->button(time, button, WL_POINTER_BUTTON_STATE_PRESSED); + + if (m_buttonCount == 1) + m_grabSerial = wl_display_get_serial(m_compositor->wl_display()); } void Pointer::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) { sendMouseMoveEvent(localPos, globalPos); - m_buttonCount--; uint32_t time = m_compositor->currentTimeMsecs(); + m_buttonCount--; m_grab->button(time, button, WL_POINTER_BUTTON_STATE_RELEASED); + + if (m_buttonCount == 1) + m_grabSerial = wl_display_get_serial(m_compositor->wl_display()); } void Pointer::sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos) @@ -234,8 +283,7 @@ void Pointer::motion(uint32_t time) void Pointer::button(uint32_t time, Qt::MouseButton button, uint32_t state) { if (m_focusResource) { - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - send_button(m_focusResource->handle, serial, time, toWaylandButton(button), state); + sendButton(time, button, state); } if (!buttonPressed() && state == WL_POINTER_BUTTON_STATE_RELEASED) diff --git a/src/compositor/wayland_wrapper/qwlpointer_p.h b/src/compositor/wayland_wrapper/qwlpointer_p.h index f6db2dcb..ed53b048 100644 --- a/src/compositor/wayland_wrapper/qwlpointer_p.h +++ b/src/compositor/wayland_wrapper/qwlpointer_p.h @@ -42,10 +42,12 @@ #ifndef QTWAYLAND_QWLPOINTER_P_H #define QTWAYLAND_QWLPOINTER_P_H +#include <QtCompositor/qwaylandexport.h> + #include <QtCore/QList> #include <QtCore/QPoint> -#include <qwayland-server-wayland.h> +#include <QtCompositor/private/qwayland-server-wayland.h> #include <stdint.h> @@ -58,7 +60,7 @@ class InputDevice; class Pointer; class Surface; -class PointerGrabber { +class Q_COMPOSITOR_EXPORT PointerGrabber { public: virtual ~PointerGrabber(); @@ -69,19 +71,25 @@ public: Pointer *m_pointer; }; -class Pointer : public QtWaylandServer::wl_pointer, public PointerGrabber +class Q_COMPOSITOR_EXPORT Pointer : public QtWaylandServer::wl_pointer, public PointerGrabber { public: Pointer(Compositor *compositor, InputDevice *seat); void setFocus(Surface *surface, const QPointF &position); - void startGrab(PointerGrabber *grab); + void startGrab(PointerGrabber *currentGrab); void endGrab(); + PointerGrabber *currentGrab() const; + Qt::MouseButton grabButton() const; + uint32_t grabTime() const; + uint32_t grabSerial() const; void setCurrent(Surface *surface, const QPointF &point); void setMouseFocus(Surface *surface, const QPointF &localPos, const QPointF &globalPos); + void sendButton(uint32_t time, Qt::MouseButton button, uint32_t state); + void sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos); void sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos); void sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos); @@ -90,6 +98,10 @@ public: Surface *focusSurface() const; Surface *current() const; QPointF position() const; + QPointF currentPosition() const; + Resource *focusResource() const; + + bool buttonPressed() const; void focus() Q_DECL_OVERRIDE; void motion(uint32_t time) Q_DECL_OVERRIDE; @@ -100,12 +112,13 @@ protected: void pointer_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; private: - bool buttonPressed() const; - Compositor *m_compositor; InputDevice *m_seat; PointerGrabber *m_grab; + Qt::MouseButton m_grabButton; + uint32_t m_grabTime; + uint32_t m_grabSerial; QPointF m_position; diff --git a/src/compositor/wayland_wrapper/qwlqtkey.cpp b/src/compositor/wayland_wrapper/qwlqtkey.cpp index a2b99ebc..ba028878 100644 --- a/src/compositor/wayland_wrapper/qwlqtkey.cpp +++ b/src/compositor/wayland_wrapper/qwlqtkey.cpp @@ -63,6 +63,7 @@ bool QtKeyExtensionGlobal::postQtKeyEvent(QKeyEvent *event, Surface *surface) if (target) { send_qtkey(target->handle, + surface ? surface->resource()->handle : 0, time, event->type(), event->key(), event->modifiers(), event->nativeScanCode(), event->nativeVirtualKey(), diff --git a/src/compositor/wayland_wrapper/qwlqtkey_p.h b/src/compositor/wayland_wrapper/qwlqtkey_p.h index 012ef388..6257e0a9 100644 --- a/src/compositor/wayland_wrapper/qwlqtkey_p.h +++ b/src/compositor/wayland_wrapper/qwlqtkey_p.h @@ -45,7 +45,7 @@ #include "wayland-util.h" -#include "qwayland-server-qtkey-extension.h" +#include <QtCompositor/private/qwayland-server-qtkey-extension.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlqttouch_p.h b/src/compositor/wayland_wrapper/qwlqttouch_p.h index 2610936a..f2729c99 100644 --- a/src/compositor/wayland_wrapper/qwlqttouch_p.h +++ b/src/compositor/wayland_wrapper/qwlqttouch_p.h @@ -42,7 +42,7 @@ #define WLTOUCH_H #include <private/qwlcompositor_p.h> -#include "qwayland-server-touch-extension.h" +#include <QtCompositor/private/qwayland-server-touch-extension.h> #include "wayland-util.h" QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlregion_p.h b/src/compositor/wayland_wrapper/qwlregion_p.h index f905d96b..06d21ff3 100644 --- a/src/compositor/wayland_wrapper/qwlregion_p.h +++ b/src/compositor/wayland_wrapper/qwlregion_p.h @@ -46,7 +46,7 @@ #include <QRegion> #include <wayland-util.h> -#include "qwayland-server-wayland.h" +#include <QtCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlshellsurface.cpp b/src/compositor/wayland_wrapper/qwlshellsurface.cpp index a1e6bb37..9b61d60b 100644 --- a/src/compositor/wayland_wrapper/qwlshellsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlshellsurface.cpp @@ -65,28 +65,41 @@ void Shell::bind_func(struct wl_client *client, void *data, wl_client_add_object(client,&wl_shell_interface,&shell_interface,id,data); } +ShellSurfacePopupGrabber *Shell::getPopupGrabber(InputDevice *input) +{ + if (!m_popupGrabber.contains(input)) + m_popupGrabber.insert(input, new ShellSurfacePopupGrabber(input)); + + return m_popupGrabber.value(input); +} + void Shell::get_shell_surface(struct wl_client *client, struct wl_resource *shell_resource, uint32_t id, struct wl_resource *surface_super) { - Q_UNUSED(shell_resource); + Shell *shell = static_cast<Shell*>(shell_resource->data); Surface *surface = Surface::fromResource(surface_super); - new ShellSurface(client,id,surface); + new ShellSurface(shell, client, id, surface); } const struct wl_shell_interface Shell::shell_interface = { Shell::get_shell_surface }; -ShellSurface::ShellSurface(wl_client *client, uint32_t id, Surface *surface) +ShellSurface::ShellSurface(Shell *shell, wl_client *client, uint32_t id, Surface *surface) : wl_shell_surface(client, id) + , m_shell(shell) , m_surface(surface) , m_resizeGrabber(0) , m_moveGrabber(0) + , m_popupGrabber(0) , m_transientParent(0) , m_xOffset(0) , m_yOffset(0) + , m_windowType(QWaylandSurface::None) + , m_popupLocation() + , m_popupSerial() { surface->setShellSurface(this); } @@ -96,6 +109,13 @@ void ShellSurface::sendConfigure(uint32_t edges, int32_t width, int32_t height) send_configure(edges, width, height); } +void ShellSurface::ping() +{ + uint32_t serial = wl_display_next_serial(m_surface->compositor()->wl_display()); + m_pings.insert(serial); + send_ping(serial); +} + Surface *ShellSurface::surface() const { return m_surface; @@ -150,8 +170,26 @@ void ShellSurface::setOffset(const QPointF &offset) m_yOffset = offset.y(); } +QWaylandSurface::WindowType ShellSurface::windowType() const +{ + return m_windowType; +} + +void ShellSurface::mapPopup() +{ + if (m_popupGrabber->grabSerial() == m_popupSerial) { + m_popupGrabber->addPopup(this); + } else { + send_popup_done(); + m_popupGrabber->setClient(0); + } +} + void ShellSurface::shell_surface_destroy_resource(Resource *) { + if (m_popupGrabber) + m_popupGrabber->removePopup(this); + delete this; } @@ -209,6 +247,11 @@ void ShellSurface::shell_surface_set_toplevel(Resource *resource) m_xOffset = 0; m_yOffset = 0; + if (m_windowType != QWaylandSurface::Toplevel) { + m_windowType = QWaylandSurface::Toplevel; + emit m_surface->waylandSurface()->windowTypeChanged(m_windowType); + } + if (m_surface->extendedSurface()) m_surface->extendedSurface()->setVisibility(QWindow::Windowed, false); } @@ -229,6 +272,11 @@ void ShellSurface::shell_surface_set_transient(Resource *resource, if (flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE) surface()->setTransientInactive(true); + if (m_windowType != QWaylandSurface::Transient) { + m_windowType = QWaylandSurface::Transient; + emit m_surface->waylandSurface()->windowTypeChanged(m_windowType); + } + if (m_surface->extendedSurface()) m_surface->extendedSurface()->setVisibility(QWindow::AutomaticVisibility, false); } @@ -249,16 +297,24 @@ void ShellSurface::shell_surface_set_fullscreen(Resource *resource, m_surface->extendedSurface()->setVisibility(QWindow::FullScreen, false); } -void ShellSurface::shell_surface_set_popup(Resource *resource, wl_resource *input_device, uint32_t time, wl_resource *parent, int32_t x, int32_t y, uint32_t flags) +void ShellSurface::shell_surface_set_popup(Resource *resource, wl_resource *input_device, uint32_t serial, wl_resource *parent, int32_t x, int32_t y, uint32_t flags) { Q_UNUSED(resource); Q_UNUSED(input_device); - Q_UNUSED(time); - Q_UNUSED(parent); - Q_UNUSED(x); - Q_UNUSED(y); Q_UNUSED(flags); + InputDevice *input = InputDevice::fromSeatResource(input_device); + m_popupGrabber = m_shell->getPopupGrabber(input); + + m_popupSerial = serial; + m_transientParent = Surface::fromResource(parent)->shellSurface(); + m_popupLocation = QPointF(x, y); + + if (m_windowType != QWaylandSurface::Popup) { + m_windowType = QWaylandSurface::Popup; + emit m_surface->waylandSurface()->windowTypeChanged(m_windowType); + } + if (m_surface->extendedSurface()) m_surface->extendedSurface()->setVisibility(QWindow::AutomaticVisibility, false); } @@ -279,7 +335,10 @@ void ShellSurface::shell_surface_pong(Resource *resource, uint32_t serial) { Q_UNUSED(resource); - Q_UNUSED(serial); + if (m_pings.remove(serial)) + emit m_surface->waylandSurface()->pong(); + else + qWarning("Received an unexpected pong!"); } void ShellSurface::shell_surface_set_title(Resource *resource, @@ -381,6 +440,87 @@ void ShellSurfaceMoveGrabber::button(uint32_t time, Qt::MouseButton button, uint } } +ShellSurfacePopupGrabber::ShellSurfacePopupGrabber(InputDevice *inputDevice) + : PointerGrabber() + , m_inputDevice(inputDevice) + , m_client(0) + , m_surfaces() + , m_initialUp(false) +{ +} + +uint32_t ShellSurfacePopupGrabber::grabSerial() const +{ + return m_inputDevice->pointerDevice()->grabSerial(); +} + +struct ::wl_client *ShellSurfacePopupGrabber::client() const +{ + return m_client; +} + +void ShellSurfacePopupGrabber::setClient(struct ::wl_client *client) +{ + m_client = client; +} + +void ShellSurfacePopupGrabber::addPopup(ShellSurface *surface) +{ + if (m_surfaces.isEmpty()) { + m_client = surface->resource()->client(); + + if (m_inputDevice->pointerDevice()->buttonPressed()) + m_initialUp = false; + + m_surfaces.append(surface); + m_inputDevice->pointerDevice()->startGrab(this); + } else { + m_surfaces.append(surface); + } +} + +void ShellSurfacePopupGrabber::removePopup(ShellSurface *surface) +{ + if (m_surfaces.isEmpty()) + return; + + m_surfaces.removeOne(surface); + if (m_surfaces.isEmpty()) + m_inputDevice->pointerDevice()->endGrab(); +} + +void ShellSurfacePopupGrabber::focus() +{ + if (m_pointer->current() && m_pointer->current()->resource()->client() == m_client) + m_pointer->setFocus(m_pointer->current(), m_pointer->currentPosition()); + else + m_pointer->setFocus(0, QPointF()); +} + +void ShellSurfacePopupGrabber::motion(uint32_t time) +{ + m_pointer->motion(time); +} + +void ShellSurfacePopupGrabber::button(uint32_t time, Qt::MouseButton button, uint32_t state) +{ + if (m_pointer->focusResource()) { + m_pointer->sendButton(time, button, state); + } else if (state == QtWaylandServer::wl_pointer::button_state_pressed && + (m_initialUp || time - m_pointer->grabTime() > 500) && + m_pointer->currentGrab() == this) { + m_pointer->endGrab(); + Q_FOREACH (ShellSurface *surface, m_surfaces) { + surface->send_popup_done(); + } + m_surfaces.clear(); + } + + if (state == QtWaylandServer::wl_pointer::button_state_released) + m_initialUp = true; +} + + } QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlshellsurface_p.h b/src/compositor/wayland_wrapper/qwlshellsurface_p.h index 91fb17c2..18ecdabb 100644 --- a/src/compositor/wayland_wrapper/qwlshellsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlshellsurface_p.h @@ -41,11 +41,16 @@ #ifndef WLSHELLSURFACE_H #define WLSHELLSURFACE_H +#include <QtCompositor/qwaylandexport.h> +#include <QtCompositor/qwaylandsurface.h> + #include <wayland-server.h> +#include <QHash> #include <QPoint> +#include <QSet> #include <private/qwlpointer_p.h> -#include <qwayland-server-wayland.h> +#include <QtCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE @@ -56,6 +61,7 @@ class Surface; class ShellSurface; class ShellSurfaceResizeGrabber; class ShellSurfaceMoveGrabber; +class ShellSurfacePopupGrabber; class Shell { @@ -64,6 +70,8 @@ public: static void bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id); + + ShellSurfacePopupGrabber* getPopupGrabber(InputDevice *input); private: static void get_shell_surface(struct wl_client *client, struct wl_resource *resource, @@ -71,13 +79,15 @@ private: struct wl_resource *surface); static const struct wl_shell_interface shell_interface; + QHash<InputDevice*, ShellSurfacePopupGrabber*> m_popupGrabber; }; -class ShellSurface : public QtWaylandServer::wl_shell_surface +class Q_COMPOSITOR_EXPORT ShellSurface : public QtWaylandServer::wl_shell_surface { public: - ShellSurface(struct wl_client *client, uint32_t id, Surface *surface); + ShellSurface(Shell *shell, struct wl_client *client, uint32_t id, Surface *surface); void sendConfigure(uint32_t edges, int32_t width, int32_t height); + void ping(); Surface *surface() const; @@ -89,17 +99,30 @@ public: ShellSurface *transientParent() const; void setOffset(const QPointF &offset); + QWaylandSurface::WindowType windowType() const; + + void mapPopup(); + private: + Shell *m_shell; Surface *m_surface; ShellSurfaceResizeGrabber *m_resizeGrabber; ShellSurfaceMoveGrabber *m_moveGrabber; + ShellSurfacePopupGrabber *m_popupGrabber; ShellSurface *m_transientParent; int32_t m_xOffset; int32_t m_yOffset; + QWaylandSurface::WindowType m_windowType; + + QPointF m_popupLocation; + uint32_t m_popupSerial; + + QSet<uint32_t> m_pings; + void shell_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; void shell_surface_move(Resource *resource, @@ -173,6 +196,30 @@ private: QPointF m_offset; }; +class ShellSurfacePopupGrabber : public PointerGrabber +{ +public: + ShellSurfacePopupGrabber(InputDevice *inputDevice); + + uint32_t grabSerial() const; + + struct ::wl_client *client() const; + void setClient(struct ::wl_client *client); + + void addPopup(ShellSurface *surface); + void removePopup(ShellSurface *surface); + + void focus() Q_DECL_OVERRIDE; + void motion(uint32_t time) Q_DECL_OVERRIDE; + void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; + +private: + InputDevice *m_inputDevice; + struct ::wl_client *m_client; + QList<ShellSurface *> m_surfaces; + bool m_initialUp; +}; + } QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlsubsurface_p.h b/src/compositor/wayland_wrapper/qwlsubsurface_p.h index 6f6ad120..938c2be3 100644 --- a/src/compositor/wayland_wrapper/qwlsubsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlsubsurface_p.h @@ -43,7 +43,7 @@ #include <private/qwlsurface_p.h> -#include "wayland-sub-surface-extension-server-protocol.h" +#include <QtCompositor/private/wayland-sub-surface-extension-server-protocol.h> #include <QtCore/QLinkedList> diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp index f3a9aa4d..2b410948 100644 --- a/src/compositor/wayland_wrapper/qwlsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlsurface.cpp @@ -59,7 +59,7 @@ #include <wayland-server.h> #ifdef QT_COMPOSITOR_WAYLAND_GL -#include "hardware_integration/qwaylandgraphicshardwareintegration.h" +#include "hardware_integration/qwaylandclientbufferintegration.h" #include <qpa/qplatformopenglcontext.h> #endif @@ -83,6 +83,7 @@ Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor) , m_extendedSurface(0) , m_subSurface(0) , m_shellSurface(0) + , m_inputPanelSurface(0) , m_transientInactive(false) , m_isCursorSurface(false) { @@ -125,14 +126,14 @@ bool Surface::isYInverted() const { bool ret = false; static bool negateReturn = qgetenv("QT_COMPOSITOR_NEGATE_INVERTED_Y").toInt(); - QWaylandGraphicsHardwareIntegration *graphicsHWIntegration = m_compositor->graphicsHWIntegration(); + QWaylandClientBufferIntegration *clientBufferIntegration = m_compositor->clientBufferIntegration(); #ifdef QT_COMPOSITOR_WAYLAND_GL SurfaceBuffer *surfacebuffer = currentSurfaceBuffer(); if (!surfacebuffer) { ret = false; - } else if (graphicsHWIntegration && surfacebuffer->waylandBufferHandle() && type() != QWaylandSurface::Shm) { - ret = graphicsHWIntegration->isYInverted(surfacebuffer->waylandBufferHandle()); + } else if (clientBufferIntegration && surfacebuffer->waylandBufferHandle() && type() != QWaylandSurface::Shm) { + ret = clientBufferIntegration->isYInverted(surfacebuffer->waylandBufferHandle()); } else #endif ret = true; @@ -203,14 +204,13 @@ QImage Surface::image() const } #ifdef QT_COMPOSITOR_WAYLAND_GL -GLuint Surface::textureId(QOpenGLContext *context) const +GLuint Surface::textureId() const { const SurfaceBuffer *surfacebuffer = currentSurfaceBuffer(); - if (m_compositor->graphicsHWIntegration() && type() == QWaylandSurface::Texture + if (m_compositor->clientBufferIntegration() && type() == QWaylandSurface::Texture && !surfacebuffer->textureCreated()) { - QWaylandGraphicsHardwareIntegration *hwIntegration = m_compositor->graphicsHWIntegration(); - const_cast<SurfaceBuffer *>(surfacebuffer)->createTexture(hwIntegration,context); + const_cast<SurfaceBuffer *>(surfacebuffer)->createTexture(); } return surfacebuffer->texture(); } @@ -228,7 +228,7 @@ void Surface::sendFrameCallback() bool updateNeeded = advanceBufferQueue(); - uint time = Compositor::currentTimeMsecs(); + uint time = m_compositor->currentTimeMsecs(); struct wl_resource *frame_callback, *next; wl_list_for_each_safe(frame_callback, next, &m_frame_callback_list, link) { wl_callback_send_done(frame_callback, time); @@ -287,6 +287,16 @@ ShellSurface *Surface::shellSurface() const return m_shellSurface; } +void Surface::setInputPanelSurface(InputPanelSurface *inputPanelSurface) +{ + m_inputPanelSurface = inputPanelSurface; +} + +InputPanelSurface *Surface::inputPanelSurface() const +{ + return m_inputPanelSurface; +} + Compositor *Surface::compositor() const { return m_compositor; @@ -298,8 +308,13 @@ bool Surface::advanceBufferQueue() //do we have another buffer in the queue //and does it have a valid damage rect - if (m_backBuffer && !m_backBuffer->isDisplayed()) - return true; + if (m_backBuffer && !m_backBuffer->isDisplayed()) { + if (m_backBuffer->waylandBufferHandle()) { + return true; + } else { + m_backBuffer->disown(); + } + } if (m_bufferQueue.size()) { QSize size; if (m_backBuffer && m_backBuffer->waylandBufferHandle()) { diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h index a4817d7b..ea213435 100644 --- a/src/compositor/wayland_wrapper/qwlsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlsurface_p.h @@ -53,13 +53,12 @@ #include <QtCore/QMetaType> #ifdef QT_COMPOSITOR_WAYLAND_GL -#include <QtGui/QOpenGLContext> #include <QtGui/qopengl.h> #endif #include <wayland-util.h> -#include "qwayland-server-wayland.h" +#include <QtCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE @@ -70,6 +69,7 @@ namespace QtWayland { class Compositor; class Buffer; class ExtendedSurface; +class InputPanelSurface; class SubSurface; class ShellSurface; @@ -101,7 +101,7 @@ public: QImage image() const; #ifdef QT_COMPOSITOR_WAYLAND_GL - GLuint textureId(QOpenGLContext *context) const; + GLuint textureId() const; #endif void sendFrameCallback(); @@ -121,6 +121,9 @@ public: void setShellSurface(ShellSurface *shellSurface); ShellSurface *shellSurface() const; + void setInputPanelSurface(InputPanelSurface *inputPanelSurface); + InputPanelSurface *inputPanelSurface() const; + Compositor *compositor() const; QString className() const { return m_className; } @@ -154,6 +157,7 @@ private: ExtendedSurface *m_extendedSurface; SubSurface *m_subSurface; ShellSurface *m_shellSurface; + InputPanelSurface *m_inputPanelSurface; QRegion m_inputRegion; QRegion m_opaqueRegion; diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp index 9fafc39c..90570031 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp @@ -44,7 +44,7 @@ #include "qwlcompositor_p.h" #ifdef QT_COMPOSITOR_WAYLAND_GL -#include "hardware_integration/qwaylandgraphicshardwareintegration.h" +#include "hardware_integration/qwaylandclientbufferintegration.h" #include <qpa/qplatformopenglcontext.h> #endif @@ -110,18 +110,19 @@ void SurfaceBuffer::destructBufferState() destroyTexture(); if (m_buffer) { + sendRelease(); + if (m_handle) { if (m_shmBuffer) { delete static_cast<QImage *>(m_handle); #ifdef QT_COMPOSITOR_WAYLAND_GL } else { - QWaylandGraphicsHardwareIntegration *hwIntegration = m_compositor->graphicsHWIntegration(); + QWaylandClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); hwIntegration->unlockNativeBuffer(m_handle, m_compositor->directRenderContext()); #endif } } wl_list_remove(&m_destroy_listener.listener.link); - sendRelease(); } m_buffer = 0; m_handle = 0; @@ -138,7 +139,7 @@ QSize SurfaceBuffer::size() const m_size = QSize(wl_shm_buffer_get_width(m_shmBuffer), wl_shm_buffer_get_height(m_shmBuffer)); #ifdef QT_COMPOSITOR_WAYLAND_GL } else { - QWaylandGraphicsHardwareIntegration *hwIntegration = m_compositor->graphicsHWIntegration(); + QWaylandClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); m_size = hwIntegration->bufferSize(m_buffer); #endif } @@ -217,12 +218,16 @@ void SurfaceBuffer::destroyTexture() { #ifdef QT_COMPOSITOR_WAYLAND_GL if (m_texture) { - Q_ASSERT(m_guard); /* When QOpenGLSharedResourceGuard is freed, destroyTexture might be reentered - to cause double free. So clear m_texture first. */ + to cause double free. So clear m_texture first. */ m_texture = 0; - m_guard->free(); - m_guard = 0; + if (m_guard) { + m_guard->free(); + m_guard = 0; + } else { + QWaylandClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); + hwIntegration->destroyTextureForBuffer(m_buffer); + } } #endif } @@ -253,8 +258,8 @@ void *SurfaceBuffer::handle() const that->m_handle = image; #ifdef QT_COMPOSITOR_WAYLAND_GL } else { - QWaylandGraphicsHardwareIntegration *hwIntegration = m_compositor->graphicsHWIntegration(); - that->m_handle = hwIntegration->lockNativeBuffer(m_buffer, m_compositor->directRenderContext()); + QWaylandClientBufferIntegration *clientBufferIntegration = m_compositor->clientBufferIntegration(); + that->m_handle = clientBufferIntegration->lockNativeBuffer(m_buffer, m_compositor->directRenderContext()); #endif } } @@ -295,11 +300,18 @@ void freeTexture(QOpenGLFunctions *, GLuint id) glDeleteTextures(1, &id); } -void SurfaceBuffer::createTexture(QWaylandGraphicsHardwareIntegration *hwIntegration, QOpenGLContext *context) +void SurfaceBuffer::createTexture() { + QWaylandClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); #ifdef QT_COMPOSITOR_WAYLAND_GL - m_texture = hwIntegration->createTextureFromBuffer(m_buffer, context); - m_guard = new QOpenGLSharedResourceGuard(QOpenGLContext::currentContext(), m_texture, freeTexture); + if (!m_texture) + m_texture = hwIntegration->textureForBuffer(m_buffer); + if (!m_texture) { + glGenTextures(1, &m_texture); + m_guard = new QOpenGLSharedResourceGuard(QOpenGLContext::currentContext(), m_texture, freeTexture); + } + glBindTexture(GL_TEXTURE_2D, m_texture); + hwIntegration->bindTextureToBuffer(m_buffer); #else Q_UNUSED(hwIntegration); Q_UNUSED(context); diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h index 93627f67..42c26e7d 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h @@ -51,8 +51,7 @@ QT_BEGIN_NAMESPACE -class QWaylandGraphicsHardwareIntegration; -class QOpenGLContext; +class QWaylandClientBufferIntegration; namespace QtWayland { @@ -99,7 +98,7 @@ public: inline bool textureCreated() const { return m_texture; } - void createTexture(QWaylandGraphicsHardwareIntegration *hwIntegration, QOpenGLContext *context); + void createTexture(); inline GLuint texture() const; void destroyTexture(); diff --git a/src/compositor/wayland_wrapper/qwltextinput.cpp b/src/compositor/wayland_wrapper/qwltextinput.cpp new file mode 100644 index 00000000..35bce832 --- /dev/null +++ b/src/compositor/wayland_wrapper/qwltextinput.cpp @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwltextinput_p.h" + +#include "qwlcompositor_p.h" +#include "qwlinputdevice_p.h" +#include "qwlinputmethod_p.h" +#include "qwlinputmethodcontext_p.h" +#include "qwlinputpanel_p.h" +#include "qwlsurface_p.h" + +#include <algorithm> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +TextInput::TextInput(Compositor *compositor, struct ::wl_client *client, int id) + : wl_text_input(client, id) + , m_compositor(compositor) + , m_focus() + , m_inputPanelVisible() + , m_cursorRectangle() +{ +} + +Surface *TextInput::focus() const +{ + return m_focus; +} + +bool TextInput::inputPanelVisible() const +{ + return m_inputPanelVisible; +} + +QRect TextInput::cursorRectangle() const +{ + return m_cursorRectangle; +} + +void TextInput::deactivate(InputMethod *inputMethod) +{ + if (m_activeInputMethods.removeOne(inputMethod)) + inputMethod->deactivate(); + + if (m_activeInputMethods.isEmpty()) + send_leave(); +} + +void TextInput::text_input_destroy_resource(Resource *) +{ + Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { + deactivate(inputMethod); + } + + delete this; +} + +void TextInput::text_input_activate(Resource *, wl_resource *seat, wl_resource *surface) +{ + Surface *oldSurface = m_focus; + m_focus = Surface::fromResource(surface); + + if (oldSurface != m_focus) + send_leave(); + + bool wasEmpty = m_activeInputMethods.isEmpty(); + + InputMethod *inputMethod = InputDevice::fromSeatResource(seat)->inputMethod(); + + if (!m_activeInputMethods.contains(inputMethod)) { + m_activeInputMethods.append(inputMethod); + inputMethod->activate(this); + } + + if (wasEmpty || oldSurface != m_focus) + send_enter(surface); +} + +void TextInput::text_input_deactivate(Resource *, wl_resource *seat) +{ + InputMethod *inputMethod = InputDevice::fromSeatResource(seat)->inputMethod(); + + deactivate(inputMethod); +} + +static bool isInputMethodBound(InputMethod *inputMethod) +{ + return inputMethod->isBound(); +} + +void TextInput::text_input_show_input_panel(Resource *) +{ + m_inputPanelVisible = true; + + if (std::find_if(m_activeInputMethods.cbegin(), m_activeInputMethods.cend(), isInputMethodBound) != m_activeInputMethods.cend()) + m_compositor->inputPanel()->setInputPanelVisible(true); +} + +void TextInput::text_input_hide_input_panel(Resource *) +{ + m_inputPanelVisible = false; + + if (std::find_if(m_activeInputMethods.cbegin(), m_activeInputMethods.cend(), isInputMethodBound) != m_activeInputMethods.cend()) + m_compositor->inputPanel()->setInputPanelVisible(false); +} + +void TextInput::text_input_set_cursor_rectangle(Resource *, int32_t x, int32_t y, int32_t width, int32_t height) +{ + m_cursorRectangle = QRect(x, y, width, height); + + if (!m_activeInputMethods.isEmpty()) + m_compositor->inputPanel()->setCursorRectangle(m_cursorRectangle); +} + +void TextInput::text_input_reset(Resource *) +{ + Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { + if (inputMethod->context()) + inputMethod->context()->send_reset(); + } +} + +void TextInput::text_input_commit_state(Resource *, uint32_t serial) +{ + Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { + if (inputMethod->context()) + inputMethod->context()->send_commit_state(serial); + } +} + +void TextInput::text_input_set_content_type(Resource *, uint32_t hint, uint32_t purpose) +{ + Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { + if (inputMethod->context()) + inputMethod->context()->send_content_type(hint, purpose); + } +} + +void TextInput::text_input_set_preferred_language(Resource *, const QString &language) +{ + Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { + if (inputMethod->context()) + inputMethod->context()->send_preferred_language(language); + } +} + +void TextInput::text_input_set_surrounding_text(Resource *, const QString &text, uint32_t cursor, uint32_t anchor) +{ + Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { + if (inputMethod->context()) + inputMethod->context()->send_surrounding_text(text, cursor, anchor); + } +} + +void TextInput::text_input_invoke_action(Resource *, uint32_t button, uint32_t index) +{ + Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { + if (inputMethod->context()) + inputMethod->context()->send_invoke_action(button, index); + } +} + +} // namespace QtWayland + +QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwltextinput_p.h b/src/compositor/wayland_wrapper/qwltextinput_p.h new file mode 100644 index 00000000..7bfe6b88 --- /dev/null +++ b/src/compositor/wayland_wrapper/qwltextinput_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTWAYLAND_QWLTEXTINPUT_P_H +#define QTWAYLAND_QWLTEXTINPUT_P_H + +#include <QtCompositor/private/qwayland-server-text.h> + +#include <QRect> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class Compositor; +class InputMethod; +class Surface; + +class TextInput : public QtWaylandServer::wl_text_input +{ +public: + explicit TextInput(Compositor *compositor, struct ::wl_client *client, int id); + + Surface *focus() const; + + bool inputPanelVisible() const; + QRect cursorRectangle() const; + + void deactivate(InputMethod *inputMethod); + +protected: + void text_input_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + + void text_input_activate(Resource *resource, wl_resource *seat, wl_resource *surface) Q_DECL_OVERRIDE; + void text_input_deactivate(Resource *resource, wl_resource *seat) Q_DECL_OVERRIDE; + void text_input_show_input_panel(Resource *resource) Q_DECL_OVERRIDE; + void text_input_hide_input_panel(Resource *resource) Q_DECL_OVERRIDE; + void text_input_reset(Resource *resource) Q_DECL_OVERRIDE; + void text_input_commit_state(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; + void text_input_set_content_type(Resource *resource, uint32_t hint, uint32_t purpose) Q_DECL_OVERRIDE; + void text_input_set_cursor_rectangle(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) Q_DECL_OVERRIDE; + void text_input_set_preferred_language(Resource *resource, const QString &language) Q_DECL_OVERRIDE; + void text_input_set_surrounding_text(Resource *resource, const QString &text, uint32_t cursor, uint32_t anchor) Q_DECL_OVERRIDE; + void text_input_invoke_action(Resource *resource, uint32_t button, uint32_t index) Q_DECL_OVERRIDE; + +private: + Compositor *m_compositor; + QList<InputMethod*> m_activeInputMethods; + Surface *m_focus; + + bool m_inputPanelVisible; + QRect m_cursorRectangle; + +}; + +} // namespace QtWayland + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLTEXTINPUT_P_H diff --git a/src/compositor/wayland_wrapper/qwltextinputmanager.cpp b/src/compositor/wayland_wrapper/qwltextinputmanager.cpp new file mode 100644 index 00000000..87b6e54e --- /dev/null +++ b/src/compositor/wayland_wrapper/qwltextinputmanager.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwltextinputmanager_p.h" + +#include "qwlcompositor_p.h" +#include "qwltextinput_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +TextInputManager::TextInputManager(Compositor *compositor) + : QtWaylandServer::wl_text_input_manager(compositor->wl_display()) + , m_compositor(compositor) +{ +} + +TextInputManager::~TextInputManager() +{ +} + +void TextInputManager::text_input_manager_create_text_input(Resource *resource, uint32_t id) +{ + new TextInput(m_compositor, resource->client(), id); +} + +} // namespace QtWayland + +QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwltextinputmanager_p.h b/src/compositor/wayland_wrapper/qwltextinputmanager_p.h new file mode 100644 index 00000000..2d9be14d --- /dev/null +++ b/src/compositor/wayland_wrapper/qwltextinputmanager_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTWAYLAND_QWLTEXTINPUTMANAGER_P_H +#define QTWAYLAND_QWLTEXTINPUTMANAGER_P_H + +#include <QtCompositor/private/qwayland-server-text.h> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class Compositor; + +class TextInputManager : public QtWaylandServer::wl_text_input_manager +{ +public: + TextInputManager(Compositor *compositor); + ~TextInputManager(); + +protected: + void text_input_manager_create_text_input(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + +private: + Compositor *m_compositor; +}; + +} // namespace QtWayland + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLTEXTINPUTMANAGER_P_H diff --git a/src/compositor/wayland_wrapper/qwltouch.cpp b/src/compositor/wayland_wrapper/qwltouch.cpp index e595440d..2a4070e5 100644 --- a/src/compositor/wayland_wrapper/qwltouch.cpp +++ b/src/compositor/wayland_wrapper/qwltouch.cpp @@ -51,7 +51,9 @@ Touch::Touch(Compositor *compositor) , m_compositor(compositor) , m_focus() , m_focusResource() + , m_grab(this) { + m_grab->setTouch(this); } void Touch::setFocus(Surface *surface) @@ -60,6 +62,17 @@ void Touch::setFocus(Surface *surface) m_focusResource = surface ? resourceMap().value(surface->resource()->client()) : 0; } +void Touch::startGrab(TouchGrabber *grab) +{ + m_grab = grab; + grab->setTouch(this); +} + +void Touch::endGrab() +{ + m_grab = this; +} + void Touch::sendCancel() { if (m_focusResource) @@ -74,32 +87,71 @@ void Touch::sendFrame() void Touch::sendDown(int touch_id, const QPointF &position) { + m_grab->down(m_compositor->currentTimeMsecs(), touch_id, position); +} + +void Touch::sendMotion(int touch_id, const QPointF &position) +{ + m_grab->motion(m_compositor->currentTimeMsecs(), touch_id, position); +} + +void Touch::sendUp(int touch_id) +{ + m_grab->up(m_compositor->currentTimeMsecs(), touch_id); +} + +void Touch::down(uint32_t time, int touch_id, const QPointF &position) +{ if (!m_focusResource || !m_focus) return; uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - send_down(m_focusResource->handle, serial, Compositor::currentTimeMsecs(), m_focus->resource()->handle, touch_id, + send_down(m_focusResource->handle, serial, time, m_focus->resource()->handle, touch_id, wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); } -void Touch::sendMotion(int touch_id, const QPointF &position) +void Touch::up(uint32_t time, int touch_id) { if (!m_focusResource) return; - send_motion(m_focusResource->handle, Compositor::currentTimeMsecs(), touch_id, - wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); + uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + + send_up(m_focusResource->handle, serial, time, touch_id); } -void Touch::sendUp(int touch_id) +void Touch::motion(uint32_t time, int touch_id, const QPointF &position) { if (!m_focusResource) return; - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + send_motion(m_focusResource->handle, time, touch_id, + wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); +} - send_up(m_focusResource->handle, serial, Compositor::currentTimeMsecs(), touch_id); +TouchGrabber::TouchGrabber() + : m_touch(0) +{ +} + +TouchGrabber::~TouchGrabber() +{ +} + +const Touch *TouchGrabber::touch() const +{ + return m_touch; +} + +Touch *TouchGrabber::touch() +{ + return m_touch; +} + +void TouchGrabber::setTouch(Touch *touch) +{ + m_touch = touch; } } // namespace QtWayland diff --git a/src/compositor/wayland_wrapper/qwltouch_p.h b/src/compositor/wayland_wrapper/qwltouch_p.h index 6b597e29..69560980 100644 --- a/src/compositor/wayland_wrapper/qwltouch_p.h +++ b/src/compositor/wayland_wrapper/qwltouch_p.h @@ -42,9 +42,11 @@ #ifndef QTWAYLAND_QWLTOUCH_P_H #define QTWAYLAND_QWLTOUCH_P_H +#include <QtCompositor/qwaylandexport.h> + #include <QtCore/QPoint> -#include <qwayland-server-wayland.h> +#include <QtCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE @@ -52,14 +54,35 @@ namespace QtWayland { class Compositor; class Surface; +class Touch; + +class Q_COMPOSITOR_EXPORT TouchGrabber { +public: + TouchGrabber(); + virtual ~TouchGrabber(); -class Touch : public QtWaylandServer::wl_touch + virtual void down(uint32_t time, int touch_id, const QPointF &position) = 0; + virtual void up(uint32_t time, int touch_id) = 0; + virtual void motion(uint32_t time, int touch_id, const QPointF &position) = 0; + + const Touch *touch() const; + Touch *touch(); + void setTouch(Touch *touch); + +private: + Touch *m_touch; +}; + +class Q_COMPOSITOR_EXPORT Touch : public QtWaylandServer::wl_touch, public TouchGrabber { public: explicit Touch(Compositor *compositor); void setFocus(Surface *surface); + void startGrab(TouchGrabber *grab); + void endGrab(); + void sendCancel(); void sendFrame(); @@ -67,11 +90,17 @@ public: void sendMotion(int touch_id, const QPointF &position); void sendUp(int touch_id); + void down(uint32_t time, int touch_id, const QPointF &position); + void up(uint32_t time, int touch_id); + void motion(uint32_t time, int touch_id, const QPointF &position); + private: Compositor *m_compositor; Surface *m_focus; Resource *m_focusResource; + + TouchGrabber *m_grab; }; } // namespace QtWayland diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri index 663638ec..3b695532 100644 --- a/src/compositor/wayland_wrapper/wayland_wrapper.pri +++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri @@ -1,3 +1,4 @@ +CONFIG += wayland-scanner WAYLANDSERVERSOURCES += \ ../extensions/surface-extension.xml \ ../extensions/sub-surface-extension.xml \ @@ -5,7 +6,9 @@ WAYLANDSERVERSOURCES += \ ../extensions/touch-extension.xml \ ../extensions/qtkey-extension.xml \ ../extensions/windowmanager.xml \ - ../3rdparty/protocol/wayland.xml + ../3rdparty/protocol/wayland.xml \ + ../3rdparty/protocol/input-method.xml \ + ../3rdparty/protocol/text.xml HEADERS += \ wayland_wrapper/qwlcompositor_p.h \ @@ -17,6 +20,10 @@ HEADERS += \ wayland_wrapper/qwlextendedoutput_p.h \ wayland_wrapper/qwlextendedsurface_p.h \ wayland_wrapper/qwlinputdevice_p.h \ + wayland_wrapper/qwlinputmethod_p.h \ + wayland_wrapper/qwlinputmethodcontext_p.h \ + wayland_wrapper/qwlinputpanel_p.h \ + wayland_wrapper/qwlinputpanelsurface_p.h \ wayland_wrapper/qwlkeyboard_p.h \ wayland_wrapper/qwloutput_p.h \ wayland_wrapper/qwlpointer_p.h \ @@ -27,7 +34,9 @@ HEADERS += \ wayland_wrapper/qwlsubsurface_p.h \ wayland_wrapper/qwlsurface_p.h \ wayland_wrapper/qwlsurfacebuffer_p.h \ - wayland_wrapper/qwltouch_p.h + wayland_wrapper/qwltextinput_p.h \ + wayland_wrapper/qwltextinputmanager_p.h \ + wayland_wrapper/qwltouch_p.h \ SOURCES += \ wayland_wrapper/qwlcompositor.cpp \ @@ -39,6 +48,10 @@ SOURCES += \ wayland_wrapper/qwlextendedoutput.cpp \ wayland_wrapper/qwlextendedsurface.cpp \ wayland_wrapper/qwlinputdevice.cpp \ + wayland_wrapper/qwlinputmethod.cpp \ + wayland_wrapper/qwlinputmethodcontext.cpp \ + wayland_wrapper/qwlinputpanel.cpp \ + wayland_wrapper/qwlinputpanelsurface.cpp \ wayland_wrapper/qwlkeyboard.cpp \ wayland_wrapper/qwloutput.cpp \ wayland_wrapper/qwlpointer.cpp \ @@ -49,15 +62,17 @@ SOURCES += \ wayland_wrapper/qwlsubsurface.cpp \ wayland_wrapper/qwlsurface.cpp \ wayland_wrapper/qwlsurfacebuffer.cpp \ - wayland_wrapper/qwltouch.cpp + wayland_wrapper/qwltextinput.cpp \ + wayland_wrapper/qwltextinputmanager.cpp \ + wayland_wrapper/qwltouch.cpp \ INCLUDEPATH += wayland_wrapper config_xkbcommon { !contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += xkbcommon + PKGCONFIG_PRIVATE += xkbcommon } else { - LIBS += -lxkbcommon + LIBS_PRIVATE += -lxkbcommon } } else { DEFINES += QT_NO_WAYLAND_XKB diff --git a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h index ccf5d4e8..4b2a753e 100644 --- a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h +++ b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h @@ -42,7 +42,7 @@ #define WAYLANDWINDOWMANAGERINTEGRATION_H #include <QtCompositor/qwaylandexport.h> -#include "qwayland-server-windowmanager.h" +#include <QtCompositor/private/qwayland-server-windowmanager.h> #include <QObject> #include <QMap> diff --git a/src/extensions/drm-egl-server-buffer.xml b/src/extensions/drm-egl-server-buffer.xml new file mode 100644 index 00000000..597552ee --- /dev/null +++ b/src/extensions/drm-egl-server-buffer.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="drm_egl_server_buffer"> + <copyright> + Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). + Contact: http://www.qt-project.org/legal + + This file is part of the plugins of the Qt Toolkit. + + $QT_BEGIN_LICENSE:BSD$ + You may use this file under the terms of the BSD license as follows: + + "Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + + $QT_END_LICENSE$ + </copyright> + <interface name="qt_drm_egl_server_buffer" version="1"> + <!-- We depend on wayland-egl to authenticate for us --> + <enum name="format"> + <entry name="RGBA32" value="0"/> + <entry name="A8" value="1"/> + </enum> + <event name="server_buffer_created"> + <arg name="id" type="new_id" interface="qt_server_buffer"/> + <arg name="name" type="int"/> + <arg name="width" type="int"/> + <arg name="height" type="int"/> + <arg name="stride" type="int"/> + <arg name="format" type="int"/> + </event> + </interface> +</protocol> + diff --git a/src/extensions/hardware-integration.xml b/src/extensions/hardware-integration.xml new file mode 100644 index 00000000..ad505c9d --- /dev/null +++ b/src/extensions/hardware-integration.xml @@ -0,0 +1,54 @@ +<protocol name="hardware_integration"> + + <copyright> + Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). + Contact: http://www.qt-project.org/legal + + This file is part of the plugins of the Qt Toolkit. + + $QT_BEGIN_LICENSE:BSD$ + You may use this file under the terms of the BSD license as follows: + + "Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + + $QT_END_LICENSE$ + </copyright> + + <interface name="qt_hardware_integration" version="1"> + <description summary="compostors communicates supported buffer sharing extensions"> + Using this protocol the compositor can signal to clients which buffer sharing extensions + the client should use + </description> + <event name="client_backend"> + <arg name="name" type="string"/> + </event> + <event name="server_backend"> + <arg name="name" type="string"/> + </event> + </interface> +</protocol> + diff --git a/src/extensions/qtkey-extension.xml b/src/extensions/qtkey-extension.xml index 1d0db59d..711a2c28 100644 --- a/src/extensions/qtkey-extension.xml +++ b/src/extensions/qtkey-extension.xml @@ -38,12 +38,13 @@ $QT_END_LICENSE$ </copyright> - <interface name="qt_key_extension" version="1"> + <interface name="qt_key_extension" version="2"> <event name="qtkey"> <description summary="qtkey event"> Serialized QKeyEvent </description> + <arg name="surface" type="object" interface="wl_surface"/> <arg name="time" type="uint"/> <arg name="type" type="uint"/> <arg name="key" type="uint"/> diff --git a/src/extensions/server-buffer-extension.xml b/src/extensions/server-buffer-extension.xml new file mode 100644 index 00000000..370a8013 --- /dev/null +++ b/src/extensions/server-buffer-extension.xml @@ -0,0 +1,53 @@ +<protocol name="server_buffer_extension"> + + <copyright> + Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). + Contact: http://www.qt-project.org/legal + + This file is part of the plugins of the Qt Toolkit. + + $QT_BEGIN_LICENSE:BSD$ + You may use this file under the terms of the BSD license as follows: + + "Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + + $QT_END_LICENSE$ + </copyright> + + <interface name="qt_server_buffer" version="1"> + <description summary="buffers managed by the compositor"> + Server buffer is an extension which makes it possible to share a + buffer created by the compositor to share it with arbitrary + clients. These types of buffers are intended to be read only + buffers for clients, but this is an implementation detail. + + Server buffers main purpose is to help implement caches + </description> + <request name="release"> + </request> + </interface> +</protocol> diff --git a/src/extensions/surface-extension.xml b/src/extensions/surface-extension.xml index a2c9688c..31f28620 100644 --- a/src/extensions/surface-extension.xml +++ b/src/extensions/surface-extension.xml @@ -78,6 +78,7 @@ <enum name="windowflag"> <entry name="OverridesSystemGestures" value="1"/> <entry name="StaysOnTop" value="2"/> + <entry name="BypassWindowManager" value="4"/> </enum> <request name="set_window_flags"> diff --git a/src/hardwareintegration/client/brcm-egl/brcm-egl.pri b/src/hardwareintegration/client/brcm-egl/brcm-egl.pri new file mode 100644 index 00000000..542c1c71 --- /dev/null +++ b/src/hardwareintegration/client/brcm-egl/brcm-egl.pri @@ -0,0 +1,13 @@ +INCLUDEPATH += $$PWD +LIBS += -lEGL + +SOURCES += $$PWD/qwaylandbrcmeglintegration.cpp \ + $$PWD/qwaylandbrcmglcontext.cpp \ + $$PWD/qwaylandbrcmeglwindow.cpp + +HEADERS += $$PWD/qwaylandbrcmeglintegration.h \ + $$PWD/qwaylandbrcmglcontext.h \ + $$PWD/qwaylandbrcmeglwindow.h + +CONFIG += wayland-scanner +WAYLANDCLIENTSOURCES += ../../../extensions/brcm.xml diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglintegration.cpp index f82ad6f9..197f4d2c 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglintegration.cpp @@ -124,9 +124,4 @@ EGLDisplay QWaylandBrcmEglIntegration::eglDisplay() const return m_eglDisplay; } -QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) -{ - return new QWaylandBrcmEglIntegration(waylandDisplay); -} - QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglintegration.h index f1100d8d..f1100d8d 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglintegration.h diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp index 31db4328..5c67ba8e 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.cpp +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp @@ -53,6 +53,7 @@ #define EGL_EGLEXT_PROTOTYPES #include <EGL/eglext_brcm.h> +#include <wayland-client.h> #include "wayland-brcm-client-protocol.h" QT_BEGIN_NAMESPACE @@ -64,10 +65,12 @@ public: struct qt_brcm *brcm, const QSize &size, EGLint *data, - int count) + int count, + struct wl_event_queue *eventQueue) : m_size(size) , m_released(true) , m_display(display) + , m_eventQueue(eventQueue) { wl_array_init(&m_array); m_data = static_cast<EGLint *>(wl_array_add(&m_array, count * sizeof(EGLint))); @@ -76,6 +79,7 @@ public: m_data[i] = data[i]; mBuffer = qt_brcm_create_buffer(brcm, size.width(), size.height(), &m_array); + wl_proxy_set_queue(reinterpret_cast<struct wl_proxy*>(mBuffer), m_eventQueue); static const struct wl_buffer_listener buffer_listener = { QWaylandBrcmBuffer::buffer_release @@ -100,35 +104,27 @@ public: { if (m_released) return; - m_mutex.lock(); - while (!m_released) - m_condition.wait(&m_mutex); - m_mutex.unlock(); + while (!m_released) { + wl_display_dispatch_queue(m_display->wl_display(), m_eventQueue); + } } static void buffer_release(void *data, wl_buffer *buffer) { Q_UNUSED(buffer); - m_mutex.lock(); static_cast<QWaylandBrcmBuffer *>(data)->m_released = true; - m_condition.wakeAll(); - m_mutex.unlock(); } private: - static QWaitCondition m_condition; - static QMutex m_mutex; QSize m_size; bool m_released; wl_array m_array; EGLint *m_data; QWaylandDisplay *m_display; + struct wl_event_queue *m_eventQueue; }; -QWaitCondition QWaylandBrcmBuffer::m_condition; -QMutex QWaylandBrcmBuffer::m_mutex; - QWaylandBrcmEglWindow::QWaylandBrcmEglWindow(QWindow *window) : QWaylandWindow(window) , m_eglIntegration(static_cast<QWaylandBrcmEglIntegration *>(mDisplay->eglIntegration())) @@ -136,6 +132,7 @@ QWaylandBrcmEglWindow::QWaylandBrcmEglWindow(QWindow *window) , m_format(window->format()) , m_current(0) , m_count(0) + , m_eventQueue(wl_display_create_queue(mDisplay->wl_display())) { } @@ -238,7 +235,7 @@ void QWaylandBrcmEglWindow::createEglSurfaces() m_eglSurfaces[i] = eglCreatePixmapSurface(m_eglIntegration->eglDisplay(), m_eglConfig, (EGLNativePixmapType)&m_globalImages[5*i], attrs); if (m_eglSurfaces[i] == EGL_NO_SURFACE) qFatal("eglCreatePixmapSurface failed: %x, global image id: %d %d\n", eglGetError(), m_globalImages[5*i], m_globalImages[5*i+1]); - m_buffers[i] = new QWaylandBrcmBuffer(mDisplay, m_eglIntegration->waylandBrcm(), size, &m_globalImages[5*i], 5); + m_buffers[i] = new QWaylandBrcmBuffer(mDisplay, m_eglIntegration->waylandBrcm(), size, &m_globalImages[5*i], 5, m_eventQueue); } } @@ -277,6 +274,7 @@ void QWaylandBrcmEglWindow::flushBuffers() QWaylandBrcmBuffer *buffer = m_pending.takeFirst(); attach(buffer, 0, 0); damage(QRect(QPoint(), size)); + commit(); } m_mutex.unlock(); diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.h index 02abd244..5a3fa046 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglwindow.h +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.h @@ -88,6 +88,8 @@ private: QWaylandBrcmBuffer *m_buffers[3]; QSurfaceFormat m_format; + struct wl_event_queue *m_eventQueue; + int m_current; int m_count; diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmglcontext.cpp index dfb86e54..dfb86e54 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.cpp +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmglcontext.cpp diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.h b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmglcontext.h index 7beef166..7beef166 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmglcontext.h +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmglcontext.h diff --git a/src/hardwareintegration/client/drm-egl-server/drm-egl-server.pri b/src/hardwareintegration/client/drm-egl-server/drm-egl-server.pri new file mode 100644 index 00000000..dbc8dacf --- /dev/null +++ b/src/hardwareintegration/client/drm-egl-server/drm-egl-server.pri @@ -0,0 +1,17 @@ +INCLUDEPATH += $$PWD + +contains(QT_CONFIG, no-pkg-config) { + LIBS += -lEGL -lwayland-client +} else { + CONFIG += link_pkgconfig + PKGCONFIG += egl wayland-client +} + +SOURCES += \ + $$PWD/drmeglserverbufferintegration.cpp + +HEADERS += \ + $$PWD/drmeglserverbufferintegration.h + +CONFIG += wayland-scanner +WAYLANDCLIENTSOURCES += $$PWD/../../../extensions/drm-egl-server-buffer.xml diff --git a/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.cpp b/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.cpp new file mode 100644 index 00000000..beb9106b --- /dev/null +++ b/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "drmeglserverbufferintegration.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> +#include <QDebug> +#include <QtGui/QOpenGLContext> + +#include <EGL/egl.h> + +QT_BEGIN_NAMESPACE + +DrmServerBuffer::DrmServerBuffer(DrmEglServerBufferIntegration *integration + , int32_t name + , int32_t width + , int32_t height + , int32_t stride + , int32_t format) + : QWaylandServerBuffer() + , m_integration(integration) +{ + m_size = QSize(width, height); + EGLint egl_format; + int32_t format_stride; + switch (format) { + case QtWayland::qt_drm_egl_server_buffer::format_RGBA32: + m_format = QWaylandServerBuffer::RGBA32; + egl_format = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA; + format_stride = stride / 4; + break; +#ifdef EGL_DRM_BUFFER_FORMAT_A8_MESA + case QtWayland::qt_drm_egl_server_buffer::format_A8: + m_format = QWaylandServerBuffer::A8; + egl_format = EGL_DRM_BUFFER_FORMAT_A8_MESA; + format_stride = stride; + break; +#endif + default: + qWarning("DrmServerBuffer: unknown format"); + m_format = QWaylandServerBuffer::RGBA32; + egl_format = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA; + format_stride = stride / 4; + break; + } + EGLint attribs[] = { + EGL_WIDTH, width, + EGL_HEIGHT, height, + EGL_DRM_BUFFER_STRIDE_MESA, format_stride, + EGL_DRM_BUFFER_FORMAT_MESA, egl_format, + EGL_NONE + }; + + qintptr name_pointer = name; + m_image = integration->eglCreateImageKHR(EGL_NO_CONTEXT, EGL_DRM_BUFFER_MESA, (EGLClientBuffer) name_pointer, attribs); + +} + +DrmServerBuffer::~DrmServerBuffer() +{ + m_integration->eglDestroyImageKHR(m_image); +} + +void DrmServerBuffer::bindTextureToBuffer() +{ + if (!QOpenGLContext::currentContext()) + qWarning("DrmServerBuffer: creating texture with no current context"); + + m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + +void DrmEglServerBufferIntegration::initialize(QWaylandDisplay *display) +{ + m_egl_display = eglGetDisplay((EGLNativeDisplayType) display->wl_display()); + if (EGL_NO_DISPLAY) { + qWarning("Failed to initialize drm egl server buffer integration. Could not get egl display from wl_display."); + return; + } + + const char *extensionString = eglQueryString(m_egl_display, EGL_EXTENSIONS); + if (!extensionString || !strstr(extensionString, "EGL_KHR_image")) { + qWarning("Failed to initialize drm egl server buffer integration. There is no EGL_KHR_image extension.\n"); + return; + } + m_egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); + m_egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); + if (!m_egl_create_image || !m_egl_destroy_image) { + qWarning("Failed to initialize drm egl server buffer integration. Could not resolve eglCreateImageKHR or eglDestroyImageKHR"); + return; + } + + m_gl_egl_image_target_texture = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES")); + if (!m_gl_egl_image_target_texture) { + qWarning("Failed to initialize drm egl server buffer integration. Could not resolve glEGLImageTargetTexture2DOES"); + return; + } + + QtWayland::wl_registry::init(wl_display_get_registry(display->wl_display())); +} + +QWaylandServerBuffer *DrmEglServerBufferIntegration::serverBuffer(struct qt_server_buffer *buffer) +{ + return static_cast<QWaylandServerBuffer *>(qt_server_buffer_get_user_data(buffer)); +} + +void DrmEglServerBufferIntegration::registry_global(uint32_t name, const QString &interface, uint32_t version) +{ + Q_UNUSED(version); + if (interface == QStringLiteral("qt_drm_egl_server_buffer")) { + struct ::wl_registry *registry = QtWayland::wl_registry::object(); + QtWayland::qt_drm_egl_server_buffer::init(registry, name); + } +} + +void DrmEglServerBufferIntegration::drm_egl_server_buffer_server_buffer_created(struct ::qt_server_buffer *id + , int32_t name + , int32_t width + , int32_t height + , int32_t stride + , int32_t format) +{ + DrmServerBuffer *server_buffer = new DrmServerBuffer(this, name, width, height, stride, format); + qt_server_buffer_set_user_data(id, server_buffer); +} + +QT_END_NAMESPACE diff --git a/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.h b/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.h new file mode 100644 index 00000000..f74b8aca --- /dev/null +++ b/src/hardwareintegration/client/drm-egl-server/drmeglserverbufferintegration.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DRMEGLSERVERBUFFERINTEGRATION_H +#define DRMEGLSERVERBUFFERINTEGRATION_H + +#include <QtWaylandClient/private/qwayland-wayland.h> +#include "qwayland-drm-egl-server-buffer.h" +#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> + +#include "drmeglserverbufferintegration.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> +#include <QtCore/QTextStream> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#ifndef EGL_KHR_image +typedef void *EGLImageKHR; +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); +#endif + +#ifndef GL_OES_EGL_image +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +#endif + +QT_BEGIN_NAMESPACE + +class DrmEglServerBufferIntegration; + +class DrmServerBuffer : public QWaylandServerBuffer +{ +public: + DrmServerBuffer(DrmEglServerBufferIntegration *integration, int32_t name, int32_t width, int32_t height, int32_t stride, int32_t format); + ~DrmServerBuffer(); + void bindTextureToBuffer() Q_DECL_OVERRIDE; +private: + DrmEglServerBufferIntegration *m_integration; + EGLImageKHR m_image; +}; + +class DrmEglServerBufferIntegration + : public QWaylandServerBufferIntegration + , public QtWayland::wl_registry + , public QtWayland::qt_drm_egl_server_buffer +{ +public: + void initialize(QWaylandDisplay *display) Q_DECL_OVERRIDE; + + virtual QWaylandServerBuffer *serverBuffer(struct qt_server_buffer *buffer) Q_DECL_OVERRIDE; + + inline EGLImageKHR eglCreateImageKHR(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); + inline EGLBoolean eglDestroyImageKHR (EGLImageKHR image); + inline void glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +protected: + void registry_global(uint32_t name, const QString &interface, uint32_t version) Q_DECL_OVERRIDE; + void drm_egl_server_buffer_server_buffer_created(struct ::qt_server_buffer *id, int32_t name, int32_t width, int32_t height, int32_t stride, int32_t format) Q_DECL_OVERRIDE; +private: + PFNEGLCREATEIMAGEKHRPROC m_egl_create_image; + PFNEGLDESTROYIMAGEKHRPROC m_egl_destroy_image; + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC m_gl_egl_image_target_texture; + EGLDisplay m_egl_display; +}; + +EGLImageKHR DrmEglServerBufferIntegration::eglCreateImageKHR(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) +{ + if (!m_egl_create_image) { + qWarning("DrmEglServerBufferIntegration: Trying to used unresolved function eglCreateImageKHR"); + return EGL_NO_IMAGE_KHR; + } + return m_egl_create_image(m_egl_display, ctx, target, buffer,attrib_list); +} + +EGLBoolean DrmEglServerBufferIntegration::eglDestroyImageKHR (EGLImageKHR image) +{ + if (!m_egl_destroy_image) { + qWarning("DrmEglServerBufferIntegration: Trying to use unresolved function eglDestroyImageKHR"); + return false; + } + return m_egl_destroy_image(m_egl_display, image); +} + +void DrmEglServerBufferIntegration::glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) +{ + if (!m_gl_egl_image_target_texture) { + qWarning("DrmEglServerBufferIntegration: Trying to use unresolved function glEGLImageTargetRenderbufferStorageOES"); + return; + } + m_gl_egl_image_target_texture(target,image); +} +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp index 07f6d586..68d38c49 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp @@ -39,9 +39,7 @@ ** ****************************************************************************/ -#include "qwaylandeglintegration.h" - -#include "qwaylandglintegration.h" +#include "qwaylandeglclientbufferintegration.h" #include "qwaylandeglwindow.h" #include "qwaylandglcontext.h" @@ -52,25 +50,33 @@ QT_BEGIN_NAMESPACE -QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay) - : m_waylandDisplay(waylandDisplay) +static const char *qwaylandegl_threadedgl_blacklist_vendor[] = { + "Mesa Project", + 0 +}; + +QWaylandEglClientBufferIntegration::QWaylandEglClientBufferIntegration() + : m_waylandDisplay(0) + , m_supportsThreading(false) { qDebug() << "Using Wayland-EGL"; } -QWaylandEglIntegration::~QWaylandEglIntegration() +QWaylandEglClientBufferIntegration::~QWaylandEglClientBufferIntegration() { eglTerminate(m_eglDisplay); } -void QWaylandEglIntegration::initialize() +void QWaylandEglClientBufferIntegration::initialize(QWaylandDisplay *display) { QByteArray eglPlatform = qgetenv("EGL_PLATFORM"); if (eglPlatform.isEmpty()) { setenv("EGL_PLATFORM","wayland",true); } + m_waylandDisplay = display->wl_display(); + EGLint major,minor; m_eglDisplay = eglGetDisplay((EGLNativeDisplayType) m_waylandDisplay); if (m_eglDisplay == NULL) { @@ -81,31 +87,38 @@ void QWaylandEglIntegration::initialize() return; } } + + m_supportsThreading = true; + if (qEnvironmentVariableIsSet("QT_OPENGL_NO_SANITY_CHECK")) + return; + + const char *vendor = eglQueryString(m_eglDisplay, EGL_VENDOR); + for (int i = 0; qwaylandegl_threadedgl_blacklist_vendor[i]; ++i) { + if (strstr(vendor, qwaylandegl_threadedgl_blacklist_vendor[i]) != 0) { + m_supportsThreading = false; + break; + } + } } -bool QWaylandEglIntegration::supportsThreadedOpenGL() const +bool QWaylandEglClientBufferIntegration::supportsThreadedOpenGL() const { - return true; + return m_supportsThreading; } -QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWindow *window) +QWaylandWindow *QWaylandEglClientBufferIntegration::createEglWindow(QWindow *window) { return new QWaylandEglWindow(window); } -QPlatformOpenGLContext *QWaylandEglIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +QPlatformOpenGLContext *QWaylandEglClientBufferIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const { return new QWaylandGLContext(m_eglDisplay, glFormat, share); } -EGLDisplay QWaylandEglIntegration::eglDisplay() const +EGLDisplay QWaylandEglClientBufferIntegration::eglDisplay() const { return m_eglDisplay; } -QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) -{ - return new QWaylandEglIntegration(waylandDisplay->wl_display()); -} - QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h index 64e7d97d..0c7d76cb 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglintegration.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h @@ -42,7 +42,7 @@ #ifndef QWAYLANDEGLINTEGRATION_H #define QWAYLANDEGLINTEGRATION_H -#include "qwaylandglintegration.h" +#include <QtWaylandClient/private/qwaylandclientbufferintegration_p.h> #include "qwaylandeglinclude.h" @@ -51,17 +51,17 @@ QT_BEGIN_NAMESPACE class QWaylandWindow; class QWindow; -class QWaylandEglIntegration : public QWaylandGLIntegration +class QWaylandEglClientBufferIntegration : public QWaylandClientBufferIntegration { public: - QWaylandEglIntegration(struct wl_display *waylandDisplay); - ~QWaylandEglIntegration(); + QWaylandEglClientBufferIntegration(); + ~QWaylandEglClientBufferIntegration(); - void initialize(); - bool supportsThreadedOpenGL() const; + void initialize(QWaylandDisplay *display) Q_DECL_OVERRIDE; + bool supportsThreadedOpenGL() const Q_DECL_OVERRIDE; - QWaylandWindow *createEglWindow(QWindow *window); - QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + QWaylandWindow *createEglWindow(QWindow *window) Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const Q_DECL_OVERRIDE; EGLDisplay eglDisplay() const; @@ -69,6 +69,7 @@ private: struct wl_display *m_waylandDisplay; EGLDisplay m_eglDisplay; + bool m_supportsThreading; }; QT_END_NAMESPACE diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandegldisplay.h b/src/hardwareintegration/client/wayland-egl/qwaylandegldisplay.h new file mode 100644 index 00000000..4eadacca --- /dev/null +++ b/src/hardwareintegration/client/wayland-egl/qwaylandegldisplay.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDEGLWINDOW_H +#define QWAYLANDEGLWINDOW_H + +#include <QtWaylandClient/qwaylanddisplay.h> + +#include "qwaylandeglintegration.h" + +QT_BEGIN_NAMESPACE + +class QWaylandEglDisplay : public QWaylandDisplay +{ +public: + + QWaylandEglDisplay() + : QWaylandDisplay() + { } +}; + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglinclude.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h index fb42d43c..9b151a5e 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglinclude.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h @@ -47,10 +47,6 @@ #include <wayland-egl.h> -#define GL_GLEXT_PROTOTYPES -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> - #define EGL_EGLEXT_PROTOTYPES #include <EGL/egl.h> #include <EGL/eglext.h> diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp index 7829f381..1e86bd31 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp @@ -41,7 +41,7 @@ #include "qwaylandeglwindow.h" -#include "qwaylandscreen.h" +#include <QtWaylandClient/private/qwaylandscreen_p.h> #include "qwaylandglcontext.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE QWaylandEglWindow::QWaylandEglWindow(QWindow *window) : QWaylandWindow(window) - , m_eglIntegration(static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration())) + , m_clientBufferIntegration(static_cast<QWaylandEglClientBufferIntegration *>(mDisplay->clientBufferIntegration())) , m_waylandEglWindow(0) , m_eglSurface(0) , m_eglConfig(0) @@ -70,7 +70,7 @@ QWaylandEglWindow::QWaylandEglWindow(QWindow *window) QWaylandEglWindow::~QWaylandEglWindow() { if (m_eglSurface) { - eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface); + eglDestroySurface(m_clientBufferIntegration->eglDisplay(), m_eglSurface); m_eglSurface = 0; } @@ -86,9 +86,11 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const void QWaylandEglWindow::setGeometry(const QRect &rect) { + QWaylandWindow::setGeometry(rect); + createDecoration(); QMargins margins = frameMargins(); - QSize sizeWithMargins = rect.size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); + QSize sizeWithMargins = geometry().size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); if (m_waylandEglWindow) { int current_width, current_height; @@ -102,8 +104,6 @@ void QWaylandEglWindow::setGeometry(const QRect &rect) } else { m_waylandEglWindow = wl_egl_window_create(object(), sizeWithMargins.width(), sizeWithMargins.height()); } - - QWaylandWindow::setGeometry(rect); } QRect QWaylandEglWindow::contentsRect() const @@ -129,11 +129,11 @@ EGLSurface QWaylandEglWindow::eglSurface() const } if (!m_eglSurface) { - m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), window()->format(), true); - const_cast<QWaylandEglWindow *>(this)->m_format = q_glFormatFromConfig(m_eglIntegration->eglDisplay(),m_eglConfig); + m_eglConfig = q_configFromGLFormat(m_clientBufferIntegration->eglDisplay(), window()->format(), true); + const_cast<QWaylandEglWindow *>(this)->m_format = q_glFormatFromConfig(m_clientBufferIntegration->eglDisplay(),m_eglConfig); EGLNativeWindowType window = (EGLNativeWindowType) m_waylandEglWindow; - m_eglSurface = eglCreateWindowSurface(m_eglIntegration->eglDisplay(), m_eglConfig, window, 0); + m_eglSurface = eglCreateWindowSurface(m_clientBufferIntegration->eglDisplay(), m_eglConfig, window, 0); } return m_eglSurface; diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h index f973547a..9f08559d 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h @@ -42,9 +42,9 @@ #ifndef QWAYLANDEGLWINDOW_H #define QWAYLANDEGLWINDOW_H -#include "qwaylandwindow.h" +#include <QtWaylandClient/private/qwaylandwindow_p.h> #include "qwaylandeglinclude.h" -#include "qwaylandeglintegration.h" +#include "qwaylandeglclientbufferintegration.h" QT_BEGIN_NAMESPACE @@ -70,7 +70,7 @@ public: void bindContentFBO(); private: - QWaylandEglIntegration *m_eglIntegration; + QWaylandEglClientBufferIntegration *m_clientBufferIntegration; mutable struct wl_egl_window *m_waylandEglWindow; const QWaylandWindow *m_parentWindow; diff --git a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index 303e59f7..3bc1ff2b 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp @@ -41,10 +41,10 @@ #include "qwaylandglcontext.h" -#include "qwaylanddisplay.h" -#include "qwaylandwindow.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> +#include <QtWaylandClient/private/qwaylandwindow_p.h> +#include <QtWaylandClient/private/qwaylanddecoration_p.h> #include "qwaylandeglwindow.h" -#include "qwaylanddecoration.h" #include <QDebug> #include <QtPlatformSupport/private/qeglconvenience_p.h> @@ -64,10 +64,27 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat , m_format(q_glFormatFromConfig(m_eglDisplay, m_config)) , m_blitProgram(0) , m_textureCache(0) + , mUseNativeDefaultFbo(false) { m_shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT; - eglBindAPI(EGL_OPENGL_ES_API); + switch (m_format.renderableType()) { + case QSurfaceFormat::OpenVG: + eglBindAPI(EGL_OPENVG_API); + break; +#ifdef EGL_VERSION_1_4 +# if !defined(QT_OPENGL_ES_2) + case QSurfaceFormat::DefaultRenderableType: +# endif + case QSurfaceFormat::OpenGL: + eglBindAPI(EGL_OPENGL_API); + break; +#endif + case QSurfaceFormat::OpenGLES: + default: + eglBindAPI(EGL_OPENGL_ES_API); + break; + } QVector<EGLint> eglContextAttrs; eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); @@ -120,6 +137,7 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) if (window->decoration()) { makeCurrent(surface); if (!m_blitProgram) { + initializeOpenGLFunctions(); m_blitProgram = new QOpenGLShaderProgram(); m_blitProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, "attribute vec4 position;\n\ attribute vec4 texCoords;\n\ @@ -146,9 +164,14 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) m_textureCache = new QOpenGLTextureCache(this->context()); } + QRect windowRect = window->window()->frameGeometry(); + glViewport(0, 0, windowRect.width(), windowRect.height()); + glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); + mUseNativeDefaultFbo = true; glBindFramebuffer(GL_FRAMEBUFFER, 0); + mUseNativeDefaultFbo = false; static const GLfloat squareVertices[] = { -1.f, -1.f, @@ -171,13 +194,14 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) 1.0f, 1.0f, }; + m_blitProgram->bind(); + m_blitProgram->setUniformValue("texture", 0); m_blitProgram->enableAttributeArray("position"); m_blitProgram->enableAttributeArray("texCoords"); m_blitProgram->setAttributeArray("texCoords", textureVertices, 2); - m_blitProgram->bind(); glActiveTexture(GL_TEXTURE0); //Draw Decoration @@ -186,8 +210,6 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) m_textureCache->bindTexture(context(), decorationImage); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - QRect windowRect = window->window()->frameGeometry(); - glViewport(0, 0, windowRect.width(), windowRect.height()); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); //Draw Content @@ -210,6 +232,9 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const { + if (mUseNativeDefaultFbo) + return 0; + return static_cast<QWaylandEglWindow *>(surface)->contentFBO(); } diff --git a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h index bc231e82..38548ac8 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h @@ -42,9 +42,10 @@ #ifndef QWAYLANDGLCONTEXT_H #define QWAYLANDGLCONTEXT_H -#include "qwaylanddisplay.h" +#include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <qpa/qplatformopenglcontext.h> +#include <QtGui/QOpenGLFunctions> #include "qwaylandeglinclude.h" @@ -55,7 +56,8 @@ class QWaylandGLWindowSurface; class QOpenGLShaderProgram; class QOpenGLTextureCache; -class QWaylandGLContext : public QPlatformOpenGLContext { +class QWaylandGLContext : public QPlatformOpenGLContext, protected QOpenGLFunctions +{ public: QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share); ~QWaylandGLContext(); @@ -86,6 +88,7 @@ private: QSurfaceFormat m_format; QOpenGLShaderProgram *m_blitProgram; QOpenGLTextureCache *m_textureCache; + bool mUseNativeDefaultFbo; }; QT_END_NAMESPACE diff --git a/src/hardwareintegration/client/wayland-egl/wayland-egl.pri b/src/hardwareintegration/client/wayland-egl/wayland-egl.pri new file mode 100644 index 00000000..bf03a8c7 --- /dev/null +++ b/src/hardwareintegration/client/wayland-egl/wayland-egl.pri @@ -0,0 +1,16 @@ +INCLUDEPATH += $$PWD +!contains(QT_CONFIG, no-pkg-config) { + CONFIG += link_pkgconfig + PKGCONFIG += wayland-egl egl +} else { + LIBS += -lwayland-egl -lEGL +} + +SOURCES += $$PWD/qwaylandeglclientbufferintegration.cpp \ + $$PWD/qwaylandglcontext.cpp \ + $$PWD/qwaylandeglwindow.cpp + +HEADERS += $$PWD/qwaylandeglclientbufferintegration.h \ + $$PWD/qwaylandglcontext.h \ + $$PWD/qwaylandeglwindow.h \ + $$PWD/qwaylandeglinclude.h diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp index cd3a06ff..12ab0a47 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qwaylandxcompositeeglintegration.h" +#include "qwaylandxcompositeeglclientbufferintegration.h" #include "qwaylandxcompositeeglwindow.h" @@ -49,86 +49,82 @@ QT_BEGIN_NAMESPACE -QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) -{ - return new QWaylandXCompositeEGLIntegration(waylandDisplay); -} - -QWaylandXCompositeEGLIntegration::QWaylandXCompositeEGLIntegration(QWaylandDisplay * waylandDisplay) - : QWaylandGLIntegration() - , mWaylandDisplay(waylandDisplay) +QWaylandXCompositeEGLClientBufferIntegration::QWaylandXCompositeEGLClientBufferIntegration() + : QWaylandClientBufferIntegration() + , mWaylandDisplay(0) { qDebug() << "Using XComposite-EGL"; - waylandDisplay->addRegistryListener(&wlDisplayHandleGlobal, this); } -QWaylandXCompositeEGLIntegration::~QWaylandXCompositeEGLIntegration() +QWaylandXCompositeEGLClientBufferIntegration::~QWaylandXCompositeEGLClientBufferIntegration() { XCloseDisplay(mDisplay); } -void QWaylandXCompositeEGLIntegration::initialize() +void QWaylandXCompositeEGLClientBufferIntegration::initialize(QWaylandDisplay *display) { + mWaylandDisplay = display; + mWaylandDisplay->addRegistryListener(&wlDisplayHandleGlobal, this); } -QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWindow *window) +QWaylandWindow * QWaylandXCompositeEGLClientBufferIntegration::createEglWindow(QWindow *window) { return new QWaylandXCompositeEGLWindow(window,this); } -QPlatformOpenGLContext *QWaylandXCompositeEGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +QPlatformOpenGLContext *QWaylandXCompositeEGLClientBufferIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const { return new QWaylandXCompositeEGLContext(glFormat, share, eglDisplay()); } -Display * QWaylandXCompositeEGLIntegration::xDisplay() const +Display * QWaylandXCompositeEGLClientBufferIntegration::xDisplay() const { return mDisplay; } -EGLDisplay QWaylandXCompositeEGLIntegration::eglDisplay() const +EGLDisplay QWaylandXCompositeEGLClientBufferIntegration::eglDisplay() const { return mEglDisplay; } -int QWaylandXCompositeEGLIntegration::screen() const +int QWaylandXCompositeEGLClientBufferIntegration::screen() const { return mScreen; } -Window QWaylandXCompositeEGLIntegration::rootWindow() const +Window QWaylandXCompositeEGLClientBufferIntegration::rootWindow() const { return mRootWindow; } -QWaylandDisplay * QWaylandXCompositeEGLIntegration::waylandDisplay() const +QWaylandDisplay * QWaylandXCompositeEGLClientBufferIntegration::waylandDisplay() const { return mWaylandDisplay; } -qt_xcomposite * QWaylandXCompositeEGLIntegration::waylandXComposite() const +qt_xcomposite * QWaylandXCompositeEGLClientBufferIntegration::waylandXComposite() const { return mWaylandComposite; } -const struct qt_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite_listener = { - QWaylandXCompositeEGLIntegration::rootInformation +const struct qt_xcomposite_listener QWaylandXCompositeEGLClientBufferIntegration::xcomposite_listener = { + QWaylandXCompositeEGLClientBufferIntegration::rootInformation }; -void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) +void QWaylandXCompositeEGLClientBufferIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); if (interface == "qt_xcomposite") { - QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data); + QWaylandXCompositeEGLClientBufferIntegration *integration = static_cast<QWaylandXCompositeEGLClientBufferIntegration *>(data); integration->mWaylandComposite = static_cast<struct qt_xcomposite *>(wl_registry_bind(registry,id,&qt_xcomposite_interface,1)); qt_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); } } -void QWaylandXCompositeEGLIntegration::rootInformation(void *data, qt_xcomposite *xcomposite, const char *display_name, uint32_t root_window) +void QWaylandXCompositeEGLClientBufferIntegration::rootInformation(void *data, qt_xcomposite *xcomposite, const char *display_name, uint32_t root_window) { Q_UNUSED(xcomposite); - QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data); + QWaylandXCompositeEGLClientBufferIntegration *integration = static_cast<QWaylandXCompositeEGLClientBufferIntegration *>(data); integration->mDisplay = XOpenDisplay(display_name); integration->mRootWindow = (Window) root_window; diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.h index ba36fac3..9cf19e1c 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.h @@ -39,11 +39,11 @@ ** ****************************************************************************/ -#ifndef QWAYLANDXCOMPOSITEEGLINTEGRATION_H -#define QWAYLANDXCOMPOSITEEGLINTEGRATION_H +#ifndef QWAYLANDXCOMPOSITEEGLCLIENTBUFFERINTEGRATION_H +#define QWAYLANDXCOMPOSITEEGLCLIENTBUFFERINTEGRATION_H -#include "qwaylandglintegration.h" -#include "wayland-client.h" +#include <QtWaylandClient/private/qwaylandclientbufferintegration_p.h> +#include <wayland-client.h> #include <QtCore/QTextStream> #include <QtCore/QDataStream> @@ -68,17 +68,17 @@ struct qt_xcomposite; QT_BEGIN_NAMESPACE -class QWaylandXCompositeEGLIntegration : public QWaylandGLIntegration +class QWaylandXCompositeEGLClientBufferIntegration : public QWaylandClientBufferIntegration { public: - QWaylandXCompositeEGLIntegration(QWaylandDisplay * waylandDispaly); - ~QWaylandXCompositeEGLIntegration(); + QWaylandXCompositeEGLClientBufferIntegration(); + ~QWaylandXCompositeEGLClientBufferIntegration(); - void initialize(); - bool waitingForEvents() { return !mDisplay; } + void initialize(QWaylandDisplay *dispaly) Q_DECL_OVERRIDE; + bool waitingForEvents() Q_DECL_OVERRIDE { return !mDisplay; } - QWaylandWindow *createEglWindow(QWindow *window); - QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + QWaylandWindow *createEglWindow(QWindow *window) Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const Q_DECL_OVERRIDE; QWaylandDisplay *waylandDisplay() const; struct qt_xcomposite *waylandXComposite() const; @@ -111,4 +111,4 @@ private: QT_END_NAMESPACE -#endif // QWAYLANDXCOMPOSITEEGLINTEGRATION_H +#endif // QWAYLANDXCOMPOSITEEGLCLIENTBUFFERINTEGRATION_H diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp index 1ebcdde1..1ebcdde1 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.h b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.h index 32cdb432..bc988480 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.h +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.h @@ -44,7 +44,7 @@ #include <qpa/qplatformopenglcontext.h> -#include "qwaylandxcompositeeglintegration.h" +#include "qwaylandxcompositeeglclientbufferintegration.h" #include <QtPlatformSupport/private/qeglplatformcontext_p.h> diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp index 4b414451..01d63241 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp @@ -48,13 +48,13 @@ #include "wayland-xcomposite-client-protocol.h" #include <X11/extensions/Xcomposite.h> -#include "qwaylandxcompositeeglintegration.h" +#include "qwaylandxcompositeeglclientbufferintegration.h" #include <QtCore/QDebug> QT_BEGIN_NAMESPACE -QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration) +QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLClientBufferIntegration *glxIntegration) : QWaylandWindow(window) , m_glxIntegration(glxIntegration) , m_context(0) diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.h index a9642c58..b45beaa2 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.h @@ -42,10 +42,10 @@ #ifndef QWAYLANDXCOMPOSITEEGLWINDOW_H #define QWAYLANDXCOMPOSITEEGLWINDOW_H -#include "qwaylandwindow.h" -#include "qwaylandbuffer.h" +#include <QtWaylandClient/private/qwaylandwindow_p.h> +#include <QtWaylandClient/private/qwaylandbuffer_p.h> -#include "qwaylandxcompositeeglintegration.h" +#include "qwaylandxcompositeeglclientbufferintegration.h" #include "qwaylandxcompositeeglcontext.h" QT_BEGIN_NAMESPACE @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE class QWaylandXCompositeEGLWindow : public QWaylandWindow { public: - QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration); + QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLClientBufferIntegration *glxIntegration); WindowType windowType() const; void setGeometry(const QRect &rect); @@ -65,7 +65,7 @@ public: private: void createEglSurface(); - QWaylandXCompositeEGLIntegration *m_glxIntegration; + QWaylandXCompositeEGLClientBufferIntegration *m_glxIntegration; QWaylandXCompositeEGLContext *m_context; QWaylandBuffer *m_buffer; diff --git a/src/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri b/src/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri new file mode 100644 index 00000000..fa08daaf --- /dev/null +++ b/src/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri @@ -0,0 +1,19 @@ +INCLUDEPATH += $$PWD +include($$PWD/../xcomposite_share/xcomposite_share.pri) + +!contains(QT_CONFIG, no-pkg-config) { + CONFIG += link_pkgconfig + PKGCONFIG += xcomposite egl x11 +} else { + LIBS += -lXcomposite -lEGL -lX11 +} + +SOURCES += \ + $$PWD/qwaylandxcompositeeglcontext.cpp \ + $$PWD/qwaylandxcompositeeglclientbufferintegration.cpp \ + $$PWD/qwaylandxcompositeeglwindow.cpp + +HEADERS += \ + $$PWD/qwaylandxcompositeeglcontext.h \ + $$PWD/qwaylandxcompositeeglclientbufferintegration.h \ + $$PWD/qwaylandxcompositeeglwindow.h diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.cpp index 4ee02260..4ee02260 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.cpp diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.h b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.h index de031126..de031126 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.h +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.h diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.cpp index 2e8b444f..62a9b0f3 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.cpp @@ -49,11 +49,6 @@ QT_BEGIN_NAMESPACE -QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) -{ - return new QWaylandXCompositeGLXIntegration(waylandDisplay); -} - QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay *waylandDisplay) : mWaylandDisplay(waylandDisplay) , mWaylandComposite(0) diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.h index 90533db1..8e1d762d 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.h @@ -42,8 +42,8 @@ #ifndef QWAYLANDXCOMPOSITEGLXINTEGRATION_H #define QWAYLANDXCOMPOSITEGLXINTEGRATION_H -#include "qwaylandglintegration.h" -#include "wayland-client.h" +#include <QtWaylandClient/qwaylandglintegration.h> +#include <wayland-client.h> #include <QtCore/QTextStream> #include <QtCore/QDataStream> diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.cpp index f33790f3..f33790f3 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.cpp diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.h b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.h index 88f417f2..88f417f2 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.h +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxwindow.h diff --git a/src/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri b/src/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri new file mode 100644 index 00000000..cc41322b --- /dev/null +++ b/src/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri @@ -0,0 +1,19 @@ +INCLUDEPATH += $$PWD +include ($$PWD/../xcomposite_share/xcomposite_share.pri) + +!contains(QT_CONFIG, no-pkg-config) { + CONFIG += link_pkgconfig + PKGCONFIG += xcomposite gl x11 +} else { + LIBS += -lXcomposite -lGL -lX11 +} + +SOURCES += \ + $$PWD/qwaylandxcompositeglxcontext.cpp \ + $$PWD/qwaylandxcompositeglxintegration.cpp \ + $$PWD/qwaylandxcompositeglxwindow.cpp + +HEADERS += \ + $$PWD/qwaylandxcompositeglxcontext.h \ + $$PWD/qwaylandxcompositeglxintegration.h \ + $$PWD/qwaylandxcompositeglxwindow.h diff --git a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/hardwareintegration/client/xcomposite_share/qwaylandxcompositebuffer.cpp index c65ad4a1..94a9772a 100644 --- a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp +++ b/src/hardwareintegration/client/xcomposite_share/qwaylandxcompositebuffer.cpp @@ -41,7 +41,7 @@ #include "qwaylandxcompositebuffer.h" -#include "wayland-client.h" +#include <wayland-client.h> #include "wayland-xcomposite-client-protocol.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.h b/src/hardwareintegration/client/xcomposite_share/qwaylandxcompositebuffer.h index e7001241..a2f42166 100644 --- a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.h +++ b/src/hardwareintegration/client/xcomposite_share/qwaylandxcompositebuffer.h @@ -42,7 +42,7 @@ #ifndef QWAYLANDXCOMPOSITEBUFFER_H #define QWAYLANDXCOMPOSITEBUFFER_H -#include "qwaylandbuffer.h" +#include <QtWaylandClient/private/qwaylandbuffer_p.h> #include <stdint.h> struct qt_xcomposite; diff --git a/src/plugins/platforms/xcomposite_share/xcomposite_share.pri b/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri index 77d56f4c..be3c9fc1 100644 --- a/src/plugins/platforms/xcomposite_share/xcomposite_share.pri +++ b/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri @@ -1,5 +1,6 @@ INCLUDEPATH += $$PWD +CONFIG += wayland-scanner WAYLANDCLIENTSOURCES += $$PWD/../../../extensions/xcomposite.xml HEADERS += \ diff --git a/src/hardwareintegration/compositor/brcm-egl/brcm-egl.pri b/src/hardwareintegration/compositor/brcm-egl/brcm-egl.pri new file mode 100644 index 00000000..c04b4abc --- /dev/null +++ b/src/hardwareintegration/compositor/brcm-egl/brcm-egl.pri @@ -0,0 +1,19 @@ +PLUGIN_TYPE = waylandcompositors +load(qt_plugin) + +QT = compositor compositor-private core-private gui-private + +INCLUDEPATH = $$PWD +LIBS += -lwayland-server -lEGL + +SOURCES += \ + brcmeglintegration.cpp \ + brcmbuffer.cpp + + +HEADERS += \ + brcmeglintegration.h \ + brcmbuffer.h + +CONFIG += wayland-scanner +WAYLANDSERVERSOURCES += $$PWD/../../../extensions/brcm.xml diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp b/src/hardwareintegration/compositor/brcm-egl/brcmbuffer.cpp index e4fbfb55..e4fbfb55 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.cpp +++ b/src/hardwareintegration/compositor/brcm-egl/brcmbuffer.cpp diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h b/src/hardwareintegration/compositor/brcm-egl/brcmbuffer.h index 6ec5868f..6ec5868f 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmbuffer.h +++ b/src/hardwareintegration/compositor/brcm-egl/brcmbuffer.h diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp index 0ef8318f..a0be625d 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.cpp +++ b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp @@ -76,7 +76,7 @@ public: }; BrcmEglIntegration::BrcmEglIntegration() - : QWaylandGraphicsHardwareIntegration() + : QWaylandClientBufferIntegration() , QtWaylandServer::qt_brcm() , d_ptr(new BrcmEglIntegrationPrivate) { @@ -124,30 +124,25 @@ void BrcmEglIntegration::initializeHardware(QtWayland::Display *waylandDisplay) } } -GLuint BrcmEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) +void BrcmEglIntegration::bindTextureToBuffer(struct ::wl_resource *buffer) { Q_D(BrcmEglIntegration); if (!d->valid) { - qWarning("createTextureFromBuffer() failed\n"); - return 0; + qWarning("bindTextureToBuffer failed!"); + return; } BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(buffer); if (!d->eglQueryGlobalImageBRCM(brcmBuffer->handle(), brcmBuffer->handle() + 2)) { qWarning("eglQueryGlobalImageBRCM failed!"); - return 0; + return; } EGLImageKHR image = d->eglCreateImageKHR(d->egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)brcmBuffer->handle(), NULL); if (image == EGL_NO_IMAGE_KHR) qWarning("eglCreateImageKHR() failed: %x\n", eglGetError()); - GLuint textureId; - glGenTextures(1, &textureId); - - glBindTexture(GL_TEXTURE_2D, textureId); - d->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -156,8 +151,6 @@ GLuint BrcmEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); d->eglDestroyImageKHR(d->egl_display, image); - - return textureId; } bool BrcmEglIntegration::isYInverted(struct ::wl_resource *) const diff --git a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h index 22990561..f6486ed4 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcmeglintegration.h +++ b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h @@ -41,7 +41,7 @@ #ifndef BRCMEGLINTEGRATION_H #define BRCMEGLINTEGRATION_H -#include <QtCompositor/qwaylandgraphicshardwareintegration.h> +#include <QtCompositor/qwaylandclientbufferintegration.h> #include "qwayland-server-brcm.h" #include <QtCore/QScopedPointer> @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE class BrcmEglIntegrationPrivate; -class BrcmEglIntegration : public QWaylandGraphicsHardwareIntegration, public QtWaylandServer::qt_brcm +class BrcmEglIntegration : public QWaylandClientBufferIntegration, public QtWaylandServer::qt_brcm { Q_DECLARE_PRIVATE(BrcmEglIntegration) public: @@ -58,7 +58,7 @@ public: void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + void udpateTextureFromBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; diff --git a/src/hardwareintegration/compositor/drm-egl-server/drm-egl-server.pri b/src/hardwareintegration/compositor/drm-egl-server/drm-egl-server.pri new file mode 100644 index 00000000..cd2e2471 --- /dev/null +++ b/src/hardwareintegration/compositor/drm-egl-server/drm-egl-server.pri @@ -0,0 +1,18 @@ +INCLUDEPATH += $$PWD + +contains(QT_CONFIG, no-pkg-config) { + LIBS += -lwayland-server -lEGL +} else { + CONFIG += link_pkgconfig + PKGCONFIG += wayland-server egl +} + +SOURCES += \ + $$PWD/drmeglserverbufferintegration.cpp + + +HEADERS += \ + $$PWD/drmeglserverbufferintegration.h + +CONFIG += wayland-scanner +WAYLANDSERVERSOURCES += $$PWD/../../../extensions/drm-egl-server-buffer.xml diff --git a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp new file mode 100644 index 00000000..9c7440dc --- /dev/null +++ b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "drmeglserverbufferintegration.h" + +#include <QtGui/QOpenGLContext> + +QT_BEGIN_NAMESPACE + +DrmEglServerBuffer::DrmEglServerBuffer(DrmEglServerBufferIntegration *integration, const QSize &size, QWaylandServerBuffer::Format format) + : QWaylandServerBuffer(size,format) + , m_integration(integration) +{ + m_format = format; + + EGLint egl_format; + switch (m_format) { + case RGBA32: + m_drm_format = QtWaylandServer::qt_drm_egl_server_buffer::format_RGBA32; + egl_format = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA; + break; +#ifdef EGL_DRM_BUFFER_FORMAT_A8_MESA + case A8: + m_drm_format = QtWaylandServer::qt_drm_egl_server_buffer::format_A8; + egl_format = EGL_DRM_BUFFER_FORMAT_A8_MESA; + break; +#endif + default: + qWarning("DrmEglServerBuffer: unsupported format"); + m_drm_format = QtWaylandServer::qt_drm_egl_server_buffer::format_RGBA32; + egl_format = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA; + break; + } + EGLint imageAttribs[] = { + EGL_WIDTH, m_size.width(), + EGL_HEIGHT, m_size.height(), + EGL_DRM_BUFFER_FORMAT_MESA, egl_format, + EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA, + EGL_NONE + }; + + m_image = m_integration->eglCreateDRMImageMESA(imageAttribs); + + EGLint handle; + if (!m_integration->eglExportDRMImageMESA(m_image, &m_name, &handle, &m_stride)) { + qWarning("DrmEglServerBuffer: Failed to export egl image"); + } + +} + +struct ::wl_resource *DrmEglServerBuffer::resourceForClient(struct ::wl_client *client) +{ + QMultiMap<struct ::wl_client *, Resource *>::iterator it = resourceMap().find(client); + if (it == resourceMap().end()) { + QMultiMap<struct ::wl_client *, QtWaylandServer::qt_drm_egl_server_buffer::Resource *>::iterator drm_egl_it = m_integration->resourceMap().find(client); + if (drm_egl_it == m_integration->resourceMap().end()) { + qWarning("DrmEglServerBuffer::resourceForClient: Trying to get resource for ServerBuffer. But client is not bound to the drm_egl interface"); + return 0; + } + struct ::wl_resource *drm_egl_resource = (*drm_egl_it)->handle; + Resource *resource = add(client); + m_integration->send_server_buffer_created(drm_egl_resource, resource->handle, m_name, m_size.width(), m_size.height(), m_stride, m_drm_format); + return resource->handle; + } + return (*it)->handle; +} + +void DrmEglServerBuffer::bindTextureToBuffer() +{ + if (!QOpenGLContext::currentContext()) { + qWarning("DrmEglServerBuffer: No current context when creating buffer. Texture loading will fail"); + return; + } + + m_integration->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + +DrmEglServerBufferIntegration::DrmEglServerBufferIntegration() +{ +} + +DrmEglServerBufferIntegration::~DrmEglServerBufferIntegration() +{ +} + +void DrmEglServerBufferIntegration::initializeHardware(QWaylandCompositor *compositor) +{ + QWindow *window = compositor->window(); + Q_ASSERT(QGuiApplication::platformNativeInterface()); + + m_egl_display = static_cast<EGLDisplay>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("egldisplay", window)); + if (!m_egl_display) { + qWarning("Cant initialize drm egl server buffer integration. Missing egl display from platformplugin"); + return; + } + + const char *extensionString = eglQueryString(m_egl_display, EGL_EXTENSIONS); + if (!extensionString || !strstr(extensionString, "EGL_KHR_image")) { + qWarning("Failed to initialize drm egl server buffer integration. There is no EGL_KHR_image extension.\n"); + return; + } + m_egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); + m_egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); + if (!m_egl_create_image || !m_egl_destroy_image) { + qWarning("Failed to initialize drm egl server buffer integration. Could not resolve eglCreateImageKHR or eglDestroyImageKHR"); + return; + } + + if (!extensionString || !strstr(extensionString, "EGL_MESA_drm_image")) { + qWarning("Failed to initialize drm egl server buffer integration. There is no EGL_MESA_drm_image extension.\n"); + return; + } + + m_egl_create_drm_image = reinterpret_cast<PFNEGLCREATEDRMIMAGEMESAPROC>(eglGetProcAddress("eglCreateDRMImageMESA")); + m_egl_export_drm_image = reinterpret_cast<PFNEGLEXPORTDRMIMAGEMESAPROC>(eglGetProcAddress("eglExportDRMImageMESA")); + if (!m_egl_create_drm_image || !m_egl_export_drm_image) { + qWarning("Failed to initialize drm egl server buffer integration. Could not find eglCreateDRMImageMESA or eglExportDRMImageMESA.\n"); + return; + } + + m_gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES")); + if (!m_gl_egl_image_target_texture_2d) { + qWarning("Failed to initialize drm egl server buffer integration. Could not find glEGLImageTargetTexture2DOES.\n"); + return; + } + + QtWaylandServer::qt_drm_egl_server_buffer::init(compositor->waylandDisplay()); +} + +bool DrmEglServerBufferIntegration::supportsFormat(QWaylandServerBuffer::Format format) const +{ + switch (format) { + case QWaylandServerBuffer::RGBA32: + return true; + case QWaylandServerBuffer::A8: +#ifdef EGL_DRM_BUFFER_FORMAT_A8_MESA + return true; +#else + return false; +#endif + default: + return false; + } +} + +QWaylandServerBuffer *DrmEglServerBufferIntegration::createServerBuffer(const QSize &size, QWaylandServerBuffer::Format format) +{ + return new DrmEglServerBuffer(this, size, format); +} + +QT_END_NAMESPACE diff --git a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.h b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.h new file mode 100644 index 00000000..659b261e --- /dev/null +++ b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.h @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Compositor. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DRMEGLSERVERBUFFERINTEGRATION_H +#define DRMEGLSERVERBUFFERINTEGRATION_H + +#include <QtCompositor/qwaylandserverbufferintegration.h> + +#include "qwayland-server-drm-egl-server-buffer.h" + +#include <QtGui/QWindow> +#include <QtGui/qpa/qplatformnativeinterface.h> +#include <QtGui/QGuiApplication> + +#include <QtCompositor/qwaylandcompositor.h> +#include <QtCompositor/private/qwayland-server-server-buffer-extension.h> + +#include <QtCore/QDebug> +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#ifndef EGL_KHR_image +typedef void *EGLImageKHR; +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); +#endif + +#ifndef GL_OES_EGL_image +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +#endif +#ifndef EGL_MESA_drm_image +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#endif + +QT_BEGIN_NAMESPACE + +class DrmEglServerBufferIntegration; + +class DrmEglServerBuffer : public QWaylandServerBuffer, public QtWaylandServer::qt_server_buffer +{ +public: + DrmEglServerBuffer(DrmEglServerBufferIntegration *integration, const QSize &size, QWaylandServerBuffer::Format format); + + struct ::wl_resource *resourceForClient(struct ::wl_client *) Q_DECL_OVERRIDE; + void bindTextureToBuffer() Q_DECL_OVERRIDE; + +private: + DrmEglServerBufferIntegration *m_integration; + + EGLImageKHR m_image; + + int32_t m_name; + int32_t m_stride; + QtWaylandServer::qt_drm_egl_server_buffer::format m_drm_format; +}; + +class DrmEglServerBufferIntegration : + public QWaylandServerBufferIntegration, + public QtWaylandServer::qt_drm_egl_server_buffer +{ +public: + DrmEglServerBufferIntegration(); + ~DrmEglServerBufferIntegration(); + + void initializeHardware(QWaylandCompositor *); + + bool supportsFormat(QWaylandServerBuffer::Format format) const Q_DECL_OVERRIDE; + QWaylandServerBuffer *createServerBuffer(const QSize &size, QWaylandServerBuffer::Format format) Q_DECL_OVERRIDE; + + EGLDisplay display() const { return m_egl_display; } + + inline EGLImageKHR eglCreateImageKHR(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); + inline EGLBoolean eglDestroyImageKHR (EGLImageKHR image); + inline EGLImageKHR eglCreateDRMImageMESA (const EGLint *attrib_list); + inline EGLBoolean eglExportDRMImageMESA (EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); + inline void glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); + +private: + EGLDisplay m_egl_display; + PFNEGLCREATEDRMIMAGEMESAPROC m_egl_create_drm_image; + PFNEGLEXPORTDRMIMAGEMESAPROC m_egl_export_drm_image; + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC m_gl_egl_image_target_texture_2d; + + PFNEGLCREATEIMAGEKHRPROC m_egl_create_image; + PFNEGLDESTROYIMAGEKHRPROC m_egl_destroy_image; +}; + +EGLImageKHR DrmEglServerBufferIntegration::eglCreateImageKHR(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) +{ + if (!m_egl_create_image) { + qWarning("DrmEglServerBufferIntegration: Trying to used unresolved function eglCreateImageKHR"); + return EGL_NO_IMAGE_KHR; + } + return m_egl_create_image(m_egl_display, ctx, target, buffer,attrib_list); +} + +EGLBoolean DrmEglServerBufferIntegration::eglDestroyImageKHR (EGLImageKHR image) +{ + if (!m_egl_destroy_image) { + qWarning("DrmEglServerBufferIntegration: Trying to use unresolved function eglDestroyImageKHR"); + return false; + } + return m_egl_destroy_image(m_egl_display, image); +} + +EGLImageKHR DrmEglServerBufferIntegration::eglCreateDRMImageMESA (const EGLint *attrib_list) +{ + if (m_egl_create_drm_image) + return m_egl_create_drm_image(m_egl_display, attrib_list); + else + qWarning("DrmEglServerBufferIntegration: Trying to use unresolved function eglCreateDRMImageMESA"); + return EGL_NO_IMAGE_KHR; + +} + +EGLBoolean DrmEglServerBufferIntegration::eglExportDRMImageMESA (EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride) +{ + if (m_egl_export_drm_image) + return m_egl_export_drm_image(m_egl_display, image, name, handle, stride); + else + qWarning("DrmEglServerBufferIntegration: Trying to use unresolved function eglExportDRMImageMESA"); + return 0; +} + +void DrmEglServerBufferIntegration::glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) +{ + if (m_gl_egl_image_target_texture_2d) + return m_gl_egl_image_target_texture_2d(target, image); + else + qWarning("DrmEglServerBufferIntegration: Trying to use unresolved function glEGLImageTargetTexture2DOES"); +} +QT_END_NAMESPACE + +#endif diff --git a/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri b/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri new file mode 100644 index 00000000..2d4771a2 --- /dev/null +++ b/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri @@ -0,0 +1,14 @@ +INCLUDEPATH += $$PWD + +!contains(QT_CONFIG, no-pkg-config) { + CONFIG += link_pkgconfig + PKGCONFIG += wayland-server wayland-egl egl +} else { + LIBS += -lwayland-egl -lwayland-server -lEGL +} + +SOURCES += \ + $$PWD/waylandeglclientbufferintegration.cpp + +HEADERS += \ + $$PWD/waylandeglclientbufferintegration.h diff --git a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp index abf12fad..a127b7bd 100644 --- a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.cpp +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp @@ -38,7 +38,7 @@ ** ****************************************************************************/ -#include "waylandeglintegration.h" +#include "waylandeglclientbufferintegration.h" #include <QtCompositor/private/qwlcompositor_p.h> #include <QtCompositor/private/qwlsurface_p.h> @@ -54,9 +54,6 @@ #include <EGL/egl.h> #include <EGL/eglext.h> -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> - #ifndef EGL_WL_bind_wayland_display typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display); typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display); @@ -75,10 +72,10 @@ typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenu QT_BEGIN_NAMESPACE -class WaylandEglIntegrationPrivate +class WaylandEglClientBufferIntegrationPrivate { public: - WaylandEglIntegrationPrivate() + WaylandEglClientBufferIntegrationPrivate() : egl_display(EGL_NO_DISPLAY) , valid(false) , display_bound(false) @@ -94,9 +91,6 @@ public: bool valid; bool display_bound; bool flipperConnected; -#ifdef EGL_WL_request_client_buffer_format - QPointer<WaylandSurface> directRenderSurface; -#endif PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display; PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display; PFNEGLQUERYWAYLANDBUFFERWL egl_query_wayland_buffer; @@ -107,15 +101,15 @@ public: PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d; }; -WaylandEglIntegration::WaylandEglIntegration() - : QWaylandGraphicsHardwareIntegration() - , d_ptr(new WaylandEglIntegrationPrivate) +WaylandEglClientBufferIntegration::WaylandEglClientBufferIntegration() + : QWaylandClientBufferIntegration() + , d_ptr(new WaylandEglClientBufferIntegrationPrivate) { } -void WaylandEglIntegration::initializeHardware(QtWayland::Display *waylandDisplay) +void WaylandEglClientBufferIntegration::initializeHardware(QtWayland::Display *waylandDisplay) { - Q_D(WaylandEglIntegration); + Q_D(WaylandEglClientBufferIntegration); const bool ignoreBindDisplay = !qgetenv("QT_WAYLAND_IGNORE_BIND_DISPLAY").isEmpty(); @@ -139,7 +133,7 @@ void WaylandEglIntegration::initializeHardware(QtWayland::Display *waylandDispla d->egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL")); d->egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL")); - if (!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display && !ignoreBindDisplay) { + if ((!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display) && !ignoreBindDisplay) { qWarning("Failed to initialize egl display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL.\n"); return; } @@ -165,7 +159,7 @@ void WaylandEglIntegration::initializeHardware(QtWayland::Display *waylandDispla if (d->egl_bind_wayland_display && d->egl_unbind_wayland_display) { d->display_bound = d->egl_bind_wayland_display(d->egl_display, waylandDisplay->handle()); - if (!d->display_bound || ignoreBindDisplay) { + if (!d->display_bound && !ignoreBindDisplay) { qWarning("Failed to initialize egl display. Could not bind Wayland display.\n"); return; } @@ -176,23 +170,18 @@ void WaylandEglIntegration::initializeHardware(QtWayland::Display *waylandDispla qWarning("EGL Wayland extension successfully initialized.%s\n", !d->display_bound ? " eglBindWaylandDisplayWL ignored" : ""); } -GLuint WaylandEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) +void WaylandEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer) { - Q_D(WaylandEglIntegration); + Q_D(WaylandEglClientBufferIntegration); if (!d->valid) { - qWarning("createTextureFromBuffer() failed\n"); - return 0; + qWarning("bindTextureToBuffer() failed"); + return; } EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, buffer, NULL); - GLuint textureId; - glGenTextures(1,&textureId); - - glBindTexture(GL_TEXTURE_2D, textureId); - d->gl_egl_image_target_texture_2d(GL_TEXTURE_2D, image); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -201,23 +190,31 @@ GLuint WaylandEglIntegration::createTextureFromBuffer(struct ::wl_resource *buff glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); d->egl_destroy_image(d->egl_display, image); - - return textureId; } -bool WaylandEglIntegration::isYInverted(struct ::wl_resource *buffer) const +bool WaylandEglClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const { -#ifdef EGL_WL_request_client_buffer_format - return eglGetBufferYInvertedWL(buffer); -#else - return QWaylandGraphicsHardwareIntegration::isYInverted(buffer); +#if defined(EGL_WAYLAND_Y_INVERTED_WL) + Q_D(const WaylandEglClientBufferIntegration); + + EGLint isYInverted; + EGLBoolean ret; + ret = d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WAYLAND_Y_INVERTED_WL, &isYInverted); + + // Yes, this looks strange, but the specification says that EGL_FALSE return + // value (not supported) should be treated the same as EGL_TRUE return value + // and EGL_TRUE in value. + if (ret == EGL_FALSE || isYInverted == EGL_TRUE) + return true; #endif + + return QWaylandClientBufferIntegration::isYInverted(buffer); } -bool WaylandEglIntegration::setDirectRenderSurface(QWaylandSurface *surface) +bool WaylandEglClientBufferIntegration::setDirectRenderSurface(QWaylandSurface *surface) { - Q_D(WaylandEglIntegration); + Q_D(WaylandEglClientBufferIntegration); QPlatformScreen *screen = QPlatformScreen::platformScreenForWindow(m_compositor->window()); QPlatformScreenPageFlipper *flipper = screen ? screen->pageFlipper() : 0; @@ -225,28 +222,13 @@ bool WaylandEglIntegration::setDirectRenderSurface(QWaylandSurface *surface) QObject::connect(flipper, SIGNAL(bufferReleased(QPlatformScreenBuffer*)), m_compositor->handle(), SLOT(releaseBuffer(QPlatformScreenBuffer*))); d->flipperConnected = true; } -#ifdef EGL_WL_request_client_buffer_format - int buffer_format = surface ? EGL_SCANOUT_FORMAT_WL : EGL_RENDER_FORMAT_WL; - struct wl_client *client = 0; - if (surface) { - client = surface->handle()->base()->resource.client; - } else { - WaylandSurface *oldSurface = d->directRenderSurface.data(); - if (oldSurface) - client = oldSurface->handle()->base()->resource.client; - } - if (client) - eglRequestClientBufferFormatWL(d->egl_display, client, buffer_format); - d->directRenderSurface = surface; -#else Q_UNUSED(surface); -#endif return flipper; } -void *WaylandEglIntegration::lockNativeBuffer(struct ::wl_resource *buffer, QOpenGLContext *) const +void *WaylandEglClientBufferIntegration::lockNativeBuffer(struct ::wl_resource *buffer, QOpenGLContext *) const { - Q_D(const WaylandEglIntegration); + Q_D(const WaylandEglClientBufferIntegration); EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, @@ -254,21 +236,21 @@ void *WaylandEglIntegration::lockNativeBuffer(struct ::wl_resource *buffer, QOpe return image; } -void WaylandEglIntegration::unlockNativeBuffer(void *native_buffer, QOpenGLContext *) const +void WaylandEglClientBufferIntegration::unlockNativeBuffer(void *native_buffer, QOpenGLContext *) const { - Q_D(const WaylandEglIntegration); + Q_D(const WaylandEglClientBufferIntegration); EGLImageKHR image = static_cast<EGLImageKHR>(native_buffer); d->egl_destroy_image(d->egl_display, image); } -QSize WaylandEglIntegration::bufferSize(struct ::wl_resource *buffer) const +QSize WaylandEglClientBufferIntegration::bufferSize(struct ::wl_resource *buffer) const { - Q_D(const WaylandEglIntegration); + Q_D(const WaylandEglClientBufferIntegration); int width, height; - d->egl_query_wayland_buffer(d->egl_display, reinterpret_cast<struct ::wl_buffer *>(buffer), EGL_WIDTH, &width); - d->egl_query_wayland_buffer(d->egl_display, reinterpret_cast<struct ::wl_buffer *>(buffer), EGL_HEIGHT, &height); + d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WIDTH, &width); + d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_HEIGHT, &height); return QSize(width, height); } diff --git a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h index ce328429..a289baa0 100644 --- a/src/plugins/waylandcompositors/wayland-egl/waylandeglintegration.h +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h @@ -41,22 +41,22 @@ #ifndef WAYLANDEGLINTEGRATION_H #define WAYLANDEGLINTEGRATION_H -#include <QtCompositor/qwaylandgraphicshardwareintegration.h> +#include <QtCompositor/qwaylandclientbufferintegration.h> #include <QtCore/QScopedPointer> QT_BEGIN_NAMESPACE -class WaylandEglIntegrationPrivate; +class WaylandEglClientBufferIntegrationPrivate; -class WaylandEglIntegration : public QWaylandGraphicsHardwareIntegration +class WaylandEglClientBufferIntegration : public QWaylandClientBufferIntegration { - Q_DECLARE_PRIVATE(WaylandEglIntegration) + Q_DECLARE_PRIVATE(WaylandEglClientBufferIntegration) public: - WaylandEglIntegration(); + WaylandEglClientBufferIntegration(); void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; bool setDirectRenderSurface(QWaylandSurface *) Q_DECL_OVERRIDE; @@ -67,8 +67,8 @@ public: QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; private: - Q_DISABLE_COPY(WaylandEglIntegration) - QScopedPointer<WaylandEglIntegrationPrivate> d_ptr; + Q_DISABLE_COPY(WaylandEglClientBufferIntegration) + QScopedPointer<WaylandEglClientBufferIntegrationPrivate> d_ptr; }; QT_END_NAMESPACE diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcomposite-egl.pri b/src/hardwareintegration/compositor/xcomposite-egl/xcomposite-egl.pri new file mode 100644 index 00000000..cde790bd --- /dev/null +++ b/src/hardwareintegration/compositor/xcomposite-egl/xcomposite-egl.pri @@ -0,0 +1,16 @@ +include($$PWD/../xcomposite_share/xcomposite_share.pri) + +!contains(QT_CONFIG, no-pkg-config) { + CONFIG += link_pkgconfig + PKGCONFIG += xcomposite egl x11 wayland-server +} else { + LIBS += -lXcomposite -lEGL -lX11 +} + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/xcompositeeglintegration.h + +SOURCES += \ + $$PWD/xcompositeeglintegration.cpp diff --git a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp index b80858b2..c645b997 100644 --- a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp +++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp @@ -67,14 +67,14 @@ QVector<EGLint> eglbuildSpec() return spec; } -XCompositeEglIntegration::XCompositeEglIntegration() - : QWaylandGraphicsHardwareIntegration() +XCompositeEglClientBufferIntegration::XCompositeEglClientBufferIntegration() + : QWaylandClientBufferIntegration() , mDisplay(0) { } -void XCompositeEglIntegration::initializeHardware(QtWayland::Display *) +void XCompositeEglClientBufferIntegration::initializeHardware(QtWayland::Display *) { QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); if (nativeInterface) { @@ -91,7 +91,7 @@ void XCompositeEglIntegration::initializeHardware(QtWayland::Display *) new XCompositeHandler(m_compositor->handle(), mDisplay); } -GLuint XCompositeEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) +void XCompositeEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer) { XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); @@ -103,7 +103,7 @@ GLuint XCompositeEglIntegration::createTextureFromBuffer(struct ::wl_resource *b bool matched = eglChooseConfig(mEglDisplay,eglConfigSpec.constData(),&config,1,&matching); if (!matched || !matching) { qWarning("Could not retrieve a suitable EGL config"); - return 0; + return; } QVector<EGLint> attribList; @@ -121,26 +121,20 @@ GLuint XCompositeEglIntegration::createTextureFromBuffer(struct ::wl_resource *b compositorBuffer->setInvertedY(true); - GLuint textureId; - glGenTextures(1,&textureId); - glBindTexture(GL_TEXTURE_2D, textureId); - if (!eglBindTexImage(mEglDisplay,surface,EGL_BACK_BUFFER)) { qDebug() << "Failed to bind"; } // eglDestroySurface(mEglDisplay,surface); - - return textureId; } -bool XCompositeEglIntegration::isYInverted(struct ::wl_resource *buffer) const +bool XCompositeEglClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const { XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); return compositorBuffer->isYInverted(); } -QSize XCompositeEglIntegration::bufferSize(struct ::wl_resource *buffer) const +QSize XCompositeEglClientBufferIntegration::bufferSize(struct ::wl_resource *buffer) const { XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); diff --git a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h index 562fce14..5497daed 100644 --- a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.h +++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h @@ -41,7 +41,7 @@ #ifndef XCOMPOSITEEGLINTEGRATION_H #define XCOMPOSITEEGLINTEGRATION_H -#include <QtCompositor/qwaylandgraphicshardwareintegration.h> +#include <QtCompositor/qwaylandclientbufferintegration.h> #include "xlibinclude.h" @@ -49,14 +49,14 @@ QT_BEGIN_NAMESPACE -class XCompositeEglIntegration : public QWaylandGraphicsHardwareIntegration +class XCompositeEglClientBufferIntegration : public QWaylandClientBufferIntegration { public: - XCompositeEglIntegration(); + XCompositeEglClientBufferIntegration(); void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; diff --git a/src/hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.pri b/src/hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.pri new file mode 100644 index 00000000..ccbbe46a --- /dev/null +++ b/src/hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.pri @@ -0,0 +1,16 @@ +include($$PWD/../xcomposite_share/xcomposite_share.pri) + +!contains(QT_CONFIG, no-pkg-config) { + CONFIG += link_pkgconfig + PKGCONFIG += xcomposite gl x11 wayland-server +} else { + LIBS += -lXcomposite -lGL -lX11 +} + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/xcompositeglxintegration.h + +SOURCES += \ + $$PWD/xcompositeglxintegration.cpp diff --git a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp index 421e5df1..a58827ce 100644 --- a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp +++ b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp @@ -71,19 +71,19 @@ QVector<int> qglx_buildSpec() } -XCompositeGLXIntegration::XCompositeGLXIntegration() - : QWaylandGraphicsHardwareIntegration() +XCompositeGLXClientBufferIntegration::XCompositeGLXClientBufferIntegration() + : QWaylandClientBufferIntegration() , mDisplay(0) , mHandler(0) { } -XCompositeGLXIntegration::~XCompositeGLXIntegration() +XCompositeGLXClientBufferIntegration::~XCompositeGLXClientBufferIntegration() { delete mHandler; } -void XCompositeGLXIntegration::initializeHardware(QtWayland::Display *) +void XCompositeGLXClientBufferIntegration::initializeHardware(QtWayland::Display *) { QPlatformNativeInterface *nativeInterface = QGuiApplicationPrivate::platformIntegration()->nativeInterface(); if (nativeInterface) { @@ -112,7 +112,7 @@ void XCompositeGLXIntegration::initializeHardware(QtWayland::Display *) delete glContext; } -GLuint XCompositeGLXIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) +void XCompositeGLXClientBufferIntegration::updateTextureFromBuffer(struct ::wl_resource *buffer) { XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); @@ -135,22 +135,18 @@ GLuint XCompositeGLXIntegration::createTextureFromBuffer(struct ::wl_resource *b XFree(configs); - GLuint textureId; - glGenTextures(1,&textureId); - glBindTexture(GL_TEXTURE_2D, textureId); m_glxBindTexImageEXT(mDisplay,glxPixmap,GLX_FRONT_EXT, 0); //Do we need to change the api so that we do bind and release in the painevent? //The specification states that when deleting the texture the color buffer is deleted // m_glxReleaseTexImageEXT(mDisplay,glxPixmap,GLX_FRONT_EXT); - return textureId; } -bool XCompositeGLXIntegration::isYInverted(struct ::wl_resource *buffer) const +bool XCompositeGLXClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const { return XCompositeBuffer::fromResource(buffer)->isYInverted(); } -QSize XCompositeGLXIntegration::bufferSize(struct ::wl_resource *buffer) const +QSize XCompositeGLXClientBufferIntegration::bufferSize(struct ::wl_resource *buffer) const { XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); diff --git a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h index 11146ef2..5a724eed 100644 --- a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.h +++ b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h @@ -41,7 +41,7 @@ #ifndef XCOMPOSITEGLXINTEGRATION_H #define XCOMPOSITEGLXINTEGRATION_H -#include <QtCompositor/qwaylandgraphicshardwareintegration.h> +#include <QtCompositor/qwaylandclientbufferintegration.h> #include "xlibinclude.h" @@ -53,15 +53,15 @@ QT_BEGIN_NAMESPACE class XCompositeHandler; -class XCompositeGLXIntegration : public QWaylandGraphicsHardwareIntegration +class XCompositeGLXClientBufferIntegration : public QWaylandClientBufferIntegration { public: - XCompositeGLXIntegration(); - ~XCompositeGLXIntegration(); + XCompositeGLXClientBufferIntegration(); + ~XCompositeGLXClientBufferIntegration(); void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcomposite_share.pri b/src/hardwareintegration/compositor/xcomposite_share/xcomposite_share.pri index 7e0bc457..06937c41 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcomposite_share.pri +++ b/src/hardwareintegration/compositor/xcomposite_share/xcomposite_share.pri @@ -1,5 +1,6 @@ INCLUDEPATH += $$PWD +CONFIG += wayland-scanner WAYLANDSERVERSOURCES += $$PWD/../../../extensions/xcomposite.xml $$PWD/../../../3rdparty/protocol/wayland.xml HEADERS += \ diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp index 0457214b..0457214b 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp +++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.h index 20cf399b..20cf399b 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h +++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.h diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp index 0f10d38d..0f10d38d 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp +++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.h b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.h index 678ad446..678ad446 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.h +++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.h diff --git a/src/plugins/waylandcompositors/xcomposite_share/xlibinclude.h b/src/hardwareintegration/compositor/xcomposite_share/xlibinclude.h index 733fd6fd..733fd6fd 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xlibinclude.h +++ b/src/hardwareintegration/compositor/xcomposite_share/xlibinclude.h diff --git a/src/plugins/waylandcompositors/brcm-egl/brcm-egl.json b/src/plugins/hardwareintegration/client/brcm-egl/brcm-egl.json index 48611c6a..48611c6a 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcm-egl.json +++ b/src/plugins/hardwareintegration/client/brcm-egl/brcm-egl.json diff --git a/src/plugins/hardwareintegration/client/brcm-egl/brcm-egl.pro b/src/plugins/hardwareintegration/client/brcm-egl/brcm-egl.pro new file mode 100644 index 00000000..d98b7941 --- /dev/null +++ b/src/plugins/hardwareintegration/client/brcm-egl/brcm-egl.pro @@ -0,0 +1,14 @@ +PLUGIN_TYPE = wayland-graphics-integration/client +load(qt_plugin) + +QT += waylandclient-private + +include(../../../../hardwareintegration/client/brcm-egl/brcm-egl.pri) + +LIBS += -lEGL + +OTHER_FILES += \ + brcm-egl.json + +SOURCES += main.cpp + diff --git a/src/plugins/hardwareintegration/client/brcm-egl/main.cpp b/src/plugins/hardwareintegration/client/brcm-egl/main.cpp new file mode 100644 index 00000000..b7f37655 --- /dev/null +++ b/src/plugins/hardwareintegration/client/brcm-egl/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWaylandClient/qwaylandclientbufferintegrationplugin.h> +#include "qwaylandbrcmeglclientbufferintegration.h" + +QT_BEGIN_NAMESPACE + +class QWaylandBrcmEglClientBufferPlugin : public QWaylandClientBufferIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.WaylandClient.QWaylandClientBufferIntegrationFactoryInterface.5.1" FILE "brcm-egl.json") +public: + QStringList keys() const; + QWaylandClientBufferIntegration *create(const QString&, const QStringList&); +}; + +QStringList QWaylandBrcmEglClientBufferPlugin::keys() const +{ + QStringList list; + list << "brcm"; + return list; +} + +QWaylandEglClientBufferIntegration *QWaylandBrcmEglClientBufferPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "brcm") + return new QWaylandBrcmEglClientBufferIntegration(); + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/hardwareintegration/client/client.pro b/src/plugins/hardwareintegration/client/client.pro new file mode 100644 index 00000000..1d79b263 --- /dev/null +++ b/src/plugins/hardwareintegration/client/client.pro @@ -0,0 +1,19 @@ +TEMPLATE=subdirs + +config_wayland_egl: \ + SUBDIRS += wayland-egl + +config_brcm_egl: \ + SUBDIRS += brcm-egl + +config_xcomposite { + config_egl: \ + SUBDIRS += xcomposite-egl + + !contains(QT_CONFIG, opengles2):config_glx: \ + SUBDIRS += xcomposite-glx +} + +config_drm_egl_server: \ + SUBDIRS += drm-egl-server + diff --git a/src/plugins/hardwareintegration/client/drm-egl-server/drm-egl-server.json b/src/plugins/hardwareintegration/client/drm-egl-server/drm-egl-server.json new file mode 100644 index 00000000..e2266ec6 --- /dev/null +++ b/src/plugins/hardwareintegration/client/drm-egl-server/drm-egl-server.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "drm-egl-server" ] +} diff --git a/src/plugins/hardwareintegration/client/drm-egl-server/drm-egl-server.pro b/src/plugins/hardwareintegration/client/drm-egl-server/drm-egl-server.pro new file mode 100644 index 00000000..d282afc8 --- /dev/null +++ b/src/plugins/hardwareintegration/client/drm-egl-server/drm-egl-server.pro @@ -0,0 +1,14 @@ +PLUGIN_TYPE = wayland-graphics-integration/client +load(qt_plugin) + +QT += waylandclient-private + +include(../../../../hardwareintegration/client/drm-egl-server/drm-egl-server.pri) + +LIBS += -lEGL + +OTHER_FILES += \ + drm-egl-server.json + +SOURCES += main.cpp + diff --git a/src/plugins/hardwareintegration/client/drm-egl-server/main.cpp b/src/plugins/hardwareintegration/client/drm-egl-server/main.cpp new file mode 100644 index 00000000..460ccb7a --- /dev/null +++ b/src/plugins/hardwareintegration/client/drm-egl-server/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWaylandClient/private/qwaylandserverbufferintegrationplugin_p.h> +#include "drmeglserverbufferintegration.h" + +QT_BEGIN_NAMESPACE + +class DrmEglServerBufferPlugin : public QWaylandServerBufferIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.WaylandClient.QWaylandServerBufferIntegrationFactoryInterface.5.1" FILE "drm-egl-server.json") +public: + QStringList keys() const; + QWaylandServerBufferIntegration *create(const QString&, const QStringList&); +}; + +QStringList DrmEglServerBufferPlugin::keys() const +{ + QStringList list; + list << "drm-egl-server"; + return list; +} + +QWaylandServerBufferIntegration *DrmEglServerBufferPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "drm-egl-server") + return new DrmEglServerBufferIntegration(); + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/hardwareintegration/client/wayland-egl/main.cpp b/src/plugins/hardwareintegration/client/wayland-egl/main.cpp new file mode 100644 index 00000000..44ce6019 --- /dev/null +++ b/src/plugins/hardwareintegration/client/wayland-egl/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWaylandClient/private/qwaylandclientbufferintegrationplugin_p.h> +#include "qwaylandeglclientbufferintegration.h" + +QT_BEGIN_NAMESPACE + +class QWaylandEglClientBufferPlugin : public QWaylandClientBufferIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.WaylandClient.QWaylandClientBufferIntegrationFactoryInterface.5.1" FILE "wayland-egl.json") +public: + QStringList keys() const; + QWaylandClientBufferIntegration *create(const QString&, const QStringList&); +}; + +QStringList QWaylandEglClientBufferPlugin::keys() const +{ + QStringList list; + list << "wayland-egl"; + return list; +} + +QWaylandClientBufferIntegration *QWaylandEglClientBufferPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "wayland-egl") + return new QWaylandEglClientBufferIntegration(); + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/waylandcompositors/wayland-egl/wayland-egl.json b/src/plugins/hardwareintegration/client/wayland-egl/wayland-egl.json index 4ea5bab9..4ea5bab9 100644 --- a/src/plugins/waylandcompositors/wayland-egl/wayland-egl.json +++ b/src/plugins/hardwareintegration/client/wayland-egl/wayland-egl.json diff --git a/src/plugins/hardwareintegration/client/wayland-egl/wayland-egl.pro b/src/plugins/hardwareintegration/client/wayland-egl/wayland-egl.pro new file mode 100644 index 00000000..0eca1d41 --- /dev/null +++ b/src/plugins/hardwareintegration/client/wayland-egl/wayland-egl.pro @@ -0,0 +1,12 @@ +PLUGIN_TYPE = wayland-graphics-integration/client +load(qt_plugin) + +QT += waylandclient-private + +include(../../../../hardwareintegration/client/wayland-egl/wayland-egl.pri) + +OTHER_FILES += \ + wayland-egl.json + +SOURCES += main.cpp + diff --git a/src/plugins/hardwareintegration/client/xcomposite-egl/main.cpp b/src/plugins/hardwareintegration/client/xcomposite-egl/main.cpp new file mode 100644 index 00000000..7c6135cc --- /dev/null +++ b/src/plugins/hardwareintegration/client/xcomposite-egl/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWaylandClient/private/qwaylandclientbufferintegrationplugin_p.h> +#include "qwaylandxcompositeeglclientbufferintegration.h" + +QT_BEGIN_NAMESPACE + +class QWaylandXCompositeEglClientBufferIntegrationPlugin : public QWaylandClientBufferIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.WaylandClient.QWaylandClientBufferIntegrationFactoryInterface.5.1" FILE "xcomposite-egl.json") +public: + QStringList keys() const; + QWaylandClientBufferIntegration *create(const QString&, const QStringList&); +}; + +QStringList QWaylandXCompositeEglClientBufferIntegrationPlugin::keys() const +{ + QStringList list; + list << "xcomposite" << "xcomposite-egl"; + return list; +} + +QWaylandClientBufferIntegration *QWaylandXCompositeEglClientBufferIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "xcomposite" || system.toLower() == "xcomposite-egl") + return new QWaylandXCompositeEGLClientBufferIntegration(); + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/waylandcompositors/xcomposite-egl/xcomposite-egl.json b/src/plugins/hardwareintegration/client/xcomposite-egl/xcomposite-egl.json index 8ccd5b46..8ccd5b46 100644 --- a/src/plugins/waylandcompositors/xcomposite-egl/xcomposite-egl.json +++ b/src/plugins/hardwareintegration/client/xcomposite-egl/xcomposite-egl.json diff --git a/src/plugins/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pro b/src/plugins/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pro new file mode 100644 index 00000000..3129f844 --- /dev/null +++ b/src/plugins/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pro @@ -0,0 +1,12 @@ +PLUGIN_TYPE = wayland-graphics-integration/client +load(qt_plugin) + +QT += waylandclient-private + +include(../../../../hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri) + +OTHER_FILES += xcomposite-egl.json + +SOURCES += \ + main.cpp + diff --git a/src/plugins/hardwareintegration/client/xcomposite-glx/main.cpp b/src/plugins/hardwareintegration/client/xcomposite-glx/main.cpp new file mode 100644 index 00000000..4beb7e6e --- /dev/null +++ b/src/plugins/hardwareintegration/client/xcomposite-glx/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWaylandClient/qwaylandclientbufferintegrationplugin.h> +#include "qwaylandxcompositeglxclientbufferintegration.h" + +QT_BEGIN_NAMESPACE + +class QWaylandXCompositeGlxClientBufferIntegrationPlugin : public QWaylandClientBufferIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.WaylandClient.QWaylandClientBufferIntegrationFactoryInterface.5.1" FILE "xcomposite-glx.json") +public: + QStringList keys() const; + QWaylandClientBufferIntegration *create(const QString&, const QStringList&); +}; + +QStringList QWaylandXCompositeGlxClientBufferIntegrationPlugin::keys() const +{ + QStringList list; + list << "xcomposite-glx"; + return list; +} + +QWaylandClientBufferIntegration *QWaylandXCompositeGlxClientBufferIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "xcomposite-glx") + return new QWaylandXCompositeGLXClientBufferIntegration(); + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/hardwareintegration/client/xcomposite-glx/xcomposite-glx.json b/src/plugins/hardwareintegration/client/xcomposite-glx/xcomposite-glx.json new file mode 100644 index 00000000..0f4a3bf6 --- /dev/null +++ b/src/plugins/hardwareintegration/client/xcomposite-glx/xcomposite-glx.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "wayland-xcomposite-glx" ] +} diff --git a/src/plugins/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pro b/src/plugins/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pro new file mode 100644 index 00000000..3146b369 --- /dev/null +++ b/src/plugins/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pro @@ -0,0 +1,12 @@ +PLUGIN_TYPE = wayland-graphics-integration/client +load(qt_plugin) + +QT += waylandclient-private + +include(../../../../hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri) + +OTHER_FILES += xcomposite-glx.json + +SOURCES += \ + main.cpp + diff --git a/src/plugins/hardwareintegration/compositor/brcm-egl/brcm-egl.json b/src/plugins/hardwareintegration/compositor/brcm-egl/brcm-egl.json new file mode 100644 index 00000000..48611c6a --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/brcm-egl/brcm-egl.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "wayland-brcm" ] +} diff --git a/src/plugins/hardwareintegration/compositor/brcm-egl/brcm-egl.pro b/src/plugins/hardwareintegration/compositor/brcm-egl/brcm-egl.pro new file mode 100644 index 00000000..56dc2740 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/brcm-egl/brcm-egl.pro @@ -0,0 +1,13 @@ +PLUGIN_TYPE = wayland-graphics-integration/server +load(qt_plugin) + +QT = compositor compositor-private core-private gui-private + +OTHER_FILES += brcm-egl.json + +LIBS += -lEGL + +SOURCES += \ + main.cpp + +include($PWD/../../../../hardwareintegration/compositor/brcm-egl/brcm-egl.pri) diff --git a/src/plugins/waylandcompositors/brcm-egl/main.cpp b/src/plugins/hardwareintegration/compositor/brcm-egl/main.cpp index 56fd6da2..bfdfa643 100644 --- a/src/plugins/waylandcompositors/brcm-egl/main.cpp +++ b/src/plugins/hardwareintegration/compositor/brcm-egl/main.cpp @@ -39,28 +39,28 @@ ** ****************************************************************************/ -#include <QtCompositor/qwaylandgraphicshardwareintegrationplugin.h> +#include <QtCompositor/qwaylandclientbufferintegrationplugin.h> #include "brcmeglintegration.h" QT_BEGIN_NAMESPACE -class QWaylandIntegrationPlugin : public QWaylandGraphicsHardwareIntegrationPlugin +class QWaylandBrcmClientBufferIntegration : public QWaylandClientBufferIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Compositor.QWaylandGraphicsHardwareIntegrationFactoryInterface.5.3" FILE "brcm-egl.json") + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Compositor.QWaylandClientBufferIntegrationFactoryInterface.5.3" FILE "brcm-egl.json") public: QStringList keys() const; - QWaylandGraphicsHardwareIntegration *create(const QString&, const QStringList&); + QWaylandClientBufferIntegration *create(const QString&, const QStringList&); }; -QStringList QWaylandIntegrationPlugin::keys() const +QStringList QWaylandBrcmClientBufferIntegration::keys() const { QStringList list; list << "wayland-brcm"; return list; } -QWaylandGraphicsHardwareIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) +QWaylandClientBufferIntegration *QWaylandBrcmClientBufferIntegration::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); if (system.toLower() == "wayland-brcm") diff --git a/src/plugins/hardwareintegration/compositor/compositor.pro b/src/plugins/hardwareintegration/compositor/compositor.pro new file mode 100644 index 00000000..3c1ff5d7 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/compositor.pro @@ -0,0 +1,17 @@ +TEMPLATE = subdirs + +config_wayland_egl: \ + SUBDIRS += wayland-egl +config_brcm_egl: \ + SUBDIRS += brcm-egl + +config_xcomposite { + config_egl: \ + SUBDIRS += xcomposite-egl + + !contains(QT_CONFIG, opengles2):config_glx: \ + SUBDIRS += xcomposite-glx +} + +config_drm_egl_server: \ + SUBDIRS += drm-egl-server diff --git a/src/plugins/hardwareintegration/compositor/drm-egl-server/drm-egl-server.json b/src/plugins/hardwareintegration/compositor/drm-egl-server/drm-egl-server.json new file mode 100644 index 00000000..e2266ec6 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/drm-egl-server/drm-egl-server.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "drm-egl-server" ] +} diff --git a/src/plugins/hardwareintegration/compositor/drm-egl-server/drm-egl-server.pro b/src/plugins/hardwareintegration/compositor/drm-egl-server/drm-egl-server.pro new file mode 100644 index 00000000..a4e53f61 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/drm-egl-server/drm-egl-server.pro @@ -0,0 +1,12 @@ +PLUGIN_TYPE = wayland-graphics-integration/server +load(qt_plugin) + +QT = compositor compositor-private core-private gui-private + +OTHER_FILES += drm-egl-server.json + +SOURCES += \ + main.cpp + +include($PWD/../../../../../hardwareintegration/compositor/drm-egl-server/drm-egl-server.pri) + diff --git a/src/plugins/hardwareintegration/compositor/drm-egl-server/main.cpp b/src/plugins/hardwareintegration/compositor/drm-egl-server/main.cpp new file mode 100644 index 00000000..713791cc --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/drm-egl-server/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCompositor/qwaylandserverbufferintegrationplugin.h> +#include "drmeglserverbufferintegration.h" + +QT_BEGIN_NAMESPACE + +class DrmEglServerBufferIntegrationPlugin : public QWaylandServerBufferIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Compositor.QWaylandServerBufferIntegrationFactoryInterface.5.1" FILE "drm-egl-server.json") +public: + QStringList keys() const; + QWaylandServerBufferIntegration *create(const QString&, const QStringList&); +}; + +QStringList DrmEglServerBufferIntegrationPlugin::keys() const +{ + QStringList list; + list << "drm-egl-server"; + return list; +} + +QWaylandServerBufferIntegration *DrmEglServerBufferIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "drm-egl-server") + return new DrmEglServerBufferIntegration(); + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/waylandcompositors/wayland-egl/main.cpp b/src/plugins/hardwareintegration/compositor/wayland-egl/main.cpp index fcf917a1..8a222589 100644 --- a/src/plugins/waylandcompositors/wayland-egl/main.cpp +++ b/src/plugins/hardwareintegration/compositor/wayland-egl/main.cpp @@ -39,18 +39,19 @@ ** ****************************************************************************/ -#include <QtCompositor/qwaylandgraphicshardwareintegrationplugin.h> -#include "waylandeglintegration.h" +#include <QtCompositor/qwaylandclientbufferintegrationfactory.h> +#include <QtCompositor/qwaylandclientbufferintegrationplugin.h> +#include "waylandeglclientbufferintegration.h" QT_BEGIN_NAMESPACE -class QWaylandIntegrationPlugin : public QWaylandGraphicsHardwareIntegrationPlugin +class QWaylandIntegrationPlugin : public QWaylandClientBufferIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Compositor.QWaylandGraphicsHardwareIntegrationFactoryInterface.5.3" FILE "wayland-egl.json") + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Compositor.QWaylandClientBufferIntegrationFactoryInterface.5.3" FILE "wayland-egl.json") public: QStringList keys() const; - QWaylandGraphicsHardwareIntegration *create(const QString&, const QStringList&); + QWaylandClientBufferIntegration *create(const QString&, const QStringList&); }; QStringList QWaylandIntegrationPlugin::keys() const @@ -60,11 +61,11 @@ QStringList QWaylandIntegrationPlugin::keys() const return list; } -QWaylandGraphicsHardwareIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) +QWaylandClientBufferIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); if (system.toLower() == "wayland-egl") - return new WaylandEglIntegration(); + return new WaylandEglClientBufferIntegration(); return 0; } diff --git a/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.json b/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.json new file mode 100644 index 00000000..4ea5bab9 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "wayland-egl" ] +} diff --git a/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro b/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro new file mode 100644 index 00000000..f0ad78ba --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro @@ -0,0 +1,11 @@ +PLUGIN_TYPE = wayland-graphics-integration/server +load(qt_plugin) + +QT = compositor compositor-private core-private gui-private + +OTHER_FILES += wayland-egl.json + +SOURCES += \ + main.cpp + +include(../../../../hardwareintegration/compositor/wayland-egl/wayland-egl.pri) diff --git a/src/plugins/waylandcompositors/xcomposite-egl/main.cpp b/src/plugins/hardwareintegration/compositor/xcomposite-egl/main.cpp index 93f25fd8..8dd43e91 100644 --- a/src/plugins/waylandcompositors/xcomposite-egl/main.cpp +++ b/src/plugins/hardwareintegration/compositor/xcomposite-egl/main.cpp @@ -39,32 +39,32 @@ ** ****************************************************************************/ -#include <QtCompositor/qwaylandgraphicshardwareintegrationplugin.h> +#include <QtCompositor/qwaylandclientbufferintegrationplugin.h> #include "xcompositeeglintegration.h" QT_BEGIN_NAMESPACE -class QWaylandIntegrationPlugin : public QWaylandGraphicsHardwareIntegrationPlugin +class QWaylandXCompositeClientBufferIntegration : public QWaylandClientBufferIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Compositor.QWaylandGraphicsHardwareIntegrationFactoryInterface.5.3" FILE "xcomposite-egl.json") + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Compositor.QWaylandClientBufferIntegrationFactoryInterface.5.3" FILE "xcomposite-egl.json") public: QStringList keys() const; - QWaylandGraphicsHardwareIntegration *create(const QString&, const QStringList&); + QWaylandClientBufferIntegration *create(const QString&, const QStringList&); }; -QStringList QWaylandIntegrationPlugin::keys() const +QStringList QWaylandXCompositeClientBufferIntegration::keys() const { QStringList list; list << "wayland-xcomposite"; return list; } -QWaylandGraphicsHardwareIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) +QWaylandClientBufferIntegration *QWaylandXCompositeClientBufferIntegration::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); if (system.toLower() == "wayland-xcomposite") - return new XCompositeEglIntegration(); + return new XCompositeEglClientBufferIntegration(); return 0; } diff --git a/src/plugins/waylandcompositors/xcomposite-glx/xcomposite-glx.json b/src/plugins/hardwareintegration/compositor/xcomposite-egl/xcomposite-egl.json index 8ccd5b46..8ccd5b46 100644 --- a/src/plugins/waylandcompositors/xcomposite-glx/xcomposite-glx.json +++ b/src/plugins/hardwareintegration/compositor/xcomposite-egl/xcomposite-egl.json diff --git a/src/plugins/hardwareintegration/compositor/xcomposite-egl/xcomposite-egl.pro b/src/plugins/hardwareintegration/compositor/xcomposite-egl/xcomposite-egl.pro new file mode 100644 index 00000000..9c14eb84 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/xcomposite-egl/xcomposite-egl.pro @@ -0,0 +1,11 @@ +PLUGIN_TYPE = wayland-graphics-integration/server +load(qt_plugin) + +QT += compositor compositor-private core-private gui-private + +OTHER_FILES += xcomposite-egl.json + +SOURCES += \ + main.cpp + +include(../../../../hardwareintegration/compositor/xcomposite-egl/xcomposite-egl.pri) diff --git a/src/plugins/waylandcompositors/xcomposite-glx/main.cpp b/src/plugins/hardwareintegration/compositor/xcomposite-glx/main.cpp index 33c5440c..b7673893 100644 --- a/src/plugins/waylandcompositors/xcomposite-glx/main.cpp +++ b/src/plugins/hardwareintegration/compositor/xcomposite-glx/main.cpp @@ -39,32 +39,32 @@ ** ****************************************************************************/ -#include <QtCompositor/qwaylandgraphicshardwareintegrationplugin.h> +#include <QtCompositor/qwaylandclientbufferintegrationplugin.h> #include "xcompositeglxintegration.h" QT_BEGIN_NAMESPACE -class QWaylandIntegrationPlugin : public QWaylandGraphicsHardwareIntegrationPlugin +class QWaylandXCompositeClientBufferIntegration : public QWaylandClientBufferIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Compositor.QWaylandGraphicsHardwareIntegrationFactoryInterface.5.3" FILE "xcomposite-glx.json") + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Compositor.QWaylandClientBufferIntegrationFactoryInterface.5.3" FILE "xcomposite-glx.json") public: QStringList keys() const; - QWaylandGraphicsHardwareIntegration *create(const QString&, const QStringList&); + QWaylandClientBufferIntegration *create(const QString&, const QStringList&); }; -QStringList QWaylandIntegrationPlugin::keys() const +QStringList QWaylandXCompositeClientBufferIntegration::keys() const { QStringList list; - list << "wayland-xcomposite"; + list << "wayland-xcomposite-glx"; return list; } -QWaylandGraphicsHardwareIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) +QWaylandClientBufferIntegration *QWaylandXCompositeClientBufferIntegration::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); - if (system.toLower() == "wayland-xcomposite") - return new XCompositeGLXIntegration(); + if (system.toLower() == "wayland-xcomposite-glx") + return new XCompositeGLXClientBufferIntegration(); return 0; } diff --git a/src/plugins/hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.json b/src/plugins/hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.json new file mode 100644 index 00000000..8ccd5b46 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "wayland-xcomposite" ] +} diff --git a/src/plugins/hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.pro b/src/plugins/hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.pro new file mode 100644 index 00000000..8ec0e564 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.pro @@ -0,0 +1,11 @@ +PLUGIN_TYPE = wayland-graphics-integration/server +load(qt_plugin) + +QT += compositor compositor-private core-private gui-private + +OTHER_FILES += xcomposite-glx.json + +SOURCES += \ + main.cpp + +include(../../../../hardwareintegration/compositor/xcomposite-glx/xcomposite-glx.pri) diff --git a/src/plugins/hardwareintegration/hardwareintegration.pro b/src/plugins/hardwareintegration/hardwareintegration.pro new file mode 100644 index 00000000..4f5ec145 --- /dev/null +++ b/src/plugins/hardwareintegration/hardwareintegration.pro @@ -0,0 +1,7 @@ +TEMPLATE=subdirs + +SUBDIRS += client +#The compositor plugins are only useful with QtCompositor +contains(CONFIG, wayland-compositor) { + SUBDIRS += compositor +} diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 16760290..0665511c 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -1,25 +1,22 @@ TEMPLATE=subdirs CONFIG+=ordered -SUBDIRS += wayland_common -equals(QT_WAYLAND_GL_CONFIG, nogl) { - SUBDIRS += qwayland-nogl -} else { - config_wayland_egl { - SUBDIRS += qwayland-egl - } +SUBDIRS += qwayland-generic + +config_wayland_egl { + SUBDIRS += qwayland-egl +} - #The following integrations are only useful with QtCompositor - contains(CONFIG, wayland-compositor) { - config_brcm_egl { - SUBDIRS += qwayland-brcm-egl - } - config_xcomposite { - config_egl { - SUBDIRS += qwayland-xcomposite-egl - } else:config_glx { - SUBDIRS += qwayland-xcomposite-glx - } - } +#The following integrations are only useful with QtCompositor +contains(CONFIG, wayland-compositor) { + config_brcm_egl: \ + SUBDIRS += qwayland-brcm-egl + + config_xcomposite { + config_egl: \ + SUBDIRS += qwayland-xcomposite-egl + !contains(QT_CONFIG, opengles2):config_glx: \ + SUBDIRS += qwayland-xcomposite-glx } } + diff --git a/src/plugins/platforms/qwayland-brcm-egl/main.cpp b/src/plugins/platforms/qwayland-brcm-egl/main.cpp index f395705e..c8c4eef1 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/main.cpp +++ b/src/plugins/platforms/qwayland-brcm-egl/main.cpp @@ -40,14 +40,14 @@ ****************************************************************************/ #include <qpa/qplatformintegrationplugin.h> -#include "qwaylandintegration.h" +#include "qwaylandbrcmeglplatformintegration.h" QT_BEGIN_NAMESPACE class QWaylandIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3" FILE "qwayland-brcm-egl.json") + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "qwayland-brcm-egl.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -64,7 +64,7 @@ QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, c { Q_UNUSED(paramList); if (system.toLower() == "wayland-brcm") - return new QWaylandIntegration(); + return new QWaylandBrcmEglPlatformIntegration(); return 0; } diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwayland-brcm-egl.pro b/src/plugins/platforms/qwayland-brcm-egl/qwayland-brcm-egl.pro index 2e5a66e9..31bc718f 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwayland-brcm-egl.pro +++ b/src/plugins/platforms/qwayland-brcm-egl/qwayland-brcm-egl.pro @@ -1,20 +1,14 @@ PLUGIN_TYPE = platforms load(qt_plugin) -include(../wayland_common/wayland_common.pri) +QT += waylandclient-private + +include(../../../hardwareintegration/client/brcm-egl/brcm-egl.pri) LIBS += -lEGL OTHER_FILES += \ qwayland-brcm-egl.json -SOURCES += qwaylandbrcmeglintegration.cpp \ - qwaylandbrcmglcontext.cpp \ - qwaylandbrcmeglwindow.cpp \ - main.cpp - -HEADERS += qwaylandbrcmeglintegration.h \ - qwaylandbrcmglcontext.h \ - qwaylandbrcmeglwindow.h +SOURCES += main.cpp -WAYLANDCLIENTSOURCES += ../../../extensions/brcm.xml diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglplatformintegration.h b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglplatformintegration.h new file mode 100644 index 00000000..7dbe82fe --- /dev/null +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglplatformintegration.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDBRCMEGLPLATFORMINTEGRATION_H +#define QWAYLANDBRCMEGLPLATFORMINTEGRATION_H + +#include <QtWaylandClient/qwaylandintegration.h> +#include "qwaylandbrcmeglintegration.h" + +QT_BEGIN_NAMESPACE + +class QWaylandBrcmEglPlatformIntegration : public QWaylandIntegration +{ +public: + QWaylandBrcmEglPlatformIntegration() + : QWaylandIntegration() + , m_gl_integration(new QWaylandBrcmEglIntegration(display()) + { + } + + QWaylandGLIntegration *glIntegration() const Q_DECL_OVERRIDE + { + return m_gl_integration; + } +private: + QWaylandGLIntegration *m_gl_integration; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/qwayland-egl/main.cpp b/src/plugins/platforms/qwayland-egl/main.cpp index 6cf6fec2..6f790a14 100644 --- a/src/plugins/platforms/qwayland-egl/main.cpp +++ b/src/plugins/platforms/qwayland-egl/main.cpp @@ -40,14 +40,14 @@ ****************************************************************************/ #include <qpa/qplatformintegrationplugin.h> -#include "qwaylandintegration.h" +#include "qwaylandeglplatformintegration.h" QT_BEGIN_NAMESPACE class QWaylandIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3" FILE "qwayland-egl.json") + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "qwayland-egl.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -56,15 +56,15 @@ public: QStringList QWaylandIntegrationPlugin::keys() const { QStringList list; - list << "wayland" << "wayland-egl"; + list << "wayland-egl"; return list; } QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); - if (system.toLower() == "wayland" || system.toLower() == "wayland-egl") - return new QWaylandIntegration(); + if (system.toLower() == "wayland-egl") + return new QWaylandEglPlatformIntegration(); return 0; } diff --git a/src/plugins/platforms/qwayland-egl/qwayland-egl.json b/src/plugins/platforms/qwayland-egl/qwayland-egl.json index 3ab70d3c..4ea5bab9 100644 --- a/src/plugins/platforms/qwayland-egl/qwayland-egl.json +++ b/src/plugins/platforms/qwayland-egl/qwayland-egl.json @@ -1,3 +1,3 @@ { - "Keys": [ "wayland", "wayland-egl" ] + "Keys": [ "wayland-egl" ] } diff --git a/src/plugins/platforms/qwayland-egl/qwayland-egl.pro b/src/plugins/platforms/qwayland-egl/qwayland-egl.pro index 339f9461..279a7c38 100644 --- a/src/plugins/platforms/qwayland-egl/qwayland-egl.pro +++ b/src/plugins/platforms/qwayland-egl/qwayland-egl.pro @@ -1,24 +1,12 @@ PLUGIN_TYPE = platforms load(qt_plugin) -include(../wayland_common/wayland_common.pri) +QT += waylandclient-private + +include(../../../hardwareintegration/client/wayland-egl/wayland-egl.pri) OTHER_FILES += \ qwayland-egl.json -!contains(QT_CONFIG, no-pkg-config) { - CONFIG += link_pkgconfig - PKGCONFIG += wayland-egl egl -} else { - LIBS += -lwayland-egl -lEGL -} - -SOURCES += qwaylandeglintegration.cpp \ - qwaylandglcontext.cpp \ - qwaylandeglwindow.cpp \ - main.cpp +SOURCES += main.cpp -HEADERS += qwaylandeglintegration.h \ - qwaylandglcontext.h \ - qwaylandeglwindow.h \ - qwaylandeglinclude.h diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglplatformintegration.h b/src/plugins/platforms/qwayland-egl/qwaylandeglplatformintegration.h new file mode 100644 index 00000000..5f23f68d --- /dev/null +++ b/src/plugins/platforms/qwayland-egl/qwaylandeglplatformintegration.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDEGLPLATFORMINTEGRATION_H +#define QWAYLANDEGLPLATFORMINTEGRATION_H + +#include <QtWaylandClient/private/qwaylandintegration_p.h> + +#include "qwaylandeglclientbufferintegration.h" + +QT_BEGIN_NAMESPACE + +class QWaylandEglPlatformIntegration : public QWaylandIntegration +{ +public: + QWaylandEglPlatformIntegration() + : QWaylandIntegration() + , m_client_buffer_integration(new QWaylandEglClientBufferIntegration()) + { + m_client_buffer_integration->initialize(display()); + } + + QWaylandEglClientBufferIntegration *clientBufferIntegration() const + { return m_client_buffer_integration; } + +private: + QWaylandEglClientBufferIntegration *m_client_buffer_integration; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/qwayland-nogl/main.cpp b/src/plugins/platforms/qwayland-generic/main.cpp index e1ae9de8..0575d0dc 100644 --- a/src/plugins/platforms/qwayland-nogl/main.cpp +++ b/src/plugins/platforms/qwayland-generic/main.cpp @@ -40,14 +40,14 @@ ****************************************************************************/ #include <qpa/qplatformintegrationplugin.h> -#include "qwaylandintegration.h" +#include <QtWaylandClient/private/qwaylandintegration_p.h> QT_BEGIN_NAMESPACE class QWaylandIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3" FILE "qwayland-nogl.json") + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "qwayland-generic.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -56,14 +56,14 @@ public: QStringList QWaylandIntegrationPlugin::keys() const { QStringList list; - list << "wayland" << "wayland-nogl"; + list << "wayland"; return list; } QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); - if (system.toLower() == "wayland" || system.toLower() == "wayland-nogl") + if (system.toLower() == "wayland") return new QWaylandIntegration(); return 0; diff --git a/src/plugins/platforms/qwayland-generic/qwayland-generic.json b/src/plugins/platforms/qwayland-generic/qwayland-generic.json new file mode 100644 index 00000000..8e56c4fd --- /dev/null +++ b/src/plugins/platforms/qwayland-generic/qwayland-generic.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "wayland" ] +} diff --git a/src/plugins/platforms/qwayland-generic/qwayland-generic.pro b/src/plugins/platforms/qwayland-generic/qwayland-generic.pro new file mode 100644 index 00000000..cf42d1eb --- /dev/null +++ b/src/plugins/platforms/qwayland-generic/qwayland-generic.pro @@ -0,0 +1,10 @@ +PLUGIN_TYPE = platforms +load(qt_plugin) + +QT += waylandclient-private + +OTHER_FILES += \ + qwayland-generic.json + +SOURCES += main.cpp + diff --git a/src/plugins/platforms/qwayland-nogl/qwayland-nogl.json b/src/plugins/platforms/qwayland-nogl/qwayland-nogl.json deleted file mode 100644 index 8cbc863f..00000000 --- a/src/plugins/platforms/qwayland-nogl/qwayland-nogl.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": [ "wayland", "wayland-nogl" ] -} diff --git a/src/plugins/platforms/qwayland-nogl/qwayland-nogl.pro b/src/plugins/platforms/qwayland-nogl/qwayland-nogl.pro deleted file mode 100644 index cb3b86eb..00000000 --- a/src/plugins/platforms/qwayland-nogl/qwayland-nogl.pro +++ /dev/null @@ -1,8 +0,0 @@ -PLUGIN_TYPE = platforms -load(qt_plugin) - -include(../wayland_common/wayland_common.pri) - -OTHER_FILES += qwayland-nogl.json - -SOURCES += main.cpp diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/main.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/main.cpp index 4b37cab6..b065a465 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/main.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/main.cpp @@ -40,14 +40,14 @@ ****************************************************************************/ #include <qpa/qplatformintegrationplugin.h> -#include "qwaylandintegration.h" +#include "qwaylandxcompositeeglplatformintegration.h" QT_BEGIN_NAMESPACE class QWaylandIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3" FILE "qwayland-xcomposite-egl.json") + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "qwayland-xcomposite-egl.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -56,15 +56,15 @@ public: QStringList QWaylandIntegrationPlugin::keys() const { QStringList list; - list << "wayland-xcomposite"; + list << "wayland-xcomposite" << "wayland-xcomposite-egl"; return list; } QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); - if (system.toLower() == "wayland-xcomposite") - return new QWaylandIntegration(); + if (system.toLower() == "wayland-xcomposite" || system.toLower() == "wayland-xcomposite-egl") + return new QWaylandXCompositeEglPlatformIntegration(); return 0; } diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro b/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro index b691ec9d..74a71a57 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro @@ -1,25 +1,12 @@ PLUGIN_TYPE = platforms load(qt_plugin) -include(../wayland_common/wayland_common.pri) -include (../xcomposite_share/xcomposite_share.pri) +QT += waylandclient-private -OTHER_FILES += qwayland-xcomposite-egl.json +include(../../../hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri) -!contains(QT_CONFIG, no-pkg-config) { - CONFIG += link_pkgconfig - PKGCONFIG += xcomposite egl x11 -} else { - LIBS += -lXcomposite -lEGL -lX11 -} +OTHER_FILES += qwayland-xcomposite-egl.json SOURCES += \ - qwaylandxcompositeeglcontext.cpp \ - qwaylandxcompositeeglintegration.cpp \ - qwaylandxcompositeeglwindow.cpp \ main.cpp -HEADERS += \ - qwaylandxcompositeeglcontext.h \ - qwaylandxcompositeeglintegration.h \ - qwaylandxcompositeeglwindow.h diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglplatformintegration.h b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglplatformintegration.h new file mode 100644 index 00000000..340ab03c --- /dev/null +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglplatformintegration.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDXCOMPOSITEEGLPLATFROMINTEGRATION_H +#define QWAYLANDXCOMPOSITEEGLPLATFROMINTEGRATION_H + +#include <QtWaylandClient/private/qwaylandintegration_p.h> + +#include "qwaylandxcompositeeglclientbufferintegration.h" + +QT_BEGIN_NAMESPACE + +class QWaylandXCompositeEglPlatformIntegration : public QWaylandIntegration +{ +public: + QWaylandXCompositeEglPlatformIntegration() + : QWaylandIntegration() + , m_client_buffer_integration(new QWaylandXCompositeEGLClientBufferIntegration()) + { + m_client_buffer_integration->initialize(display()); + } + + QWaylandClientBufferIntegration *clientBufferIntegration() const Q_DECL_OVERRIDE + { return m_client_buffer_integration; } + +private: + QWaylandClientBufferIntegration *m_client_buffer_integration; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/main.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/main.cpp index 5024f307..17b20f98 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/main.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/main.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE class QWaylandIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3" FILE "qwayland-xcomposite-glx.json") + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "qwayland-xcomposite-glx.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -56,15 +56,15 @@ public: QStringList QWaylandIntegrationPlugin::keys() const { QStringList list; - list << "wayland-xcomposite"; + list << "wayland-xcomposite-glx"; return list; } QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); - if (system.toLower() == "wayland-xcomposite") - return new QWaylandIntegration(); + if (system.toLower() == "wayland-xcomposite-glx") + return new QWaylandXCompositeGlxPlatformIntegration(); return 0; } diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwayland-xcomposite-glx.json b/src/plugins/platforms/qwayland-xcomposite-glx/qwayland-xcomposite-glx.json index 8ccd5b46..0f4a3bf6 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwayland-xcomposite-glx.json +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwayland-xcomposite-glx.json @@ -1,3 +1,3 @@ { - "Keys": [ "wayland-xcomposite" ] + "Keys": [ "wayland-xcomposite-glx" ] } diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwayland-xcomposite-glx.pro b/src/plugins/platforms/qwayland-xcomposite-glx/qwayland-xcomposite-glx.pro index 6d704108..dcf2e1b6 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwayland-xcomposite-glx.pro +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwayland-xcomposite-glx.pro @@ -1,25 +1,12 @@ PLUGIN_TYPE = platforms load(qt_plugin) -include(../wayland_common/wayland_common.pri) -include (../xcomposite_share/xcomposite_share.pri) +QT += waylandclient-private -OTHER_FILES += qwayland-xcomposite-glx.json +include(../../../hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri) -!contains(QT_CONFIG, no-pkg-config) { - CONFIG += link_pkgconfig - PKGCONFIG += xcomposite gl x11 -} else { - LIBS += -lXcomposite -lGL -lX11 -} +OTHER_FILES += qwayland-xcomposite-glx.json SOURCES += \ - qwaylandxcompositeglxcontext.cpp \ - qwaylandxcompositeglxintegration.cpp \ - qwaylandxcompositeglxwindow.cpp \ main.cpp -HEADERS += \ - qwaylandxcompositeglxcontext.h \ - qwaylandxcompositeglxintegration.h \ - qwaylandxcompositeglxwindow.h diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxplatformintegration.h b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxplatformintegration.h new file mode 100644 index 00000000..fe8c5b7c --- /dev/null +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxplatformintegration.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDXCOMPOSITEGLXPLATFORMINTEGRATION_H +#define QWAYLANDXCOMPOSITEGLXPLATFORMINTEGRATION_H + +#include <QtWaylandClient/qwaylandintegration.h> + +#include "qwaylandxcompositeglxintegration.h" + +class QWaylandXCompositeGlxPlatformIntegration : public QWaylandIntegration +{ +public: + QWaylandXCompositeGlxPlatformIntegration() + : QWaylandIntegration() + , m_gl_integration(new QWaylandXCompositeGLXIntegration(display())) + { } + + QWaylandGLIntegration *glIntegration() const Q_DECL_OVERRIDE + { return m_gl_integration; } + +private: + QWaylandGLIntegration *m_gl_integration; +}; + +#endif diff --git a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp deleted file mode 100644 index 8674aae9..00000000 --- a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylanddatadevicemanager.h" - -#include "qwaylandinputdevice.h" -#include "qwaylanddataoffer.h" -#include "qwaylanddatasource.h" -#include "qwaylandshmbackingstore.h" - -#include <wayland-client-protocol.h> -#include <wayland-client.h> - -#include <QtGui/QGuiApplication> -#include <QtGui/private/qguiapplication_p.h> -#include <qpa/qplatformclipboard.h> -#include <QtGui/QPainter> - -#include <qpa/qwindowsysteminterface.h> - -#include <QtCore/QDebug> - -QT_BEGIN_NAMESPACE - -void QWaylandDataDeviceManager::data_offer(void *data, - struct wl_data_device *data_device, - struct wl_data_offer *id) -{ - Q_UNUSED(data_device); - QWaylandDataDeviceManager *handler = static_cast<QWaylandDataDeviceManager *>(data); - - new QWaylandDataOffer(handler->display(),id); -} - -void QWaylandDataDeviceManager::enter(void *data, - struct wl_data_device *wl_data_device, - uint32_t time, - struct wl_surface *surface, - wl_fixed_t x, - wl_fixed_t y, - struct wl_data_offer *id) -{ - - Q_UNUSED(wl_data_device); - Q_UNUSED(x); - Q_UNUSED(y); - QWaylandDataDeviceManager *data_device_manager = static_cast<QWaylandDataDeviceManager *>(data); - if (time < data_device_manager->m_drag_last_event_time) - return; - data_device_manager->m_drag_last_event_time = time; - - data_device_manager->m_drag_current_event_window = QWaylandWindow::fromWlSurface(surface); - if (!surface) - return; - QWaylandDataOffer *offer = static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)); - if (!offer) - return; - -// QPoint point(x,y); -// Qt::DropActions allActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; -// QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(data_device_manager->m_drag_current_event_window->window(), -// offer,point,allActions); -// data_device_manager->m_drag_can_drop = response.accepted(); - data_device_manager->m_drag_data_offer = offer; - if (data_device_manager->m_drag_can_drop) { - const char *first_offer = qPrintable(offer->formats_sys().at(0)); - wl_data_offer_accept(offer->handle(),QWaylandDisplay::currentTimeMillisec(),first_offer); - } else { - wl_data_offer_accept(offer->handle(),QWaylandDisplay::currentTimeMillisec(),0); - } -} - -void QWaylandDataDeviceManager::leave(void *data, - struct wl_data_device *wl_data_device) -{ - Q_UNUSED(wl_data_device); - QWaylandDataDeviceManager *data_device_manager = static_cast<QWaylandDataDeviceManager *>(data); -// QWindowSystemInterface::handleDrag(data_device_manager->m_drag_current_event_window->window(),0,QPoint(0,0),Qt::IgnoreAction); - data_device_manager->m_drag_can_drop = false; - data_device_manager->m_drag_data_offer = 0; - data_device_manager->m_drag_last_event_time = 0; - data_device_manager->m_drag_current_event_window = 0; - data_device_manager->m_drag_position = QPoint(); -} - -void QWaylandDataDeviceManager::motion(void *data, - struct wl_data_device *wl_data_device, - uint32_t time, - wl_fixed_t x, - wl_fixed_t y) -{ - Q_UNUSED(wl_data_device); - QWaylandDataDeviceManager *data_device_manager = static_cast<QWaylandDataDeviceManager *>(data); - if (time < data_device_manager->m_drag_last_event_time) - return; - data_device_manager->m_drag_position = QPoint(wl_fixed_to_int(x), wl_fixed_to_int(y)); - -// Qt::DropActions allActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; -// QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(data_device_manager->m_drag_current_event_window->window(), -// data_device_manager->m_drag_data_offer, data_device_manager->m_drag_position ,allActions); -// data_device_manager->m_drag_can_drop = response.accepted(); - const char *offerMime = 0; - if (data_device_manager->m_drag_can_drop) { - offerMime = qPrintable(data_device_manager->m_drag_data_offer->formats_sys().at(0)); - } - wl_data_offer_accept(data_device_manager->m_drag_data_offer->handle(),QWaylandDisplay::currentTimeMillisec(),offerMime); -} - -void QWaylandDataDeviceManager::drop(void *data, - struct wl_data_device *wl_data_device) -{ - Q_UNUSED(wl_data_device); - QWaylandDataDeviceManager *data_device_manager = static_cast<QWaylandDataDeviceManager *>(data); - QWindow *window = data_device_manager->m_drag_current_event_window->window(); - QMimeData *mime = data_device_manager->m_drag_data_offer; -// QPoint point = data_device_manager->m_drag_position; -// Qt::DropActions allActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; - - Q_UNUSED(window); - Q_UNUSED(mime); -// QWindowSystemInterface::handleDrop(window,mime,point,allActions); -} - - -void QWaylandDataDeviceManager::selection(void *data, - struct wl_data_device *wl_data_device, - struct wl_data_offer *id) -{ - Q_UNUSED(wl_data_device); - - QWaylandDataDeviceManager *handler = static_cast<QWaylandDataDeviceManager *>(data); - QWaylandDataOffer *mime = handler->m_selection_data_offer; - delete mime; - QWaylandDataSource *transfer_source = handler->m_selection_data_source; - delete transfer_source; - handler->m_selection_data_source = 0; - - if (id) { - mime = static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)); - handler->m_selection_data_offer = mime; - } else { - handler->m_selection_data_offer = 0; - } - - QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard); -} - -const struct wl_data_device_listener QWaylandDataDeviceManager::transfer_device_listener = { - QWaylandDataDeviceManager::data_offer, - QWaylandDataDeviceManager::enter, - QWaylandDataDeviceManager::leave, - QWaylandDataDeviceManager::motion, - QWaylandDataDeviceManager::drop, - QWaylandDataDeviceManager::selection -}; - -QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id) - : m_display(display) - , m_selection_data_offer(0) - , m_selection_data_source(0) - , m_drag_data_offer(0) - , m_drag_data_source(0) - , m_drag_surface(0) - , m_drag_icon_surface(0) - , m_drag_icon_buffer(0) - , m_drag_can_drop(false) -{ - m_data_device_manager = static_cast<struct wl_data_device_manager *>(wl_registry_bind(display->wl_registry(),id,&wl_data_device_manager_interface,1)); - - // Create transfer devices for all input devices. - // ### This only works if we get the global before all devices and is surely wrong when hotplugging. - QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices(); - for (int i = 0; i < inputDevices.size();i++) { - inputDevices.at(i)->setTransferDevice(getDataDevice(inputDevices.at(i))); - } -} - -QWaylandDataDeviceManager::~QWaylandDataDeviceManager() -{ - wl_data_device_manager_destroy(m_data_device_manager); -} - -struct wl_data_device *QWaylandDataDeviceManager::getDataDevice(QWaylandInputDevice *inputDevice) -{ - struct wl_data_device *transfer_device = wl_data_device_manager_get_data_device(m_data_device_manager, - inputDevice->wl_seat()); - wl_data_device_add_listener(transfer_device,&transfer_device_listener,this); - - return transfer_device; -} - -QWaylandDataOffer *QWaylandDataDeviceManager::selectionTransfer() const -{ - return m_selection_data_offer; -} - -void QWaylandDataDeviceManager::createAndSetDrag(QDrag *drag) -{ - QWaylandInputDevice *inputDevice = m_display->lastKeyboardFocusInputDevice(); - if (!inputDevice) - return; - - if (m_drag_data_source) { - qDebug() << "QWaylandDndSelectionHandler::createAndSetDrag: Allready have a valid drag"; - delete m_drag_data_source; - } - - delete m_drag_data_offer; - m_drag_data_offer = 0; - - m_drag_data_source = new QWaylandDataSource(this,drag->mimeData()); - - struct wl_data_device *transfer_device = inputDevice->transferDevice(); - m_drag_surface = m_display->createSurface(this); - QPixmap pixmap = drag->pixmap(); - if (pixmap.isNull()) { -// pixmap = QPlatformDrag::defaultPixmap(); - } - - m_drag_icon_buffer = new QWaylandShmBuffer(m_display, pixmap.size(), QImage::Format_ARGB32_Premultiplied); - - { - QPainter p(m_drag_icon_buffer->image()); - p.drawPixmap(0,0,pixmap); - } - - m_drag_icon_surface = m_display->compositor()->create_surface(); - wl_surface_attach(m_drag_icon_surface, m_drag_icon_buffer->buffer(), -drag->hotSpot().x(), -drag->hotSpot().y()); - - wl_data_device_start_drag(transfer_device, m_drag_data_source->handle(), m_drag_surface, m_drag_icon_surface, QWaylandDisplay::currentTimeMillisec()); -} - -QMimeData *QWaylandDataDeviceManager::dragMime() const -{ - if (m_drag_data_offer) { - return m_drag_data_offer; - } else if (m_drag_data_source){ - return m_drag_data_source->mimeData(); - } - return 0; -} - -bool QWaylandDataDeviceManager::canDropDrag() const -{ - return m_drag_can_drop; -} - -void QWaylandDataDeviceManager::cancelDrag() -{ - wl_data_source_destroy(m_drag_data_source->handle() ); - wl_surface_destroy(m_drag_icon_surface); - m_drag_data_source = 0; -} - -void QWaylandDataDeviceManager::createAndSetSelectionSource(QMimeData *mimeData, QClipboard::Mode mode) -{ - Q_UNUSED(mode); - QWaylandDataSource *transfer_source = m_selection_data_source; - delete transfer_source; - - transfer_source = new QWaylandDataSource(this,mimeData); - m_selection_data_source = transfer_source; - QWaylandInputDevice *inputDevice = m_display->lastKeyboardFocusInputDevice(); - if (!inputDevice) - inputDevice = m_display->inputDevices().first(); // try to survive in apps without any surfaces - struct wl_data_device *transfer_device = inputDevice->transferDevice(); - wl_data_device_set_selection(transfer_device,transfer_source->handle(),QWaylandDisplay::currentTimeMillisec()); - - QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard); -} - -QWaylandDataSource *QWaylandDataDeviceManager::selectionTransferSource() -{ - return m_selection_data_source; -} - - -QWaylandDisplay * QWaylandDataDeviceManager::display() const -{ - return m_display; -} - -struct wl_data_device_manager *QWaylandDataDeviceManager::handle() const -{ - return m_data_device_manager; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.h b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.h deleted file mode 100644 index 101f7844..00000000 --- a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDDATADEVICEMANAGER_H -#define QWAYLANDDATADEVICEMANAGER_H - -#include "qwaylanddisplay.h" - -#include <QtCore/QMap> -#include <QtCore/QMimeData> -#include <QtCore/QStringList> -#include <QtGui/QClipboard> - -QT_BEGIN_NAMESPACE - -class QWaylandDataOffer; -class QWaylandDataSource; -class QDrag; -class QWaylandShmBuffer; -class QWaylandWindow; - -class QWaylandDataDeviceManager -{ -public: - QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id); - ~QWaylandDataDeviceManager(); - - struct wl_data_device *getDataDevice(QWaylandInputDevice *inputDevice); - - QWaylandDataOffer *selectionTransfer() const; - - void createAndSetDrag(QDrag *drag); - QMimeData *dragMime() const; - bool canDropDrag() const; - void cancelDrag(); - - void createAndSetSelectionSource(QMimeData *mimeData, QClipboard::Mode mode); - QWaylandDataSource *selectionTransferSource(); - - QWaylandDisplay *display()const; - - struct wl_data_device_manager *handle() const; - -private: - struct wl_data_device_manager *m_data_device_manager; - QWaylandDisplay *m_display; - - QWaylandDataOffer *m_selection_data_offer; - QWaylandDataSource *m_selection_data_source; - - QWaylandDataOffer *m_drag_data_offer; - QWaylandDataSource *m_drag_data_source; - QWaylandWindow *m_drag_current_event_window; - wl_surface *m_drag_surface; - wl_surface *m_drag_icon_surface; - QWaylandShmBuffer *m_drag_icon_buffer; - bool m_drag_can_drop; - uint32_t m_drag_last_event_time; - QPoint m_drag_position; - - static void data_offer(void *data, - struct wl_data_device *wl_data_device, - struct wl_data_offer *id); - static void enter(void *data, - struct wl_data_device *wl_data_device, - uint32_t time, - struct wl_surface *surface, - wl_fixed_t x, - wl_fixed_t y, - struct wl_data_offer *id); - static void leave(void *data, - struct wl_data_device *wl_data_device); - static void motion(void *data, - struct wl_data_device *wl_data_device, - uint32_t time, - wl_fixed_t x, - wl_fixed_t y); - static void drop(void *data, - struct wl_data_device *wl_data_device); - static void selection(void *data, - struct wl_data_device *wl_data_device, - struct wl_data_offer *id); - - static const struct wl_data_device_listener transfer_device_listener; -}; - -QT_END_NAMESPACE - -#endif // QWAYLANDDATADEVICEMANAGER_H diff --git a/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp b/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp deleted file mode 100644 index 7bf8b0c9..00000000 --- a/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylanddatasource.h" -#include "qwaylanddataoffer.h" -#include "qwaylandinputdevice.h" -#include "qwaylandmimehelper.h" - -#include <QtCore/QFile> - -#include <QtCore/QDebug> - -#include <unistd.h> - -QT_BEGIN_NAMESPACE - -void QWaylandDataSource::data_source_target(void *data, - struct wl_data_source *wl_data_source, - const char *mime_type) -{ - Q_UNUSED(data); - Q_UNUSED(wl_data_source); - Q_UNUSED(mime_type); -} - -void QWaylandDataSource::data_source_send(void *data, - struct wl_data_source *wl_data_source, - const char *mime_type, - int32_t fd) -{ - Q_UNUSED(wl_data_source); - QWaylandDataSource *self = static_cast<QWaylandDataSource *>(data); - QString mimeType = QString::fromLatin1(mime_type); - QByteArray content = QWaylandMimeHelper::getByteArray(self->m_mime_data, mimeType); - if (!content.isEmpty()) { - QFile f; - if (f.open(fd, QIODevice::WriteOnly)) - f.write(content); - } - close(fd); -} - -void QWaylandDataSource::data_source_cancelled(void *data, - struct wl_data_source *wl_data_source) -{ - Q_UNUSED(data); - Q_UNUSED(wl_data_source); -} - -const struct wl_data_source_listener QWaylandDataSource::data_source_listener = { - data_source_target, - data_source_send, - data_source_cancelled -}; - -QWaylandDataSource::QWaylandDataSource(QWaylandDataDeviceManager *dndSelectionHandler, QMimeData *mimeData) - : m_mime_data(mimeData) -{ - m_data_source = wl_data_device_manager_create_data_source(dndSelectionHandler->handle()); - wl_data_source_add_listener(m_data_source,&data_source_listener,this); - QStringList formats = mimeData->formats(); - for (int i = 0; i < formats.size(); i++) { - const char *offer = qPrintable(formats.at(i)); - wl_data_source_offer(m_data_source,offer); - } -} - -QWaylandDataSource::~QWaylandDataSource() -{ - wl_data_source_destroy(m_data_source); -} - -QMimeData * QWaylandDataSource::mimeData() const -{ - return m_mime_data; -} - -struct wl_data_source *QWaylandDataSource::handle() const -{ - return m_data_source; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp deleted file mode 100644 index aab939f6..00000000 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp +++ /dev/null @@ -1,739 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandinputdevice.h" - -#include "qwaylandintegration.h" -#include "qwaylandwindow.h" -#include "qwaylandbuffer.h" -#include "qwaylanddatadevicemanager.h" -#include "qwaylandtouch.h" -#include "qwaylandscreen.h" -#include "qwaylandcursor.h" - -#include <QtGui/private/qpixmap_raster_p.h> -#include <qpa/qplatformwindow.h> -#include <QDebug> - -#include <unistd.h> -#include <fcntl.h> -#include <sys/mman.h> - -#include <wayland-cursor.h> - -#include <QtGui/QGuiApplication> - -#ifndef QT_NO_WAYLAND_XKB -#include <xkbcommon/xkbcommon.h> -#include <X11/keysym.h> -#endif - -QT_BEGIN_NAMESPACE - -QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) - : QtWayland::wl_seat(display->wl_registry(), id) - , mQDisplay(display) - , mDisplay(display->wl_display()) - , mFocusCallback(0) - , mCaps(0) - , mTransferDevice(0) - , mPointerFocus(0) - , mKeyboardFocus(0) - , mTouchFocus(0) - , mButtons(0) - , mCursorSerial(0) - , mTouchDevice(0) - #ifndef QT_NO_WAYLAND_XKB - , mXkbContext(0) - , mXkbMap(0) - , mXkbState(0) - #endif -{ -#ifndef QT_NO_WAYLAND_XKB - xkb_rule_names names; - names.rules = strdup("evdev"); - names.model = strdup("pc105"); - names.layout = strdup("us"); - names.variant = strdup(""); - names.options = strdup(""); - - mXkbContext = xkb_context_new(xkb_context_flags(0)); - if (mXkbContext) { - mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0)); - if (mXkbMap) { - mXkbState = xkb_state_new(mXkbMap); - } - } - - if (!mXkbContext || !mXkbMap || !mXkbState) - qWarning() << "xkb_map_new_from_names failed, no key input"; -#endif - - if (mQDisplay->dndSelectionHandler()) { - mTransferDevice = mQDisplay->dndSelectionHandler()->getDataDevice(this); - } -} - -QWaylandInputDevice::~QWaylandInputDevice() -{ -#ifndef QT_NO_WAYLAND_XKB - if (mXkbState) - xkb_state_unref(mXkbState); - if (mXkbMap) - xkb_map_unref(mXkbMap); - if (mXkbContext) - xkb_context_unref(mXkbContext); -#endif -} - -void QWaylandInputDevice::seat_capabilities(uint32_t caps) -{ - mCaps = caps; - - if (caps & WL_SEAT_CAPABILITY_KEYBOARD) - QtWayland::wl_keyboard::init(get_keyboard()); - - if (caps & WL_SEAT_CAPABILITY_POINTER) { - QtWayland::wl_pointer::init(get_pointer()); - pointerSurface = mQDisplay->createSurface(this); - } - - if (caps & WL_SEAT_CAPABILITY_TOUCH) { - QtWayland::wl_touch::init(get_touch()); - - if (!mTouchDevice) { - mTouchDevice = new QTouchDevice; - mTouchDevice->setType(QTouchDevice::TouchScreen); - mTouchDevice->setCapabilities(QTouchDevice::Position); - QWindowSystemInterface::registerTouchDevice(mTouchDevice); - } - } -} - -void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window) -{ - if (window == mPointerFocus) - mPointerFocus = 0; - if (window == mKeyboardFocus) - mKeyboardFocus = 0; -} - -void QWaylandInputDevice::setTransferDevice(struct wl_data_device *device) -{ - mTransferDevice = device; -} - -struct wl_data_device *QWaylandInputDevice::transferDevice() const -{ - Q_ASSERT(mTransferDevice); - return mTransferDevice; -} - -void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) -{ - mButtons = mButtons & !button; -} - -void QWaylandInputDevice::setCursor(Qt::CursorShape newShape, QWaylandScreen *screen) -{ - struct wl_cursor_image *image = screen->waylandCursor()->cursorImage(newShape); - if (!image) { - return; - } - - struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); - setCursor(buffer, image); -} - -void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image) -{ - if (mCaps & WL_SEAT_CAPABILITY_POINTER) { - mCursorSerial = mEnterSerial; - /* Hide cursor */ - if (!buffer) - { - set_cursor(mEnterSerial, NULL, 0, 0); - return; - } - - set_cursor(mEnterSerial, pointerSurface, - image->hotspot_x, image->hotspot_y); - wl_surface_attach(pointerSurface, buffer, 0, 0); - wl_surface_damage(pointerSurface, 0, 0, image->width, image->height); - wl_surface_commit(pointerSurface); - } -} - -void QWaylandInputDevice::pointer_enter(uint32_t serial, struct wl_surface *surface, - wl_fixed_t sx, wl_fixed_t sy) -{ - Q_UNUSED(sx); - Q_UNUSED(sy); - - if (!surface) - return; - - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - window->window()->setCursor(window->window()->cursor()); - - mPointerFocus = window; - - mTime = QWaylandDisplay::currentTimeMillisec(); - mSerial = serial; - mEnterSerial = serial; - - window->handleMouseEnter(this); - window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); -} - -void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surface) -{ - // The event may arrive after destroying the window, indicated by - // a null surface. - if (!surface) - return; - - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - window->handleMouseLeave(this); - mPointerFocus = 0; - mButtons = Qt::NoButton; - - mTime = time; -} - -void QWaylandInputDevice::pointer_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) -{ - Q_UNUSED(surface_x); - Q_UNUSED(surface_y); - - QWaylandWindow *window = mPointerFocus; - - if (window == NULL) { - // We destroyed the pointer focus surface, but the server - // didn't get the message yet. - return; - } - - QPointF pos(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)); - QPointF delta = pos - pos.toPoint(); - QPointF global = window->window()->mapToGlobal(pos.toPoint()); - global += delta; - - mSurfacePos = pos; - mGlobalPos = global; - mTime = time; - - window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); -} - -void QWaylandInputDevice::pointer_button(uint32_t serial, uint32_t time, - uint32_t button, uint32_t state) -{ - Q_UNUSED(serial); - QWaylandWindow *window = mPointerFocus; - Qt::MouseButton qt_button; - - // translate from kernel (input.h) 'button' to corresponding Qt:MouseButton. - // The range of mouse values is 0x110 <= mouse_button < 0x120, the first Joystick button. - switch (button) { - case 0x110: qt_button = Qt::LeftButton; break; // kernel BTN_LEFT - case 0x111: qt_button = Qt::RightButton; break; - case 0x112: qt_button = Qt::MiddleButton; break; - case 0x113: qt_button = Qt::ExtraButton1; break; // AKA Qt::BackButton - case 0x114: qt_button = Qt::ExtraButton2; break; // AKA Qt::ForwardButton - case 0x115: qt_button = Qt::ExtraButton3; break; // AKA Qt::TaskButton - case 0x116: qt_button = Qt::ExtraButton4; break; - case 0x117: qt_button = Qt::ExtraButton5; break; - case 0x118: qt_button = Qt::ExtraButton6; break; - case 0x119: qt_button = Qt::ExtraButton7; break; - case 0x11a: qt_button = Qt::ExtraButton8; break; - case 0x11b: qt_button = Qt::ExtraButton9; break; - case 0x11c: qt_button = Qt::ExtraButton10; break; - case 0x11d: qt_button = Qt::ExtraButton11; break; - case 0x11e: qt_button = Qt::ExtraButton12; break; - case 0x11f: qt_button = Qt::ExtraButton13; break; - default: return; // invalid button number (as far as Qt is concerned) - } - - if (state) - mButtons |= qt_button; - else - mButtons &= ~qt_button; - - mTime = time; - mSerial = serial; - - if (window) - window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); -} - -void QWaylandInputDevice::pointer_axis(uint32_t time, uint32_t axis, int32_t value) -{ - QWaylandWindow *window = mPointerFocus; - QPoint pixelDelta; - QPoint angleDelta; - - //normalize value and inverse axis - int valueDelta = wl_fixed_to_int(value) * -12; - - if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) { - pixelDelta = QPoint(); - angleDelta.setX(valueDelta); - } else { - pixelDelta = QPoint(); - angleDelta.setY(valueDelta); - } - - QWindowSystemInterface::handleWheelEvent(window->window(), - time, mSurfacePos, - mGlobalPos, pixelDelta, - angleDelta); -} - -#ifndef QT_NO_WAYLAND_XKB - -static Qt::KeyboardModifiers translateModifiers(xkb_state *state) -{ - Qt::KeyboardModifiers ret = Qt::NoModifier; - xkb_state_component cstate = xkb_state_component(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED); - - if (xkb_state_mod_name_is_active(state, "Shift", cstate)) - ret |= Qt::ShiftModifier; - if (xkb_state_mod_name_is_active(state, "Control", cstate)) - ret |= Qt::ControlModifier; - if (xkb_state_mod_name_is_active(state, "Alt", cstate)) - ret |= Qt::AltModifier; - if (xkb_state_mod_name_is_active(state, "Mod1", cstate)) - ret |= Qt::AltModifier; - if (xkb_state_mod_name_is_active(state, "Mod4", cstate)) - ret |= Qt::MetaModifier; - - return ret; -} - -static const uint32_t KeyTbl[] = { - XK_Escape, Qt::Key_Escape, - XK_Tab, Qt::Key_Tab, - XK_ISO_Left_Tab, Qt::Key_Backtab, - XK_BackSpace, Qt::Key_Backspace, - XK_Return, Qt::Key_Return, - XK_Insert, Qt::Key_Insert, - XK_Delete, Qt::Key_Delete, - XK_Clear, Qt::Key_Delete, - XK_Pause, Qt::Key_Pause, - XK_Print, Qt::Key_Print, - - XK_Home, Qt::Key_Home, - XK_End, Qt::Key_End, - XK_Left, Qt::Key_Left, - XK_Up, Qt::Key_Up, - XK_Right, Qt::Key_Right, - XK_Down, Qt::Key_Down, - XK_Prior, Qt::Key_PageUp, - XK_Next, Qt::Key_PageDown, - - XK_Shift_L, Qt::Key_Shift, - XK_Shift_R, Qt::Key_Shift, - XK_Shift_Lock, Qt::Key_Shift, - XK_Control_L, Qt::Key_Control, - XK_Control_R, Qt::Key_Control, - XK_Meta_L, Qt::Key_Meta, - XK_Meta_R, Qt::Key_Meta, - XK_Alt_L, Qt::Key_Alt, - XK_Alt_R, Qt::Key_Alt, - XK_Caps_Lock, Qt::Key_CapsLock, - XK_Num_Lock, Qt::Key_NumLock, - XK_Scroll_Lock, Qt::Key_ScrollLock, - XK_Super_L, Qt::Key_Super_L, - XK_Super_R, Qt::Key_Super_R, - XK_Menu, Qt::Key_Menu, - XK_Hyper_L, Qt::Key_Hyper_L, - XK_Hyper_R, Qt::Key_Hyper_R, - XK_Help, Qt::Key_Help, - - XK_KP_Space, Qt::Key_Space, - XK_KP_Tab, Qt::Key_Tab, - XK_KP_Enter, Qt::Key_Enter, - XK_KP_Home, Qt::Key_Home, - XK_KP_Left, Qt::Key_Left, - XK_KP_Up, Qt::Key_Up, - XK_KP_Right, Qt::Key_Right, - XK_KP_Down, Qt::Key_Down, - XK_KP_Prior, Qt::Key_PageUp, - XK_KP_Next, Qt::Key_PageDown, - XK_KP_End, Qt::Key_End, - XK_KP_Begin, Qt::Key_Clear, - XK_KP_Insert, Qt::Key_Insert, - XK_KP_Delete, Qt::Key_Delete, - XK_KP_Equal, Qt::Key_Equal, - XK_KP_Multiply, Qt::Key_Asterisk, - XK_KP_Add, Qt::Key_Plus, - XK_KP_Separator, Qt::Key_Comma, - XK_KP_Subtract, Qt::Key_Minus, - XK_KP_Decimal, Qt::Key_Period, - XK_KP_Divide, Qt::Key_Slash, - - XK_ISO_Level3_Shift, Qt::Key_AltGr, - XK_Multi_key, Qt::Key_Multi_key, - XK_Codeinput, Qt::Key_Codeinput, - XK_SingleCandidate, Qt::Key_SingleCandidate, - XK_MultipleCandidate, Qt::Key_MultipleCandidate, - XK_PreviousCandidate, Qt::Key_PreviousCandidate, - - XK_Mode_switch, Qt::Key_Mode_switch, - XK_script_switch, Qt::Key_Mode_switch, - - 0, 0 -}; - -static int keysymToQtKey(xkb_keysym_t key) -{ - int code = 0; - int i = 0; - while (KeyTbl[i]) { - if (key == KeyTbl[i]) { - code = (int)KeyTbl[i+1]; - break; - } - i += 2; - } - - return code; -} - -static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, const QString &text) -{ - int code = 0; - - if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) { - code = Qt::Key_F1 + (int(keysym) - XKB_KEY_F1); - } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) { - if (keysym >= XKB_KEY_KP_0) { - // numeric keypad keys - code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0); - } else { - code = keysymToQtKey(keysym); - } - modifiers |= Qt::KeypadModifier; - } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f - && text.unicode()->unicode() != 0x7f - && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_currency)) { - code = text.unicode()->toUpper().unicode(); - } else { - // any other keys - code = keysymToQtKey(keysym); - } - - return code; -} - -#endif // QT_NO_WAYLAND_XKB - -void QWaylandInputDevice::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size) -{ -#ifndef QT_NO_WAYLAND_XKB - if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { - close(fd); - return; - } - - char *map_str = (char *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); - if (map_str == MAP_FAILED) { - close(fd); - return; - } - - mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, (xkb_keymap_compile_flags)0); - munmap(map_str, size); - close(fd); - - mXkbState = xkb_state_new(mXkbMap); -#else - Q_UNUSED(format); - Q_UNUSED(fd); - Q_UNUSED(size); -#endif -} - -void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surface, struct wl_array *keys) -{ - Q_UNUSED(time); - Q_UNUSED(keys); - - if (!surface) - return; - - - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - mKeyboardFocus = window; - - if (!mFocusCallback) { - mFocusCallback = wl_display_sync(mDisplay); - wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); - } -} - -void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surface) -{ - Q_UNUSED(time); - Q_UNUSED(surface); - - mKeyboardFocus = NULL; - - // Use a callback to set the focus because we may get a leave/enter pair, and - // the latter one would be lost in the QWindowSystemInterface queue, if - // we issue the handleWindowActivated() calls immediately. - if (!mFocusCallback) { - mFocusCallback = wl_display_sync(mDisplay); - wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); - } -} - -const wl_callback_listener QWaylandInputDevice::callback = { - QWaylandInputDevice::focusCallback -}; - -void QWaylandInputDevice::focusCallback(void *data, struct wl_callback *callback, uint32_t time) -{ - Q_UNUSED(time); - Q_UNUSED(callback); - QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data); - if (self->mFocusCallback) { - wl_callback_destroy(self->mFocusCallback); - self->mFocusCallback = 0; - } - - self->mQDisplay->setLastKeyboardFocusInputDevice(self->mKeyboardFocus ? self : 0); - QWindowSystemInterface::handleWindowActivated(self->mKeyboardFocus ? self->mKeyboardFocus->window() : 0); -} - -void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -{ - Q_UNUSED(serial); - QWaylandWindow *window = mKeyboardFocus; -#ifndef QT_NO_WAYLAND_XKB - if (!mXkbMap) - return; - - uint32_t code = key + 8; - bool isDown = state != 0; - const xkb_keysym_t *syms; - uint32_t numSyms = xkb_key_get_syms(mXkbState, code, &syms); - xkb_state_update_key(mXkbState, code, - isDown ? XKB_KEY_DOWN : XKB_KEY_UP); - - if (!window) { - // We destroyed the keyboard focus surface, but the server - // didn't get the message yet. - return; - } - - if (numSyms == 1) { - xkb_keysym_t sym = syms[0]; - Qt::KeyboardModifiers modifiers = translateModifiers(mXkbState); - QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; - - uint utf32 = xkb_keysym_to_utf32(sym); - QString text = QString::fromUcs4(&utf32, 1); - - int qtkey = keysymToQtKey(sym, modifiers, text); - - QWindowSystemInterface::handleExtendedKeyEvent(window->window(), - time, type, qtkey, - modifiers, - code, 0, 0, text); - } -#else - // Generic fallback for single hard keys: Assume 'key' is a Qt key code. - if (window) { - QWindowSystemInterface::handleExtendedKeyEvent(window->window(), - time, state ? QEvent::KeyPress : QEvent::KeyRelease, - key + 8, // qt-compositor substracts 8 for some reason - Qt::NoModifier, - key + 8, 0, 0); - } -#endif -} - -void QWaylandInputDevice::keyboard_modifiers(uint32_t serial, - uint32_t mods_depressed, - uint32_t mods_latched, - uint32_t mods_locked, - uint32_t group) -{ - Q_UNUSED(serial); -#ifndef QT_NO_WAYLAND_XKB - if (mXkbState) - xkb_state_update_mask(mXkbState, - mods_depressed, mods_latched, mods_locked, - 0, 0, group); -#else - Q_UNUSED(serial); - Q_UNUSED(mods_depressed); - Q_UNUSED(mods_latched); - Q_UNUSED(mods_locked); - Q_UNUSED(group); -#endif -} - -void QWaylandInputDevice::touch_down(uint32_t serial, - uint32_t time, - struct wl_surface *surface, - int32_t id, - wl_fixed_t x, - wl_fixed_t y) -{ - Q_UNUSED(serial); - Q_UNUSED(time); - mTouchFocus = QWaylandWindow::fromWlSurface(surface); - handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); -} - -void QWaylandInputDevice::touch_up(uint32_t serial, uint32_t time, int32_t id) -{ - Q_UNUSED(serial); - Q_UNUSED(time); - mTouchFocus = 0; - handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); -} - -void QWaylandInputDevice::touch_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) -{ - Q_UNUSED(time); - handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved); -} - -void QWaylandInputDevice::touch_cancel() -{ - mPrevTouchPoints.clear(); - mTouchPoints.clear(); - - QWaylandTouchExtension *touchExt = mQDisplay->touchExtension(); - if (touchExt) - touchExt->touchCanceled(); - - QWindowSystemInterface::handleTouchCancelEvent(0, mTouchDevice); -} - -void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state) -{ - QWindowSystemInterface::TouchPoint tp; - - // Find out the coordinates for Released events. - bool coordsOk = false; - if (state == Qt::TouchPointReleased) - for (int i = 0; i < mPrevTouchPoints.count(); ++i) - if (mPrevTouchPoints.at(i).id == id) { - tp.area = mPrevTouchPoints.at(i).area; - coordsOk = true; - break; - } - - if (!coordsOk) { - // x and y are surface relative. - // We need a global (screen) position. - QWaylandWindow *win = mTouchFocus; - - //is it possible that mTouchFocus is null; - if (!win) - win = mPointerFocus; - if (!win) - win = mKeyboardFocus; - if (!win || !win->window()) - return; - - tp.area = QRectF(0, 0, 8, 8); - QMargins margins = win->frameMargins(); - tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x+margins.left(), y+margins.top()))); - } - - tp.state = state; - tp.id = id; - tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1; - mTouchPoints.append(tp); -} - -void QWaylandInputDevice::touch_frame() -{ - // Copy all points, that are in the previous but not in the current list, as stationary. - for (int i = 0; i < mPrevTouchPoints.count(); ++i) { - const QWindowSystemInterface::TouchPoint &prevPoint(mPrevTouchPoints.at(i)); - if (prevPoint.state == Qt::TouchPointReleased) - continue; - bool found = false; - for (int j = 0; j < mTouchPoints.count(); ++j) - if (mTouchPoints.at(j).id == prevPoint.id) { - found = true; - break; - } - if (!found) { - QWindowSystemInterface::TouchPoint p = prevPoint; - p.state = Qt::TouchPointStationary; - mTouchPoints.append(p); - } - } - - if (mTouchPoints.isEmpty()) { - mPrevTouchPoints.clear(); - return; - } - - QWindow *window = mTouchFocus ? mTouchFocus->window() : 0; - - QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, mTouchPoints); - - bool allReleased = true; - for (int i = 0; i < mTouchPoints.count(); ++i) - if (mTouchPoints.at(i).state != Qt::TouchPointReleased) { - allReleased = false; - break; - } - - mPrevTouchPoints = mTouchPoints; - mTouchPoints.clear(); - - if (allReleased) { - QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, mTouchPoints); - mPrevTouchPoints.clear(); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/wayland_common.pri b/src/plugins/platforms/wayland_common/wayland_common.pri deleted file mode 100644 index cc956a72..00000000 --- a/src/plugins/platforms/wayland_common/wayland_common.pri +++ /dev/null @@ -1,10 +0,0 @@ -#This file(wayland_common.pri) is included from .pro files of GL integrations. - -include ($$PWD/wayland_common_share.pri) - -INCLUDEPATH += $$PWD - -staticlib = $$shadowed($$PWD)/$${QMAKE_PREFIX_STATICLIB}wayland_common.$${QMAKE_EXTENSION_STATICLIB} -LIBS += $$staticlib -PRE_TARGETDEPS += $$staticlib - diff --git a/src/plugins/platforms/wayland_common/wayland_common.pro b/src/plugins/platforms/wayland_common/wayland_common.pro deleted file mode 100644 index d8aedb65..00000000 --- a/src/plugins/platforms/wayland_common/wayland_common.pro +++ /dev/null @@ -1,72 +0,0 @@ -TEMPLATE = lib -CONFIG += staticlib - -include ($$PWD/wayland_common_share.pri) - -SOURCES += qwaylandintegration.cpp \ - qwaylandnativeinterface.cpp \ - qwaylandshmbackingstore.cpp \ - qwaylandinputdevice.cpp \ - qwaylandcursor.cpp \ - qwaylanddisplay.cpp \ - qwaylandwindow.cpp \ - qwaylandscreen.cpp \ - qwaylandshmwindow.cpp \ - qwaylandclipboard.cpp \ - qwaylanddnd.cpp \ - qwaylanddataoffer.cpp \ - qwaylanddatadevicemanager.cpp \ - qwaylanddatasource.cpp \ - qwaylandshellsurface.cpp \ - qwaylandextendedoutput.cpp \ - qwaylandextendedsurface.cpp \ - qwaylandsubsurface.cpp \ - qwaylandtouch.cpp \ - qwaylandqtkey.cpp \ - ../../../shared/qwaylandmimehelper.cpp \ - qwaylanddecoration.cpp \ - qwaylandeventthread.cpp\ - qwaylandwindowmanagerintegration.cpp - -HEADERS += qwaylandintegration.h \ - qwaylandnativeinterface.h \ - qwaylandcursor.h \ - qwaylanddisplay.h \ - qwaylandwindow.h \ - qwaylandscreen.h \ - qwaylandshmbackingstore.h \ - qwaylandinputdevice.h \ - qwaylandbuffer.h \ - qwaylandshmwindow.h \ - qwaylandclipboard.h \ - qwaylanddnd.h \ - qwaylanddataoffer.h \ - qwaylanddatadevicemanager.h \ - qwaylanddatasource.h \ - qwaylandshellsurface.h \ - qwaylandextendedoutput.h \ - qwaylandextendedsurface.h \ - qwaylandsubsurface.h \ - qwaylandtouch.h \ - qwaylandqtkey.h \ - ../../../shared/qwaylandmimehelper.h \ - qwaylanddecoration.h \ - qwaylandeventthread.h \ - qwaylandwindowmanagerintegration.h - -contains(DEFINES, QT_WAYLAND_GL_SUPPORT) { - SOURCES += qwaylandglintegration.cpp - HEADERS += qwaylandglintegration.h -} - -WAYLANDCLIENTSOURCES += \ - ../../../extensions/surface-extension.xml \ - ../../../extensions/sub-surface-extension.xml \ - ../../../extensions/output-extension.xml \ - ../../../extensions/touch-extension.xml \ - ../../../extensions/qtkey-extension.xml \ - ../../../extensions/windowmanager.xml \ - -PLUGIN_TYPE = platforms - -load(qt_common) diff --git a/src/plugins/platforms/wayland_common/wayland_common_share.pri b/src/plugins/platforms/wayland_common/wayland_common_share.pri deleted file mode 100644 index a9a990b4..00000000 --- a/src/plugins/platforms/wayland_common/wayland_common_share.pri +++ /dev/null @@ -1,26 +0,0 @@ -QT += core-private gui-private platformsupport-private -CONFIG += link_pkgconfig qpa/genericunixfontdatabase - -!equals(QT_WAYLAND_GL_CONFIG, nogl) { - DEFINES += QT_WAYLAND_GL_SUPPORT -} - -config_xkbcommon { - !contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += xkbcommon - } else { - LIBS += -lxkbcommon - } -} else { - DEFINES += QT_NO_WAYLAND_XKB -} - -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += wayland-client wayland-cursor -} else { - LIBS += -lwayland-client -lwayland-cursor -} - -INCLUDEPATH += $$PWD/../../../shared - -WAYLANDCLIENTSOURCES += ../../../3rdparty/protocol/wayland.xml diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 9613979b..554dd40c 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,7 +1,2 @@ TEMPLATE=subdirs -SUBDIRS += platforms - -#The compositor plugins are only useful with QtCompositor -contains(CONFIG, wayland-compositor) { - SUBDIRS += waylandcompositors -} +SUBDIRS += platforms hardwareintegration diff --git a/src/plugins/waylandcompositors/brcm-egl/brcm-egl.pro b/src/plugins/waylandcompositors/brcm-egl/brcm-egl.pro deleted file mode 100644 index 4dcfbaf9..00000000 --- a/src/plugins/waylandcompositors/brcm-egl/brcm-egl.pro +++ /dev/null @@ -1,22 +0,0 @@ -PLUGIN_TYPE = waylandcompositors -load(qt_plugin) - -QT = compositor compositor-private core-private gui-private - -OTHER_FILES += wayland_egl.json - -LIBS += -lEGL - -SOURCES += \ - brcmeglintegration.cpp \ - brcmbuffer.cpp \ - main.cpp - - -HEADERS += \ - brcmeglintegration.h \ - brcmbuffer.h - -OTHER_FILES += brcm-egl.json - -WAYLANDSERVERSOURCES += $$PWD/../../../extensions/brcm.xml $$PWD/../../../3rdparty/protocol/wayland.xml diff --git a/src/plugins/waylandcompositors/wayland-egl/wayland-egl.pro b/src/plugins/waylandcompositors/wayland-egl/wayland-egl.pro deleted file mode 100644 index 73095639..00000000 --- a/src/plugins/waylandcompositors/wayland-egl/wayland-egl.pro +++ /dev/null @@ -1,22 +0,0 @@ -PLUGIN_TYPE = waylandcompositors -load(qt_plugin) - -QT = compositor compositor-private core-private gui-private - -OTHER_FILES += wayland-egl.json - -WAYLANDSERVERSOURCES += $$PWD/../../../3rdparty/protocol/wayland.xml - -!contains(QT_CONFIG, no-pkg-config) { - CONFIG += link_pkgconfig - PKGCONFIG += wayland-egl egl -} else { - LIBS += -lwayland-egl -lEGL -} - -SOURCES += \ - waylandeglintegration.cpp \ - main.cpp - -HEADERS += \ - waylandeglintegration.h diff --git a/src/plugins/waylandcompositors/waylandcompositors.pro b/src/plugins/waylandcompositors/waylandcompositors.pro deleted file mode 100644 index 8a4d9b04..00000000 --- a/src/plugins/waylandcompositors/waylandcompositors.pro +++ /dev/null @@ -1,17 +0,0 @@ -TEMPLATE = subdirs - -!isEqual(QT_WAYLAND_GL_CONFIG,nogl) { - config_wayland_egl { - SUBDIRS += wayland-egl - } - config_brcm_egl { - SUBDIRS += brcm-egl - } - config_xcomposite { - config_egl { - SUBDIRS += xcomposite-egl - } else:config_glx { - SUBDIRS += xcomposite-glx - } - } -} diff --git a/src/plugins/waylandcompositors/xcomposite-egl/xcomposite-egl.pro b/src/plugins/waylandcompositors/xcomposite-egl/xcomposite-egl.pro deleted file mode 100644 index d463e6e8..00000000 --- a/src/plugins/waylandcompositors/xcomposite-egl/xcomposite-egl.pro +++ /dev/null @@ -1,22 +0,0 @@ -PLUGIN_TYPE = waylandcompositors -load(qt_plugin) - -QT = compositor compositor-private core-private gui-private - -OTHER_FILES += xcomposite-egl.json - -include (../xcomposite_share/xcomposite_share.pri) - -!contains(QT_CONFIG, no-pkg-config) { - CONFIG += link_pkgconfig - PKGCONFIG += xcomposite egl x11 -} else { - LIBS += -lXcomposite -lEGL -lX11 -} - -HEADERS += \ - xcompositeeglintegration.h - -SOURCES += \ - xcompositeeglintegration.cpp \ - main.cpp diff --git a/src/plugins/waylandcompositors/xcomposite-glx/xcomposite-glx.pro b/src/plugins/waylandcompositors/xcomposite-glx/xcomposite-glx.pro deleted file mode 100644 index dc2d70de..00000000 --- a/src/plugins/waylandcompositors/xcomposite-glx/xcomposite-glx.pro +++ /dev/null @@ -1,22 +0,0 @@ -PLUGIN_TYPE = waylandcompositors -load(qt_plugin) - -QT = compositor compositor-private core-private gui-private - -OTHER_FILES += xcomposite-glx.json - -include (../xcomposite_share/xcomposite_share.pri) - -!contains(QT_CONFIG, no-pkg-config) { - CONFIG += link_pkgconfig - PKGCONFIG += xcomposite gl x11 -} else { - LIBS += -lXcomposite -lGL -lX11 -} - -HEADERS += \ - xcompositeglxintegration.h - -SOURCES += \ - xcompositeglxintegration.cpp \ - main.cpp diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp index 7264950e..43783222 100644 --- a/src/qtwaylandscanner/qtwaylandscanner.cpp +++ b/src/qtwaylandscanner/qtwaylandscanner.cpp @@ -226,7 +226,7 @@ const WaylandArgument *newIdArgument(const QList<WaylandArgument> &arguments) return 0; } -void printEvent(const WaylandEvent &e, const char *interfaceName, bool omitNames = false, bool withResource = false) +void printEvent(const WaylandEvent &e, bool omitNames = false, bool withResource = false) { printf("%s(", e.name.constData()); bool needsComma = false; @@ -260,8 +260,6 @@ void printEvent(const WaylandEvent &e, const char *interfaceName, bool omitNames printf("const struct ::wl_interface *%s, uint32_t%s", omitNames ? "" : "interface", omitNames ? "" : " version"); continue; } - - printf("struct ::%s *%s, ", interfaceName, omitNames ? "" : "object"); } } @@ -329,7 +327,7 @@ bool ignoreInterface(const QByteArray &name) || (isServerSide() && name == "wl_registry"); } -void process(QXmlStreamReader &xml) +void process(QXmlStreamReader &xml, const QByteArray &headerPath) { if (!xml.readNextStartElement()) return; @@ -346,6 +344,11 @@ void process(QXmlStreamReader &xml) return; } + //We should convert - to _ so that the preprocessor wont generate code which will lead to unexpected behavior + //However, the wayland-scanner doesn't do so we will do the same for now + //QByteArray preProcessorProtocolName = QByteArray(protocolName).replace('-', '_').toUpper(); + QByteArray preProcessorProtocolName = QByteArray(protocolName).toUpper(); + QList<WaylandInterface> interfaces; while (xml.readNextStartElement()) { @@ -359,12 +362,15 @@ void process(QXmlStreamReader &xml) return; if (option == ServerHeader) { - QByteArray inclusionGuard = "QT_WAYLAND_SERVER_" + protocolName.toUpper(); + QByteArray inclusionGuard = QByteArray("QT_WAYLAND_SERVER_") + preProcessorProtocolName.constData(); printf("#ifndef %s\n", inclusionGuard.constData()); printf("#define %s\n", inclusionGuard.constData()); printf("\n"); printf("#include \"wayland-server.h\"\n"); - printf("#include \"wayland-%s-server-protocol.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + if (headerPath.isEmpty()) + printf("#include \"wayland-%s-server-protocol.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + else + printf("#include <%s/wayland-%s-server-protocol.h>\n", headerPath.constData(), QByteArray(protocolName).replace('_', '-').constData()); printf("#include <QByteArray>\n"); printf("#include <QMultiMap>\n"); printf("#include <QString>\n"); @@ -379,6 +385,19 @@ void process(QXmlStreamReader &xml) printf("\n"); printf("QT_BEGIN_NAMESPACE\n"); + + QByteArray serverExport; + if (headerPath.size()) { + serverExport = QByteArray("Q_WAYLAND_SERVER_") + preProcessorProtocolName + "_EXPORT"; + printf("\n"); + printf("#if !defined(%s)\n", serverExport.constData()); + printf("# if defined(QT_SHARED)\n"); + printf("# define %s Q_DECL_EXPORT\n", serverExport.constData()); + printf("# else\n"); + printf("# define %s\n", serverExport.constData()); + printf("# endif\n"); + printf("#endif\n"); + } printf("\n"); printf("namespace QtWaylandServer {\n"); @@ -393,7 +412,7 @@ void process(QXmlStreamReader &xml) QByteArray stripped = stripInterfaceName(interface.name); const char *interfaceNameStripped = stripped.constData(); - printf(" class %s\n {\n", interfaceName); + printf(" class %s %s\n {\n", serverExport.constData(), interfaceName); printf(" public:\n"); printf(" %s(struct ::wl_client *client, int id);\n", interfaceName); printf(" %s(struct ::wl_display *display);\n", interfaceName); @@ -418,6 +437,7 @@ void process(QXmlStreamReader &xml) printf(" void init(struct ::wl_client *client, int id);\n"); printf(" void init(struct ::wl_display *display);\n"); printf("\n"); + printf(" Resource *add(struct ::wl_client *client);\n"); printf(" Resource *add(struct ::wl_client *client, int id);\n"); printf(" Resource *add(struct wl_list *resource_list, struct ::wl_client *client, int id);\n"); printf("\n"); @@ -438,10 +458,10 @@ void process(QXmlStreamReader &xml) printf("\n"); foreach (const WaylandEvent &e, interface.events) { printf(" void send_"); - printEvent(e, interfaceName); + printEvent(e); printf(";\n"); printf(" void send_"); - printEvent(e, interfaceName, false, true); + printEvent(e, false, true); printf(";\n"); } } @@ -459,7 +479,7 @@ void process(QXmlStreamReader &xml) printf("\n"); foreach (const WaylandEvent &e, interface.requests) { printf(" virtual void %s_", interfaceNameStripped); - printEvent(e, interfaceName); + printEvent(e); printf(";\n"); } } @@ -503,7 +523,10 @@ void process(QXmlStreamReader &xml) } if (option == ServerCode) { - printf("#include \"qwayland-server-%s.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + if (headerPath.isEmpty()) + printf("#include \"qwayland-server-%s.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + else + printf("#include <%s/qwayland-server-%s.h>\n", headerPath.constData(), QByteArray(protocolName).replace('_', '-').constData()); printf("\n"); printf("QT_BEGIN_NAMESPACE\n"); printf("\n"); @@ -563,6 +586,14 @@ void process(QXmlStreamReader &xml) printf(" }\n"); printf("\n"); + printf(" %s::Resource *%s::add(struct ::wl_client *client)\n", interfaceName, interfaceName); + printf(" {\n"); + printf(" Resource *resource = bind(client, 0);\n"); + printf(" m_resource_map.insert(client, resource);\n"); + printf(" return resource;\n"); + printf(" }\n"); + printf("\n"); + printf(" %s::Resource *%s::add(struct ::wl_client *client, int id)\n", interfaceName, interfaceName); printf(" {\n"); printf(" Resource *resource = bind(client, id);\n"); @@ -617,12 +648,14 @@ void process(QXmlStreamReader &xml) QByteArray interfaceMember = hasRequests ? "&m_" + interface.name + "_interface" : QByteArray("0"); + //We should consider changing bind so that it doesn't special case id == 0 + //and use function overloading instead. Jan do you have a lot of code dependent on this behavior? printf(" %s::Resource *%s::bind(struct ::wl_client *client, uint32_t id)\n", interfaceName, interfaceName); printf(" {\n"); printf(" Resource *resource = %s_allocate();\n", interfaceNameStripped); printf(" resource->%s = this;\n", interfaceNameStripped); printf("\n"); - printf(" struct ::wl_resource *handle = wl_client_add_object(client, &::%s_interface, %s, id, resource);\n", interfaceName, interfaceMember.constData()); + printf(" struct ::wl_resource *handle = id != 0 ? wl_client_add_object(client, &::%s_interface, %s, id, resource) : wl_client_new_object(client, &::%s_interface, %s, resource);\n", interfaceName, interfaceMember.constData(), interfaceName, interfaceMember.constData()); printf("\n"); printf(" handle->destroy = destroy_func;\n"); printf(" resource->handle = handle;\n"); @@ -646,7 +679,7 @@ void process(QXmlStreamReader &xml) foreach (const WaylandEvent &e, interface.requests) { printf("\n"); printf(" void %s::%s_", interfaceName, interfaceNameStripped); - printEvent(e, interfaceName, true); + printEvent(e, true); printf("\n"); printf(" {\n"); printf(" }\n"); @@ -686,7 +719,7 @@ void process(QXmlStreamReader &xml) printf("\n"); const WaylandEvent &e = interface.events.at(i); printf(" void %s::send_", interfaceName); - printEvent(e, interfaceName); + printEvent(e); printf("\n"); printf(" {\n"); printf(" send_%s(\n", e.name.constData()); @@ -701,7 +734,7 @@ void process(QXmlStreamReader &xml) printf("\n"); printf(" void %s::send_", interfaceName); - printEvent(e, interfaceName, false, true); + printEvent(e, false, true); printf("\n"); printf(" {\n"); @@ -746,15 +779,32 @@ void process(QXmlStreamReader &xml) } if (option == ClientHeader) { - QByteArray inclusionGuard = "QT_WAYLAND_" + protocolName.toUpper(); + QByteArray inclusionGuard = QByteArray("QT_WAYLAND_") + preProcessorProtocolName.constData(); printf("#ifndef %s\n", inclusionGuard.constData()); printf("#define %s\n", inclusionGuard.constData()); printf("\n"); - printf("#include \"wayland-%s-client-protocol.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + if (headerPath.isEmpty()) + printf("#include \"wayland-%s-client-protocol.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + else + printf("#include <%s/wayland-%s-client-protocol.h>\n", headerPath.constData(), QByteArray(protocolName).replace('_', '-').constData()); printf("#include <QByteArray>\n"); printf("#include <QString>\n"); printf("\n"); printf("QT_BEGIN_NAMESPACE\n"); + + QByteArray clientExport; + + if (headerPath.size()) { + clientExport = QByteArray("Q_WAYLAND_CLIENT_") + preProcessorProtocolName + "_EXPORT"; + printf("\n"); + printf("#if !defined(%s)\n", clientExport.constData()); + printf("# if defined(QT_SHARED)\n"); + printf("# define %s Q_DECL_EXPORT\n", clientExport.constData()); + printf("# else\n"); + printf("# define %s\n", clientExport.constData()); + printf("# endif\n"); + printf("#endif\n"); + } printf("\n"); printf("namespace QtWayland {\n"); for (int j = 0; j < interfaces.size(); ++j) { @@ -768,7 +818,7 @@ void process(QXmlStreamReader &xml) QByteArray stripped = stripInterfaceName(interface.name); const char *interfaceNameStripped = stripped.constData(); - printf(" class %s\n {\n", interfaceName); + printf(" class %s %s\n {\n", clientExport.constData(), interfaceName); printf(" public:\n"); printf(" %s(struct ::wl_registry *registry, int id);\n", interfaceName); printf(" %s(struct ::%s *object);\n", interfaceName, interfaceName); @@ -791,7 +841,7 @@ void process(QXmlStreamReader &xml) foreach (const WaylandEvent &e, interface.requests) { const WaylandArgument *new_id = newIdArgument(e.arguments); printf(" %s", new_id ? (new_id->interface.isEmpty() ? "void *" : "struct ::" + new_id->interface + " *").constData() : "void "); - printEvent(e, interfaceName); + printEvent(e); printf(";\n"); } } @@ -803,7 +853,7 @@ void process(QXmlStreamReader &xml) printf(" protected:\n"); foreach (const WaylandEvent &e, interface.events) { printf(" virtual void %s_", interfaceNameStripped); - printEvent(e, interfaceName); + printEvent(e); printf(";\n"); } } @@ -835,7 +885,10 @@ void process(QXmlStreamReader &xml) } if (option == ClientCode) { - printf("#include \"qwayland-%s.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + if (headerPath.isEmpty()) + printf("#include \"qwayland-%s.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + else + printf("#include <%s/qwayland-%s.h>\n", headerPath.constData(), QByteArray(protocolName).replace('_', '-').constData()); printf("\n"); printf("QT_BEGIN_NAMESPACE\n"); printf("\n"); @@ -880,7 +933,7 @@ void process(QXmlStreamReader &xml) printf(" void %s::init(struct ::wl_registry *registry, int id)\n", interfaceName); printf(" {\n"); - printf(" m_%s = static_cast<struct ::%s *>(wl_registry_bind(registry, id, &%s_interface, %d));\n", interfaceName, interfaceName, interfaceName, interface.version); + printf(" m_%s = static_cast<struct ::%s *>(wl_registry_bind(registry, id, &%s_interface, %d));\n", interfaceName, interfaceName, interfaceName, 1); if (hasEvents) printf(" init_listener();\n"); printf(" }\n"); @@ -904,7 +957,7 @@ void process(QXmlStreamReader &xml) const WaylandEvent &e = interface.requests.at(i); const WaylandArgument *new_id = newIdArgument(e.arguments); printf(" %s%s::", new_id ? (new_id->interface.isEmpty() ? "void *" : "struct ::" + new_id->interface + " *").constData() : "void ", interfaceName); - printEvent(e, interfaceName); + printEvent(e); printf("\n"); printf(" {\n"); for (int i = 0; i < e.arguments.size(); ++i) { @@ -956,7 +1009,7 @@ void process(QXmlStreamReader &xml) for (int i = 0; i < interface.events.size(); ++i) { const WaylandEvent &e = interface.events.at(i); printf(" void %s::%s_", interfaceName, interfaceNameStripped); - printEvent(e, interfaceName, true); + printEvent(e, true); printf("\n"); printf(" {\n"); printf(" }\n"); @@ -965,8 +1018,7 @@ void process(QXmlStreamReader &xml) printEventHandlerSignature(e, interfaceName, false); printf("\n"); printf(" {\n"); - if (!newIdArgument(e.arguments)) - printf(" Q_UNUSED(object);\n"); + printf(" Q_UNUSED(object);\n"); printf(" static_cast<%s *>(data)->%s_%s(", interfaceName, interfaceNameStripped, e.name.constData()); for (int i = 0; i < e.arguments.size(); ++i) { printf("\n"); @@ -974,8 +1026,6 @@ void process(QXmlStreamReader &xml) QByteArray cType = waylandToCType(a.type, a.interface); QByteArray qtType = waylandToQtType(a.type, a.interface, e.request); const char *argumentName = a.name.constData(); - if (a.type == "new_id") - printf(" object,\n"); if (a.type == "string") printf(" QString::fromUtf8(%s)", argumentName); else @@ -1015,12 +1065,15 @@ void process(QXmlStreamReader &xml) int main(int argc, char **argv) { if (argc <= 2 || !parseOption(argv[1], &option)) { - fprintf(stderr, "Usage: %s [client-header|server-header|client-code|server-code] specfile\n", argv[0]); + fprintf(stderr, "Usage: %s [client-header|server-header|client-code|server-code] specfile [header-path]\n", argv[0]); return 1; } QCoreApplication app(argc, argv); + QByteArray headerPath; + if (argc == 4) + headerPath = QByteArray(argv[3]); QFile file(argv[2]); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { fprintf(stderr, "Unable to open file %s\n", argv[2]); @@ -1028,7 +1081,7 @@ int main(int argc, char **argv) } QXmlStreamReader xml(&file); - process(xml); + process(xml, headerPath); if (xml.hasError()) { fprintf(stderr, "XML error: %s\nLine %lld, column %lld\n", xml.errorString().toLocal8Bit().constData(), xml.lineNumber(), xml.columnNumber()); diff --git a/src/src.pro b/src/src.pro index ac4e62aa..274cc01c 100644 --- a/src/src.pro +++ b/src/src.pro @@ -8,4 +8,4 @@ contains(CONFIG, wayland-compositor) { SUBDIRS += compositor } -SUBDIRS += plugins +SUBDIRS += client plugins diff --git a/sync.profile b/sync.profile index e8c62c4d..5bff7535 100644 --- a/sync.profile +++ b/sync.profile @@ -1,5 +1,6 @@ %modules = ( # path to module name map "QtCompositor" => "$basedir/src/compositor", + "QtWaylandClient" => "$basedir/src/client", ); %moduleheaders = ( # restrict the module headers to those found in relative path ); diff --git a/tests/auto/client/client.pro b/tests/auto/client/client.pro index 448f7d51..eaf6c6e9 100644 --- a/tests/auto/client/client.pro +++ b/tests/auto/client/client.pro @@ -10,6 +10,7 @@ QT += core-private gui-private LIBS += -lwayland-client -lwayland-server } +CONFIG += wayland-scanner WAYLANDSERVERSOURCES += \ ../../../src/3rdparty/protocol/wayland.xml diff --git a/tests/auto/compositor/mockclient.h b/tests/auto/compositor/mockclient.h index fa7c28a8..db748df4 100644 --- a/tests/auto/compositor/mockclient.h +++ b/tests/auto/compositor/mockclient.h @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "wayland-client.h" +#include <wayland-client.h> #include <QObject> #include <QImage> |