diff options
author | Andy Nichols <andy.nichols@digia.com> | 2015-05-11 16:36:50 +0200 |
---|---|---|
committer | Andy Nichols <andy.nichols@digia.com> | 2015-05-11 16:48:38 +0200 |
commit | 298e4e678b2fa6dc62f5a90e0b27caa954aaed66 (patch) | |
tree | 9cceb057bca8d16946b2c3df788dce81ccf97159 |
Initial public release of Qt Gamepad module
Qt Gamepad is a Qt 5 module that adds support for using Gamepad devices
(like the XBox 360 controller) inside of Qt applications.
Change-Id: I5dff629dcfdcc5625a90274017b8e97f45e8fd30
102 files changed, 6795 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5a23b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1,328 @@ +# This file is used to ignore files which are generated in the Qt build system +# ---------------------------------------------------------------------------- + +examples/*/*/* +!examples/*/*/*[.]* +!examples/*/*/README +!examples/*/doc/* +!examples/*/doc/*/* +examples/*/*/*[.]app +!examples/declarative/* +examples/tutorials/*/*/* +!examples/tutorials/*/*/*[.]* +!examples/tutorials/*/*/README +!examples/tutorials/* +!examples/tutorials/*/* +!examples/ja_JP/*/* +demos/*/* +!demos/spectrum/* +demos/spectrum/bin +!demos/*/*[.]* +demos/*/*[.]app +!demos/declarative/* +config.tests/*/*/* +!config.tests/*/*/*[.]* +config.tests/*/*/*[.]app + +callgrind.out.* +pcviewer.cfg +*~ +*.a +*.la +*.core +*.d +*.dylib +*.moc +*.o +*.obj +*.orig +*.swp +*.rej +*.so +*.so.* +*.pbxuser +*.mode1 +*.mode1v3 +*_pch.h.cpp +*_resource.rc +.#* +*.*# +core +.qmake.cache +.qmake.vars +.device.vars +*.prl +tags +.DS_Store +*.debug +Makefile* +!qmake/Makefile.win32* +!qmake/Makefile.unix +*.prl +*.app +*.pro.user* +*.qmlproject.user* +*.gcov +*.gcda +*.gcno +bin/*.dll +bin/assistant* +bin/designer* +bin/dumpcpp* +bin/idc* +bin/jsondb* +bin/linguist* +bin/lrelease* +bin/lupdate* +bin/lconvert* +bin/moc* +bin/makeqpf* +bin/pixeltool* +bin/qmake* +bin/qdoc* +bin/qt3to4* +bin/qttracereplay* +bin/rcc* +bin/uic* +bin/patternist* +bin/phonon* +bin/qcollectiongenerator* +bin/qdbus* +bin/qhelpconverter* +bin/qhelpgenerator* +bin/qglinfo* +bin/qtconfig* +bin/xmlpatterns* +bin/cetest* +bin/collectiongenerator +bin/helpconverter +bin/helpgenerator +bin/kmap2qmap* +bin/qlalr* +bin/qmlconv* +bin/qmldebugger* +bin/qml* +bin/qttracereplay* +bin/qt.conf +bin/servicefw* +bin/sfwlisten* +configure.cache +config.status +config.summary +mkspecs/default +mkspecs/default-host +mkspecs/qconfig.pri +mkspecs/qdevice.pri +mkspecs/qfeatures.pri +moc_*.cpp +qmake/qmake.exe +qmake/Makefile.bak +qmake/qmake_pch.pch +src/corelib/global/qconfig.cpp +src/corelib/global/qconfig.h +src/corelib/global/qconfig.h.qmake +src/corelib/global/qfeatures.h +src/platformsupport/*_interface.* +src/platformsupport/*_adaptor.* +ui_*.h +tests/auto/qprocess/test*/*.exe +tests/auto/qtcpsocket/stressTest/*.exe +tests/auto/qprocess/fileWriterProcess/*.exe +tests/auto/qmake/testdata/quotedfilenames/*.exe +tests/auto/compilerwarnings/*.exe +tests/auto/qmake/testdata/quotedfilenames/test.cpp +tests/auto/qprocess/fileWriterProcess.txt +tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/mime/ +tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/mime/ +.com.apple.timemachine.supported +tests/auto/qlibrary/libmylib.so* +tests/auto/qresourceengine/runtime_resource.rcc +tools/activeqt/testcon/testcon.tlb +translations/*.qm +translations/*_untranslated.ts +qrc_*.cpp + +# Test generated files +QObject.log +tst_* +!tst_*.* +tst_*.log +tst_*.debug +tst_*~ +tests/auto/cmake/build + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +*.exe.embed.manifest +*.exe_manifest.rc +*.exe_manifest.res + +# MinGW generated files +*.Debug +*.Release + +# WebKit temp files +src/3rdparty/webkit/WebCore/mocinclude.tmp +src/3rdparty/webkit/includes.txt +src/3rdparty/webkit/includes2.txt + +# generated files in configure.exe bootstrapping +tools/configure/configure.intermediate.manifest +tools/configure/configure_pch.pch +/configure.exe + +# Symlinks generated by configure +tools/qvfb/qvfbhdr.h +tools/qvfb/qlock_p.h +tools/qvfb/qlock.cpp +tools/qvfb/qwssignalhandler.cpp +tools/qvfb/qwssignalhandler_p.h +.DS_Store +.pch +.rcc +*.app +config.status +config.tests/unix/cups/cups +config.tests/unix/getaddrinfo/getaddrinfo +config.tests/unix/getifaddrs/getifaddrs +config.tests/unix/iconv/iconv +config.tests/unix/ipv6/ipv6 +config.tests/unix/ipv6ifname/ipv6ifname +config.tests/unix/largefile/largefile +config.tests/unix/nis/nis +config.tests/unix/odbc/odbc +config.tests/unix/openssl/openssl +config.tests/unix/stl/stl +config.tests/unix/zlib/zlib +config.tests/unix/3dnow/3dnow +config.tests/unix/mmx/mmx +config.tests/unix/sse/sse +config.tests/unix/sse2/sse2 + + + +# Directories to ignore +# --------------------- + +debug +examples/tools/plugandpaint/plugins +include/* +include/*/* +lib/* +imports/* +!lib/fonts +!lib/README +plugins/*/* +release +tmp +doc-build +doc/html/* +doc/qt*/* +doc/qch +doc-build +.rcc +.pch +.metadata +tmp-debug +tmp-debug-shared +tmp-release +tmp-release-shared + +qtc-debugging-helper +qtc-qmldump +qtc-qmldbg +src/corelib/lib +src/network/lib +src/xml/lib/ + +.pc/ + +# INTEGRITY generated files +*.gpj +*.int +*.ael +*.dla +*.dnm +*.dep +*.map +work + + +#generated module def and version header files +mkspecs/modules/qt_*.pri +mkspecs/modules-inst/ +mkspecs/qmodule.pri + +#unit tests libs/plugins +tests/auto/corelib/plugin/qlibrary/libmylib.so2 +tests/auto/corelib/plugin/qlibrary/mylib.dl2 + +#unit tests executables (other than those named tst_*) +tests/auto/testlib/selftests/assert/assert +tests/auto/testlib/selftests/badxml/badxml +tests/auto/testlib/selftests/benchlibcallgrind/benchlibcallgrind +tests/auto/testlib/selftests/benchlibeventcounter/benchlibeventcounter +tests/auto/testlib/selftests/benchliboptions/benchliboptions +tests/auto/testlib/selftests/benchlibtickcounter/benchlibtickcounter +tests/auto/testlib/selftests/benchlibwalltime/benchlibwalltime +tests/auto/testlib/selftests/cmptest/cmptest +tests/auto/testlib/selftests/commandlinedata/commandlinedata +tests/auto/testlib/selftests/crashes/crashes +tests/auto/testlib/selftests/datatable/datatable +tests/auto/testlib/selftests/datetime/datetime +tests/auto/testlib/selftests/differentexec/differentexec +tests/auto/testlib/selftests/exceptionthrow/exceptionthrow +tests/auto/testlib/selftests/expectfail/expectfail +tests/auto/testlib/selftests/failinit/failinit +tests/auto/testlib/selftests/failinitdata/failinitdata +tests/auto/testlib/selftests/fetchbogus/fetchbogus +tests/auto/testlib/selftests/float/float +tests/auto/testlib/selftests/globaldata/globaldata +tests/auto/testlib/selftests/longstring/longstring +tests/auto/testlib/selftests/maxwarnings/maxwarnings +tests/auto/testlib/selftests/multiexec/multiexec +tests/auto/testlib/selftests/qexecstringlist/qexecstringlist +tests/auto/testlib/selftests/singleskip/singleskip +tests/auto/testlib/selftests/skip/skip +tests/auto/testlib/selftests/skipglobal/skipglobal +tests/auto/testlib/selftests/skipinit/skipinit +tests/auto/testlib/selftests/skipinitdata/skipinitdata +tests/auto/testlib/selftests/sleep/sleep +tests/auto/testlib/selftests/strcmp/strcmp +tests/auto/testlib/selftests/subtest/subtest +tests/auto/testlib/selftests/waitwithoutgui/waitwithoutgui +tests/auto/testlib/selftests/warnings/warnings +tests/auto/testlib/selftests/xunit/xunit +tests/auto/corelib/thread/qthreadstorage/crashOnExit +tests/auto/corelib/io/qresourceengine/qresourceengine +tests/auto/corelib/codecs/qtextcodec/echo/echo +tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness +tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper +tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper +tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver +tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger +tests/auto/dbus/qdbusabstractinterface/test/pinger_interface.* +tests/auto/dbus/qdbusinterface/qmyserver/qmyserver +tests/auto/gui/kernel/qfileopenevent/qfileopeneventexternal/qfileopeneventexternal +tests/auto/network/bearer/qnetworksession/lackey/lackey +tests/auto/widgets/kernel/qapplication/modal/modal + +# Generated static plugin import sources +*_plugin_import.cpp diff --git a/.qmake.conf b/.qmake.conf new file mode 100644 index 0000000..a98bcf6 --- /dev/null +++ b/.qmake.conf @@ -0,0 +1,3 @@ +load(qt_build_config) + +MODULE_VERSION = 5.5.0 diff --git a/LICENSE.GPL b/LICENSE.GPL new file mode 100644 index 0000000..94a9ed0 --- /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.LGPLv3 b/LICENSE.LGPLv3 new file mode 100644 index 0000000..8fbb743 --- /dev/null +++ b/LICENSE.LGPLv3 @@ -0,0 +1,173 @@ + GNU LESSER GENERAL PUBLIC LICENSE + + The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. + Contact: http://www.qt.io/licensing/ + + You may use, distribute and copy the Qt GUI Toolkit under the terms of + GNU Lesser General Public License version 3, which is displayed below. + +------------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> +Everyone is permitted to copy and distribute verbatim copies of this +licensedocument, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + +0. Additional Definitions. + + As used herein, “this License” refers to version 3 of the GNU Lesser +General Public License, and the “GNU GPL” refers to version 3 of the +GNU General Public License. + + “The Library” refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An “Application” is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A “Combined Work” is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the “Linked +Version”. + + The “Minimal Corresponding Source” for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The “Corresponding Application Code” for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + +1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + +2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort + to ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + +3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this + license document. + +4. Combined Works. + + You may convey a Combined Work under terms of your choice that, taken +together, effectively do not restrict modification of the portions of +the Library contained in the Combined Work and reverse engineering for +debugging such modifications, if you also do each of the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this + license document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of + this License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with + the Library. A suitable mechanism is one that (a) uses at run + time a copy of the Library already present on the user's + computer system, and (b) will operate properly with a modified + version of the Library that is interface-compatible with the + Linked Version. + + e) Provide Installation Information, but only if you would + otherwise be required to provide such information under section 6 + of the GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the Application + with a modified version of the Linked Version. (If you use option + 4d0, the Installation Information must accompany the Minimal + Corresponding Source and Corresponding Application Code. If you + use option 4d1, you must provide the Installation Information in + the manner specified by section 6 of the GNU GPL for conveying + Corresponding Source.) + +5. Combined Libraries. + + 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 that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities, conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of + it is a work based on the Library, and explaining where to find + the accompanying uncombined form of the same work. + +6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU 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 +as you received it specifies that a certain numbered version of the +GNU Lesser General Public License “or any later version” applies to +it, you have the option of following the terms and conditions either +of that published version or of any later version published by the +Free Software Foundation. If the Library as you received it does not +specify a version number of the GNU Lesser General Public License, +you may choose any version of the GNU Lesser General Public License +ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the Library. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..7a2ec2c --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +Qt Gamepad + +A Qt 5 module that adds support for getting events from gamepad devices on multiple platforms. + +Currently supports Linux (evdev), Windows (xinput) and OS X (via SDL2). + +This module provides classes that can: + - Read input events from game controllers (Button and Axis events), both from C++ and Qt Quick (QML) + - Provide a queryable input state (by processing events) + - Provide key bindings diff --git a/config.tests/sdl/main.cpp b/config.tests/sdl/main.cpp new file mode 100644 index 0000000..4fe2480 --- /dev/null +++ b/config.tests/sdl/main.cpp @@ -0,0 +1,9 @@ +#include <SDL.h> +#include <SDL_gamecontroller.h> + +int main(int argc, char** argv) +{ + SDL_Init(SDL_INIT_GAMECONTROLLER); + SDL_Quit(); + return 0; +} diff --git a/config.tests/sdl/sdl.pro b/config.tests/sdl/sdl.pro new file mode 100644 index 0000000..7d5263a --- /dev/null +++ b/config.tests/sdl/sdl.pro @@ -0,0 +1,15 @@ +SOURCES += main.cpp +QT = +CONFIG -= qt + +osx:{ + INCLUDEPATH += /Library/Frameworks/SDL2.framework/Headers + LIBS += -F/Library/Frameworks/ -framework SDL2 +} + +unix:!osx{ + CONFIG += link_pkgconfig + PKGCONFIG += sdl2 +} + +win32: LIBS += -lSDL2 -lSDL2main diff --git a/examples/examples.pro b/examples/examples.pro new file mode 100644 index 0000000..4461e4d --- /dev/null +++ b/examples/examples.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs + +SUBDIRS += simple \ + mouseItem + +qtHaveModule(quick) { + SUBDIRS += quickGamepad \ + keyNavigation +} diff --git a/examples/keyNavigation/deployment.pri b/examples/keyNavigation/deployment.pri new file mode 100644 index 0000000..839b3b5 --- /dev/null +++ b/examples/keyNavigation/deployment.pri @@ -0,0 +1,23 @@ +android-no-sdk { + target.path = /data/user/qt + export(target.path) + INSTALLS += target +} else:android { + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + export(target.path) + INSTALLS += target +} else:unix { + isEmpty(target.path) { + target.path = /opt/$${TARGET}/bin + export(target.path) + } + INSTALLS += target +} + +export(INSTALLS) diff --git a/examples/keyNavigation/keyNavigation.pro b/examples/keyNavigation/keyNavigation.pro new file mode 100644 index 0000000..1cdc565 --- /dev/null +++ b/examples/keyNavigation/keyNavigation.pro @@ -0,0 +1,13 @@ +TEMPLATE = app + +QT += qml quick widgets + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) diff --git a/examples/keyNavigation/keyNavigation64.png b/examples/keyNavigation/keyNavigation64.png Binary files differnew file mode 100644 index 0000000..707d5c4 --- /dev/null +++ b/examples/keyNavigation/keyNavigation64.png diff --git a/examples/keyNavigation/keyNavigation80.png b/examples/keyNavigation/keyNavigation80.png Binary files differnew file mode 100644 index 0000000..6ad8096 --- /dev/null +++ b/examples/keyNavigation/keyNavigation80.png diff --git a/examples/keyNavigation/main.cpp b/examples/keyNavigation/main.cpp new file mode 100644 index 0000000..188b215 --- /dev/null +++ b/examples/keyNavigation/main.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 <QApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:///qml/main.qml"))); + + return app.exec(); +} diff --git a/examples/keyNavigation/qml.qrc b/examples/keyNavigation/qml.qrc new file mode 100644 index 0000000..69145a8 --- /dev/null +++ b/examples/keyNavigation/qml.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>qml/main.qml</file> + </qresource> +</RCC> diff --git a/examples/keyNavigation/qml/main.qml b/examples/keyNavigation/qml/main.qml new file mode 100644 index 0000000..2c4106c --- /dev/null +++ b/examples/keyNavigation/qml/main.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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.2 +import QtQuick.Controls 1.1 +import QtGamepad 1.0 + +ApplicationWindow { + visible: true + width: 640 + height: 480 + title: qsTr("Gamepad Key Navigation") + + Gamepad { + id: gamepad1 + index: 0 + } + + GamepadKeyNavigation { + id: gamepadKeyNavigation + gamepad: gamepad1 + active: true + buttonYKey: Qt.Key_Y + } + + Text { + text: qsTr("Test key events from Gamepad") + anchors.centerIn: parent + focus: true + Keys.onPressed: { + if (event.key === Qt.Key_Up) { + text = "Key Up Pressed"; + } else if (event.key === Qt.Key_Down) { + text = "Key Down Pressed"; + } else if (event.key === Qt.Key_Right) { + text = "Key Right Pressed"; + } else if (event.key === Qt.Key_Left) { + text = "Key Left Pressed"; + } else if (event.key === Qt.Key_Return) { + text = "Key Return Pressed"; + } else if (event.key === Qt.Key_Back) { + text = "Key Back Pressed"; + } else if (event.key === Qt.Key_Forward) { + text = "Key Forward Pressed"; + } else if (event.key === Qt.Key_Y) { + text = "Key Y Pressed"; + } + } + Keys.onReleased: { + if (event.key === Qt.Key_Up) { + text = "Key Up Released"; + } else if (event.key === Qt.Key_Down) { + text = "Key Down Released"; + } else if (event.key === Qt.Key_Right) { + text = "Key Right Released"; + } else if (event.key === Qt.Key_Left) { + text = "Key Left Released"; + } else if (event.key === Qt.Key_Return) { + text = "Key Return Released"; + } else if (event.key === Qt.Key_Back) { + text = "Key Back Released"; + } else if (event.key === Qt.Key_Forward) { + text = "Key Forward Released"; + } else if (event.key === Qt.Key_Y) { + text = "Key Y Released"; + } + } + } +} diff --git a/examples/mouseItem/deployment.pri b/examples/mouseItem/deployment.pri new file mode 100644 index 0000000..839b3b5 --- /dev/null +++ b/examples/mouseItem/deployment.pri @@ -0,0 +1,23 @@ +android-no-sdk { + target.path = /data/user/qt + export(target.path) + INSTALLS += target +} else:android { + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + export(target.path) + INSTALLS += target +} else:unix { + isEmpty(target.path) { + target.path = /opt/$${TARGET}/bin + export(target.path) + } + INSTALLS += target +} + +export(INSTALLS) diff --git a/examples/mouseItem/main.cpp b/examples/mouseItem/main.cpp new file mode 100644 index 0000000..ab95334 --- /dev/null +++ b/examples/mouseItem/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 <QApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:///qml/main.qml"))); + + return app.exec(); +} diff --git a/examples/mouseItem/mouseItem.pro b/examples/mouseItem/mouseItem.pro new file mode 100644 index 0000000..1cdc565 --- /dev/null +++ b/examples/mouseItem/mouseItem.pro @@ -0,0 +1,13 @@ +TEMPLATE = app + +QT += qml quick widgets + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) diff --git a/examples/mouseItem/mouseItem64.png b/examples/mouseItem/mouseItem64.png Binary files differnew file mode 100644 index 0000000..707d5c4 --- /dev/null +++ b/examples/mouseItem/mouseItem64.png diff --git a/examples/mouseItem/mouseItem80.png b/examples/mouseItem/mouseItem80.png Binary files differnew file mode 100644 index 0000000..6ad8096 --- /dev/null +++ b/examples/mouseItem/mouseItem80.png diff --git a/examples/mouseItem/qml.qrc b/examples/mouseItem/qml.qrc new file mode 100644 index 0000000..69145a8 --- /dev/null +++ b/examples/mouseItem/qml.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>qml/main.qml</file> + </qresource> +</RCC> diff --git a/examples/mouseItem/qml/main.qml b/examples/mouseItem/qml/main.qml new file mode 100644 index 0000000..4ab1f8a --- /dev/null +++ b/examples/mouseItem/qml/main.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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.2 +import QtQuick.Controls 1.1 +import QtGamepad 1.0 + +ApplicationWindow { + visible: true + width: 640 + height: 480 + title: qsTr("Hello World") + + Gamepad { + id: gamepad1 + index: 0 + + onButtonAChanged: { + if (value == true) { + gamepadMouse.mouseButtonPressed(Qt.LeftButton); + console.log("fake clicked qt: " + gamepadMouse.mousePosition.x + "," + gamepadMouse.mousePosition.y); + } else { + gamepadMouse.mouseButtonReleased(Qt.LeftButton); + } + } + } + + GamepadMouseItem { + id: gamepadMouse + anchors.fill: parent + gamepad: gamepad1 + active: true + + Rectangle { + id: cursor + width: 4 + height: 4 + x: gamepadMouse.mousePosition.x + y: gamepadMouse.mousePosition.y + color: "red" + } + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("clicked qt: " + mouse.x + "," + mouse.y); + } + } +} diff --git a/examples/quickGamepad/deployment.pri b/examples/quickGamepad/deployment.pri new file mode 100644 index 0000000..839b3b5 --- /dev/null +++ b/examples/quickGamepad/deployment.pri @@ -0,0 +1,23 @@ +android-no-sdk { + target.path = /data/user/qt + export(target.path) + INSTALLS += target +} else:android { + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + export(target.path) + INSTALLS += target +} else:unix { + isEmpty(target.path) { + target.path = /opt/$${TARGET}/bin + export(target.path) + } + INSTALLS += target +} + +export(INSTALLS) diff --git a/examples/quickGamepad/main.cpp b/examples/quickGamepad/main.cpp new file mode 100644 index 0000000..188b215 --- /dev/null +++ b/examples/quickGamepad/main.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 <QApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:///qml/main.qml"))); + + return app.exec(); +} diff --git a/examples/quickGamepad/qml.qrc b/examples/quickGamepad/qml.qrc new file mode 100644 index 0000000..d82637e --- /dev/null +++ b/examples/quickGamepad/qml.qrc @@ -0,0 +1,24 @@ +<RCC> + <qresource prefix="/"> + <file>qml/main.qml</file> + <file>qml/JoystickViewer.qml</file> + <file>qml/xboxControllerButtonA.png</file> + <file>qml/xboxControllerButtonB.png</file> + <file>qml/xboxControllerButtonX.png</file> + <file>qml/xboxControllerButtonY.png</file> + <file>qml/ButtonImage.qml</file> + <file>qml/xboxControllerBack.png</file> + <file>qml/xboxControllerButtonGuide.png</file> + <file>qml/xboxControllerDPad.png</file> + <file>qml/xboxControllerLeftShoulder.png</file> + <file>qml/xboxControllerLeftThumbstick.png</file> + <file>qml/xboxControllerLeftTrigger.png</file> + <file>qml/xboxControllerRightShoulder.png</file> + <file>qml/xboxControllerRightThumbstick.png</file> + <file>qml/xboxControllerRightTrigger.png</file> + <file>qml/xboxControllerStart.png</file> + <file>qml/LeftThumbstick.qml</file> + <file>qml/RightThumbstick.qml</file> + <file>qml/DPad.qml</file> + </qresource> +</RCC> diff --git a/examples/quickGamepad/qml/ButtonImage.qml b/examples/quickGamepad/qml/ButtonImage.qml new file mode 100644 index 0000000..8057542 --- /dev/null +++ b/examples/quickGamepad/qml/ButtonImage.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 +import QtGraphicalEffects 1.0 + +Item { + width: buttonImage.sourceSize.width + height: buttonImage.sourceSize.height + + property alias source: buttonImage.source + property bool active: false + + Image { + id: buttonImage + smooth: true +// visible: !active + } + + Rectangle { + anchors.fill: buttonImage + color: "#14abff" + opacity: 0.6 + radius: 8 + visible: active + } + + // BrightnessContrast { + // anchors.fill: buttonImage + // source: buttonImage + // brightness: 0.5 + // contrast: 0.5 + // visible: active + // } +} diff --git a/examples/quickGamepad/qml/DPad.qml b/examples/quickGamepad/qml/DPad.qml new file mode 100644 index 0000000..d34c953 --- /dev/null +++ b/examples/quickGamepad/qml/DPad.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 +import QtGamepad 1.0 +import QtGraphicalEffects 1.0 + +Item { + property Gamepad gamepad + + width: dpadImage.sourceSize.width + height: dpadImage.sourceSize.height + Image { + id: dpadImage + anchors.fill: parent + source: "xboxControllerDPad.png" + } + + Rectangle { + id: upArea + visible: gamepad.buttonUp + color: "#3814abff" + radius: 5 + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width * 0.3 + height: parent.height * 0.3 + anchors.topMargin: parent.height * 0.05 + } + Rectangle { + id: downArea + visible: gamepad.buttonDown + color: "#3814abff" + radius: 5 + width: parent.width * 0.3 + height: parent.height * 0.3 + anchors.bottom: parent.bottom + anchors.bottomMargin: parent.height * 0.05 + anchors.horizontalCenter: parent.horizontalCenter + } + Rectangle { + id: leftArea + visible: gamepad.buttonLeft + color: "#3814abff" + radius: 5 + width: parent.width * 0.3 + height: parent.height * 0.3 + anchors.left: parent.left + anchors.leftMargin: parent.width * 0.05 + anchors.verticalCenter: parent.verticalCenter + } + + Rectangle { + id: rightArea + visible: gamepad.buttonRight + color: "#3814abff" + radius: 5 + width: parent.width * 0.3 + height: parent.height * 0.3 + anchors.right: parent.right + anchors.rightMargin: parent.width * 0.05 + anchors.verticalCenter: parent.verticalCenter + } +} diff --git a/examples/quickGamepad/qml/JoystickViewer.qml b/examples/quickGamepad/qml/JoystickViewer.qml new file mode 100644 index 0000000..da0168e --- /dev/null +++ b/examples/quickGamepad/qml/JoystickViewer.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 { + width: 100 + height: 100 + + property real xAxisValue: 0 + property real yAxisValue: 0 + + onXAxisValueChanged: { + joystickCanvas.requestPaint(); + } + onYAxisValueChanged: { + joystickCanvas.requestPaint() + } + + Canvas { + id: joystickCanvas + anchors.fill: parent + + onPaint: { + var context = joystickCanvas.getContext("2d") + context.clearRect(0, 0, width, height); + var targetX = (xAxisValue + 1) / 2 * width; + var targetY = (yAxisValue + 1) / 2 * height; + context.fillStyle = "red"; + context.beginPath(); + context.arc(targetX, targetY, 5, 0, 2 * Math.PI, false); + context.closePath(); + context.fill(); + } + } + +} diff --git a/examples/quickGamepad/qml/LeftThumbstick.qml b/examples/quickGamepad/qml/LeftThumbstick.qml new file mode 100644 index 0000000..8ee0db0 --- /dev/null +++ b/examples/quickGamepad/qml/LeftThumbstick.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 +import QtGamepad 1.0 + +ButtonImage { + + property Gamepad gamepad + + id: leftStickButton + source: "xboxControllerLeftThumbstick.png" + active: gamepad.buttonL3 + + JoystickViewer { + id: leftJoystick + anchors.top: parent.top + anchors.left: parent.left + anchors.margins: parent.width * (3 / 153) + width: parent.width * (140 / 153) + xAxisValue: gamepad.axisLeftX + yAxisValue: gamepad.axisLeftY + height: width + } +} diff --git a/examples/quickGamepad/qml/RightThumbstick.qml b/examples/quickGamepad/qml/RightThumbstick.qml new file mode 100644 index 0000000..9dfa3de --- /dev/null +++ b/examples/quickGamepad/qml/RightThumbstick.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 +import QtGamepad 1.0 + +ButtonImage { + + property Gamepad gamepad + + id: rightStickButton + source: "xboxControllerRightThumbstick.png" + active: gamepad.buttonR3 + + JoystickViewer { + id: rightJoystick + anchors.top: parent.top + anchors.right: parent.right + anchors.margins: parent.width * (3 / 153) + width: parent.width * (140 / 153) + xAxisValue: gamepad.axisRightX + yAxisValue: gamepad.axisRightY + height: width + } +} + diff --git a/examples/quickGamepad/qml/main.qml b/examples/quickGamepad/qml/main.qml new file mode 100644 index 0000000..10b6674 --- /dev/null +++ b/examples/quickGamepad/qml/main.qml @@ -0,0 +1,235 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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.2 +import QtQuick.Controls 1.1 +import QtGamepad 1.0 + +ApplicationWindow { + id: applicationWindow1 + visible: true + width: 800 + height: 600 + title: qsTr("QtGamepad Example") + + Rectangle { + id: background + color: "#363330" + anchors.fill: parent + + Item { + id: buttonL2Item + height: leftTrigger.height + width: leftTrigger.width + buttonL2Value.width + anchors.left: parent.left + anchors.leftMargin: 8 + anchors.top: parent.top + anchors.topMargin: 8 + + ButtonImage { + id: leftTrigger + anchors.top: parent.top + anchors.left: parent.left + anchors.bottom: parent.bottom + source: "xboxControllerLeftTrigger.png" + active: gamepad.buttonL2 != 0 + } + + ProgressBar { + id: buttonL2Value + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: leftTrigger.right + orientation: 0 + value: gamepad.buttonL2 + } + } + ButtonImage { + id: buttonL1 + anchors.left: buttonL2Item.left + anchors.top: buttonL2Item.bottom + anchors.topMargin: 8 + source: "xboxControllerLeftShoulder.png" + active: gamepad.buttonL1 + } + + + Item { + id: buttonR2Item + height: rightTrigger.height + width: rightTrigger.width + buttonR2Value.width + anchors.right: parent.right + anchors.rightMargin: 8 + anchors.top: parent.top + anchors.topMargin: 8 + + ButtonImage { + id: rightTrigger + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: parent.bottom + source: "xboxControllerRightTrigger.png" + active: gamepad.buttonR2 != 0 + } + + ProgressBar { + id: buttonR2Value + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: rightTrigger.left + orientation: 0 + value: gamepad.buttonR2 + } + } + ButtonImage { + id: buttonR1 + anchors.right: buttonR2Item.right + anchors.top: buttonR2Item.bottom + anchors.topMargin: 8 + source: "xboxControllerRightShoulder.png" + active: gamepad.buttonR1 + } + + Item { + id: centerButtons + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.topMargin: 8 + height: guideButton.height + width: guideButton.width + 16 + backButton.width + startButton.width + ButtonImage { + id: backButton + anchors.verticalCenter: parent.verticalCenter + anchors.right: guideButton.left + anchors.rightMargin: 8 + source: "xboxControllerBack.png" + active: gamepad.buttonSelect + } + ButtonImage { + id: guideButton + anchors.centerIn: parent + source: "xboxControllerButtonGuide.png" + active: gamepad.buttonGuide + } + ButtonImage { + anchors.verticalCenter: parent.verticalCenter + anchors.left: guideButton.right + anchors.leftMargin: 8 + id: startButton + source: "xboxControllerStart.png" + active: gamepad.buttonStart + } + } + + + + + DPad { + id: dPad + gamepad: gamepad + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: 8 + } + + Row { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.margins: 8 + spacing: 16 + + LeftThumbstick { + id: leftThumbstick + gamepad: gamepad + } + + RightThumbstick { + id: rightThumbstick + gamepad: gamepad + } + } + + + Item { + width: 200 + height: 200 + anchors.right: parent.right + anchors.rightMargin: 8 + anchors.bottom: parent.bottom + anchors.bottomMargin: 8 + ButtonImage { + id: buttonA + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + source: "xboxControllerButtonA.png"; + active: gamepad.buttonA + } + ButtonImage { + id: buttonB + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + source: "xboxControllerButtonB.png"; + active: gamepad.buttonB + } + ButtonImage { + id: buttonX + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + source: "xboxControllerButtonX.png"; + active: gamepad.buttonX + } + ButtonImage { + id: buttonY + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + source: "xboxControllerButtonY.png"; + active: gamepad.buttonY + } + } + + } + + + + Gamepad { + id: gamepad + } + +} diff --git a/examples/quickGamepad/qml/xboxControllerBack.png b/examples/quickGamepad/qml/xboxControllerBack.png Binary files differnew file mode 100644 index 0000000..d97972c --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerBack.png diff --git a/examples/quickGamepad/qml/xboxControllerButtonA.png b/examples/quickGamepad/qml/xboxControllerButtonA.png Binary files differnew file mode 100644 index 0000000..271e8c8 --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerButtonA.png diff --git a/examples/quickGamepad/qml/xboxControllerButtonB.png b/examples/quickGamepad/qml/xboxControllerButtonB.png Binary files differnew file mode 100644 index 0000000..f1e06b6 --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerButtonB.png diff --git a/examples/quickGamepad/qml/xboxControllerButtonGuide.png b/examples/quickGamepad/qml/xboxControllerButtonGuide.png Binary files differnew file mode 100644 index 0000000..287d32b --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerButtonGuide.png diff --git a/examples/quickGamepad/qml/xboxControllerButtonX.png b/examples/quickGamepad/qml/xboxControllerButtonX.png Binary files differnew file mode 100644 index 0000000..8d29281 --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerButtonX.png diff --git a/examples/quickGamepad/qml/xboxControllerButtonY.png b/examples/quickGamepad/qml/xboxControllerButtonY.png Binary files differnew file mode 100644 index 0000000..465ac48 --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerButtonY.png diff --git a/examples/quickGamepad/qml/xboxControllerDPad.png b/examples/quickGamepad/qml/xboxControllerDPad.png Binary files differnew file mode 100644 index 0000000..efaeb16 --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerDPad.png diff --git a/examples/quickGamepad/qml/xboxControllerLeftShoulder.png b/examples/quickGamepad/qml/xboxControllerLeftShoulder.png Binary files differnew file mode 100644 index 0000000..9b084df --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerLeftShoulder.png diff --git a/examples/quickGamepad/qml/xboxControllerLeftThumbstick.png b/examples/quickGamepad/qml/xboxControllerLeftThumbstick.png Binary files differnew file mode 100644 index 0000000..08fbaa2 --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerLeftThumbstick.png diff --git a/examples/quickGamepad/qml/xboxControllerLeftTrigger.png b/examples/quickGamepad/qml/xboxControllerLeftTrigger.png Binary files differnew file mode 100644 index 0000000..1fd7324 --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerLeftTrigger.png diff --git a/examples/quickGamepad/qml/xboxControllerRightShoulder.png b/examples/quickGamepad/qml/xboxControllerRightShoulder.png Binary files differnew file mode 100644 index 0000000..a22c8ca --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerRightShoulder.png diff --git a/examples/quickGamepad/qml/xboxControllerRightThumbstick.png b/examples/quickGamepad/qml/xboxControllerRightThumbstick.png Binary files differnew file mode 100644 index 0000000..ab95ef5 --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerRightThumbstick.png diff --git a/examples/quickGamepad/qml/xboxControllerRightTrigger.png b/examples/quickGamepad/qml/xboxControllerRightTrigger.png Binary files differnew file mode 100644 index 0000000..717f7ab --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerRightTrigger.png diff --git a/examples/quickGamepad/qml/xboxControllerStart.png b/examples/quickGamepad/qml/xboxControllerStart.png Binary files differnew file mode 100644 index 0000000..709459e --- /dev/null +++ b/examples/quickGamepad/qml/xboxControllerStart.png diff --git a/examples/quickGamepad/quickGamepad.pro b/examples/quickGamepad/quickGamepad.pro new file mode 100644 index 0000000..1cdc565 --- /dev/null +++ b/examples/quickGamepad/quickGamepad.pro @@ -0,0 +1,13 @@ +TEMPLATE = app + +QT += qml quick widgets + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) diff --git a/examples/quickGamepad/quickGamepad64.png b/examples/quickGamepad/quickGamepad64.png Binary files differnew file mode 100644 index 0000000..707d5c4 --- /dev/null +++ b/examples/quickGamepad/quickGamepad64.png diff --git a/examples/quickGamepad/quickGamepad80.png b/examples/quickGamepad/quickGamepad80.png Binary files differnew file mode 100644 index 0000000..6ad8096 --- /dev/null +++ b/examples/quickGamepad/quickGamepad80.png diff --git a/examples/simple/gamepadmonitor.cpp b/examples/simple/gamepadmonitor.cpp new file mode 100644 index 0000000..4883da3 --- /dev/null +++ b/examples/simple/gamepadmonitor.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 "gamepadmonitor.h" +#include <QtGamepad/QGamepad> + +#include <QDebug> + +GamepadMonitor::GamepadMonitor(QObject *parent) + : QObject(parent) + , m_gamepad(0) +{ + m_gamepad = new QGamepad(0, this); + connect(m_gamepad, SIGNAL(buttonL2Changed(double)), this, SLOT(printStatusL2())); + connect(m_gamepad, SIGNAL(buttonR2Changed(double)), this, SLOT(printStatusR2())); +} + +GamepadMonitor::~GamepadMonitor() +{ + delete m_gamepad; +} + +void GamepadMonitor::printStatusL2() +{ + qDebug() << "L2: " << m_gamepad->buttonL2(); +} + +void GamepadMonitor::printStatusR2() +{ + qDebug() << "R2: " << m_gamepad->buttonR2(); +} diff --git a/examples/simple/gamepadmonitor.h b/examples/simple/gamepadmonitor.h new file mode 100644 index 0000000..103d8b4 --- /dev/null +++ b/examples/simple/gamepadmonitor.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 GAMEPADMONITOR_H +#define GAMEPADMONITOR_H + +#include <QtCore/QObject> +#include <QtCore/QTimer> + +class QGamepad; + +class GamepadMonitor : public QObject +{ + Q_OBJECT +public: + explicit GamepadMonitor(QObject *parent = 0); + ~GamepadMonitor(); + +public slots: + void printStatusL2(); + void printStatusR2(); + +private: + QGamepad *m_gamepad; +}; + +#endif // GAMEPADMONITOR_H diff --git a/examples/simple/main.cpp b/examples/simple/main.cpp new file mode 100644 index 0000000..3bb4818 --- /dev/null +++ b/examples/simple/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Gamepad module +** +** $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 The Qt Company Ltd 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 <QtCore/QCoreApplication> +#include "gamepadmonitor.h" + +int main(int argc, char **argv) +{ + QCoreApplication application(argc, argv); + + GamepadMonitor monitor; + + return application.exec(); +} diff --git a/examples/simple/simple.pro b/examples/simple/simple.pro new file mode 100644 index 0000000..a9b341f --- /dev/null +++ b/examples/simple/simple.pro @@ -0,0 +1,7 @@ +QT += gamepad + +SOURCES = main.cpp \ + gamepadmonitor.cpp + +HEADERS += \ + gamepadmonitor.h diff --git a/qtgamepad.pro b/qtgamepad.pro new file mode 100644 index 0000000..99a88ff --- /dev/null +++ b/qtgamepad.pro @@ -0,0 +1,5 @@ +load(configure) + +qtCompileTest(sdl) + +load(qt_parts) diff --git a/src/gamepad/doc/qtgamepad.qdocconf b/src/gamepad/doc/qtgamepad.qdocconf new file mode 100644 index 0000000..9aa005f --- /dev/null +++ b/src/gamepad/doc/qtgamepad.qdocconf @@ -0,0 +1,65 @@ +include($QT_INSTALL_DOCS/global/macros.qdocconf) +include($QT_INSTALL_DOCS/global/qt-cpp-defines.qdocconf) +include($QT_INSTALL_DOCS/global/compat.qdocconf) +include($QT_INSTALL_DOCS/global/fileextensions.qdocconf) +include($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf) + +project = QtGamepad +description = Qt Gamepad Reference Documentation +url = http://doc.qt.digia.com/QtGamepad/ +version = 1.0 + +qhp.projects = QtGamepad + +qhp.QtGamepad.file = qtgamepad.qhp +qhp.QtGamepad.namespace = com.digia.qtgamepad.1.0 +qhp.QtGamepad.virtualFolder = qtgamepad +qhp.QtGamepad.indexTitle = Qt Gamepad +qhp.QtGamepad.indexRoot = +qhp.QtGamepad.filterAttributes = qtgamepad 1.0 qtrefdoc +qhp.QtGamepad.customFilters.Qt.name = QtGamepad 1.0 +qhp.QtGamepad.customFilters.Qt.filterAttributes = qtgamepad 1.0 + +qhp.QtGamepad.subprojects = qmltypes classes examples +qhp.QtGamepad.subprojects.qmltypes.title = QML Types +qhp.QtGamepad.subprojects.qmltypes.indexTitle = Qt Gamepad QML Types +qhp.QtGamepad.subprojects.qmltypes.selectors = fake:qmlclass +qhp.QtGamepad.subprojects.qmltypes.sortPages = true +qhp.QtGamepad.subprojects.classes.title = C++ Classes +qhp.QtGamepad.subprojects.classes.indexTitle = Qt Gamepad C++ Classes +qhp.QtGamepad.subprojects.classes.selectors = class fake:headerfile +qhp.QtGamepad.subprojects.classes.sortPages = true +qhp.QtGamepad.subprojects.examples.title = Examples +qhp.QtGamepad.subprojects.examples.indexTitle = Qt Gamepad Examples +qhp.QtGamepad.subprojects.examples.selectors = fake:example + +HTML.footer = \ + "<div class=\"footer\">\n" \ + " <p>\n" \ + " <acronym title=\"Copyright\">©</acronym> 2014 Digia. Qt and Qt logos are\n" \ + " trademarks of of Digia Corporation in Finland and/or other countries worldwide.\n" \ + " </p>\n" \ + " All other trademarks are property of their respective owners.\n" \ + " <br />\n" \ + " <p>\n" \ + " Licensees holding valid Qt Enterprise licenses may use this document in accordance\n" \ + " with the Qt Enterprise License Agreement provided with the Software or,\n" \ + " alternatively, in accordance with the terms contained in a written agreement\n" \ + " between you and Digia.\n" \ + " </p>\n" \ + "</div>\n" + +indexes += $QT_INSTALL_DOCS/qtqml/qtqml.index \ + $QT_INSTALL_DOCS/qtquick/qtquick.index \ + $QT_INSTALL_DOCS/qtdoc/qtdoc.index \ + $QT_INSTALL_DOCS/qtquickcontrols/qtquickcontrols.index + +headerdirs += ../ +sourcedirs += ../ +exampledirs += ../../../examples/ +imagedirs += images + +navigation.landingpage = "Qt Gamepad" +navigation.qmltypespage = "Qt Gamepad QML Types" +navigation.cppclassespage = "Qt Gamepad C++ Classes" +buildversion = "Qt Gamepad 1.0" diff --git a/src/gamepad/doc/src/qtgamepad-cpp.qdoc b/src/gamepad/doc/src/qtgamepad-cpp.qdoc new file mode 100644 index 0000000..9168584 --- /dev/null +++ b/src/gamepad/doc/src/qtgamepad-cpp.qdoc @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Gamepad Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \module QtGamepad + \title Qt Gamepad C++ Classes + \ingroup modules + + \brief Provides C++ classes for using Gamepad hardware. + + To include the definitions of the module's classes, use the following directive: + + \code + #include <QtGamepad> + \endcode + + To link against the module, add this line to your \l qmake \c .pro file: + + \code + QT += gamepad + \endcode + + For more information about using these classes in your application, + see the \l{Qt Gamepad} documentation. +*/ diff --git a/src/gamepad/doc/src/qtgamepad-examples.qdoc b/src/gamepad/doc/src/qtgamepad-examples.qdoc new file mode 100644 index 0000000..bab880e --- /dev/null +++ b/src/gamepad/doc/src/qtgamepad-examples.qdoc @@ -0,0 +1,29 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Gamepad Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group qtgamepad-examples + \title Qt Gamepad Examples + \brief Examples for the Qt Gamepad module + + These are the Qt Gamepad examples. + +*/ + diff --git a/src/gamepad/doc/src/qtgamepad-overview.qdoc b/src/gamepad/doc/src/qtgamepad-overview.qdoc new file mode 100644 index 0000000..5a3a741 --- /dev/null +++ b/src/gamepad/doc/src/qtgamepad-overview.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Gamepad Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page index.html + \title Qt Gamepad + \brief A cross-platform library to facilitate the use of gamepad hardware in Qt and Qt Quick applications + + Qt Gamepad is an add-on library that enables Qt applications to support + the use of gamepad hardware. + + \section1 API Reference + + \list + \li \l{Qt Gamepad QML Types} + \li \l{Qt Gamepad C++ Classes} + \endlist + +*/ diff --git a/src/gamepad/doc/src/qtgamepad-qmltypes.qdoc b/src/gamepad/doc/src/qtgamepad-qmltypes.qdoc new file mode 100644 index 0000000..0e92f31 --- /dev/null +++ b/src/gamepad/doc/src/qtgamepad-qmltypes.qdoc @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Gamepad Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmlmodule QtGamepad 1.0 + \title Qt Gamepad QML Types + \ingroup qmlmodules + \brief Provides QML types for using gamepad hardware. + + The Qt Gamepad module provides QML types that can be used to access the + state of gamepad hardware that may be available on a system. + + The QML types can be imported into your application using the following + import statement: + + \code + import QtGamepad 1.0 + \endcode + + To link against the module, add this line to your \l qmake \c .pro file: + + \code + QT += gamepad + \endcode + + For more information about using these types in your application, + see the \l{Qt Gamepad} documentation. +*/ diff --git a/src/gamepad/gamepad.pro b/src/gamepad/gamepad.pro new file mode 100644 index 0000000..53c1f3d --- /dev/null +++ b/src/gamepad/gamepad.pro @@ -0,0 +1,27 @@ +TARGET = QtGamepad +QT = core-private core gui + +MODULE_PLUGIN_TYPES = gamepads + +load(qt_module) + +DEFINES += QT_BUILD_GAMEPAD_LIB + +QMAKE_DOCS = $$PWD/doc/qtgamepad.qdocconf + +HEADERS += \ + qtgamepadglobal.h \ + qgamepadmanager.h \ + qgamepad.h \ + qgamepadbackend_p.h \ + qgamepadbackendfactory_p.h \ + qgamepadkeynavigation.h \ + qgamepadbackendplugin_p.h +SOURCES += \ + qgamepadmanager.cpp \ + qgamepad.cpp \ + qgamepadbackend.cpp \ + qgamepadbackendfactory.cpp \ + qgamepadkeynavigation.cpp \ + qgamepadbackendplugin.cpp + diff --git a/src/gamepad/qgamepad.cpp b/src/gamepad/qgamepad.cpp new file mode 100644 index 0000000..9c3b73e --- /dev/null +++ b/src/gamepad/qgamepad.cpp @@ -0,0 +1,600 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgamepad.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QGamepad + \inmodule QtGamepad + \brief A gamepad device connected to a system + + QGamepad is used to access the current state of gamepad hardware connected + to a system. + */ + +/*! + * \brief Constructs a QGamepad for device at \a index. + * \param index is the number of the gamepad you wish to see the state of + * \param parent + */ +QGamepad::QGamepad(int index, QObject *parent) + : QObject(parent) + , m_index(index) + , m_connected(false) + , m_axisLeftX(0.0) + , m_axisLeftY(0.0) + , m_axisRightX(0.0) + , m_axisRightY(0.0) + , m_buttonA(false) + , m_buttonB(false) + , m_buttonX(false) + , m_buttonY(false) + , m_buttonL1(false) + , m_buttonR1(false) + , m_buttonL2(0.0) + , m_buttonR2(0.0) + , m_buttonSelect(false) + , m_buttonStart(false) + , m_buttonL3(false) + , m_buttonR3(false) + , m_buttonUp(false) + , m_buttonDown(false) + , m_buttonLeft(false) + , m_buttonRight(false) + , m_buttonGuide(false) +{ + m_gamepadManager = QGamepadManager::instance(); + connect(m_gamepadManager, SIGNAL(gamepadConnected(int)), this, SLOT(handleGamepadConnected(int))); + connect(m_gamepadManager, SIGNAL(gamepadDisconnected(int)), this, SLOT(handleGamepadDisconnected(int))); + connect(m_gamepadManager, SIGNAL(gamepadAxisEvent(int,QGamepadManager::GamepadAxis,double)), this, SLOT(handleGamepadAxisEvent(int,QGamepadManager::GamepadAxis,double))); + connect(m_gamepadManager, SIGNAL(gamepadButtonPressEvent(int,QGamepadManager::GamepadButton,double)), this, SLOT(handleGamepadButtonPressEvent(int,QGamepadManager::GamepadButton,double))); + connect(m_gamepadManager, SIGNAL(gamepadButtonReleaseEvent(int,QGamepadManager::GamepadButton)), this, SLOT(handleGamepadButtonReleaseEvent(int,QGamepadManager::GamepadButton))); + + setConnected(m_gamepadManager->isGamepadConnected(m_index)); +} + +/*! + * \brief Destroys the QGamepad. + */ +QGamepad::~QGamepad() +{ +} + +/*! + * \property QGamepad::index + * + * This property holds the index of the gamepad device. It is possible for there to be + * multiple gamepad devices connected at any given time, so setting this property defines + * which gamepad to use. + * + */ +int QGamepad::index() const +{ + return m_index; +} + +/*! + * \property QGamepad::isConnected + * + * This property holds the connectivity state of the gamepad device. If a gamepad is connected + * this property will be true, otherwise false. + */ + +bool QGamepad::isConnected() const +{ + return m_connected; +} + +/*! + * \property QGamepad::name + * + * This property holds the reported name of the gamepad if one is available. + */ +QString QGamepad::name() const +{ + return m_name; +} + +/*! + * \property QGamepad::axisLeftX + * + * This property holds the value of the left thumbstick's X axis. + * The range of axis values are from -1.0 to 1.0 + */ +double QGamepad::axisLeftX() const +{ + return m_axisLeftX; +} + +/*! + * \property QGamepad::axisLeftY + * + * This property holds the value of the left thumbstick's Y axis. + * The range of axis values are from -1.0 to 1.0 + */ +double QGamepad::axisLeftY() const +{ + return m_axisLeftY; +} + +/*! + * \property QGamepad::axisRightX + * + * This property holds the value of the right thumbstick's X axis. + * The range of axis values are from -1.0 to 1.0 + */ +double QGamepad::axisRightX() const +{ + return m_axisRightX; +} + +/*! + * \property QGamepad::axisRightY + * + * This property holds the value of the right thumbstick's Y axis. + * The range of axis values are from -1.0 to 1.0 + */ +double QGamepad::axisRightY() const +{ + return m_axisRightY; +} + +/*! + * \property QGamepad::buttonA + * + * This property holds the state of the A button. True when pressed, false when not + * pressed. + */ +bool QGamepad::buttonA() const +{ + return m_buttonA; +} + +/*! + * \property QGamepad::buttonB + * + * This property holds the state of the B button. True when pressed, false when not + * pressed. + */ +bool QGamepad::buttonB() const +{ + return m_buttonB; +} + +/*! + * \property QGamepad::buttonX + * + * This property holds the state of the X button. True when pressed, false when not + * pressed. + */ +bool QGamepad::buttonX() const +{ + return m_buttonX; +} + +/*! + * \property QGamepad::buttonY + * + * This property holds the state of the Y button. True when pressed, false when not + * pressed. + */ +bool QGamepad::buttonY() const +{ + return m_buttonY; +} + +/*! + * \property QGamepad::buttonL1 + * + * This property holds the state of the left shoulder button. + * True when pressed, false when not pressed. + */ +bool QGamepad::buttonL1() const +{ + return m_buttonL1; +} + +/*! + * \property QGamepad::buttonR1 + * + * This property holds the state of the right shoulder button. + * True when pressed, false when not pressed. + */ +bool QGamepad::buttonR1() const +{ + return m_buttonR1; +} + +/*! + * \property QGamepad::buttonL2 + * + * This property holds the value of the left trigger button. + * This trigger value ranges from 0.0 when not pressed to 1.0 + * when pressed completely. + */ +double QGamepad::buttonL2() const +{ + return m_buttonL2; +} + +/*! + * \property QGamepad::buttonR2 + * + * This property holds the value of the right trigger button. + * This trigger value ranges from 0.0 when not pressed to 1.0 + * when pressed completely. + */ +double QGamepad::buttonR2() const +{ + return m_buttonR2; +} + +/*! + * \property QGamepad::buttonSelect + * + * This property holds the state of the Select button. True when pressed, false when not + * pressed. This button can sometimes be labled as the Back button on some gamepads. + */ +bool QGamepad::buttonSelect() const +{ + return m_buttonSelect; +} + +/*! + * \property QGamepad::buttonStart + * + * This property holds the state of the Start button. True when pressed, false when not + * pressed. This button can sometimes be labled as the Forward button on some gamepads. + */ +bool QGamepad::buttonStart() const +{ + return m_buttonStart; +} + +/*! + * \property QGamepad::buttonL3 + * + * This property holds the state of the left stick button. True when pressed, false when not + * pressed. This button is usually triggered by pressing the left joystick itself. + */ +bool QGamepad::buttonL3() const +{ + return m_buttonL3; +} + +/*! + * \property QGamepad::buttonR3 + * + * This property holds the state of the right stick button. True when pressed, false when not + * pressed. This button is usually triggered by pressing the right joystick itself. + */ +bool QGamepad::buttonR3() const +{ + return m_buttonR3; +} + +/*! + * \property QGamepad::buttonUp + * + * This property holds the state of the direction pad up button. + * True when pressed, false when not pressed. + */ +bool QGamepad::buttonUp() const +{ + return m_buttonUp; +} + +/*! + * \property QGamepad::buttonDown + * + * This property holds the state of the direction pad down button. + * True when pressed, false when not pressed. + */ +bool QGamepad::buttonDown() const +{ + return m_buttonDown; +} + +/*! + * \property QGamepad::buttonLeft + * + * This property holds the state of the direction pad left button. + * True when pressed, false when not pressed. + */ +bool QGamepad::buttonLeft() const +{ + return m_buttonLeft; +} + +/*! + * \property QGamepad::buttonRight + * + * This property holds the state of the direction pad right button. + * True when pressed, false when not pressed. + */ +bool QGamepad::buttonRight() const +{ + return m_buttonRight; +} + +/*! + * \property QGamepad::buttonGuide + * + * This property holds the state of the guide button. + * True when pressed, false when not pressed. + * This button is typically the one in the center of the gamepad with a logo. + * Some gamepads will not have a guide button. + */ +bool QGamepad::buttonGuide() const +{ + return m_buttonGuide; +} + +void QGamepad::setIndex(int number) +{ + if (m_index != number) { + m_index = number; + emit indexChanged(number); + setConnected(m_gamepadManager->isGamepadConnected(m_index)); + } +} + +void QGamepad::setConnected(bool isConnected) +{ + if (m_connected != isConnected) { + m_connected = isConnected; + emit connectedChanged(m_connected); + } +} + +/*! + * \internal + */\ +void QGamepad::handleGamepadConnected(int index) +{ + if (index == m_index) { + setConnected(true); + } +} + +/*! + * \internal + */\ +void QGamepad::handleGamepadDisconnected(int index) +{ + if (index == m_index) { + setConnected(false); + } +} + +/*! + * \internal + */\ +void QGamepad::handleGamepadAxisEvent(int index, QGamepadManager::GamepadAxis axis, double value) +{ + if (index != m_index) + return; + + switch (axis) { + case QGamepadManager::AxisLeftX: + m_axisLeftX = value; + emit axisLeftXChanged(value); + break; + case QGamepadManager::AxisLeftY: + m_axisLeftY = value; + emit axisLeftYChanged(value); + break; + case QGamepadManager::AxisRightX: + m_axisRightX = value; + emit axisRightXChanged(value); + break; + case QGamepadManager::AxisRightY: + m_axisRightY = value; + emit axisRightYChanged(value); + break; + default: + break; + } +} + +/*! + * \internal + */\ +void QGamepad::handleGamepadButtonPressEvent(int index, QGamepadManager::GamepadButton button, double value) +{ + if (index != m_index) + return; + + switch (button) { + case QGamepadManager::ButtonA: + m_buttonA = true; + emit buttonAChanged(true); + break; + case QGamepadManager::ButtonB: + m_buttonB = true; + emit buttonBChanged(true); + break; + case QGamepadManager::ButtonX: + m_buttonX = true; + emit buttonXChanged(true); + break; + case QGamepadManager::ButtonY: + m_buttonY = true; + emit buttonYChanged(true); + break; + case QGamepadManager::ButtonL1: + m_buttonL1 = true; + emit buttonL1Changed(true); + break; + case QGamepadManager::ButtonR1: + m_buttonR1 = true; + emit buttonR1Changed(true); + break; + case QGamepadManager::ButtonL2: + m_buttonL2 = value; + emit buttonL2Changed(value); + break; + case QGamepadManager::ButtonR2: + m_buttonR2 = value; + emit buttonR2Changed(value); + break; + case QGamepadManager::ButtonL3: + m_buttonL3 = true; + emit buttonL3Changed(true); + break; + case QGamepadManager::ButtonR3: + m_buttonR3 = true; + emit buttonR3Changed(true); + break; + case QGamepadManager::ButtonSelect: + m_buttonSelect = true; + emit buttonSelectChanged(true); + break; + case QGamepadManager::ButtonStart: + m_buttonStart = true; + emit buttonStartChanged(true); + break; + case QGamepadManager::ButtonUp: + m_buttonUp = true; + emit buttonUpChanged(true); + break; + case QGamepadManager::ButtonDown: + m_buttonDown = true; + emit buttonDownChanged(true); + break; + case QGamepadManager::ButtonLeft: + m_buttonLeft = true; + emit buttonLeftChanged(true); + break; + case QGamepadManager::ButtonRight: + m_buttonRight = true; + emit buttonRightChanged(true); + break; + case QGamepadManager::ButtonGuide: + m_buttonGuide = true; + emit buttonGuideChanged(true); + break; + default: + break; + } + +} + +/*! + * \internal + */\ +void QGamepad::handleGamepadButtonReleaseEvent(int index, QGamepadManager::GamepadButton button) +{ + if (index != m_index) + return; + + switch (button) { + case QGamepadManager::ButtonA: + m_buttonA = false; + emit buttonAChanged(false); + break; + case QGamepadManager::ButtonB: + m_buttonB = false; + emit buttonBChanged(false); + break; + case QGamepadManager::ButtonX: + m_buttonX = false; + emit buttonXChanged(false); + break; + case QGamepadManager::ButtonY: + m_buttonY = false; + emit buttonYChanged(false); + break; + case QGamepadManager::ButtonL1: + m_buttonL1 = false; + emit buttonL1Changed(false); + break; + case QGamepadManager::ButtonR1: + m_buttonR1 = false; + emit buttonR1Changed(false); + break; + case QGamepadManager::ButtonL2: + m_buttonL2 = 0.0; + emit buttonL2Changed(0.0); + break; + case QGamepadManager::ButtonR2: + m_buttonR2 = 0.0; + emit buttonR2Changed(0.0); + break; + case QGamepadManager::ButtonL3: + m_buttonL3 = false; + emit buttonL3Changed(false); + break; + case QGamepadManager::ButtonR3: + m_buttonR3 = false; + emit buttonR3Changed(false); + break; + case QGamepadManager::ButtonSelect: + m_buttonSelect = false; + emit buttonSelectChanged(false); + break; + case QGamepadManager::ButtonStart: + m_buttonStart = false; + emit buttonStartChanged(false); + break; + case QGamepadManager::ButtonUp: + m_buttonUp = false; + emit buttonUpChanged(false); + break; + case QGamepadManager::ButtonDown: + m_buttonDown = false; + emit buttonDownChanged(false); + break; + case QGamepadManager::ButtonLeft: + m_buttonLeft = false; + emit buttonLeftChanged(false); + break; + case QGamepadManager::ButtonRight: + m_buttonRight = false; + emit buttonRightChanged(false); + break; + case QGamepadManager::ButtonGuide: + m_buttonGuide = false; + emit buttonGuideChanged(false); + break; + default: + break; + } +} + +QT_END_NAMESPACE diff --git a/src/gamepad/qgamepad.h b/src/gamepad/qgamepad.h new file mode 100644 index 0000000..e561ad3 --- /dev/null +++ b/src/gamepad/qgamepad.h @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGAMEPAD_H +#define QGAMEPAD_H + +#include <QtCore/QObject> +#include <QtGamepad/qtgamepadglobal.h> +#include <QtGamepad/QGamepadManager> + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +class Q_GAMEPAD_EXPORT QGamepad : public QObject +{ + Q_OBJECT + Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged) + Q_PROPERTY(bool connected READ isConnected NOTIFY connectedChanged) + Q_PROPERTY(QString name READ name NOTIFY nameChanged) + Q_PROPERTY(double axisLeftX READ axisLeftX NOTIFY axisLeftXChanged) + Q_PROPERTY(double axisLeftY READ axisLeftY NOTIFY axisLeftYChanged) + Q_PROPERTY(double axisRightX READ axisRightX NOTIFY axisRightXChanged) + Q_PROPERTY(double axisRightY READ axisRightY NOTIFY axisRightYChanged) + Q_PROPERTY(bool buttonA READ buttonA NOTIFY buttonAChanged) + Q_PROPERTY(bool buttonB READ buttonB NOTIFY buttonBChanged) + Q_PROPERTY(bool buttonX READ buttonX NOTIFY buttonXChanged) + Q_PROPERTY(bool buttonY READ buttonY NOTIFY buttonYChanged) + Q_PROPERTY(bool buttonL1 READ buttonL1 NOTIFY buttonL1Changed) + Q_PROPERTY(bool buttonR1 READ buttonR1 NOTIFY buttonR1Changed) + Q_PROPERTY(double buttonL2 READ buttonL2 NOTIFY buttonL2Changed) + Q_PROPERTY(double buttonR2 READ buttonR2 NOTIFY buttonR2Changed) + Q_PROPERTY(bool buttonSelect READ buttonSelect NOTIFY buttonSelectChanged) + Q_PROPERTY(bool buttonStart READ buttonStart NOTIFY buttonStartChanged) + Q_PROPERTY(bool buttonL3 READ buttonL3 NOTIFY buttonL3Changed) + Q_PROPERTY(bool buttonR3 READ buttonR3 NOTIFY buttonR3Changed) + Q_PROPERTY(bool buttonUp READ buttonUp NOTIFY buttonUpChanged) + Q_PROPERTY(bool buttonDown READ buttonDown NOTIFY buttonDownChanged) + Q_PROPERTY(bool buttonLeft READ buttonLeft NOTIFY buttonLeftChanged) + Q_PROPERTY(bool buttonRight READ buttonRight NOTIFY buttonRightChanged) + Q_PROPERTY(bool buttonGuide READ buttonGuide NOTIFY buttonGuideChanged) +public: + explicit QGamepad(int index = 0, QObject *parent = 0); + ~QGamepad(); + + int index() const; + + bool isConnected() const; + + QString name() const; + + double axisLeftX() const; + double axisLeftY() const; + double axisRightX() const; + double axisRightY() const; + bool buttonA() const; + bool buttonB() const; + bool buttonX() const; + bool buttonY() const; + bool buttonL1() const; + bool buttonR1() const; + double buttonL2() const; + double buttonR2() const; + bool buttonSelect() const; + bool buttonStart() const; + bool buttonL3() const; + bool buttonR3() const; + bool buttonUp() const; + bool buttonDown() const; + bool buttonLeft() const; + bool buttonRight() const; + bool buttonGuide() const; + +signals: + + void indexChanged(int value); + void connectedChanged(bool value); + void nameChanged(QString value); + void axisLeftXChanged(double value); + void axisLeftYChanged(double value); + void axisRightXChanged(double value); + void axisRightYChanged(double value); + void buttonAChanged(bool value); + void buttonBChanged(bool value); + void buttonXChanged(bool value); + void buttonYChanged(bool value); + void buttonL1Changed(bool value); + void buttonR1Changed(bool value); + void buttonL2Changed(double value); + void buttonR2Changed(double value); + void buttonSelectChanged(bool value); + void buttonStartChanged(bool value); + void buttonL3Changed(bool value); + void buttonR3Changed(bool value); + void buttonUpChanged(bool value); + void buttonDownChanged(bool value); + void buttonLeftChanged(bool value); + void buttonRightChanged(bool value); + void buttonGuideChanged(bool value); + +public slots: + + void setIndex(int number); + +private slots: + void setConnected(bool isConnected); + + void handleGamepadConnected(int index); + void handleGamepadDisconnected(int index); + void handleGamepadAxisEvent(int index, QGamepadManager::GamepadAxis axis, double value); + void handleGamepadButtonPressEvent(int index, QGamepadManager::GamepadButton button, double value); + void handleGamepadButtonReleaseEvent(int index, QGamepadManager::GamepadButton button); + +private: + + QGamepadManager *m_gamepadManager; + + int m_index; + bool m_connected; + QString m_name; + double m_axisLeftX; + double m_axisLeftY; + double m_axisRightX; + double m_axisRightY; + bool m_buttonA; + bool m_buttonB; + bool m_buttonX; + bool m_buttonY; + bool m_buttonL1; + bool m_buttonR1; + double m_buttonL2; + double m_buttonR2; + bool m_buttonSelect; + bool m_buttonStart; + bool m_buttonL3; + bool m_buttonR3; + bool m_buttonUp; + bool m_buttonDown; + bool m_buttonLeft; + bool m_buttonRight; + bool m_buttonGuide; +}; + +Q_DECLARE_METATYPE(QGamepad*) + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QGAMEPAD_H diff --git a/src/gamepad/qgamepadbackend.cpp b/src/gamepad/qgamepadbackend.cpp new file mode 100644 index 0000000..812a940 --- /dev/null +++ b/src/gamepad/qgamepadbackend.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgamepadbackend_p.h" + +QT_BEGIN_NAMESPACE + +QGamepadBackend::QGamepadBackend(QObject *parent) : + QObject(parent) +{ +} + +bool QGamepadBackend::start() +{ + return true; +} + +void QGamepadBackend::stop() +{ + +} + +QT_END_NAMESPACE diff --git a/src/gamepad/qgamepadbackend_p.h b/src/gamepad/qgamepadbackend_p.h new file mode 100644 index 0000000..cc6453d --- /dev/null +++ b/src/gamepad/qgamepadbackend_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGAMEPADBACKEND_H +#define QGAMEPADBACKEND_H + +#include <QtGamepad/qtgamepadglobal.h> + +#include <QtCore/QObject> +#include <QtGamepad/QGamepadManager> + +QT_BEGIN_NAMESPACE + +class Q_GAMEPAD_EXPORT QGamepadBackend : public QObject +{ + Q_OBJECT +public: + explicit QGamepadBackend(QObject *parent = 0); + +public slots: + virtual bool start(); + virtual void stop(); + +signals: + void gamepadAdded(int index); + void gamepadRemoved(int index); + void gamepadAxisMoved(int index, QGamepadManager::GamepadAxis axis, double value); + void gamepadButtonPressed(int index, QGamepadManager::GamepadButton button, double value); + void gamepadButtonReleased(int index, QGamepadManager::GamepadButton button); +}; + +QT_END_NAMESPACE + +#endif // QGAMEPADBACKEND_H diff --git a/src/gamepad/qgamepadbackendfactory.cpp b/src/gamepad/qgamepadbackendfactory.cpp new file mode 100644 index 0000000..0434e4b --- /dev/null +++ b/src/gamepad/qgamepadbackendfactory.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgamepadbackendfactory_p.h" +#include "qgamepadbackendplugin_p.h" +#include "qgamepadbackend_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, (QtGamepadBackendFactoryInterface_iid, QLatin1String("/gamepads"), Qt::CaseInsensitive)) +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, (QtGamepadBackendFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) +#endif + +QStringList QGamepadBackendFactory::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 +} + +QGamepadBackend *QGamepadBackendFactory::create(const QString &name, const QStringList &args, const QString &pluginPath) +{ +#ifndef QT_NO_LIBRARY + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + if (QGamepadBackend *ret = qLoadPlugin1<QGamepadBackend, QGamepadBackendPlugin>(directLoader(), name, args)) + return ret; + } + if (QGamepadBackend *ret = qLoadPlugin1<QGamepadBackend, QGamepadBackendPlugin>(loader(), name, args)) + return ret; +#endif + return 0; +} + +QT_END_NAMESPACE diff --git a/src/gamepad/qgamepadbackendfactory_p.h b/src/gamepad/qgamepadbackendfactory_p.h new file mode 100644 index 0000000..773a14d --- /dev/null +++ b/src/gamepad/qgamepadbackendfactory_p.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGAMEPADBACKENDFACTORY_P_H +#define QGAMEPADBACKENDFACTORY_P_H + +#include <QtGamepad/qtgamepadglobal.h> +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE + +class QGamepadBackend; + +class Q_GAMEPAD_EXPORT QGamepadBackendFactory +{ +public: + static QStringList keys(const QString &pluginPath = QString()); + static QGamepadBackend *create(const QString &name, const QStringList &args, const QString &pluginPath = QString()); +}; + +QT_END_NAMESPACE + +#endif // QGAMEPADBACKENDFACTORY_P_H diff --git a/src/gamepad/qgamepadbackendplugin.cpp b/src/gamepad/qgamepadbackendplugin.cpp new file mode 100644 index 0000000..a06a287 --- /dev/null +++ b/src/gamepad/qgamepadbackendplugin.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgamepadbackendplugin_p.h" + +QT_BEGIN_NAMESPACE + +QGamepadBackendPlugin::QGamepadBackendPlugin(QObject *parent) : QObject(parent) +{ + +} + +QGamepadBackendPlugin::~QGamepadBackendPlugin() +{ + +} + +QT_END_NAMESPACE + diff --git a/src/gamepad/qgamepadbackendplugin_p.h b/src/gamepad/qgamepadbackendplugin_p.h new file mode 100644 index 0000000..4147972 --- /dev/null +++ b/src/gamepad/qgamepadbackendplugin_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGAMEPADBACKENDPLUGIN_H +#define QGAMEPADBACKENDPLUGIN_H + +#include <QtGamepad/qtgamepadglobal.h> + +#include <QtCore/qplugin.h> +#include <QtCore/qfactoryinterface.h> + +QT_BEGIN_NAMESPACE + +class QGamepadBackend; + +#define QtGamepadBackendFactoryInterface_iid "com.bsquask.Qt.Gamepad.QtGamepadBackendFactoryInterface.5.5" + +class Q_GAMEPAD_EXPORT QGamepadBackendPlugin : public QObject +{ + Q_OBJECT +public: + explicit QGamepadBackendPlugin(QObject *parent = 0); + ~QGamepadBackendPlugin(); + + virtual QGamepadBackend *create(const QString &key, const QStringList ¶mList) = 0; + +signals: + +public slots: +}; + +QT_END_NAMESPACE + +#endif // QGAMEPADBACKENDPLUGIN_H diff --git a/src/gamepad/qgamepadkeynavigation.cpp b/src/gamepad/qgamepadkeynavigation.cpp new file mode 100644 index 0000000..f6f1201 --- /dev/null +++ b/src/gamepad/qgamepadkeynavigation.cpp @@ -0,0 +1,374 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgamepadkeynavigation.h" +#include <QtGui/QKeyEvent> +#include <QtGui/QGuiApplication> +#include <QtGui/QWindow> +#include <QtGamepad/QGamepad> + +QT_BEGIN_NAMESPACE + +QGamepadKeyNavigation::QGamepadKeyNavigation(QObject *parent) + : QObject(parent) + , m_buttonL2Pressed(false) + , m_buttonR2Pressed(false) +{ + m_gamepadManger = QGamepadManager::instance(); + + //Default keymap + m_keyMapping.insert(QGamepadManager::ButtonUp, Qt::Key_Up); + m_keyMapping.insert(QGamepadManager::ButtonDown, Qt::Key_Down); + m_keyMapping.insert(QGamepadManager::ButtonLeft, Qt::Key_Left); + m_keyMapping.insert(QGamepadManager::ButtonRight, Qt::Key_Right); + m_keyMapping.insert(QGamepadManager::ButtonA, Qt::Key_Return); + m_keyMapping.insert(QGamepadManager::ButtonB, Qt::Key_Back); + m_keyMapping.insert(QGamepadManager::ButtonX, Qt::Key_Back); + m_keyMapping.insert(QGamepadManager::ButtonY, Qt::Key_Back); + m_keyMapping.insert(QGamepadManager::ButtonSelect, Qt::Key_Back); + m_keyMapping.insert(QGamepadManager::ButtonStart, Qt::Key_Return); + m_keyMapping.insert(QGamepadManager::ButtonGuide, Qt::Key_Back); + m_keyMapping.insert(QGamepadManager::ButtonL1, Qt::Key_Back); + m_keyMapping.insert(QGamepadManager::ButtonR1, Qt::Key_Forward); + m_keyMapping.insert(QGamepadManager::ButtonL2, Qt::Key_Back); + m_keyMapping.insert(QGamepadManager::ButtonR2, Qt::Key_Forward); + m_keyMapping.insert(QGamepadManager::ButtonL3, Qt::Key_Back); + m_keyMapping.insert(QGamepadManager::ButtonR3, Qt::Key_Forward); + + connect(m_gamepadManger, SIGNAL(gamepadButtonPressEvent(int,QGamepadManager::GamepadButton,double)), + this, SLOT(processGamepadButtonPressEvent(int,QGamepadManager::GamepadButton,double))); + connect(m_gamepadManger, SIGNAL(gamepadButtonReleaseEvent(int,QGamepadManager::GamepadButton)), + this, SLOT(procressGamepadButtonReleaseEvent(int,QGamepadManager::GamepadButton))); +} + +bool QGamepadKeyNavigation::active() const +{ + return m_active; +} + +QGamepad *QGamepadKeyNavigation::gamepad() const +{ + return m_gamepad; +} + +Qt::Key QGamepadKeyNavigation::upKey() const +{ + return m_keyMapping[QGamepadManager::ButtonUp]; +} + +Qt::Key QGamepadKeyNavigation::downKey() const +{ + return m_keyMapping[QGamepadManager::ButtonDown]; +} + +Qt::Key QGamepadKeyNavigation::leftKey() const +{ + return m_keyMapping[QGamepadManager::ButtonLeft]; +} + +Qt::Key QGamepadKeyNavigation::rightKey() const +{ + return m_keyMapping[QGamepadManager::ButtonRight]; +} + +Qt::Key QGamepadKeyNavigation::buttonAKey() const +{ + return m_keyMapping[QGamepadManager::ButtonA]; +} + +Qt::Key QGamepadKeyNavigation::buttonBKey() const +{ + return m_keyMapping[QGamepadManager::ButtonB]; +} + +Qt::Key QGamepadKeyNavigation::buttonXKey() const +{ + return m_keyMapping[QGamepadManager::ButtonX]; +} + +Qt::Key QGamepadKeyNavigation::buttonYKey() const +{ + return m_keyMapping[QGamepadManager::ButtonY]; +} + +Qt::Key QGamepadKeyNavigation::buttonSelectKey() const +{ + return m_keyMapping[QGamepadManager::ButtonSelect]; +} + +Qt::Key QGamepadKeyNavigation::buttonStartKey() const +{ + return m_keyMapping[QGamepadManager::ButtonStart]; +} + +Qt::Key QGamepadKeyNavigation::buttonGuideKey() const +{ + return m_keyMapping[QGamepadManager::ButtonGuide]; +} + +Qt::Key QGamepadKeyNavigation::buttonL1Key() const +{ + return m_keyMapping[QGamepadManager::ButtonL1]; +} + +Qt::Key QGamepadKeyNavigation::buttonR1Key() const +{ + return m_keyMapping[QGamepadManager::ButtonL2]; +} + +Qt::Key QGamepadKeyNavigation::buttonL2Key() const +{ + return m_keyMapping[QGamepadManager::ButtonL2]; +} + +Qt::Key QGamepadKeyNavigation::buttonR2Key() const +{ + return m_keyMapping[QGamepadManager::ButtonL2]; +} + +Qt::Key QGamepadKeyNavigation::buttonL3Key() const +{ + return m_keyMapping[QGamepadManager::ButtonL3]; +} + +Qt::Key QGamepadKeyNavigation::buttonR3Key() const +{ + return m_keyMapping[QGamepadManager::ButtonL3]; +} + +void QGamepadKeyNavigation::setActive(bool isActive) +{ + if (m_active != isActive) { + m_active = isActive; + emit activeChanged(isActive); + } +} + +void QGamepadKeyNavigation::setGamepad(QGamepad *gamepad) +{ + if (m_gamepad != gamepad) { + m_gamepad = gamepad; + emit gamepadChanged(gamepad); + } +} + +void QGamepadKeyNavigation::setUpKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonUp] != key) { + m_keyMapping[QGamepadManager::ButtonUp] = key; + emit upKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setDownKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonDown] != key) { + m_keyMapping[QGamepadManager::ButtonDown] = key; + emit downKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setLeftKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonLeft] != key) { + m_keyMapping[QGamepadManager::ButtonLeft] = key; + emit leftKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setRightKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonRight] != key) { + m_keyMapping[QGamepadManager::ButtonRight] = key; + emit rightKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonAKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonA] != key) { + m_keyMapping[QGamepadManager::ButtonA] = key; + emit buttonAKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonBKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonB] != key) { + m_keyMapping[QGamepadManager::ButtonB] = key; + emit buttonBKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonXKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonX] != key) { + m_keyMapping[QGamepadManager::ButtonX] = key; + emit buttonXKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonYKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonY] != key) { + m_keyMapping[QGamepadManager::ButtonY] = key; + emit buttonYKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonSelectKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonSelect] != key) { + m_keyMapping[QGamepadManager::ButtonSelect] = key; + emit buttonSelectKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonStartKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonStart] != key) { + m_keyMapping[QGamepadManager::ButtonStart] = key; + emit buttonStartKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonGuideKey(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonGuide] != key) { + m_keyMapping[QGamepadManager::ButtonGuide] = key; + emit buttonGuideKeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonL1Key(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonL1] != key) { + m_keyMapping[QGamepadManager::ButtonL1] = key; + emit buttonL1KeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonR1Key(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonR1] != key) { + m_keyMapping[QGamepadManager::ButtonR1] = key; + emit buttonR1KeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonL2Key(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonL2] != key) { + m_keyMapping[QGamepadManager::ButtonL2] = key; + emit buttonL1KeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonR2Key(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonR2] != key) { + m_keyMapping[QGamepadManager::ButtonR2] = key; + emit buttonR1KeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonL3Key(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonL3] != key) { + m_keyMapping[QGamepadManager::ButtonL3] = key; + emit buttonL1KeyChanged(key); + } +} + +void QGamepadKeyNavigation::setButtonR3Key(Qt::Key key) +{ + if (m_keyMapping[QGamepadManager::ButtonR3] != key) { + m_keyMapping[QGamepadManager::ButtonR3] = key; + emit buttonR1KeyChanged(key); + } +} + +void QGamepadKeyNavigation::processGamepadButtonPressEvent(int index, QGamepadManager::GamepadButton button, double value) +{ + Q_UNUSED(value) + + //If a gamepad has been set then, only use the events of that gamepad + if (m_gamepad && m_gamepad->index() != index) + return; + + //Trigger buttons are a special case as they get multiple press events as the value changes + if (button == QGamepadManager::ButtonL2 && m_buttonL2Pressed) + return; + else + m_buttonL2Pressed = true; + if (button == QGamepadManager::ButtonR2 && m_buttonR2Pressed) + return; + else + m_buttonR2Pressed = true; + + QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, m_keyMapping[button], Qt::NoModifier); + sendGeneratedKeyEvent(event); +} + +void QGamepadKeyNavigation::procressGamepadButtonReleaseEvent(int index, QGamepadManager::GamepadButton button) +{ + //If a gamepad has been set then, only use the events of that gamepad + if (m_gamepad && m_gamepad->index() != index) + return; + + //Free the trigger buttons if necessary + if (button == QGamepadManager::ButtonL2) + m_buttonL2Pressed = false; + if (button == QGamepadManager::ButtonR2) + m_buttonR2Pressed = false; + + QKeyEvent *event = new QKeyEvent(QEvent::KeyRelease, m_keyMapping[button], Qt::NoModifier); + sendGeneratedKeyEvent(event); +} + +void QGamepadKeyNavigation::sendGeneratedKeyEvent(QKeyEvent *event) +{ + if (!m_active) { + delete event; + return; + } + const QGuiApplication *app = qApp; + QWindow *focusWindow = app ? app->focusWindow() : 0; + if (focusWindow) + QGuiApplication::sendEvent(focusWindow, event); +} + +QT_END_NAMESPACE diff --git a/src/gamepad/qgamepadkeynavigation.h b/src/gamepad/qgamepadkeynavigation.h new file mode 100644 index 0000000..03ea422 --- /dev/null +++ b/src/gamepad/qgamepadkeynavigation.h @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGAMEPADKEYNAVIGATION_H +#define QGAMEPADKEYNAVIGATION_H + +#include <QtCore/QObject> +#include <QtCore/QMap> +#include <QtGamepad/qtgamepadglobal.h> + +#include <QtGamepad/QGamepadManager> + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +class QKeyEvent; +class QGamepad; +class Q_GAMEPAD_EXPORT QGamepadKeyNavigation : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) + Q_PROPERTY(QGamepad *gamepad READ gamepad WRITE setGamepad NOTIFY gamepadChanged) + Q_PROPERTY(Qt::Key upKey READ upKey WRITE setUpKey NOTIFY upKeyChanged) + Q_PROPERTY(Qt::Key downKey READ downKey WRITE setDownKey NOTIFY downKeyChanged) + Q_PROPERTY(Qt::Key leftKey READ leftKey WRITE setLeftKey NOTIFY leftKeyChanged) + Q_PROPERTY(Qt::Key rightKey READ rightKey WRITE setRightKey NOTIFY rightKeyChanged) + Q_PROPERTY(Qt::Key buttonAKey READ buttonAKey WRITE setButtonAKey NOTIFY buttonAKeyChanged) + Q_PROPERTY(Qt::Key buttonBKey READ buttonBKey WRITE setButtonBKey NOTIFY buttonBKeyChanged) + Q_PROPERTY(Qt::Key buttonXKey READ buttonXKey WRITE setButtonXKey NOTIFY buttonXKeyChanged) + Q_PROPERTY(Qt::Key buttonYKey READ buttonYKey WRITE setButtonYKey NOTIFY buttonYKeyChanged) + Q_PROPERTY(Qt::Key buttonSelectKey READ buttonSelectKey WRITE setButtonSelectKey NOTIFY buttonSelectKeyChanged) + Q_PROPERTY(Qt::Key buttonStartKey READ buttonStartKey WRITE setButtonStartKey NOTIFY buttonStartKeyChanged) + Q_PROPERTY(Qt::Key buttonGuideKey READ buttonGuideKey WRITE setButtonGuideKey NOTIFY buttonGuideKeyChanged) + Q_PROPERTY(Qt::Key buttonL1Key READ buttonL1Key WRITE setButtonL1Key NOTIFY buttonL1KeyChanged) + Q_PROPERTY(Qt::Key buttonR1Key READ buttonR1Key WRITE setButtonR1Key NOTIFY buttonR1KeyChanged) + Q_PROPERTY(Qt::Key buttonL2Key READ buttonL2Key WRITE setButtonL2Key NOTIFY buttonL2KeyChanged) + Q_PROPERTY(Qt::Key buttonR2Key READ buttonR2Key WRITE setButtonR2Key NOTIFY buttonR2KeyChanged) + Q_PROPERTY(Qt::Key buttonL3Key READ buttonL3Key WRITE setButtonL3Key NOTIFY buttonL3KeyChanged) + Q_PROPERTY(Qt::Key buttonR3Key READ buttonR3Key WRITE setButtonR3Key NOTIFY buttonR3KeyChanged) +public: + explicit QGamepadKeyNavigation(QObject *parent = 0); + + bool active() const; + QGamepad *gamepad() const; + + Qt::Key upKey() const; + Qt::Key downKey() const; + Qt::Key leftKey() const; + Qt::Key rightKey() const; + Qt::Key buttonAKey() const; + Qt::Key buttonBKey() const; + Qt::Key buttonXKey() const; + Qt::Key buttonYKey() const; + Qt::Key buttonSelectKey() const; + Qt::Key buttonStartKey() const; + Qt::Key buttonGuideKey() const; + Qt::Key buttonL1Key() const; + Qt::Key buttonR1Key() const; + Qt::Key buttonL2Key() const; + Qt::Key buttonR2Key() const; + Qt::Key buttonL3Key() const; + Qt::Key buttonR3Key() const; + +signals: + void activeChanged(bool isActive); + void gamepadChanged(QGamepad *gamepad); + + void upKeyChanged(Qt::Key key); + void downKeyChanged(Qt::Key key); + void leftKeyChanged(Qt::Key key); + void rightKeyChanged(Qt::Key key); + void buttonAKeyChanged(Qt::Key key); + void buttonBKeyChanged(Qt::Key key); + void buttonXKeyChanged(Qt::Key key); + void buttonYKeyChanged(Qt::Key key); + void buttonSelectKeyChanged(Qt::Key key); + void buttonStartKeyChanged(Qt::Key key); + void buttonGuideKeyChanged(Qt::Key key); + void buttonL1KeyChanged(Qt::Key key); + void buttonR1KeyChanged(Qt::Key key); + void buttonL2KeyChanged(Qt::Key key); + void buttonR2KeyChanged(Qt::Key key); + void buttonL3KeyChanged(Qt::Key key); + void buttonR3KeyChanged(Qt::Key key); + +public slots: + void setActive(bool isActive); + void setGamepad(QGamepad *gamepad); + + void setUpKey(Qt::Key key); + void setDownKey(Qt::Key key); + void setLeftKey(Qt::Key key); + void setRightKey(Qt::Key key); + void setButtonAKey(Qt::Key key); + void setButtonBKey(Qt::Key key); + void setButtonXKey(Qt::Key key); + void setButtonYKey(Qt::Key key); + void setButtonSelectKey(Qt::Key key); + void setButtonStartKey(Qt::Key key); + void setButtonGuideKey(Qt::Key key); + void setButtonL1Key(Qt::Key key); + void setButtonR1Key(Qt::Key key); + void setButtonL2Key(Qt::Key key); + void setButtonR2Key(Qt::Key key); + void setButtonL3Key(Qt::Key key); + void setButtonR3Key(Qt::Key key); + +private slots: + void processGamepadButtonPressEvent(int index, QGamepadManager::GamepadButton button, double value); + void procressGamepadButtonReleaseEvent(int index, QGamepadManager::GamepadButton button); + +private: + void sendGeneratedKeyEvent(QKeyEvent *event); + + bool m_active; + QGamepad *m_gamepad; + QGamepadManager *m_gamepadManger; + bool m_buttonL2Pressed; + bool m_buttonR2Pressed; + QMap<QGamepadManager::GamepadButton, Qt::Key> m_keyMapping; +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QGAMEPADKEYNAVIGATION_H diff --git a/src/gamepad/qgamepadmanager.cpp b/src/gamepad/qgamepadmanager.cpp new file mode 100644 index 0000000..e58298b --- /dev/null +++ b/src/gamepad/qgamepadmanager.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgamepadmanager.h" + +#include "qgamepadbackend_p.h" +#include "qgamepadbackendfactory_p.h" + +#include <QtCore/QLoggingCategory> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(gp, "qt.gamepad") + +QGamepadManager::QGamepadManager() : + QObject(0) +{ + loadBackend(); + + qRegisterMetaType<QGamepadManager::GamepadButton>("QGamepadManager::GamepadButton"); + qRegisterMetaType<QGamepadManager::GamepadAxis>("QGamepadManager::GamepadAxis"); + + connect(m_gamepadBackend, SIGNAL(gamepadAdded(int)), this, SLOT(forwardGamepadConnected(int))); + connect(m_gamepadBackend, SIGNAL(gamepadRemoved(int)), this, SLOT(forwardGamepadDisconnected(int))); + connect(m_gamepadBackend, SIGNAL(gamepadAxisMoved(int,QGamepadManager::GamepadAxis,double)), this, SLOT(forwardGamepadAxisEvent(int,QGamepadManager::GamepadAxis,double))); + connect(m_gamepadBackend, SIGNAL(gamepadButtonPressed(int,QGamepadManager::GamepadButton,double)), this, SLOT(forwardGamepadButtonPressEvent(int,QGamepadManager::GamepadButton,double))); + connect(m_gamepadBackend, SIGNAL(gamepadButtonReleased(int,QGamepadManager::GamepadButton)), this, SLOT(forwardGamepadButtonReleaseEvent(int,QGamepadManager::GamepadButton))); + + if (!m_gamepadBackend->start()) + qCWarning(gp) << "Failed to start gamepad backend"; +} + +QGamepadManager::~QGamepadManager() +{ + m_gamepadBackend->stop(); + m_gamepadBackend->deleteLater(); +} + +void QGamepadManager::loadBackend() +{ + QStringList keys = QGamepadBackendFactory::keys(); + qCDebug(gp) << "Available backends:" << keys; + if (!keys.isEmpty()) { + QString requestedKey = QString::fromUtf8(qgetenv("QT_GAMEPAD")); + QString targetKey = keys.first(); + if (!requestedKey.isEmpty() && keys.contains(requestedKey)) + targetKey = requestedKey; + if (!targetKey.isEmpty()) { + qCDebug(gp) << "Loading backend" << targetKey; + m_gamepadBackend = QGamepadBackendFactory::create(targetKey, QStringList()); + } + } + + if (!m_gamepadBackend) { + //Use dummy backend + m_gamepadBackend = new QGamepadBackend(); + qCDebug(gp) << "Using dummy backend"; + } +} + +QGamepadManager *QGamepadManager::instance() +{ + static QGamepadManager instance; + return &instance; +} + +bool QGamepadManager::isGamepadConnected(int index) +{ + return m_connectedGamepads.contains(index); +} + +void QGamepadManager::forwardGamepadConnected(int index) +{ + //qDebug() << "gamepad connected: " << index; + m_connectedGamepads.append(index); + emit gamepadConnected(index); +} + +void QGamepadManager::forwardGamepadDisconnected(int index) +{ + //qDebug() << "gamepad disconnected: " << index; + m_connectedGamepads.removeAll(index); + emit gamepadDisconnected(index); +} + +void QGamepadManager::forwardGamepadAxisEvent(int index, QGamepadManager::GamepadAxis axis, double value) +{ + //qDebug() << "gamepad axis event: " << index << axis << value; + emit gamepadAxisEvent(index, axis, value); +} + +void QGamepadManager::forwardGamepadButtonPressEvent(int index, QGamepadManager::GamepadButton button, double value) +{ + //qDebug() << "gamepad button press event: " << index << button << value; + emit gamepadButtonPressEvent(index, button, value); +} + +void QGamepadManager::forwardGamepadButtonReleaseEvent(int index, QGamepadManager::GamepadButton button) +{ + //qDebug() << "gamepad button release event: " << index << button; + emit gamepadButtonReleaseEvent(index, button); +} + +QT_END_NAMESPACE diff --git a/src/gamepad/qgamepadmanager.h b/src/gamepad/qgamepadmanager.h new file mode 100644 index 0000000..49eaa94 --- /dev/null +++ b/src/gamepad/qgamepadmanager.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JOYSTICKMANAGER_H +#define JOYSTICKMANAGER_H + +#include <QtCore/QObject> +#include <QtCore/QList> +#include <QtGamepad/qtgamepadglobal.h> + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +class QGamepadBackend; +class QGamepad; + +class Q_GAMEPAD_EXPORT QGamepadManager : public QObject +{ + Q_OBJECT + Q_FLAGS(GamepadButton GamepadButtons) + Q_FLAGS(GamepadAxis GamepadAxes) + +public: + enum GamepadButton { + ButtonInvalid = -1, + ButtonA = 0, + ButtonB, + ButtonX, + ButtonY, + ButtonL1, + ButtonR1, + ButtonL2, + ButtonR2, + ButtonSelect, + ButtonStart, + ButtonL3, + ButtonR3, + ButtonUp, + ButtonDown, + ButtonRight, + ButtonLeft, + ButtonGuide + }; + Q_DECLARE_FLAGS(GamepadButtons, GamepadButton) + + enum GamepadAxis { + AxisInvalid = -1, + AxisLeftX = 0, + AxisLeftY, + AxisRightX, + AxisRightY + }; + Q_DECLARE_FLAGS(GamepadAxes, GamepadAxis) + + static QGamepadManager* instance(); + + bool isGamepadConnected(int index); + +signals: + void gamepadConnected(int index); + void gamepadDisconnected(int index); + void gamepadAxisEvent(int index, QGamepadManager::GamepadAxis axis, double value); + void gamepadButtonPressEvent(int index, QGamepadManager::GamepadButton button, double value); + void gamepadButtonReleaseEvent(int index, QGamepadManager::GamepadButton button); + +private slots: + void forwardGamepadConnected(int index); + void forwardGamepadDisconnected(int index); + void forwardGamepadAxisEvent(int index, QGamepadManager::GamepadAxis axis, double value); + void forwardGamepadButtonPressEvent(int index, QGamepadManager::GamepadButton button, double value); + void forwardGamepadButtonReleaseEvent(int index, QGamepadManager::GamepadButton button); + +private: + QGamepadManager(); + ~QGamepadManager(); + QGamepadManager(QGamepadManager const&); + void operator=(QGamepadManager const&); + + void loadBackend(); + + QGamepadBackend *m_gamepadBackend; + QList<int> m_connectedGamepads; + +}; + +Q_DECLARE_METATYPE(QGamepadManager::GamepadButton) +Q_DECLARE_METATYPE(QGamepadManager::GamepadAxis) + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // JOYSTICKMANAGER_H diff --git a/src/gamepad/qtgamepadglobal.h b/src/gamepad/qtgamepadglobal.h new file mode 100644 index 0000000..c2f37d5 --- /dev/null +++ b/src/gamepad/qtgamepadglobal.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTGAMEPADGLOBAL_H +#define QTGAMEPADGLOBAL_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +#ifndef Q_GAMEPAD_EXPORT +# ifndef QT_STATIC +# if defined(QT_BUILD_GAMEPAD_LIB) +# define Q_GAMEPAD_EXPORT Q_DECL_EXPORT +# else +# define Q_GAMEPAD_EXPORT Q_DECL_IMPORT +# endif +# else +# define Q_GAMEPAD_EXPORT +# endif +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/imports/gamepad/gamepad.pro b/src/imports/gamepad/gamepad.pro new file mode 100644 index 0000000..c6ee21c --- /dev/null +++ b/src/imports/gamepad/gamepad.pro @@ -0,0 +1,16 @@ +CXX_MODULE = gamepad +TARGET = declarative_gamepad +TARGETPATH = QtGamepad +IMPORT_VERSION = 1.0 + +QT += qml quick gamepad +SOURCES += \ + $$PWD/qtgamepad.cpp \ + qgamepadmouseitem.cpp + +load(qml_plugin) + +OTHER_FILES += qmldir + +HEADERS += \ + qgamepadmouseitem.h diff --git a/src/imports/gamepad/plugins.qmltypes b/src/imports/gamepad/plugins.qmltypes new file mode 100644 index 0000000..3c88613 --- /dev/null +++ b/src/imports/gamepad/plugins.qmltypes @@ -0,0 +1,140 @@ +import QtQuick.tooling 1.1 + +// This file describes the plugin-supplied types contained in the library. +// It is used for QML tooling purposes only. +// +// This file was auto-generated by: +// 'qmlplugindump QtGamepad 1.0 ../qml/' + +Module { + Component { + name: "QGamepad" + prototype: "QObject" + exports: ["Gamepad 1.0"] + exportMetaObjectRevisions: [0] + Property { name: "index"; type: "int" } + Property { name: "connected"; type: "bool"; isReadonly: true } + Property { name: "name"; type: "string"; isReadonly: true } + Property { name: "axisLeftX"; type: "double"; isReadonly: true } + Property { name: "axisLeftY"; type: "double"; isReadonly: true } + Property { name: "axisRightX"; type: "double"; isReadonly: true } + Property { name: "axisRightY"; type: "double"; isReadonly: true } + Property { name: "buttonA"; type: "bool"; isReadonly: true } + Property { name: "buttonB"; type: "bool"; isReadonly: true } + Property { name: "buttonX"; type: "bool"; isReadonly: true } + Property { name: "buttonY"; type: "bool"; isReadonly: true } + Property { name: "buttonL1"; type: "bool"; isReadonly: true } + Property { name: "buttonR1"; type: "bool"; isReadonly: true } + Property { name: "buttonL2"; type: "double"; isReadonly: true } + Property { name: "buttonR2"; type: "double"; isReadonly: true } + Property { name: "buttonSelect"; type: "bool"; isReadonly: true } + Property { name: "buttonStart"; type: "bool"; isReadonly: true } + Property { name: "buttonL3"; type: "bool"; isReadonly: true } + Property { name: "buttonR3"; type: "bool"; isReadonly: true } + Property { name: "buttonUp"; type: "bool"; isReadonly: true } + Property { name: "buttonDown"; type: "bool"; isReadonly: true } + Property { name: "buttonLeft"; type: "bool"; isReadonly: true } + Property { name: "buttonRight"; type: "bool"; isReadonly: true } + Property { name: "buttonGuide"; type: "bool"; isReadonly: true } + Signal { + name: "indexChanged" + Parameter { name: "value"; type: "int" } + } + Signal { + name: "connectedChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "nameChanged" + Parameter { name: "value"; type: "string" } + } + Signal { + name: "axisLeftXChanged" + Parameter { name: "value"; type: "double" } + } + Signal { + name: "axisLeftYChanged" + Parameter { name: "value"; type: "double" } + } + Signal { + name: "axisRightXChanged" + Parameter { name: "value"; type: "double" } + } + Signal { + name: "axisRightYChanged" + Parameter { name: "value"; type: "double" } + } + Signal { + name: "buttonAChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonBChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonXChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonYChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonL1Changed" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonR1Changed" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonL2Changed" + Parameter { name: "value"; type: "double" } + } + Signal { + name: "buttonR2Changed" + Parameter { name: "value"; type: "double" } + } + Signal { + name: "buttonSelectChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonStartChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonL3Changed" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonR3Changed" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonUpChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonDownChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonLeftChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonRightChanged" + Parameter { name: "value"; type: "bool" } + } + Signal { + name: "buttonGuideChanged" + Parameter { name: "value"; type: "bool" } + } + Method { + name: "setIndex" + Parameter { name: "number"; type: "int" } + } + } +} diff --git a/src/imports/gamepad/qgamepadmouseitem.cpp b/src/imports/gamepad/qgamepadmouseitem.cpp new file mode 100644 index 0000000..b8144d7 --- /dev/null +++ b/src/imports/gamepad/qgamepadmouseitem.cpp @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgamepadmouseitem.h" +#include <cmath> + +#include <QtGamepad/QGamepad> +#include <QtGui/QWindow> +#include <QtQuick/QQuickWindow> +#include <QtGui/QGuiApplication> + +QT_BEGIN_NAMESPACE + +QGamepadMouseItem::QGamepadMouseItem(QQuickItem *parent) + : QQuickItem(parent) + , m_active(false) + , m_gamepad(0) + , m_joystick(QGamepadMouseItem::LeftStick) + , m_deadZoneSize(0.1) +{ + m_updateTimer.setInterval(16); + connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateMousePostion())); +} + +bool QGamepadMouseItem::active() const +{ + return m_active; +} + +QGamepad *QGamepadMouseItem::gamepad() const +{ + return m_gamepad; +} + +QGamepadMouseItem::GamepadJoystick QGamepadMouseItem::joystick() const +{ + return m_joystick; +} + +double QGamepadMouseItem::deadZoneSize() const +{ + return m_deadZoneSize; +} + +QPointF QGamepadMouseItem::mousePosition() const +{ + return m_mousePosition; +} + +void QGamepadMouseItem::setActive(bool arg) +{ + if (m_active != arg) { + m_active = arg; + if (m_active) { + m_deltaTimer.start(); + m_updateTimer.start(); + } else { + m_updateTimer.stop(); + m_deltaTimer.invalidate(); + } + emit activeChanged(arg); + } +} + +void QGamepadMouseItem::setGamepad(QGamepad *gamepad) +{ + if (m_gamepad != gamepad) { + m_gamepad = gamepad; + emit gamepadChanged(gamepad); + } +} + +void QGamepadMouseItem::setJoystick(QGamepadMouseItem::GamepadJoystick joystick) +{ + if (m_joystick != joystick) { + m_joystick = joystick; + emit joystickChanged(joystick); + } +} + +void QGamepadMouseItem::setDeadZoneSize(double size) +{ + if (m_deadZoneSize != size) { + m_deadZoneSize = size; + emit deadZoneSizeChanged(size); + } +} + +void QGamepadMouseItem::mouseButtonPressed(int button) +{ + processMouseButtonEvent(true, (Qt::MouseButton)button); +} + +void QGamepadMouseItem::mouseButtonReleased(int button) +{ + processMouseButtonEvent(false, (Qt::MouseButton)button); +} + +void QGamepadMouseItem::updateMousePostion() +{ + //Get the delta from the last call + qint64 delta = m_deltaTimer.restart(); + + //Don't bother when there is not gamepad to read from + if (!m_gamepad || !m_gamepad->isConnected()) + return; + + double xVelocity = 0.0; + double yVelocity = 0.0; + + if (m_joystick == QGamepadMouseItem::LeftStick) { + xVelocity = m_gamepad->axisLeftX(); + yVelocity = m_gamepad->axisLeftY(); + } else if (m_joystick == QGamepadMouseItem::RightStick) { + xVelocity = m_gamepad->axisRightX(); + yVelocity = m_gamepad->axisRightY(); + } else { //The greatest of both + if (std::abs(m_gamepad->axisLeftX()) > std::abs(m_gamepad->axisRightX())) + xVelocity = m_gamepad->axisLeftX(); + else + xVelocity = m_gamepad->axisRightX(); + if (std::abs(m_gamepad->axisLeftY()) > std::abs(m_gamepad->axisRightY())) + yVelocity = m_gamepad->axisLeftY(); + else + yVelocity = m_gamepad->axisRightY(); + } + + //Check for deadzone limits] + if (std::abs(xVelocity) < m_deadZoneSize) + xVelocity = 0.0; + if (std::abs(yVelocity) < m_deadZoneSize) + yVelocity = 0.0; + if (xVelocity == 0.0 && yVelocity == 0.0) + return; + + double newXPosition = m_mousePosition.x() + xVelocity * delta; + double newYPosition = m_mousePosition.y() + yVelocity * delta; + //Check bounds + if (newXPosition < 0) + newXPosition = 0; + else if (newXPosition > width()) + newXPosition = width(); + + if (newYPosition < 0) + newYPosition = 0; + else if (newYPosition > height()) + newYPosition = height(); + + m_mousePosition = QPointF(newXPosition, newYPosition); + emit mousePositionChanged(m_mousePosition); +} + +void QGamepadMouseItem::processMouseMoveEvent(QPointF position) +{ + QMouseEvent *mouseEvent = new QMouseEvent(QEvent::MouseMove, mapToScene(position), Qt::NoButton, m_mouseButtons, Qt::NoModifier); + sendGeneratedMouseEvent(mouseEvent); +} + +void QGamepadMouseItem::processMouseButtonEvent(bool isPressed, Qt::MouseButton button) +{ + QMouseEvent *event; + if (isPressed) { + m_mouseButtons |= button; + event = new QMouseEvent(QEvent::MouseButtonPress, mapToScene(m_mousePosition), button, m_mouseButtons, Qt::NoModifier); + } else { + m_mouseButtons ^= button; + event = new QMouseEvent(QEvent::MouseButtonRelease, mapToScene(m_mousePosition), button, m_mouseButtons, Qt::NoModifier); + } + + sendGeneratedMouseEvent(event); +} + +void QGamepadMouseItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + QQuickItem::geometryChanged(newGeometry, oldGeometry); + + m_mousePosition = newGeometry.center(); +} + +void QGamepadMouseItem::sendGeneratedMouseEvent(QMouseEvent *event) +{ + if (!m_active || !this->window()) { + delete event; + return; + } + + QWindow *window = qobject_cast<QWindow*>(this->window()); + if (window) + QGuiApplication::sendEvent(window, event); +} + +QT_END_NAMESPACE diff --git a/src/imports/gamepad/qgamepadmouseitem.h b/src/imports/gamepad/qgamepadmouseitem.h new file mode 100644 index 0000000..d5eb1e7 --- /dev/null +++ b/src/imports/gamepad/qgamepadmouseitem.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGAMEPADMOUSEITEM_H +#define QGAMEPADMOUSEITEM_H + +#include <QtQuick/QQuickItem> +#include <QtCore/QTimer> +#include <QtCore/QElapsedTimer> + +QT_BEGIN_NAMESPACE + +class QGamepad; +class QGamepadManager; +class QGamepadMouseItem : public QQuickItem +{ + Q_OBJECT + Q_ENUMS(GamepadJoystick) + Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) + Q_PROPERTY(QGamepad* gamepad READ gamepad WRITE setGamepad NOTIFY gamepadChanged) + Q_PROPERTY(GamepadJoystick joystick READ joystick WRITE setJoystick NOTIFY joystickChanged) + Q_PROPERTY(double deadZoneSize READ deadZoneSize WRITE setDeadZoneSize NOTIFY deadZoneSizeChanged) + Q_PROPERTY(QPointF mousePosition READ mousePosition NOTIFY mousePositionChanged) + +public: + enum GamepadJoystick { + LeftStick, + RightStick, + Both + }; + + explicit QGamepadMouseItem(QQuickItem *parent = 0); + + bool active() const; + QGamepad* gamepad() const; + GamepadJoystick joystick() const; + double deadZoneSize() const; + QPointF mousePosition() const; + +signals: + + void activeChanged(bool isActive); + void gamepadChanged(QGamepad* gamepad); + void joystickChanged(GamepadJoystick joystick); + void deadZoneSizeChanged(double size); + void mousePositionChanged(QPointF position); + +public slots: + + void setActive(bool arg); + void setGamepad(QGamepad* gamepad); + void setJoystick(GamepadJoystick joystick); + void setDeadZoneSize(double size); + + void mouseButtonPressed(int button); + void mouseButtonReleased(int button); + +private slots: + void updateMousePostion(); + void processMouseMoveEvent(QPointF position); + void processMouseButtonEvent(bool isPressed, Qt::MouseButton button = Qt::LeftButton); + +protected: + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + +private: + void sendGeneratedMouseEvent(QMouseEvent *event); + + QPointF m_mousePosition; + QTimer m_updateTimer; + QElapsedTimer m_deltaTimer; + Qt::MouseButtons m_mouseButtons; + + bool m_active; + QGamepad* m_gamepad; + GamepadJoystick m_joystick; + double m_deadZoneSize; + + +}; + +QT_END_NAMESPACE + +#endif // QGAMEPADMOUSEITEM_H diff --git a/src/imports/gamepad/qmldir b/src/imports/gamepad/qmldir new file mode 100644 index 0000000..fa9e6e4 --- /dev/null +++ b/src/imports/gamepad/qmldir @@ -0,0 +1,4 @@ +module QtGamepad +plugin declarative_gamepad +typeinfo plugins.qmltypes +classname QGamepadModule diff --git a/src/imports/gamepad/qtgamepad.cpp b/src/imports/gamepad/qtgamepad.cpp new file mode 100644 index 0000000..ae37e62 --- /dev/null +++ b/src/imports/gamepad/qtgamepad.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqmlextensionplugin.h> +#include <QtQml/qqml.h> + +#include <QtGamepad/QGamepad> +#include <QtGamepad/QGamepadKeyNavigation> + +#include "qgamepadmouseitem.h" + +QT_BEGIN_NAMESPACE + +class QGamepadModule : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") +public: + void registerTypes(const char *uri) + { + Q_ASSERT(QLatin1String(uri) == QLatin1String("QtGamepad")); + + qmlRegisterType<QGamepad>(uri, 1, 0, "Gamepad"); + qmlRegisterType<QGamepadKeyNavigation>(uri, 1, 0, "GamepadKeyNavigation"); + qmlRegisterType<QGamepadMouseItem>(uri, 1, 0, "GamepadMouseItem"); + } + + void initializeEngine(QQmlEngine *engine, const char *uri) + { + Q_UNUSED(uri); + Q_UNUSED(engine); + } +}; + +QT_END_NAMESPACE + +#include "qtgamepad.moc" diff --git a/src/imports/imports.pro b/src/imports/imports.pro new file mode 100644 index 0000000..72acdb0 --- /dev/null +++ b/src/imports/imports.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += gamepad diff --git a/src/plugins/gamepads/evdev/evdev.json b/src/plugins/gamepads/evdev/evdev.json new file mode 100644 index 0000000..90c6d7d --- /dev/null +++ b/src/plugins/gamepads/evdev/evdev.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "evdev" ] +} diff --git a/src/plugins/gamepads/evdev/evdev.pro b/src/plugins/gamepads/evdev/evdev.pro new file mode 100644 index 0000000..7263f5c --- /dev/null +++ b/src/plugins/gamepads/evdev/evdev.pro @@ -0,0 +1,14 @@ +TARGET = evdevgamepad +QT += core-private platformsupport-private gamepad gamepad-private + +PLUGIN_TYPE = gamepads +PLUGIN_CLASS_NAME = QEvdevGamepadBackendPlugin +load(qt_plugin) + +HEADERS += qevdevgamepadbackend_p.h +SOURCES += \ + qevdevgamepadbackend.cpp \ + main.cpp + +OTHER_FILES += \ + evdev.json diff --git a/src/plugins/gamepads/evdev/main.cpp b/src/plugins/gamepads/evdev/main.cpp new file mode 100644 index 0000000..64f6952 --- /dev/null +++ b/src/plugins/gamepads/evdev/main.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGamepad/private/qgamepadbackendfactory_p.h> +#include <QtGamepad/private/qgamepadbackendplugin_p.h> + +#include "qevdevgamepadbackend_p.h" + +QT_BEGIN_NAMESPACE + +class QEvdevGamepadBackendPlugin : public QGamepadBackendPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QtGamepadBackendFactoryInterface_iid FILE "evdev.json") +public: + QGamepadBackend *create(const QString &key, const QStringList ¶mList) Q_DECL_OVERRIDE; +}; + +QGamepadBackend *QEvdevGamepadBackendPlugin::create(const QString &key, const QStringList ¶mList) +{ + Q_UNUSED(key) + Q_UNUSED(paramList) + + return new QEvdevGamepadBackend; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp b/src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp new file mode 100644 index 0000000..d0c4a3f --- /dev/null +++ b/src/plugins/gamepads/evdev/qevdevgamepadbackend.cpp @@ -0,0 +1,404 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qevdevgamepadbackend_p.h" +#include <QtCore/QSocketNotifier> +#include <QtCore/QLoggingCategory> +#include <QtPlatformSupport/private/qdevicediscovery_p.h> +#include <QtCore/private/qcore_unix_p.h> +#include <linux/input.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcEGB, "qt.gamepad") + +QEvdevGamepadBackend::QEvdevGamepadBackend() + : m_nextIndex(0) +{ +} + +bool QEvdevGamepadBackend::start() +{ + qCDebug(lcEGB) << "start"; + QByteArray device = qgetenv("QT_GAMEPAD_DEVICE"); + if (device.isEmpty()) { + qCDebug(lcEGB) << "Using device discovery"; + m_discovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Joystick, this); + if (m_discovery) { + QStringList devices = m_discovery->scanConnectedDevices(); + foreach (const QString &devStr, devices) { + device = devStr.toUtf8(); + m_devices.append(newDevice(device)); + } + connect(m_discovery, SIGNAL(deviceDetected(QString)), this, SLOT(handleAddedDevice(QString))); + connect(m_discovery, SIGNAL(deviceRemoved(QString)), this, SLOT(handleRemovedDevice(QString))); + } else { + qWarning("No device specified, set QT_GAMEPAD_DEVICE"); + return false; + } + } else { + qCDebug(lcEGB) << "Using device" << device; + m_devices.append(newDevice(device)); + } + + return true; +} + +QEvdevGamepadDevice *QEvdevGamepadBackend::newDevice(const QByteArray &device) +{ + qCDebug(lcEGB) << "Opening device" << device; + return new QEvdevGamepadDevice(device, this); +} + +// To be called only when it is sure that there is a controller on-line. +int QEvdevGamepadBackend::indexForDevice(const QByteArray &device) +{ + int index; + if (m_devIndex.contains(device)) { + index = m_devIndex[device]; + } else { + index = m_nextIndex++; + m_devIndex[device] = index; + } + return index; +} + +void QEvdevGamepadBackend::stop() +{ + qCDebug(lcEGB) << "stop"; + qDeleteAll(m_devices); + m_devices.clear(); +} + +void QEvdevGamepadBackend::handleAddedDevice(const QString &device) +{ + // This does not imply that an actual controller is connected. + // When connecting the wireless receiver 4 devices will show up right away. + // Therefore gamepadAdded() will be emitted only later, when something is read. + qCDebug(lcEGB) << "Connected device" << device; + m_devices.append(newDevice(device.toUtf8())); +} + +void QEvdevGamepadBackend::handleRemovedDevice(const QString &device) +{ + qCDebug(lcEGB) << "Disconnected device" << device; + QByteArray dev = device.toUtf8(); + for (int i = 0; i < m_devices.count(); ++i) { + if (m_devices[i]->deviceName() == dev) { + delete m_devices[i]; + m_devices.removeAt(i); + break; + } + } +} + +QEvdevGamepadDevice::QEvdevGamepadDevice(const QByteArray &dev, QEvdevGamepadBackend *backend) + : m_dev(dev), + m_backend(backend), + m_index(-1), + m_fd(-1), + m_notifier(0), + m_prevYHatButton(QGamepadManager::ButtonInvalid), + m_prevXHatButton(QGamepadManager::ButtonInvalid) +{ + openDevice(dev); +} + +QEvdevGamepadDevice::~QEvdevGamepadDevice() +{ + if (m_fd != -1) + QT_CLOSE(m_fd); + if (m_index >= 0) + emit m_backend->gamepadRemoved(m_index); +} + +bool QEvdevGamepadDevice::openDevice(const QByteArray &dev) +{ + m_fd = QT_OPEN(dev.constData(), O_RDONLY | O_NDELAY, 0); + + if (m_fd >= 0) { + m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readData())); + qCDebug(lcEGB) << "Successfully opened" << dev; + } else { + qErrnoWarning(errno, "Gamepad: Cannot open input device %s", qPrintable(dev)); + return false; + } + + // Defaults. To be replaced with queried values below. + m_axisInfo.insert(ABS_X, AxisInfo(-32768, 32767)); + m_axisInfo.insert(ABS_Y, AxisInfo(-32768, 32767)); + m_axisInfo.insert(ABS_RX, AxisInfo(-32768, 32767)); + m_axisInfo.insert(ABS_RY, AxisInfo(-32768, 32767)); + m_axisInfo.insert(ABS_Z, AxisInfo(0, 255)); + m_axisInfo.insert(ABS_RZ, AxisInfo(0, 255)); + + input_absinfo absInfo; + memset(&absInfo, 0, sizeof(input_absinfo)); + if (ioctl(m_fd, EVIOCGABS(ABS_X), &absInfo) >= 0) + m_axisInfo.insert(ABS_X, AxisInfo(absInfo.minimum, absInfo.maximum)); + if (ioctl(m_fd, EVIOCGABS(ABS_Y), &absInfo) >= 0) + m_axisInfo.insert(ABS_Y, AxisInfo(absInfo.minimum, absInfo.maximum)); + if (ioctl(m_fd, EVIOCGABS(ABS_RX), &absInfo) >= 0) + m_axisInfo.insert(ABS_RX, AxisInfo(absInfo.minimum, absInfo.maximum)); + if (ioctl(m_fd, EVIOCGABS(ABS_RY), &absInfo) >= 0) + m_axisInfo.insert(ABS_RY, AxisInfo(absInfo.minimum, absInfo.maximum)); + if (ioctl(m_fd, EVIOCGABS(ABS_Z), &absInfo) >= 0) + m_axisInfo.insert(ABS_Z, AxisInfo(absInfo.minimum, absInfo.maximum)); + if (ioctl(m_fd, EVIOCGABS(ABS_RZ), &absInfo) >= 0) + m_axisInfo.insert(ABS_RZ, AxisInfo(absInfo.minimum, absInfo.maximum)); + + qCDebug(lcEGB) << "Axis limits:" << m_axisInfo; + + return true; +} + +QDebug operator<<(QDebug dbg, const QEvdevGamepadDevice::AxisInfo &axisInfo) +{ + dbg.nospace() << "AxisInfo(min=" << axisInfo.minValue << ", max=" << axisInfo.maxValue << ")"; + return dbg.space(); +} + +void QEvdevGamepadDevice::readData() +{ + input_event buffer[32]; + int events = 0, n = 0; + for (; ;) { + events = QT_READ(m_fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n); + if (events <= 0) + goto err; + n += events; + if (n % sizeof(::input_event) == 0) + break; + } + + n /= sizeof(::input_event); + + for (int i = 0; i < n; ++i) + processInputEvent(&buffer[i]); + + return; + +err: + if (!events) { + qWarning("Gamepad: Got EOF from input device"); + return; + } else if (events < 0) { + if (errno != EINTR && errno != EAGAIN) { + qErrnoWarning(errno, "Gamepad: Could not read from input device"); + if (errno == ENODEV) { // device got disconnected -> stop reading + delete m_notifier; + m_notifier = 0; + QT_CLOSE(m_fd); + m_fd = -1; + } + } + } +} + +double QEvdevGamepadDevice::AxisInfo::normalized(int value) const +{ + if (minValue >= 0) + return (value - minValue) / double(maxValue - minValue); + else + return 2 * (value - minValue) / double(maxValue - minValue) - 1.0; +} + +void QEvdevGamepadDevice::processInputEvent(input_event *e) +{ + if (m_index < 0) { + m_index = m_backend->indexForDevice(m_dev); + qCDebug(lcEGB) << "Adding gamepad" << m_dev << "with index" << m_index; + emit m_backend->gamepadAdded(m_index); + } + + if (e->type == EV_KEY) { + const bool pressed = e->value; + QGamepadManager::GamepadButton btn = QGamepadManager::ButtonInvalid; + + switch (e->code) { + case BTN_START: + btn = QGamepadManager::ButtonStart; + break; + case BTN_SELECT: + btn = QGamepadManager::ButtonSelect; + break; + case BTN_MODE: + btn = QGamepadManager::ButtonGuide; + break; + + case BTN_X: + btn = QGamepadManager::ButtonX; + break; + case BTN_Y: + btn = QGamepadManager::ButtonY; + break; + case BTN_A: + btn = QGamepadManager::ButtonA; + break; + case BTN_B: + btn = QGamepadManager::ButtonB; + break; + + case BTN_TL: + btn = QGamepadManager::ButtonL1; + break; + case BTN_TR: + btn = QGamepadManager::ButtonR1; + break; + + case BTN_THUMB: // wireless + case BTN_THUMBL: // wired + btn = QGamepadManager::ButtonL3; + break; + case BTN_THUMBR: + btn = QGamepadManager::ButtonR3; + break; + + // Directional buttons for wireless + case BTN_TRIGGER_HAPPY1: + btn = QGamepadManager::ButtonLeft; + break; + case BTN_TRIGGER_HAPPY2: + btn = QGamepadManager::ButtonRight; + break; + case BTN_TRIGGER_HAPPY3: + btn = QGamepadManager::ButtonUp; + break; + case BTN_TRIGGER_HAPPY4: + btn = QGamepadManager::ButtonDown; + break; + + default: + break; + } + if (btn != QGamepadManager::ButtonInvalid) { + if (pressed) + emit m_backend->gamepadButtonPressed(m_index, btn, 1.0); + else + emit m_backend->gamepadButtonReleased(m_index, btn); + } + } else if (e->type == EV_ABS) { + if (e->code == ABS_HAT0X || e->code == ABS_HAT0Y) { + //Special logic for digital direction buttons as it is treated as a hat axis + //with the wired controller. + double value = m_axisInfo.value(e->code).normalized(e->value); + QGamepadManager::GamepadButton btn = QGamepadManager::ButtonInvalid; + bool pressed = false; + if (e->code == ABS_HAT0X) { + if (value == 1.0) { + btn = QGamepadManager::ButtonRight; + m_prevXHatButton = btn; + pressed = true; + } else if (value == -1.0) { + btn = QGamepadManager::ButtonLeft; + m_prevXHatButton = btn; + pressed = true; + } else { + //Release + btn = m_prevXHatButton; + m_prevXHatButton = QGamepadManager::ButtonInvalid; + pressed = false; + } + } else { + if (value == 1.0) { + btn = QGamepadManager::ButtonDown; + m_prevYHatButton = btn; + pressed = true; + } else if (value == -1.0) { + btn = QGamepadManager::ButtonUp; + m_prevYHatButton = btn; + pressed = true; + } else { + //Release + btn = m_prevYHatButton; + m_prevYHatButton = QGamepadManager::ButtonInvalid; + pressed = false; + } + } + if (btn != QGamepadManager::ButtonInvalid) { + if (pressed) + emit m_backend->gamepadButtonPressed(m_index, btn, 1.0); + else + emit m_backend->gamepadButtonReleased(m_index, btn); + } + + } else { + QGamepadManager::GamepadAxis axis = QGamepadManager::AxisInvalid; + QGamepadManager::GamepadButton btn = QGamepadManager::ButtonInvalid; + + switch (e->code) { + case ABS_X: + axis = QGamepadManager::AxisLeftX; + break; + case ABS_Y: + axis = QGamepadManager::AxisLeftY; + break; + + case ABS_RX: + axis = QGamepadManager::AxisRightX; + break; + case ABS_RY: + axis = QGamepadManager::AxisRightY; + break; + + case ABS_Z: + btn = QGamepadManager::ButtonL2; + break; + case ABS_RZ: + btn = QGamepadManager::ButtonR2; + break; + + default: + break; + } + + AxisInfo axisInfo = m_axisInfo.value(e->code); + const double value = axisInfo.normalized(e->value); + + if (axis != QGamepadManager::AxisInvalid) { + emit m_backend->gamepadAxisMoved(m_index, axis, value); + } else if (btn != QGamepadManager::ButtonInvalid) { + if (!qFuzzyIsNull(value)) + emit m_backend->gamepadButtonPressed(m_index, btn, value); + else + emit m_backend->gamepadButtonReleased(m_index, btn); + } + } + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/gamepads/evdev/qevdevgamepadbackend_p.h b/src/plugins/gamepads/evdev/qevdevgamepadbackend_p.h new file mode 100644 index 0000000..0371989 --- /dev/null +++ b/src/plugins/gamepads/evdev/qevdevgamepadbackend_p.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVDEVGAMEPADCONTROLLER_H +#define QEVDEVGAMEPADCONTROLLER_H + +#include <QtGamepad/QGamepadManager> +#include <QtGamepad/private/qgamepadbackend_p.h> +#include <QtCore/QHash> +#include <QtCore/QVector> + +struct input_event; + +QT_BEGIN_NAMESPACE + +class QSocketNotifier; +class QDeviceDiscovery; +class QEvdevGamepadBackend; + +class QEvdevGamepadDevice : public QObject +{ + Q_OBJECT + +public: + QEvdevGamepadDevice(const QByteArray &dev, QEvdevGamepadBackend *backend); + ~QEvdevGamepadDevice(); + QByteArray deviceName() const { return m_dev; } + +private slots: + void readData(); + +private: + void processInputEvent(input_event *e); + bool openDevice(const QByteArray &dev); + + QByteArray m_dev; + QEvdevGamepadBackend *m_backend; + int m_index; + int m_fd; + QSocketNotifier *m_notifier; + struct AxisInfo { + AxisInfo() : minValue(0), maxValue(1) { } + AxisInfo(int minValue, int maxValue) : minValue(minValue), maxValue(maxValue) { } + double normalized(int value) const; + + int minValue; + int maxValue; + }; + QHash<int, AxisInfo> m_axisInfo; + QGamepadManager::GamepadButton m_prevYHatButton; + QGamepadManager::GamepadButton m_prevXHatButton; + friend QDebug operator<<(QDebug dbg, const QEvdevGamepadDevice::AxisInfo &axisInfo); +}; + +QDebug operator<<(QDebug dbg, const QEvdevGamepadDevice::AxisInfo &axisInfo); + +class QEvdevGamepadBackend : public QGamepadBackend +{ + Q_OBJECT + +public: + QEvdevGamepadBackend(); + bool start() Q_DECL_OVERRIDE; + void stop() Q_DECL_OVERRIDE; + int indexForDevice(const QByteArray &device); + +private slots: + void handleAddedDevice(const QString &device); + void handleRemovedDevice(const QString &device); + +private: + QEvdevGamepadDevice *newDevice(const QByteArray &device); + + QDeviceDiscovery *m_discovery; + QVector<QEvdevGamepadDevice *> m_devices; + QHash<QByteArray, int> m_devIndex; + int m_nextIndex; +}; + +QT_END_NAMESPACE + +#endif // QEVDEVGAMEPADCONTROLLER_H diff --git a/src/plugins/gamepads/gamepads.pro b/src/plugins/gamepads/gamepads.pro new file mode 100644 index 0000000..928b288 --- /dev/null +++ b/src/plugins/gamepads/gamepads.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +config_sdl:SUBDIRS += sdl2 +contains(QT_CONFIG, evdev): SUBDIRS += evdev +win32: !wince*: SUBDIRS += xinput diff --git a/src/plugins/gamepads/sdl2/main.cpp b/src/plugins/gamepads/sdl2/main.cpp new file mode 100644 index 0000000..cc28ad2 --- /dev/null +++ b/src/plugins/gamepads/sdl2/main.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGamepad/private/qgamepadbackendfactory_p.h> +#include <QtGamepad/private/qgamepadbackendplugin_p.h> + +#include "qsdlgamepadbackend_p.h" + +QT_BEGIN_NAMESPACE + +class QSdl2GamepadBackendPlugin : public QGamepadBackendPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QtGamepadBackendFactoryInterface_iid FILE "sdl2.json") +public: + QGamepadBackend *create(const QString &key, const QStringList ¶mList) Q_DECL_OVERRIDE; +}; + +QGamepadBackend *QSdl2GamepadBackendPlugin::create(const QString &key, const QStringList ¶mList) { + Q_UNUSED(key) + Q_UNUSED(paramList) + + return new QSdlGamepadBackend(); +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/gamepads/sdl2/qsdlgamepadbackend.cpp b/src/plugins/gamepads/sdl2/qsdlgamepadbackend.cpp new file mode 100644 index 0000000..791e383 --- /dev/null +++ b/src/plugins/gamepads/sdl2/qsdlgamepadbackend.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qsdlgamepadbackend_p.h" + +#include <QtCore/QDebug> + +#include <SDL.h> + +QT_BEGIN_NAMESPACE + +QSdlGamepadBackend::QSdlGamepadBackend(QObject *parent) + : QGamepadBackend(parent) +{ + connect(&m_eventLoopTimer, SIGNAL(timeout()), this, SLOT(pumpSdlEventLoop())); +} + +QSdlGamepadBackend::~QSdlGamepadBackend() +{ +} + +void QSdlGamepadBackend::pumpSdlEventLoop() +{ + SDL_Event event; + while (SDL_PollEvent(&event)) { + if (event.type == SDL_CONTROLLERAXISMOTION) { + SDL_ControllerAxisEvent axisEvent = event.caxis; + //qDebug() << axisEvent.timestamp << "Axis Event: " << axisEvent.which << axisEvent.axis << axisEvent.value; + double value; + if (axisEvent.value >= 0) + value = axisEvent.value / 32767.0; + else + value = axisEvent.value / 32768.0; + switch (axisEvent.axis) { + case SDL_CONTROLLER_AXIS_LEFTX: + emit gamepadAxisMoved(m_instanceIdForIndex[axisEvent.which], QGamepadManager::AxisLeftX, value); + break; + case SDL_CONTROLLER_AXIS_LEFTY: + emit gamepadAxisMoved(m_instanceIdForIndex[axisEvent.which], QGamepadManager::AxisLeftY, value); + break; + case SDL_CONTROLLER_AXIS_RIGHTX: + emit gamepadAxisMoved(m_instanceIdForIndex[axisEvent.which], QGamepadManager::AxisRightX, value); + break; + case SDL_CONTROLLER_AXIS_RIGHTY: + emit gamepadAxisMoved(m_instanceIdForIndex[axisEvent.which], QGamepadManager::AxisRightY, value); + break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + if (value == 0) + emit gamepadButtonReleased(m_instanceIdForIndex[axisEvent.which], QGamepadManager::ButtonL2); + else + emit gamepadButtonPressed(m_instanceIdForIndex[axisEvent.which], QGamepadManager::ButtonL2, value); + break; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + if (value == 0) + emit gamepadButtonReleased(m_instanceIdForIndex[axisEvent.which], QGamepadManager::ButtonR2); + else + emit gamepadButtonPressed(m_instanceIdForIndex[axisEvent.which], QGamepadManager::ButtonR2, value); + break; + default: + break; + } + + } else if (event.type == SDL_CONTROLLERBUTTONDOWN) { + SDL_ControllerButtonEvent buttonEvent = event.cbutton; + //qDebug() << buttonEvent.timestamp << "Button Press: " << buttonEvent.which << buttonEvent.button << buttonEvent.state; + emit gamepadButtonPressed(m_instanceIdForIndex[buttonEvent.which], translateButton(buttonEvent.button), 1.0); + } else if (event.type == SDL_CONTROLLERBUTTONUP) { + SDL_ControllerButtonEvent buttonEvent = event.cbutton; + //qDebug() << buttonEvent.timestamp << "Button Release: " << buttonEvent.which << buttonEvent.button << buttonEvent.state; + emit gamepadButtonReleased(m_instanceIdForIndex[buttonEvent.which], translateButton(buttonEvent.button)); + } else if (event.type == SDL_CONTROLLERDEVICEADDED) { + SDL_ControllerDeviceEvent deviceEvent = event.cdevice; + //qDebug() << deviceEvent.timestamp << "Controller Added: " << deviceEvent.which; + SDL_GameController *controller = SDL_GameControllerOpen(deviceEvent.which); + if (controller) { + m_indexForController.insert(deviceEvent.which, controller); + int instanceID = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller)); + m_instanceIdForIndex.insert(instanceID, deviceEvent.which); + //qDebug() << "Controller " << deviceEvent.which << " added with instanceId: " << instanceID; + emit gamepadAdded(deviceEvent.which); + } + } else if (event.type == SDL_CONTROLLERDEVICEREMOVED) { + SDL_ControllerDeviceEvent deviceEvent = event.cdevice; + + int index = m_instanceIdForIndex[deviceEvent.which]; + SDL_GameControllerClose(m_indexForController[index]); + emit gamepadRemoved(index); + m_indexForController.remove(index); + m_instanceIdForIndex.remove(deviceEvent.which); + + } else if (event.type == SDL_CONTROLLERDEVICEREMAPPED) { + //SDL_ControllerDeviceEvent deviceEvent = event.cdevice; + //qDebug() << deviceEvent.timestamp << "Controller Remapped: " << deviceEvent.which; + } + } +} + +bool QSdlGamepadBackend::start() +{ + //Initialize SDL with necessary subsystems for gamepad support + if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK)) { + qDebug() << SDL_GetError(); + return false; + } + + m_eventLoopTimer.start(16); + return true; +} + +void QSdlGamepadBackend::stop() +{ + m_eventLoopTimer.stop(); + SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK); +} + +QGamepadManager::GamepadButton QSdlGamepadBackend::translateButton(int button) +{ + switch (button) { + case SDL_CONTROLLER_BUTTON_A: + return QGamepadManager::ButtonA; + case SDL_CONTROLLER_BUTTON_B: + return QGamepadManager::ButtonB; + case SDL_CONTROLLER_BUTTON_X: + return QGamepadManager::ButtonX; + case SDL_CONTROLLER_BUTTON_Y: + return QGamepadManager::ButtonY; + case SDL_CONTROLLER_BUTTON_BACK: + return QGamepadManager::ButtonSelect; + case SDL_CONTROLLER_BUTTON_GUIDE: + return QGamepadManager::ButtonGuide; + case SDL_CONTROLLER_BUTTON_START: + return QGamepadManager::ButtonStart; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: + return QGamepadManager::ButtonL3; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: + return QGamepadManager::ButtonR3; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + return QGamepadManager::ButtonL1; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + return QGamepadManager::ButtonR1; + case SDL_CONTROLLER_BUTTON_DPAD_UP: + return QGamepadManager::ButtonUp; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + return QGamepadManager::ButtonDown; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + return QGamepadManager::ButtonLeft; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + return QGamepadManager::ButtonRight; + default: + return QGamepadManager::ButtonInvalid; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/gamepads/sdl2/qsdlgamepadbackend_p.h b/src/plugins/gamepads/sdl2/qsdlgamepadbackend_p.h new file mode 100644 index 0000000..44e81dc --- /dev/null +++ b/src/plugins/gamepads/sdl2/qsdlgamepadbackend_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSDLGAMEPADCONTROLLER_H +#define QSDLGAMEPADCONTROLLER_H + +#include <QtCore/QTimer> +#include <QtCore/QMap> + +#include <SDL_gamecontroller.h> + +#include <QtGamepad/QGamepadManager> +#include <QtGamepad/private/qgamepadbackend_p.h> + +QT_BEGIN_NAMESPACE + +class QSdlGamepadBackend : public QGamepadBackend +{ + Q_OBJECT +public: + explicit QSdlGamepadBackend(QObject *parent = 0); + ~QSdlGamepadBackend(); + +private slots: + void pumpSdlEventLoop(); + +protected: + bool start(); + void stop(); + +private: + QGamepadManager::GamepadButton translateButton(int button); + + QTimer m_eventLoopTimer; + QMap<int, SDL_GameController*> m_indexForController; + QMap<int, int> m_instanceIdForIndex; +}; + +QT_END_NAMESPACE + +#endif // QSDLGAMEPADCONTROLLER_H diff --git a/src/plugins/gamepads/sdl2/sdl2.json b/src/plugins/gamepads/sdl2/sdl2.json new file mode 100644 index 0000000..d2bd585 --- /dev/null +++ b/src/plugins/gamepads/sdl2/sdl2.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "sdl2" ] +} diff --git a/src/plugins/gamepads/sdl2/sdl2.pro b/src/plugins/gamepads/sdl2/sdl2.pro new file mode 100644 index 0000000..3d53711 --- /dev/null +++ b/src/plugins/gamepads/sdl2/sdl2.pro @@ -0,0 +1,27 @@ +TARGET = sdl2gamepad +QT += gamepad gamepad-private + +PLUGIN_TYPE = gamepads +PLUGIN_CLASS_NAME = QSdl2GamepadBackendPlugin +load(qt_plugin) + +osx { + INCLUDEPATH += /Library/Frameworks/SDL2.framework/Headers + LIBS += -F/Library/Frameworks/ -framework SDL2 +} + +unix:!osx{ + CONFIG += link_pkgconfig + PKGCONFIG += sdl2 +} + +win32: LIBS += -lSDL2 + +HEADERS += qsdlgamepadbackend_p.h +SOURCES += \ + qsdlgamepadbackend.cpp \ + main.cpp + +OTHER_FILES += \ + sdl2.json + diff --git a/src/plugins/gamepads/xinput/main.cpp b/src/plugins/gamepads/xinput/main.cpp new file mode 100644 index 0000000..a5eb0f8 --- /dev/null +++ b/src/plugins/gamepads/xinput/main.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGamepad/private/qgamepadbackendfactory_p.h> +#include <QtGamepad/private/qgamepadbackendplugin_p.h> + +#include "qxinputgamepadbackend_p.h" + +QT_BEGIN_NAMESPACE + +class QXInputGamepadBackendPlugin : public QGamepadBackendPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QtGamepadBackendFactoryInterface_iid FILE "xinput.json") +public: + QGamepadBackend *create(const QString &key, const QStringList ¶mList) Q_DECL_OVERRIDE; +}; + +QGamepadBackend *QXInputGamepadBackendPlugin::create(const QString &key, const QStringList ¶mList) +{ + Q_UNUSED(key) + Q_UNUSED(paramList) + + return new QXInputGamepadBackend; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/gamepads/xinput/qxinputgamepadbackend.cpp b/src/plugins/gamepads/xinput/qxinputgamepadbackend.cpp new file mode 100644 index 0000000..97680cb --- /dev/null +++ b/src/plugins/gamepads/xinput/qxinputgamepadbackend.cpp @@ -0,0 +1,291 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qxinputgamepadbackend_p.h" +#include <QtCore/QLoggingCategory> +#include <QtCore/QThread> +#include <qmath.h> +#include <windows.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcXGB, "qt.gamepad") + +#define POLL_SLEEP_MS 5 +#define POLL_SLOT_CHECK_MS 4000 + +#define XUSER_MAX_COUNT 4 + +#define XINPUT_GAMEPAD_DPAD_UP 0x0001 +#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 +#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004 +#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 +#define XINPUT_GAMEPAD_START 0x0010 +#define XINPUT_GAMEPAD_BACK 0x0020 +#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040 +#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 +#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 +#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 +#define XINPUT_GAMEPAD_A 0x1000 +#define XINPUT_GAMEPAD_B 0x2000 +#define XINPUT_GAMEPAD_X 0x4000 +#define XINPUT_GAMEPAD_Y 0x8000 + +#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849 +#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689 +#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30 + +struct XINPUT_GAMEPAD +{ + unsigned short wButtons; + unsigned char bLeftTrigger; + unsigned char bRightTrigger; + short sThumbLX; + short sThumbLY; + short sThumbRX; + short sThumbRY; +}; + +struct XINPUT_STATE +{ + unsigned long dwPacketNumber; + XINPUT_GAMEPAD Gamepad; +}; + +typedef DWORD (WINAPI *XInputGetState_t)(DWORD dwUserIndex, XINPUT_STATE *pState); +static XInputGetState_t XInputGetState; + +class QXInputThread : public QThread +{ +public: + QXInputThread(QXInputGamepadBackend *backend); + void run() Q_DECL_OVERRIDE; + void signalQuit() { m_quit.fetchAndStoreAcquire(1); } + +private: + void dispatch(int idx, XINPUT_GAMEPAD *state); + + QXInputGamepadBackend *m_backend; + QAtomicInt m_quit; + struct Controller { + bool connected; + int skippedPolls; + unsigned long lastPacketNumber; + // State cache. Only want to emit signals for values that really change. + unsigned short buttons; + unsigned char triggers[2]; + double axis[2][2]; + } m_controllers[XUSER_MAX_COUNT]; +}; + +QXInputThread::QXInputThread(QXInputGamepadBackend *backend) + : m_backend(backend), + m_quit(false) +{ + memset(m_controllers, 0, sizeof(m_controllers)); +} + +void QXInputThread::dispatch(int idx, XINPUT_GAMEPAD *state) +{ + static const struct ButtonMap { + unsigned short xbutton; + QGamepadManager::GamepadButton qbutton; + } buttonMap[] = { + { XINPUT_GAMEPAD_DPAD_UP, QGamepadManager::ButtonUp }, + { XINPUT_GAMEPAD_DPAD_DOWN, QGamepadManager::ButtonDown }, + { XINPUT_GAMEPAD_DPAD_LEFT, QGamepadManager::ButtonLeft }, + { XINPUT_GAMEPAD_DPAD_RIGHT, QGamepadManager::ButtonRight }, + { XINPUT_GAMEPAD_START, QGamepadManager::ButtonStart }, + { XINPUT_GAMEPAD_BACK, QGamepadManager::ButtonSelect }, + { XINPUT_GAMEPAD_LEFT_SHOULDER, QGamepadManager::ButtonL1 }, + { XINPUT_GAMEPAD_RIGHT_SHOULDER, QGamepadManager::ButtonR1 }, + { XINPUT_GAMEPAD_LEFT_THUMB, QGamepadManager::ButtonL3 }, + { XINPUT_GAMEPAD_RIGHT_THUMB, QGamepadManager::ButtonR3 }, + { XINPUT_GAMEPAD_A, QGamepadManager::ButtonA }, + { XINPUT_GAMEPAD_B, QGamepadManager::ButtonB }, + { XINPUT_GAMEPAD_X, QGamepadManager::ButtonX }, + { XINPUT_GAMEPAD_Y, QGamepadManager::ButtonY } + }; + for (int i = 0; i < sizeof(buttonMap) / sizeof(ButtonMap); ++i) { + const unsigned short xb = buttonMap[i].xbutton; + unsigned short isDown = state->wButtons & xb; + if (isDown != (m_controllers[idx].buttons & xb)) { + if (isDown) { + m_controllers[idx].buttons |= xb; + emit m_backend->gamepadButtonPressed(idx, buttonMap[i].qbutton, 1); + } else { + m_controllers[idx].buttons &= ~xb; + emit m_backend->gamepadButtonReleased(idx, buttonMap[i].qbutton); + } + } + } + + if (m_controllers[idx].triggers[0] != state->bLeftTrigger) { + m_controllers[idx].triggers[0] = state->bLeftTrigger; + const double value = state->bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD + ? (state->bLeftTrigger - XINPUT_GAMEPAD_TRIGGER_THRESHOLD) + / (255.0 - XINPUT_GAMEPAD_TRIGGER_THRESHOLD) + : 0.0; + if (!qFuzzyIsNull(value)) + emit m_backend->gamepadButtonPressed(idx, QGamepadManager::ButtonL2, value); + else + emit m_backend->gamepadButtonReleased(idx, QGamepadManager::ButtonL2); + } + if (m_controllers[idx].triggers[1] != state->bRightTrigger) { + m_controllers[idx].triggers[1] = state->bRightTrigger; + const double value = state->bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD + ? (state->bRightTrigger - XINPUT_GAMEPAD_TRIGGER_THRESHOLD) + / (255.0 - XINPUT_GAMEPAD_TRIGGER_THRESHOLD) + : 0.0; + if (!qFuzzyIsNull(value)) + emit m_backend->gamepadButtonPressed(idx, QGamepadManager::ButtonR2, value); + else + emit m_backend->gamepadButtonReleased(idx, QGamepadManager::ButtonR2); + } + + double x, y; + if (qSqrt(state->sThumbLX * state->sThumbLX + state->sThumbLY * state->sThumbLY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { + x = 2 * (state->sThumbLX + 32768.0) / 65535.0 - 1.0; + y = 2 * (-state->sThumbLY + 32768.0) / 65535.0 - 1.0; + } else { + x = y = 0; + } + if (m_controllers[idx].axis[0][0] != x) { + m_controllers[idx].axis[0][0] = x; + emit m_backend->gamepadAxisMoved(idx, QGamepadManager::AxisLeftX, x); + } + if (m_controllers[idx].axis[0][1] != y) { + m_controllers[idx].axis[0][1] = y; + emit m_backend->gamepadAxisMoved(idx, QGamepadManager::AxisLeftY, y); + } + if (qSqrt(state->sThumbRX * state->sThumbRX + state->sThumbRY * state->sThumbRY) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { + x = 2 * (state->sThumbRX + 32768.0) / 65535.0 - 1.0; + y = 2 * (-state->sThumbRY + 32768.0) / 65535.0 - 1.0; + } else { + x = y = 0; + } + if (m_controllers[idx].axis[1][0] != x) { + m_controllers[idx].axis[1][0] = x; + emit m_backend->gamepadAxisMoved(idx, QGamepadManager::AxisRightX, x); + } + if (m_controllers[idx].axis[1][1] != y) { + m_controllers[idx].axis[1][1] = y; + emit m_backend->gamepadAxisMoved(idx, QGamepadManager::AxisRightY, y); + } +} + +void QXInputThread::run() +{ + qCDebug(lcXGB, "XInput thread running"); + bool firstPoll = true; + while (!m_quit.testAndSetAcquire(1, 0)) { + for (int i = 0; i < XUSER_MAX_COUNT; ++i) { + Controller *controller = m_controllers + i; + + if (!firstPoll && !controller->connected && controller->skippedPolls < POLL_SLOT_CHECK_MS / POLL_SLEEP_MS) { + controller->skippedPolls++; + continue; + } + + firstPoll = false; + controller->skippedPolls = 0; + XINPUT_STATE state; + memset(&state, 0, sizeof(state)); + + if (XInputGetState(i, &state) == ERROR_SUCCESS) { + if (controller->connected) { + if (controller->lastPacketNumber != state.dwPacketNumber) { + controller->lastPacketNumber = state.dwPacketNumber; + dispatch(i, &state.Gamepad); + } + } else { + controller->connected = true; + controller->lastPacketNumber = state.dwPacketNumber; + emit m_backend->gamepadAdded(i); + dispatch(i, &state.Gamepad); + } + } else { + if (controller->connected) { + controller->connected = false; + emit m_backend->gamepadRemoved(i); + } + } + } + + Sleep(POLL_SLEEP_MS); + } + qCDebug(lcXGB, "XInput thread stopping"); +} + +QXInputGamepadBackend::QXInputGamepadBackend() + : m_thread(0) +{ +} + +bool QXInputGamepadBackend::start() +{ + qCDebug(lcXGB) << "start"; + + m_lib.setFileName(QStringLiteral("xinput1_4.dll")); + if (!m_lib.load()) { + m_lib.setFileName(QStringLiteral("xinput1_3.dll")); + m_lib.load(); + } + + if (m_lib.isLoaded()) { + qCDebug(lcXGB, "Loaded XInput library %s", qPrintable(m_lib.fileName())); + XInputGetState = (XInputGetState_t) m_lib.resolve("XInputGetState"); + if (XInputGetState) { + m_thread = new QXInputThread(this); + m_thread->start(); + } else { + qWarning("Failed to resolve XInputGetState"); + } + } else { + qWarning("Failed to load XInput library %s", qPrintable(m_lib.fileName())); + } + + return m_lib.isLoaded(); +} + +void QXInputGamepadBackend::stop() +{ + qCDebug(lcXGB) << "stop"; + m_thread->signalQuit(); + m_thread->wait(); + XInputGetState = 0; +} + +QT_END_NAMESPACE diff --git a/src/plugins/gamepads/xinput/qxinputgamepadbackend_p.h b/src/plugins/gamepads/xinput/qxinputgamepadbackend_p.h new file mode 100644 index 0000000..42f7a4a --- /dev/null +++ b/src/plugins/gamepads/xinput/qxinputgamepadbackend_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gamepad module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QXINPUTGAMEPADCONTROLLER_H +#define QXINPUTGAMEPADCONTROLLER_H + +#include <QtGamepad/QGamepadManager> +#include <QtGamepad/private/qgamepadbackend_p.h> +#include <QtCore/QLibrary> + +QT_BEGIN_NAMESPACE + +class QXInputThread; + +class QXInputGamepadBackend : public QGamepadBackend +{ + Q_OBJECT + +public: + QXInputGamepadBackend(); + bool start() Q_DECL_OVERRIDE; + void stop() Q_DECL_OVERRIDE; + +private: + QXInputThread *m_thread; + QLibrary m_lib; +}; + +QT_END_NAMESPACE + +#endif // QXINPUTGAMEPADCONTROLLER_H diff --git a/src/plugins/gamepads/xinput/xinput.json b/src/plugins/gamepads/xinput/xinput.json new file mode 100644 index 0000000..f8e3fb2 --- /dev/null +++ b/src/plugins/gamepads/xinput/xinput.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "xinput" ] +} diff --git a/src/plugins/gamepads/xinput/xinput.pro b/src/plugins/gamepads/xinput/xinput.pro new file mode 100644 index 0000000..5dac854 --- /dev/null +++ b/src/plugins/gamepads/xinput/xinput.pro @@ -0,0 +1,14 @@ +TARGET = xinputgamepad +QT += gamepad gamepad-private + +PLUGIN_TYPE = gamepads +PLUGIN_CLASS_NAME = QXInputGamepadBackendPlugin +load(qt_plugin) + +HEADERS += qxinputgamepadbackend_p.h +SOURCES += \ + qxinputgamepadbackend.cpp \ + main.cpp + +OTHER_FILES += \ + xinput.json diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro new file mode 100644 index 0000000..ac81e82 --- /dev/null +++ b/src/plugins/plugins.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += gamepads diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 0000000..ed7c34c --- /dev/null +++ b/src/src.pro @@ -0,0 +1,11 @@ +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS += \ + gamepad \ + plugins + +qtHaveModule(quick) { + src_imports.subdir = imports + src_imports.depends = gamepad + SUBDIRS += src_imports +} diff --git a/sync.profile b/sync.profile new file mode 100644 index 0000000..8f07116 --- /dev/null +++ b/sync.profile @@ -0,0 +1,14 @@ +%modules = ( # path to module name map + "QtGamepad" => "$basedir/src/gamepad", +); +%moduleheaders = ( # restrict the module headers to those found in relative path +); +# Module dependencies. +# Every module that is required to build this module should have one entry. +# Each of the module version specifiers can take one of the following values: +# - A specific Git revision. +# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch) +# +%dependencies = ( + "qtbase" => "refs/heads/master", +); diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro new file mode 100644 index 0000000..fce98ce --- /dev/null +++ b/tests/auto/auto.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt new file mode 100644 index 0000000..3d77b9e --- /dev/null +++ b/tests/auto/cmake/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 2.8) + +project(qmake_cmake_files) + +enable_testing() + +find_package(Qt5Core REQUIRED) + +include("${_Qt5CTestMacros}") + +test_module_includes( +) diff --git a/tests/auto/cmake/cmake.pro b/tests/auto/cmake/cmake.pro new file mode 100644 index 0000000..929589a --- /dev/null +++ b/tests/auto/cmake/cmake.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs + +CMAKE_QT_MODULES_UNDER_TEST = gamepad + +CONFIG += ctest_testcase diff --git a/tests/tests.pro b/tests/tests.pro new file mode 100644 index 0000000..f887d53 --- /dev/null +++ b/tests/tests.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs + +!package: SUBDIRS += auto |