From 928cd41fa960f458e79a64491fde622470a694f2 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 16 Jan 2017 15:18:13 +0100 Subject: [PATCH 001/792] Initial import Lifted out of the monolithic Akela library. Signed-off-by: Gergely Nagy --- .gitignore | 2 + COPYING | 674 +++++++++++++++++++++++++++++ README.md | 78 ++++ examples/MagicCombo/MagicCombo.ino | 68 +++ library.properties | 10 + src/Akela-MagicCombo.h | 21 + src/Akela/MagicCombo.cpp | 76 ++++ src/Akela/MagicCombo.h | 50 +++ 8 files changed, 979 insertions(+) create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 README.md create mode 100644 examples/MagicCombo/MagicCombo.ino create mode 100644 library.properties create mode 100644 src/Akela-MagicCombo.h create mode 100644 src/Akela/MagicCombo.cpp create mode 100644 src/Akela/MagicCombo.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..aead9485 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.#* +*~ diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/README.md b/README.md new file mode 100644 index 00000000..d784f468 --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# Akela-MagicCombo + +The `MagicCombo` extension provides a way to perform custom actions when a +particular set of keys are held down together. The functionality assigned to +these keys are not changed, and the custom action triggers as long as all keys +within the set are pressed. The order in which they were pressed do not matter. + +This can be used to tie complex actions to key chords. + +## Using the extension + +To use the extension, we must include the header, create a dictionary, and +configure the plugin to use it: + +```c++ +#include + +static const Akela::MagicCombo::dictionary_t dictionary[] PROGMEM = { + {R1C3 | R2C1 | R2C4 | R2C7, // left hand, + R0C11 | R1C12 | R2C14 //right hand + }, + {0, 0} +}; + +void setup (void) { + MagicCombo.configure (dictionary); + + Keyboardio.setup (KEYMAP_SIZE); + Keyboardio.use (&MagicCombo, NULL); +} +``` + +The dictionary **must** reside in `PROGMEM`, and is a list of tuples. Each +element in the array has two fields: the left hand state, and the right hand +state upon which to trigger the custom action. Both of these are bit fields, +each bit set tells the extension that the key with that index must be held for +the action to trigger. It is recommended to use the `RxCy` macros of the core +`KeyboardioFirmware`, and *or* them together to form a bitfield. + +The dictionary **must** end with an element containing zero values for both the +left and the right halves. + +## Extension methods + +The extension provides a `MagicCombo` singleton object, with the following method: + +### `.configure(dictionary[, timeout])` + +> Configures the extension to use the supplied dictionary, and restrict it to +> fire at most once every `timeout` cycles. +> +> If the timeout is not specified, it defaults to `DEFAULT_TIMEOUT`, which in +> turn is 40 cycles. + +## Overrideable methods + +Whenever an combination is found to be held, the extension will trigger an +action, in each scan cycle until the keys remain held. This is done by calling +the overrideable `magicComboActions` function: + +### `magicComboActions(comboIndex, leftHand, rightHand)` + +> Called whenever a combination is found to be held. The function by default +> does nothing, and it is recommended to override it from within the Sketch. +> +> The first argument will be the index in the dictionary, the other two are the +> key states on the left and right halves, respectively. +> +> Plugins that build upon this extensions *should not* override this function, +> but provide helpers that can be called from it. An override should only happen +> in the Sketch. + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/Akela-Plugins/Akela-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino new file mode 100644 index 00000000..5f0cea20 --- /dev/null +++ b/examples/MagicCombo/MagicCombo.ino @@ -0,0 +1,68 @@ +/* -*- mode: c++ -*- + * Akela -- Animated Keyboardio Extension Library for Anything + * Copyright (C) 2016, 2017 Gergely Nagy + * + * 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 . + */ + +#include + +void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { + switch (comboIndex) { + case 0: + Serial.println ("It's a kind of magic!"); + break; + } +} + +static const Akela::MagicCombo::dictionary_t dictionary[] PROGMEM = { + {R1C3 | R2C1 | R2C4 | R2C7, // left hand, + R0C11 | R1C12 | R2C14 //right hand + }, + {0, 0} +}; + +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + ( + Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + + Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, + Key_skip + ), +}; + +void setup () { + Serial.begin (9600); + + MagicCombo.configure (dictionary); + + Keyboardio.setup (KEYMAP_SIZE); + Keyboardio.use (&MagicCombo, NULL); +} + +void loop () { + Keyboardio.loop (); +} diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..9d25317a --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Akela-MagicCombo +version=0.0.0 +author=Gergely Nagy +maintainer=Gergely Nagy +sentence=Magic combo framework for Keyboardio boards. +paragraph=Provides hooks for Keyboardio boards, to make it possible to run code on certain magic combinations. +category=Communication +url=https://github.com/Akela-Plugins/Akela-MagicCombo +architectures=avr +dot_a_linkage=true diff --git a/src/Akela-MagicCombo.h b/src/Akela-MagicCombo.h new file mode 100644 index 00000000..1366f253 --- /dev/null +++ b/src/Akela-MagicCombo.h @@ -0,0 +1,21 @@ +/* -*- mode: c++ -*- + * Akela -- Animated Keyboardio Extension Library for Anything + * Copyright (C) 2016, 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include diff --git a/src/Akela/MagicCombo.cpp b/src/Akela/MagicCombo.cpp new file mode 100644 index 00000000..3a19ea76 --- /dev/null +++ b/src/Akela/MagicCombo.cpp @@ -0,0 +1,76 @@ +/* -*- mode: c++ -*- + * Akela -- Animated Keyboardio Extension Library for Anything + * Copyright (C) 2016, 2017 Gergely Nagy + * + * 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 . + */ + +#include + +namespace Akela { + + const MagicCombo::dictionary_t *MagicCombo::dictionary; + uint8_t MagicCombo::timeOut; + uint8_t MagicCombo::timer; + + MagicCombo::MagicCombo (void) { + } + + void + MagicCombo::begin (void) { + loop_hook_add (this->loopHook); + } + + void + MagicCombo::configure (const MagicCombo::dictionary_t dictionary_[], uint8_t timeOut_) { + dictionary = (dictionary_t *)dictionary_; + timeOut = timeOut_; + } + + void + MagicCombo::loopHook (bool postClear) { + if (!dictionary || postClear) + return; + + if (timer && timer < timeOut) + timer++; + + for (byte i = 0;; i++) { + dictionary_t combo; + + combo.leftHand = pgm_read_dword (&(dictionary[i].leftHand)); + combo.rightHand = pgm_read_dword (&(dictionary[i].rightHand)); + + if (combo.leftHand == 0 && combo.rightHand == 0) + break; + + if (KeyboardHardware.leftHandState.all == combo.leftHand && + KeyboardHardware.rightHandState.all == combo.rightHand) { + if (timer == 0 || timer >= timeOut || timeOut == 0) { + magicComboActions (i, combo.leftHand, combo.rightHand); + timer = 1; + } + break; + } + } + } + +}; + +__attribute__((weak)) +void +magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { +} + +Akela::MagicCombo MagicCombo; diff --git a/src/Akela/MagicCombo.h b/src/Akela/MagicCombo.h new file mode 100644 index 00000000..c5338353 --- /dev/null +++ b/src/Akela/MagicCombo.h @@ -0,0 +1,50 @@ +/* -*- mode: c++ -*- + * Akela -- Animated Keyboardio Extension Library for Anything + * Copyright (C) 2016, 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include + +#define AKELA_MAGICCOMBO_TIMEOUT DEFAULT_TIMEOUT + +namespace Akela { + class MagicCombo : public KeyboardioPlugin { + public: + typedef struct { + uint32_t leftHand, rightHand; + } dictionary_t; + + MagicCombo (void); + + virtual void begin (void) final; + + static void configure (const dictionary_t dictionary[], uint8_t timeout); + static void configure (const dictionary_t dictionary[]) { configure (dictionary, AKELA_MAGICCOMBO_TIMEOUT); }; + + private: + static const dictionary_t *dictionary; + static uint8_t timeOut; + static uint8_t timer; + + static void loopHook (bool postClear); + }; +}; + +void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand); + +extern Akela::MagicCombo MagicCombo; From 1fdcaebef19b6a02291f613902be467f095a4062 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 16 Jan 2017 17:16:49 +0100 Subject: [PATCH 002/792] Add a status icon. Signed-off-by: Gergely Nagy --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index d784f468..56a60582 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Akela-MagicCombo +![status][st:stable] + + [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + The `MagicCombo` extension provides a way to perform custom actions when a particular set of keys are held down together. The functionality assigned to these keys are not changed, and the custom action triggers as long as all keys From 0c497f884ac83e0ef994ee1f54692f77e2ce5a93 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 17 Jan 2017 10:15:07 +0100 Subject: [PATCH 003/792] Move from Akela-Plugins to keyboardio Signed-off-by: Gergely Nagy --- README.md | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 56a60582..a748267d 100644 --- a/README.md +++ b/README.md @@ -81,4 +81,4 @@ the overrideable `magicComboActions` function: Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/Akela-Plugins/Akela-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino + [plugin:example]: https://github.com/keyboardio/Akela-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino diff --git a/library.properties b/library.properties index 9d25317a..d37921f8 100644 --- a/library.properties +++ b/library.properties @@ -5,6 +5,6 @@ maintainer=Gergely Nagy sentence=Magic combo framework for Keyboardio boards. paragraph=Provides hooks for Keyboardio boards, to make it possible to run code on certain magic combinations. category=Communication -url=https://github.com/Akela-Plugins/Akela-MagicCombo +url=https://github.com/keyboardio/Akela-MagicCombo architectures=avr dot_a_linkage=true From d78f8901cbd5e483c2169362786b99717a683259 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 21 Jan 2017 20:22:16 +0100 Subject: [PATCH 004/792] Initial import Signed-off-by: Gergely Nagy --- .gitignore | 2 + COPYING | 674 ++++++++++++++++++++++++++++++++++++++ README.md | 43 +++ library.properties | 10 + src/Akela-LED-Stalker.h | 21 ++ src/Akela/LED-Stalker.cpp | 84 +++++ src/Akela/LED-Stalker.h | 40 +++ 7 files changed, 874 insertions(+) create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Akela-LED-Stalker.h create mode 100644 src/Akela/LED-Stalker.cpp create mode 100644 src/Akela/LED-Stalker.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..aead9485 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.#* +*~ diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/README.md b/README.md new file mode 100644 index 00000000..7a15fdd7 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# Akela-LED-Stalker + +![status][st:experimental] + + [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + +A haunting effect, where the lights follow your fingers as you keep typing. +Always behind, always watching, always stalking the fingertips... + +The plugin simply lights up the LED below keys you press, and fades them away +soon after, producing a haunting trail effect. + +## Using the plugin + +To use the plugin, one needs to include the header, and activate the effect. It +is also possible to use a custom color instead of the white-ish default. + +```c++ +#include + +void setup () { + Keyboardio.setup (KEYMAP_SIZE); + + Keyboardio.use (&StalkerEffect, NULL); + + StalkerEffect.configure ({0x00, 0xff, 0xff}); +} +``` + +It is recommended to place the activation of the plugin (the `Keyboardio.use` +call) as early as possible, so the plugin can catch all relevant key presses. + +## Plugin methods + +The plugin provides the `StalkerEffect` object, which has the following +method: + +### `.configure(color)` + +> Set the color to use for highlighting pressed keys. If unset, will use the +> default white-ish color. diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..36458fc5 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Akela-LED-Stalker +version=0.0.0 +author=Gergely Nagy +maintainer=Gergely Nagy +sentence=Stalk keys pressed by lighting up and fading back the LED under them. +paragraph=Stalk keys pressed by lighting up and fading back the LED under them. +category=Communication +url=https://github.com/algernon/Akela-LED-Stalker +architectures=avr +dot_a_linkage=true diff --git a/src/Akela-LED-Stalker.h b/src/Akela-LED-Stalker.h new file mode 100644 index 00000000..1a48dc2e --- /dev/null +++ b/src/Akela-LED-Stalker.h @@ -0,0 +1,21 @@ +/* -*- mode: c++ -*- + * Akela -- Animated Keyboardio Extension Library for Anything + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include diff --git a/src/Akela/LED-Stalker.cpp b/src/Akela/LED-Stalker.cpp new file mode 100644 index 00000000..847dc2a1 --- /dev/null +++ b/src/Akela/LED-Stalker.cpp @@ -0,0 +1,84 @@ +/* -*- mode: c++ -*- + * Akela -- Animated Keyboardio Extension Library for Anything + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include + +namespace Akela { + namespace LEDEffects { + cRGB StalkerEffect::highlightColor = (cRGB) {64, 128, 128}; + uint8_t StalkerEffect::map[ROWS][COLS]; + + StalkerEffect::StalkerEffect (void) { + } + + void + StalkerEffect::begin (void) { + event_handler_hook_add (eventHandlerHook); + loop_hook_add (loopHook); + } + + void + StalkerEffect::configure (const cRGB highlightColor_) { + highlightColor = highlightColor_; + } + + Key + StalkerEffect::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) { + if (row >= ROWS || col >= COLS) + return mappedKey; + + if (key_is_pressed (keyState)) + map[row][col] = 0xff; + + return mappedKey; + } + + void + StalkerEffect::loopHook (bool postClear) { + if (postClear) + return; + + float mb = highlightColor.b / 255.0; + float mg = highlightColor.g / 255.0; + float mr = highlightColor.r / 255.0; + + for (byte r = 0; r < ROWS; r++) { + for (byte c = 0; c < COLS; c++) { + cRGB color = {(uint8_t)min(map[r][c] * mb, 255), + (uint8_t)min(map[r][c] * mg, 255), + (uint8_t)min(map[r][c] * mr, 255)}; + + if (map[r][c]) + led_set_crgb_at (r, c, color); + + if (map[r][c] >= 0xf0) + map[r][c]--; + else if (map[r][c] >= 0x40) + map[r][c] -= 16; + else if (map[r][c] >= 32) + map[r][c] -= 32; + else + map[r][c] = 0; + } + } + } + + }; +}; + +Akela::LEDEffects::StalkerEffect StalkerEffect; diff --git a/src/Akela/LED-Stalker.h b/src/Akela/LED-Stalker.h new file mode 100644 index 00000000..60a6debe --- /dev/null +++ b/src/Akela/LED-Stalker.h @@ -0,0 +1,40 @@ +/* -*- mode: c++ -*- + * Akela -- Animated Keyboardio Extension Library for Anything + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include + +namespace Akela { + namespace LEDEffects { + class StalkerEffect : public KeyboardioPlugin { + public: + StalkerEffect (void); + + static void configure (const cRGB highlightColor); + virtual void begin (void) final; + + private: + static cRGB highlightColor; + static uint8_t map[ROWS][COLS]; + + static Key eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState); + static void loopHook (bool postClear); + }; + }; +}; + +extern Akela::LEDEffects::StalkerEffect StalkerEffect; From 4177d0ae35490137b4a80f01ed3b1a234062d987 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 21 Jan 2017 22:10:02 +0100 Subject: [PATCH 005/792] Rework the plugin, to have customisable effects Signed-off-by: Gergely Nagy --- README.md | 42 ++++++++++++++++++------ src/Akela/LED-Stalker.cpp | 69 ++++++++++++++++++++++++++++++--------- src/Akela/LED-Stalker.h | 35 ++++++++++++++++++-- 3 files changed, 119 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 7a15fdd7..cd6fddc4 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,13 @@ [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 -A haunting effect, where the lights follow your fingers as you keep typing. -Always behind, always watching, always stalking the fingertips... - -The plugin simply lights up the LED below keys you press, and fades them away -soon after, producing a haunting trail effect. +The `StalkerEffect` plugin provides an interesting new typing experience: the +LEDs light up as you tap keys, and play one of the selected effects: a haunting +trail of ghostly white lights, or a blazing trail of fire. ## Using the plugin -To use the plugin, one needs to include the header, and activate the effect. It -is also possible to use a custom color instead of the white-ish default. +To use the plugin, one needs to include the header, and select the effect. ```c++ #include @@ -23,6 +20,7 @@ is also possible to use a custom color instead of the white-ish default. void setup () { Keyboardio.setup (KEYMAP_SIZE); + StalkerEffect.configure (STALKER (Haunt, {0xff, 0, 0})); Keyboardio.use (&StalkerEffect, NULL); StalkerEffect.configure ({0x00, 0xff, 0xff}); @@ -31,13 +29,37 @@ void setup () { It is recommended to place the activation of the plugin (the `Keyboardio.use` call) as early as possible, so the plugin can catch all relevant key presses. +The configuration can happen at any time, but using the `STALKER` macro is +highly recommended. ## Plugin methods The plugin provides the `StalkerEffect` object, which has the following method: -### `.configure(color)` +### `.configure(effect)` + +> Set the effect to use with the plugin. See below for a list. +> +> It is recommended to use the `STALKER` macro to declare the effect itself. + +## Plugin helpers + +### `STALKER(effect, params...)` + +> Returns an effect, to be used by the `.configure` method of the +> `StalkerEffect` object. Any arguments given to the macro, are also passed on +> to the effect. If the effect takes no arguments, use `NULL`. + +## Plugin effects + +The plugin provides the following effects: + +### `Haunt([color])` + +> A ghostly haunt effect, that trails the key taps with a ghostly white color +> (or any other color, if specified). + +### `BlazingTrail()` -> Set the color to use for highlighting pressed keys. If unset, will use the -> default white-ish color. +> A blazing trail of fire will follow our fingers! diff --git a/src/Akela/LED-Stalker.cpp b/src/Akela/LED-Stalker.cpp index 847dc2a1..c62d52eb 100644 --- a/src/Akela/LED-Stalker.cpp +++ b/src/Akela/LED-Stalker.cpp @@ -20,24 +20,24 @@ namespace Akela { namespace LEDEffects { - cRGB StalkerEffect::highlightColor = (cRGB) {64, 128, 128}; uint8_t StalkerEffect::map[ROWS][COLS]; + StalkerEffect::ColorComputer *StalkerEffect::colorComputer; StalkerEffect::StalkerEffect (void) { } void - StalkerEffect::begin (void) { - event_handler_hook_add (eventHandlerHook); - loop_hook_add (loopHook); + StalkerEffect::configure (ColorComputer *colorComputer_) { + colorComputer = colorComputer_; } void - StalkerEffect::configure (const cRGB highlightColor_) { - highlightColor = highlightColor_; + StalkerEffect::begin (void) { + event_handler_hook_add (eventHandlerHook); + loop_hook_add (loopHook); } - Key + Key StalkerEffect::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) { if (row >= ROWS || col >= COLS) return mappedKey; @@ -53,18 +53,13 @@ namespace Akela { if (postClear) return; - float mb = highlightColor.b / 255.0; - float mg = highlightColor.g / 255.0; - float mr = highlightColor.r / 255.0; + if (!colorComputer) + return; for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { - cRGB color = {(uint8_t)min(map[r][c] * mb, 255), - (uint8_t)min(map[r][c] * mg, 255), - (uint8_t)min(map[r][c] * mr, 255)}; - if (map[r][c]) - led_set_crgb_at (r, c, color); + led_set_crgb_at (r, c, colorComputer->compute (map[r][c])); if (map[r][c] >= 0xf0) map[r][c]--; @@ -78,6 +73,50 @@ namespace Akela { } } + namespace Stalker { + + // Haunt + float Haunt::mb; + float Haunt::mg; + float Haunt::mr; + + Haunt::Haunt (const cRGB highlightColor) { + mb = highlightColor.b / 255.0; + mg = highlightColor.g / 255.0; + mr = highlightColor.r / 255.0; + } + + cRGB + Haunt::compute (uint8_t step) { + cRGB color = {(uint8_t)min(step * mb, 255), + (uint8_t)min(step * mg, 255), + (uint8_t)min(step * mr, 255)}; + + return color; + } + + // BlazingTrail + BlazingTrail::BlazingTrail (...) { + } + + cRGB + BlazingTrail::compute (uint8_t step) { + cRGB color; + + color.b = 0; + color.r = step; + + if (step >= 0xf0) { + } else if (step >= 0x80) { + color.g = 0xa0 - step / 2; + } else + color.g = step; + + return color; + } + + }; + }; }; diff --git a/src/Akela/LED-Stalker.h b/src/Akela/LED-Stalker.h index 60a6debe..75fc3137 100644 --- a/src/Akela/LED-Stalker.h +++ b/src/Akela/LED-Stalker.h @@ -18,22 +18,53 @@ #include +#define STALKER(n, ...) (({static Akela::LEDEffects::Stalker::n _effect (__VA_ARGS__); &_effect;})) + namespace Akela { namespace LEDEffects { class StalkerEffect : public KeyboardioPlugin { public: + class ColorComputer { + public: + virtual cRGB compute (uint8_t step) = 0; + }; + StalkerEffect (void); - static void configure (const cRGB highlightColor); virtual void begin (void) final; + static void configure (ColorComputer *colorComputer); private: - static cRGB highlightColor; + static ColorComputer *colorComputer; static uint8_t map[ROWS][COLS]; static Key eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState); static void loopHook (bool postClear); }; + + namespace Stalker { + + class Haunt : public StalkerEffect::ColorComputer { + public: + Haunt (const cRGB highlightColor); + Haunt (void) : Haunt ({0x40, 0x80, 0x80}) {}; + Haunt (void *) : Haunt () {}; + + virtual cRGB compute (uint8_t step) final; + + private: + static float mr, mg, mb; + }; + + class BlazingTrail : public StalkerEffect::ColorComputer { + public: + BlazingTrail (...); + + virtual cRGB compute (uint8_t step) final; + }; + + }; + }; }; From 7fc47a28da0c54bd586a9244a94e949502f06570 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 21 Jan 2017 23:23:20 +0100 Subject: [PATCH 006/792] Move to the keyboardio organization Signed-off-by: Gergely Nagy --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 36458fc5..c1fc414d 100644 --- a/library.properties +++ b/library.properties @@ -5,6 +5,6 @@ maintainer=Gergely Nagy sentence=Stalk keys pressed by lighting up and fading back the LED under them. paragraph=Stalk keys pressed by lighting up and fading back the LED under them. category=Communication -url=https://github.com/algernon/Akela-LED-Stalker +url=https://github.com/keyboardio/Akela-LED-Stalker architectures=avr dot_a_linkage=true From c458408356e18d18803607225483dd030b64d6d4 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 22 Jan 2017 11:10:27 +0100 Subject: [PATCH 007/792] README: Remove the old configure from the example Signed-off-by: Gergely Nagy --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index cd6fddc4..163a687d 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,6 @@ void setup () { StalkerEffect.configure (STALKER (Haunt, {0xff, 0, 0})); Keyboardio.use (&StalkerEffect, NULL); - - StalkerEffect.configure ({0x00, 0xff, 0xff}); } ``` From 44fb59ededff30571f000b34f1cb9b1fc8f5bd5c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 22 Jan 2017 11:12:00 +0100 Subject: [PATCH 008/792] Add an example Signed-off-by: Gergely Nagy --- README.md | 7 ++++ examples/LED-Stalker/LED-Stalker.ino | 51 ++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 examples/LED-Stalker/LED-Stalker.ino diff --git a/README.md b/README.md index 163a687d..7afe95a1 100644 --- a/README.md +++ b/README.md @@ -61,3 +61,10 @@ The plugin provides the following effects: ### `BlazingTrail()` > A blazing trail of fire will follow our fingers! + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Akela-LED-Stalker/blob/master/examples/LED-Stalker/LED-Stalker.ino diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino new file mode 100644 index 00000000..c4fb6df5 --- /dev/null +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -0,0 +1,51 @@ +/* -*- mode: c++ -*- + * Akela -- Animated Keyboardio Extension Library for Anything + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include + +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + ( + Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + + Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, + Key_skip + ), +}; + +void setup () { + Keyboardio.setup (KEYMAP_SIZE); + + StalkerEffect.configure (STALKER (BlazingTrail, NULL)); + Keyboardio.use (&StalkerEffect, NULL); +} + +void loop () { + Keyboardio.loop (); +} From 11535dd716a775bbfec6a56cc75e8b8dfeb1666e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 23 Jan 2017 11:15:36 +0100 Subject: [PATCH 009/792] Turn the LED off at the end of the fade sequence Instead of relying on the active effect to turn the LED off, do so ourselves at the end. Fixes #1. Signed-off-by: Gergely Nagy --- src/Akela/LED-Stalker.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Akela/LED-Stalker.cpp b/src/Akela/LED-Stalker.cpp index c62d52eb..c39c1b2f 100644 --- a/src/Akela/LED-Stalker.cpp +++ b/src/Akela/LED-Stalker.cpp @@ -67,8 +67,10 @@ namespace Akela { map[r][c] -= 16; else if (map[r][c] >= 32) map[r][c] -= 32; - else + else { map[r][c] = 0; + led_set_crgb_at (r, c, (cRGB){0, 0, 0}); + } } } } From 80b832744292e4a2487a165521d4b1ab79ab0143 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 23 Jan 2017 18:57:39 +0100 Subject: [PATCH 010/792] Really, really fix the turn-off-at-the-end code Only turn the LED off if it was on before. Otherwise we will turn off those too that were not in the map yet. Signed-off-by: Gergely Nagy --- src/Akela/LED-Stalker.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Akela/LED-Stalker.cpp b/src/Akela/LED-Stalker.cpp index c39c1b2f..c119c147 100644 --- a/src/Akela/LED-Stalker.cpp +++ b/src/Akela/LED-Stalker.cpp @@ -61,16 +61,19 @@ namespace Akela { if (map[r][c]) led_set_crgb_at (r, c, colorComputer->compute (map[r][c])); + bool wasZero = (map[r][c] == 0); + if (map[r][c] >= 0xf0) map[r][c]--; else if (map[r][c] >= 0x40) map[r][c] -= 16; else if (map[r][c] >= 32) map[r][c] -= 32; - else { + else map[r][c] = 0; + + if (!wasZero && !map[r][c]) led_set_crgb_at (r, c, (cRGB){0, 0, 0}); - } } } } From 08508341969777e534c99b795e27192ccdf97b06 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 24 Jan 2017 22:47:42 +0100 Subject: [PATCH 011/792] Lifted out of core KeyboardioFirmware This is the same plugin that was in KeyboardioFirmware before, with a README, and a license file attached, and the URL corrected in library.properties. Signed-off-by: Gergely Nagy --- COPYING | 339 ++++++++++++++++++++++++++++++++++++++ README.md | 5 + library.properties | 10 ++ src/Keyboardio-Macros.cpp | 68 ++++++++ src/Keyboardio-Macros.h | 19 +++ src/MacroKeyDefs.h | 15 ++ src/MacroSteps.h | 26 +++ 7 files changed, 482 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Keyboardio-Macros.cpp create mode 100644 src/Keyboardio-Macros.h create mode 100644 src/MacroKeyDefs.h create mode 100644 src/MacroSteps.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..95e1b955 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Keyboardio-Macros + +This is a plugin for [KeyboardioFirmware][fw], that adds support for macros. + + [fw]: https://github.com/keyboardio/KeyboardioFirmware diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..5628c4b7 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Keyboardio-Macros +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=Macro keys for Keyboardio boards. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Keyboardio-Macros +architectures=avr +dot_a_linkage=true diff --git a/src/Keyboardio-Macros.cpp b/src/Keyboardio-Macros.cpp new file mode 100644 index 00000000..f5d0a1b9 --- /dev/null +++ b/src/Keyboardio-Macros.cpp @@ -0,0 +1,68 @@ +#include "Keyboardio-Macros.h" + +__attribute__((weak)) +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { + return MACRO_NONE; +} + +void Macros_::play(const macro_t *macro_p) { + macro_t macro = END; + uint8_t interval = 0; + Key key; + + if (!macro_p) + return; + + while (true) { + switch (macro = pgm_read_byte(macro_p++)) { + case MACRO_ACTION_STEP_INTERVAL: + interval = pgm_read_byte(macro_p++); + break; + case MACRO_ACTION_STEP_WAIT: { + uint8_t wait = pgm_read_byte(macro_p++); + delay(wait); + break; + } + case MACRO_ACTION_STEP_KEYDOWN: + key.flags = pgm_read_byte(macro_p++); + key.keyCode = pgm_read_byte(macro_p++); + handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); + Keyboard.sendReport(); + break; + case MACRO_ACTION_STEP_KEYUP: + key.flags = pgm_read_byte(macro_p++); + key.keyCode = pgm_read_byte(macro_p++); + handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); + Keyboard.sendReport(); + break; + case END: + default: + return; + } + + delay(interval); + } +} + +static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { + if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) + return mappedKey; + + if (!key_toggled_on(keyState)) + return Key_NoKey; + + const macro_t *m = macroAction(mappedKey.keyCode, keyState); + + Macros.play(m); + return Key_NoKey; +} + +Macros_::Macros_ (void) { +} + +void +Macros_::begin (void) { + event_handler_hook_add (handleMacroEvent); +} + +Macros_ Macros; diff --git a/src/Keyboardio-Macros.h b/src/Keyboardio-Macros.h new file mode 100644 index 00000000..172de9d7 --- /dev/null +++ b/src/Keyboardio-Macros.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "MacroKeyDefs.h" +#include "MacroSteps.h" + +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); + +class Macros_ : public KeyboardioPlugin { + public: + Macros_(void); + + virtual void begin(void) final; + + void play(const macro_t *macro_p); +}; + +extern Macros_ Macros; diff --git a/src/MacroKeyDefs.h b/src/MacroKeyDefs.h new file mode 100644 index 00000000..46c7b4b3 --- /dev/null +++ b/src/MacroKeyDefs.h @@ -0,0 +1,15 @@ +#pragma once + +#define IS_MACRO B00100000 + +#define M(n) (Key){ KEY_FLAGS|SYNTHETIC|IS_MACRO, n} +#define Key_macroKey1 M(1) +#define Key_macroKey2 M(2) +#define Key_macroKey3 M(3) +#define Key_macroKey4 M(4) +#define Key_macroKey5 M(5) +#define Key_macroKey6 M(6) +#define Key_macroKey7 M(7) +#define Key_macroKey8 M(8) +#define Key_macroKey9 M(9) +#define Key_macroKey10 M(10) diff --git a/src/MacroSteps.h b/src/MacroSteps.h new file mode 100644 index 00000000..2bef68cb --- /dev/null +++ b/src/MacroSteps.h @@ -0,0 +1,26 @@ +#pragma once + +typedef enum { + MACRO_ACTION_END, + + MACRO_ACTION_STEP_INTERVAL, + MACRO_ACTION_STEP_WAIT, + MACRO_ACTION_STEP_KEYDOWN, + MACRO_ACTION_STEP_KEYUP, +} MacroActionStepType; + +typedef uint8_t macro_t; + +#define MACRO_NONE 0 +#define MACRO(...) ({static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; }) +#define MACRODOWN(...) (key_toggled_on(keyState) ? MACRO(__VA_ARGS__) : MACRO_NONE) + +#define I(n) MACRO_ACTION_STEP_INTERVAL, n +#define W(n) MACRO_ACTION_STEP_WAIT, n +#define Dr(k) MACRO_ACTION_STEP_KEYDOWN, (k).flags, (k).keyCode +#define D(k) Dr(Key_ ## k) +#define Ur(k) MACRO_ACTION_STEP_KEYUP, (k).flags, (k).keyCode +#define U(k) Ur(Key_ ## k) +#define Tr(k) Dr(k), Ur(k) +#define T(k) D(k), U(k) +#define END MACRO_ACTION_END From 675cbc6cb6aee5819ee80bdf555d05574f84de4e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 24 Jan 2017 22:52:27 +0100 Subject: [PATCH 012/792] Lifted out of KeyboardioFirmware This is the same Keyboardio-MouseKeys that lived in core KeyboardioFirmware up until this point. It has been lifted out, the same GPL-2 license file added, along with a README, and the URL in library.properties has been updated. Signed-off-by: Gergely Nagy --- COPYING | 339 +++++++++++++++++++++++++++++++++++ README.md | 5 + library.properties | 10 ++ src/Keyboardio-MouseKeys.cpp | 68 +++++++ src/Keyboardio-MouseKeys.h | 13 ++ src/MouseKeyDefs.h | 41 +++++ src/MouseWrapper.cpp | 120 +++++++++++++ src/MouseWrapper.h | 56 ++++++ 8 files changed, 652 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Keyboardio-MouseKeys.cpp create mode 100644 src/Keyboardio-MouseKeys.h create mode 100644 src/MouseKeyDefs.h create mode 100644 src/MouseWrapper.cpp create mode 100644 src/MouseWrapper.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..e06bd6c6 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Keyboardio-MouseKeys + +This is a plugin for [KeyboardioFirmware][fw], that adds support for mouse keys. + + [fw]: https://github.com/keyboardio/KeyboardioFirmware diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..23cd518c --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Keyboardio-MouseKeys +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=Mouse keys for Keyboardio boards. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Keyboardio-MouseKeys +architectures=avr +dot_a_linkage=true \ No newline at end of file diff --git a/src/Keyboardio-MouseKeys.cpp b/src/Keyboardio-MouseKeys.cpp new file mode 100644 index 00000000..aba457a0 --- /dev/null +++ b/src/Keyboardio-MouseKeys.cpp @@ -0,0 +1,68 @@ +#include + +#include "Keyboardio-MouseKeys.h" +#include "MouseWrapper.h" +#include "KeyboardioFirmware.h" + +static void handle_mouse_key_event(Key mappedKey, uint8_t keyState) { + if (key_toggled_off(keyState)) { + if (mappedKey.keyCode & KEY_MOUSE_UP || mappedKey.keyCode & KEY_MOUSE_DOWN) { + MouseWrapper.mouseActiveForCyclesY=0; + } + if (mappedKey.keyCode & KEY_MOUSE_LEFT || mappedKey.keyCode & KEY_MOUSE_RIGHT) { + MouseWrapper.mouseActiveForCyclesX=0; + } + } + + if (!key_is_pressed(keyState)) + return; + + if (mappedKey.keyCode & KEY_MOUSE_UP) { + MouseWrapper.move(0,-1); + } else if (mappedKey.keyCode & KEY_MOUSE_DOWN) { + MouseWrapper.move(0,1); + } + + if (mappedKey.keyCode & KEY_MOUSE_LEFT) { + MouseWrapper.move(-1,0); + } else if (mappedKey.keyCode & KEY_MOUSE_RIGHT) { + MouseWrapper.move(1,0); + } +} + +static Key handleMouseKeys(Key mappedKey, byte row, byte col, uint8_t keyState) { + if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY)) + return mappedKey; + + if (mappedKey.keyCode & KEY_MOUSE_BUTTON) { + uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; + + if (key_toggled_on(keyState)) { + MouseWrapper.press_button(button); + } else if (key_toggled_off(keyState)) { + MouseWrapper.release_button(button); + } + } else if (!(mappedKey.keyCode & KEY_MOUSE_WARP)) { + handle_mouse_key_event(mappedKey, keyState); + } else if (key_toggled_on(keyState)) { + if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { + // we don't pass in the left and up values because those are the + // default, "no-op" conditionals + MouseWrapper.warp( ((mappedKey.keyCode & KEY_MOUSE_WARP_END) ? WARP_END : 0x00) | + ((mappedKey.keyCode & KEY_MOUSE_DOWN) ? WARP_DOWN : 0x00) | + ((mappedKey.keyCode & KEY_MOUSE_RIGHT) ? WARP_RIGHT : 0x00) ); + } + } + + return Key_NoKey; +} + +MouseKeys_::MouseKeys_(void) { +} + +void +MouseKeys_::begin (void) { + event_handler_hook_add (handleMouseKeys); +} + +MouseKeys_ MouseKeys; diff --git a/src/Keyboardio-MouseKeys.h b/src/Keyboardio-MouseKeys.h new file mode 100644 index 00000000..da24ec57 --- /dev/null +++ b/src/Keyboardio-MouseKeys.h @@ -0,0 +1,13 @@ +#pragma once + +#include "KeyboardioFirmware.h" +#include "MouseKeyDefs.h" + +class MouseKeys_ : public KeyboardioPlugin { + public: + MouseKeys_ (void); + + virtual void begin(void) final; +}; + +extern MouseKeys_ MouseKeys; diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h new file mode 100644 index 00000000..b8479b27 --- /dev/null +++ b/src/MouseKeyDefs.h @@ -0,0 +1,41 @@ +#pragma once + +#define IS_MOUSE_KEY B00010000 + +// Synthetic, not internal +#define KEY_MOUSE_BTN_L 0x01 // Synthetic key +#define KEY_MOUSE_BTN_M 0x02 // Synthetic key +#define KEY_MOUSE_BTN_R 0x03 // Synthetic key + + +#define KEY_MOUSE_UP B0000001 +#define KEY_MOUSE_DOWN B0000010 +#define KEY_MOUSE_LEFT B0000100 +#define KEY_MOUSE_RIGHT B0001000 +#define KEY_MOUSE_BUTTON B0010000 +#define KEY_MOUSE_WARP B0100000 +#define KEY_MOUSE_WARP_END B1000000 + + +#define Key_mouseWarpNW (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT } +#define Key_mouseWarpNE (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_RIGHT } +#define Key_mouseWarpSW (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_LEFT } +#define Key_mouseWarpSE (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT } +#define Key_mouseWarpEnd (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_WARP_END} + + +#define Key_mouseUpL (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_UP | KEY_MOUSE_LEFT } +#define Key_mouseUp (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_UP } +#define Key_mouseUpR (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_UP | KEY_MOUSE_RIGHT } +#define Key_mouseL (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_LEFT } +#define Key_mouseR (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_RIGHT } +#define Key_mouseDnL (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_DOWN | KEY_MOUSE_LEFT } +#define Key_mouseDn (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_DOWN } +#define Key_mouseDnR (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT } +#define Key_mouseScrollUp +#define Key_mouseScrollDn +#define Key_mouseScrollL +#define Key_mouseScrollR +#define Key_mouseBtnL (Key){ KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY, KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_L } +#define Key_mouseBtnM (Key){ KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY, KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_M } +#define Key_mouseBtnR (Key){ KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY, KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_R } diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp new file mode 100644 index 00000000..8426f044 --- /dev/null +++ b/src/MouseWrapper.cpp @@ -0,0 +1,120 @@ + +// Mouse-related methods +// +// +#include "MouseWrapper.h" + + +MouseWrapper_::MouseWrapper_(void) { + Mouse.begin(); + AbsoluteMouse.begin(); +} + +void MouseWrapper_::press_button(uint8_t button) { + Mouse.press(button); + end_warping(); + +} + +void MouseWrapper_::release_button(uint8_t button) { + Mouse.release(button); +} + + +void MouseWrapper_::warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width) { + uint16_t x_center = left + width/2; + uint16_t y_center = top + height/2; + AbsoluteMouse.moveTo(x_center,y_center); +} + + + + + +void MouseWrapper_::begin_warping() { + section_left = WARP_ABS_LEFT; + section_top = WARP_ABS_TOP; + next_width = MAX_WARP_WIDTH; + next_height = MAX_WARP_HEIGHT; + is_warping = true; +} + +void MouseWrapper_::end_warping() { + is_warping= false; +} + +void MouseWrapper_::warp(uint8_t warp_cmd) { + if (is_warping == false) { + begin_warping(); + } + + + if ( warp_cmd & WARP_END) { + end_warping(); + return; + } + + + next_width = next_width / 2; + next_height = next_height/2; + + if (warp_cmd & WARP_UP) { +// Serial.print(" - up "); + } else if (warp_cmd & WARP_DOWN) { +// Serial.print(" - down "); + section_top = section_top + next_height; + } + + if (warp_cmd & WARP_LEFT) { + // Serial.print(" - left "); + } else if (warp_cmd & WARP_RIGHT) { + // Serial.print(" - right "); + section_left = section_left + next_width; + } + + warp_jump(section_left, section_top, next_height,next_width); + +} + + +// cubic wave function based on code from FastLED +uint8_t MouseWrapper_::acceleration(uint8_t cycles) { + uint8_t i = cycles; + + if( i & 0x80) { + i = 255 - i; + } + + i = i << 1; + + uint8_t ii = (i*i) >> 8; + uint8_t iii = (ii*i) >> 8; + + i = (( (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii))) / 2) + ACCELERATION_FLOOR; + + if ( i > ACCELERATION_CEIL) { + i = ACCELERATION_CEIL; + } + return i; +} + + +void MouseWrapper_::move( int8_t x, int8_t y) { + int16_t moveX =0; + int16_t moveY = 0; + if (x != 0 ) { + if (mouseActiveForCyclesX < 255) { mouseActiveForCyclesX++;} + moveX = (x * acceleration(mouseActiveForCyclesX)); + } + if (y != 0) { + if (mouseActiveForCyclesY < 255) { mouseActiveForCyclesY++;} + moveY = (y * acceleration(mouseActiveForCyclesY)); + + } + + end_warping(); + Mouse.move(moveX, moveY, 0); + +} + +MouseWrapper_ MouseWrapper; diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h new file mode 100644 index 00000000..4e8b7fd6 --- /dev/null +++ b/src/MouseWrapper.h @@ -0,0 +1,56 @@ +#pragma once + +#include "Arduino.h" +#include "KeyboardioHID.h" + +// Warping commands + +#define WARP_END 1 +#define WARP_UP 2 +#define WARP_DOWN 4 +#define WARP_LEFT 8 +#define WARP_RIGHT 16 + + + +// apparently, the mac discards 15% of the value space for mouse movement. +// need to test this on other platforms + +#define MAX_WARP_WIDTH 32767 +#define MAX_WARP_HEIGHT 32767 + +#define WARP_ABS_TOP 0 +#define WARP_ABS_LEFT 0 + +// Mouse acceleration + +// we want the whole s curve, not just the bit +// that's usually above the x and y axes; +#define ACCELERATION_FLOOR 2 +#define ACCELERATION_CEIL 50 + + +class MouseWrapper_ { + public: + MouseWrapper_(void); + void move( int8_t x, int8_t y); + void warp(uint8_t warp_cmd); + void press_button(uint8_t button); + void release_button(uint8_t button); + uint8_t mouseActiveForCyclesX = 0; + uint8_t mouseActiveForCyclesY = 0; + + private: + uint16_t next_width = 0; + uint16_t next_height = 0; + uint16_t section_top = 0; + uint16_t section_left = 0; + boolean is_warping = false; + + uint8_t acceleration (uint8_t cycles); + void begin_warping(); + void end_warping(); + void warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width); + +}; +extern MouseWrapper_ MouseWrapper; From 6337d878bbd0127163faea6c57f59178586a290f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 25 Jan 2017 10:54:49 +0100 Subject: [PATCH 013/792] Adjusted the M() macro to reflect the flags/keyCode swap Signed-off-by: Gergely Nagy --- src/MacroKeyDefs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MacroKeyDefs.h b/src/MacroKeyDefs.h index 46c7b4b3..4907c7a2 100644 --- a/src/MacroKeyDefs.h +++ b/src/MacroKeyDefs.h @@ -2,7 +2,7 @@ #define IS_MACRO B00100000 -#define M(n) (Key){ KEY_FLAGS|SYNTHETIC|IS_MACRO, n} +#define M(n) (Key){ n, KEY_FLAGS|SYNTHETIC|IS_MACRO } #define Key_macroKey1 M(1) #define Key_macroKey2 M(2) #define Key_macroKey3 M(3) From 6d2587f7afb05b0b12cec30bee3d930c5c55e377 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 25 Jan 2017 10:59:21 +0100 Subject: [PATCH 014/792] Adjust for the flags/keyCode swap Signed-off-by: Gergely Nagy --- src/MouseKeyDefs.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index b8479b27..237eef24 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -17,25 +17,25 @@ #define KEY_MOUSE_WARP_END B1000000 -#define Key_mouseWarpNW (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT } -#define Key_mouseWarpNE (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_RIGHT } -#define Key_mouseWarpSW (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_LEFT } -#define Key_mouseWarpSE (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT } -#define Key_mouseWarpEnd (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_WARP| KEY_MOUSE_WARP_END} - - -#define Key_mouseUpL (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_UP | KEY_MOUSE_LEFT } -#define Key_mouseUp (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_UP } -#define Key_mouseUpR (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_UP | KEY_MOUSE_RIGHT } -#define Key_mouseL (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_LEFT } -#define Key_mouseR (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_RIGHT } -#define Key_mouseDnL (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_DOWN | KEY_MOUSE_LEFT } -#define Key_mouseDn (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_DOWN } -#define Key_mouseDnR (Key){ KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY, KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT } +#define Key_mouseWarpNW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseWarpNE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseWarpSW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseWarpSE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseWarpEnd (Key) { KEY_MOUSE_WARP| KEY_MOUSE_WARP_END, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } + + +#define Key_mouseUpL (Key) { KEY_MOUSE_UP | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseUp (Key) { KEY_MOUSE_UP, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseUpR (Key) { KEY_MOUSE_UP | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseL (Key) { KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseR (Key) { KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseDnL (Key) { KEY_MOUSE_DOWN | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseDn (Key) { KEY_MOUSE_DOWN, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseDnR (Key) { KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseScrollUp #define Key_mouseScrollDn #define Key_mouseScrollL #define Key_mouseScrollR -#define Key_mouseBtnL (Key){ KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY, KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_L } -#define Key_mouseBtnM (Key){ KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY, KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_M } -#define Key_mouseBtnR (Key){ KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY, KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_R } +#define Key_mouseBtnL (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_L, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } +#define Key_mouseBtnM (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_M, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } +#define Key_mouseBtnR (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_R, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } From 53e36c13e2a00972cc29a390bf4643fd8fa3a791 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 09:11:58 +0100 Subject: [PATCH 015/792] Lift out the LED control & effect parts from the core This is a slightly tweaked version of LEDControl from core KeyboardioFirmware, along with the built-in LED effects. The one major change is that LED sync is now called just before the update, instead of at the end of the main loop. This, however, should not be a noticeable change. Signed-off-by: Gergely Nagy --- COPYING | 339 ++++++++++++++++++++++++++++++++++ README.md | 6 + library.properties | 10 + src/BootAnimation.cpp | 40 ++++ src/BootAnimation.h | 3 + src/Keyboardio-LEDControl.cpp | 150 +++++++++++++++ src/Keyboardio-LEDControl.h | 52 ++++++ src/LED-BreatheEffect.cpp | 12 ++ src/LED-BreatheEffect.h | 15 ++ src/LED-ChaseEffect.cpp | 23 +++ src/LED-ChaseEffect.h | 20 ++ src/LED-Numlock.cpp | 55 ++++++ src/LED-Numlock.h | 17 ++ src/LED-Off.cpp | 3 + src/LED-Off.h | 10 + src/LED-RainbowEffect.cpp | 52 ++++++ src/LED-RainbowEffect.h | 43 +++++ src/LED-SolidColor.cpp | 13 ++ src/LED-SolidColor.h | 13 ++ src/LEDUtils.cpp | 86 +++++++++ src/LEDUtils.h | 6 + 21 files changed, 968 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/BootAnimation.cpp create mode 100644 src/BootAnimation.h create mode 100644 src/Keyboardio-LEDControl.cpp create mode 100644 src/Keyboardio-LEDControl.h create mode 100644 src/LED-BreatheEffect.cpp create mode 100644 src/LED-BreatheEffect.h create mode 100644 src/LED-ChaseEffect.cpp create mode 100644 src/LED-ChaseEffect.h create mode 100644 src/LED-Numlock.cpp create mode 100644 src/LED-Numlock.h create mode 100644 src/LED-Off.cpp create mode 100644 src/LED-Off.h create mode 100644 src/LED-RainbowEffect.cpp create mode 100644 src/LED-RainbowEffect.h create mode 100644 src/LED-SolidColor.cpp create mode 100644 src/LED-SolidColor.h create mode 100644 src/LEDUtils.cpp create mode 100644 src/LEDUtils.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..a74162ee --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Keyboardio-LEDControl + +This is a plugin for [KeyboardioFirmware][fw], for controlling the LEDs, and LED +effects. + + [fw]: https://github.com/keyboardio/KeyboardioFirmware diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..ff66292e --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Keyboardio-LEDControl +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=LED control for Keyboardio boards. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Keyboardio-LEDControl +architectures=avr +dot_a_linkage=true diff --git a/src/BootAnimation.cpp b/src/BootAnimation.cpp new file mode 100644 index 00000000..76c4a336 --- /dev/null +++ b/src/BootAnimation.cpp @@ -0,0 +1,40 @@ +#include "BootAnimation.h" +#include "Keyboardio-LEDControl.h" +#include "EEPROM.h" + +#define EEPROM_BOOT_ANIMATION_LOCATION 1 + +static void +type_letter(uint8_t letter) { + LEDControl.led_set_crgb_at(letter, {255, 0, 0}); + LEDControl.led_sync(); + delay(250); + LEDControl.led_set_crgb_at(letter, {0, 0, 0}); + LEDControl.led_sync(); + delay(10); +} + +void +bootAnimation (void) { + if (EEPROM.read (EEPROM_BOOT_ANIMATION_LOCATION)) + return; + + LEDControl.set_all_leds_to(0, 0, 0); + + type_letter(LED_K); + type_letter(LED_E); + type_letter(LED_Y); + type_letter(LED_B); + type_letter(LED_O); + type_letter(LED_A); + type_letter(LED_R); + type_letter(LED_D); + type_letter(LED_I); + type_letter(LED_O); + type_letter(LED_SPACE); + type_letter(LED_0); + type_letter(LED_PERIOD); + type_letter(LED_9); + + EEPROM.update (EEPROM_BOOT_ANIMATION_LOCATION, 1); +} diff --git a/src/BootAnimation.h b/src/BootAnimation.h new file mode 100644 index 00000000..f8b49cac --- /dev/null +++ b/src/BootAnimation.h @@ -0,0 +1,3 @@ +#pragma once + +void bootAnimation(void); diff --git a/src/Keyboardio-LEDControl.cpp b/src/Keyboardio-LEDControl.cpp new file mode 100644 index 00000000..acba5121 --- /dev/null +++ b/src/Keyboardio-LEDControl.cpp @@ -0,0 +1,150 @@ +#include "Keyboardio-LEDControl.h" + +LEDMode *LEDControl_::modes[LED_MAX_MODES]; +uint8_t LEDControl_::previousMode, LEDControl_::mode; + +void +LEDMode::activate (void) { + LEDControl.activate (this); +} + +void +LEDMode::begin(void) { + LEDControl.mode_add(this); +} + +LEDControl_::LEDControl_(void) { + mode = previousMode = 0; + memset (modes, 0, LED_MAX_MODES * sizeof (modes[0])); +} + +void +LEDControl_::next_mode (void) { + mode++; + + if (mode >= LED_MAX_MODES) { + mode = 0; + return; + } + + if (modes[mode]) + return; + + mode = 0; +} + +void +LEDControl_::update (void) { + if (previousMode != mode) { + set_all_leds_to ({0, 0, 0}); + if (modes[mode]) + (modes[mode]->init) (); + } + + if (modes[mode]) + (modes[mode]->update) (); + + previousMode = mode; +} + +void +LEDControl_::set_mode (uint8_t mode_) { + if (mode_ < LED_MAX_MODES) + mode = mode_; +} + +uint8_t +LEDControl_::get_mode (void) { + return mode; +} + +void +LEDControl_::activate (LEDMode *mode) { + for (uint8_t i = 0; i < LED_MAX_MODES; i++) { + if (modes[i] == mode) + return set_mode(i); + } +} + +int8_t +LEDControl_::mode_add (LEDMode *mode) { + for (int i = 0; i < LED_MAX_MODES; i++) { + if (modes[i]) + continue; + + modes[i] = mode; + return i; + } + return -1; +} + +void +LEDControl_::set_all_leds_to(uint8_t r, uint8_t g, uint8_t b) { + cRGB color; + color.r=r; + color.g=g; + color.b=b; + set_all_leds_to(color); +} + +void +LEDControl_::set_all_leds_to(cRGB color) { + for (uint8_t i = 0; i < LED_COUNT; i++) { + led_set_crgb_at(i, color); + } +} + +void +LEDControl_::led_set_crgb_at(uint8_t i, cRGB crgb) { + KeyboardHardware.led_set_crgb_at(i, crgb); +} + +void +LEDControl_::led_set_crgb_at(byte row, byte col, cRGB color) { + KeyboardHardware.led_set_crgb_at(row, col, color); +} + +cRGB +LEDControl_::led_get_crgb_at(uint8_t i) { + return KeyboardHardware.led_get_crgb_at(i); +} + +void +LEDControl_::led_sync(void) { + KeyboardHardware.led_sync(); +} + +void +LEDControl_::begin (void) { + set_all_leds_to ({0, 0, 0}); + + for (uint8_t i = 0; i < LED_MAX_MODES; i++) { + if (modes[i]) + (modes[i]->setup)(); + } + + event_handler_hook_add(eventHandler); + loop_hook_add(loopHook); +} + +Key +LEDControl_::eventHandler (Key mappedKey, byte row, byte col, uint8_t keyState) { + if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) + return mappedKey; + + if (key_toggled_on(keyState)) + LEDControl.next_mode(); + + return Key_NoKey; +} + +void +LEDControl_::loopHook (bool postClear) { + if (postClear) + return; + + led_sync(); + update(); +} + +LEDControl_ LEDControl; diff --git a/src/Keyboardio-LEDControl.h b/src/Keyboardio-LEDControl.h new file mode 100644 index 00000000..ff388397 --- /dev/null +++ b/src/Keyboardio-LEDControl.h @@ -0,0 +1,52 @@ +#pragma once + +#include + +#define LED_MAX_MODES 24 + +#define LED_TOGGLE B00000001 // Synthetic, internal + +#define Key_LEDEffectNext (Key) { 0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } + +class LEDMode : public KeyboardioPlugin { + public: + virtual void begin (void); + virtual void setup (void) {}; + virtual void init (void) {}; + virtual void update (void) {}; + virtual void activate (void); +}; + +class LEDControl_ : public KeyboardioPlugin { + public: + LEDControl_(void); + + virtual void begin(void) final; + + static void next_mode(void); + static void setup(void); + static void update(void); + static void set_mode(uint8_t mode); + static uint8_t get_mode(); + + static int8_t mode_add (LEDMode *mode); + + static void led_set_crgb_at(uint8_t i, cRGB crgb); + static void led_set_crgb_at(byte row, byte col, cRGB color); + static cRGB led_get_crgb_at(uint8_t i); + static void led_sync(void); + + static void set_all_leds_to(uint8_t r, uint8_t g, uint8_t b); + static void set_all_leds_to(cRGB color); + + static void activate (LEDMode *mode); + + private: + static LEDMode *modes[LED_MAX_MODES]; + static uint8_t previousMode, mode; + + static Key eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState); + static void loopHook (bool postClear); +}; + +extern LEDControl_ LEDControl; diff --git a/src/LED-BreatheEffect.cpp b/src/LED-BreatheEffect.cpp new file mode 100644 index 00000000..3f249bda --- /dev/null +++ b/src/LED-BreatheEffect.cpp @@ -0,0 +1,12 @@ +#include "LED-BreatheEffect.h" + +LEDBreatheEffect_::LEDBreatheEffect_ (void) { +} + +void +LEDBreatheEffect_::update (void) { + cRGB color = breath_compute(); + LEDControl.set_all_leds_to (color); +} + +LEDBreatheEffect_ LEDBreatheEffect; diff --git a/src/LED-BreatheEffect.h b/src/LED-BreatheEffect.h new file mode 100644 index 00000000..781cf59f --- /dev/null +++ b/src/LED-BreatheEffect.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" +#include "LEDUtils.h" + +class LEDBreatheEffect_ : LEDMode { + public: + LEDBreatheEffect_ (void); + + virtual void update (void) final; + + private: +}; + +extern LEDBreatheEffect_ LEDBreatheEffect; diff --git a/src/LED-ChaseEffect.cpp b/src/LED-ChaseEffect.cpp new file mode 100644 index 00000000..7c32b568 --- /dev/null +++ b/src/LED-ChaseEffect.cpp @@ -0,0 +1,23 @@ +#include "LED-ChaseEffect.h" + +LEDChaseEffect_::LEDChaseEffect_ (void) { +} + +void +LEDChaseEffect_::update (void) { + if (current_chase_counter++ < chase_threshold) { + return; + } + current_chase_counter = 0; + LEDControl.led_set_crgb_at(pos - (chase_sign* chase_pixels), {0, 0, 0}); + LEDControl.led_set_crgb_at(pos, {0, 0, 0}); + + pos += chase_sign; + if (pos >= LED_COUNT || pos <= 0) { + chase_sign = -chase_sign; + } + LEDControl.led_set_crgb_at(pos, {0, 0, 255}); + LEDControl.led_set_crgb_at(pos - (chase_sign * chase_pixels), {255, 0, 0}); +} + +LEDChaseEffect_ LEDChaseEffect; diff --git a/src/LED-ChaseEffect.h b/src/LED-ChaseEffect.h new file mode 100644 index 00000000..2576df9d --- /dev/null +++ b/src/LED-ChaseEffect.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" +#include "LEDUtils.h" + +class LEDChaseEffect_ : LEDMode { + public: + LEDChaseEffect_ (void); + + virtual void update (void) final; + + private: + uint8_t pos = 0; + int8_t chase_sign = 1; //negative values when it's going backwar + uint8_t chase_pixels = 5; + uint8_t current_chase_counter = 0; + static const uint8_t chase_threshold = 20; +}; + +extern LEDChaseEffect_ LEDChaseEffect; diff --git a/src/LED-Numlock.cpp b/src/LED-Numlock.cpp new file mode 100644 index 00000000..4a17f99e --- /dev/null +++ b/src/LED-Numlock.cpp @@ -0,0 +1,55 @@ +#include "LED-Numlock.h" +#include "LEDUtils.h" +#include "layers.h" + +static uint8_t numpadIndex; +static uint8_t storedLEDMode; +static uint8_t us; + +LEDNumlock::LEDNumlock (uint8_t numpadIdx) { + numpadIndex = numpadIdx; +} + +void +LEDNumlock::begin (void) { + us = LEDControl.mode_add (this); + loop_hook_add (this->loopHook); +} + +void +LEDNumlock::setup (void) { + if (!Layer.isOn (numpadIndex)) { + LEDControl.next_mode (); + } +} + +void +LEDNumlock::update (void) { + for (uint8_t i = 0; i < 44; i++) { + LEDControl.led_set_crgb_at(i, {0, 0, 0}); + } + for (uint8_t i = 44; i < LED_COUNT; i++) { + LEDControl.led_set_crgb_at(i, {255, 0, 0}); + } + + cRGB color = breath_compute (); + LEDControl.led_set_crgb_at (60, color); +} + +void +LEDNumlock::loopHook (bool postClear) { + if (!postClear) + return; + + if (Layer.isOn (numpadIndex)) { + if (storedLEDMode != us) { + storedLEDMode = LEDControl.get_mode (); + } + LEDControl.set_mode (us); + } + + if (!Layer.isOn (numpadIndex) && + LEDControl.get_mode () == us) { + LEDControl.set_mode (storedLEDMode); + } +} diff --git a/src/LED-Numlock.h b/src/LED-Numlock.h new file mode 100644 index 00000000..14521096 --- /dev/null +++ b/src/LED-Numlock.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" +#include "LEDUtils.h" + +class LEDNumlock : LEDMode { + public: + LEDNumlock (uint8_t numpadIndex); + + virtual void begin (void) final; + + virtual void update (void) final; + virtual void setup (void) final; + + private: + static void loopHook (bool postClear); +}; diff --git a/src/LED-Off.cpp b/src/LED-Off.cpp new file mode 100644 index 00000000..b2c91c55 --- /dev/null +++ b/src/LED-Off.cpp @@ -0,0 +1,3 @@ +#include "LED-Off.h" + +LEDOff_ LEDOff; diff --git a/src/LED-Off.h b/src/LED-Off.h new file mode 100644 index 00000000..4f75d9bb --- /dev/null +++ b/src/LED-Off.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" + +class LEDOff_ : public LEDMode { + public: + LEDOff_ (void) { }; +}; + +extern LEDOff_ LEDOff; diff --git a/src/LED-RainbowEffect.cpp b/src/LED-RainbowEffect.cpp new file mode 100644 index 00000000..e258f06d --- /dev/null +++ b/src/LED-RainbowEffect.cpp @@ -0,0 +1,52 @@ +#include "LED-RainbowEffect.h" + +LEDRainbowEffect_::LEDRainbowEffect_ (void) { +} + +void +LEDRainbowEffect_::update (void) { + if (rainbow_current_ticks++ < rainbow_ticks) { + return; + } else { + rainbow_current_ticks = 0; + } + + cRGB rainbow = hsv_to_rgb(rainbow_hue, rainbow_saturation, rainbow_value); + + rainbow_hue += rainbow_steps; + if (rainbow_hue >= 255) { + rainbow_hue -= 255; + } + LEDControl.set_all_leds_to(rainbow); +} + +LEDRainbowEffect_ LEDRainbowEffect; + +// --------- + +LEDRainbowWaveEffect_::LEDRainbowWaveEffect_ (void) { +} + +void +LEDRainbowWaveEffect_::update (void) { + if (rainbow_current_ticks++ < rainbow_wave_ticks) { + return; + } else { + rainbow_current_ticks = 0; + } + + for (uint8_t i = 0; i < LED_COUNT; i++) { + uint16_t key_hue = rainbow_hue +16*(i/4); + if (key_hue >= 255) { + key_hue -= 255; + } + cRGB rainbow = hsv_to_rgb(key_hue, rainbow_saturation, rainbow_value); + LEDControl.led_set_crgb_at (i, rainbow); + } + rainbow_hue += rainbow_wave_steps; + if (rainbow_hue >= 255) { + rainbow_hue -= 255; + } +} + +LEDRainbowWaveEffect_ LEDRainbowWaveEffect; diff --git a/src/LED-RainbowEffect.h b/src/LED-RainbowEffect.h new file mode 100644 index 00000000..5589e18c --- /dev/null +++ b/src/LED-RainbowEffect.h @@ -0,0 +1,43 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" +#include "LEDUtils.h" + +class LEDRainbowEffect_ : LEDMode { + public: + LEDRainbowEffect_ (void); + + virtual void update (void) final; + + private: + uint16_t rainbow_hue = 0; //stores 0 to 614 + + static const uint8_t rainbow_steps = 1; //number of hues we skip in a 360 range per update + long rainbow_current_ticks = 0; + static const long rainbow_ticks = 10; //delays between update + + static const byte rainbow_saturation = 255; + static const byte rainbow_value = 50; + +}; + +extern LEDRainbowEffect_ LEDRainbowEffect; + +class LEDRainbowWaveEffect_ : LEDMode { + public: + LEDRainbowWaveEffect_ (void); + + virtual void update (void) final; + + private: + uint16_t rainbow_hue = 0; //stores 0 to 614 + + static const uint8_t rainbow_wave_steps = 1; //number of hues we skip in a 360 range per update + long rainbow_current_ticks = 0; + static const long rainbow_wave_ticks = 10; //delays between update + + static const byte rainbow_saturation = 255; + static const byte rainbow_value = 50; +}; + +extern LEDRainbowWaveEffect_ LEDRainbowWaveEffect; diff --git a/src/LED-SolidColor.cpp b/src/LED-SolidColor.cpp new file mode 100644 index 00000000..84a57126 --- /dev/null +++ b/src/LED-SolidColor.cpp @@ -0,0 +1,13 @@ +#include "LED-SolidColor.h" + +LEDSolidColor::LEDSolidColor (uint8_t r, uint8_t g, uint8_t b) { + this->r = r; + this->g = g; + this->b = b; + LEDControl.mode_add (this); +} + +void +LEDSolidColor::init (void) { + LEDControl.set_all_leds_to (r, g, b); +} diff --git a/src/LED-SolidColor.h b/src/LED-SolidColor.h new file mode 100644 index 00000000..01965678 --- /dev/null +++ b/src/LED-SolidColor.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" + +class LEDSolidColor : LEDMode { + public: + LEDSolidColor (uint8_t r, uint8_t g, uint8_t b); + + virtual void init (void) final; + + private: + uint8_t r, g, b; +}; diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp new file mode 100644 index 00000000..3897b5b8 --- /dev/null +++ b/src/LEDUtils.cpp @@ -0,0 +1,86 @@ +#include "LEDUtils.h" + +cRGB +breath_compute () { + + // This code is adapted from FastLED lib8tion.h as of dd5d96c6b289cb6b4b891748a4aeef3ddceaf0e6 + // Eventually, we should consider just using FastLED + + uint8_t i = (uint16_t)millis()/12; + + if( i & 0x80) { + i = 255 - i; + } + + i = i << 1; + uint8_t ii = (i*i)>>8; + uint8_t iii = (ii*i)>>8; + + i = (( (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii))) / 2) + 2; + + return hsv_to_rgb(200, 255, i); +} + + + +// From http://web.mit.edu/storborg/Public/hsvtorgb.c - talk to Scott about licensing +cRGB +hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v) { + cRGB color; + + /* HSV to RGB conversion function with only integer + * math */ + uint16_t region, fpart, p, q, t; + + if(s == 0) { + /* color is grayscale */ + color.r = color.g = color.b = v; + return color; + } + + /* make hue 0-5 */ + region = (h *6) >> 8; + /* find remainder part, make it from 0-255 */ + fpart = (h*6) - (region <<8); + + /* calculate temp vars, doing integer multiplication */ + p = (v * (255 - s)) >> 8; + q = (v * (255 - ((s * fpart) >> 8))) >> 8; + t = (v * (255 - ((s * (255 - fpart)) >> 8))) >> 8; + + /* assign temp vars based on color cone region */ + switch(region) { + case 0: + color.r = v; + color.g = t; + color.b = p; + break; + case 1: + color.r = q; + color.g = v; + color.b = p; + break; + case 2: + color.r = p; + color.g = v; + color.b = t; + break; + case 3: + color.r = p; + color.g = q; + color.b = v; + break; + case 4: + color.r = t; + color.g = p; + color.b = v; + break; + default: + color.r = v; + color.g = p; + color.b = q; + break; + } + + return color; +} diff --git a/src/LEDUtils.h b/src/LEDUtils.h new file mode 100644 index 00000000..40e0d2c2 --- /dev/null +++ b/src/LEDUtils.h @@ -0,0 +1,6 @@ +#pragma once + +#include "KeyboardConfig.h" + +cRGB breath_compute (void); +cRGB hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v); From d73104de7f5fe0a786b56b04745b4b9da9676269 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 09:37:29 +0100 Subject: [PATCH 016/792] Updated to use Keyboardio-LEDControl Signed-off-by: Gergely Nagy --- examples/LED-Stalker/LED-Stalker.ino | 2 +- src/Akela/LED-Stalker.cpp | 4 ++-- src/Akela/LED-Stalker.h | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index c4fb6df5..aa276ea0 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -43,7 +43,7 @@ void setup () { Keyboardio.setup (KEYMAP_SIZE); StalkerEffect.configure (STALKER (BlazingTrail, NULL)); - Keyboardio.use (&StalkerEffect, NULL); + Keyboardio.use (&LEDControl, &StalkerEffect, NULL); } void loop () { diff --git a/src/Akela/LED-Stalker.cpp b/src/Akela/LED-Stalker.cpp index c119c147..f89c9678 100644 --- a/src/Akela/LED-Stalker.cpp +++ b/src/Akela/LED-Stalker.cpp @@ -59,7 +59,7 @@ namespace Akela { for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { if (map[r][c]) - led_set_crgb_at (r, c, colorComputer->compute (map[r][c])); + LEDControl.led_set_crgb_at (r, c, colorComputer->compute (map[r][c])); bool wasZero = (map[r][c] == 0); @@ -73,7 +73,7 @@ namespace Akela { map[r][c] = 0; if (!wasZero && !map[r][c]) - led_set_crgb_at (r, c, (cRGB){0, 0, 0}); + LEDControl.led_set_crgb_at (r, c, (cRGB){0, 0, 0}); } } } diff --git a/src/Akela/LED-Stalker.h b/src/Akela/LED-Stalker.h index 75fc3137..74b5d75b 100644 --- a/src/Akela/LED-Stalker.h +++ b/src/Akela/LED-Stalker.h @@ -17,6 +17,7 @@ */ #include +#include #define STALKER(n, ...) (({static Akela::LEDEffects::Stalker::n _effect (__VA_ARGS__); &_effect;})) From ecff024f028dd8d09fe15ba3174b8030d88e7367 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 09:38:16 +0100 Subject: [PATCH 017/792] Don't use Key_LEDEffectNext in the example Signed-off-by: Gergely Nagy --- examples/MagicCombo/MagicCombo.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index 5f0cea20..f652b89a 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -36,10 +36,10 @@ static const Akela::MagicCombo::dictionary_t dictionary[] PROGMEM = { const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED ( - Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, Key_skip, From 2a35a350f19cf46a7948abe5efbe2fe6901d153b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 11:09:20 +0100 Subject: [PATCH 018/792] Moved the effects to separate libraries Dropped dot_a_linkage, so that the functions in LEDUtils do not get optimized out. Signed-off-by: Gergely Nagy --- library.properties | 1 - src/LED-BreatheEffect.cpp | 12 --------- src/LED-BreatheEffect.h | 15 ----------- src/LED-ChaseEffect.cpp | 23 ---------------- src/LED-ChaseEffect.h | 20 -------------- src/LED-Numlock.cpp | 55 --------------------------------------- src/LED-Numlock.h | 17 ------------ src/LED-RainbowEffect.cpp | 52 ------------------------------------ src/LED-RainbowEffect.h | 43 ------------------------------ src/LED-SolidColor.cpp | 13 --------- src/LED-SolidColor.h | 13 --------- 11 files changed, 264 deletions(-) delete mode 100644 src/LED-BreatheEffect.cpp delete mode 100644 src/LED-BreatheEffect.h delete mode 100644 src/LED-ChaseEffect.cpp delete mode 100644 src/LED-ChaseEffect.h delete mode 100644 src/LED-Numlock.cpp delete mode 100644 src/LED-Numlock.h delete mode 100644 src/LED-RainbowEffect.cpp delete mode 100644 src/LED-RainbowEffect.h delete mode 100644 src/LED-SolidColor.cpp delete mode 100644 src/LED-SolidColor.h diff --git a/library.properties b/library.properties index ff66292e..55e9a724 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,3 @@ paragraph=... category=Communication url=https://github.com/keyboardio/Keyboardio-LEDControl architectures=avr -dot_a_linkage=true diff --git a/src/LED-BreatheEffect.cpp b/src/LED-BreatheEffect.cpp deleted file mode 100644 index 3f249bda..00000000 --- a/src/LED-BreatheEffect.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "LED-BreatheEffect.h" - -LEDBreatheEffect_::LEDBreatheEffect_ (void) { -} - -void -LEDBreatheEffect_::update (void) { - cRGB color = breath_compute(); - LEDControl.set_all_leds_to (color); -} - -LEDBreatheEffect_ LEDBreatheEffect; diff --git a/src/LED-BreatheEffect.h b/src/LED-BreatheEffect.h deleted file mode 100644 index 781cf59f..00000000 --- a/src/LED-BreatheEffect.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "Keyboardio-LEDControl.h" -#include "LEDUtils.h" - -class LEDBreatheEffect_ : LEDMode { - public: - LEDBreatheEffect_ (void); - - virtual void update (void) final; - - private: -}; - -extern LEDBreatheEffect_ LEDBreatheEffect; diff --git a/src/LED-ChaseEffect.cpp b/src/LED-ChaseEffect.cpp deleted file mode 100644 index 7c32b568..00000000 --- a/src/LED-ChaseEffect.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "LED-ChaseEffect.h" - -LEDChaseEffect_::LEDChaseEffect_ (void) { -} - -void -LEDChaseEffect_::update (void) { - if (current_chase_counter++ < chase_threshold) { - return; - } - current_chase_counter = 0; - LEDControl.led_set_crgb_at(pos - (chase_sign* chase_pixels), {0, 0, 0}); - LEDControl.led_set_crgb_at(pos, {0, 0, 0}); - - pos += chase_sign; - if (pos >= LED_COUNT || pos <= 0) { - chase_sign = -chase_sign; - } - LEDControl.led_set_crgb_at(pos, {0, 0, 255}); - LEDControl.led_set_crgb_at(pos - (chase_sign * chase_pixels), {255, 0, 0}); -} - -LEDChaseEffect_ LEDChaseEffect; diff --git a/src/LED-ChaseEffect.h b/src/LED-ChaseEffect.h deleted file mode 100644 index 2576df9d..00000000 --- a/src/LED-ChaseEffect.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "Keyboardio-LEDControl.h" -#include "LEDUtils.h" - -class LEDChaseEffect_ : LEDMode { - public: - LEDChaseEffect_ (void); - - virtual void update (void) final; - - private: - uint8_t pos = 0; - int8_t chase_sign = 1; //negative values when it's going backwar - uint8_t chase_pixels = 5; - uint8_t current_chase_counter = 0; - static const uint8_t chase_threshold = 20; -}; - -extern LEDChaseEffect_ LEDChaseEffect; diff --git a/src/LED-Numlock.cpp b/src/LED-Numlock.cpp deleted file mode 100644 index 4a17f99e..00000000 --- a/src/LED-Numlock.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "LED-Numlock.h" -#include "LEDUtils.h" -#include "layers.h" - -static uint8_t numpadIndex; -static uint8_t storedLEDMode; -static uint8_t us; - -LEDNumlock::LEDNumlock (uint8_t numpadIdx) { - numpadIndex = numpadIdx; -} - -void -LEDNumlock::begin (void) { - us = LEDControl.mode_add (this); - loop_hook_add (this->loopHook); -} - -void -LEDNumlock::setup (void) { - if (!Layer.isOn (numpadIndex)) { - LEDControl.next_mode (); - } -} - -void -LEDNumlock::update (void) { - for (uint8_t i = 0; i < 44; i++) { - LEDControl.led_set_crgb_at(i, {0, 0, 0}); - } - for (uint8_t i = 44; i < LED_COUNT; i++) { - LEDControl.led_set_crgb_at(i, {255, 0, 0}); - } - - cRGB color = breath_compute (); - LEDControl.led_set_crgb_at (60, color); -} - -void -LEDNumlock::loopHook (bool postClear) { - if (!postClear) - return; - - if (Layer.isOn (numpadIndex)) { - if (storedLEDMode != us) { - storedLEDMode = LEDControl.get_mode (); - } - LEDControl.set_mode (us); - } - - if (!Layer.isOn (numpadIndex) && - LEDControl.get_mode () == us) { - LEDControl.set_mode (storedLEDMode); - } -} diff --git a/src/LED-Numlock.h b/src/LED-Numlock.h deleted file mode 100644 index 14521096..00000000 --- a/src/LED-Numlock.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "Keyboardio-LEDControl.h" -#include "LEDUtils.h" - -class LEDNumlock : LEDMode { - public: - LEDNumlock (uint8_t numpadIndex); - - virtual void begin (void) final; - - virtual void update (void) final; - virtual void setup (void) final; - - private: - static void loopHook (bool postClear); -}; diff --git a/src/LED-RainbowEffect.cpp b/src/LED-RainbowEffect.cpp deleted file mode 100644 index e258f06d..00000000 --- a/src/LED-RainbowEffect.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "LED-RainbowEffect.h" - -LEDRainbowEffect_::LEDRainbowEffect_ (void) { -} - -void -LEDRainbowEffect_::update (void) { - if (rainbow_current_ticks++ < rainbow_ticks) { - return; - } else { - rainbow_current_ticks = 0; - } - - cRGB rainbow = hsv_to_rgb(rainbow_hue, rainbow_saturation, rainbow_value); - - rainbow_hue += rainbow_steps; - if (rainbow_hue >= 255) { - rainbow_hue -= 255; - } - LEDControl.set_all_leds_to(rainbow); -} - -LEDRainbowEffect_ LEDRainbowEffect; - -// --------- - -LEDRainbowWaveEffect_::LEDRainbowWaveEffect_ (void) { -} - -void -LEDRainbowWaveEffect_::update (void) { - if (rainbow_current_ticks++ < rainbow_wave_ticks) { - return; - } else { - rainbow_current_ticks = 0; - } - - for (uint8_t i = 0; i < LED_COUNT; i++) { - uint16_t key_hue = rainbow_hue +16*(i/4); - if (key_hue >= 255) { - key_hue -= 255; - } - cRGB rainbow = hsv_to_rgb(key_hue, rainbow_saturation, rainbow_value); - LEDControl.led_set_crgb_at (i, rainbow); - } - rainbow_hue += rainbow_wave_steps; - if (rainbow_hue >= 255) { - rainbow_hue -= 255; - } -} - -LEDRainbowWaveEffect_ LEDRainbowWaveEffect; diff --git a/src/LED-RainbowEffect.h b/src/LED-RainbowEffect.h deleted file mode 100644 index 5589e18c..00000000 --- a/src/LED-RainbowEffect.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "Keyboardio-LEDControl.h" -#include "LEDUtils.h" - -class LEDRainbowEffect_ : LEDMode { - public: - LEDRainbowEffect_ (void); - - virtual void update (void) final; - - private: - uint16_t rainbow_hue = 0; //stores 0 to 614 - - static const uint8_t rainbow_steps = 1; //number of hues we skip in a 360 range per update - long rainbow_current_ticks = 0; - static const long rainbow_ticks = 10; //delays between update - - static const byte rainbow_saturation = 255; - static const byte rainbow_value = 50; - -}; - -extern LEDRainbowEffect_ LEDRainbowEffect; - -class LEDRainbowWaveEffect_ : LEDMode { - public: - LEDRainbowWaveEffect_ (void); - - virtual void update (void) final; - - private: - uint16_t rainbow_hue = 0; //stores 0 to 614 - - static const uint8_t rainbow_wave_steps = 1; //number of hues we skip in a 360 range per update - long rainbow_current_ticks = 0; - static const long rainbow_wave_ticks = 10; //delays between update - - static const byte rainbow_saturation = 255; - static const byte rainbow_value = 50; -}; - -extern LEDRainbowWaveEffect_ LEDRainbowWaveEffect; diff --git a/src/LED-SolidColor.cpp b/src/LED-SolidColor.cpp deleted file mode 100644 index 84a57126..00000000 --- a/src/LED-SolidColor.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "LED-SolidColor.h" - -LEDSolidColor::LEDSolidColor (uint8_t r, uint8_t g, uint8_t b) { - this->r = r; - this->g = g; - this->b = b; - LEDControl.mode_add (this); -} - -void -LEDSolidColor::init (void) { - LEDControl.set_all_leds_to (r, g, b); -} diff --git a/src/LED-SolidColor.h b/src/LED-SolidColor.h deleted file mode 100644 index 01965678..00000000 --- a/src/LED-SolidColor.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "Keyboardio-LEDControl.h" - -class LEDSolidColor : LEDMode { - public: - LEDSolidColor (uint8_t r, uint8_t g, uint8_t b); - - virtual void init (void) final; - - private: - uint8_t r, g, b; -}; From 04902c903c05f1bd0d4728fa67cdfb67992779b9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 11:11:48 +0100 Subject: [PATCH 019/792] Lifted out from Keyboardio-LEDControl Signed-off-by: Gergely Nagy --- COPYING | 339 +++++++++++++++++++++++++++ README.md | 5 + library.properties | 10 + src/Keyboardio-LEDEffect-Breathe.cpp | 12 + src/Keyboardio-LEDEffect-Breathe.h | 15 ++ 5 files changed, 381 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Keyboardio-LEDEffect-Breathe.cpp create mode 100644 src/Keyboardio-LEDEffect-Breathe.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..5b2205a5 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Keyboardio-LEDEffect-Breathe + +This is a plugin for [KeyboardioFirmware][fw], adding a breathe LED effect. + + [fw]: https://github.com/keyboardio/KeyboardioFirmware diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..d2bfc2c2 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Keyboardio-LEDEffect-Breathe +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=A breathing effect for the LEDs on Keyboardio boards. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Keyboardio-LEDEffect-Breathe +architectures=avr +dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-Breathe.cpp b/src/Keyboardio-LEDEffect-Breathe.cpp new file mode 100644 index 00000000..166fce0b --- /dev/null +++ b/src/Keyboardio-LEDEffect-Breathe.cpp @@ -0,0 +1,12 @@ +#include "Keyboardio-LEDEffect-Breathe.h" + +LEDBreatheEffect_::LEDBreatheEffect_ (void) { +} + +void +LEDBreatheEffect_::update (void) { + cRGB color = breath_compute(); + LEDControl.set_all_leds_to (color); +} + +LEDBreatheEffect_ LEDBreatheEffect; diff --git a/src/Keyboardio-LEDEffect-Breathe.h b/src/Keyboardio-LEDEffect-Breathe.h new file mode 100644 index 00000000..781cf59f --- /dev/null +++ b/src/Keyboardio-LEDEffect-Breathe.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" +#include "LEDUtils.h" + +class LEDBreatheEffect_ : LEDMode { + public: + LEDBreatheEffect_ (void); + + virtual void update (void) final; + + private: +}; + +extern LEDBreatheEffect_ LEDBreatheEffect; From 7a903afb69fd390ee7fd0cf8184941d76098511a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 11:11:49 +0100 Subject: [PATCH 020/792] Lifted out from Keyboardio-LEDControl Signed-off-by: Gergely Nagy --- COPYING | 339 +++++++++++++++++++++++++++++ README.md | 5 + library.properties | 10 + src/Keyboardio-LEDEffect-Chase.cpp | 23 ++ src/Keyboardio-LEDEffect-Chase.h | 20 ++ 5 files changed, 397 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Keyboardio-LEDEffect-Chase.cpp create mode 100644 src/Keyboardio-LEDEffect-Chase.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..a466a36d --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Keyboardio-LEDEffect-Chase + +This is a plugin for [KeyboardioFirmware][fw], adding a Chase LED effect. + + [fw]: https://github.com/keyboardio/KeyboardioFirmware diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..8df7d6bc --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Keyboardio-LEDEffect-Chase +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=A Chase LED effect for Keyboardio boards. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Keyboardio-LEDEffect-Chase +architectures=avr +dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-Chase.cpp b/src/Keyboardio-LEDEffect-Chase.cpp new file mode 100644 index 00000000..60acef7c --- /dev/null +++ b/src/Keyboardio-LEDEffect-Chase.cpp @@ -0,0 +1,23 @@ +#include "Keyboardio-LEDEffect-Chase.h" + +LEDChaseEffect_::LEDChaseEffect_ (void) { +} + +void +LEDChaseEffect_::update (void) { + if (current_chase_counter++ < chase_threshold) { + return; + } + current_chase_counter = 0; + LEDControl.led_set_crgb_at(pos - (chase_sign* chase_pixels), {0, 0, 0}); + LEDControl.led_set_crgb_at(pos, {0, 0, 0}); + + pos += chase_sign; + if (pos >= LED_COUNT || pos <= 0) { + chase_sign = -chase_sign; + } + LEDControl.led_set_crgb_at(pos, {0, 0, 255}); + LEDControl.led_set_crgb_at(pos - (chase_sign * chase_pixels), {255, 0, 0}); +} + +LEDChaseEffect_ LEDChaseEffect; diff --git a/src/Keyboardio-LEDEffect-Chase.h b/src/Keyboardio-LEDEffect-Chase.h new file mode 100644 index 00000000..2576df9d --- /dev/null +++ b/src/Keyboardio-LEDEffect-Chase.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" +#include "LEDUtils.h" + +class LEDChaseEffect_ : LEDMode { + public: + LEDChaseEffect_ (void); + + virtual void update (void) final; + + private: + uint8_t pos = 0; + int8_t chase_sign = 1; //negative values when it's going backwar + uint8_t chase_pixels = 5; + uint8_t current_chase_counter = 0; + static const uint8_t chase_threshold = 20; +}; + +extern LEDChaseEffect_ LEDChaseEffect; From 5df5b209d7f11c885e2946889d0a7deb805ad550 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 11:11:51 +0100 Subject: [PATCH 021/792] Lifted out from Keyboardio-LEDControl Signed-off-by: Gergely Nagy --- COPYING | 339 +++++++++++++++++++++++++++ README.md | 6 + library.properties | 10 + src/Keyboardio-LEDEffect-Numlock.cpp | 56 +++++ src/Keyboardio-LEDEffect-Numlock.h | 17 ++ 5 files changed, 428 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Keyboardio-LEDEffect-Numlock.cpp create mode 100644 src/Keyboardio-LEDEffect-Numlock.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..971fd4f3 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Keyboardio-LEDEffect-Numlock + +This is a plugin for [KeyboardioFirmware][fw], adding an LED effect for when +Num-lock is active. + + [fw]: https://github.com/keyboardio/KeyboardioFirmware diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..2618caee --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Keyboardio-LEDEffect-Numlock +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=Special LED effect for when Numlock is pressed on Keyboardio boards. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Keyboardio-LEDEffect-Numlock +architectures=avr +dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-Numlock.cpp b/src/Keyboardio-LEDEffect-Numlock.cpp new file mode 100644 index 00000000..0b707eb1 --- /dev/null +++ b/src/Keyboardio-LEDEffect-Numlock.cpp @@ -0,0 +1,56 @@ +#include "Keyboardio-LEDEffect-Numlock.h" +#include "LEDUtils.h" +#include "KeyboardioFirmware.h" +#include "layers.h" + +static uint8_t numpadIndex; +static uint8_t storedLEDMode; +static uint8_t us; + +LEDNumlock::LEDNumlock (uint8_t numpadIdx) { + numpadIndex = numpadIdx; +} + +void +LEDNumlock::begin (void) { + us = LEDControl.mode_add (this); + loop_hook_add (this->loopHook); +} + +void +LEDNumlock::setup (void) { + if (!Layer.isOn (numpadIndex)) { + LEDControl.next_mode (); + } +} + +void +LEDNumlock::update (void) { + for (uint8_t i = 0; i < 44; i++) { + LEDControl.led_set_crgb_at(i, {0, 0, 0}); + } + for (uint8_t i = 44; i < LED_COUNT; i++) { + LEDControl.led_set_crgb_at(i, {255, 0, 0}); + } + + cRGB color = breath_compute (); + LEDControl.led_set_crgb_at (60, color); +} + +void +LEDNumlock::loopHook (bool postClear) { + if (!postClear) + return; + + if (Layer.isOn (numpadIndex)) { + if (storedLEDMode != us) { + storedLEDMode = LEDControl.get_mode (); + } + LEDControl.set_mode (us); + } + + if (!Layer.isOn (numpadIndex) && + LEDControl.get_mode () == us) { + LEDControl.set_mode (storedLEDMode); + } +} diff --git a/src/Keyboardio-LEDEffect-Numlock.h b/src/Keyboardio-LEDEffect-Numlock.h new file mode 100644 index 00000000..14521096 --- /dev/null +++ b/src/Keyboardio-LEDEffect-Numlock.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" +#include "LEDUtils.h" + +class LEDNumlock : LEDMode { + public: + LEDNumlock (uint8_t numpadIndex); + + virtual void begin (void) final; + + virtual void update (void) final; + virtual void setup (void) final; + + private: + static void loopHook (bool postClear); +}; From 86eaa90abdda6e340155d907c7ed8f90bc3c9491 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 11:11:53 +0100 Subject: [PATCH 022/792] Lifted out from Keyboardio-LEDControl Signed-off-by: Gergely Nagy --- COPYING | 339 +++++++++++++++++++++++++++ README.md | 5 + library.properties | 10 + src/Keyboardio-LEDEffect-Rainbow.cpp | 52 ++++ src/Keyboardio-LEDEffect-Rainbow.h | 43 ++++ 5 files changed, 449 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Keyboardio-LEDEffect-Rainbow.cpp create mode 100644 src/Keyboardio-LEDEffect-Rainbow.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..1413c3c4 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Keyboardio-LEDEffect-Rainbow + +This is a plugin for [KeyboardioFirmware][fw], adding some Rainbow LED effects. + + [fw]: https://github.com/keyboardio/KeyboardioFirmware diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..ad54b633 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Keyboardio-LEDEffect-Rainbow +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=Rainbow LED effects for KeyboardioFirmware. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Keyboardio-LEDEffect-Rainbow +architectures=avr +dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-Rainbow.cpp b/src/Keyboardio-LEDEffect-Rainbow.cpp new file mode 100644 index 00000000..c1285a1f --- /dev/null +++ b/src/Keyboardio-LEDEffect-Rainbow.cpp @@ -0,0 +1,52 @@ +#include "Keyboardio-LEDEffect-Rainbow.h" + +LEDRainbowEffect_::LEDRainbowEffect_ (void) { +} + +void +LEDRainbowEffect_::update (void) { + if (rainbow_current_ticks++ < rainbow_ticks) { + return; + } else { + rainbow_current_ticks = 0; + } + + cRGB rainbow = hsv_to_rgb(rainbow_hue, rainbow_saturation, rainbow_value); + + rainbow_hue += rainbow_steps; + if (rainbow_hue >= 255) { + rainbow_hue -= 255; + } + LEDControl.set_all_leds_to(rainbow); +} + +LEDRainbowEffect_ LEDRainbowEffect; + +// --------- + +LEDRainbowWaveEffect_::LEDRainbowWaveEffect_ (void) { +} + +void +LEDRainbowWaveEffect_::update (void) { + if (rainbow_current_ticks++ < rainbow_wave_ticks) { + return; + } else { + rainbow_current_ticks = 0; + } + + for (uint8_t i = 0; i < LED_COUNT; i++) { + uint16_t key_hue = rainbow_hue +16*(i/4); + if (key_hue >= 255) { + key_hue -= 255; + } + cRGB rainbow = hsv_to_rgb(key_hue, rainbow_saturation, rainbow_value); + LEDControl.led_set_crgb_at (i, rainbow); + } + rainbow_hue += rainbow_wave_steps; + if (rainbow_hue >= 255) { + rainbow_hue -= 255; + } +} + +LEDRainbowWaveEffect_ LEDRainbowWaveEffect; diff --git a/src/Keyboardio-LEDEffect-Rainbow.h b/src/Keyboardio-LEDEffect-Rainbow.h new file mode 100644 index 00000000..5589e18c --- /dev/null +++ b/src/Keyboardio-LEDEffect-Rainbow.h @@ -0,0 +1,43 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" +#include "LEDUtils.h" + +class LEDRainbowEffect_ : LEDMode { + public: + LEDRainbowEffect_ (void); + + virtual void update (void) final; + + private: + uint16_t rainbow_hue = 0; //stores 0 to 614 + + static const uint8_t rainbow_steps = 1; //number of hues we skip in a 360 range per update + long rainbow_current_ticks = 0; + static const long rainbow_ticks = 10; //delays between update + + static const byte rainbow_saturation = 255; + static const byte rainbow_value = 50; + +}; + +extern LEDRainbowEffect_ LEDRainbowEffect; + +class LEDRainbowWaveEffect_ : LEDMode { + public: + LEDRainbowWaveEffect_ (void); + + virtual void update (void) final; + + private: + uint16_t rainbow_hue = 0; //stores 0 to 614 + + static const uint8_t rainbow_wave_steps = 1; //number of hues we skip in a 360 range per update + long rainbow_current_ticks = 0; + static const long rainbow_wave_ticks = 10; //delays between update + + static const byte rainbow_saturation = 255; + static const byte rainbow_value = 50; +}; + +extern LEDRainbowWaveEffect_ LEDRainbowWaveEffect; From 563a9e9ad3f443fbf20fe9c4f77dbcb2c4332698 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 11:11:54 +0100 Subject: [PATCH 023/792] Lifted out from Keyboardio-LEDControl Signed-off-by: Gergely Nagy --- COPYING | 339 ++++++++++++++++++++++++ README.md | 5 + library.properties | 10 + src/Keyboardio-LEDEffect-SolidColor.cpp | 13 + src/Keyboardio-LEDEffect-SolidColor.h | 13 + 5 files changed, 380 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Keyboardio-LEDEffect-SolidColor.cpp create mode 100644 src/Keyboardio-LEDEffect-SolidColor.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..2715a771 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Keyboardio-LEDEffect-SolidColor + +This is a plugin for [KeyboardioFirmware][fw], adding a solid color LED effect. + + [fw]: https://github.com/keyboardio/KeyboardioFirmware diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..39ccf3f2 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Keyboardio-LEDEffect-SolidColor +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=Solid color LED effects for KeyboardioFirmware. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Keyboardio-LEDEffect-SolidColor +architectures=avr +dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-SolidColor.cpp b/src/Keyboardio-LEDEffect-SolidColor.cpp new file mode 100644 index 00000000..a49b0dce --- /dev/null +++ b/src/Keyboardio-LEDEffect-SolidColor.cpp @@ -0,0 +1,13 @@ +#include "Keyboardio-LEDEffect-SolidColor.h" + +LEDSolidColor::LEDSolidColor (uint8_t r, uint8_t g, uint8_t b) { + this->r = r; + this->g = g; + this->b = b; + LEDControl.mode_add (this); +} + +void +LEDSolidColor::init (void) { + LEDControl.set_all_leds_to (r, g, b); +} diff --git a/src/Keyboardio-LEDEffect-SolidColor.h b/src/Keyboardio-LEDEffect-SolidColor.h new file mode 100644 index 00000000..01965678 --- /dev/null +++ b/src/Keyboardio-LEDEffect-SolidColor.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Keyboardio-LEDControl.h" + +class LEDSolidColor : LEDMode { + public: + LEDSolidColor (uint8_t r, uint8_t g, uint8_t b); + + virtual void init (void) final; + + private: + uint8_t r, g, b; +}; From ed92d5109c64574b42d3a4ec6d3dfbc0ebed0ced Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 12:00:53 +0100 Subject: [PATCH 024/792] Fix the LED mode handling First of all, to disallow switching to LEDNumlock, we need to do the check in the `.init()` method, not in `.setup()`. Second, tracking the previous LED mode can be done a lot simpler - and a lot reliably. With these changes, the NumLock LED effect works as it is expected to. Signed-off-by: Gergely Nagy --- src/Keyboardio-LEDEffect-Numlock.cpp | 16 ++++++---------- src/Keyboardio-LEDEffect-Numlock.h | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/Keyboardio-LEDEffect-Numlock.cpp b/src/Keyboardio-LEDEffect-Numlock.cpp index 0b707eb1..6468fd78 100644 --- a/src/Keyboardio-LEDEffect-Numlock.cpp +++ b/src/Keyboardio-LEDEffect-Numlock.cpp @@ -18,9 +18,9 @@ LEDNumlock::begin (void) { } void -LEDNumlock::setup (void) { +LEDNumlock::init (void) { if (!Layer.isOn (numpadIndex)) { - LEDControl.next_mode (); + LEDControl.next_mode(); } } @@ -42,15 +42,11 @@ LEDNumlock::loopHook (bool postClear) { if (!postClear) return; - if (Layer.isOn (numpadIndex)) { - if (storedLEDMode != us) { + if (!Layer.isOn (numpadIndex)) { + if (LEDControl.get_mode () != us) storedLEDMode = LEDControl.get_mode (); - } - LEDControl.set_mode (us); - } - - if (!Layer.isOn (numpadIndex) && - LEDControl.get_mode () == us) { LEDControl.set_mode (storedLEDMode); + } else { + LEDControl.set_mode (us); } } diff --git a/src/Keyboardio-LEDEffect-Numlock.h b/src/Keyboardio-LEDEffect-Numlock.h index 14521096..46ea71d7 100644 --- a/src/Keyboardio-LEDEffect-Numlock.h +++ b/src/Keyboardio-LEDEffect-Numlock.h @@ -10,7 +10,7 @@ class LEDNumlock : LEDMode { virtual void begin (void) final; virtual void update (void) final; - virtual void setup (void) final; + virtual void init (void) final; private: static void loopHook (bool postClear); From 7057b0864c51cf4d5e249ebeccbdc7b59d5fa400 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 17:15:11 +0100 Subject: [PATCH 025/792] Minor code cleanup Remove a stray "private", that is not used or needed anymore. Signed-off-by: Gergely Nagy --- src/Keyboardio-LEDEffect-Breathe.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Keyboardio-LEDEffect-Breathe.h b/src/Keyboardio-LEDEffect-Breathe.h index 781cf59f..d8abf441 100644 --- a/src/Keyboardio-LEDEffect-Breathe.h +++ b/src/Keyboardio-LEDEffect-Breathe.h @@ -8,8 +8,6 @@ class LEDBreatheEffect_ : LEDMode { LEDBreatheEffect_ (void); virtual void update (void) final; - - private: }; extern LEDBreatheEffect_ LEDBreatheEffect; From a2ce2335318695612e9f546e316108c815af0e9b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 23:01:25 +0100 Subject: [PATCH 026/792] Use the new, double-add protected hook functions Signed-off-by: Gergely Nagy --- src/Keyboardio-LEDControl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Keyboardio-LEDControl.cpp b/src/Keyboardio-LEDControl.cpp index acba5121..18c3a953 100644 --- a/src/Keyboardio-LEDControl.cpp +++ b/src/Keyboardio-LEDControl.cpp @@ -123,8 +123,8 @@ LEDControl_::begin (void) { (modes[i]->setup)(); } - event_handler_hook_add(eventHandler); - loop_hook_add(loopHook); + event_handler_hook_use(eventHandler); + loop_hook_use(loopHook); } Key From 93bd91429676f89cc4bceff2618c3f101838f703 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 23:01:25 +0100 Subject: [PATCH 027/792] Use the new, double-add protected hook functions Signed-off-by: Gergely Nagy --- src/Keyboardio-Macros.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Keyboardio-Macros.cpp b/src/Keyboardio-Macros.cpp index f5d0a1b9..bd4b4e4e 100644 --- a/src/Keyboardio-Macros.cpp +++ b/src/Keyboardio-Macros.cpp @@ -62,7 +62,7 @@ Macros_::Macros_ (void) { void Macros_::begin (void) { - event_handler_hook_add (handleMacroEvent); + event_handler_hook_use (handleMacroEvent); } Macros_ Macros; From 7dbb5b39e024a3865ecc8e51a1368eab57b8d525 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 23:01:25 +0100 Subject: [PATCH 028/792] Use the new, double-add protected hook functions Signed-off-by: Gergely Nagy --- src/Akela/MagicCombo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Akela/MagicCombo.cpp b/src/Akela/MagicCombo.cpp index 3a19ea76..cde6f777 100644 --- a/src/Akela/MagicCombo.cpp +++ b/src/Akela/MagicCombo.cpp @@ -29,7 +29,7 @@ namespace Akela { void MagicCombo::begin (void) { - loop_hook_add (this->loopHook); + loop_hook_use (this->loopHook); } void From 6497d3ae8fe6f0b34c0c1f19c6d7883570437148 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 23:01:25 +0100 Subject: [PATCH 029/792] Use the new, double-add protected hook functions Signed-off-by: Gergely Nagy --- src/Akela/LED-Stalker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Akela/LED-Stalker.cpp b/src/Akela/LED-Stalker.cpp index f89c9678..adaca428 100644 --- a/src/Akela/LED-Stalker.cpp +++ b/src/Akela/LED-Stalker.cpp @@ -33,8 +33,8 @@ namespace Akela { void StalkerEffect::begin (void) { - event_handler_hook_add (eventHandlerHook); - loop_hook_add (loopHook); + event_handler_hook_use (eventHandlerHook); + loop_hook_use (loopHook); } Key From dcd8d8405e56d99fb8fe81323e460b255e44aad5 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 23:01:26 +0100 Subject: [PATCH 030/792] Use the new, double-add protected hook functions Signed-off-by: Gergely Nagy --- src/Keyboardio-MouseKeys.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Keyboardio-MouseKeys.cpp b/src/Keyboardio-MouseKeys.cpp index aba457a0..b3a2a7be 100644 --- a/src/Keyboardio-MouseKeys.cpp +++ b/src/Keyboardio-MouseKeys.cpp @@ -62,7 +62,7 @@ MouseKeys_::MouseKeys_(void) { void MouseKeys_::begin (void) { - event_handler_hook_add (handleMouseKeys); + event_handler_hook_use (handleMouseKeys); } MouseKeys_ MouseKeys; From 975cd0bf045b3872fde47724518cc71f43bd0de5 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 27 Jan 2017 23:09:19 +0100 Subject: [PATCH 031/792] Use the new, double-add protected hook functions Signed-off-by: Gergely Nagy --- src/Keyboardio-LEDEffect-Numlock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Keyboardio-LEDEffect-Numlock.cpp b/src/Keyboardio-LEDEffect-Numlock.cpp index 6468fd78..2f8f9759 100644 --- a/src/Keyboardio-LEDEffect-Numlock.cpp +++ b/src/Keyboardio-LEDEffect-Numlock.cpp @@ -14,7 +14,7 @@ LEDNumlock::LEDNumlock (uint8_t numpadIdx) { void LEDNumlock::begin (void) { us = LEDControl.mode_add (this); - loop_hook_add (this->loopHook); + loop_hook_use (this->loopHook); } void From 8431e3a48a60b6a367c9228f9797909e2e530539 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 28 Jan 2017 12:21:42 +0100 Subject: [PATCH 032/792] Make LED modes automatically use LEDControl This way the end-user does not have to explicitly call `Keyboardio.use(&LEDControl)`, it is enough to use a LED effect. Signed-off-by: Gergely Nagy --- src/Keyboardio-LEDControl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Keyboardio-LEDControl.cpp b/src/Keyboardio-LEDControl.cpp index 18c3a953..b9351cd4 100644 --- a/src/Keyboardio-LEDControl.cpp +++ b/src/Keyboardio-LEDControl.cpp @@ -10,6 +10,7 @@ LEDMode::activate (void) { void LEDMode::begin(void) { + Keyboardio.use(&LEDControl, NULL); LEDControl.mode_add(this); } From ace478116f4cf14b630a060fadaa91604f9789a1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 28 Jan 2017 14:09:24 +0100 Subject: [PATCH 033/792] Make the macros aware of the row/col they were pressed at Signed-off-by: Gergely Nagy --- src/Keyboardio-Macros.cpp | 4 ++-- src/Keyboardio-Macros.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Keyboardio-Macros.cpp b/src/Keyboardio-Macros.cpp index bd4b4e4e..5518b333 100644 --- a/src/Keyboardio-Macros.cpp +++ b/src/Keyboardio-Macros.cpp @@ -1,7 +1,7 @@ #include "Keyboardio-Macros.h" __attribute__((weak)) -const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { +const macro_t *macroAction(uint8_t macroIndex, byte row, byte col, uint8_t keyState) { return MACRO_NONE; } @@ -51,7 +51,7 @@ static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) if (!key_toggled_on(keyState)) return Key_NoKey; - const macro_t *m = macroAction(mappedKey.keyCode, keyState); + const macro_t *m = macroAction(mappedKey.keyCode, row, col, keyState); Macros.play(m); return Key_NoKey; diff --git a/src/Keyboardio-Macros.h b/src/Keyboardio-Macros.h index 172de9d7..7b24dd2f 100644 --- a/src/Keyboardio-Macros.h +++ b/src/Keyboardio-Macros.h @@ -5,7 +5,7 @@ #include "MacroKeyDefs.h" #include "MacroSteps.h" -const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); +const macro_t *macroAction(uint8_t macroIndex, byte row, byte col, uint8_t keyState); class Macros_ : public KeyboardioPlugin { public: From 051778048dcec8e7ae000a3febb70b29c9724826 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 28 Jan 2017 14:37:15 +0100 Subject: [PATCH 034/792] Turn the plugin into a macro The expected usage is now calling `NumLock.toggle(row, col, layer)` from within a macro. Signed-off-by: Gergely Nagy --- src/Keyboardio-LEDEffect-Numlock.cpp | 65 +++++++++++++++++----------- src/Keyboardio-LEDEffect-Numlock.h | 14 ++++-- 2 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/Keyboardio-LEDEffect-Numlock.cpp b/src/Keyboardio-LEDEffect-Numlock.cpp index 2f8f9759..d80a6d86 100644 --- a/src/Keyboardio-LEDEffect-Numlock.cpp +++ b/src/Keyboardio-LEDEffect-Numlock.cpp @@ -3,50 +3,63 @@ #include "KeyboardioFirmware.h" #include "layers.h" -static uint8_t numpadIndex; -static uint8_t storedLEDMode; -static uint8_t us; +uint8_t NumLock_::previousLEDMode; +uint8_t NumLock_::us; +bool NumLock_::isActive; +byte NumLock_::row = 255, NumLock_::col = 255; -LEDNumlock::LEDNumlock (uint8_t numpadIdx) { - numpadIndex = numpadIdx; +NumLock_::NumLock_ (void) { } void -LEDNumlock::begin (void) { - us = LEDControl.mode_add (this); - loop_hook_use (this->loopHook); +NumLock_::begin (void) { + us = LEDControl.mode_add (this); } void -LEDNumlock::init (void) { - if (!Layer.isOn (numpadIndex)) { +NumLock_::init (void) { + if (!isActive) { LEDControl.next_mode(); } } void -LEDNumlock::update (void) { - for (uint8_t i = 0; i < 44; i++) { - LEDControl.led_set_crgb_at(i, {0, 0, 0}); - } - for (uint8_t i = 44; i < LED_COUNT; i++) { - LEDControl.led_set_crgb_at(i, {255, 0, 0}); +NumLock_::update (void) { + for (uint8_t r = 0; r < ROWS; r++) { + for (uint8_t c = 0; c < COLS; c++) { + Key k = Layer.lookup (r, c); + + if (k.raw < Key_NumLock.raw || k.raw > Key_KeypadDot.raw) + continue; + + LEDControl.led_set_crgb_at(r, c, {255, 0, 0}); + } } - cRGB color = breath_compute (); - LEDControl.led_set_crgb_at (60, color); + if (row > ROWS || col > COLS) + return; + + cRGB color = breath_compute(); + LEDControl.led_set_crgb_at (row, col, color); } -void -LEDNumlock::loopHook (bool postClear) { - if (!postClear) - return; +const macro_t * +NumLock_::toggle (byte row_, byte col_, uint8_t numPadLayer) { + row = row_; + col = col_; - if (!Layer.isOn (numpadIndex)) { - if (LEDControl.get_mode () != us) - storedLEDMode = LEDControl.get_mode (); - LEDControl.set_mode (storedLEDMode); + if (Layer.isOn (numPadLayer)) { + isActive = false; + LEDControl.set_mode (previousLEDMode); + Layer.off (numPadLayer); } else { + isActive = true; + previousLEDMode = LEDControl.get_mode (); LEDControl.set_mode (us); + Layer.on (numPadLayer); } + + return MACRO(T(NumLock), END); } + +NumLock_ NumLock; diff --git a/src/Keyboardio-LEDEffect-Numlock.h b/src/Keyboardio-LEDEffect-Numlock.h index 46ea71d7..b6af6d55 100644 --- a/src/Keyboardio-LEDEffect-Numlock.h +++ b/src/Keyboardio-LEDEffect-Numlock.h @@ -1,17 +1,25 @@ #pragma once #include "Keyboardio-LEDControl.h" +#include "Keyboardio-Macros.h" #include "LEDUtils.h" -class LEDNumlock : LEDMode { +class NumLock_ : LEDMode { public: - LEDNumlock (uint8_t numpadIndex); + NumLock_ (void); virtual void begin (void) final; virtual void update (void) final; virtual void init (void) final; + static const macro_t *toggle (byte row, byte col, uint8_t numPadLayer); + private: - static void loopHook (bool postClear); + static uint8_t previousLEDMode; + static uint8_t us; + static bool isActive; + static byte row, col; }; + +extern NumLock_ NumLock; From 4d22c27e8db4dc290ca6c3ff7a40e45fbee831ee Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 29 Jan 2017 08:20:03 +0100 Subject: [PATCH 035/792] Use Macros.row/.col instead of macroAction params To make the signature of `macroAction` simple, the `row` and `col` properties are not passed in every time anymore, but they are available as `Macros.row` and `Macros.col`, respectively. This keeps the function simple, but still allows access to these properties for the rarer case of needing them. Signed-off-by: Gergely Nagy --- src/Keyboardio-Macros.cpp | 8 ++++++-- src/Keyboardio-Macros.h | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Keyboardio-Macros.cpp b/src/Keyboardio-Macros.cpp index 5518b333..eb408576 100644 --- a/src/Keyboardio-Macros.cpp +++ b/src/Keyboardio-Macros.cpp @@ -1,10 +1,12 @@ #include "Keyboardio-Macros.h" __attribute__((weak)) -const macro_t *macroAction(uint8_t macroIndex, byte row, byte col, uint8_t keyState) { +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { return MACRO_NONE; } +byte Macros_::row, Macros_::col; + void Macros_::play(const macro_t *macro_p) { macro_t macro = END; uint8_t interval = 0; @@ -51,7 +53,9 @@ static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) if (!key_toggled_on(keyState)) return Key_NoKey; - const macro_t *m = macroAction(mappedKey.keyCode, row, col, keyState); + Macros_::row = row; + Macros_::col = col; + const macro_t *m = macroAction(mappedKey.keyCode, keyState); Macros.play(m); return Key_NoKey; diff --git a/src/Keyboardio-Macros.h b/src/Keyboardio-Macros.h index 7b24dd2f..e5e8b723 100644 --- a/src/Keyboardio-Macros.h +++ b/src/Keyboardio-Macros.h @@ -5,7 +5,7 @@ #include "MacroKeyDefs.h" #include "MacroSteps.h" -const macro_t *macroAction(uint8_t macroIndex, byte row, byte col, uint8_t keyState); +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); class Macros_ : public KeyboardioPlugin { public: @@ -14,6 +14,8 @@ class Macros_ : public KeyboardioPlugin { virtual void begin(void) final; void play(const macro_t *macro_p); + + static byte row, col; }; extern Macros_ Macros; From 17046f281e9000a6b6ac5be49c8181f18992aea7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 29 Jan 2017 08:23:12 +0100 Subject: [PATCH 036/792] Introduce two helper macros `TOGGLENUMLOCK` is the index of the macro, to be used in the `macroAction` function, and `Key_ToggleNumlock` is to be used in the keymap, instead of `M(0)`. This is considerably friendlier than before. Signed-off-by: Gergely Nagy --- src/Keyboardio-LEDEffect-Numlock.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Keyboardio-LEDEffect-Numlock.h b/src/Keyboardio-LEDEffect-Numlock.h index b6af6d55..8a71f8fc 100644 --- a/src/Keyboardio-LEDEffect-Numlock.h +++ b/src/Keyboardio-LEDEffect-Numlock.h @@ -4,6 +4,9 @@ #include "Keyboardio-Macros.h" #include "LEDUtils.h" +#define TOGGLENUMLOCK 0 +#define Key_ToggleNumlock M(TOGGLENUMLOCK) + class NumLock_ : LEDMode { public: NumLock_ (void); From 89b92927e4be8154076c62164a6f25653674df63 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 30 Jan 2017 23:22:19 +0100 Subject: [PATCH 037/792] Rename to Keyboardio-Numlock Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- ...boardio-LEDEffect-Numlock.cpp => Keyboardio-Numlock.cpp} | 2 +- ...{Keyboardio-LEDEffect-Numlock.h => Keyboardio-Numlock.h} | 0 4 files changed, 7 insertions(+), 7 deletions(-) rename src/{Keyboardio-LEDEffect-Numlock.cpp => Keyboardio-Numlock.cpp} (96%) rename src/{Keyboardio-LEDEffect-Numlock.h => Keyboardio-Numlock.h} (100%) diff --git a/README.md b/README.md index 971fd4f3..9c121ae8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Keyboardio-LEDEffect-Numlock +# Keyboardio-Numlock -This is a plugin for [KeyboardioFirmware][fw], adding an LED effect for when -Num-lock is active. +This is a plugin for [KeyboardioFirmware][fw], that adds a NumLock-specific LED +effect, along with a way to toggle to a numpad layer, and apply the effect. [fw]: https://github.com/keyboardio/KeyboardioFirmware diff --git a/library.properties b/library.properties index 2618caee..d2d6d175 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Keyboardio-LEDEffect-Numlock +name=Keyboardio-Numlock version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=Special LED effect for when Numlock is pressed on Keyboardio boards. +sentence=A Numlock plugin for KeyboardioFirmware. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-LEDEffect-Numlock +url=https://github.com/keyboardio/Keyboardio-Numlock architectures=avr dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-Numlock.cpp b/src/Keyboardio-Numlock.cpp similarity index 96% rename from src/Keyboardio-LEDEffect-Numlock.cpp rename to src/Keyboardio-Numlock.cpp index d80a6d86..ed216fee 100644 --- a/src/Keyboardio-LEDEffect-Numlock.cpp +++ b/src/Keyboardio-Numlock.cpp @@ -1,4 +1,4 @@ -#include "Keyboardio-LEDEffect-Numlock.h" +#include "Keyboardio-Numlock.h" #include "LEDUtils.h" #include "KeyboardioFirmware.h" #include "layers.h" diff --git a/src/Keyboardio-LEDEffect-Numlock.h b/src/Keyboardio-Numlock.h similarity index 100% rename from src/Keyboardio-LEDEffect-Numlock.h rename to src/Keyboardio-Numlock.h From 263b12151c398fde0b34c2a2315081832533e836 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 1 Feb 2017 14:09:26 +0100 Subject: [PATCH 038/792] Expose the timeOut (and rename it) Fixes #1. Signed-off-by: Gergely Nagy --- README.md | 13 ++++++++----- src/Akela/MagicCombo.cpp | 9 ++++----- src/Akela/MagicCombo.h | 7 ++----- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a748267d..e69cac96 100644 --- a/README.md +++ b/README.md @@ -50,13 +50,16 @@ left and the right halves. The extension provides a `MagicCombo` singleton object, with the following method: -### `.configure(dictionary[, timeout])` +### `.configure(dictionary)` -> Configures the extension to use the supplied dictionary, and restrict it to -> fire at most once every `timeout` cycles. +> Configures the extension to use the supplied dictionary. + +### `.minInterval` + +> Restrict the magic action to fire at most once every `minInterval` cycles. +> Defaults to 10. > -> If the timeout is not specified, it defaults to `DEFAULT_TIMEOUT`, which in -> turn is 40 cycles. +> Not strictly a method, it is a variable one can assign a new value to. ## Overrideable methods diff --git a/src/Akela/MagicCombo.cpp b/src/Akela/MagicCombo.cpp index cde6f777..8adddb38 100644 --- a/src/Akela/MagicCombo.cpp +++ b/src/Akela/MagicCombo.cpp @@ -21,7 +21,7 @@ namespace Akela { const MagicCombo::dictionary_t *MagicCombo::dictionary; - uint8_t MagicCombo::timeOut; + uint8_t MagicCombo::minInterval = 10; uint8_t MagicCombo::timer; MagicCombo::MagicCombo (void) { @@ -33,9 +33,8 @@ namespace Akela { } void - MagicCombo::configure (const MagicCombo::dictionary_t dictionary_[], uint8_t timeOut_) { + MagicCombo::configure (const MagicCombo::dictionary_t dictionary_[]) { dictionary = (dictionary_t *)dictionary_; - timeOut = timeOut_; } void @@ -43,7 +42,7 @@ namespace Akela { if (!dictionary || postClear) return; - if (timer && timer < timeOut) + if (timer && timer < minInterval) timer++; for (byte i = 0;; i++) { @@ -57,7 +56,7 @@ namespace Akela { if (KeyboardHardware.leftHandState.all == combo.leftHand && KeyboardHardware.rightHandState.all == combo.rightHand) { - if (timer == 0 || timer >= timeOut || timeOut == 0) { + if (timer == 0 || timer >= minInterval || minInterval == 0) { magicComboActions (i, combo.leftHand, combo.rightHand); timer = 1; } diff --git a/src/Akela/MagicCombo.h b/src/Akela/MagicCombo.h index c5338353..fa84a188 100644 --- a/src/Akela/MagicCombo.h +++ b/src/Akela/MagicCombo.h @@ -20,8 +20,6 @@ #include -#define AKELA_MAGICCOMBO_TIMEOUT DEFAULT_TIMEOUT - namespace Akela { class MagicCombo : public KeyboardioPlugin { public: @@ -33,12 +31,11 @@ namespace Akela { virtual void begin (void) final; - static void configure (const dictionary_t dictionary[], uint8_t timeout); - static void configure (const dictionary_t dictionary[]) { configure (dictionary, AKELA_MAGICCOMBO_TIMEOUT); }; + static void configure (const dictionary_t dictionary[]); + static uint8_t minInterval; private: static const dictionary_t *dictionary; - static uint8_t timeOut; static uint8_t timer; static void loopHook (bool postClear); From c782eb727523565d57b2a874cb66e17c69ebf5b5 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Feb 2017 09:18:54 +0100 Subject: [PATCH 039/792] Make diagonal mouse movement considerably smoother Instead of acting on mouse movement keys immediately in the event handler hook, just store them, and act on them during a loop hook. This has the effect of collecting all movement intents noticed in a full scan, and acting on them in one go, rather than acting individually. This makes diagonal movement (up & right keys pressed at the same time) a lot smoother, at the cost of a few ms of delay. The delay is not noticeable, and the smoothing would be a good trade anyway. No more jerky diagonal movements! Signed-off-by: Gergely Nagy --- src/Keyboardio-MouseKeys.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Keyboardio-MouseKeys.cpp b/src/Keyboardio-MouseKeys.cpp index b3a2a7be..e8af08d7 100644 --- a/src/Keyboardio-MouseKeys.cpp +++ b/src/Keyboardio-MouseKeys.cpp @@ -4,6 +4,25 @@ #include "MouseWrapper.h" #include "KeyboardioFirmware.h" +static uint8_t mouseMoveIntent; + +static void loopHook(bool postClear) { + if (postClear) { + mouseMoveIntent = 0; + return; + } + + if (mouseMoveIntent & KEY_MOUSE_UP) + MouseWrapper.move(0, -1); + else if (mouseMoveIntent & KEY_MOUSE_DOWN) + MouseWrapper.move(0, 1); + + if (mouseMoveIntent & KEY_MOUSE_LEFT) + MouseWrapper.move(-1, 0); + else if (mouseMoveIntent & KEY_MOUSE_RIGHT) + MouseWrapper.move(1, 0); +} + static void handle_mouse_key_event(Key mappedKey, uint8_t keyState) { if (key_toggled_off(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_UP || mappedKey.keyCode & KEY_MOUSE_DOWN) { @@ -17,17 +36,7 @@ static void handle_mouse_key_event(Key mappedKey, uint8_t keyState) { if (!key_is_pressed(keyState)) return; - if (mappedKey.keyCode & KEY_MOUSE_UP) { - MouseWrapper.move(0,-1); - } else if (mappedKey.keyCode & KEY_MOUSE_DOWN) { - MouseWrapper.move(0,1); - } - - if (mappedKey.keyCode & KEY_MOUSE_LEFT) { - MouseWrapper.move(-1,0); - } else if (mappedKey.keyCode & KEY_MOUSE_RIGHT) { - MouseWrapper.move(1,0); - } + mouseMoveIntent |= mappedKey.keyCode; } static Key handleMouseKeys(Key mappedKey, byte row, byte col, uint8_t keyState) { @@ -63,6 +72,7 @@ MouseKeys_::MouseKeys_(void) { void MouseKeys_::begin (void) { event_handler_hook_use (handleMouseKeys); + loop_hook_use (loopHook); } MouseKeys_ MouseKeys; From 41d57b598add3219bcfa87a756ae4e06ce1f9f15 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Feb 2017 09:58:54 +0100 Subject: [PATCH 040/792] Use a single accel counter Instead of calculating separate acceleration for the x and y axes, use only a single one, that applies to both axes. Thus, holding mouse up, and then pressing and holding right will move the mouse cursor in a straight diagonal line, instead of a curve. Signed-off-by: Gergely Nagy --- src/Keyboardio-MouseKeys.cpp | 25 ++++++++++++------------- src/MouseWrapper.cpp | 12 ++++-------- src/MouseWrapper.h | 4 ++-- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/Keyboardio-MouseKeys.cpp b/src/Keyboardio-MouseKeys.cpp index e8af08d7..9a61e123 100644 --- a/src/Keyboardio-MouseKeys.cpp +++ b/src/Keyboardio-MouseKeys.cpp @@ -12,27 +12,26 @@ static void loopHook(bool postClear) { return; } + if (mouseMoveIntent == 0) { + MouseWrapper.mouseActiveForCycles = 0; + return; + } + + if (MouseWrapper.mouseActiveForCycles < 255) + MouseWrapper.mouseActiveForCycles++; + if (mouseMoveIntent & KEY_MOUSE_UP) - MouseWrapper.move(0, -1); + MouseWrapper.move(0, -1); else if (mouseMoveIntent & KEY_MOUSE_DOWN) - MouseWrapper.move(0, 1); + MouseWrapper.move(0, 1); if (mouseMoveIntent & KEY_MOUSE_LEFT) - MouseWrapper.move(-1, 0); + MouseWrapper.move(-1, 0); else if (mouseMoveIntent & KEY_MOUSE_RIGHT) - MouseWrapper.move(1, 0); + MouseWrapper.move(1, 0); } static void handle_mouse_key_event(Key mappedKey, uint8_t keyState) { - if (key_toggled_off(keyState)) { - if (mappedKey.keyCode & KEY_MOUSE_UP || mappedKey.keyCode & KEY_MOUSE_DOWN) { - MouseWrapper.mouseActiveForCyclesY=0; - } - if (mappedKey.keyCode & KEY_MOUSE_LEFT || mappedKey.keyCode & KEY_MOUSE_RIGHT) { - MouseWrapper.mouseActiveForCyclesX=0; - } - } - if (!key_is_pressed(keyState)) return; diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 8426f044..a8e8eaaf 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -103,18 +103,14 @@ void MouseWrapper_::move( int8_t x, int8_t y) { int16_t moveX =0; int16_t moveY = 0; if (x != 0 ) { - if (mouseActiveForCyclesX < 255) { mouseActiveForCyclesX++;} - moveX = (x * acceleration(mouseActiveForCyclesX)); + moveX = (x * acceleration(mouseActiveForCycles)); } if (y != 0) { - if (mouseActiveForCyclesY < 255) { mouseActiveForCyclesY++;} - moveY = (y * acceleration(mouseActiveForCyclesY)); - + moveY = (y * acceleration(mouseActiveForCycles)); } - - end_warping(); - Mouse.move(moveX, moveY, 0); + end_warping(); + Mouse.move(moveX, moveY, 0); } MouseWrapper_ MouseWrapper; diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 4e8b7fd6..df2d98c8 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -37,8 +37,7 @@ class MouseWrapper_ { void warp(uint8_t warp_cmd); void press_button(uint8_t button); void release_button(uint8_t button); - uint8_t mouseActiveForCyclesX = 0; - uint8_t mouseActiveForCyclesY = 0; + uint8_t mouseActiveForCycles = 0; private: uint16_t next_width = 0; @@ -53,4 +52,5 @@ class MouseWrapper_ { void warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width); }; + extern MouseWrapper_ MouseWrapper; From ba1a8604a07f32359e56c0982b0f2b0d81ebc96c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Feb 2017 10:18:51 +0100 Subject: [PATCH 041/792] Some small code cleanups Move the hooks inside the `MouseKeys_` object, and drop the `handle_mouse_key_event` function, by inlining it into the event handler hook. Signed-off-by: Gergely Nagy --- src/Keyboardio-MouseKeys.cpp | 20 +++++++------------- src/Keyboardio-MouseKeys.h | 6 ++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Keyboardio-MouseKeys.cpp b/src/Keyboardio-MouseKeys.cpp index 9a61e123..4fb73917 100644 --- a/src/Keyboardio-MouseKeys.cpp +++ b/src/Keyboardio-MouseKeys.cpp @@ -4,9 +4,9 @@ #include "MouseWrapper.h" #include "KeyboardioFirmware.h" -static uint8_t mouseMoveIntent; +uint8_t MouseKeys_::mouseMoveIntent; -static void loopHook(bool postClear) { +void MouseKeys_::loopHook(bool postClear) { if (postClear) { mouseMoveIntent = 0; return; @@ -31,14 +31,7 @@ static void loopHook(bool postClear) { MouseWrapper.move(1, 0); } -static void handle_mouse_key_event(Key mappedKey, uint8_t keyState) { - if (!key_is_pressed(keyState)) - return; - - mouseMoveIntent |= mappedKey.keyCode; -} - -static Key handleMouseKeys(Key mappedKey, byte row, byte col, uint8_t keyState) { +Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY)) return mappedKey; @@ -51,7 +44,8 @@ static Key handleMouseKeys(Key mappedKey, byte row, byte col, uint8_t keyState) MouseWrapper.release_button(button); } } else if (!(mappedKey.keyCode & KEY_MOUSE_WARP)) { - handle_mouse_key_event(mappedKey, keyState); + if (key_is_pressed(keyState)) + mouseMoveIntent |= mappedKey.keyCode; } else if (key_toggled_on(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { // we don't pass in the left and up values because those are the @@ -70,8 +64,8 @@ MouseKeys_::MouseKeys_(void) { void MouseKeys_::begin (void) { - event_handler_hook_use (handleMouseKeys); - loop_hook_use (loopHook); + event_handler_hook_use(eventHandlerHook); + loop_hook_use(loopHook); } MouseKeys_ MouseKeys; diff --git a/src/Keyboardio-MouseKeys.h b/src/Keyboardio-MouseKeys.h index da24ec57..17d47aa5 100644 --- a/src/Keyboardio-MouseKeys.h +++ b/src/Keyboardio-MouseKeys.h @@ -8,6 +8,12 @@ class MouseKeys_ : public KeyboardioPlugin { MouseKeys_ (void); virtual void begin(void) final; + + private: + static uint8_t mouseMoveIntent; + + static void loopHook(bool postClear); + static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); }; extern MouseKeys_ MouseKeys; From ce734dbd37dcca1936bf1c3f2f409bbf61f26086 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Feb 2017 10:24:14 +0100 Subject: [PATCH 042/792] MouseWrapper: static-ification Mark most of the things static, to save a couple of bytes in program-space. Signed-off-by: Gergely Nagy --- src/MouseWrapper.cpp | 28 +++++++++++++--------------- src/MouseWrapper.h | 35 ++++++++++++++++------------------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index a8e8eaaf..fb58547e 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -4,6 +4,13 @@ // #include "MouseWrapper.h" +uint16_t MouseWrapper_::next_width; +uint16_t MouseWrapper_::next_height; +uint16_t MouseWrapper_::section_top; +uint16_t MouseWrapper_::section_left; +boolean MouseWrapper_::is_warping; + +uint8_t MouseWrapper_::mouseActiveForCycles; MouseWrapper_::MouseWrapper_(void) { Mouse.begin(); @@ -20,17 +27,12 @@ void MouseWrapper_::release_button(uint8_t button) { Mouse.release(button); } - void MouseWrapper_::warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width) { uint16_t x_center = left + width/2; uint16_t y_center = top + height/2; - AbsoluteMouse.moveTo(x_center,y_center); + AbsoluteMouse.moveTo(x_center, y_center); } - - - - void MouseWrapper_::begin_warping() { section_left = WARP_ABS_LEFT; section_top = WARP_ABS_TOP; @@ -48,14 +50,12 @@ void MouseWrapper_::warp(uint8_t warp_cmd) { begin_warping(); } - - if ( warp_cmd & WARP_END) { + if (warp_cmd & WARP_END) { end_warping(); return; } - - next_width = next_width / 2; + next_width = next_width/2; next_height = next_height/2; if (warp_cmd & WARP_UP) { @@ -73,10 +73,8 @@ void MouseWrapper_::warp(uint8_t warp_cmd) { } warp_jump(section_left, section_top, next_height,next_width); - } - // cubic wave function based on code from FastLED uint8_t MouseWrapper_::acceleration(uint8_t cycles) { uint8_t i = cycles; @@ -92,14 +90,14 @@ uint8_t MouseWrapper_::acceleration(uint8_t cycles) { i = (( (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii))) / 2) + ACCELERATION_FLOOR; - if ( i > ACCELERATION_CEIL) { - i = ACCELERATION_CEIL; + if (i > ACCELERATION_CEIL) { + i = ACCELERATION_CEIL; } return i; } -void MouseWrapper_::move( int8_t x, int8_t y) { +void MouseWrapper_::move(int8_t x, int8_t y) { int16_t moveX =0; int16_t moveY = 0; if (x != 0 ) { diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index df2d98c8..6c9fff10 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -11,8 +11,6 @@ #define WARP_LEFT 8 #define WARP_RIGHT 16 - - // apparently, the mac discards 15% of the value space for mouse movement. // need to test this on other platforms @@ -29,28 +27,27 @@ #define ACCELERATION_FLOOR 2 #define ACCELERATION_CEIL 50 - class MouseWrapper_ { public: MouseWrapper_(void); - void move( int8_t x, int8_t y); - void warp(uint8_t warp_cmd); - void press_button(uint8_t button); - void release_button(uint8_t button); - uint8_t mouseActiveForCycles = 0; - private: - uint16_t next_width = 0; - uint16_t next_height = 0; - uint16_t section_top = 0; - uint16_t section_left = 0; - boolean is_warping = false; - - uint8_t acceleration (uint8_t cycles); - void begin_warping(); - void end_warping(); - void warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width); + static void move(int8_t x, int8_t y); + static void warp(uint8_t warp_cmd); + static void press_button(uint8_t button); + static void release_button(uint8_t button); + static uint8_t mouseActiveForCycles; + private: + static uint16_t next_width; + static uint16_t next_height; + static uint16_t section_top; + static uint16_t section_left; + static boolean is_warping; + + static uint8_t acceleration(uint8_t cycles); + static void begin_warping(); + static void end_warping(); + static void warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width); }; extern MouseWrapper_ MouseWrapper; From 34923f8f755409734f06c4c0ee516337146b144f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Feb 2017 23:17:34 +0100 Subject: [PATCH 043/792] Minor mouse movement optimalisation When acting on `moveIntent`, set up the direction first, and move the cursor only once, instead of twice (once for each axis). This makes the movement even smoother, and also saves us a few bytes of code. Signed-off-by: Gergely Nagy --- src/Keyboardio-MouseKeys.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Keyboardio-MouseKeys.cpp b/src/Keyboardio-MouseKeys.cpp index 4fb73917..23a85a64 100644 --- a/src/Keyboardio-MouseKeys.cpp +++ b/src/Keyboardio-MouseKeys.cpp @@ -17,18 +17,22 @@ void MouseKeys_::loopHook(bool postClear) { return; } + int8_t moveX = 0, moveY = 0; + if (MouseWrapper.mouseActiveForCycles < 255) MouseWrapper.mouseActiveForCycles++; if (mouseMoveIntent & KEY_MOUSE_UP) - MouseWrapper.move(0, -1); + moveY = -1; else if (mouseMoveIntent & KEY_MOUSE_DOWN) - MouseWrapper.move(0, 1); + moveY = 1; if (mouseMoveIntent & KEY_MOUSE_LEFT) - MouseWrapper.move(-1, 0); + moveX = -1; else if (mouseMoveIntent & KEY_MOUSE_RIGHT) - MouseWrapper.move(1, 0); + moveX = 1; + + MouseWrapper.move(moveX, moveY); } Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) { From d0182ad2bb18fb7b9f940292ac293b387216fa14 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 4 Feb 2017 18:20:23 +0100 Subject: [PATCH 044/792] Instead of including KeyboardConfig.h, include KeyboardioFirmware.h This works both when the hardware bits are still in KeyboardioFirmware, and when lifted out, too. Signed-off-by: Gergely Nagy --- src/LEDUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LEDUtils.h b/src/LEDUtils.h index 40e0d2c2..ee0d851e 100644 --- a/src/LEDUtils.h +++ b/src/LEDUtils.h @@ -1,6 +1,6 @@ #pragma once -#include "KeyboardConfig.h" +#include cRGB breath_compute (void); cRGB hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v); From c7a622f0cc851835d4279afc740c9dbe26237a0e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 4 Feb 2017 18:30:56 +0100 Subject: [PATCH 045/792] Lifted out from the core firmware This is a library that implements the hardware-specific pieces for the Keyboardio Model01, to be used with KeyboardioFirmware. It's the same as `src/Model01.cpp`, `src/Model01.h`, `src/KeyboardConfig.cpp`, `src/KeyboardConfig.h`, `src/utils.cpp`, and `src/utils.h` from KeyboardioFirmware, merged into two files. Signed-off-by: Gergely Nagy --- COPYING | 339 ++++++++++++++++++++++++++++ README.md | 7 + library.properties | 9 + src/Keyboardio-Hardware-Model01.cpp | 173 ++++++++++++++ src/Keyboardio-Hardware-Model01.h | 208 +++++++++++++++++ 5 files changed, 736 insertions(+) create mode 100644 COPYING create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Keyboardio-Hardware-Model01.cpp create mode 100644 src/Keyboardio-Hardware-Model01.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..76de0d05 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Keyboardio-Hardware-Model01 + +This is a plugin for [KeyboardioFirmware][fw], that adds hardware support for +the [Keyboardio Model01][kbdio:model01]. + + [fw]: https://github.com/keyboardio/KeyboardioFirmware + [kbdio:model01]: https://shop.keyboard.io/ diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..cdfe1578 --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=Keyboardio-Hardware-Model01 +version=0.0.1 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=Keyboardio Model01 Hardware support for KeyboardioFirmware. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Keyboardio-Hardware-Model01 +architectures=avr diff --git a/src/Keyboardio-Hardware-Model01.cpp b/src/Keyboardio-Hardware-Model01.cpp new file mode 100644 index 00000000..bcd9033b --- /dev/null +++ b/src/Keyboardio-Hardware-Model01.cpp @@ -0,0 +1,173 @@ +#include +#include + +KeyboardioScanner Model01::leftHand(0); +KeyboardioScanner Model01::rightHand(3); + +static constexpr uint8_t key_led_map[4][16] = { + {3,4,11,12,19,20,26,27, 36,37,43,44,51,52,59,60}, + {2,5,10,13,18,21,25,28, 35,38,42,45,50,53,58,61}, + {1,6, 9,14,17,22,24,29, 34,39,41,46,49,54,57,62}, + {0,7, 8,15,16,23,31,30, 33,32,40,47,48,55,56,63}, +}; + +Model01::Model01(void) { + +} + +void Model01::enable_scanner_power(void) { + // PC7 + //pinMode(13, OUTPUT); + //digitalWrite(13, HIGH); + // Turn on power to the LED net + DDRC |= _BV(7); + PORTC |= _BV(7); + +} + +// This lets the keyboard pull up to 1.6 amps from +// the host. That violates the USB spec. But it sure +// is pretty looking +void Model01::enable_high_power_leds(void) { + // PE6 + // pinMode(7, OUTPUT); +// digitalWrite(7, LOW); + + DDRE |= _BV(6); + PORTE &= ~_BV(6); + +} + +void Model01::setup(void) { + enable_scanner_power(); + + // Consider not doing this until 30s after keyboard + // boot up, to make it easier to rescue things + // in case of power draw issues. + enable_high_power_leds(); + leftHandState.all = 0; + rightHandState.all = 0; + + TWBR=12; // This is 400mhz, which is the fastest we can drive the ATTiny +} + + +void Model01::led_set_crgb_at(uint8_t i, cRGB crgb) { + if(i<32) { + leftHand.ledData.leds[i] = crgb; + } else if (i<64) { + rightHand.ledData.leds[i-32] = crgb; + } else { + // TODO how do we want to handle debugging assertions about crazy user + // code that would overwrite other memory? + } +} + +void Model01::led_set_crgb_at(byte row, byte col, cRGB color) { + led_set_crgb_at(key_led_map[row][col], color); +} + +cRGB Model01::led_get_crgb_at(uint8_t i) { + if(i<32) { + return leftHand.ledData.leds[i]; + } else if (i<64) { + return rightHand.ledData.leds[i-32] ; + } else { + return {0, 0, 0}; + } +} + +void Model01::led_sync() { + leftHand.sendLEDData(); + rightHand.sendLEDData(); + + leftHand.sendLEDData(); + rightHand.sendLEDData(); + + leftHand.sendLEDData(); + rightHand.sendLEDData(); + + leftHand.sendLEDData(); + rightHand.sendLEDData(); + +} + +void debug_key_event(keydata_t state, keydata_t previousState, uint8_t keynum, uint8_t row, uint8_t col) { + if (bitRead(state.all, keynum) != bitRead(previousState.all, keynum )) { + Serial.print("Looking at row "); + Serial.print(row); + Serial.print(", col "); + Serial.print(col); + Serial.print(" key # "); + Serial.print(keynum); + Serial.print(" "); + Serial.print(bitRead(previousState.all, keynum)); + Serial.print(" -> "); + Serial.print(bitRead(state.all, keynum )); + Serial.println(); + } +} + + +void Model01::read_matrix() { + //scan the Keyboard matrix looking for connections + previousLeftHandState = leftHandState; + previousRightHandState = rightHandState; + + if (leftHand.readKeys()) { + leftHandState = leftHand.getKeyData(); + } + + if (rightHand.readKeys()) { + rightHandState = rightHand.getKeyData(); + } +} + + + +void Model01::act_on_matrix_scan() { + for (byte row = 0; row < 4; row++) { + for (byte col = 0; col < 8; col++) { + + uint8_t keynum = (row*8)+(col); + + uint8_t keyState = (bitRead(previousLeftHandState.all, keynum) << 0) | + (bitRead(leftHandState.all, keynum) << 1); + handle_key_event(Key_NoKey, row, 7-col, keyState); + + keyState = (bitRead(previousRightHandState.all, keynum) << 0) | + (bitRead(rightHandState.all, keynum) << 1); + + handle_key_event(Key_NoKey, row, (15- col), keyState); + } + } +} + + +void Model01::scan_matrix() { + read_matrix(); + act_on_matrix_scan(); +} + +void Model01::reboot_bootloader() { + // Set the magic bits to get a Caterina-based device + // to reboot into the bootloader and stay there, rather + // than run move onward + // + // These values are the same as those defined in + // Caterina.c + + uint16_t bootKey = 0x7777; + uint16_t *const bootKeyPtr = (uint16_t *)0x0800; + + // Stash the magic key + *bootKeyPtr = bootKey; + + // Set a watchdog timer + wdt_enable(WDTO_120MS); + + while (1) {} // This infinite loop ensures nothing else + // happens before the watchdog reboots us +} + +HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Keyboardio-Hardware-Model01.h b/src/Keyboardio-Hardware-Model01.h new file mode 100644 index 00000000..15483a7d --- /dev/null +++ b/src/Keyboardio-Hardware-Model01.h @@ -0,0 +1,208 @@ +#pragma once + +#include + +#define HARDWARE_IMPLEMENTATION Model01 +#include "KeyboardioScanner.h" + +//#include "keymap_metadata.h" +//#include "key_events.h" + +class Model01 { + public: + Model01(void); + void led_sync(void); + void led_set_crgb_at(byte row, byte col, cRGB color); + void led_set_crgb_at(uint8_t i, cRGB crgb); + cRGB led_get_crgb_at(uint8_t i); + cRGB get_key_color(byte row, byte col); + + void scan_matrix(void); + void read_matrix(void); + void act_on_matrix_scan(void); + void setup(); + void enable_high_power_leds(void); + void enable_scanner_power(void); + void reboot_bootloader(); + + keydata_t leftHandState; + keydata_t rightHandState; + keydata_t previousLeftHandState; + keydata_t previousRightHandState; + + private: + static KeyboardioScanner leftHand; + static KeyboardioScanner rightHand; +}; + +#define SCANBIT(row,col) ((uint32_t)1 << (row * 8 + (7 - col))) + +#define R0C0 SCANBIT(0, 0) +#define R0C1 SCANBIT(0, 1) +#define R0C2 SCANBIT(0, 2) +#define R0C3 SCANBIT(0, 3) +#define R0C4 SCANBIT(0, 4) +#define R0C5 SCANBIT(0, 5) +#define R0C6 SCANBIT(0, 6) +#define R0C7 SCANBIT(0, 7) +#define R1C0 SCANBIT(1, 0) +#define R1C1 SCANBIT(1, 1) +#define R1C2 SCANBIT(1, 2) +#define R1C3 SCANBIT(1, 3) +#define R1C4 SCANBIT(1, 4) +#define R1C5 SCANBIT(1, 5) +#define R1C6 SCANBIT(1, 6) +#define R1C7 SCANBIT(1, 7) +#define R2C0 SCANBIT(2, 0) +#define R2C1 SCANBIT(2, 1) +#define R2C2 SCANBIT(2, 2) +#define R2C3 SCANBIT(2, 3) +#define R2C4 SCANBIT(2, 4) +#define R2C5 SCANBIT(2, 5) +#define R2C6 SCANBIT(2, 6) +#define R2C7 SCANBIT(2, 7) +#define R3C0 SCANBIT(3, 0) +#define R3C1 SCANBIT(3, 1) +#define R3C2 SCANBIT(3, 2) +#define R3C3 SCANBIT(3, 3) +#define R3C4 SCANBIT(3, 4) +#define R3C5 SCANBIT(3, 5) +#define R3C6 SCANBIT(3, 6) +#define R3C7 SCANBIT(3, 7) + +#define R0C8 SCANBIT(0, 0) +#define R0C9 SCANBIT(0, 1) +#define R0C10 SCANBIT(0, 2) +#define R0C11 SCANBIT(0, 3) +#define R0C12 SCANBIT(0, 4) +#define R0C13 SCANBIT(0, 5) +#define R0C14 SCANBIT(0, 6) +#define R0C15 SCANBIT(0, 7) +#define R1C8 SCANBIT(1, 0) +#define R1C9 SCANBIT(1, 1) +#define R1C10 SCANBIT(1, 2) +#define R1C11 SCANBIT(1, 3) +#define R1C12 SCANBIT(1, 4) +#define R1C13 SCANBIT(1, 5) +#define R1C14 SCANBIT(1, 6) +#define R1C15 SCANBIT(1, 7) +#define R2C8 SCANBIT(2, 0) +#define R2C9 SCANBIT(2, 1) +#define R2C10 SCANBIT(2, 2) +#define R2C11 SCANBIT(2, 3) +#define R2C12 SCANBIT(2, 4) +#define R2C13 SCANBIT(2, 5) +#define R2C14 SCANBIT(2, 6) +#define R2C15 SCANBIT(2, 7) +#define R3C8 SCANBIT(3, 0) +#define R3C9 SCANBIT(3, 1) +#define R3C10 SCANBIT(3, 2) +#define R3C11 SCANBIT(3, 3) +#define R3C12 SCANBIT(3, 4) +#define R3C13 SCANBIT(3, 5) +#define R3C14 SCANBIT(3, 6) +#define R3C15 SCANBIT(3, 7) + + +#define LED_COUNT 64 + + +#define LED_PGDN 0 +#define LED_PGUP 1 +#define LED_BACKTICK 2 +#define LED_LED 3 +#define LED_1 4 +#define LED_Q 5 +#define LED_A 6 +#define LED_Z 7 +#define LED_X 8 +#define LED_S 9 +#define LED_W 10 +#define LED_2 11 +#define LED_3 12 +#define LED_E 13 +#define LED_D 14 +#define LED_C 15 +#define LED_V 16 +#define LED_F 17 +#define LED_R 18 +#define LED_4 19 +#define LED_5 20 +#define LED_T 21 +#define LED_REC_MACRO 22 +#define LED_B 23 +#define LED_ESC 24 +#define LED_TAB 25 +#define LED_REC 26 +#define LED_L_FN 27 +#define LED_L_CTRL 28 +#define LED_DEL 29 +#define LED_CMD 30 +#define LED_L_SHIFT 31 +#define LED_R_SHIFT 32 +#define LED_ALT 33 +#define LED_SPACE 34 +#define LED_CTRL 35 +#define LED_R_FN 36 +#define LED_ANY 37 +#define LED_RETURN 38 +#define LED_BUTTERFLY 39 +#define LED_N 40 +#define LED_H 41 +#define LED_Y 42 +#define LED_6 43 +#define LED_7 44 +#define LED_U 45 +#define LED_J 46 +#define LED_M 47 +#define LED_COMMA 48 +#define LED_K 49 +#define LED_I 50 +#define LED_8 51 +#define LED_9 52 +#define LED_O 53 +#define LED_L 54 +#define LED_PERIOD 55 +#define LED_SLASH 56 +#define LED_SEMICOLON 57 +#define LED_P 58 +#define LED_0 59 +#define LED_NUM 60 +#define LED_EQUALS 61 +#define LED_APOSTROPHE 62 +#define LED_MINUS 63 + +#define KEYMAP_STACKED( \ + r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, \ + r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, \ + r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, \ + r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r2c6, \ + r0c7, r1c7, r2c7, r3c7, \ + r3c6, \ + \ + r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15, \ + r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15, \ + r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, \ + r2c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, \ + r3c8, r2c8, r1c8, r0c8, \ + r3c9) \ + { \ + {r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c7, r0c8, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15}, \ + {r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15}, \ + {r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15}, \ + {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15}, \ + } + +#define KEYMAP( \ + r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15, \ + r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15, \ + r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, \ + r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r2c6, r2c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, \ + r0c7, r1c7, r2c7, r3c7, r3c8, r2c8, r1c8, r0c8, \ + r3c6, r3c9) \ + { \ + {r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c7, r0c8, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15}, \ + {r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15}, \ + {r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15}, \ + {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15}, \ + } From cb25a044938e91c4537fe3a80c6a79de0d535cab Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 5 Feb 2017 08:53:42 +0100 Subject: [PATCH 046/792] Moved COLS and ROWS over from core Thanks @obra for catching this! Signed-off-by: Gergely Nagy --- src/Keyboardio-Hardware-Model01.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Keyboardio-Hardware-Model01.h b/src/Keyboardio-Hardware-Model01.h index 15483a7d..448d0ca7 100644 --- a/src/Keyboardio-Hardware-Model01.h +++ b/src/Keyboardio-Hardware-Model01.h @@ -5,8 +5,8 @@ #define HARDWARE_IMPLEMENTATION Model01 #include "KeyboardioScanner.h" -//#include "keymap_metadata.h" -//#include "key_events.h" +#define COLS 16 +#define ROWS 4 class Model01 { public: From a691a949ab99e908b4c6fcdce65a1c3b8e577e8e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 5 Feb 2017 09:02:32 +0100 Subject: [PATCH 047/792] Merge Storage into Model01 Moved over the primary layer read/write code from KeyboardioFirmware, and renamed them to `load_primary_layer`/`save_primary_layer`, because they deal with layers, not keymaps now. Signed-off-by: Gergely Nagy --- src/Keyboardio-Hardware-Model01.cpp | 15 +++++++++++++++ src/Keyboardio-Hardware-Model01.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/src/Keyboardio-Hardware-Model01.cpp b/src/Keyboardio-Hardware-Model01.cpp index bcd9033b..d2493e8d 100644 --- a/src/Keyboardio-Hardware-Model01.cpp +++ b/src/Keyboardio-Hardware-Model01.cpp @@ -1,5 +1,8 @@ #include #include +#include + +#define EEPROM_LAYER_LOCATION 0 KeyboardioScanner Model01::leftHand(0); KeyboardioScanner Model01::rightHand(3); @@ -170,4 +173,16 @@ void Model01::reboot_bootloader() { // happens before the watchdog reboots us } +void Model01::save_primary_layer(uint8_t layer) { + EEPROM.write(EEPROM_LAYER_LOCATION, layer); +} + +uint8_t Model01::load_primary_layer(uint8_t layer_count) { + uint8_t layer = EEPROM.read(EEPROM_LAYER_LOCATION); + if (layer >= layer_count) { + return 0; // undefined positions get saved as 255 + } + return 0; // return keymap; +} + HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Keyboardio-Hardware-Model01.h b/src/Keyboardio-Hardware-Model01.h index 448d0ca7..9c647943 100644 --- a/src/Keyboardio-Hardware-Model01.h +++ b/src/Keyboardio-Hardware-Model01.h @@ -25,6 +25,9 @@ class Model01 { void enable_scanner_power(void); void reboot_bootloader(); + uint8_t load_primary_layer(uint8_t layer_count); + void save_primary_layer(uint8_t layer); + keydata_t leftHandState; keydata_t rightHandState; keydata_t previousLeftHandState; From eae20c72de7faa5e5e471ae480f03870ae2eba02 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 7 Feb 2017 21:22:56 -0800 Subject: [PATCH 048/792] Initial commit --- COPYING | 339 ++++++++++++++++++++++++++++ library.properties | 10 + src/Keyboardio-Model01-TestMode.cpp | 137 +++++++++++ src/Keyboardio-Model01-TestMode.h | 19 ++ 4 files changed, 505 insertions(+) create mode 100644 COPYING create mode 100644 library.properties create mode 100644 src/Keyboardio-Model01-TestMode.cpp create mode 100644 src/Keyboardio-Model01-TestMode.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..c8c461a2 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Keyboardio-Model01-TestMode +version=0.0.0 +author=Jesse Vincent +maintainer=Jesse Vincent +sentence=A factory test mode for the Model 01. +paragraph=A special mode for the Model 01 to help factory workers test the Model 01 during assembly. +category=Communication +url=https://github.com/keyboardio/Keyboardio-Model01-TestMode +architectures=avr +dot_a_linkage=true diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp new file mode 100644 index 00000000..99e588d2 --- /dev/null +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -0,0 +1,137 @@ +#include "KeyboardioFirmware.h" +#include "Keyboardio-Model01-TestMode.h" +#include "Keyboardio-LEDEffect-Rainbow.h" + +cRGB red; +cRGB blue; + +#define LED_TEST_DELAY 2000 + +uint8_t TestMode_::minInterval = 10; +uint8_t TestMode_::timer; + +TestMode_::TestMode_(void) { +} + + +void TestMode_::begin(void) { + loop_hook_use (this->loopHook); + +} + +void TestMode_::loopHook (bool postClear) { + if (!dictionary || postClear) + return; + if (timer && timer < minInterval) + timer++; + if (KeyboardHardware.leftHandState.all == R1C3 | R2C1 | R2C4 | R2C7 +// && KeyboardHardware.rightHandState.all == combo.rightHand + ) { + if (timer == 0 || timer >= minInterval || minInterval == 0) { + loop(); + timer = 1; + } + return; + } +} + +void TestMode_::TestLEDs(void) { + // make all LEDs dim red + LEDControl.set_all_leds_to(50,0,0); + LEDControl.led_sync(); + delay(LED_TEST_DELAY); + // make all LEDs dim blue + LEDControl.set_all_leds_to(0,50,0); + LEDControl.led_sync(); + delay(LED_TEST_DELAY); + // make all LEDs dim green + LEDControl.set_all_leds_to(0,0,50); + LEDControl.led_sync(); + delay(LED_TEST_DELAY); + // make all LEDs dim white + LEDControl.set_all_leds_to(50,50,50); + LEDControl.led_sync(); + delay(LED_TEST_DELAY); + // make all the LEDs bright red + LEDControl.set_all_leds_to(200,0,0); + LEDControl.led_sync(); + delay(LED_TEST_DELAY); + // make all the LEDs bright green + LEDControl.set_all_leds_to(0,200,0); + LEDControl.led_sync(); + delay(LED_TEST_DELAY); + // make all the LEDs bright blue + LEDControl.set_all_leds_to(0,0,200); + LEDControl.led_sync(); + delay(LED_TEST_DELAY); + // make all the LEDs bright white (1.6A) + LEDControl.set_all_leds_to(160,160,160); + LEDControl.led_sync(); + delay(LED_TEST_DELAY); + // rainbow for 10 seconds + for(auto i=0; i<1000; i++ ) { + LEDRainbowEffect.update(); + LEDControl.led_sync(); + } + // set all the keys to red + LEDControl.set_all_leds_to(50,0,0); + // make all LEDs dim blue + // as you hit each key, set it to blue + // as you hit each key a second time, set it to green + // as you hit each key a third time, set it to off +} + + + + +void TestMode_::TestMatrix () { + while(1) { + KeyboardHardware.read_matrix(); + for (byte row = 0; row < 4; row++) { + for (byte col = 0; col < 8; col++) { + + uint8_t keynum = (row*8)+(col); + + uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | + (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); + + if(keyState ==3 ) { + Serial.print(" Key: "); + Serial.print(keynum); + Serial.print(" value "); + Serial.println(keyState); + KeyboardHardware.led_set_crgb_at(row, 7-col, red); + } else if (keyState ==1) { + KeyboardHardware.led_set_crgb_at(row,7-col, blue); + } + + keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | + (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); + + if(keyState ==3 ) { + Serial.print(" Key: "); + Serial.print(keynum); + Serial.print(" value "); + Serial.println(keyState); + KeyboardHardware.led_set_crgb_at(row, 15-col, red); + } else if (keyState ==1) { + KeyboardHardware.led_set_crgb_at(row,15-col, blue); + } + } + } + LEDControl.led_sync(); + } +} + +void TestMode_::setup() { +red.r=101; +blue.b=101; + TestLEDs(); + +} + +void TestMode_::loop() { + TestMatrix(); +} + +TestMode_ TestMode; diff --git a/src/Keyboardio-Model01-TestMode.h b/src/Keyboardio-Model01-TestMode.h new file mode 100644 index 00000000..9115876a --- /dev/null +++ b/src/Keyboardio-Model01-TestMode.h @@ -0,0 +1,19 @@ +#pragma once +#include + +class TestMode_ { + public: + TestMode_(void); + void setup(); + void loop(); + + private: + void TestLEDs(); + void TestKeys(); + void TestMatrix(); + void TestOneKey(); +}; + +extern TestMode_ TestMode; + +Key handle_key_event_test(Key mappedKey, byte row, byte col, uint8_t keyState); From 82ae0041596a9ae75aaa7e34c0bf874c84480209 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 7 Feb 2017 23:35:16 -0800 Subject: [PATCH 049/792] Fixes so the code compiles. It doesn't, like, work yet or anything. --- src/Keyboardio-Model01-TestMode.cpp | 4 ++-- src/Keyboardio-Model01-TestMode.h | 14 +++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp index 99e588d2..bebfd35a 100644 --- a/src/Keyboardio-Model01-TestMode.cpp +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -20,11 +20,11 @@ void TestMode_::begin(void) { } void TestMode_::loopHook (bool postClear) { - if (!dictionary || postClear) + if ( postClear) return; if (timer && timer < minInterval) timer++; - if (KeyboardHardware.leftHandState.all == R1C3 | R2C1 | R2C4 | R2C7 + if (KeyboardHardware.leftHandState.all == (R1C3 | R2C1 | R2C4 | R2C7) // && KeyboardHardware.rightHandState.all == combo.rightHand ) { if (timer == 0 || timer >= minInterval || minInterval == 0) { diff --git a/src/Keyboardio-Model01-TestMode.h b/src/Keyboardio-Model01-TestMode.h index 9115876a..71aab9e9 100644 --- a/src/Keyboardio-Model01-TestMode.h +++ b/src/Keyboardio-Model01-TestMode.h @@ -5,13 +5,17 @@ class TestMode_ { public: TestMode_(void); void setup(); - void loop(); + static void loop(); + void begin(); + static uint8_t minInterval; private: - void TestLEDs(); - void TestKeys(); - void TestMatrix(); - void TestOneKey(); + static void TestLEDs(); + static void TestKeys(); + static void TestMatrix(); + static void TestOneKey(); + static uint8_t timer; + static void loopHook(bool postClear); }; extern TestMode_ TestMode; From 8f0976219a2f4f9100bebf4ed855c4827a4f9bce Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 8 Feb 2017 13:50:14 -0800 Subject: [PATCH 050/792] Remove vestiges of timers from Akela::MagicCombo --- src/Keyboardio-Model01-TestMode.cpp | 9 --------- src/Keyboardio-Model01-TestMode.h | 2 -- 2 files changed, 11 deletions(-) diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp index bebfd35a..9ba16e1a 100644 --- a/src/Keyboardio-Model01-TestMode.cpp +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -7,9 +7,6 @@ cRGB blue; #define LED_TEST_DELAY 2000 -uint8_t TestMode_::minInterval = 10; -uint8_t TestMode_::timer; - TestMode_::TestMode_(void) { } @@ -22,17 +19,11 @@ void TestMode_::begin(void) { void TestMode_::loopHook (bool postClear) { if ( postClear) return; - if (timer && timer < minInterval) - timer++; if (KeyboardHardware.leftHandState.all == (R1C3 | R2C1 | R2C4 | R2C7) // && KeyboardHardware.rightHandState.all == combo.rightHand ) { - if (timer == 0 || timer >= minInterval || minInterval == 0) { loop(); - timer = 1; } - return; - } } void TestMode_::TestLEDs(void) { diff --git a/src/Keyboardio-Model01-TestMode.h b/src/Keyboardio-Model01-TestMode.h index 71aab9e9..0f430244 100644 --- a/src/Keyboardio-Model01-TestMode.h +++ b/src/Keyboardio-Model01-TestMode.h @@ -7,14 +7,12 @@ class TestMode_ { void setup(); static void loop(); void begin(); - static uint8_t minInterval; private: static void TestLEDs(); static void TestKeys(); static void TestMatrix(); static void TestOneKey(); - static uint8_t timer; static void loopHook(bool postClear); }; From 0ec9767232a32206fdcdb7ed340026ccb619d2be Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 8 Feb 2017 14:02:44 -0800 Subject: [PATCH 051/792] reorganziation to remove unused functions from the api --- src/Keyboardio-Model01-TestMode.cpp | 18 +++++++----------- src/Keyboardio-Model01-TestMode.h | 9 +++------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp index 9ba16e1a..f71c8f23 100644 --- a/src/Keyboardio-Model01-TestMode.cpp +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -12,6 +12,8 @@ TestMode_::TestMode_(void) { void TestMode_::begin(void) { +red.r=101; +blue.b=101; loop_hook_use (this->loopHook); } @@ -26,7 +28,7 @@ void TestMode_::loopHook (bool postClear) { } } -void TestMode_::TestLEDs(void) { +void TestMode_::test_leds(void) { // make all LEDs dim red LEDControl.set_all_leds_to(50,0,0); LEDControl.led_sync(); @@ -75,7 +77,7 @@ void TestMode_::TestLEDs(void) { -void TestMode_::TestMatrix () { +void TestMode_::test_matrix () { while(1) { KeyboardHardware.read_matrix(); for (byte row = 0; row < 4; row++) { @@ -114,15 +116,9 @@ void TestMode_::TestMatrix () { } } -void TestMode_::setup() { -red.r=101; -blue.b=101; - TestLEDs(); - -} - -void TestMode_::loop() { - TestMatrix(); +void TestMode_::run_tests() { + test_leds(); + test_matrix(); } TestMode_ TestMode; diff --git a/src/Keyboardio-Model01-TestMode.h b/src/Keyboardio-Model01-TestMode.h index 0f430244..752f3e55 100644 --- a/src/Keyboardio-Model01-TestMode.h +++ b/src/Keyboardio-Model01-TestMode.h @@ -4,15 +4,12 @@ class TestMode_ { public: TestMode_(void); - void setup(); - static void loop(); void begin(); private: - static void TestLEDs(); - static void TestKeys(); - static void TestMatrix(); - static void TestOneKey(); + static void run_tests(); + static void test_leds(); + static void test_matrix(); static void loopHook(bool postClear); }; From 5c59ea650ffe17e0ff5208d057321d843c3f4c73 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 8 Feb 2017 14:38:26 -0800 Subject: [PATCH 052/792] Actually jump into the test mode when you tap left prog, left led, left fn. --- src/Keyboardio-Model01-TestMode.cpp | 6 ++++-- src/Keyboardio-Model01-TestMode.h | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp index f71c8f23..52835a7c 100644 --- a/src/Keyboardio-Model01-TestMode.cpp +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -21,10 +21,10 @@ blue.b=101; void TestMode_::loopHook (bool postClear) { if ( postClear) return; - if (KeyboardHardware.leftHandState.all == (R1C3 | R2C1 | R2C4 | R2C7) + if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6 ) // && KeyboardHardware.rightHandState.all == combo.rightHand ) { - loop(); + run_tests(); } } @@ -117,8 +117,10 @@ void TestMode_::test_matrix () { } void TestMode_::run_tests() { +Serial.println("Running tests"); test_leds(); test_matrix(); +Serial.println("Done running tests"); } TestMode_ TestMode; diff --git a/src/Keyboardio-Model01-TestMode.h b/src/Keyboardio-Model01-TestMode.h index 752f3e55..bd780e93 100644 --- a/src/Keyboardio-Model01-TestMode.h +++ b/src/Keyboardio-Model01-TestMode.h @@ -1,7 +1,9 @@ #pragma once + #include +#include "KeyboardioFirmware.h" -class TestMode_ { +class TestMode_ : public KeyboardioPlugin { public: TestMode_(void); void begin(); From 0e71744c0113e306514caa8691658a19551f5e9a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 8 Feb 2017 15:47:09 -0800 Subject: [PATCH 053/792] astyle. no code changes --- src/Keyboardio-Model01-TestMode.cpp | 88 ++++++++++++++--------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp index 52835a7c..37cf6162 100644 --- a/src/Keyboardio-Model01-TestMode.cpp +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -12,20 +12,20 @@ TestMode_::TestMode_(void) { void TestMode_::begin(void) { -red.r=101; -blue.b=101; + red.r=101; + blue.b=101; loop_hook_use (this->loopHook); } void TestMode_::loopHook (bool postClear) { if ( postClear) - return; + return; if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6 ) // && KeyboardHardware.rightHandState.all == combo.rightHand - ) { - run_tests(); - } + ) { + run_tests(); + } } void TestMode_::test_leds(void) { @@ -78,49 +78,49 @@ void TestMode_::test_leds(void) { void TestMode_::test_matrix () { - while(1) { - KeyboardHardware.read_matrix(); - for (byte row = 0; row < 4; row++) { - for (byte col = 0; col < 8; col++) { - - uint8_t keynum = (row*8)+(col); - - uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | - (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); - - if(keyState ==3 ) { - Serial.print(" Key: "); - Serial.print(keynum); - Serial.print(" value "); - Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 7-col, red); - } else if (keyState ==1) { - KeyboardHardware.led_set_crgb_at(row,7-col, blue); - } - - keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | - (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); - - if(keyState ==3 ) { - Serial.print(" Key: "); - Serial.print(keynum); - Serial.print(" value "); - Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 15-col, red); - } else if (keyState ==1) { - KeyboardHardware.led_set_crgb_at(row,15-col, blue); - } + while(1) { + KeyboardHardware.read_matrix(); + for (byte row = 0; row < 4; row++) { + for (byte col = 0; col < 8; col++) { + + uint8_t keynum = (row*8)+(col); + + uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | + (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); + + if(keyState ==3 ) { + Serial.print(" Key: "); + Serial.print(keynum); + Serial.print(" value "); + Serial.println(keyState); + KeyboardHardware.led_set_crgb_at(row, 7-col, red); + } else if (keyState ==1) { + KeyboardHardware.led_set_crgb_at(row,7-col, blue); + } + + keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | + (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); + + if(keyState ==3 ) { + Serial.print(" Key: "); + Serial.print(keynum); + Serial.print(" value "); + Serial.println(keyState); + KeyboardHardware.led_set_crgb_at(row, 15-col, red); + } else if (keyState ==1) { + KeyboardHardware.led_set_crgb_at(row,15-col, blue); + } + } } + LEDControl.led_sync(); } - LEDControl.led_sync(); - } } void TestMode_::run_tests() { -Serial.println("Running tests"); - test_leds(); - test_matrix(); -Serial.println("Done running tests"); + Serial.println("Running tests"); + test_leds(); + test_matrix(); + Serial.println("Done running tests"); } TestMode_ TestMode; From fcd0c8025dff664390f400d6adefff4fe4f1cf32 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 8 Feb 2017 18:53:20 -0800 Subject: [PATCH 054/792] Switch our LED testing to use a helper function that waits for a keypress --- src/Keyboardio-Model01-TestMode.cpp | 51 +++++++++++++++-------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp index 37cf6162..f763840a 100644 --- a/src/Keyboardio-Model01-TestMode.cpp +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -28,39 +28,42 @@ void TestMode_::loopHook (bool postClear) { } } +void TestMode_::wait_for_keypress() { + delay(25); + while (1) { + KeyboardHardware.read_matrix(); + if (KeyboardHardware.leftHandState.all == R3C6 + && KeyboardHardware.previousLeftHandState.all == 0 ) { + break; + } +} + +} + +void TestMode_::set_leds(uint8_t r, uint8_t g, uint8_t b) { + LEDControl.set_all_leds_to(r,g,b); + LEDControl.led_sync(); + wait_for_keypress(); + +} + void TestMode_::test_leds(void) { // make all LEDs dim red - LEDControl.set_all_leds_to(50,0,0); - LEDControl.led_sync(); - delay(LED_TEST_DELAY); + set_leds(50,0,0); // make all LEDs dim blue - LEDControl.set_all_leds_to(0,50,0); - LEDControl.led_sync(); - delay(LED_TEST_DELAY); + set_leds(0,50,0); // make all LEDs dim green - LEDControl.set_all_leds_to(0,0,50); - LEDControl.led_sync(); - delay(LED_TEST_DELAY); + set_leds(0,0,50); // make all LEDs dim white - LEDControl.set_all_leds_to(50,50,50); - LEDControl.led_sync(); - delay(LED_TEST_DELAY); + set_leds(50,50,50); // make all the LEDs bright red - LEDControl.set_all_leds_to(200,0,0); - LEDControl.led_sync(); - delay(LED_TEST_DELAY); + set_leds(200,0,0); // make all the LEDs bright green - LEDControl.set_all_leds_to(0,200,0); - LEDControl.led_sync(); - delay(LED_TEST_DELAY); + set_leds(0,200,0); // make all the LEDs bright blue - LEDControl.set_all_leds_to(0,0,200); - LEDControl.led_sync(); - delay(LED_TEST_DELAY); + set_leds(0,0,200); // make all the LEDs bright white (1.6A) - LEDControl.set_all_leds_to(160,160,160); - LEDControl.led_sync(); - delay(LED_TEST_DELAY); + set_leds(160,160,160); // rainbow for 10 seconds for(auto i=0; i<1000; i++ ) { LEDRainbowEffect.update(); From c407c9608b126e587787e918364fbc2eda6e52f0 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 8 Feb 2017 18:54:16 -0800 Subject: [PATCH 055/792] move matrix test setup to one place --- src/Keyboardio-Model01-TestMode.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp index f763840a..6cdc096b 100644 --- a/src/Keyboardio-Model01-TestMode.cpp +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -70,17 +70,13 @@ void TestMode_::test_leds(void) { LEDControl.led_sync(); } // set all the keys to red - LEDControl.set_all_leds_to(50,0,0); - // make all LEDs dim blue - // as you hit each key, set it to blue - // as you hit each key a second time, set it to green - // as you hit each key a third time, set it to off } void TestMode_::test_matrix () { + LEDControl.set_all_leds_to(50,0,0); while(1) { KeyboardHardware.read_matrix(); for (byte row = 0; row < 4; row++) { From 518dda8e57f0c08ebbf0eeaf3009a7cc168bd91d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 8 Feb 2017 18:54:27 -0800 Subject: [PATCH 056/792] add a way to get out of test mode --- src/Keyboardio-Model01-TestMode.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp index 6cdc096b..1eff9dda 100644 --- a/src/Keyboardio-Model01-TestMode.cpp +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -79,6 +79,9 @@ void TestMode_::test_matrix () { LEDControl.set_all_leds_to(50,0,0); while(1) { KeyboardHardware.read_matrix(); + if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6 ) { + break; + } for (byte row = 0; row < 4; row++) { for (byte col = 0; col < 8; col++) { From c2a398f7ab605252db16af74b8baf7ea1b813f9a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 8 Feb 2017 20:44:27 -0800 Subject: [PATCH 057/792] Add initial support for reading the "power fault" line --- src/Keyboardio-Hardware-Model01.cpp | 17 +++++++++++++++-- src/Keyboardio-Hardware-Model01.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Keyboardio-Hardware-Model01.cpp b/src/Keyboardio-Hardware-Model01.cpp index d2493e8d..a7094c32 100644 --- a/src/Keyboardio-Hardware-Model01.cpp +++ b/src/Keyboardio-Hardware-Model01.cpp @@ -34,11 +34,16 @@ void Model01::enable_scanner_power(void) { void Model01::enable_high_power_leds(void) { // PE6 // pinMode(7, OUTPUT); -// digitalWrite(7, LOW); - + // digitalWrite(7, LOW); DDRE |= _BV(6); PORTE &= ~_BV(6); + // Set B4, the overcurrent check to an input with an internal pull-up + DDRB &= ~_BV(4); // set bit, input + PORTB &= ~_BV(4); // set bit, enable pull-up resistor + + + } void Model01::setup(void) { @@ -95,6 +100,14 @@ void Model01::led_sync() { } +boolean Model01::led_power_fault() { + if (PINB & _BV(4)) { + return true; + } else { + return false; + } +} + void debug_key_event(keydata_t state, keydata_t previousState, uint8_t keynum, uint8_t row, uint8_t col) { if (bitRead(state.all, keynum) != bitRead(previousState.all, keynum )) { Serial.print("Looking at row "); diff --git a/src/Keyboardio-Hardware-Model01.h b/src/Keyboardio-Hardware-Model01.h index 9c647943..d131a024 100644 --- a/src/Keyboardio-Hardware-Model01.h +++ b/src/Keyboardio-Hardware-Model01.h @@ -25,6 +25,8 @@ class Model01 { void enable_scanner_power(void); void reboot_bootloader(); + boolean led_power_fault(void); + uint8_t load_primary_layer(uint8_t layer_count); void save_primary_layer(uint8_t layer); From 05c80e632a75877804118515e0ba8f29afa1c292 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 9 Feb 2017 20:41:07 +0100 Subject: [PATCH 058/792] Implement a way to slow down the acceleration Signed-off-by: Gergely Nagy --- src/Keyboardio-MouseKeys.cpp | 10 ++++++++-- src/Keyboardio-MouseKeys.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Keyboardio-MouseKeys.cpp b/src/Keyboardio-MouseKeys.cpp index 23a85a64..702af5b6 100644 --- a/src/Keyboardio-MouseKeys.cpp +++ b/src/Keyboardio-MouseKeys.cpp @@ -5,6 +5,8 @@ #include "KeyboardioFirmware.h" uint8_t MouseKeys_::mouseMoveIntent; +uint8_t MouseKeys_::accelDelay; +uint8_t MouseKeys_::accelDelayCounter; void MouseKeys_::loopHook(bool postClear) { if (postClear) { @@ -19,8 +21,12 @@ void MouseKeys_::loopHook(bool postClear) { int8_t moveX = 0, moveY = 0; - if (MouseWrapper.mouseActiveForCycles < 255) - MouseWrapper.mouseActiveForCycles++; + if (accelDelayCounter == accelDelay) { + if (MouseWrapper.mouseActiveForCycles < 255) + MouseWrapper.mouseActiveForCycles++; + accelDelayCounter = 0; + } else + accelDelayCounter++; if (mouseMoveIntent & KEY_MOUSE_UP) moveY = -1; diff --git a/src/Keyboardio-MouseKeys.h b/src/Keyboardio-MouseKeys.h index 17d47aa5..ff42ea07 100644 --- a/src/Keyboardio-MouseKeys.h +++ b/src/Keyboardio-MouseKeys.h @@ -8,9 +8,11 @@ class MouseKeys_ : public KeyboardioPlugin { MouseKeys_ (void); virtual void begin(void) final; + static uint8_t accelDelay; private: static uint8_t mouseMoveIntent; + static uint8_t accelDelayCounter; static void loopHook(bool postClear); static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); From 8aa753fe233f3c156e01dadcef6f1269efcae146 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 9 Feb 2017 23:02:20 +0100 Subject: [PATCH 059/792] Add a timer, and expose stepLength With the recent speedup of the scan cycle, we need some delays for the animation to look nice. Fixes #2. Signed-off-by: Gergely Nagy --- README.md | 9 +++++++++ src/Akela/LED-Stalker.cpp | 29 ++++++++++++++++++++--------- src/Akela/LED-Stalker.h | 2 ++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7afe95a1..8d77c8ea 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,15 @@ method: > > It is recommended to use the `STALKER` macro to declare the effect itself. +### `.stepLength` + +> The length - in milliseconds - of each step of the animation. An animation +> lasts 256 steps. +> +> Not a method itself, but a changeable value. +> +> Defaults to 50. + ## Plugin helpers ### `STALKER(effect, params...)` diff --git a/src/Akela/LED-Stalker.cpp b/src/Akela/LED-Stalker.cpp index adaca428..4cc2cf92 100644 --- a/src/Akela/LED-Stalker.cpp +++ b/src/Akela/LED-Stalker.cpp @@ -22,6 +22,8 @@ namespace Akela { namespace LEDEffects { uint8_t StalkerEffect::map[ROWS][COLS]; StalkerEffect::ColorComputer *StalkerEffect::colorComputer; + uint16_t StalkerEffect::stepLength = 50; + uint32_t StalkerEffect::stepStartTime; StalkerEffect::StalkerEffect (void) { } @@ -35,6 +37,7 @@ namespace Akela { StalkerEffect::begin (void) { event_handler_hook_use (eventHandlerHook); loop_hook_use (loopHook); + stepStartTime = millis (); } Key @@ -42,8 +45,9 @@ namespace Akela { if (row >= ROWS || col >= COLS) return mappedKey; - if (key_is_pressed (keyState)) + if (key_is_pressed (keyState)) { map[row][col] = 0xff; + } return mappedKey; } @@ -56,6 +60,8 @@ namespace Akela { if (!colorComputer) return; + bool timeOut = (millis () - stepStartTime) >= stepLength; + for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { if (map[r][c]) @@ -63,19 +69,24 @@ namespace Akela { bool wasZero = (map[r][c] == 0); - if (map[r][c] >= 0xf0) - map[r][c]--; - else if (map[r][c] >= 0x40) - map[r][c] -= 16; - else if (map[r][c] >= 32) - map[r][c] -= 32; - else - map[r][c] = 0; + if (timeOut) { + if (map[r][c] >= 0xf0) + map[r][c]--; + else if (map[r][c] >= 0x40) + map[r][c] -= 16; + else if (map[r][c] >= 32) + map[r][c] -= 32; + else + map[r][c] = 0; + } if (!wasZero && !map[r][c]) LEDControl.led_set_crgb_at (r, c, (cRGB){0, 0, 0}); } } + + if (timeOut) + stepStartTime = millis (); } namespace Stalker { diff --git a/src/Akela/LED-Stalker.h b/src/Akela/LED-Stalker.h index 74b5d75b..16dcc06b 100644 --- a/src/Akela/LED-Stalker.h +++ b/src/Akela/LED-Stalker.h @@ -34,8 +34,10 @@ namespace Akela { virtual void begin (void) final; static void configure (ColorComputer *colorComputer); + static uint16_t stepLength; private: + static uint32_t stepStartTime; static ColorComputer *colorComputer; static uint8_t map[ROWS][COLS]; From 35918a91a0ad9ac81ce507b0bba7677f51310677 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 9 Feb 2017 23:39:03 +0100 Subject: [PATCH 060/792] Use a timer instead of a loop counter Loop counters are unreliable, use proper timers instead. Fixes #2. Signed-off-by: Gergely Nagy --- README.md | 6 ++++-- src/Akela/MagicCombo.cpp | 11 ++++------- src/Akela/MagicCombo.h | 4 ++-- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e69cac96..131622f6 100644 --- a/README.md +++ b/README.md @@ -56,8 +56,10 @@ The extension provides a `MagicCombo` singleton object, with the following metho ### `.minInterval` -> Restrict the magic action to fire at most once every `minInterval` cycles. -> Defaults to 10. +> Restrict the magic action to fire at most once every `minInterval` +> milliseconds. +> +> Defaults to 500. > > Not strictly a method, it is a variable one can assign a new value to. diff --git a/src/Akela/MagicCombo.cpp b/src/Akela/MagicCombo.cpp index 8adddb38..01da07d2 100644 --- a/src/Akela/MagicCombo.cpp +++ b/src/Akela/MagicCombo.cpp @@ -21,8 +21,8 @@ namespace Akela { const MagicCombo::dictionary_t *MagicCombo::dictionary; - uint8_t MagicCombo::minInterval = 10; - uint8_t MagicCombo::timer; + uint16_t MagicCombo::minInterval = 500; + uint32_t MagicCombo::startTime; MagicCombo::MagicCombo (void) { } @@ -42,9 +42,6 @@ namespace Akela { if (!dictionary || postClear) return; - if (timer && timer < minInterval) - timer++; - for (byte i = 0;; i++) { dictionary_t combo; @@ -56,9 +53,9 @@ namespace Akela { if (KeyboardHardware.leftHandState.all == combo.leftHand && KeyboardHardware.rightHandState.all == combo.rightHand) { - if (timer == 0 || timer >= minInterval || minInterval == 0) { + if (startTime == 0 || minInterval == 0 || ((millis () - startTime) >= minInterval)) { magicComboActions (i, combo.leftHand, combo.rightHand); - timer = 1; + startTime = millis (); } break; } diff --git a/src/Akela/MagicCombo.h b/src/Akela/MagicCombo.h index fa84a188..5618f532 100644 --- a/src/Akela/MagicCombo.h +++ b/src/Akela/MagicCombo.h @@ -32,11 +32,11 @@ namespace Akela { virtual void begin (void) final; static void configure (const dictionary_t dictionary[]); - static uint8_t minInterval; + static uint16_t minInterval; private: static const dictionary_t *dictionary; - static uint8_t timer; + static uint32_t startTime; static void loopHook (bool postClear); }; From a33621e867585245436341086ec246b5a3fbf88e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 10 Feb 2017 11:38:53 +0100 Subject: [PATCH 061/792] Introducing the tuning knobs Instead of counting loops for the purpose of calculating acceleration, use timers and steps instead. This means that we can now tune how often the mouse moves (`speedDelay`), how much it moves when it does (`speed`), how fast acceleration is (`accelSpeed`), and how often we accelerate (`accelDelay`). By default, the movement speed is one, and there is no delay, while acceleration has an 50ms delay, and a speed of one. But all of these can be tuned at run-time: we can turn off acceleration completely, or slow down the mouse considerably - the possibilities are almost endless! Signed-off-by: Gergely Nagy --- src/Keyboardio-MouseKeys.cpp | 44 +++++++++++++++++++++++++----------- src/Keyboardio-MouseKeys.h | 9 ++++++-- src/MouseWrapper.cpp | 6 ++--- src/MouseWrapper.h | 2 +- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/Keyboardio-MouseKeys.cpp b/src/Keyboardio-MouseKeys.cpp index 702af5b6..7c05490d 100644 --- a/src/Keyboardio-MouseKeys.cpp +++ b/src/Keyboardio-MouseKeys.cpp @@ -5,8 +5,15 @@ #include "KeyboardioFirmware.h" uint8_t MouseKeys_::mouseMoveIntent; -uint8_t MouseKeys_::accelDelay; -uint8_t MouseKeys_::accelDelayCounter; + +uint8_t MouseKeys_::speed = 1; +uint16_t MouseKeys_::speedDelay = 0; + +uint8_t MouseKeys_::accelSpeed = 1; +uint16_t MouseKeys_::accelDelay = 50; + +uint32_t MouseKeys_::accelStartTime; +uint32_t MouseKeys_::startTime; void MouseKeys_::loopHook(bool postClear) { if (postClear) { @@ -15,28 +22,33 @@ void MouseKeys_::loopHook(bool postClear) { } if (mouseMoveIntent == 0) { - MouseWrapper.mouseActiveForCycles = 0; + MouseWrapper.accelStep = 0; + startTime = 0; + accelStartTime = 0; return; } + if ((millis() - startTime) < speedDelay) + return; + + startTime = millis(); + int8_t moveX = 0, moveY = 0; - if (accelDelayCounter == accelDelay) { - if (MouseWrapper.mouseActiveForCycles < 255) - MouseWrapper.mouseActiveForCycles++; - accelDelayCounter = 0; - } else - accelDelayCounter++; + if ((millis() - accelStartTime) >= (accelDelay * MouseWrapper.accelStep)) { + if (MouseWrapper.accelStep < 255 - accelSpeed) + MouseWrapper.accelStep += accelSpeed; + } if (mouseMoveIntent & KEY_MOUSE_UP) - moveY = -1; + moveY = -speed; else if (mouseMoveIntent & KEY_MOUSE_DOWN) - moveY = 1; + moveY = speed; if (mouseMoveIntent & KEY_MOUSE_LEFT) - moveX = -1; + moveX = -speed; else if (mouseMoveIntent & KEY_MOUSE_RIGHT) - moveX = 1; + moveX = speed; MouseWrapper.move(moveX, moveY); } @@ -54,6 +66,12 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS MouseWrapper.release_button(button); } } else if (!(mappedKey.keyCode & KEY_MOUSE_WARP)) { + if (key_toggled_on(keyState)) { + if (!startTime) + startTime = millis(); + if (!accelStartTime) + accelStartTime = millis(); + } if (key_is_pressed(keyState)) mouseMoveIntent |= mappedKey.keyCode; } else if (key_toggled_on(keyState)) { diff --git a/src/Keyboardio-MouseKeys.h b/src/Keyboardio-MouseKeys.h index ff42ea07..7bc805ed 100644 --- a/src/Keyboardio-MouseKeys.h +++ b/src/Keyboardio-MouseKeys.h @@ -8,11 +8,16 @@ class MouseKeys_ : public KeyboardioPlugin { MouseKeys_ (void); virtual void begin(void) final; - static uint8_t accelDelay; + + static uint8_t speed; + static uint16_t speedDelay; + static uint8_t accelSpeed; + static uint16_t accelDelay; private: static uint8_t mouseMoveIntent; - static uint8_t accelDelayCounter; + static uint32_t startTime; + static uint32_t accelStartTime; static void loopHook(bool postClear); static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index fb58547e..553a5356 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -10,7 +10,7 @@ uint16_t MouseWrapper_::section_top; uint16_t MouseWrapper_::section_left; boolean MouseWrapper_::is_warping; -uint8_t MouseWrapper_::mouseActiveForCycles; +uint8_t MouseWrapper_::accelStep; MouseWrapper_::MouseWrapper_(void) { Mouse.begin(); @@ -101,10 +101,10 @@ void MouseWrapper_::move(int8_t x, int8_t y) { int16_t moveX =0; int16_t moveY = 0; if (x != 0 ) { - moveX = (x * acceleration(mouseActiveForCycles)); + moveX = (x * acceleration(accelStep)); } if (y != 0) { - moveY = (y * acceleration(mouseActiveForCycles)); + moveY = (y * acceleration(accelStep)); } end_warping(); diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 6c9fff10..fc2f8126 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -35,7 +35,7 @@ class MouseWrapper_ { static void warp(uint8_t warp_cmd); static void press_button(uint8_t button); static void release_button(uint8_t button); - static uint8_t mouseActiveForCycles; + static uint8_t accelStep; private: static uint16_t next_width; From 7a2804250cea4490631c926f91331af2bdac07cd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 10 Feb 2017 13:05:58 +0100 Subject: [PATCH 062/792] Add support for the Shortcut, too Signed-off-by: Gergely Nagy --- src/Akela/MagicCombo.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Akela/MagicCombo.cpp b/src/Akela/MagicCombo.cpp index 01da07d2..c5cf8541 100644 --- a/src/Akela/MagicCombo.cpp +++ b/src/Akela/MagicCombo.cpp @@ -18,6 +18,16 @@ #include +#if defined(ARDUINO_AVR_MODEL01) +#define LEFTHANDSTATE KeyboardHardware.leftHandState +#define RIGHTHANDSTATE KeyboardHardware.rightHandState +#endif + +#if defined(ARDUINO_AVR_SHORTCUT) +#define LEFTHANDSTATE KeyboardHardware.scanner.leftHandState +#define RIGHTHANDSTATE KeyboardHardware.scanner.rightHandState +#endif + namespace Akela { const MagicCombo::dictionary_t *MagicCombo::dictionary; @@ -51,8 +61,8 @@ namespace Akela { if (combo.leftHand == 0 && combo.rightHand == 0) break; - if (KeyboardHardware.leftHandState.all == combo.leftHand && - KeyboardHardware.rightHandState.all == combo.rightHand) { + if (LEFTHANDSTATE.all == combo.leftHand && + RIGHTHANDSTATE.all == combo.rightHand) { if (startTime == 0 || minInterval == 0 || ((millis () - startTime) >= minInterval)) { magicComboActions (i, combo.leftHand, combo.rightHand); startTime = millis (); From dddc014619f4bc235b9a3d3ed3a62cc6ce2cefca Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 00:13:09 +0100 Subject: [PATCH 063/792] BootAnimation: Make this part Model01-specific Not all keyboard hardware has per-key LEDs, and not all of them define the LED_* helpers. To make the LEDControl at least compile for these, guard the BootAnimation with a Model01-specific ifdef. Signed-off-by: Gergely Nagy --- src/BootAnimation.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/BootAnimation.cpp b/src/BootAnimation.cpp index 76c4a336..fe1318eb 100644 --- a/src/BootAnimation.cpp +++ b/src/BootAnimation.cpp @@ -4,6 +4,7 @@ #define EEPROM_BOOT_ANIMATION_LOCATION 1 +#ifdef ARDUINO_AVR_MODEL01 static void type_letter(uint8_t letter) { LEDControl.led_set_crgb_at(letter, {255, 0, 0}); @@ -13,14 +14,15 @@ type_letter(uint8_t letter) { LEDControl.led_sync(); delay(10); } +#endif void bootAnimation (void) { +#ifdef ARDUINO_AVR_MODEL01 if (EEPROM.read (EEPROM_BOOT_ANIMATION_LOCATION)) return; LEDControl.set_all_leds_to(0, 0, 0); - type_letter(LED_K); type_letter(LED_E); type_letter(LED_Y); @@ -37,4 +39,5 @@ bootAnimation (void) { type_letter(LED_9); EEPROM.update (EEPROM_BOOT_ANIMATION_LOCATION, 1); +#endif } From 5bdd12e533961434c6545db04fccf5affcfb51c7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 22:49:15 +0100 Subject: [PATCH 064/792] The Big Rename Rename the library to Kaleidoscope-Hardware-Model01, and follow up with other renames. Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- ...rdware-Model01.cpp => Kaleidoscope-Hardware-Model01.cpp} | 2 +- ...o-Hardware-Model01.h => Kaleidoscope-Hardware-Model01.h} | 0 4 files changed, 7 insertions(+), 7 deletions(-) rename src/{Keyboardio-Hardware-Model01.cpp => Kaleidoscope-Hardware-Model01.cpp} (99%) rename src/{Keyboardio-Hardware-Model01.h => Kaleidoscope-Hardware-Model01.h} (100%) diff --git a/README.md b/README.md index 76de0d05..b0b985b8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# Keyboardio-Hardware-Model01 +# Kaleidoscope-Hardware-Model01 -This is a plugin for [KeyboardioFirmware][fw], that adds hardware support for +This is a plugin for [Kaleidoscope][fw], that adds hardware support for the [Keyboardio Model01][kbdio:model01]. - [fw]: https://github.com/keyboardio/KeyboardioFirmware + [fw]: https://github.com/keyboardio/Kaleidoscope [kbdio:model01]: https://shop.keyboard.io/ diff --git a/library.properties b/library.properties index cdfe1578..9bdf34cf 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ -name=Keyboardio-Hardware-Model01 +name=Kaleidoscope-Hardware-Model01 version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=Keyboardio Model01 Hardware support for KeyboardioFirmware. +sentence=Keyboardio Model01 Hardware support for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-Hardware-Model01 +url=https://github.com/keyboardio/Kaleidoscope-Hardware-Model01 architectures=avr diff --git a/src/Keyboardio-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp similarity index 99% rename from src/Keyboardio-Hardware-Model01.cpp rename to src/Kaleidoscope-Hardware-Model01.cpp index a7094c32..bab20aff 100644 --- a/src/Keyboardio-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/src/Keyboardio-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h similarity index 100% rename from src/Keyboardio-Hardware-Model01.h rename to src/Kaleidoscope-Hardware-Model01.h From 1a8ce8cab140fd8d0f56c1c5da155bbc49c27fa9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:15:00 +0100 Subject: [PATCH 065/792] The Big Rename Renamed the library to Kaleidoscope-LEDControl, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- src/BootAnimation.cpp | 2 +- ...eyboardio-LEDControl.cpp => Kaleidoscope-LEDControl.cpp} | 4 ++-- src/{Keyboardio-LEDControl.h => Kaleidoscope-LEDControl.h} | 6 +++--- src/LED-Off.h | 2 +- src/LEDUtils.h | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) rename src/{Keyboardio-LEDControl.cpp => Kaleidoscope-LEDControl.cpp} (97%) rename src/{Keyboardio-LEDControl.h => Kaleidoscope-LEDControl.h} (91%) diff --git a/README.md b/README.md index a74162ee..675d2c9a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Keyboardio-LEDControl +# Kaleidoscope-LEDControl -This is a plugin for [KeyboardioFirmware][fw], for controlling the LEDs, and LED +This is a plugin for [Kaleidoscope][fw], for controlling the LEDs, and LED effects. - [fw]: https://github.com/keyboardio/KeyboardioFirmware + [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/library.properties b/library.properties index 55e9a724..ebaa64a3 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ -name=Keyboardio-LEDControl +name=Kaleidoscope-LEDControl version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=LED control for Keyboardio boards. +sentence=LED control for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-LEDControl +url=https://github.com/keyboardio/Kaleidoscope-LEDControl architectures=avr diff --git a/src/BootAnimation.cpp b/src/BootAnimation.cpp index fe1318eb..3ba6d40f 100644 --- a/src/BootAnimation.cpp +++ b/src/BootAnimation.cpp @@ -1,5 +1,5 @@ #include "BootAnimation.h" -#include "Keyboardio-LEDControl.h" +#include "Kaleidoscope-LEDControl.h" #include "EEPROM.h" #define EEPROM_BOOT_ANIMATION_LOCATION 1 diff --git a/src/Keyboardio-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp similarity index 97% rename from src/Keyboardio-LEDControl.cpp rename to src/Kaleidoscope-LEDControl.cpp index b9351cd4..30b24b36 100644 --- a/src/Keyboardio-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -1,4 +1,4 @@ -#include "Keyboardio-LEDControl.h" +#include "Kaleidoscope-LEDControl.h" LEDMode *LEDControl_::modes[LED_MAX_MODES]; uint8_t LEDControl_::previousMode, LEDControl_::mode; @@ -10,7 +10,7 @@ LEDMode::activate (void) { void LEDMode::begin(void) { - Keyboardio.use(&LEDControl, NULL); + Kaleidoscope.use(&LEDControl, NULL); LEDControl.mode_add(this); } diff --git a/src/Keyboardio-LEDControl.h b/src/Kaleidoscope-LEDControl.h similarity index 91% rename from src/Keyboardio-LEDControl.h rename to src/Kaleidoscope-LEDControl.h index ff388397..a6c678a1 100644 --- a/src/Keyboardio-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #define LED_MAX_MODES 24 @@ -8,7 +8,7 @@ #define Key_LEDEffectNext (Key) { 0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } -class LEDMode : public KeyboardioPlugin { +class LEDMode : public KaleidoscopePlugin { public: virtual void begin (void); virtual void setup (void) {}; @@ -17,7 +17,7 @@ class LEDMode : public KeyboardioPlugin { virtual void activate (void); }; -class LEDControl_ : public KeyboardioPlugin { +class LEDControl_ : public KaleidoscopePlugin { public: LEDControl_(void); diff --git a/src/LED-Off.h b/src/LED-Off.h index 4f75d9bb..6ea7ca6d 100644 --- a/src/LED-Off.h +++ b/src/LED-Off.h @@ -1,6 +1,6 @@ #pragma once -#include "Keyboardio-LEDControl.h" +#include "Kaleidoscope-LEDControl.h" class LEDOff_ : public LEDMode { public: diff --git a/src/LEDUtils.h b/src/LEDUtils.h index ee0d851e..7fbfd8c3 100644 --- a/src/LEDUtils.h +++ b/src/LEDUtils.h @@ -1,6 +1,6 @@ #pragma once -#include +#include cRGB breath_compute (void); cRGB hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v); From 805327533afafca6f1118862399c763d46848ce8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:20:06 +0100 Subject: [PATCH 066/792] The Big Rename Renamed the library to Kaleidoscope-LEDEffect-Breathe, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- ...ffect-Breathe.cpp => Kaleidoscope-LEDEffect-Breathe.cpp} | 2 +- ...LEDEffect-Breathe.h => Kaleidoscope-LEDEffect-Breathe.h} | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/{Keyboardio-LEDEffect-Breathe.cpp => Kaleidoscope-LEDEffect-Breathe.cpp} (81%) rename src/{Keyboardio-LEDEffect-Breathe.h => Kaleidoscope-LEDEffect-Breathe.h} (83%) diff --git a/README.md b/README.md index 5b2205a5..12bee0bf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Keyboardio-LEDEffect-Breathe +# Kaleidoscope-LEDEffect-Breathe -This is a plugin for [KeyboardioFirmware][fw], adding a breathe LED effect. +This is a plugin for [Kaleidoscope][fw], adding a breathe LED effect. - [fw]: https://github.com/keyboardio/KeyboardioFirmware + [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/library.properties b/library.properties index d2bfc2c2..2bbb13f0 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Keyboardio-LEDEffect-Breathe +name=Kaleidoscope-LEDEffect-Breathe version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=A breathing effect for the LEDs on Keyboardio boards. +sentence=A breathing effect on the LEDs, for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-LEDEffect-Breathe +url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-Breathe architectures=avr dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp similarity index 81% rename from src/Keyboardio-LEDEffect-Breathe.cpp rename to src/Kaleidoscope-LEDEffect-Breathe.cpp index 166fce0b..b5129474 100644 --- a/src/Keyboardio-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -1,4 +1,4 @@ -#include "Keyboardio-LEDEffect-Breathe.h" +#include "Kaleidoscope-LEDEffect-Breathe.h" LEDBreatheEffect_::LEDBreatheEffect_ (void) { } diff --git a/src/Keyboardio-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h similarity index 83% rename from src/Keyboardio-LEDEffect-Breathe.h rename to src/Kaleidoscope-LEDEffect-Breathe.h index d8abf441..3fa7b643 100644 --- a/src/Keyboardio-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -1,6 +1,6 @@ #pragma once -#include "Keyboardio-LEDControl.h" +#include "Kaleidoscope-LEDControl.h" #include "LEDUtils.h" class LEDBreatheEffect_ : LEDMode { From 4611026d352df8055bce8fb8d72f8630be9dbfda Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:22:24 +0100 Subject: [PATCH 067/792] The Big Rename Renamed the library to Kaleidoscope-LEDEffect-Chase, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- ...LEDEffect-Chase.cpp => Kaleidoscope-LEDEffect-Chase.cpp} | 2 +- ...dio-LEDEffect-Chase.h => Kaleidoscope-LEDEffect-Chase.h} | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/{Keyboardio-LEDEffect-Chase.cpp => Kaleidoscope-LEDEffect-Chase.cpp} (92%) rename src/{Keyboardio-LEDEffect-Chase.h => Kaleidoscope-LEDEffect-Chase.h} (91%) diff --git a/README.md b/README.md index a466a36d..3c8e8c2d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Keyboardio-LEDEffect-Chase +# Kaleidoscope-LEDEffect-Chase -This is a plugin for [KeyboardioFirmware][fw], adding a Chase LED effect. +This is a plugin for [Kaleidoscope][fw], adding a Chase LED effect. - [fw]: https://github.com/keyboardio/KeyboardioFirmware + [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/library.properties b/library.properties index 8df7d6bc..6cc68c0f 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Keyboardio-LEDEffect-Chase +name=Kaleidoscope-LEDEffect-Chase version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=A Chase LED effect for Keyboardio boards. +sentence=A Chase LED effect for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-LEDEffect-Chase +url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-Chase architectures=avr dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp similarity index 92% rename from src/Keyboardio-LEDEffect-Chase.cpp rename to src/Kaleidoscope-LEDEffect-Chase.cpp index 60acef7c..54c601cd 100644 --- a/src/Keyboardio-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -1,4 +1,4 @@ -#include "Keyboardio-LEDEffect-Chase.h" +#include "Kaleidoscope-LEDEffect-Chase.h" LEDChaseEffect_::LEDChaseEffect_ (void) { } diff --git a/src/Keyboardio-LEDEffect-Chase.h b/src/Kaleidoscope-LEDEffect-Chase.h similarity index 91% rename from src/Keyboardio-LEDEffect-Chase.h rename to src/Kaleidoscope-LEDEffect-Chase.h index 2576df9d..46669aac 100644 --- a/src/Keyboardio-LEDEffect-Chase.h +++ b/src/Kaleidoscope-LEDEffect-Chase.h @@ -1,6 +1,6 @@ #pragma once -#include "Keyboardio-LEDControl.h" +#include "Kaleidoscope-LEDControl.h" #include "LEDUtils.h" class LEDChaseEffect_ : LEDMode { From dd734adb1cd4b9331860a9736651baf64f7a4ad7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:23:50 +0100 Subject: [PATCH 068/792] The Big Rename Renamed the library to Kaleidoscope-LEDEffect-Rainbow, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- ...ffect-Rainbow.cpp => Kaleidoscope-LEDEffect-Rainbow.cpp} | 2 +- ...LEDEffect-Rainbow.h => Kaleidoscope-LEDEffect-Rainbow.h} | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/{Keyboardio-LEDEffect-Rainbow.cpp => Kaleidoscope-LEDEffect-Rainbow.cpp} (96%) rename src/{Keyboardio-LEDEffect-Rainbow.h => Kaleidoscope-LEDEffect-Rainbow.h} (96%) diff --git a/README.md b/README.md index 1413c3c4..d56ec4f7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Keyboardio-LEDEffect-Rainbow +# Kaleidoscope-LEDEffect-Rainbow -This is a plugin for [KeyboardioFirmware][fw], adding some Rainbow LED effects. +This is a plugin for [Kaleidoscope][fw], adding some Rainbow LED effects. - [fw]: https://github.com/keyboardio/KeyboardioFirmware + [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/library.properties b/library.properties index ad54b633..1900dfa4 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Keyboardio-LEDEffect-Rainbow +name=Kaleidoscope-LEDEffect-Rainbow version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=Rainbow LED effects for KeyboardioFirmware. +sentence=Rainbow LED effects for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-LEDEffect-Rainbow +url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-Rainbow architectures=avr dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp similarity index 96% rename from src/Keyboardio-LEDEffect-Rainbow.cpp rename to src/Kaleidoscope-LEDEffect-Rainbow.cpp index c1285a1f..bc194a1f 100644 --- a/src/Keyboardio-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -1,4 +1,4 @@ -#include "Keyboardio-LEDEffect-Rainbow.h" +#include "Kaleidoscope-LEDEffect-Rainbow.h" LEDRainbowEffect_::LEDRainbowEffect_ (void) { } diff --git a/src/Keyboardio-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h similarity index 96% rename from src/Keyboardio-LEDEffect-Rainbow.h rename to src/Kaleidoscope-LEDEffect-Rainbow.h index 5589e18c..4703306f 100644 --- a/src/Keyboardio-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -1,6 +1,6 @@ #pragma once -#include "Keyboardio-LEDControl.h" +#include "Kaleidoscope-LEDControl.h" #include "LEDUtils.h" class LEDRainbowEffect_ : LEDMode { From c53b67fbea6ad9e593aa6c8a360869ee3efbdd16 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:24:57 +0100 Subject: [PATCH 069/792] The Big Rename Renamed the library to Kaleidoscope-LEDEffect-SolidColor, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- ...SolidColor.cpp => Kaleidoscope-LEDEffect-SolidColor.cpp} | 2 +- ...ect-SolidColor.h => Kaleidoscope-LEDEffect-SolidColor.h} | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/{Keyboardio-LEDEffect-SolidColor.cpp => Kaleidoscope-LEDEffect-SolidColor.cpp} (82%) rename src/{Keyboardio-LEDEffect-SolidColor.h => Kaleidoscope-LEDEffect-SolidColor.h} (82%) diff --git a/README.md b/README.md index 2715a771..a09cb3df 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Keyboardio-LEDEffect-SolidColor +# Kaleidoscope-LEDEffect-SolidColor -This is a plugin for [KeyboardioFirmware][fw], adding a solid color LED effect. +This is a plugin for [Kaleidoscope][fw], adding a solid color LED effect. - [fw]: https://github.com/keyboardio/KeyboardioFirmware + [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/library.properties b/library.properties index 39ccf3f2..8b7571e8 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Keyboardio-LEDEffect-SolidColor +name=Kaleidoscope-LEDEffect-SolidColor version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=Solid color LED effects for KeyboardioFirmware. +sentence=Solid color LED effects for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-LEDEffect-SolidColor +url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-SolidColor architectures=avr dot_a_linkage=true diff --git a/src/Keyboardio-LEDEffect-SolidColor.cpp b/src/Kaleidoscope-LEDEffect-SolidColor.cpp similarity index 82% rename from src/Keyboardio-LEDEffect-SolidColor.cpp rename to src/Kaleidoscope-LEDEffect-SolidColor.cpp index a49b0dce..4a49b8ef 100644 --- a/src/Keyboardio-LEDEffect-SolidColor.cpp +++ b/src/Kaleidoscope-LEDEffect-SolidColor.cpp @@ -1,4 +1,4 @@ -#include "Keyboardio-LEDEffect-SolidColor.h" +#include "Kaleidoscope-LEDEffect-SolidColor.h" LEDSolidColor::LEDSolidColor (uint8_t r, uint8_t g, uint8_t b) { this->r = r; diff --git a/src/Keyboardio-LEDEffect-SolidColor.h b/src/Kaleidoscope-LEDEffect-SolidColor.h similarity index 82% rename from src/Keyboardio-LEDEffect-SolidColor.h rename to src/Kaleidoscope-LEDEffect-SolidColor.h index 01965678..823969a1 100644 --- a/src/Keyboardio-LEDEffect-SolidColor.h +++ b/src/Kaleidoscope-LEDEffect-SolidColor.h @@ -1,6 +1,6 @@ #pragma once -#include "Keyboardio-LEDControl.h" +#include "Kaleidoscope-LEDControl.h" class LEDSolidColor : LEDMode { public: From 68b3e2c5f215a35358c61cad7ebb7e3257cad76c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:33:27 +0100 Subject: [PATCH 070/792] The Big Rename Renamed the library to Kaleidoscope-LED-Stalker, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 13 +++++++------ examples/LED-Stalker/LED-Stalker.ino | 11 ++++++----- library.properties | 4 ++-- ...la-LED-Stalker.h => Kaleidoscope-LED-Stalker.h} | 4 ++-- src/{Akela => Kaleidoscope}/LED-Stalker.cpp | 8 ++++---- src/{Akela => Kaleidoscope}/LED-Stalker.h | 14 +++++++------- 6 files changed, 28 insertions(+), 26 deletions(-) rename src/{Akela-LED-Stalker.h => Kaleidoscope-LED-Stalker.h} (84%) rename src/{Akela => Kaleidoscope}/LED-Stalker.cpp (93%) rename src/{Akela => Kaleidoscope}/LED-Stalker.h (80%) diff --git a/README.md b/README.md index 8d77c8ea..314e5c83 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Akela-LED-Stalker +# Kaleidoscope-LED-Stalker ![status][st:experimental] @@ -15,17 +15,18 @@ trail of ghostly white lights, or a blazing trail of fire. To use the plugin, one needs to include the header, and select the effect. ```c++ -#include +#include +#include void setup () { - Keyboardio.setup (KEYMAP_SIZE); + Kaleidoscope.setup (KEYMAP_SIZE); StalkerEffect.configure (STALKER (Haunt, {0xff, 0, 0})); - Keyboardio.use (&StalkerEffect, NULL); + Kaleidoscope.use (&StalkerEffect, NULL); } ``` -It is recommended to place the activation of the plugin (the `Keyboardio.use` +It is recommended to place the activation of the plugin (the `Kaleidoscope.use` call) as early as possible, so the plugin can catch all relevant key presses. The configuration can happen at any time, but using the `STALKER` macro is highly recommended. @@ -76,4 +77,4 @@ The plugin provides the following effects: Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/keyboardio/Akela-LED-Stalker/blob/master/examples/LED-Stalker/LED-Stalker.ino + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-Stalker/blob/master/examples/LED-Stalker/LED-Stalker.ino diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index aa276ea0..1f835dcc 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Akela -- Animated Keyboardio Extension Library for Anything + * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -16,7 +16,8 @@ * along with this program. If not, see . */ -#include +#include +#include const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED @@ -40,12 +41,12 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { }; void setup () { - Keyboardio.setup (KEYMAP_SIZE); + Kaleidoscope.setup (KEYMAP_SIZE); StalkerEffect.configure (STALKER (BlazingTrail, NULL)); - Keyboardio.use (&LEDControl, &StalkerEffect, NULL); + Kaleidoscope.use (&LEDControl, &StalkerEffect, NULL); } void loop () { - Keyboardio.loop (); + Kaleidoscope.loop (); } diff --git a/library.properties b/library.properties index c1fc414d..8c121e5d 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Akela-LED-Stalker +name=Kaleidoscope-LED-Stalker version=0.0.0 author=Gergely Nagy maintainer=Gergely Nagy sentence=Stalk keys pressed by lighting up and fading back the LED under them. paragraph=Stalk keys pressed by lighting up and fading back the LED under them. category=Communication -url=https://github.com/keyboardio/Akela-LED-Stalker +url=https://github.com/keyboardio/Kaleidoscope-LED-Stalker architectures=avr dot_a_linkage=true diff --git a/src/Akela-LED-Stalker.h b/src/Kaleidoscope-LED-Stalker.h similarity index 84% rename from src/Akela-LED-Stalker.h rename to src/Kaleidoscope-LED-Stalker.h index 1a48dc2e..e9c84797 100644 --- a/src/Akela-LED-Stalker.h +++ b/src/Kaleidoscope-LED-Stalker.h @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Akela -- Animated Keyboardio Extension Library for Anything + * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -18,4 +18,4 @@ #pragma once -#include +#include diff --git a/src/Akela/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp similarity index 93% rename from src/Akela/LED-Stalker.cpp rename to src/Kaleidoscope/LED-Stalker.cpp index 4cc2cf92..02cf86a0 100644 --- a/src/Akela/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Akela -- Animated Keyboardio Extension Library for Anything + * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -#include +#include -namespace Akela { +namespace KaleidoscopePlugins { namespace LEDEffects { uint8_t StalkerEffect::map[ROWS][COLS]; StalkerEffect::ColorComputer *StalkerEffect::colorComputer; @@ -136,4 +136,4 @@ namespace Akela { }; }; -Akela::LEDEffects::StalkerEffect StalkerEffect; +KaleidoscopePlugins::LEDEffects::StalkerEffect StalkerEffect; diff --git a/src/Akela/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h similarity index 80% rename from src/Akela/LED-Stalker.h rename to src/Kaleidoscope/LED-Stalker.h index 16dcc06b..af108a8a 100644 --- a/src/Akela/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Akela -- Animated Keyboardio Extension Library for Anything + * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -16,14 +16,14 @@ * along with this program. If not, see . */ -#include -#include +#include +#include -#define STALKER(n, ...) (({static Akela::LEDEffects::Stalker::n _effect (__VA_ARGS__); &_effect;})) +#define STALKER(n, ...) (({static KaleidoscopePlugins::LEDEffects::Stalker::n _effect (__VA_ARGS__); &_effect;})) -namespace Akela { +namespace KaleidoscopePlugins { namespace LEDEffects { - class StalkerEffect : public KeyboardioPlugin { + class StalkerEffect : public KaleidoscopePlugin { public: class ColorComputer { public: @@ -71,4 +71,4 @@ namespace Akela { }; }; -extern Akela::LEDEffects::StalkerEffect StalkerEffect; +extern KaleidoscopePlugins::LEDEffects::StalkerEffect StalkerEffect; From e38836a7bb77c57f17ca876e65a0d92d2b2aed80 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:35:52 +0100 Subject: [PATCH 071/792] The Big Rename Renamed the library to Kaleidoscope-Macros, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- src/{Keyboardio-Macros.cpp => Kaleidoscope-Macros.cpp} | 2 +- src/{Keyboardio-Macros.h => Kaleidoscope-Macros.h} | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) rename src/{Keyboardio-Macros.cpp => Kaleidoscope-Macros.cpp} (98%) rename src/{Keyboardio-Macros.h => Kaleidoscope-Macros.h} (79%) diff --git a/README.md b/README.md index 95e1b955..a357e99c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Keyboardio-Macros +# Kaleidoscope-Macros -This is a plugin for [KeyboardioFirmware][fw], that adds support for macros. +This is a plugin for [Kaleidoscope][fw], that adds support for macros. - [fw]: https://github.com/keyboardio/KeyboardioFirmware + [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/library.properties b/library.properties index 5628c4b7..624df636 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Keyboardio-Macros +name=Kaleidoscope-Macros version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=Macro keys for Keyboardio boards. +sentence=Macro keys for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-Macros +url=https://github.com/keyboardio/Kaleidoscope-Macros architectures=avr dot_a_linkage=true diff --git a/src/Keyboardio-Macros.cpp b/src/Kaleidoscope-Macros.cpp similarity index 98% rename from src/Keyboardio-Macros.cpp rename to src/Kaleidoscope-Macros.cpp index eb408576..26ed7871 100644 --- a/src/Keyboardio-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -1,4 +1,4 @@ -#include "Keyboardio-Macros.h" +#include "Kaleidoscope-Macros.h" __attribute__((weak)) const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { diff --git a/src/Keyboardio-Macros.h b/src/Kaleidoscope-Macros.h similarity index 79% rename from src/Keyboardio-Macros.h rename to src/Kaleidoscope-Macros.h index e5e8b723..0354d077 100644 --- a/src/Keyboardio-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -1,13 +1,13 @@ #pragma once -#include +#include #include "MacroKeyDefs.h" #include "MacroSteps.h" const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); -class Macros_ : public KeyboardioPlugin { +class Macros_ : public KaleidoscopePlugin { public: Macros_(void); From 92205513de3416125c9e83a7537111bac7beb7df Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:38:50 +0100 Subject: [PATCH 072/792] The Big Rename Renamed the library to Kaleidoscope-MagicCombos, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 15 ++++++++------- examples/MagicCombo/MagicCombo.ino | 13 +++++++------ library.properties | 10 +++++----- ...ela-MagicCombo.h => Kaleidoscope-MagicCombo.h} | 4 ++-- src/{Akela => Kaleidoscope}/MagicCombo.cpp | 8 ++++---- src/{Akela => Kaleidoscope}/MagicCombo.h | 10 +++++----- 6 files changed, 31 insertions(+), 29 deletions(-) rename src/{Akela-MagicCombo.h => Kaleidoscope-MagicCombo.h} (88%) rename src/{Akela => Kaleidoscope}/MagicCombo.cpp (93%) rename src/{Akela => Kaleidoscope}/MagicCombo.h (85%) diff --git a/README.md b/README.md index 131622f6..bc97d208 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Akela-MagicCombo +# Kaleidoscope-MagicCombo ![status][st:stable] @@ -19,9 +19,10 @@ To use the extension, we must include the header, create a dictionary, and configure the plugin to use it: ```c++ -#include +#include +#include -static const Akela::MagicCombo::dictionary_t dictionary[] PROGMEM = { +static const KaleidoscopePlugins::MagicCombo::dictionary_t dictionary[] PROGMEM = { {R1C3 | R2C1 | R2C4 | R2C7, // left hand, R0C11 | R1C12 | R2C14 //right hand }, @@ -31,8 +32,8 @@ static const Akela::MagicCombo::dictionary_t dictionary[] PROGMEM = { void setup (void) { MagicCombo.configure (dictionary); - Keyboardio.setup (KEYMAP_SIZE); - Keyboardio.use (&MagicCombo, NULL); + Kaleidoscope.setup (KEYMAP_SIZE); + Kaleidoscope.use (&MagicCombo, NULL); } ``` @@ -41,7 +42,7 @@ element in the array has two fields: the left hand state, and the right hand state upon which to trigger the custom action. Both of these are bit fields, each bit set tells the extension that the key with that index must be held for the action to trigger. It is recommended to use the `RxCy` macros of the core -`KeyboardioFirmware`, and *or* them together to form a bitfield. +`KaleidoscopeFirmware`, and *or* them together to form a bitfield. The dictionary **must** end with an element containing zero values for both the left and the right halves. @@ -86,4 +87,4 @@ the overrideable `magicComboActions` function: Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/keyboardio/Akela-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index f652b89a..4f70ecb1 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Akela -- Animated Keyboardio Extension Library for Anything + * Kaleidoscope-MagicCombo -- Magic combo framework * Copyright (C) 2016, 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -16,7 +16,8 @@ * along with this program. If not, see . */ -#include +#include +#include void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { switch (comboIndex) { @@ -26,7 +27,7 @@ void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHan } } -static const Akela::MagicCombo::dictionary_t dictionary[] PROGMEM = { +static const KaleidoscopePlugins::MagicCombo::dictionary_t dictionary[] PROGMEM = { {R1C3 | R2C1 | R2C4 | R2C7, // left hand, R0C11 | R1C12 | R2C14 //right hand }, @@ -59,10 +60,10 @@ void setup () { MagicCombo.configure (dictionary); - Keyboardio.setup (KEYMAP_SIZE); - Keyboardio.use (&MagicCombo, NULL); + Kaleidoscope.setup (KEYMAP_SIZE); + Kaleidoscope.use (&MagicCombo, NULL); } void loop () { - Keyboardio.loop (); + Kaleidoscope.loop (); } diff --git a/library.properties b/library.properties index d37921f8..76089275 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Akela-MagicCombo +name=Kaleidoscope-MagicCombo version=0.0.0 author=Gergely Nagy -maintainer=Gergely Nagy -sentence=Magic combo framework for Keyboardio boards. -paragraph=Provides hooks for Keyboardio boards, to make it possible to run code on certain magic combinations. +maintainer=Gergely Nagy +sentence=Magic combo framework for Kaleidoscope. +paragraph=Provides hooks for Kaleidoscope, to make it possible to run code on certain magic combinations. category=Communication -url=https://github.com/keyboardio/Akela-MagicCombo +url=https://github.com/keyboardio/Kaleidoscope-MagicCombo architectures=avr dot_a_linkage=true diff --git a/src/Akela-MagicCombo.h b/src/Kaleidoscope-MagicCombo.h similarity index 88% rename from src/Akela-MagicCombo.h rename to src/Kaleidoscope-MagicCombo.h index 1366f253..8d390468 100644 --- a/src/Akela-MagicCombo.h +++ b/src/Kaleidoscope-MagicCombo.h @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Akela -- Animated Keyboardio Extension Library for Anything + * Kaleidoscope-MagicCombo -- Magic combo framework * Copyright (C) 2016, 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -18,4 +18,4 @@ #pragma once -#include +#include diff --git a/src/Akela/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp similarity index 93% rename from src/Akela/MagicCombo.cpp rename to src/Kaleidoscope/MagicCombo.cpp index c5cf8541..1a636cf8 100644 --- a/src/Akela/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Akela -- Animated Keyboardio Extension Library for Anything + * Kaleidoscope-MagicCombo -- Magic combo framework * Copyright (C) 2016, 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#include +#include #if defined(ARDUINO_AVR_MODEL01) #define LEFTHANDSTATE KeyboardHardware.leftHandState @@ -28,7 +28,7 @@ #define RIGHTHANDSTATE KeyboardHardware.scanner.rightHandState #endif -namespace Akela { +namespace KaleidoscopePlugins { const MagicCombo::dictionary_t *MagicCombo::dictionary; uint16_t MagicCombo::minInterval = 500; @@ -79,4 +79,4 @@ void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { } -Akela::MagicCombo MagicCombo; +KaleidoscopePlugins::MagicCombo MagicCombo; diff --git a/src/Akela/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h similarity index 85% rename from src/Akela/MagicCombo.h rename to src/Kaleidoscope/MagicCombo.h index 5618f532..a68b9659 100644 --- a/src/Akela/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Akela -- Animated Keyboardio Extension Library for Anything + * Kaleidoscope-MagicCombo -- Magic combo framework * Copyright (C) 2016, 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -18,10 +18,10 @@ #pragma once -#include +#include -namespace Akela { - class MagicCombo : public KeyboardioPlugin { +namespace KaleidoscopePlugins { + class MagicCombo : public KaleidoscopePlugin { public: typedef struct { uint32_t leftHand, rightHand; @@ -44,4 +44,4 @@ namespace Akela { void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand); -extern Akela::MagicCombo MagicCombo; +extern KaleidoscopePlugins::MagicCombo MagicCombo; From 4ec2c5888a56567f4d69192d7fb960d8b42d756a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:40:23 +0100 Subject: [PATCH 073/792] The Big Rename Renamed the library to Kaleidoscope-MouseKeys, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- ...{Keyboardio-MouseKeys.cpp => Kaleidoscope-MouseKeys.cpp} | 4 ++-- src/{Keyboardio-MouseKeys.h => Kaleidoscope-MouseKeys.h} | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) rename src/{Keyboardio-MouseKeys.cpp => Kaleidoscope-MouseKeys.cpp} (97%) rename src/{Keyboardio-MouseKeys.h => Kaleidoscope-MouseKeys.h} (86%) diff --git a/README.md b/README.md index e06bd6c6..ce8ad7e8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Keyboardio-MouseKeys +# Kaleidoscope-MouseKeys -This is a plugin for [KeyboardioFirmware][fw], that adds support for mouse keys. +This is a plugin for [Kaleidoscope][fw], that adds support for mouse keys. - [fw]: https://github.com/keyboardio/KeyboardioFirmware + [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/library.properties b/library.properties index 23cd518c..d4df7f02 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Keyboardio-MouseKeys +name=Kaleidoscope-MouseKeys version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=Mouse keys for Keyboardio boards. +sentence=Mouse keys for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-MouseKeys +url=https://github.com/keyboardio/Kaleidoscope-MouseKeys architectures=avr dot_a_linkage=true \ No newline at end of file diff --git a/src/Keyboardio-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp similarity index 97% rename from src/Keyboardio-MouseKeys.cpp rename to src/Kaleidoscope-MouseKeys.cpp index 7c05490d..17d80f02 100644 --- a/src/Keyboardio-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -1,8 +1,8 @@ #include -#include "Keyboardio-MouseKeys.h" +#include "Kaleidoscope-MouseKeys.h" #include "MouseWrapper.h" -#include "KeyboardioFirmware.h" +#include "Kaleidoscope.h" uint8_t MouseKeys_::mouseMoveIntent; diff --git a/src/Keyboardio-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h similarity index 86% rename from src/Keyboardio-MouseKeys.h rename to src/Kaleidoscope-MouseKeys.h index 7bc805ed..f303d077 100644 --- a/src/Keyboardio-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -1,9 +1,9 @@ #pragma once -#include "KeyboardioFirmware.h" +#include "Kaleidoscope.h" #include "MouseKeyDefs.h" -class MouseKeys_ : public KeyboardioPlugin { +class MouseKeys_ : public KaleidoscopePlugin { public: MouseKeys_ (void); From 5fe8ff28cb7fb928fbff893aa07c8f9fefdf7394 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 11 Feb 2017 23:41:39 +0100 Subject: [PATCH 074/792] The Big Rename Renamed the library to Kaleidoscope-Numlock, and followed up with other renames. Signed-off-by: Gergely Nagy --- README.md | 6 +++--- library.properties | 6 +++--- src/{Keyboardio-Numlock.cpp => Kaleidoscope-Numlock.cpp} | 4 ++-- src/{Keyboardio-Numlock.h => Kaleidoscope-Numlock.h} | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) rename src/{Keyboardio-Numlock.cpp => Kaleidoscope-Numlock.cpp} (95%) rename src/{Keyboardio-Numlock.h => Kaleidoscope-Numlock.h} (87%) diff --git a/README.md b/README.md index 9c121ae8..b8173982 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Keyboardio-Numlock +# Kaleidoscope-Numlock -This is a plugin for [KeyboardioFirmware][fw], that adds a NumLock-specific LED +This is a plugin for [Kaleidoscope][fw], that adds a NumLock-specific LED effect, along with a way to toggle to a numpad layer, and apply the effect. - [fw]: https://github.com/keyboardio/KeyboardioFirmware + [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/library.properties b/library.properties index d2d6d175..8db57a28 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Keyboardio-Numlock +name=Kaleidoscope-Numlock version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=A Numlock plugin for KeyboardioFirmware. +sentence=A Numlock plugin for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Keyboardio-Numlock +url=https://github.com/keyboardio/Kaleidoscope-Numlock architectures=avr dot_a_linkage=true diff --git a/src/Keyboardio-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp similarity index 95% rename from src/Keyboardio-Numlock.cpp rename to src/Kaleidoscope-Numlock.cpp index ed216fee..e25b7494 100644 --- a/src/Keyboardio-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -1,6 +1,6 @@ -#include "Keyboardio-Numlock.h" +#include "Kaleidoscope-Numlock.h" #include "LEDUtils.h" -#include "KeyboardioFirmware.h" +#include "Kaleidoscope.h" #include "layers.h" uint8_t NumLock_::previousLEDMode; diff --git a/src/Keyboardio-Numlock.h b/src/Kaleidoscope-Numlock.h similarity index 87% rename from src/Keyboardio-Numlock.h rename to src/Kaleidoscope-Numlock.h index 8a71f8fc..52fab4cd 100644 --- a/src/Keyboardio-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -1,7 +1,7 @@ #pragma once -#include "Keyboardio-LEDControl.h" -#include "Keyboardio-Macros.h" +#include "Kaleidoscope-LEDControl.h" +#include "Kaleidoscope-Macros.h" #include "LEDUtils.h" #define TOGGLENUMLOCK 0 From d31530d57999adfc5776bd76f1a2f1826c22a53a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 11 Feb 2017 19:28:39 -0800 Subject: [PATCH 075/792] start to refactor the code to be a Kaleidoscope plugin --- library.properties | 4 ++-- src/Keyboardio-Model01-TestMode.cpp | 6 +++--- src/Keyboardio-Model01-TestMode.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library.properties b/library.properties index c8c461a2..3255a9b6 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Keyboardio-Model01-TestMode +name=Kaleidoscope-Model01-TestMode version=0.0.0 author=Jesse Vincent maintainer=Jesse Vincent sentence=A factory test mode for the Model 01. paragraph=A special mode for the Model 01 to help factory workers test the Model 01 during assembly. category=Communication -url=https://github.com/keyboardio/Keyboardio-Model01-TestMode +url=https://github.com/keyboardio/Kaleidoscope-Model01-TestMode architectures=avr dot_a_linkage=true diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Keyboardio-Model01-TestMode.cpp index 1eff9dda..ffdbe6bc 100644 --- a/src/Keyboardio-Model01-TestMode.cpp +++ b/src/Keyboardio-Model01-TestMode.cpp @@ -1,6 +1,6 @@ -#include "KeyboardioFirmware.h" -#include "Keyboardio-Model01-TestMode.h" -#include "Keyboardio-LEDEffect-Rainbow.h" +#include "Kaleidoscope.h" +#include "Kaleidoscope-Model01-TestMode.h" +#include "Kaleidoscope-LEDEffect-Rainbow.h" cRGB red; cRGB blue; diff --git a/src/Keyboardio-Model01-TestMode.h b/src/Keyboardio-Model01-TestMode.h index bd780e93..b2ec7aed 100644 --- a/src/Keyboardio-Model01-TestMode.h +++ b/src/Keyboardio-Model01-TestMode.h @@ -1,9 +1,9 @@ #pragma once #include -#include "KeyboardioFirmware.h" +#include "Kaleidoscope.h" -class TestMode_ : public KeyboardioPlugin { +class TestMode_ : public KaleidoscopePlugin { public: TestMode_(void); void begin(); From 6b0623d3f24cb5a867119374eb8ac1d138f42230 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 11 Feb 2017 19:29:39 -0800 Subject: [PATCH 076/792] Step two of the rename --- ...dio-Model01-TestMode.cpp => Kaleidoscope-Model01-TestMode.cpp} | 0 ...boardio-Model01-TestMode.h => Kaleidoscope-Model01-TestMode.h} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{Keyboardio-Model01-TestMode.cpp => Kaleidoscope-Model01-TestMode.cpp} (100%) rename src/{Keyboardio-Model01-TestMode.h => Kaleidoscope-Model01-TestMode.h} (100%) diff --git a/src/Keyboardio-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp similarity index 100% rename from src/Keyboardio-Model01-TestMode.cpp rename to src/Kaleidoscope-Model01-TestMode.cpp diff --git a/src/Keyboardio-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h similarity index 100% rename from src/Keyboardio-Model01-TestMode.h rename to src/Kaleidoscope-Model01-TestMode.h From 23aba7840236d06b9356bd41d94f669523fc0b4e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 11 Feb 2017 19:45:21 -0800 Subject: [PATCH 077/792] Add some missing prototypes to the class definition --- src/Kaleidoscope-Model01-TestMode.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index b2ec7aed..883fa2aa 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -12,7 +12,9 @@ class TestMode_ : public KaleidoscopePlugin { static void run_tests(); static void test_leds(); static void test_matrix(); + static void wait_for_keypress(); static void loopHook(bool postClear); + static void set_leds(uint8_t r, uint8_t g, uint8_t b); }; extern TestMode_ TestMode; From c1d25174bc862f07a2527c770712833d0766490c Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 11 Feb 2017 19:50:59 -0800 Subject: [PATCH 078/792] Add a missing paren. Unsure how this ever compiled. --- src/Kaleidoscope-Model01-TestMode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index ffdbe6bc..7b0cff38 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -79,7 +79,7 @@ void TestMode_::test_matrix () { LEDControl.set_all_leds_to(50,0,0); while(1) { KeyboardHardware.read_matrix(); - if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6 ) { + if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6 ) ) { break; } for (byte row = 0; row < 4; row++) { From ddd6b766fdfc7d2e712ab915368124cb65372a13 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 13 Feb 2017 22:08:11 +0100 Subject: [PATCH 079/792] Initial import Signed-off-by: Gergely Nagy --- .gitignore | 2 + COPYING | 674 +++++++++++++++++++ README.md | 73 ++ examples/LED-AlphaSquare/LED-AlphaSquare.ino | 86 +++ library.properties | 10 + src/Kaleidoscope-LED-AlphaSquare.h | 21 + src/Kaleidoscope/LED-AlphaSquare.cpp | 207 ++++++ src/Kaleidoscope/LED-AlphaSquare.h | 54 ++ 8 files changed, 1127 insertions(+) create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 README.md create mode 100644 examples/LED-AlphaSquare/LED-AlphaSquare.ino create mode 100644 library.properties create mode 100644 src/Kaleidoscope-LED-AlphaSquare.h create mode 100644 src/Kaleidoscope/LED-AlphaSquare.cpp create mode 100644 src/Kaleidoscope/LED-AlphaSquare.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..aead9485 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.#* +*~ diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/README.md b/README.md new file mode 100644 index 00000000..d5ea2394 --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# Kaleidoscope-LED-AlphaSquare + +![status][st:experimental] + + [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + +An alphabet for your per-key LEDs, `AlphaSquare` provides a way to display 4x4 +"pixel" symbols on your keyboard. With this building block, one can build some +sweet animations, or just show off - the possibilities are almost endless! + +## Using the plugin + +To use the plugin, one needs to include the header, and one way or another, call +the `display` method. + +```c++ +#include +#include + +void setup () { + Kaleidoscope.setup (KEYMAP_SIZE); + + Kaleidoscope.use (&AlphaSquare, NULL); + + AlphaSquare.display (Key_A); +} +``` + +## Plugin methods + +The plugin provides the `AlphaSquare` object, which has the following methods: + +### `.display(key)` +### `.display(key, row, col)` +### `.display(key, col)` + +> Display the symbol for `key` at the given row or column. If `row` is omitted, +> the first row - `0` is assumed. If the column is omitted too, then the third - +> `2` - column is used by default. +> +> The plugin can display the English alphabet, and the numbers from 0 to 9. + +### `.display(symbol)` +### `.display(symbol, row, col)` +### `.display(symbol, col)` + +> Almost the same as the previous function, but instead of a key, it expects a +> 4x4 bitmap. + +### `.color` + +> The color to use to draw the pixels. +> +> Not a method itself, but a changeable value. +> +> Defaults to { 0x80, 0x80, 0x80 }. + +## Plugin helpers + +### `SYM4x4(...)` + +> A helper macro, which can be used to set up custom bitmaps. It expects 16 +> values, a 4x4 square of zeroes and ones. Zeroes are transparent pixels, ones +> will be colored. + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-AlphaSquare/blob/master/examples/LED-AlphaSquare/LED-AlphaSquare.ino diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino new file mode 100644 index 00000000..f60f43bc --- /dev/null +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -0,0 +1,86 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include +#include +#include +#include + +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + ( + Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, M(0), + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + + Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, + Key_skip + ), +}; + +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { + if (!key_toggled_on (keyState)) + return MACRO_NONE; + + if (macroIndex == 0) { + for (uint8_t i = Key_A.keyCode; i <= Key_0.keyCode; i++) { + LEDControl.set_all_leds_to (0, 0, 0); + LEDControl.led_sync (); + delay (100); + + uint8_t col = 2; + if (i % 2) + col = 10; + + for (uint8_t step = 0; step <= 0xf0; step += 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display ({i, 0}, col); + delay (10); + } + for (uint8_t step = 0xff; step >= 8; step -= 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display ({i, 0}, col); + delay (10); + } + delay (100); + } + } + LEDControl.set_all_leds_to (0, 0, 0); + + return MACRO_NONE; +} + +void setup () { + Kaleidoscope.setup (KEYMAP_SIZE); + + Kaleidoscope.use (&LEDControl, &AlphaSquare, &Macros, NULL); + AlphaSquare.color = { 0xcb, 0xc0, 0xff }; +} + +void loop () { + Kaleidoscope.loop (); +} diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..ecc6a2f2 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Kaleidoscope-LED-AlphaSquare +version=0.0.0 +author=Gergely Nagy +maintainer=Gergely Nagy +sentence=4x4 pixel LED alphabet, to be used with Kaleidoscope. +paragraph=Includes a small, 4x4 font of alphanumerics, so you can have text on your keyboard LEDs. +category=Communication +url=https://github.com/keyboardio/Kaleidoscope-LED-AlphaSquare +architectures=avr +dot_a_linkage=true diff --git a/src/Kaleidoscope-LED-AlphaSquare.h b/src/Kaleidoscope-LED-AlphaSquare.h new file mode 100644 index 00000000..5c456b52 --- /dev/null +++ b/src/Kaleidoscope-LED-AlphaSquare.h @@ -0,0 +1,21 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp new file mode 100644 index 00000000..088ab7e9 --- /dev/null +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -0,0 +1,207 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include + +namespace KaleidoscopePlugins { + + static const uint16_t alphabet[] PROGMEM = { + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 1), // A + SYM4x4(1, 1, 1, 1, + 1, 0, 1, 1, + 1, 1, 0, 1, + 1, 1, 1, 1), // B + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // C + SYM4x4(1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0), // D + SYM4x4(1, 1, 1, 1, + 1, 1, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // E + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 0), // F + SYM4x4(1, 1, 1, 0, + 1, 0, 0, 0, + 1, 0, 0, 1, + 1, 1, 1, 1), // G + SYM4x4(1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1), // H + SYM4x4(1, 1, 1, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 1, 1, 1), // I + SYM4x4(1, 1, 1, 1, + 0, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // J + SYM4x4(1, 0, 0, 1, + 1, 1, 0, 0, + 1, 1, 0, 0, + 1, 0, 1, 1), // K + SYM4x4(1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // L + SYM4x4(1, 0, 1, 1, + 1, 1, 1, 1, + 1, 1, 0, 1, + 1, 0, 0, 1), // M + SYM4x4(1, 0, 0, 1, + 1, 1, 0, 1, + 1, 0, 1, 1, + 1, 0, 0, 1), // N + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1), // O + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 0), // P + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 1, 1, + 1, 1, 1, 1), // Q + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 1, 1, 0, + 1, 0, 1, 1), // R + SYM4x4(1, 1, 1, 1, + 1, 1, 0, 0, + 0, 0, 1, 1, + 1, 1, 1, 1), // S + SYM4x4(1, 1, 1, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, + 0, 1, 1, 0), // T + SYM4x4(1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1), // U + SYM4x4(1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // V + SYM4x4(1, 0, 0, 1, + 1, 0, 1, 1, + 1, 1, 1, 1, + 1, 0, 1, 1), // W + SYM4x4(1, 0, 0, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 0, 0, 1), // X + SYM4x4(1, 0, 0, 1, + 1, 1, 1, 1, + 0, 1, 1, 0, + 0, 1, 1, 0), // Y + SYM4x4(1, 1, 1, 1, + 0, 0, 1, 1, + 1, 1, 0, 0, + 1, 1, 1, 1), // Z + // --------------------- + SYM4x4(0, 1, 1, 0, + 1, 0, 1, 0, + 0, 0, 1, 0, + 1, 1, 1, 1), // 1 + SYM4x4(0, 1, 1, 0, + 1, 0, 0, 1, + 0, 0, 1, 0, + 1, 1, 0, 1), // 2 + SYM4x4(1, 1, 1, 1, + 0, 0, 1, 1, + 0, 0, 0, 1, + 1, 1, 1, 1), // 3 + SYM4x4(1, 0, 0, 1, + 1, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 0, 1), // 4 + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 0, + 0, 1, 1, 1, + 1, 1, 1, 1), // 5 + SYM4x4(0, 1, 1, 0, + 1, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1), // 6 + SYM4x4(1, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 1, 0, + 0, 1, 0, 0), // 7 + SYM4x4(1, 1, 1, 0, + 1, 0, 1, 1, + 1, 1, 0, 1, + 0, 1, 1, 1), // 8 + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 1, 1, 1, + 0, 0, 0, 1), // 9 + SYM4x4(0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // 0 + }; + + cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; + + AlphaSquare::AlphaSquare (void) { + } + + void + AlphaSquare::begin (void) { + } + + void + AlphaSquare::display (Key key, uint8_t row, uint8_t col) { + if (key < Key_A || key > Key_0) + return; + + uint8_t index = key.keyCode - Key_A.keyCode; + uint16_t symbol = pgm_read_word (&alphabet[index]); + + display (symbol, row, col); + } + + void + AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col) { + for (uint8_t r = 0; r < 4; r++) { + for (uint8_t c = 0; c < 4; c++) { + uint8_t pixel = bitRead (symbol, r * 4 + c); + if (!pixel) + continue; + + LEDControl.led_set_crgb_at (row + r, col + c, color); + } + } + + LEDControl.led_sync (); + } +}; + +KaleidoscopePlugins::AlphaSquare AlphaSquare; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h new file mode 100644 index 00000000..763c6766 --- /dev/null +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -0,0 +1,54 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include +#include + +#define SYM4x4( \ + p00, p01, p02, p03, \ + p10, p11, p12, p13, \ + p20, p21, p22, p23, \ + p30, p31, p32, p33 \ + ) \ + (uint16_t) ( \ + p00 << 0 | p01 << 1 | p02 << 2 | p03 << 3 | \ + p10 << 4 | p11 << 5 | p12 << 6 | p13 << 7 | \ + p20 << 8 | p21 << 9 | p22 << 10 | p23 << 11 | \ + p30 << 12 | p31 << 13 | p32 << 14 | p33 << 15 \ + ) + +namespace KaleidoscopePlugins { + class AlphaSquare : public KaleidoscopePlugin { + public: + AlphaSquare (void); + + virtual void begin (void) final; + + static void display (Key key, uint8_t row, uint8_t col); + static void display (Key key) { display (key, 0, 2); }; + static void display (Key key, uint8_t col) { display (key, 0, col); }; + + static void display (uint16_t symbol, uint8_t row, uint8_t col); + static void display (uint16_t symbol) { display (symbol, 0, 2); }; + static void display (uint16_t symbol, uint8_t col) { display (symbol, 0, col); }; + + static cRGB color; + }; +}; + +extern KaleidoscopePlugins::AlphaSquare AlphaSquare; From 161401b22f1dee81b808aa48a3df5ed96edc4f44 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 17 Feb 2017 10:09:33 +0100 Subject: [PATCH 080/792] Add a CRGB macro The `CRGB` macro takes rgb values as arguments, in this order, and creates a `cRGB` instance with the components rearranged to fit the ordering of the hardware (in the case of the Model01, bgr). Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index d131a024..c92bbf8e 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -8,6 +8,8 @@ #define COLS 16 #define ROWS 4 +#define CRGB(r,g,b) (cRGB){b, g, r} + class Model01 { public: Model01(void); From 64ac98dcbf0b7476ba0d807ddff0c3745a741c83 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 19 Feb 2017 22:43:30 -0800 Subject: [PATCH 081/792] When the key is pressed, turn it green --- src/Kaleidoscope-Model01-TestMode.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 7b0cff38..4b1626d2 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -4,6 +4,7 @@ cRGB red; cRGB blue; +cRGB green; #define LED_TEST_DELAY 2000 @@ -14,6 +15,7 @@ TestMode_::TestMode_(void) { void TestMode_::begin(void) { red.r=101; blue.b=101; + green.g=101; loop_hook_use (this->loopHook); } @@ -95,7 +97,7 @@ void TestMode_::test_matrix () { Serial.print(keynum); Serial.print(" value "); Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 7-col, red); + KeyboardHardware.led_set_crgb_at(row, 7-col, green); } else if (keyState ==1) { KeyboardHardware.led_set_crgb_at(row,7-col, blue); } @@ -108,7 +110,7 @@ void TestMode_::test_matrix () { Serial.print(keynum); Serial.print(" value "); Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 15-col, red); + KeyboardHardware.led_set_crgb_at(row, 15-col, green); } else if (keyState ==1) { KeyboardHardware.led_set_crgb_at(row,15-col, blue); } From 559eab96ae214193336d6589ebfa98b410f14b5a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Feb 2017 23:42:42 +0100 Subject: [PATCH 082/792] Don't sync every cycle Because `led_sync` is a major cause of slowness, do not sync every cycle. In most cases, it is pointless to sync 100 times a second, about 60 - or even 30 - may be more than enough. For this reason, introduce a timer, and a settable delay: we'll only call `led_sync` once the delay's up. It can be set to 0 to call it every time, but defaults to 16 (for about 62 syncs/sec), as a safe bet. This speeds the loop up dramatically, except for the few exceptions where sync is called. Fixes #1. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 9 ++++++++- src/Kaleidoscope-LEDControl.h | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 30b24b36..35770a96 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -2,6 +2,8 @@ LEDMode *LEDControl_::modes[LED_MAX_MODES]; uint8_t LEDControl_::previousMode, LEDControl_::mode; +uint16_t LEDControl_::syncDelay = 16; +uint32_t LEDControl_::syncTimer; void LEDMode::activate (void) { @@ -126,6 +128,8 @@ LEDControl_::begin (void) { event_handler_hook_use(eventHandler); loop_hook_use(loopHook); + + syncTimer = millis(); } Key @@ -144,7 +148,10 @@ LEDControl_::loopHook (bool postClear) { if (postClear) return; - led_sync(); + if (millis() - syncTimer >= syncDelay) { + led_sync(); + syncTimer = millis(); + } update(); } diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index a6c678a1..81280b58 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -41,7 +41,10 @@ class LEDControl_ : public KaleidoscopePlugin { static void activate (LEDMode *mode); + static uint16_t syncDelay; + private: + static uint32_t syncTimer; static LEDMode *modes[LED_MAX_MODES]; static uint8_t previousMode, mode; From 09afa0ec72ffa6fed9a988884b4c31befcd19c4d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 21 Feb 2017 07:55:27 +0100 Subject: [PATCH 083/792] Improved timer checking code Instead of doing a substraction and a compare in the if check, whenever we reset the timer, add `syncDelay`, and compare against the timer only. Should result in marginally better performing code. Thanks @obra for the suggestion! Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 35770a96..7e440afc 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -129,7 +129,7 @@ LEDControl_::begin (void) { event_handler_hook_use(eventHandler); loop_hook_use(loopHook); - syncTimer = millis(); + syncTimer = millis() + syncDelay; } Key @@ -148,9 +148,9 @@ LEDControl_::loopHook (bool postClear) { if (postClear) return; - if (millis() - syncTimer >= syncDelay) { + if (millis() > syncTimer) { led_sync(); - syncTimer = millis(); + syncTimer = millis() + syncDelay; } update(); } From 3d25b7be287567475490d5bbbabf9b4e1367ca2e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 21 Feb 2017 12:44:05 +0100 Subject: [PATCH 084/792] Improved timeout handling Instead of calculating the time delta each time we check for a timeout, pre-calculate the projected ending time, and compare against that. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.cpp | 7 +++---- src/Kaleidoscope/LED-Stalker.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 02cf86a0..7c0fa655 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -23,7 +23,7 @@ namespace KaleidoscopePlugins { uint8_t StalkerEffect::map[ROWS][COLS]; StalkerEffect::ColorComputer *StalkerEffect::colorComputer; uint16_t StalkerEffect::stepLength = 50; - uint32_t StalkerEffect::stepStartTime; + uint32_t StalkerEffect::stepEndTime; StalkerEffect::StalkerEffect (void) { } @@ -37,7 +37,6 @@ namespace KaleidoscopePlugins { StalkerEffect::begin (void) { event_handler_hook_use (eventHandlerHook); loop_hook_use (loopHook); - stepStartTime = millis (); } Key @@ -60,7 +59,7 @@ namespace KaleidoscopePlugins { if (!colorComputer) return; - bool timeOut = (millis () - stepStartTime) >= stepLength; + bool timeOut = millis () >= stepEndTime; for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { @@ -86,7 +85,7 @@ namespace KaleidoscopePlugins { } if (timeOut) - stepStartTime = millis (); + stepEndTime = millis () + stepLength; } namespace Stalker { diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index af108a8a..7b670aaf 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -37,7 +37,7 @@ namespace KaleidoscopePlugins { static uint16_t stepLength; private: - static uint32_t stepStartTime; + static uint32_t stepEndTime; static ColorComputer *colorComputer; static uint8_t map[ROWS][COLS]; From 839d5c298b5a84c619e54ce7db09378d858be93f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 21 Feb 2017 12:47:52 +0100 Subject: [PATCH 085/792] Improved timer handling Instead of calculating the time delta each time we want to check for a timeout, calculate the projected ending time ahead of time. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MagicCombo.cpp | 6 +++--- src/Kaleidoscope/MagicCombo.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index 1a636cf8..50b34b91 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -32,7 +32,7 @@ namespace KaleidoscopePlugins { const MagicCombo::dictionary_t *MagicCombo::dictionary; uint16_t MagicCombo::minInterval = 500; - uint32_t MagicCombo::startTime; + uint32_t MagicCombo::endTime; MagicCombo::MagicCombo (void) { } @@ -63,9 +63,9 @@ namespace KaleidoscopePlugins { if (LEFTHANDSTATE.all == combo.leftHand && RIGHTHANDSTATE.all == combo.rightHand) { - if (startTime == 0 || minInterval == 0 || ((millis () - startTime) >= minInterval)) { + if (millis () >= endTime) { magicComboActions (i, combo.leftHand, combo.rightHand); - startTime = millis (); + endTime = millis () + minInterval; } break; } diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index a68b9659..4d505d0b 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -36,7 +36,7 @@ namespace KaleidoscopePlugins { private: static const dictionary_t *dictionary; - static uint32_t startTime; + static uint32_t endTime; static void loopHook (bool postClear); }; From 3d0903af411243033f54f9932c81c6301a8cdaf9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 21 Feb 2017 12:58:57 +0100 Subject: [PATCH 086/792] Improved timer handling Instead of calculating time deltas every time we want to check a timeout, calculate the projected end ahead of time. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-MouseKeys.cpp | 22 ++++++++++------------ src/Kaleidoscope-MouseKeys.h | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 17d80f02..9538e299 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -12,8 +12,8 @@ uint16_t MouseKeys_::speedDelay = 0; uint8_t MouseKeys_::accelSpeed = 1; uint16_t MouseKeys_::accelDelay = 50; -uint32_t MouseKeys_::accelStartTime; -uint32_t MouseKeys_::startTime; +uint32_t MouseKeys_::accelEndTime; +uint32_t MouseKeys_::endTime; void MouseKeys_::loopHook(bool postClear) { if (postClear) { @@ -23,19 +23,19 @@ void MouseKeys_::loopHook(bool postClear) { if (mouseMoveIntent == 0) { MouseWrapper.accelStep = 0; - startTime = 0; - accelStartTime = 0; + endTime = 0; + accelEndTime = 0; return; } - if ((millis() - startTime) < speedDelay) - return; + if (millis() < endTime) + return; - startTime = millis(); + endTime = millis() + speedDelay; int8_t moveX = 0, moveY = 0; - if ((millis() - accelStartTime) >= (accelDelay * MouseWrapper.accelStep)) { + if (millis() >= accelEndTime) { if (MouseWrapper.accelStep < 255 - accelSpeed) MouseWrapper.accelStep += accelSpeed; } @@ -67,10 +67,8 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS } } else if (!(mappedKey.keyCode & KEY_MOUSE_WARP)) { if (key_toggled_on(keyState)) { - if (!startTime) - startTime = millis(); - if (!accelStartTime) - accelStartTime = millis(); + endTime = millis() + speedDelay; + accelEndTime = millis() + accelDelay; } if (key_is_pressed(keyState)) mouseMoveIntent |= mappedKey.keyCode; diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index f303d077..e94d5ea9 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -16,8 +16,8 @@ class MouseKeys_ : public KaleidoscopePlugin { private: static uint8_t mouseMoveIntent; - static uint32_t startTime; - static uint32_t accelStartTime; + static uint32_t endTime; + static uint32_t accelEndTime; static void loopHook(bool postClear); static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); From 0bfd633cfaab782859affb09c5a34efaa2fb55c7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 21 Feb 2017 20:00:50 +0100 Subject: [PATCH 087/792] Only sync the LEDs, if there is a change To further improve the LED performance, sync only when there is a change. We do this by tracking when change happens, assuming everyone uses the provided accessors. While we do a bit of extra work each cycle to do the tracking, that pales in comparison to what we gain by not having to transfer data needlessly. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 11 +++++++++++ src/Kaleidoscope-Hardware-Model01.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index bab20aff..cd615cc3 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -6,6 +6,7 @@ KeyboardioScanner Model01::leftHand(0); KeyboardioScanner Model01::rightHand(3); +bool Model01::isLEDChanged; static constexpr uint8_t key_led_map[4][16] = { {3,4,11,12,19,20,26,27, 36,37,43,44,51,52,59,60}, @@ -62,8 +63,14 @@ void Model01::setup(void) { void Model01::led_set_crgb_at(uint8_t i, cRGB crgb) { if(i<32) { + cRGB oldColor = led_get_crgb_at(i); + isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); + leftHand.ledData.leds[i] = crgb; } else if (i<64) { + cRGB oldColor = led_get_crgb_at(i); + isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); + rightHand.ledData.leds[i-32] = crgb; } else { // TODO how do we want to handle debugging assertions about crazy user @@ -86,6 +93,9 @@ cRGB Model01::led_get_crgb_at(uint8_t i) { } void Model01::led_sync() { + if (!isLEDChanged) + return; + leftHand.sendLEDData(); rightHand.sendLEDData(); @@ -98,6 +108,7 @@ void Model01::led_sync() { leftHand.sendLEDData(); rightHand.sendLEDData(); + isLEDChanged = false; } boolean Model01::led_power_fault() { diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index c92bbf8e..07093d04 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -38,6 +38,7 @@ class Model01 { keydata_t previousRightHandState; private: + static bool isLEDChanged; static KeyboardioScanner leftHand; static KeyboardioScanner rightHand; }; From 7729d5b28288efb0f84eb63d076288d8dfd9215f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 21 Feb 2017 20:14:09 +0100 Subject: [PATCH 088/792] Drop the layer save/load methods Drop the `load_primary_layer` and `save_primary_layer` methods, because `save_primary_layer` is not used anywhere, and as such, the whole thing is pointless at this time. Furthermore, if we want to allow plugins to implement EEPROM storage, then its best if we leave the default layer save/load to the plugins too. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 15 --------------- src/Kaleidoscope-Hardware-Model01.h | 3 --- 2 files changed, 18 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index bab20aff..160bb716 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -1,8 +1,5 @@ #include #include -#include - -#define EEPROM_LAYER_LOCATION 0 KeyboardioScanner Model01::leftHand(0); KeyboardioScanner Model01::rightHand(3); @@ -186,16 +183,4 @@ void Model01::reboot_bootloader() { // happens before the watchdog reboots us } -void Model01::save_primary_layer(uint8_t layer) { - EEPROM.write(EEPROM_LAYER_LOCATION, layer); -} - -uint8_t Model01::load_primary_layer(uint8_t layer_count) { - uint8_t layer = EEPROM.read(EEPROM_LAYER_LOCATION); - if (layer >= layer_count) { - return 0; // undefined positions get saved as 255 - } - return 0; // return keymap; -} - HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index c92bbf8e..2018fd95 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -29,9 +29,6 @@ class Model01 { boolean led_power_fault(void); - uint8_t load_primary_layer(uint8_t layer_count); - void save_primary_layer(uint8_t layer); - keydata_t leftHandState; keydata_t rightHandState; keydata_t previousLeftHandState; From 5ba8fe34bb19f8953358343019c13c7cae114119 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Feb 2017 00:13:55 +0100 Subject: [PATCH 089/792] Mark the class a descendant of public LEDMode Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Chase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.h b/src/Kaleidoscope-LEDEffect-Chase.h index 46669aac..e1989fae 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.h +++ b/src/Kaleidoscope-LEDEffect-Chase.h @@ -3,7 +3,7 @@ #include "Kaleidoscope-LEDControl.h" #include "LEDUtils.h" -class LEDChaseEffect_ : LEDMode { +class LEDChaseEffect_ : public LEDMode { public: LEDChaseEffect_ (void); From d77b051e8fd4d0ec563786804e0465b66bba1493 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Feb 2017 00:14:42 +0100 Subject: [PATCH 090/792] Mark the class a descendant of public LEDMode Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Breathe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index 3fa7b643..ead866c0 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -3,7 +3,7 @@ #include "Kaleidoscope-LEDControl.h" #include "LEDUtils.h" -class LEDBreatheEffect_ : LEDMode { +class LEDBreatheEffect_ : public LEDMode { public: LEDBreatheEffect_ (void); From 69a8a8830fa7561b263e3bd188dfa2d2beeb91c2 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Feb 2017 00:15:20 +0100 Subject: [PATCH 091/792] Mark the classes descendants of public LEDMode Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Rainbow.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 4703306f..8a309dcf 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -3,7 +3,7 @@ #include "Kaleidoscope-LEDControl.h" #include "LEDUtils.h" -class LEDRainbowEffect_ : LEDMode { +class LEDRainbowEffect_ : public LEDMode { public: LEDRainbowEffect_ (void); @@ -23,7 +23,7 @@ class LEDRainbowEffect_ : LEDMode { extern LEDRainbowEffect_ LEDRainbowEffect; -class LEDRainbowWaveEffect_ : LEDMode { +class LEDRainbowWaveEffect_ : public LEDMode { public: LEDRainbowWaveEffect_ (void); From 7686f5871519d6ece4dcb093f2cf7b6da9bd991b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Feb 2017 00:16:04 +0100 Subject: [PATCH 092/792] Mark the class a descendant of public LEDMode Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-SolidColor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.h b/src/Kaleidoscope-LEDEffect-SolidColor.h index 823969a1..0feb2ae2 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.h +++ b/src/Kaleidoscope-LEDEffect-SolidColor.h @@ -2,7 +2,7 @@ #include "Kaleidoscope-LEDControl.h" -class LEDSolidColor : LEDMode { +class LEDSolidColor : public LEDMode { public: LEDSolidColor (uint8_t r, uint8_t g, uint8_t b); From f2773e144430b06d753758a72fc580128ddf8c84 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Feb 2017 00:16:38 +0100 Subject: [PATCH 093/792] Mark the class a descendant of public LEDMode Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-Numlock.h index 52fab4cd..b118f411 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -7,7 +7,7 @@ #define TOGGLENUMLOCK 0 #define Key_ToggleNumlock M(TOGGLENUMLOCK) -class NumLock_ : LEDMode { +class NumLock_ : public LEDMode { public: NumLock_ (void); From 69cad076bc231cc3b70d0141ba10eb5a53df4af0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Feb 2017 11:28:07 +0100 Subject: [PATCH 094/792] Test the plugin with Travis CI Signed-off-by: Gergely Nagy --- .gitignore | 2 ++ .travis.yml | 18 ++++++++++++++++++ README.md | 5 ++++- 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 .travis.yml diff --git a/.gitignore b/.gitignore index aead9485..be16c9be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .#* *~ +/hardware/ +/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..77431b24 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,18 @@ +language: cpp +dist: trusty +sudo: required +os: + - linux +before_install: + - pushd .. + - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz + - tar xf arduino-1.6.11-linux64.tar.xz + - popd +install: + - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - export DEFAULT_SKETCH=$(cd examples; basename *) + - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 + - export BOARD_HARDWARE_PATH=$(pwd)/hardware + - export EXTRA_BUILDER_ARGS="-libraries ." + - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build diff --git a/README.md b/README.md index d5ea2394..bca84246 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # Kaleidoscope-LED-AlphaSquare -![status][st:experimental] +![status][st:experimental] [![Build Status][travis:image]][travis:status] + + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 From 1dcccb0e3738eca70afb21fd1fd2627016b5bd7d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Feb 2017 11:28:15 +0100 Subject: [PATCH 095/792] Test the plugin with Travis CI Signed-off-by: Gergely Nagy --- .gitignore | 2 ++ .travis.yml | 18 ++++++++++++++++++ README.md | 5 ++++- 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 .travis.yml diff --git a/.gitignore b/.gitignore index aead9485..be16c9be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .#* *~ +/hardware/ +/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..77431b24 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,18 @@ +language: cpp +dist: trusty +sudo: required +os: + - linux +before_install: + - pushd .. + - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz + - tar xf arduino-1.6.11-linux64.tar.xz + - popd +install: + - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - export DEFAULT_SKETCH=$(cd examples; basename *) + - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 + - export BOARD_HARDWARE_PATH=$(pwd)/hardware + - export EXTRA_BUILDER_ARGS="-libraries ." + - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build diff --git a/README.md b/README.md index 314e5c83..b9ef6a71 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # Kaleidoscope-LED-Stalker -![status][st:experimental] +![status][st:experimental] [![Build Status][travis:image]][travis:status] + + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 From b203ce754a8c7ad6ca6e9a9d45ab80584e2e8402 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Feb 2017 11:28:19 +0100 Subject: [PATCH 096/792] Test the plugin with Travis CI Signed-off-by: Gergely Nagy --- .gitignore | 2 ++ .travis.yml | 18 ++++++++++++++++++ README.md | 5 ++++- 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 .travis.yml diff --git a/.gitignore b/.gitignore index aead9485..be16c9be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .#* *~ +/hardware/ +/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..77431b24 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,18 @@ +language: cpp +dist: trusty +sudo: required +os: + - linux +before_install: + - pushd .. + - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz + - tar xf arduino-1.6.11-linux64.tar.xz + - popd +install: + - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - export DEFAULT_SKETCH=$(cd examples; basename *) + - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 + - export BOARD_HARDWARE_PATH=$(pwd)/hardware + - export EXTRA_BUILDER_ARGS="-libraries ." + - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build diff --git a/README.md b/README.md index bc97d208..d5b4406c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # Kaleidoscope-MagicCombo -![status][st:stable] +![status][st:stable] [![Build Status][travis:image]][travis:status] + + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 From 8be09348a01df57222de49b937b5cf528f716724 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Feb 2017 22:33:20 +0100 Subject: [PATCH 097/792] Instead of calling macroAction only on keydown, call it every time Call `macroAction` for all `keyState`s, not only when a key toggled on. This lets the macro itself decide when to act, and makes it possible to have macro effects on the other states. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 26ed7871..d9a271b2 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -50,9 +50,6 @@ static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) return mappedKey; - if (!key_toggled_on(keyState)) - return Key_NoKey; - Macros_::row = row; Macros_::col = col; const macro_t *m = macroAction(mappedKey.keyCode, keyState); From fcde978862f29f584e8b77cc8894769e39d43bf3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 25 Feb 2017 22:46:25 +0100 Subject: [PATCH 098/792] Initial import Signed-off-by: Gergely Nagy --- .gitignore | 4 + .travis.yml | 19 + COPYING | 674 +++++++++++++++++++ README.md | 42 ++ examples/EEPROM-Settings/EEPROM-Settings.ino | 59 ++ library.properties | 10 + src/Kaleidoscope-EEPROM-Settings.h | 21 + src/Kaleidoscope/EEPROM-Settings.cpp | 63 ++ src/Kaleidoscope/EEPROM-Settings.h | 46 ++ 9 files changed, 938 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 COPYING create mode 100644 README.md create mode 100644 examples/EEPROM-Settings/EEPROM-Settings.ino create mode 100644 library.properties create mode 100644 src/Kaleidoscope-EEPROM-Settings.h create mode 100644 src/Kaleidoscope/EEPROM-Settings.cpp create mode 100644 src/Kaleidoscope/EEPROM-Settings.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..be16c9be --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.#* +*~ +/hardware/ +/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..b5ff1273 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: cpp +dist: trusty +sudo: required +os: + - linux +before_install: + - pushd .. + - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz + - tar xf arduino-1.6.11-linux64.tar.xz + - popd +install: + - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - ln -s $(pwd) hardware/keyboardio/avr/libraries/Kaleidoscope-EEPROM-Settings +script: + - export DEFAULT_SKETCH=$(cd examples; basename *) + - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 + - export BOARD_HARDWARE_PATH=$(pwd)/hardware + - export EXTRA_BUILDER_ARGS="-libraries ." + - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/README.md b/README.md new file mode 100644 index 00000000..f4b5b59c --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# Kaleidoscope-EEPROM-Settings + +![status][st:experimental] [![Build Status][travis:image]][travis:status] + + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings + + [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + +TODO + +## Using the plugin + +TODO + +```c++ +#include +#include + +void setup () { + Kaleidoscope.setup (); + + USE_PLUGINS (&EEPROMSettings); + + // TODO +} +``` + +## Plugin methods + +The plugin provides the `EEPROMSettings` object, which has the following methods: + +**TODO** + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings/blob/master/examples/EEPROM-Settings/EEPROM-Settings.ino diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino new file mode 100644 index 00000000..08e474d0 --- /dev/null +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -0,0 +1,59 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include +#include + +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + ( + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + + Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, + Key_skip + ), +}; + +void setup () { + Serial.begin (9600); + + Kaleidoscope.setup (); + + USE_PLUGINS (&EEPROMSettings); + + while (!Serial) { + } + + Serial.println (EEPROMSettings.isValid () ? "valid EEPROM settings" : "invalid EEPROM settings"); + Serial.println (EEPROMSettings.endOfSettings ()); +} + +void loop () { + Kaleidoscope.loop (); +} diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..c78bfdfa --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Kaleidoscope-EEPROM-Settings +version=0.0.0 +author=Gergely Nagy +maintainer=Gergely Nagy +sentence=Base EEPROM settings plugin for Kaleidoscope. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings +architectures=avr +dot_a_linkage=true diff --git a/src/Kaleidoscope-EEPROM-Settings.h b/src/Kaleidoscope-EEPROM-Settings.h new file mode 100644 index 00000000..f2735e3b --- /dev/null +++ b/src/Kaleidoscope-EEPROM-Settings.h @@ -0,0 +1,21 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp new file mode 100644 index 00000000..213e6b64 --- /dev/null +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -0,0 +1,63 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include + +namespace KaleidoscopePlugins { + struct EEPROMSettings::settings EEPROMSettings::settings; + bool EEPROMSettings::_isValid; + + EEPROMSettings::EEPROMSettings (void) { + } + + void + EEPROMSettings::begin (void) { + _isValid = true; + EEPROM.get (0, settings); + + if (settings.magic[0] != 'K' || settings.magic[1] != 'S') { + settings.magic[0] = 'K'; + settings.magic[1] = 'S'; + settings.endOfSettings = EEPROM_SETTINGS_RESERVED - 1; + + return update (); + } + + if (settings.endOfSettings != EEPROM_SETTINGS_RESERVED - 1) + _isValid = false; + } + + uint16_t + EEPROMSettings::endOfSettings (void) { + if (!isValid ()) + return 0; + return settings.endOfSettings; + } + + bool + EEPROMSettings::isValid (void) { + return _isValid; + } + + void + EEPROMSettings::update (void) { + EEPROM.put (0, settings); + } +}; + +KaleidoscopePlugins::EEPROMSettings EEPROMSettings; diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h new file mode 100644 index 00000000..db20b708 --- /dev/null +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -0,0 +1,46 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include +#include + +#ifndef EEPROM_SETTINGS_RESERVED +#define EEPROM_SETTINGS_RESERVED ((E2END + 1) / 2) +#endif + +namespace KaleidoscopePlugins { + class EEPROMSettings : public KaleidoscopePlugin { + public: + EEPROMSettings (void); + + virtual void begin (void) final; + + static uint16_t endOfSettings (void); + static void update (void); + static bool isValid (void); + + private: + static bool _isValid; + static struct settings { + char magic[2]; + uint16_t endOfSettings; + } settings; + }; +}; + +extern KaleidoscopePlugins::EEPROMSettings EEPROMSettings; From db09b35be3e7d378f470f5e441228df5fe13130d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 25 Feb 2017 23:32:40 +0100 Subject: [PATCH 099/792] Initial import Signed-off-by: Gergely Nagy --- .gitignore | 4 + .travis.yml | 19 + COPYING | 674 +++++++++++++++++++++++ README.md | 42 ++ examples/EEPROM-Keymap/EEPROM-Keymap.ino | 57 ++ library.properties | 10 + src/Kaleidoscope-EEPROM-Keymap.h | 21 + src/Kaleidoscope/EEPROM-Keymap.cpp | 189 +++++++ src/Kaleidoscope/EEPROM-Keymap.h | 59 ++ 9 files changed, 1075 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 COPYING create mode 100644 README.md create mode 100644 examples/EEPROM-Keymap/EEPROM-Keymap.ino create mode 100644 library.properties create mode 100644 src/Kaleidoscope-EEPROM-Keymap.h create mode 100644 src/Kaleidoscope/EEPROM-Keymap.cpp create mode 100644 src/Kaleidoscope/EEPROM-Keymap.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..be16c9be --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.#* +*~ +/hardware/ +/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..b5ff1273 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: cpp +dist: trusty +sudo: required +os: + - linux +before_install: + - pushd .. + - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz + - tar xf arduino-1.6.11-linux64.tar.xz + - popd +install: + - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - ln -s $(pwd) hardware/keyboardio/avr/libraries/Kaleidoscope-EEPROM-Settings +script: + - export DEFAULT_SKETCH=$(cd examples; basename *) + - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 + - export BOARD_HARDWARE_PATH=$(pwd)/hardware + - export EXTRA_BUILDER_ARGS="-libraries ." + - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/README.md b/README.md new file mode 100644 index 00000000..f7bda3ef --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# Kaleidoscope-EEPROM-Keymap + +![status][st:experimental] [![Build Status][travis:image]][travis:status] + + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap + + [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + +TODO + +## Using the plugin + +TODO + +```c++ +#include +#include + +void setup () { + Kaleidoscope.setup (); + + USE_PLUGINS (&EEPROMKeymap); + + // TODO +} +``` + +## Plugin methods + +The plugin provides the `EEPROMKeymap` object, which has the following methods: + +**TODO** + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-EEPROM-Keymap/blob/master/examples/EEPROM-Keymap/EEPROM-Keymap.ino diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino new file mode 100644 index 00000000..e1f1a470 --- /dev/null +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -0,0 +1,57 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include +#include +#include + +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + ( + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + + Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, + Key_skip + ), +}; + +void setup () { + Serial.begin (9600); + + Kaleidoscope.setup (); + + USE_PLUGINS (&EEPROMKeymap, &Focus); + + Focus.addCommand (FOCUS_CMD_KEYMAP); + Layer.getKey = EEPROMKeymap.getKey; +} + +void loop () { + Kaleidoscope.loop (); +} diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..4e0b6dbc --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Kaleidoscope-EEPROM-Keymap +version=0.0.0 +author=Gergely Nagy +maintainer=Gergely Nagy +sentence=EEPROM-based keymap support for Kaleidoscope. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Kaleidoscope-EEPROM-Keymap +architectures=avr +dot_a_linkage=true diff --git a/src/Kaleidoscope-EEPROM-Keymap.h b/src/Kaleidoscope-EEPROM-Keymap.h new file mode 100644 index 00000000..77d64c5c --- /dev/null +++ b/src/Kaleidoscope-EEPROM-Keymap.h @@ -0,0 +1,21 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp new file mode 100644 index 00000000..5ec287c3 --- /dev/null +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -0,0 +1,189 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include +#include + +namespace KaleidoscopePlugins { + uint16_t EEPROMKeymap::keymapBase; + uint8_t EEPROMKeymap::maxLayers; + + EEPROMKeymap::EEPROMKeymap (void) { + } + + void + EEPROMKeymap::begin (void) { + USE_PLUGINS (&::EEPROMSettings); + + uint16_t layerSize = ROWS * COLS * 2; + maxLayers = (E2END - ::EEPROMSettings.endOfSettings ()) / layerSize; + keymapBase = ::EEPROMSettings.endOfSettings () + 1; + } + + Key + EEPROMKeymap::getKey (uint8_t layer, byte row, byte col) { + Key key; + + if (layer >= maxLayers) + return Key_NoKey; + + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col) * 2; + + key.flags = EEPROM.read (keymapBase + pos); + key.keyCode = EEPROM.read (keymapBase + pos + 1); + + if (key.raw == 0xffff) + return Key_NoKey; + + return key; + } + + uint16_t + EEPROMKeymap::base (void) { + return keymapBase; + } + + bool + EEPROMKeymap::focusKeymap (const char *command) { + enum { + UPLOAD, + GETPOS, + SETPOS, + DUMP, + TRANSFER, + } subCommand; + + if (strncmp_P (command, PSTR ("keymap."), 7) != 0) + return false; + + if (strcmp_P (command + 7, PSTR ("upload")) == 0) + subCommand = UPLOAD; + else if (strcmp_P (command + 7, PSTR ("dump")) == 0) + subCommand = DUMP; + else if (strcmp_P (command + 7, PSTR ("transfer")) == 0) + subCommand = TRANSFER; + else if (strcmp_P (command + 7, PSTR ("getPos")) == 0) + subCommand = GETPOS; + else if (strcmp_P (command + 7, PSTR ("setPos")) == 0) + subCommand = SETPOS; + else + return false; + + switch (subCommand) { + case UPLOAD: + { + uint16_t i = 0; + while ((Serial.peek () != '\n') && (i < ROWS * COLS * maxLayers)) { + uint8_t flags = Serial.parseInt (); + uint8_t keyCode = Serial.parseInt (); + uint16_t pos = i * 2; + EEPROM.update (keymapBase + pos, flags); + EEPROM.update (keymapBase + pos + 1, keyCode); + i++; + } + break; + } + + case GETPOS: + { + uint8_t layer = Serial.parseInt (); + uint8_t row = Serial.parseInt (); + uint8_t col = Serial.parseInt (); + + Key k = getKey (layer, row, col); + + Serial.print (k.flags); + Serial.print (F(" ")); + Serial.println (k.keyCode); + + break; + } + + case DUMP: + { + for (uint8_t layer = 0; layer < 4; layer++) { + for (uint8_t row = 0; row < ROWS; row++) { + for (uint8_t col = 0; col < COLS; col++) { + Key k = getKey (layer, row, col); + + if (k.flags < 10) + Serial.print (F(" ")); + if (k.flags < 100) + Serial.print (F(" ")); + Serial.print (k.flags); + Serial.print (F(" ")); + + if (k.keyCode < 10) + Serial.print (F(" ")); + if (k.keyCode < 100) + Serial.print (F(" ")); + Serial.print (k.keyCode); + + if (col < COLS - 1) + Serial.print (F(" ")); + } + Serial.println (); + } + Serial.println (); + } + break; + } + + case SETPOS: + { + uint8_t layer = Serial.parseInt (); + uint8_t row = Serial.parseInt (); + uint8_t col = Serial.parseInt (); + uint8_t flags = Serial.parseInt (); + uint8_t keyCode = Serial.parseInt (); + + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col) * 2; + + EEPROM.update (keymapBase + pos, flags); + EEPROM.update (keymapBase + pos + 1, keyCode); + + break; + } + + case TRANSFER: + { + uint8_t layer = Serial.parseInt (); + + for (uint8_t row = 0; row < ROWS; row++) { + for (uint8_t col = 0; col < COLS; col++) { + Key k = Layer.getKeyFromPROGMEM (layer, row, col); + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col) * 2; + + EEPROM.update (keymapBase + pos, k.flags); + EEPROM.update (keymapBase + pos + 1, k.keyCode); + } + } + + break; + } + + } + + Serial.read (); + + return true; + } + +}; + +KaleidoscopePlugins::EEPROMKeymap EEPROMKeymap; diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h new file mode 100644 index 00000000..e80b6cb0 --- /dev/null +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -0,0 +1,59 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include +#include + +#define FOCUS_CMD_KEYMAP FOCUS_COMMAND(EEPROMKeymap.focusKeymap, \ + "keymap.dump\n" \ + "-----------\n" \ + "Dumps the keymap from EEPROM.\n\n" \ + "keymap.upload ...\n" \ + "-------------------------------\n" \ + "Uploads a new keymap to EEPROM." \ + "Starts at layer 0, row 0, column 0, " \ + "and continues as long as there is data on the line.\n\n" \ + "keymap.setPos layer row column flag keyCode\n" \ + "-------------------------------------------\n" \ + "Sets the key at the specified `layer`, `row`, and `column` " \ + "to the key with `flag`, and `keyCode` properties.\n\n" \ + "keymap.getPos layer row column\n" \ + "------------------------------\n" \ + "Dump the key at `layer`, `row`, and `column`.\n\n" \ + "keymap.transfer layer\n" \ + "---------------------\n" \ + "Transfers the `layer` from PROGMEM to EEPROM.") + +namespace KaleidoscopePlugins { + class EEPROMKeymap : public KaleidoscopePlugin { + public: + EEPROMKeymap (void); + + virtual void begin (void) final; + + static Key getKey (uint8_t layer, byte row, byte col); + static uint16_t base (void); + static bool focusKeymap (const char *command); + + private: + static uint16_t keymapBase; + static uint8_t maxLayers; + }; +}; + +extern KaleidoscopePlugins::EEPROMKeymap EEPROMKeymap; From 03ab5f1a474cfabf8303e0fbb70900039c3c4a11 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 09:04:13 +0100 Subject: [PATCH 100/792] Updated to support newest Focus Signed-off-by: Gergely Nagy --- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 5 +++- src/Kaleidoscope/EEPROM-Keymap.h | 38 ++++++++++++------------ 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index e1f1a470..9bdd3656 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -48,7 +48,10 @@ void setup () { USE_PLUGINS (&EEPROMKeymap, &Focus); - Focus.addCommand (FOCUS_CMD_KEYMAP); + Focus.addHook (FOCUS_HOOK_KEYMAP); + Focus.addHook (FOCUS_HOOK_HELP); + Focus.addHook (FOCUS_HOOK_VERSION); + Layer.getKey = EEPROMKeymap.getKey; } diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index e80b6cb0..65a77cd4 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -19,25 +19,25 @@ #include #include -#define FOCUS_CMD_KEYMAP FOCUS_COMMAND(EEPROMKeymap.focusKeymap, \ - "keymap.dump\n" \ - "-----------\n" \ - "Dumps the keymap from EEPROM.\n\n" \ - "keymap.upload ...\n" \ - "-------------------------------\n" \ - "Uploads a new keymap to EEPROM." \ - "Starts at layer 0, row 0, column 0, " \ - "and continues as long as there is data on the line.\n\n" \ - "keymap.setPos layer row column flag keyCode\n" \ - "-------------------------------------------\n" \ - "Sets the key at the specified `layer`, `row`, and `column` " \ - "to the key with `flag`, and `keyCode` properties.\n\n" \ - "keymap.getPos layer row column\n" \ - "------------------------------\n" \ - "Dump the key at `layer`, `row`, and `column`.\n\n" \ - "keymap.transfer layer\n" \ - "---------------------\n" \ - "Transfers the `layer` from PROGMEM to EEPROM.") +#define FOCUS_HOOK_KEYMAP FOCUS_HOOK(EEPROMKeymap.focusKeymap, \ + "keymap.dump\n" \ + "-----------\n" \ + "Dumps the keymap from EEPROM.\n\n" \ + "keymap.upload ...\n" \ + "-------------------------------\n" \ + "Uploads a new keymap to EEPROM." \ + "Starts at layer 0, row 0, column 0, " \ + "and continues as long as there is data on the line.\n\n" \ + "keymap.setPos layer row column flag keyCode\n" \ + "-------------------------------------------\n" \ + "Sets the key at the specified `layer`, `row`, and `column` " \ + "to the key with `flag`, and `keyCode` properties.\n\n" \ + "keymap.getPos layer row column\n" \ + "------------------------------\n" \ + "Dump the key at `layer`, `row`, and `column`.\n\n" \ + "keymap.transfer layer\n" \ + "---------------------\n" \ + "Transfers the `layer` from PROGMEM to EEPROM.") namespace KaleidoscopePlugins { class EEPROMKeymap : public KaleidoscopePlugin { From eca8be7b57838219cdc9a9667c8c149fb9fdf050 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 10:14:01 +0100 Subject: [PATCH 101/792] Add a missing #pragma once Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index db20b708..184bc1f7 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +#pragma once + #include #include From 212861173cb9d8b20f9a6a857e5b27e040e6dac2 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 10:14:30 +0100 Subject: [PATCH 102/792] Add a version to the settings struct Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings.cpp | 17 +++++++++++++++++ src/Kaleidoscope/EEPROM-Settings.h | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 213e6b64..bf221395 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -54,9 +54,26 @@ namespace KaleidoscopePlugins { return _isValid; } + void + EEPROMSettings::invalidate (void) { + _isValid = false; + } + void EEPROMSettings::update (void) { EEPROM.put (0, settings); + _isValid = true; + } + + uint8_t + EEPROMSettings::version (void) { + return settings.version; + } + + void + EEPROMSettings::version (uint8_t ver) { + settings.version = ver; + update (); } }; diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 184bc1f7..cdaf9a7a 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -35,11 +35,15 @@ namespace KaleidoscopePlugins { static uint16_t endOfSettings (void); static void update (void); static bool isValid (void); + static void invalidate (void); + static uint8_t version (void); + static void version (uint8_t ver); private: static bool _isValid; static struct settings { char magic[2]; + uint8_t version; uint16_t endOfSettings; } settings; }; From ef832250f0f732c99a37cc12e3919a6816f7fce9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 10:14:47 +0100 Subject: [PATCH 103/792] Add (optional) Focus hooks Signed-off-by: Gergely Nagy --- src/Kaleidoscope-EEPROM-Settings.h | 1 + src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 51 ++++++++++++++++++++++ src/Kaleidoscope/EEPROM-Settings-Focus.h | 33 ++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 src/Kaleidoscope/EEPROM-Settings-Focus.cpp create mode 100644 src/Kaleidoscope/EEPROM-Settings-Focus.h diff --git a/src/Kaleidoscope-EEPROM-Settings.h b/src/Kaleidoscope-EEPROM-Settings.h index f2735e3b..ca5fb963 100644 --- a/src/Kaleidoscope-EEPROM-Settings.h +++ b/src/Kaleidoscope-EEPROM-Settings.h @@ -19,3 +19,4 @@ #pragma once #include +#include diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp new file mode 100644 index 00000000..d7193b14 --- /dev/null +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -0,0 +1,51 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include + +namespace FocusHooks { + bool settings (const char *command) { + enum { + ISVALID, + GETVERSION, + } subCommand; + + if (strncmp_P (command, PSTR ("settings."), 9) != 0) + return false; + + if (strcmp_P (command + 9, PSTR ("valid?")) == 0) + subCommand = ISVALID; + else if (strcmp_P (command + 9, PSTR ("version")) == 0) + subCommand = GETVERSION; + else + return false; + + switch (subCommand) { + case ISVALID: + Serial.println (EEPROMSettings.isValid () ? F("yes") : F("no")); + break; + case GETVERSION: + Serial.println (EEPROMSettings.version ()); + break; + } + + Serial.read (); + + return true; + } +}; diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h new file mode 100644 index 00000000..67667e82 --- /dev/null +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -0,0 +1,33 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include + +namespace FocusHooks { + bool settings (const char *command); +}; + +#define FOCUS_HOOK_SETTINGS FOCUS_HOOK(FocusHooks::settings, \ + "settings.valid?\n" \ + "---------------\n" \ + "Return whether the EEPROM settings are valid, or not.\n\n" \ + "settings.version\n" \ + "----------------\n" \ + "Return the version of the EEPROM settings.") From 73c0f86d37ef7d162e4c1292d409c7afaf18bad6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 10:16:47 +0100 Subject: [PATCH 104/792] Add a missing #pragma once Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 65a77cd4..1267c1bf 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +#pragma once + #include #include From 00b836d0ace5934eb98519dfe4c1fc4637b97460 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 10:24:49 +0100 Subject: [PATCH 105/792] Code optimalization Lift out the key updating code into a private method. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 33 +++++++++++++++++------------- src/Kaleidoscope/EEPROM-Keymap.h | 2 ++ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 5ec287c3..add87f78 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -58,6 +58,12 @@ namespace KaleidoscopePlugins { return keymapBase; } + void + EEPROMKeymap::updateKey (uint16_t basePos, Key key) { + EEPROM.update (keymapBase + basePos * 2, key.flags); + EEPROM.update (keymapBase + basePos * 2 + 1, key.keyCode); + } + bool EEPROMKeymap::focusKeymap (const char *command) { enum { @@ -89,11 +95,12 @@ namespace KaleidoscopePlugins { { uint16_t i = 0; while ((Serial.peek () != '\n') && (i < ROWS * COLS * maxLayers)) { - uint8_t flags = Serial.parseInt (); - uint8_t keyCode = Serial.parseInt (); - uint16_t pos = i * 2; - EEPROM.update (keymapBase + pos, flags); - EEPROM.update (keymapBase + pos + 1, keyCode); + Key key; + + key.flags = Serial.parseInt (); + key.keyCode = Serial.parseInt (); + updateKey (i, key); + i++; } break; @@ -149,13 +156,12 @@ namespace KaleidoscopePlugins { uint8_t layer = Serial.parseInt (); uint8_t row = Serial.parseInt (); uint8_t col = Serial.parseInt (); - uint8_t flags = Serial.parseInt (); - uint8_t keyCode = Serial.parseInt (); - - uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col) * 2; + Key key; + key.flags = Serial.parseInt (); + key.keyCode = Serial.parseInt (); - EEPROM.update (keymapBase + pos, flags); - EEPROM.update (keymapBase + pos + 1, keyCode); + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); + updateKey (pos, key); break; } @@ -167,10 +173,9 @@ namespace KaleidoscopePlugins { for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t col = 0; col < COLS; col++) { Key k = Layer.getKeyFromPROGMEM (layer, row, col); - uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col) * 2; + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); - EEPROM.update (keymapBase + pos, k.flags); - EEPROM.update (keymapBase + pos + 1, k.keyCode); + updateKey (pos, k); } } diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 1267c1bf..92fc2e13 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -55,6 +55,8 @@ namespace KaleidoscopePlugins { private: static uint16_t keymapBase; static uint8_t maxLayers; + + static void updateKey (uint16_t basePos, Key key); }; }; From 45391388dbb57ac34503f4372a38e897d9f43613 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 10:25:21 +0100 Subject: [PATCH 106/792] Move the Focus hook into a separate file Signed-off-by: Gergely Nagy --- src/Kaleidoscope-EEPROM-Keymap.h | 1 + src/Kaleidoscope/EEPROM-Keymap-Focus.h | 42 ++++++++++++++++++++++++++ src/Kaleidoscope/EEPROM-Keymap.h | 20 ------------ 3 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 src/Kaleidoscope/EEPROM-Keymap-Focus.h diff --git a/src/Kaleidoscope-EEPROM-Keymap.h b/src/Kaleidoscope-EEPROM-Keymap.h index 77d64c5c..fec376e8 100644 --- a/src/Kaleidoscope-EEPROM-Keymap.h +++ b/src/Kaleidoscope-EEPROM-Keymap.h @@ -19,3 +19,4 @@ #pragma once #include +#include diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Focus.h new file mode 100644 index 00000000..5e72184d --- /dev/null +++ b/src/Kaleidoscope/EEPROM-Keymap-Focus.h @@ -0,0 +1,42 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include +#include + +#define FOCUS_HOOK_KEYMAP FOCUS_HOOK(EEPROMKeymap.focusKeymap, \ + "keymap.dump\n" \ + "-----------\n" \ + "Dumps the keymap from EEPROM.\n\n" \ + "keymap.upload ...\n" \ + "-------------------------------\n" \ + "Uploads a new keymap to EEPROM." \ + "Starts at layer 0, row 0, column 0, " \ + "and continues as long as there is data on the line.\n\n" \ + "keymap.setPos layer row column flag keyCode\n" \ + "-------------------------------------------\n" \ + "Sets the key at the specified `layer`, `row`, and `column` " \ + "to the key with `flag`, and `keyCode` properties.\n\n" \ + "keymap.getPos layer row column\n" \ + "------------------------------\n" \ + "Dump the key at `layer`, `row`, and `column`.\n\n" \ + "keymap.transfer layer\n" \ + "---------------------\n" \ + "Transfers the `layer` from PROGMEM to EEPROM.") diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 92fc2e13..5dedee66 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -21,26 +21,6 @@ #include #include -#define FOCUS_HOOK_KEYMAP FOCUS_HOOK(EEPROMKeymap.focusKeymap, \ - "keymap.dump\n" \ - "-----------\n" \ - "Dumps the keymap from EEPROM.\n\n" \ - "keymap.upload ...\n" \ - "-------------------------------\n" \ - "Uploads a new keymap to EEPROM." \ - "Starts at layer 0, row 0, column 0, " \ - "and continues as long as there is data on the line.\n\n" \ - "keymap.setPos layer row column flag keyCode\n" \ - "-------------------------------------------\n" \ - "Sets the key at the specified `layer`, `row`, and `column` " \ - "to the key with `flag`, and `keyCode` properties.\n\n" \ - "keymap.getPos layer row column\n" \ - "------------------------------\n" \ - "Dump the key at `layer`, `row`, and `column`.\n\n" \ - "keymap.transfer layer\n" \ - "---------------------\n" \ - "Transfers the `layer` from PROGMEM to EEPROM.") - namespace KaleidoscopePlugins { class EEPROMKeymap : public KaleidoscopePlugin { public: From 807d18ab31bfe84055d5d0773c6213d152bc31a0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 10:28:54 +0100 Subject: [PATCH 107/792] Nicer dump output Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index add87f78..3bc46b2d 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -142,7 +142,7 @@ namespace KaleidoscopePlugins { Serial.print (k.keyCode); if (col < COLS - 1) - Serial.print (F(" ")); + Serial.print (F(" | ")); } Serial.println (); } From 496cff414b512fb554f682f2a192addbb3d9ce05 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 13:06:11 +0100 Subject: [PATCH 108/792] Travis: Remove obsolete workarounds Signed-off-by: Gergely Nagy --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b5ff1273..ed2b2e3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,8 @@ before_install: - popd install: - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr - - ln -s $(pwd) hardware/keyboardio/avr/libraries/Kaleidoscope-EEPROM-Settings script: - export DEFAULT_SKETCH=$(cd examples; basename *) - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 - export BOARD_HARDWARE_PATH=$(pwd)/hardware - - export EXTRA_BUILDER_ARGS="-libraries ." - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build From 80178956e41ee4a3c08c14d348705421e97b4086 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 26 Feb 2017 13:09:33 +0100 Subject: [PATCH 109/792] Travis: Remove obsolete workarounds Signed-off-by: Gergely Nagy --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b5ff1273..ed2b2e3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,8 @@ before_install: - popd install: - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr - - ln -s $(pwd) hardware/keyboardio/avr/libraries/Kaleidoscope-EEPROM-Settings script: - export DEFAULT_SKETCH=$(cd examples; basename *) - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 - export BOARD_HARDWARE_PATH=$(pwd)/hardware - - export EXTRA_BUILDER_ARGS="-libraries ." - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build From 33f5d8d9de24b5720e757e1beae417427079c413 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 28 Feb 2017 09:42:32 +0100 Subject: [PATCH 110/792] Some small code optimizations Lifted out a few things from the main `focusKeymap` method, to make code size smaller. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 55 ++++++++++++++++-------------- src/Kaleidoscope/EEPROM-Keymap.h | 2 ++ 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 3bc46b2d..5a737175 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -64,6 +64,32 @@ namespace KaleidoscopePlugins { EEPROM.update (keymapBase + basePos * 2 + 1, key.keyCode); } + Key + EEPROMKeymap::parseKey (void) { + Key key; + + key.flags = Serial.parseInt (); + key.keyCode = Serial.parseInt (); + + return key; + } + + void + EEPROMKeymap::printKey (Key k) { + if (k.flags < 10) + Serial.print (F(" ")); + if (k.flags < 100) + Serial.print (F(" ")); + Serial.print (k.flags); + Serial.print (F(" ")); + + if (k.keyCode < 10) + Serial.print (F(" ")); + if (k.keyCode < 100) + Serial.print (F(" ")); + Serial.print (k.keyCode); + } + bool EEPROMKeymap::focusKeymap (const char *command) { enum { @@ -95,12 +121,7 @@ namespace KaleidoscopePlugins { { uint16_t i = 0; while ((Serial.peek () != '\n') && (i < ROWS * COLS * maxLayers)) { - Key key; - - key.flags = Serial.parseInt (); - key.keyCode = Serial.parseInt (); - updateKey (i, key); - + updateKey (i, parseKey ()); i++; } break; @@ -114,9 +135,7 @@ namespace KaleidoscopePlugins { Key k = getKey (layer, row, col); - Serial.print (k.flags); - Serial.print (F(" ")); - Serial.println (k.keyCode); + printKey (k); break; } @@ -128,18 +147,7 @@ namespace KaleidoscopePlugins { for (uint8_t col = 0; col < COLS; col++) { Key k = getKey (layer, row, col); - if (k.flags < 10) - Serial.print (F(" ")); - if (k.flags < 100) - Serial.print (F(" ")); - Serial.print (k.flags); - Serial.print (F(" ")); - - if (k.keyCode < 10) - Serial.print (F(" ")); - if (k.keyCode < 100) - Serial.print (F(" ")); - Serial.print (k.keyCode); + printKey (k); if (col < COLS - 1) Serial.print (F(" | ")); @@ -156,12 +164,9 @@ namespace KaleidoscopePlugins { uint8_t layer = Serial.parseInt (); uint8_t row = Serial.parseInt (); uint8_t col = Serial.parseInt (); - Key key; - key.flags = Serial.parseInt (); - key.keyCode = Serial.parseInt (); uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); - updateKey (pos, key); + updateKey (pos, parseKey ()); break; } diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 5dedee66..83809a89 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -37,6 +37,8 @@ namespace KaleidoscopePlugins { static uint8_t maxLayers; static void updateKey (uint16_t basePos, Key key); + static Key parseKey (void); + static void printKey (Key key); }; }; From 18d8a3133858134e76f657e68cdaf0d4eeb24642 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 28 Feb 2017 13:48:13 +0100 Subject: [PATCH 111/792] Drop the getPos & setPos commands They are not all that useful, and take up considerable space, for very little gain. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap-Focus.h | 7 ------ src/Kaleidoscope/EEPROM-Keymap.cpp | 31 -------------------------- 2 files changed, 38 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Focus.h index 5e72184d..72103329 100644 --- a/src/Kaleidoscope/EEPROM-Keymap-Focus.h +++ b/src/Kaleidoscope/EEPROM-Keymap-Focus.h @@ -30,13 +30,6 @@ "Uploads a new keymap to EEPROM." \ "Starts at layer 0, row 0, column 0, " \ "and continues as long as there is data on the line.\n\n" \ - "keymap.setPos layer row column flag keyCode\n" \ - "-------------------------------------------\n" \ - "Sets the key at the specified `layer`, `row`, and `column` " \ - "to the key with `flag`, and `keyCode` properties.\n\n" \ - "keymap.getPos layer row column\n" \ - "------------------------------\n" \ - "Dump the key at `layer`, `row`, and `column`.\n\n" \ "keymap.transfer layer\n" \ "---------------------\n" \ "Transfers the `layer` from PROGMEM to EEPROM.") diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 5a737175..dce75463 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -94,8 +94,6 @@ namespace KaleidoscopePlugins { EEPROMKeymap::focusKeymap (const char *command) { enum { UPLOAD, - GETPOS, - SETPOS, DUMP, TRANSFER, } subCommand; @@ -109,10 +107,6 @@ namespace KaleidoscopePlugins { subCommand = DUMP; else if (strcmp_P (command + 7, PSTR ("transfer")) == 0) subCommand = TRANSFER; - else if (strcmp_P (command + 7, PSTR ("getPos")) == 0) - subCommand = GETPOS; - else if (strcmp_P (command + 7, PSTR ("setPos")) == 0) - subCommand = SETPOS; else return false; @@ -127,19 +121,6 @@ namespace KaleidoscopePlugins { break; } - case GETPOS: - { - uint8_t layer = Serial.parseInt (); - uint8_t row = Serial.parseInt (); - uint8_t col = Serial.parseInt (); - - Key k = getKey (layer, row, col); - - printKey (k); - - break; - } - case DUMP: { for (uint8_t layer = 0; layer < 4; layer++) { @@ -159,18 +140,6 @@ namespace KaleidoscopePlugins { break; } - case SETPOS: - { - uint8_t layer = Serial.parseInt (); - uint8_t row = Serial.parseInt (); - uint8_t col = Serial.parseInt (); - - uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); - updateKey (pos, parseKey ()); - - break; - } - case TRANSFER: { uint8_t layer = Serial.parseInt (); From 46bf755e7cacf532091c0f569d98135d2b6243d3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 1 Mar 2017 11:44:59 +0100 Subject: [PATCH 112/792] Implement gamma correction for the LEDs Instead of using the supplied linear color component values as-is, convert them to gamma-corrected, non-linear values first. This way, we can use numbers like 127 to mean half brightness, and have it automatically translated to the correct, gamma-corrected value. Table copied from: https://learn.adafruit.com/led-tricks-gamma-correction/the-quick-fix This adds a bit over 256 bytes of code, but makes working with colors a lot easier. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index cda9b60f..f5c04d45 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -12,6 +12,25 @@ static constexpr uint8_t key_led_map[4][16] = { {0,7, 8,15,16,23,31,30, 33,32,40,47,48,55,56,63}, }; +const uint8_t PROGMEM gamma8[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, + 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, + 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, + 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, + 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, + 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, + 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, + 90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114, + 115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142, + 144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175, + 177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213, + 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 +}; + Model01::Model01(void) { } @@ -58,7 +77,13 @@ void Model01::setup(void) { } -void Model01::led_set_crgb_at(uint8_t i, cRGB crgb) { +void Model01::led_set_crgb_at(uint8_t i, cRGB crgb_) { + cRGB crgb; + + crgb.r = pgm_read_byte(&gamma8[crgb_.r]); + crgb.g = pgm_read_byte(&gamma8[crgb_.g]); + crgb.b = pgm_read_byte(&gamma8[crgb_.b]); + if(i<32) { cRGB oldColor = led_get_crgb_at(i); isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); From e48d23c0ea6b061773ce812032149d346ab3b4c3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 13:39:39 +0100 Subject: [PATCH 113/792] Add a way to display symbols in different colors While it is possible to play with the ->color property, sometimes one just wants to override the color once. In this case, saving the previous value, and changing it back would be an overkill. Instead, add a few functions that take a color argument as well, and make the color-less arities use the global property. Signed-off-by: Gergely Nagy --- README.md | 13 ++++++++----- src/Kaleidoscope/LED-AlphaSquare.cpp | 18 ++++++++++++++---- src/Kaleidoscope/LED-AlphaSquare.h | 2 ++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index bca84246..3a46dd76 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,9 @@ the `display` method. #include void setup () { - Kaleidoscope.setup (KEYMAP_SIZE); + Kaleidoscope.setup (); - Kaleidoscope.use (&AlphaSquare, NULL); + USE_PLUGINS (&AlphaSquare); AlphaSquare.display (Key_A); } @@ -38,16 +38,19 @@ The plugin provides the `AlphaSquare` object, which has the following methods: ### `.display(key)` ### `.display(key, row, col)` ### `.display(key, col)` +### `.display(key, row, col, color)` -> Display the symbol for `key` at the given row or column. If `row` is omitted, -> the first row - `0` is assumed. If the column is omitted too, then the third - -> `2` - column is used by default. +> Display the symbol for `key` at the given row or column, with pixels set to +> the specified `color`. If `row` is omitted, the first row - `0` is assumed. If +> the column is omitted too, then the third - `2` - column is used by default. +> If the `color` is omitted, the plugin will use the global `.color` property. > > The plugin can display the English alphabet, and the numbers from 0 to 9. ### `.display(symbol)` ### `.display(symbol, row, col)` ### `.display(symbol, col)` +### `.display(symbol, row, col, color)` > Almost the same as the previous function, but instead of a key, it expects a > 4x4 bitmap. diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 088ab7e9..9fda9d51 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -178,30 +178,40 @@ namespace KaleidoscopePlugins { } void - AlphaSquare::display (Key key, uint8_t row, uint8_t col) { + AlphaSquare::display (Key key, uint8_t row, uint8_t col, cRGB keyColor) { if (key < Key_A || key > Key_0) return; uint8_t index = key.keyCode - Key_A.keyCode; uint16_t symbol = pgm_read_word (&alphabet[index]); - display (symbol, row, col); + display (symbol, row, col, keyColor); } void - AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col) { + AlphaSquare::display (Key key, uint8_t row, uint8_t col) { + display (key, row, col, color); + } + + void + AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor) { for (uint8_t r = 0; r < 4; r++) { for (uint8_t c = 0; c < 4; c++) { uint8_t pixel = bitRead (symbol, r * 4 + c); if (!pixel) continue; - LEDControl.led_set_crgb_at (row + r, col + c, color); + LEDControl.led_set_crgb_at (row + r, col + c, keyColor); } } LEDControl.led_sync (); } + + void + AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col) { + display (symbol, row, col, color); + } }; KaleidoscopePlugins::AlphaSquare AlphaSquare; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index 763c6766..d6c52818 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -39,10 +39,12 @@ namespace KaleidoscopePlugins { virtual void begin (void) final; + static void display (Key key, uint8_t row, uint8_t col, cRGB keyColor); static void display (Key key, uint8_t row, uint8_t col); static void display (Key key) { display (key, 0, 2); }; static void display (Key key, uint8_t col) { display (key, 0, col); }; + static void display (uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor); static void display (uint16_t symbol, uint8_t row, uint8_t col); static void display (uint16_t symbol) { display (symbol, 0, 2); }; static void display (uint16_t symbol, uint8_t col) { display (symbol, 0, col); }; From ca1cd7c5906f3fbb165936f067ab9cf39c5725ac Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 13:45:47 +0100 Subject: [PATCH 114/792] Implement a set of .clear() methods Signed-off-by: Gergely Nagy --- README.md | 7 +++++++ src/Kaleidoscope/LED-AlphaSquare.h | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/README.md b/README.md index 3a46dd76..662de721 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,13 @@ The plugin provides the `AlphaSquare` object, which has the following methods: > Almost the same as the previous function, but instead of a key, it expects a > 4x4 bitmap. +### `.clear(key)`, `.clear(symbol)` +### `.clear(key, col)`, `.clear(symbol, col)` +### `.clear(key, col, row)`, `.clear(symbol, col, row)` + +> Just like the `.display()` counterparts, except these clear the symbol, by +> turning the LED pixels it is made up from, off. + ### `.color` > The color to use to draw the pixels. diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index d6c52818..9517cfb4 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -49,6 +49,14 @@ namespace KaleidoscopePlugins { static void display (uint16_t symbol) { display (symbol, 0, 2); }; static void display (uint16_t symbol, uint8_t col) { display (symbol, 0, col); }; + static void clear (Key key, uint8_t row, uint8_t col) { display (key, row, col, {0, 0, 0}); }; + static void clear (Key key, uint8_t col) { clear (key, 0, col); }; + static void clear (Key key) { clear (key, 0, 2); }; + + static void clear (uint16_t symbol, uint8_t row, uint8_t col) { display (symbol, row, col, {0, 0, 0}); }; + static void clear (uint16_t symbol, uint8_t col) { clear (symbol, 0, col); }; + static void clear (uint16_t symbol) { clear (symbol, 0, 2); }; + static cRGB color; }; }; From 29841ec02e3346cc5c96c407c189ad24a7baad70 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 14:15:30 +0100 Subject: [PATCH 115/792] Add a LEDMode based on AlphaSquare. The new singleton objects implements a LED mode where each pressed key will light up the appropriate symbol on the LEDs, on the side it was pressed on. We use different timers for each half. Signed-off-by: Gergely Nagy --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 4 +- src/Kaleidoscope-LED-AlphaSquare.h | 1 + src/Kaleidoscope/AlphaSquare-Effect.cpp | 76 ++++++++++++++++++++ src/Kaleidoscope/AlphaSquare-Effect.h | 43 +++++++++++ src/Kaleidoscope/LED-AlphaSquare.h | 2 + 5 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 src/Kaleidoscope/AlphaSquare-Effect.cpp create mode 100644 src/Kaleidoscope/AlphaSquare-Effect.h diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index f60f43bc..a31cc7cb 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -75,9 +75,9 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { } void setup () { - Kaleidoscope.setup (KEYMAP_SIZE); + Kaleidoscope.setup (); - Kaleidoscope.use (&LEDControl, &AlphaSquare, &Macros, NULL); + USE_PLUGINS (&AlphaSquare, &AlphaSquareEffect, &Macros); AlphaSquare.color = { 0xcb, 0xc0, 0xff }; } diff --git a/src/Kaleidoscope-LED-AlphaSquare.h b/src/Kaleidoscope-LED-AlphaSquare.h index 5c456b52..b9190e23 100644 --- a/src/Kaleidoscope-LED-AlphaSquare.h +++ b/src/Kaleidoscope-LED-AlphaSquare.h @@ -19,3 +19,4 @@ #pragma once #include +#include diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp new file mode 100644 index 00000000..71824410 --- /dev/null +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -0,0 +1,76 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include + +namespace KaleidoscopePlugins { + namespace LEDEffects { + uint16_t AlphaSquareEffect::length = 200; + uint32_t AlphaSquareEffect::endTimeLeft, AlphaSquareEffect::endTimeRight; + Key AlphaSquareEffect::lastKeyLeft, AlphaSquareEffect::lastKeyRight; + + AlphaSquareEffect::AlphaSquareEffect (void) { + } + + void + AlphaSquareEffect::begin (void) { + Kaleidoscope.useEventHandlerHook (eventHandlerHook); + LEDMode::begin (); + } + + void + AlphaSquareEffect::update (void) { + if (endTimeLeft && millis () > endTimeLeft) { + ::AlphaSquare.clear (lastKeyLeft); + endTimeLeft = 0; + } + if (endTimeRight && millis () > endTimeRight) { + ::AlphaSquare.clear (lastKeyRight); + endTimeRight = 0; + } + } + + Key + AlphaSquareEffect::eventHandlerHook (Key key, byte row, byte col, uint8_t keyState) { + if (keyState & INJECTED) + return key; + + if (key < Key_A || key > Key_0) + return key; + + if (!key_is_pressed (keyState)) + return key; + + uint8_t displayCol = 2; + + if (col < COLS / 2) { + lastKeyLeft = key; + endTimeLeft = millis () + length; + } else { + lastKeyRight = key; + endTimeRight = millis () + length; + displayCol = 10; + } + + ::AlphaSquare.display (key, displayCol); + return key; + } + }; +}; + +KaleidoscopePlugins::LEDEffects::AlphaSquareEffect AlphaSquareEffect; diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h new file mode 100644 index 00000000..7cc0d2f5 --- /dev/null +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -0,0 +1,43 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include +#include + +namespace KaleidoscopePlugins { + namespace LEDEffects { + class AlphaSquareEffect : public LEDMode { + public: + AlphaSquareEffect (void); + + virtual void begin (void) final; + virtual void update (void) final; + + static uint16_t length; + private: + static uint32_t endTimeLeft, endTimeRight; + static Key lastKeyLeft, lastKeyRight; + + static Key eventHandlerHook (Key key, uint8_t row, uint8_t col, uint8_t keyState); + }; + }; +}; + +extern KaleidoscopePlugins::LEDEffects::AlphaSquareEffect AlphaSquareEffect; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index 9517cfb4..a26b5b3a 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +#pragma once + #include #include From 49720378bdb41c65370182a80c4d5bac5e5be115 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 19:58:18 +0100 Subject: [PATCH 116/792] Fix the right hand clearing Signed-off-by: Gergely Nagy --- src/Kaleidoscope/AlphaSquare-Effect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index 71824410..19ceb53c 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -40,7 +40,7 @@ namespace KaleidoscopePlugins { endTimeLeft = 0; } if (endTimeRight && millis () > endTimeRight) { - ::AlphaSquare.clear (lastKeyRight); + ::AlphaSquare.clear (lastKeyRight, 10); endTimeRight = 0; } } From 91380a81c84c2a760b38b3aef8cc309e34d0e6dd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 19:58:42 +0100 Subject: [PATCH 117/792] Clear the previous key when a new one is pressed When we light up a new key, clear the previous one (but only if it isn't the same, to avoid flickering). Signed-off-by: Gergely Nagy --- src/Kaleidoscope/AlphaSquare-Effect.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index 19ceb53c..ba6ee8da 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -57,16 +57,20 @@ namespace KaleidoscopePlugins { return key; uint8_t displayCol = 2; + Key prevKey = lastKeyLeft; if (col < COLS / 2) { lastKeyLeft = key; endTimeLeft = millis () + length; } else { + prevKey = lastKeyRight; lastKeyRight = key; endTimeRight = millis () + length; displayCol = 10; } + if (prevKey != key) + ::AlphaSquare.clear (prevKey, displayCol); ::AlphaSquare.display (key, displayCol); return key; } From 397c08ec9fdce2d63b2157b9ff9332a0e929dbe5 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 20:00:06 +0100 Subject: [PATCH 118/792] Up the effect length to 1 second Signed-off-by: Gergely Nagy --- src/Kaleidoscope/AlphaSquare-Effect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index ba6ee8da..83ba1930 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -20,7 +20,7 @@ namespace KaleidoscopePlugins { namespace LEDEffects { - uint16_t AlphaSquareEffect::length = 200; + uint16_t AlphaSquareEffect::length = 1000; uint32_t AlphaSquareEffect::endTimeLeft, AlphaSquareEffect::endTimeRight; Key AlphaSquareEffect::lastKeyLeft, AlphaSquareEffect::lastKeyRight; From b1c0f1fc1b5db4d3b9c01386044782f205290817 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 11:03:45 +0100 Subject: [PATCH 119/792] Convert the plugin to a LEDMode Fixes #3. Signed-off-by: Gergely Nagy --- README.md | 5 +++-- examples/LED-Stalker/LED-Stalker.ino | 6 ++++-- src/Kaleidoscope/LED-Stalker.cpp | 7 ++----- src/Kaleidoscope/LED-Stalker.h | 5 +++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index b9ef6a71..f03a1e73 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,11 @@ To use the plugin, one needs to include the header, and select the effect. #include void setup () { - Kaleidoscope.setup (KEYMAP_SIZE); + Kaleidoscope.setup (); StalkerEffect.configure (STALKER (Haunt, {0xff, 0, 0})); - Kaleidoscope.use (&StalkerEffect, NULL); + USE_PLUGINS (&StalkerEffect); + StalkerEffect.activate (); } ``` diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index 1f835dcc..e051bfad 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -41,10 +41,12 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { }; void setup () { - Kaleidoscope.setup (KEYMAP_SIZE); + Kaleidoscope.setup (); StalkerEffect.configure (STALKER (BlazingTrail, NULL)); - Kaleidoscope.use (&LEDControl, &StalkerEffect, NULL); + USE_PLUGINS (&StalkerEffect); + + StalkerEffect.activate (); } void loop () { diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 7c0fa655..db067099 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -36,7 +36,7 @@ namespace KaleidoscopePlugins { void StalkerEffect::begin (void) { event_handler_hook_use (eventHandlerHook); - loop_hook_use (loopHook); + LEDMode::begin (); } Key @@ -52,10 +52,7 @@ namespace KaleidoscopePlugins { } void - StalkerEffect::loopHook (bool postClear) { - if (postClear) - return; - + StalkerEffect::update (void) { if (!colorComputer) return; diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 7b670aaf..0f6c41ac 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -23,7 +23,7 @@ namespace KaleidoscopePlugins { namespace LEDEffects { - class StalkerEffect : public KaleidoscopePlugin { + class StalkerEffect : public LEDMode { public: class ColorComputer { public: @@ -33,6 +33,8 @@ namespace KaleidoscopePlugins { StalkerEffect (void); virtual void begin (void) final; + virtual void update (void) final; + static void configure (ColorComputer *colorComputer); static uint16_t stepLength; @@ -42,7 +44,6 @@ namespace KaleidoscopePlugins { static uint8_t map[ROWS][COLS]; static Key eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState); - static void loopHook (bool postClear); }; namespace Stalker { From c01e7d864ae275769839b603efda0a664d015540 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 20:15:41 +0100 Subject: [PATCH 120/792] Add LEDOff too, so turning Stalker off can be tested too Signed-off-by: Gergely Nagy --- examples/LED-Stalker/LED-Stalker.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index e051bfad..1e8df10a 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -18,6 +18,7 @@ #include #include +#include "LED-Off.h" const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED @@ -44,7 +45,7 @@ void setup () { Kaleidoscope.setup (); StalkerEffect.configure (STALKER (BlazingTrail, NULL)); - USE_PLUGINS (&StalkerEffect); + USE_PLUGINS (&LEDOff, &StalkerEffect); StalkerEffect.activate (); } From ebe4edcc1b6728aaf26cbdfd02a32bf7a6307e63 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 20:16:06 +0100 Subject: [PATCH 121/792] Reset the map when switching to the effect Since we keep the eventHandler on at all times, even when we are not active, clear the map when switching to the layer. It's easier this way than trying to turn the eventHandler off. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.cpp | 5 +++++ src/Kaleidoscope/LED-Stalker.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index db067099..10ec5486 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -39,6 +39,11 @@ namespace KaleidoscopePlugins { LEDMode::begin (); } + void + StalkerEffect::init (void) { + memset (map, 0, sizeof (map)); + } + Key StalkerEffect::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) { if (row >= ROWS || col >= COLS) diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 0f6c41ac..fdbeace8 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -33,6 +33,7 @@ namespace KaleidoscopePlugins { StalkerEffect (void); virtual void begin (void) final; + virtual void init (void) final; virtual void update (void) final; static void configure (ColorComputer *colorComputer); From f2ca23adc5b9ec67ba5aaf906843bca2cdd65cc1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 20:17:40 +0100 Subject: [PATCH 122/792] Minor README update Signed-off-by: Gergely Nagy --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f03a1e73..e6efb095 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,10 @@ void setup () { } ``` -It is recommended to place the activation of the plugin (the `Kaleidoscope.use` -call) as early as possible, so the plugin can catch all relevant key presses. -The configuration can happen at any time, but using the `STALKER` macro is -highly recommended. +It is recommended to place the activation of the plugin (the `USE_PLUGINS` call) +as early as possible, so the plugin can catch all relevant key presses. The +configuration can happen at any time, but using the `STALKER` macro is highly +recommended. ## Plugin methods From 10fc73716939caae8b799bd8f6a604737e266e50 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 2 Mar 2017 20:29:58 +0100 Subject: [PATCH 123/792] Start with isLEDChanged set If we start with isLEDChanged unset, then after flashing, the `R0C0` key will remain lit, because we think it is off, while it is not. Setting this flag results in the first update cycle updating everything, no matter what, which is the safest thing we can do. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index f5c04d45..783e36b4 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -3,7 +3,7 @@ KeyboardioScanner Model01::leftHand(0); KeyboardioScanner Model01::rightHand(3); -bool Model01::isLEDChanged; +bool Model01::isLEDChanged = true; static constexpr uint8_t key_led_map[4][16] = { {3,4,11,12,19,20,26,27, 36,37,43,44,51,52,59,60}, From d805d50d228215d4833f86d8259dc5107b359240 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 4 Mar 2017 16:03:16 +0100 Subject: [PATCH 124/792] Only apply the effect, if the LED mode is active When using AlphaSquareEffect, in the event handler hook, return early if the currently active LED mode is not us. Fixes #2. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/AlphaSquare-Effect.cpp | 7 ++++++- src/Kaleidoscope/AlphaSquare-Effect.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index 83ba1930..efbe1d7b 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -23,6 +23,7 @@ namespace KaleidoscopePlugins { uint16_t AlphaSquareEffect::length = 1000; uint32_t AlphaSquareEffect::endTimeLeft, AlphaSquareEffect::endTimeRight; Key AlphaSquareEffect::lastKeyLeft, AlphaSquareEffect::lastKeyRight; + uint8_t AlphaSquareEffect::us; AlphaSquareEffect::AlphaSquareEffect (void) { } @@ -30,7 +31,8 @@ namespace KaleidoscopePlugins { void AlphaSquareEffect::begin (void) { Kaleidoscope.useEventHandlerHook (eventHandlerHook); - LEDMode::begin (); + Kaleidoscope.use (&LEDControl, NULL); + us = LEDControl.mode_add (this); } void @@ -47,6 +49,9 @@ namespace KaleidoscopePlugins { Key AlphaSquareEffect::eventHandlerHook (Key key, byte row, byte col, uint8_t keyState) { + if (LEDControl.get_mode () != us) + return key; + if (keyState & INJECTED) return key; diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 7cc0d2f5..77da2a76 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -34,6 +34,7 @@ namespace KaleidoscopePlugins { private: static uint32_t endTimeLeft, endTimeRight; static Key lastKeyLeft, lastKeyRight; + static uint8_t us; static Key eventHandlerHook (Key key, uint8_t row, uint8_t col, uint8_t keyState); }; From e1e443e42ce62bd943bf044c792fdf141b9f5f32 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 9 Mar 2017 20:38:24 +0100 Subject: [PATCH 125/792] LEDOff: Always set everything to off While it was a neat optimization to only turn LEDs off at init time, that is not enough if there are other plugins in play, that work with the LEDs independently of the active LED mode. Such a plugin is LED-ActiveModColor, which never turns LEDs off, and relies on the LED mode to do that. Since LEDOff did not turn things off on update(), when used together with LED-ActiveModColor, the LEDs under the modifiers stayed active, even after the modifiers went inactive. With this simple change, LEDOff will now update, and the problem's gone. Signed-off-by: Gergely Nagy --- src/LED-Off.cpp | 4 ++++ src/LED-Off.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/LED-Off.cpp b/src/LED-Off.cpp index b2c91c55..fa35f8bd 100644 --- a/src/LED-Off.cpp +++ b/src/LED-Off.cpp @@ -1,3 +1,7 @@ #include "LED-Off.h" +void LEDOff_::update (void) { + LEDControl.set_all_leds_to ({0, 0, 0}); +} + LEDOff_ LEDOff; diff --git a/src/LED-Off.h b/src/LED-Off.h index 6ea7ca6d..92d041e0 100644 --- a/src/LED-Off.h +++ b/src/LED-Off.h @@ -5,6 +5,8 @@ class LEDOff_ : public LEDMode { public: LEDOff_ (void) { }; + + virtual void update (void) final; }; extern LEDOff_ LEDOff; From dbbc80190af5474e435889d739d3917cd6d4c9f9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 10 Mar 2017 22:56:30 +0100 Subject: [PATCH 126/792] Reuse the button bit for WARP_END WARP + Button makes no sense together, so reuse the _BUTTON bit for _WARP_END. This will allow us to use the free'd up bit for something else. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-MouseKeys.cpp | 2 +- src/MouseKeyDefs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 9538e299..50b4203f 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -57,7 +57,7 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY)) return mappedKey; - if (mappedKey.keyCode & KEY_MOUSE_BUTTON) { + if (mappedKey.keyCode & KEY_MOUSE_BUTTON && !(mappedKey.keyCode & KEY_MOUSE_WARP)) { uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; if (key_toggled_on(keyState)) { diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index 237eef24..de4d82c0 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -14,7 +14,7 @@ #define KEY_MOUSE_RIGHT B0001000 #define KEY_MOUSE_BUTTON B0010000 #define KEY_MOUSE_WARP B0100000 -#define KEY_MOUSE_WARP_END B1000000 +#define KEY_MOUSE_WARP_END B0010000 #define Key_mouseWarpNW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } From a3cca30e1f90ef0640b3a797efef9a1202a7082d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 10 Mar 2017 22:58:13 +0100 Subject: [PATCH 127/792] Implement mouse wheel support With these changes, the vertical scrolling of the mouse wheel is now properly supported. It has no acceleration, because the wheel doesn't have one either. It has a delay, however, which I tried to tune to a reasonable speed. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-MouseKeys.cpp | 26 ++++++++++++++++++++++++-- src/Kaleidoscope-MouseKeys.h | 4 ++++ src/MouseKeyDefs.h | 5 +++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 50b4203f..d330c051 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -12,8 +12,24 @@ uint16_t MouseKeys_::speedDelay = 0; uint8_t MouseKeys_::accelSpeed = 1; uint16_t MouseKeys_::accelDelay = 50; +uint8_t MouseKeys_::wheelSpeed = 1; +uint16_t MouseKeys_::wheelDelay = 50; + uint32_t MouseKeys_::accelEndTime; uint32_t MouseKeys_::endTime; +uint32_t MouseKeys_::wheelEndTime; + +void MouseKeys_::scrollWheel(uint8_t keyCode) { + if (millis() < wheelEndTime) + return; + + wheelEndTime = millis() + wheelDelay; + + if (keyCode & KEY_MOUSE_UP) + Mouse.move(0, 0, wheelSpeed); + else if (keyCode & KEY_MOUSE_DOWN) + Mouse.move(0, 0, -wheelSpeed); +} void MouseKeys_::loopHook(bool postClear) { if (postClear) { @@ -69,9 +85,15 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS if (key_toggled_on(keyState)) { endTime = millis() + speedDelay; accelEndTime = millis() + accelDelay; + wheelEndTime = 0; + } + if (key_is_pressed(keyState)) { + if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { + scrollWheel (mappedKey.keyCode); + } + else + mouseMoveIntent |= mappedKey.keyCode; } - if (key_is_pressed(keyState)) - mouseMoveIntent |= mappedKey.keyCode; } else if (key_toggled_on(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { // we don't pass in the left and up values because those are the diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index e94d5ea9..4b309cd7 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -13,12 +13,16 @@ class MouseKeys_ : public KaleidoscopePlugin { static uint16_t speedDelay; static uint8_t accelSpeed; static uint16_t accelDelay; + static uint8_t wheelSpeed; + static uint16_t wheelDelay; private: static uint8_t mouseMoveIntent; static uint32_t endTime; static uint32_t accelEndTime; + static uint32_t wheelEndTime; + static void scrollWheel(uint8_t keyCode); static void loopHook(bool postClear); static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); }; diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index de4d82c0..4b998dc0 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -15,6 +15,7 @@ #define KEY_MOUSE_BUTTON B0010000 #define KEY_MOUSE_WARP B0100000 #define KEY_MOUSE_WARP_END B0010000 +#define KEY_MOUSE_WHEEL B1000000 #define Key_mouseWarpNW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } @@ -32,8 +33,8 @@ #define Key_mouseDnL (Key) { KEY_MOUSE_DOWN | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseDn (Key) { KEY_MOUSE_DOWN, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseDnR (Key) { KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } -#define Key_mouseScrollUp -#define Key_mouseScrollDn +#define Key_mouseScrollUp (Key) { KEY_MOUSE_WHEEL | KEY_MOUSE_UP, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseScrollDn (Key) { KEY_MOUSE_WHEEL | KEY_MOUSE_DOWN, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseScrollL #define Key_mouseScrollR #define Key_mouseBtnL (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_L, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } From e3481be6edc3e45c44b35f7e62428e20a262ed9e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 14 Mar 2017 23:49:07 +0100 Subject: [PATCH 128/792] Fix the `keymap.dump` Focus command The `keymap.dump` command should dump up to `maxLayers` amount of layers, instead of a hardcoded four. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index dce75463..d5c64c06 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -123,7 +123,7 @@ namespace KaleidoscopePlugins { case DUMP: { - for (uint8_t layer = 0; layer < 4; layer++) { + for (uint8_t layer = 0; layer < maxLayers; layer++) { for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t col = 0; col < COLS; col++) { Key k = getKey (layer, row, col); From c0d2c5173006c552e8ce61400cdb02c9c9dab666 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 15 Mar 2017 10:10:55 +0100 Subject: [PATCH 129/792] Rework how the whole thing operates Allows other plugins to request a slice of EEPROM, and returns the starting location of their area. Makes a CRC out of the slice sizes, so that it can detect when the EEPROM and the Sketch become out of sync. Handling that case is left up to the user. As a consequence, we no longer reserve a big chunk of EEPROM for the keymap, that just becomes another slice of it, which can be anywhere. This makes it a bit harder to adjust the size of it, but as far as this plugin goes, playing with the EEPROM layout will usually mean having to update its contents from scratch, anyway. Signed-off-by: Gergely Nagy --- examples/EEPROM-Settings/EEPROM-Settings.ino | 5 +- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 8 +++ src/Kaleidoscope/EEPROM-Settings-Focus.h | 5 +- src/Kaleidoscope/EEPROM-Settings.cpp | 45 ++++++++++--- src/Kaleidoscope/EEPROM-Settings.h | 14 ++-- src/Kaleidoscope/crc.cpp | 71 ++++++++++++++++++++ src/Kaleidoscope/crc.h | 45 +++++++++++++ 7 files changed, 174 insertions(+), 19 deletions(-) create mode 100644 src/Kaleidoscope/crc.cpp create mode 100644 src/Kaleidoscope/crc.h diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino index 08e474d0..7ca1700a 100644 --- a/examples/EEPROM-Settings/EEPROM-Settings.ino +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -50,8 +50,9 @@ void setup () { while (!Serial) { } - Serial.println (EEPROMSettings.isValid () ? "valid EEPROM settings" : "invalid EEPROM settings"); - Serial.println (EEPROMSettings.endOfSettings ()); + Serial.println (EEPROMSettings.isValid () ? F("valid EEPROM settings") : F("invalid EEPROM settings")); + Serial.println (EEPROMSettings.crc (), HEX); + Serial.println (EEPROMSettings.version ()); } void loop () { diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index d7193b14..1be66f6e 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -17,12 +17,14 @@ */ #include +#include "crc.h" namespace FocusHooks { bool settings (const char *command) { enum { ISVALID, GETVERSION, + CRC, } subCommand; if (strncmp_P (command, PSTR ("settings."), 9) != 0) @@ -32,6 +34,8 @@ namespace FocusHooks { subCommand = ISVALID; else if (strcmp_P (command + 9, PSTR ("version")) == 0) subCommand = GETVERSION; + else if (strcmp_P (command + 9, PSTR ("crc")) == 0) + subCommand = CRC; else return false; @@ -41,6 +45,10 @@ namespace FocusHooks { break; case GETVERSION: Serial.println (EEPROMSettings.version ()); + case CRC: + Serial.print (::CRC.crc, HEX); + Serial.print (F("/")); + Serial.println (EEPROMSettings.crc (), HEX); break; } diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index 67667e82..de5af745 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -30,4 +30,7 @@ namespace FocusHooks { "Return whether the EEPROM settings are valid, or not.\n\n" \ "settings.version\n" \ "----------------\n" \ - "Return the version of the EEPROM settings.") + "Return the version of the EEPROM settings.\n\n" \ + "settings.crc\n" \ + "------------\n" \ + "Return the CRC of the settings.") diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index bf221395..1c384596 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -17,41 +17,64 @@ */ #include +#include "crc.h" namespace KaleidoscopePlugins { struct EEPROMSettings::settings EEPROMSettings::settings; bool EEPROMSettings::_isValid; + bool EEPROMSettings::sealed; + uint16_t EEPROMSettings::nextStart = sizeof (EEPROMSettings::settings); EEPROMSettings::EEPROMSettings (void) { } void EEPROMSettings::begin (void) { - _isValid = true; EEPROM.get (0, settings); + } + + bool + EEPROMSettings::isValid (void) { + return _isValid; + } + + uint16_t + EEPROMSettings::crc (void) { + if (sealed) + return settings.crc; + return 0; + } + + void + EEPROMSettings::seal (void) { + sealed = true; + + CRC.finalize (); if (settings.magic[0] != 'K' || settings.magic[1] != 'S') { settings.magic[0] = 'K'; settings.magic[1] = 'S'; - settings.endOfSettings = EEPROM_SETTINGS_RESERVED - 1; + settings.version = 0; + settings.crc = CRC.crc; return update (); } - if (settings.endOfSettings != EEPROM_SETTINGS_RESERVED - 1) + if (settings.crc != CRC.crc) _isValid = false; } uint16_t - EEPROMSettings::endOfSettings (void) { - if (!isValid ()) + EEPROMSettings::requestSlice (uint16_t size) { + if (sealed) return 0; - return settings.endOfSettings; - } - bool - EEPROMSettings::isValid (void) { - return _isValid; + uint16_t start = nextStart; + nextStart += size; + + CRC.update ((const void *)&size, sizeof (size)); + + return start; } void @@ -61,6 +84,8 @@ namespace KaleidoscopePlugins { void EEPROMSettings::update (void) { + settings.crc = CRC.crc; + EEPROM.put (0, settings); _isValid = true; } diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index cdaf9a7a..02cc7d54 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -21,10 +21,6 @@ #include #include -#ifndef EEPROM_SETTINGS_RESERVED -#define EEPROM_SETTINGS_RESERVED ((E2END + 1) / 2) -#endif - namespace KaleidoscopePlugins { class EEPROMSettings : public KaleidoscopePlugin { public: @@ -32,19 +28,25 @@ namespace KaleidoscopePlugins { virtual void begin (void) final; - static uint16_t endOfSettings (void); static void update (void); static bool isValid (void); static void invalidate (void); static uint8_t version (void); static void version (uint8_t ver); + static uint16_t requestSlice (uint16_t size); + static void seal (void); + static uint16_t crc (void); + private: + static uint16_t nextStart; static bool _isValid; + static bool sealed; + static struct settings { char magic[2]; uint8_t version; - uint16_t endOfSettings; + uint16_t crc; } settings; }; }; diff --git a/src/Kaleidoscope/crc.cpp b/src/Kaleidoscope/crc.cpp new file mode 100644 index 00000000..f8403548 --- /dev/null +++ b/src/Kaleidoscope/crc.cpp @@ -0,0 +1,71 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + * + * Originally generated by pycrc v0.9, https://pycrc.org + * + * using the configuration: + * Width = 16 + * Poly = 0x8005 + * Xor_In = 0x0000 + * ReflectIn = True + * Xor_Out = 0x0000 + * ReflectOut = True + * Algorithm = bit-by-bit-fast + */ + +#include "crc.h" + +void +CRC_::reflect (uint8_t len) { + uint8_t i; + uint16_t newCRC; + + newCRC = crc & 0x01; + for (i = 1; i < len; i++) { + crc >>= 1; + newCRC = (newCRC << 1) | (crc & 0x01); + } + + crc = newCRC; +} + +void +CRC_::update (const void *data, uint8_t len) +{ + const uint8_t *d = (const uint8_t *)data; + uint8_t i; + bool bit; + uint8_t c; + + while (len--) { + c = *d++; + for (i = 0x01; i & 0xff; i <<= 1) { + bit = crc & 0x8000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x8005; + } + } + crc &= 0xffff; + } + crc &= 0xffff; +} + +CRC_ CRC; diff --git a/src/Kaleidoscope/crc.h b/src/Kaleidoscope/crc.h new file mode 100644 index 00000000..f3db42a9 --- /dev/null +++ b/src/Kaleidoscope/crc.h @@ -0,0 +1,45 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + * + * Originally generated by pycrc v0.9, https://pycrc.org + * + * using the configuration: + * Width = 16 + * Poly = 0x8005 + * Xor_In = 0x0000 + * ReflectIn = True + * Xor_Out = 0x0000 + * ReflectOut = True + * Algorithm = bit-by-bit-fast + */ + +#pragma once + +#include + +class CRC_ { + public: + uint16_t crc = 0; + + CRC_ (void) {}; + + void update (const void *data, uint8_t len); + void finalize (void) { reflect (16); }; + void reflect (uint8_t len); +}; + +extern CRC_ CRC; From 4e1a5791364624603f4d56cbd8f854994f7fb74f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 15 Mar 2017 10:15:41 +0100 Subject: [PATCH 130/792] Do not treat 0xffff as NoKey We expect the keymap in EEPROM to be set up by the time we get to use it, instead of having uninitialized EEPROM there. So remove the special handling of 0xffff. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index d5c64c06..ea3536b4 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -47,9 +47,6 @@ namespace KaleidoscopePlugins { key.flags = EEPROM.read (keymapBase + pos); key.keyCode = EEPROM.read (keymapBase + pos + 1); - if (key.raw == 0xffff) - return Key_NoKey; - return key; } From 5a7601bb300a1e6edde869447a67bef443a2c32b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 15 Mar 2017 10:17:00 +0100 Subject: [PATCH 131/792] Update to use the new EEPROM-Settings library Signed-off-by: Gergely Nagy --- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 4 ++++ src/Kaleidoscope/EEPROM-Keymap.cpp | 8 +++++--- src/Kaleidoscope/EEPROM-Keymap.h | 5 ++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index 9bdd3656..f1127a23 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -48,11 +48,15 @@ void setup () { USE_PLUGINS (&EEPROMKeymap, &Focus); + Focus.addHook (FOCUS_HOOK_SETTINGS); Focus.addHook (FOCUS_HOOK_KEYMAP); Focus.addHook (FOCUS_HOOK_HELP); Focus.addHook (FOCUS_HOOK_VERSION); Layer.getKey = EEPROMKeymap.getKey; + + EEPROMKeymap.reserveSpace (2); + EEPROMSettings.seal (); } void loop () { diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index ea3536b4..91a42d49 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -29,10 +29,12 @@ namespace KaleidoscopePlugins { void EEPROMKeymap::begin (void) { USE_PLUGINS (&::EEPROMSettings); + } - uint16_t layerSize = ROWS * COLS * 2; - maxLayers = (E2END - ::EEPROMSettings.endOfSettings ()) / layerSize; - keymapBase = ::EEPROMSettings.endOfSettings () + 1; + void + EEPROMKeymap::reserveSpace (uint8_t layers) { + maxLayers = layers; + keymapBase = ::EEPROMSettings.requestSlice (maxLayers * ROWS * COLS * 2); } Key diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 83809a89..14b5493c 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -28,8 +28,11 @@ namespace KaleidoscopePlugins { virtual void begin (void) final; - static Key getKey (uint8_t layer, byte row, byte col); + static void reserveSpace (uint8_t layers); static uint16_t base (void); + + static Key getKey (uint8_t layer, byte row, byte col); + static bool focusKeymap (const char *command); private: From b4759decf2b844b2cc087770ded698a673655c94 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 17 Mar 2017 19:30:14 +0100 Subject: [PATCH 132/792] Optional, extra symbols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the Kaleidoscope::AlphaSquareSymbols namespace, for symbols that fall outside of the normal alphanumerics. The first such symbol is `λ`. Fixes #3. Signed-off-by: Gergely Nagy --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 18 ++++++++++++ src/Kaleidoscope-LED-AlphaSquare.h | 1 + src/Kaleidoscope/AlphaSquare-Symbols.h | 31 ++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 src/Kaleidoscope/AlphaSquare-Symbols.h diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index a31cc7cb..24cdf9bf 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -68,6 +68,24 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { } delay (100); } + + LEDControl.set_all_leds_to (0, 0, 0); + LEDControl.led_sync (); + delay (100); + for (uint8_t step = 0; step <= 0xf0; step += 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); + AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); + delay (10); + } + for (uint8_t step = 0xff; step >= 8; step -= 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); + AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); + delay (10); + } + delay (100); + } LEDControl.set_all_leds_to (0, 0, 0); diff --git a/src/Kaleidoscope-LED-AlphaSquare.h b/src/Kaleidoscope-LED-AlphaSquare.h index b9190e23..160d4eb3 100644 --- a/src/Kaleidoscope-LED-AlphaSquare.h +++ b/src/Kaleidoscope-LED-AlphaSquare.h @@ -20,3 +20,4 @@ #include #include +#include diff --git a/src/Kaleidoscope/AlphaSquare-Symbols.h b/src/Kaleidoscope/AlphaSquare-Symbols.h new file mode 100644 index 00000000..52133e27 --- /dev/null +++ b/src/Kaleidoscope/AlphaSquare-Symbols.h @@ -0,0 +1,31 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include + +namespace KaleidoscopePlugins { + namespace AlphaSquareSymbols { + /* λ */ + static constexpr uint16_t Lambda = SYM4x4(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 1, 1, 0, + 1, 0, 0, 1); + }; +}; From ff29bce43ec93459eb42657c82fea4ac6485c005 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 17 Mar 2017 19:49:55 +0100 Subject: [PATCH 133/792] Focus: Add an EEPROM dump, and an upload command Fixes keyboardio/Kaleidoscope-Focus#1. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 37 ++++++++++++++++++++++ src/Kaleidoscope/EEPROM-Settings-Focus.h | 9 ++++++ 2 files changed, 46 insertions(+) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 1be66f6e..dd683ae7 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -56,4 +56,41 @@ namespace FocusHooks { return true; } + + bool eeprom (const char *command) { + enum { + DUMP, + UPLOAD, + } subCommand; + + if (strcmp_P (command, PSTR ("eeprom.dump")) == 0) + subCommand = DUMP; + else if (strcmp_P (command, PSTR ("eeprom.upload")) == 0) + subCommand = UPLOAD; + else + return false; + + switch (subCommand) { + case DUMP: + for (uint16_t i = 0; i < EEPROM.length (); i++) { + uint8_t d = EEPROM[i]; + if (d < 16) + Serial.print (0); + Serial.print (d, HEX); + Serial.print (F(" ")); + if ((i + 1) % 32 == 0) + Serial.println (); + } + break; + case UPLOAD: + for (uint16_t i = 0; i < EEPROM.length (); i++) { + uint8_t d = Serial.parseInt (); + EEPROM.update (i, d); + } + break; + } + + Serial.read (); + return true; + } }; diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index de5af745..72e038c8 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -22,6 +22,7 @@ namespace FocusHooks { bool settings (const char *command); + bool eeprom (const char *command); }; #define FOCUS_HOOK_SETTINGS FOCUS_HOOK(FocusHooks::settings, \ @@ -34,3 +35,11 @@ namespace FocusHooks { "settings.crc\n" \ "------------\n" \ "Return the CRC of the settings.") + +#define FOCUS_HOOK_EEPROM FOCUS_HOOK(FocusHooks::eeprom, \ + "eeprom.dump\n" \ + "-----------\n" \ + "Dump the contents of EEPROM.\n\n" \ + "eeprom.upload BYTES...\n" \ + "----------------------\n" \ + "Upload `BYTES` to EEPROM.") From 67262add72e85069bd4ce98f2df4d354998ddb97 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 18 Mar 2017 11:01:23 +0100 Subject: [PATCH 134/792] Don't use floats for the Haunt effect Fixes #7. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.cpp | 18 +++++++----------- src/Kaleidoscope/LED-Stalker.h | 3 +-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 10ec5486..1f3a7fa6 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -92,22 +92,18 @@ namespace KaleidoscopePlugins { namespace Stalker { + cRGB Haunt::highlightColor; + // Haunt - float Haunt::mb; - float Haunt::mg; - float Haunt::mr; - - Haunt::Haunt (const cRGB highlightColor) { - mb = highlightColor.b / 255.0; - mg = highlightColor.g / 255.0; - mr = highlightColor.r / 255.0; + Haunt::Haunt (const cRGB highlightColor_) { + highlightColor = highlightColor_; } cRGB Haunt::compute (uint8_t step) { - cRGB color = {(uint8_t)min(step * mb, 255), - (uint8_t)min(step * mg, 255), - (uint8_t)min(step * mr, 255)}; + cRGB color = CRGB((uint8_t)min(step * highlightColor.r / 255, 255), + (uint8_t)min(step * highlightColor.g / 255, 255), + (uint8_t)min(step * highlightColor.b / 255, 255)); return color; } diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index fdbeace8..b75e28ce 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -56,9 +56,8 @@ namespace KaleidoscopePlugins { Haunt (void *) : Haunt () {}; virtual cRGB compute (uint8_t step) final; - private: - static float mr, mg, mb; + static cRGB highlightColor; }; class BlazingTrail : public StalkerEffect::ColorComputer { From ff46d8eede19d707bfeb45df313eb89657db26a4 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 19 Mar 2017 11:11:32 +0100 Subject: [PATCH 135/792] Use the new Focus helpers Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index dd683ae7..3051e472 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "crc.h" namespace FocusHooks { @@ -41,7 +42,8 @@ namespace FocusHooks { switch (subCommand) { case ISVALID: - Serial.println (EEPROMSettings.isValid () ? F("yes") : F("no")); + Focus.printBool (EEPROMSettings.isValid ()); + Serial.println (); break; case GETVERSION: Serial.println (EEPROMSettings.version ()); @@ -74,10 +76,8 @@ namespace FocusHooks { case DUMP: for (uint16_t i = 0; i < EEPROM.length (); i++) { uint8_t d = EEPROM[i]; - if (d < 16) - Serial.print (0); - Serial.print (d, HEX); - Serial.print (F(" ")); + Focus.printNumber (d); + Focus.printSpace (); if ((i + 1) % 32 == 0) Serial.println (); } From a747d6c8cf0a496cd291d2831d43f0d12278128a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 19 Mar 2017 11:12:12 +0100 Subject: [PATCH 136/792] Use the new Focus helpers Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 91a42d49..f80da400 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -18,6 +18,7 @@ #include #include +#include namespace KaleidoscopePlugins { uint16_t EEPROMKeymap::keymapBase; @@ -75,18 +76,9 @@ namespace KaleidoscopePlugins { void EEPROMKeymap::printKey (Key k) { - if (k.flags < 10) - Serial.print (F(" ")); - if (k.flags < 100) - Serial.print (F(" ")); - Serial.print (k.flags); - Serial.print (F(" ")); - - if (k.keyCode < 10) - Serial.print (F(" ")); - if (k.keyCode < 100) - Serial.print (F(" ")); - Serial.print (k.keyCode); + ::Focus.printNumber (k.flags); + ::Focus.printSpace (); + ::Focus.printNumber (k.keyCode); } bool From 035c95a20793f904933fd5166bb1fe33bbde952b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 19 Mar 2017 11:18:33 +0100 Subject: [PATCH 137/792] No need to consume the trailing \n anymore Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index f80da400..41efc99f 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -149,8 +149,6 @@ namespace KaleidoscopePlugins { } - Serial.read (); - return true; } From 3648c6687cc1796a0eb8748aa6b842ccafee4386 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 19 Mar 2017 11:18:57 +0100 Subject: [PATCH 138/792] No need to consume the trailing \n anymore Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 3051e472..84b58e55 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -54,8 +54,6 @@ namespace FocusHooks { break; } - Serial.read (); - return true; } @@ -90,7 +88,6 @@ namespace FocusHooks { break; } - Serial.read (); return true; } }; From 0c387ce1c3edf221c1db0185165da21238431c04 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 19 Mar 2017 11:27:21 +0100 Subject: [PATCH 139/792] Focus: Lift out keymap.transfer The keymap.transfer command is only useful if we have both PROGMEM & EEPROM keymaps, which will rarely be a case, and likely only temporarily, too. As such, lift that out of the `focusKeymap` function, into its own. This makes the command optional, and can save us some 140 bytes of program space (even more if documentation is enabled). Signed-off-by: Gergely Nagy --- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 1 + src/Kaleidoscope/EEPROM-Keymap-Focus.h | 11 +++++---- src/Kaleidoscope/EEPROM-Keymap.cpp | 30 ++++++++++++------------ src/Kaleidoscope/EEPROM-Keymap.h | 1 + 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index f1127a23..30d39015 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -50,6 +50,7 @@ void setup () { Focus.addHook (FOCUS_HOOK_SETTINGS); Focus.addHook (FOCUS_HOOK_KEYMAP); + Focus.addHook (FOCUS_HOOK_KEYMAP_TRANSFER); Focus.addHook (FOCUS_HOOK_HELP); Focus.addHook (FOCUS_HOOK_VERSION); diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Focus.h index 72103329..39ffbdc0 100644 --- a/src/Kaleidoscope/EEPROM-Keymap-Focus.h +++ b/src/Kaleidoscope/EEPROM-Keymap-Focus.h @@ -29,7 +29,10 @@ "-------------------------------\n" \ "Uploads a new keymap to EEPROM." \ "Starts at layer 0, row 0, column 0, " \ - "and continues as long as there is data on the line.\n\n" \ - "keymap.transfer layer\n" \ - "---------------------\n" \ - "Transfers the `layer` from PROGMEM to EEPROM.") + "and continues as long as there is data on the line.") + + +#define FOCUS_HOOK_KEYMAP_TRANSFER FOCUS_HOOK(EEPROMKeymap.focusKeymapTransfer, \ + "keymap.transfer layer\n" \ + "---------------------\n" \ + "Transfers the `layer` from PROGMEM to EEPROM.") diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 41efc99f..126c0e77 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -86,7 +86,6 @@ namespace KaleidoscopePlugins { enum { UPLOAD, DUMP, - TRANSFER, } subCommand; if (strncmp_P (command, PSTR ("keymap."), 7) != 0) @@ -96,8 +95,6 @@ namespace KaleidoscopePlugins { subCommand = UPLOAD; else if (strcmp_P (command + 7, PSTR ("dump")) == 0) subCommand = DUMP; - else if (strcmp_P (command + 7, PSTR ("transfer")) == 0) - subCommand = TRANSFER; else return false; @@ -131,22 +128,25 @@ namespace KaleidoscopePlugins { break; } - case TRANSFER: - { - uint8_t layer = Serial.parseInt (); + } - for (uint8_t row = 0; row < ROWS; row++) { - for (uint8_t col = 0; col < COLS; col++) { - Key k = Layer.getKeyFromPROGMEM (layer, row, col); - uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); + return true; + } - updateKey (pos, k); - } - } + bool + EEPROMKeymap::focusKeymapTransfer (const char *command) { + if (strcmp_P (command, PSTR ("keymap.transfer")) != 0) + return false; - break; - } + uint8_t layer = Serial.parseInt (); + + for (uint8_t row = 0; row < ROWS; row++) { + for (uint8_t col = 0; col < COLS; col++) { + Key k = Layer.getKeyFromPROGMEM (layer, row, col); + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); + updateKey (pos, k); + } } return true; diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 14b5493c..02043a55 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -34,6 +34,7 @@ namespace KaleidoscopePlugins { static Key getKey (uint8_t layer, byte row, byte col); static bool focusKeymap (const char *command); + static bool focusKeymapTransfer (const char *command); private: static uint16_t keymapBase; From 39e3c4bae070be89eb24bdffc366065146fdc8dd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Mar 2017 08:33:01 +0100 Subject: [PATCH 140/792] BlazingTrail: Make sure the g component is not junk Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 1f3a7fa6..32aa02b7 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -116,6 +116,7 @@ namespace KaleidoscopePlugins { BlazingTrail::compute (uint8_t step) { cRGB color; + color.g = 0; color.b = 0; color.r = step; From b766ad6c4d4dc8a7394b3bbd7744197d9199f926 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Mar 2017 12:36:59 +0100 Subject: [PATCH 141/792] README: Add a "Dependencies" section Signed-off-by: Gergely Nagy --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index f7bda3ef..2c6c1285 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,11 @@ The plugin provides the `EEPROMKeymap` object, which has the following methods: **TODO** +## Dependencies + +* [Kaleidoscope-EEPROM-Settings](https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings) +* [Kaleidoscope-Focus](https://github.com/keyboardio/Kaleidoscope-Focus) + ## Further reading Starting from the [example][plugin:example] is the recommended way of getting From 7884289e594bc8785580da2de97f1ebbeb687540 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Mar 2017 12:42:42 +0100 Subject: [PATCH 142/792] README: Add a "Dependencies" section Signed-off-by: Gergely Nagy --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f4b5b59c..ee2e3fc3 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,10 @@ The plugin provides the `EEPROMSettings` object, which has the following methods **TODO** +## Dependencies + +* [Kaleidoscope-Focus](https://github.com/keyboardio/Kaleidoscope-Focus) + ## Further reading Starting from the [example][plugin:example] is the recommended way of getting From 3941d98a7b92fd412958d31d8d32e837727cf36a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Mar 2017 12:50:24 +0100 Subject: [PATCH 143/792] README: Add a "Dependencies" section Signed-off-by: Gergely Nagy --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 662de721..b2513975 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,10 @@ The plugin provides the `AlphaSquare` object, which has the following methods: > values, a 4x4 square of zeroes and ones. Zeroes are transparent pixels, ones > will be colored. +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) + ## Further reading Starting from the [example][plugin:example] is the recommended way of getting From bc201e566548559ab3a4e577eaabaae7019eda6f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Mar 2017 12:51:48 +0100 Subject: [PATCH 144/792] README: Add a "Dependencies" section Signed-off-by: Gergely Nagy --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index e6efb095..aba5be07 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,10 @@ The plugin provides the following effects: > A blazing trail of fire will follow our fingers! +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) + ## Further reading Starting from the [example][plugin:example] is the recommended way of getting From 5eb702ce1fd56e1fd065bf8b2a28662e41cd0dd9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Mar 2017 20:40:06 +0100 Subject: [PATCH 145/792] Delegate stepping to the computer functions, and fix BlazingTrail Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.cpp | 60 ++++++++++++++++++++------------ src/Kaleidoscope/LED-Stalker.h | 6 ++-- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 32aa02b7..f7db1aa5 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -17,6 +17,7 @@ */ #include +#include namespace KaleidoscopePlugins { namespace LEDEffects { @@ -65,20 +66,15 @@ namespace KaleidoscopePlugins { for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { - if (map[r][c]) - LEDControl.led_set_crgb_at (r, c, colorComputer->compute (map[r][c])); + uint8_t step = map[r][c]; + if (step) { + LEDControl.led_set_crgb_at (r, c, colorComputer->compute (&step)); + } bool wasZero = (map[r][c] == 0); if (timeOut) { - if (map[r][c] >= 0xf0) - map[r][c]--; - else if (map[r][c] >= 0x40) - map[r][c] -= 16; - else if (map[r][c] >= 32) - map[r][c] -= 32; - else - map[r][c] = 0; + map[r][c] = step; } if (!wasZero && !map[r][c]) @@ -100,10 +96,19 @@ namespace KaleidoscopePlugins { } cRGB - Haunt::compute (uint8_t step) { - cRGB color = CRGB((uint8_t)min(step * highlightColor.r / 255, 255), - (uint8_t)min(step * highlightColor.g / 255, 255), - (uint8_t)min(step * highlightColor.b / 255, 255)); + Haunt::compute (uint8_t *step) { + cRGB color = CRGB((uint8_t)min(*step * highlightColor.r / 255, 255), + (uint8_t)min(*step * highlightColor.g / 255, 255), + (uint8_t)min(*step * highlightColor.b / 255, 255)); + + if (*step >= 0xf0) + *step -= 1; + else if (*step >= 0x40) + *step -= 16; + else if (*step >= 32) + *step -= 32; + else + *step = 0; return color; } @@ -113,18 +118,27 @@ namespace KaleidoscopePlugins { } cRGB - BlazingTrail::compute (uint8_t step) { + BlazingTrail::compute (uint8_t *step) { cRGB color; - color.g = 0; - color.b = 0; - color.r = step; + if (*step >= 0xff - 30) { + color = hsv_to_rgb (0xff - *step, 255, 255); + } + else { + color = hsv_to_rgb (30, 255, 255); + + color.r = min(*step * color.r / 255, 255); + color.g = min(*step * color.g / 255, 255); + } - if (step >= 0xf0) { - } else if (step >= 0x80) { - color.g = 0xa0 - step / 2; - } else - color.g = step; + if (*step >= 0xf0 - 30) + *step -= 1; + else if (*step >= 0x40) + *step -= 16; + else if (*step >= 32) + *step -= 32; + else + *step = 0; return color; } diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index b75e28ce..89c9ab3c 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -27,7 +27,7 @@ namespace KaleidoscopePlugins { public: class ColorComputer { public: - virtual cRGB compute (uint8_t step) = 0; + virtual cRGB compute (uint8_t *step) = 0; }; StalkerEffect (void); @@ -55,7 +55,7 @@ namespace KaleidoscopePlugins { Haunt (void) : Haunt ({0x40, 0x80, 0x80}) {}; Haunt (void *) : Haunt () {}; - virtual cRGB compute (uint8_t step) final; + virtual cRGB compute (uint8_t *step) final; private: static cRGB highlightColor; }; @@ -64,7 +64,7 @@ namespace KaleidoscopePlugins { public: BlazingTrail (...); - virtual cRGB compute (uint8_t step) final; + virtual cRGB compute (uint8_t *step) final; }; }; From 2fbeb322d8c047c95b73641e122f4ccd538c73fc Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 20 Mar 2017 16:20:30 -0700 Subject: [PATCH 146/792] Switch from a hardcoded structure that's in BGR order to using a cRGB and getting our color (red) correct --- src/Kaleidoscope-Numlock.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index e25b7494..253cee89 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -7,6 +7,8 @@ uint8_t NumLock_::previousLEDMode; uint8_t NumLock_::us; bool NumLock_::isActive; byte NumLock_::row = 255, NumLock_::col = 255; +cRGB numpad_color; + NumLock_::NumLock_ (void) { } @@ -14,6 +16,7 @@ NumLock_::NumLock_ (void) { void NumLock_::begin (void) { us = LEDControl.mode_add (this); + numpad_color.r=255; } void @@ -32,7 +35,7 @@ NumLock_::update (void) { if (k.raw < Key_NumLock.raw || k.raw > Key_KeypadDot.raw) continue; - LEDControl.led_set_crgb_at(r, c, {255, 0, 0}); + LEDControl.led_set_crgb_at(r, c, numpad_color); } } From 0f3dddae98bd4637d4ea055d5cd63a6c9f90446d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 21 Mar 2017 12:19:56 +0100 Subject: [PATCH 147/792] Make the `updateKey` method public It can be useful for other plugins that want to update the EEPROM keymap. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 02043a55..f9995d71 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -36,11 +36,12 @@ namespace KaleidoscopePlugins { static bool focusKeymap (const char *command); static bool focusKeymapTransfer (const char *command); + static void updateKey (uint16_t basePos, Key key); + private: static uint16_t keymapBase; static uint8_t maxLayers; - static void updateKey (uint16_t basePos, Key key); static Key parseKey (void); static void printKey (Key key); }; From 379a2d483b46a8a13307a9c7d6420ed12867e0b0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Mar 2017 08:22:13 +0100 Subject: [PATCH 148/792] Add a `getKeyOverride` method This method uses the EEPROM only to augment the PROGMEM keymap: if EEPROM is transparent, then PROGMEM is used. As such, the keymap in EEPROM is only an overlay in this case. Signed-off-by: Gergely Nagy --- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 4 ++-- src/Kaleidoscope/EEPROM-Keymap.cpp | 10 ++++++++++ src/Kaleidoscope/EEPROM-Keymap.h | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index 30d39015..b2d8be40 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -54,9 +54,9 @@ void setup () { Focus.addHook (FOCUS_HOOK_HELP); Focus.addHook (FOCUS_HOOK_VERSION); - Layer.getKey = EEPROMKeymap.getKey; + Layer.getKey = EEPROMKeymap.getKeyOverride; - EEPROMKeymap.reserveSpace (2); + EEPROMKeymap.reserveSpace (1); EEPROMSettings.seal (); } diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 126c0e77..2e095fff 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -53,6 +53,16 @@ namespace KaleidoscopePlugins { return key; } + Key + EEPROMKeymap::getKeyOverride (uint8_t layer, byte row, byte col) { + Key key; + + key = getKey (layer, row, col); + if (key == Key_Transparent) + key = Layer.getKeyFromPROGMEM (layer, row, col); + return key; + } + uint16_t EEPROMKeymap::base (void) { return keymapBase; diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index f9995d71..65574d23 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -32,6 +32,7 @@ namespace KaleidoscopePlugins { static uint16_t base (void); static Key getKey (uint8_t layer, byte row, byte col); + static Key getKeyOverride (uint8_t layer, byte row, byte col); static bool focusKeymap (const char *command); static bool focusKeymapTransfer (const char *command); From 55b035be86f835222a7ecf69b6bb270474d5af9f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 27 Mar 2017 10:40:27 +0200 Subject: [PATCH 149/792] Introduce a way to describe a tap step Instead of having to use a keydown & keyup step each time we tap a key, use a combined event that does both. While this adds a tiny bit of code to `Macros.play`, if our macros have many key taps (which by and large the most common thing), we save a lot more. Three bytes per tap! Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 8 ++++++++ src/MacroSteps.h | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index d9a271b2..128faf5c 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -37,6 +37,14 @@ void Macros_::play(const macro_t *macro_p) { handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); Keyboard.sendReport(); break; + case MACRO_ACTION_STEP_TAP: + key.flags = pgm_read_byte(macro_p++); + key.keyCode = pgm_read_byte(macro_p++); + handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); + Keyboard.sendReport(); + handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); + Keyboard.sendReport(); + break; case END: default: return; diff --git a/src/MacroSteps.h b/src/MacroSteps.h index 2bef68cb..9a0fd379 100644 --- a/src/MacroSteps.h +++ b/src/MacroSteps.h @@ -7,6 +7,7 @@ typedef enum { MACRO_ACTION_STEP_WAIT, MACRO_ACTION_STEP_KEYDOWN, MACRO_ACTION_STEP_KEYUP, + MACRO_ACTION_STEP_TAP } MacroActionStepType; typedef uint8_t macro_t; @@ -21,6 +22,6 @@ typedef uint8_t macro_t; #define D(k) Dr(Key_ ## k) #define Ur(k) MACRO_ACTION_STEP_KEYUP, (k).flags, (k).keyCode #define U(k) Ur(Key_ ## k) -#define Tr(k) Dr(k), Ur(k) -#define T(k) D(k), U(k) +#define Tr(k) MACRO_ACTION_STEP_TAP, (k).flags, (k).keyCode +#define T(k) Tr(Key_ ## k) #define END MACRO_ACTION_END From f86700bdc3181051e7e28390b2dfed0a9466c8af Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 27 Mar 2017 10:53:09 +0200 Subject: [PATCH 150/792] Introduce new step variants The new step variants only use a one-byte argument, the `keyCode` part of a `Key`, and they implicitly set flags to zero. This allows us to make macros even more compact, by not having to use the flags when they are zero anyway. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 22 ++++++++++++++++++++++ src/MacroSteps.h | 13 ++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 128faf5c..15f31adf 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -45,6 +45,28 @@ void Macros_::play(const macro_t *macro_p) { handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); Keyboard.sendReport(); break; + + case MACRO_ACTION_STEP_KEYCODEDOWN: + key.flags = 0; + key.keyCode = pgm_read_byte(macro_p++); + handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); + Keyboard.sendReport(); + break; + case MACRO_ACTION_STEP_KEYCODEUP: + key.flags = 0; + key.keyCode = pgm_read_byte(macro_p++); + handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); + Keyboard.sendReport(); + break; + case MACRO_ACTION_STEP_TAPCODE: + key.flags = 0; + key.keyCode = pgm_read_byte(macro_p++); + handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); + Keyboard.sendReport(); + handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); + Keyboard.sendReport(); + break; + case END: default: return; diff --git a/src/MacroSteps.h b/src/MacroSteps.h index 9a0fd379..7b92f526 100644 --- a/src/MacroSteps.h +++ b/src/MacroSteps.h @@ -5,9 +5,14 @@ typedef enum { MACRO_ACTION_STEP_INTERVAL, MACRO_ACTION_STEP_WAIT, + MACRO_ACTION_STEP_KEYDOWN, MACRO_ACTION_STEP_KEYUP, - MACRO_ACTION_STEP_TAP + MACRO_ACTION_STEP_TAP, + + MACRO_ACTION_STEP_KEYCODEDOWN, + MACRO_ACTION_STEP_KEYCODEUP, + MACRO_ACTION_STEP_TAPCODE, } MacroActionStepType; typedef uint8_t macro_t; @@ -18,10 +23,16 @@ typedef uint8_t macro_t; #define I(n) MACRO_ACTION_STEP_INTERVAL, n #define W(n) MACRO_ACTION_STEP_WAIT, n + #define Dr(k) MACRO_ACTION_STEP_KEYDOWN, (k).flags, (k).keyCode #define D(k) Dr(Key_ ## k) #define Ur(k) MACRO_ACTION_STEP_KEYUP, (k).flags, (k).keyCode #define U(k) Ur(Key_ ## k) #define Tr(k) MACRO_ACTION_STEP_TAP, (k).flags, (k).keyCode #define T(k) Tr(Key_ ## k) + +#define Dc(k) MACRO_ACTION_STEP_KEYCODEDOWN, (Key_ ## k).keyCode +#define Uc(k) MACRO_ACTION_STEP_KEYCODEUP, (Key_ ## k).keyCode +#define Tc(k) MACRO_ACTION_STEP_TAPCODE, (Key_ ## k).keyCode + #define END MACRO_ACTION_END From 7418eb92b6d87f80393ab61931c7694f7c3e2df5 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 27 Mar 2017 11:03:02 +0200 Subject: [PATCH 151/792] Code optimalization Lift out the keyCode reading, event handling, and report sending into a small helper function. Pretty much the same code has been called in a number of different cases, lifting them out into a common helper improves clarity, and reduces the size of the code, too. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 54 +++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 15f31adf..bcc9b7b2 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -7,10 +7,25 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { byte Macros_::row, Macros_::col; +static void readAndPlay (const macro_t *macro_p, uint8_t flags, uint8_t keyStates) { + Key key; + key.flags = flags; + key.keyCode = pgm_read_byte(macro_p++); + + if (keyStates & IS_PRESSED) { + handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); + Keyboard.sendReport(); + } + if (keyStates & WAS_PRESSED) { + handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); + Keyboard.sendReport(); + } +} + void Macros_::play(const macro_t *macro_p) { macro_t macro = END; uint8_t interval = 0; - Key key; + uint8_t flags; if (!macro_p) return; @@ -26,45 +41,26 @@ void Macros_::play(const macro_t *macro_p) { break; } case MACRO_ACTION_STEP_KEYDOWN: - key.flags = pgm_read_byte(macro_p++); - key.keyCode = pgm_read_byte(macro_p++); - handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); - Keyboard.sendReport(); + flags = pgm_read_byte(macro_p++); + readAndPlay (macro_p++, flags, IS_PRESSED); break; case MACRO_ACTION_STEP_KEYUP: - key.flags = pgm_read_byte(macro_p++); - key.keyCode = pgm_read_byte(macro_p++); - handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); - Keyboard.sendReport(); + flags = pgm_read_byte(macro_p++); + readAndPlay (macro_p++, flags, WAS_PRESSED); break; case MACRO_ACTION_STEP_TAP: - key.flags = pgm_read_byte(macro_p++); - key.keyCode = pgm_read_byte(macro_p++); - handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); - Keyboard.sendReport(); - handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); - Keyboard.sendReport(); + flags = pgm_read_byte(macro_p++); + readAndPlay (macro_p++, flags, IS_PRESSED | WAS_PRESSED); break; case MACRO_ACTION_STEP_KEYCODEDOWN: - key.flags = 0; - key.keyCode = pgm_read_byte(macro_p++); - handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); - Keyboard.sendReport(); + readAndPlay (macro_p++, 0, IS_PRESSED); break; case MACRO_ACTION_STEP_KEYCODEUP: - key.flags = 0; - key.keyCode = pgm_read_byte(macro_p++); - handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); - Keyboard.sendReport(); + readAndPlay (macro_p++, 0, WAS_PRESSED); break; case MACRO_ACTION_STEP_TAPCODE: - key.flags = 0; - key.keyCode = pgm_read_byte(macro_p++); - handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); - Keyboard.sendReport(); - handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); - Keyboard.sendReport(); + readAndPlay (macro_p++, 0, IS_PRESSED | WAS_PRESSED); break; case END: From de6cfa7f1c0b9de083b41df3a246f5408cd5d4e8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 27 Mar 2017 11:05:43 +0200 Subject: [PATCH 152/792] Rename readAndPlay to readKeyCodeAndPlay The new name reflects it better what the function does. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index bcc9b7b2..018fa540 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -7,7 +7,7 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { byte Macros_::row, Macros_::col; -static void readAndPlay (const macro_t *macro_p, uint8_t flags, uint8_t keyStates) { +static void readKeyCodeAndPlay (const macro_t *macro_p, uint8_t flags, uint8_t keyStates) { Key key; key.flags = flags; key.keyCode = pgm_read_byte(macro_p++); @@ -42,25 +42,25 @@ void Macros_::play(const macro_t *macro_p) { } case MACRO_ACTION_STEP_KEYDOWN: flags = pgm_read_byte(macro_p++); - readAndPlay (macro_p++, flags, IS_PRESSED); + readKeyCodeAndPlay (macro_p++, flags, IS_PRESSED); break; case MACRO_ACTION_STEP_KEYUP: flags = pgm_read_byte(macro_p++); - readAndPlay (macro_p++, flags, WAS_PRESSED); + readKeyCodeAndPlay (macro_p++, flags, WAS_PRESSED); break; case MACRO_ACTION_STEP_TAP: flags = pgm_read_byte(macro_p++); - readAndPlay (macro_p++, flags, IS_PRESSED | WAS_PRESSED); + readKeyCodeAndPlay (macro_p++, flags, IS_PRESSED | WAS_PRESSED); break; case MACRO_ACTION_STEP_KEYCODEDOWN: - readAndPlay (macro_p++, 0, IS_PRESSED); + readKeyCodeAndPlay (macro_p++, 0, IS_PRESSED); break; case MACRO_ACTION_STEP_KEYCODEUP: - readAndPlay (macro_p++, 0, WAS_PRESSED); + readKeyCodeAndPlay (macro_p++, 0, WAS_PRESSED); break; case MACRO_ACTION_STEP_TAPCODE: - readAndPlay (macro_p++, 0, IS_PRESSED | WAS_PRESSED); + readKeyCodeAndPlay (macro_p++, 0, IS_PRESSED | WAS_PRESSED); break; case END: From cdbbc0cd0a3ce74f81baf3db80572a3178743a72 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 27 Mar 2017 16:38:12 +0200 Subject: [PATCH 153/792] Instead of full docs, only document the commands Full documentation takes way too much space, and command names are a reasonable compromise for discoverability. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap-Focus.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Focus.h index 39ffbdc0..1b6b224d 100644 --- a/src/Kaleidoscope/EEPROM-Keymap-Focus.h +++ b/src/Kaleidoscope/EEPROM-Keymap-Focus.h @@ -23,16 +23,8 @@ #define FOCUS_HOOK_KEYMAP FOCUS_HOOK(EEPROMKeymap.focusKeymap, \ "keymap.dump\n" \ - "-----------\n" \ - "Dumps the keymap from EEPROM.\n\n" \ - "keymap.upload ...\n" \ - "-------------------------------\n" \ - "Uploads a new keymap to EEPROM." \ - "Starts at layer 0, row 0, column 0, " \ - "and continues as long as there is data on the line.") + "keymap.upload") #define FOCUS_HOOK_KEYMAP_TRANSFER FOCUS_HOOK(EEPROMKeymap.focusKeymapTransfer, \ - "keymap.transfer layer\n" \ - "---------------------\n" \ - "Transfers the `layer` from PROGMEM to EEPROM.") + "keymap.transfer layer") From f1e7ab05eb209e00820d605196542c4ec1a52f28 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 27 Mar 2017 16:38:33 +0200 Subject: [PATCH 154/792] Instead of full docs, only document the commands Full documentation takes way too much space, and command names are a reasonable compromise for discoverability. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.h | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index 72e038c8..54fc0f12 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -27,19 +27,9 @@ namespace FocusHooks { #define FOCUS_HOOK_SETTINGS FOCUS_HOOK(FocusHooks::settings, \ "settings.valid?\n" \ - "---------------\n" \ - "Return whether the EEPROM settings are valid, or not.\n\n" \ "settings.version\n" \ - "----------------\n" \ - "Return the version of the EEPROM settings.\n\n" \ - "settings.crc\n" \ - "------------\n" \ - "Return the CRC of the settings.") + "settings.crc") #define FOCUS_HOOK_EEPROM FOCUS_HOOK(FocusHooks::eeprom, \ "eeprom.dump\n" \ - "-----------\n" \ - "Dump the contents of EEPROM.\n\n" \ - "eeprom.upload BYTES...\n" \ - "----------------------\n" \ - "Upload `BYTES` to EEPROM.") + "eeprom.upload") From c07288cc5edb2b60e10c4568a1d563f5fed11d94 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 27 Mar 2017 16:54:15 +0200 Subject: [PATCH 155/792] Add an (optional) Focus hook Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 76 +++++++++++++++++++++++++++++++++ src/Kaleidoscope-LEDControl.h | 7 +++ 2 files changed, 83 insertions(+) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 7e440afc..24047283 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -1,4 +1,5 @@ #include "Kaleidoscope-LEDControl.h" +#include "Kaleidoscope-Focus.h" LEDMode *LEDControl_::modes[LED_MAX_MODES]; uint8_t LEDControl_::previousMode, LEDControl_::mode; @@ -155,4 +156,79 @@ LEDControl_::loopHook (bool postClear) { update(); } +bool +LEDControl_::focusHook (const char *command) { + enum { + SETALL, + MODE, + AT + } subCommand; + + if (strncmp_P (command, PSTR ("led."), 4) != 0) + return false; + if (strcmp_P (command + 4, PSTR ("at")) == 0) + subCommand = AT; + else if (strcmp_P (command + 4, PSTR ("setAll")) == 0) + subCommand = SETALL; + else if (strcmp_P (command + 4, PSTR ("mode")) == 0) + subCommand = MODE; + else + return false; + + switch (subCommand) { + case AT: + { + uint8_t idx = Serial.parseInt (); + + if (Serial.peek () == '\n') { + cRGB c = LEDControl.led_get_crgb_at (idx); + + Focus.printColor (c); + Serial.println (); + } else { + cRGB c; + + c.r = Serial.parseInt (); + c.g = Serial.parseInt (); + c.b = Serial.parseInt (); + + LEDControl.led_set_crgb_at (idx, c); + } + break; + } + case SETALL: + { + cRGB c; + + c.r = Serial.parseInt (); + c.g = Serial.parseInt (); + c.b = Serial.parseInt (); + + LEDControl.set_all_leds_to (c); + + break; + } + case MODE: + { + char peek = Serial.peek (); + if (peek == '\n') { + Serial.println (LEDControl.get_mode ()); + } else if (peek == 'n') { + LEDControl.next_mode (); + Serial.read (); + } else if (peek == 'p') { + // TODO + Serial.read (); + } else { + uint8_t mode = Serial.parseInt (); + + LEDControl.set_mode (mode); + } + break; + } + } + + return true; +} + LEDControl_ LEDControl; diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 81280b58..6a25bfc8 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -43,6 +43,8 @@ class LEDControl_ : public KaleidoscopePlugin { static uint16_t syncDelay; + static bool focusHook (const char *command); + private: static uint32_t syncTimer; static LEDMode *modes[LED_MAX_MODES]; @@ -53,3 +55,8 @@ class LEDControl_ : public KaleidoscopePlugin { }; extern LEDControl_ LEDControl; + +#define FOCUS_HOOK_LEDCONTROL FOCUS_HOOK (LEDControl.focusHook, \ + "led.at\n" \ + "led.setAll\n" \ + "led.mode") From 215d7de8ce0fd51801b166575663669b1bbcf94e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 27 Mar 2017 22:39:57 +0200 Subject: [PATCH 156/792] Use UNKNOWN_KEYSWITCH_LOCATION instead of magic numbers Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 018fa540..2e658a0c 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -13,11 +13,11 @@ static void readKeyCodeAndPlay (const macro_t *macro_p, uint8_t flags, uint8_t k key.keyCode = pgm_read_byte(macro_p++); if (keyStates & IS_PRESSED) { - handle_key_event(key, 255, 255, IS_PRESSED | INJECTED); + handle_key_event(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); Keyboard.sendReport(); } if (keyStates & WAS_PRESSED) { - handle_key_event(key, 255, 255, WAS_PRESSED | INJECTED); + handle_key_event(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); Keyboard.sendReport(); } } From 5d4fef2f6616a682a289d5f42aa558672768ccf9 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 27 Mar 2017 15:33:22 -0700 Subject: [PATCH 157/792] Update to new handle_keyswitch_event API naming --- src/Kaleidoscope-Hardware-Model01.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 783e36b4..27ffd021 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -141,7 +141,7 @@ boolean Model01::led_power_fault() { } } -void debug_key_event(keydata_t state, keydata_t previousState, uint8_t keynum, uint8_t row, uint8_t col) { +void debug_keyswitch_event(keydata_t state, keydata_t previousState, uint8_t keynum, uint8_t row, uint8_t col) { if (bitRead(state.all, keynum) != bitRead(previousState.all, keynum )) { Serial.print("Looking at row "); Serial.print(row); @@ -182,12 +182,12 @@ void Model01::act_on_matrix_scan() { uint8_t keyState = (bitRead(previousLeftHandState.all, keynum) << 0) | (bitRead(leftHandState.all, keynum) << 1); - handle_key_event(Key_NoKey, row, 7-col, keyState); + handle_keyswitch_event(Key_NoKey, row, 7-col, keyState); keyState = (bitRead(previousRightHandState.all, keynum) << 0) | (bitRead(rightHandState.all, keynum) << 1); - handle_key_event(Key_NoKey, row, (15- col), keyState); + handle_keyswitch_event(Key_NoKey, row, (15- col), keyState); } } } From 7d6225f724a4f87d4ec3b8563d0d5081a64933df Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 27 Mar 2017 15:34:20 -0700 Subject: [PATCH 158/792] Update to new handle_keyswitch_event API naming --- src/Kaleidoscope-Macros.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 2e658a0c..069e300f 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -13,11 +13,11 @@ static void readKeyCodeAndPlay (const macro_t *macro_p, uint8_t flags, uint8_t k key.keyCode = pgm_read_byte(macro_p++); if (keyStates & IS_PRESSED) { - handle_key_event(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); + handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); Keyboard.sendReport(); } if (keyStates & WAS_PRESSED) { - handle_key_event(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); + handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); Keyboard.sendReport(); } } From fbee5854ee99330fd5be82bcddfed166ef85880b Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 27 Mar 2017 15:34:48 -0700 Subject: [PATCH 159/792] Update to new handle_keyswitch_event API naming --- src/Kaleidoscope-Model01-TestMode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 883fa2aa..ad423e79 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -19,4 +19,4 @@ class TestMode_ : public KaleidoscopePlugin { extern TestMode_ TestMode; -Key handle_key_event_test(Key mappedKey, byte row, byte col, uint8_t keyState); +Key handle_keyswitch_event_test(Key mappedKey, byte row, byte col, uint8_t keyState); From 26d7af1b96b966d9a6db7adf0b4c18a81d314cd2 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 29 Mar 2017 14:51:32 +0200 Subject: [PATCH 160/792] Fix the `settings.version` Focus command There was a missing `break`, so control flowed through to the CRC case. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 84b58e55..d87943e7 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -47,6 +47,7 @@ namespace FocusHooks { break; case GETVERSION: Serial.println (EEPROMSettings.version ()); + break; case CRC: Serial.print (::CRC.crc, HEX); Serial.print (F("/")); From 19b5655770fa4f224551241d56231a00512b3188 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 29 Mar 2017 18:47:29 +0200 Subject: [PATCH 161/792] Add a way to figure out the used & free EEPROM amount Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 6 ++++++ src/Kaleidoscope/EEPROM-Settings-Focus.h | 1 + src/Kaleidoscope/EEPROM-Settings.cpp | 5 +++++ src/Kaleidoscope/EEPROM-Settings.h | 1 + 4 files changed, 13 insertions(+) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index d87943e7..40d201e2 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -60,6 +60,7 @@ namespace FocusHooks { bool eeprom (const char *command) { enum { + FREE, DUMP, UPLOAD, } subCommand; @@ -68,6 +69,8 @@ namespace FocusHooks { subCommand = DUMP; else if (strcmp_P (command, PSTR ("eeprom.upload")) == 0) subCommand = UPLOAD; + else if (strcmp_P (command, PSTR ("eeprom.free")) == 0) + subCommand = FREE; else return false; @@ -87,6 +90,9 @@ namespace FocusHooks { EEPROM.update (i, d); } break; + case FREE: + Serial.println (EEPROM.length () - EEPROMSettings.used ()); + break; } return true; diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index 54fc0f12..3e084e8b 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -31,5 +31,6 @@ namespace FocusHooks { "settings.crc") #define FOCUS_HOOK_EEPROM FOCUS_HOOK(FocusHooks::eeprom, \ + "eeprom.free\n" \ "eeprom.dump\n" \ "eeprom.upload") diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 1c384596..5ef289f9 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -82,6 +82,11 @@ namespace KaleidoscopePlugins { _isValid = false; } + uint16_t + EEPROMSettings::used (void) { + return nextStart; + } + void EEPROMSettings::update (void) { settings.crc = CRC.crc; diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 02cc7d54..3cd95e82 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -37,6 +37,7 @@ namespace KaleidoscopePlugins { static uint16_t requestSlice (uint16_t size); static void seal (void); static uint16_t crc (void); + static uint16_t used (void); private: static uint16_t nextStart; From 0bfb77361989f02e0409d09a4d615b2eb6a52d3d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 5 Apr 2017 10:14:45 +0200 Subject: [PATCH 162/792] Focus: Don't format the eeprom.dump output Fixes #1. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 40d201e2..2fcdcdd9 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -80,8 +80,6 @@ namespace FocusHooks { uint8_t d = EEPROM[i]; Focus.printNumber (d); Focus.printSpace (); - if ((i + 1) % 32 == 0) - Serial.println (); } break; case UPLOAD: From fc59d1f64be8384f50c3499b5f3f45a673a4a16d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 5 Apr 2017 10:25:34 +0200 Subject: [PATCH 163/792] Focus: Merge the eeprom.dump and eeprom.upload commands Fixes #2. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 35 +++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 2fcdcdd9..916dc1b3 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -60,34 +60,35 @@ namespace FocusHooks { bool eeprom (const char *command) { enum { + CONTENTS, FREE, - DUMP, - UPLOAD, } subCommand; - if (strcmp_P (command, PSTR ("eeprom.dump")) == 0) - subCommand = DUMP; - else if (strcmp_P (command, PSTR ("eeprom.upload")) == 0) - subCommand = UPLOAD; + if (strcmp_P (command, PSTR ("eeprom.contents")) == 0) + subCommand = CONTENTS; else if (strcmp_P (command, PSTR ("eeprom.free")) == 0) subCommand = FREE; else return false; switch (subCommand) { - case DUMP: - for (uint16_t i = 0; i < EEPROM.length (); i++) { - uint8_t d = EEPROM[i]; - Focus.printNumber (d); - Focus.printSpace (); - } - break; - case UPLOAD: - for (uint16_t i = 0; i < EEPROM.length (); i++) { - uint8_t d = Serial.parseInt (); - EEPROM.update (i, d); + case CONTENTS: { + if (Serial.peek () == '\n') { + for (uint16_t i = 0; i < EEPROM.length (); i++) { + uint8_t d = EEPROM[i]; + Focus.printNumber (d); + Focus.printSpace (); + } + Serial.println (); + } else { + for (uint16_t i = 0; i < EEPROM.length (); i++) { + uint8_t d = Serial.parseInt (); + EEPROM.update (i, d); + } } + break; + } case FREE: Serial.println (EEPROM.length () - EEPROMSettings.used ()); break; From cdd6b811f9b533859aeebe29f118cb49a31ee564 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 5 Apr 2017 10:27:15 +0200 Subject: [PATCH 164/792] Focus: Allow partial eeprom upload Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 916dc1b3..b892b8dd 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -81,7 +81,7 @@ namespace FocusHooks { } Serial.println (); } else { - for (uint16_t i = 0; i < EEPROM.length (); i++) { + for (uint16_t i = 0; i < EEPROM.length () && Serial.peek () != '\n'; i++) { uint8_t d = Serial.parseInt (); EEPROM.update (i, d); } From 78836fd091d4a122b8f1f853fc3c9de7d3b0d7f9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 5 Apr 2017 10:31:09 +0200 Subject: [PATCH 165/792] Focus: Less formatting in the dump output Fixes #1. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 2e095fff..01e98507 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -127,14 +127,11 @@ namespace KaleidoscopePlugins { Key k = getKey (layer, row, col); printKey (k); - - if (col < COLS - 1) - Serial.print (F(" | ")); + ::Focus.printSpace (); } - Serial.println (); } - Serial.println (); } + Serial.println (); break; } From a83d61e280b7aab4e2b02f7e5423a3d75570fbf8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 5 Apr 2017 10:34:39 +0200 Subject: [PATCH 166/792] Focus: Fix the command list `eeprom.dump` and `eeprom.upload` has been merged into `eeprom.contents`, reflect that in the command list, too. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index 3e084e8b..32c9fb13 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -32,5 +32,4 @@ namespace FocusHooks { #define FOCUS_HOOK_EEPROM FOCUS_HOOK(FocusHooks::eeprom, \ "eeprom.free\n" \ - "eeprom.dump\n" \ - "eeprom.upload") + "eeprom.contents") From 1432015235eb721bc3d88672e8060fc2d45c73d0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 5 Apr 2017 10:36:57 +0200 Subject: [PATCH 167/792] Focus: Merge keymap.dump and keymap.upload into keymap.map Fixes #2. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap-Focus.h | 5 +-- src/Kaleidoscope/EEPROM-Keymap.cpp | 51 ++++++++------------------ 2 files changed, 16 insertions(+), 40 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Focus.h index 1b6b224d..eac8f2fa 100644 --- a/src/Kaleidoscope/EEPROM-Keymap-Focus.h +++ b/src/Kaleidoscope/EEPROM-Keymap-Focus.h @@ -21,10 +21,7 @@ #include #include -#define FOCUS_HOOK_KEYMAP FOCUS_HOOK(EEPROMKeymap.focusKeymap, \ - "keymap.dump\n" \ - "keymap.upload") - +#define FOCUS_HOOK_KEYMAP FOCUS_HOOK(EEPROMKeymap.focusKeymap, "keymap.map") #define FOCUS_HOOK_KEYMAP_TRANSFER FOCUS_HOOK(EEPROMKeymap.focusKeymapTransfer, \ "keymap.transfer layer") diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 01e98507..9a4f0aa9 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -93,48 +93,27 @@ namespace KaleidoscopePlugins { bool EEPROMKeymap::focusKeymap (const char *command) { - enum { - UPLOAD, - DUMP, - } subCommand; - - if (strncmp_P (command, PSTR ("keymap."), 7) != 0) - return false; - - if (strcmp_P (command + 7, PSTR ("upload")) == 0) - subCommand = UPLOAD; - else if (strcmp_P (command + 7, PSTR ("dump")) == 0) - subCommand = DUMP; - else + if (strcmp_P (command, PSTR ("keymap.map")) != 0) return false; - switch (subCommand) { - case UPLOAD: - { - uint16_t i = 0; - while ((Serial.peek () != '\n') && (i < ROWS * COLS * maxLayers)) { - updateKey (i, parseKey ()); - i++; - } - break; - } - - case DUMP: - { - for (uint8_t layer = 0; layer < maxLayers; layer++) { - for (uint8_t row = 0; row < ROWS; row++) { - for (uint8_t col = 0; col < COLS; col++) { - Key k = getKey (layer, row, col); + if (Serial.peek () == '\n') { + for (uint8_t layer = 0; layer < maxLayers; layer++) { + for (uint8_t row = 0; row < ROWS; row++) { + for (uint8_t col = 0; col < COLS; col++) { + Key k = getKey (layer, row, col); - printKey (k); - ::Focus.printSpace (); - } + printKey (k); + ::Focus.printSpace (); } } - Serial.println (); - break; } - + Serial.println (); + } else { + uint16_t i = 0; + while ((Serial.peek () != '\n') && (i < ROWS * COLS * maxLayers)) { + updateKey (i, parseKey ()); + i++; + } } return true; From e07f00e9470c8a67069c8d699b242a7a3b6aec15 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 5 Apr 2017 10:42:05 +0200 Subject: [PATCH 168/792] Focus: keymap.map should work with raw keycodes Instead of separating `flags` and `keyCode`, just use the `raw` combination. Easier for higher level tools to work with. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 9a4f0aa9..11b0fc8a 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -78,17 +78,14 @@ namespace KaleidoscopePlugins { EEPROMKeymap::parseKey (void) { Key key; - key.flags = Serial.parseInt (); - key.keyCode = Serial.parseInt (); + key.raw = Serial.parseInt (); return key; } void EEPROMKeymap::printKey (Key k) { - ::Focus.printNumber (k.flags); - ::Focus.printSpace (); - ::Focus.printNumber (k.keyCode); + ::Focus.printNumber (k.raw); } bool From e3e6ec94887f40d1c4753c924b1162f8e1a00e2d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 6 Apr 2017 19:25:47 +0200 Subject: [PATCH 169/792] README: Change the status images to SVG Signed-off-by: Gergely Nagy --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ee2e3fc3..6395057c 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings - [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 TODO From 1379094d3926f9755da9eba7b38c840ab3f717ca Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 6 Apr 2017 19:44:17 +0200 Subject: [PATCH 170/792] Add some developer-oriented docs to the README Signed-off-by: Gergely Nagy --- README.md | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6395057c..dcb503a3 100644 --- a/README.md +++ b/README.md @@ -9,22 +9,52 @@ [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 -TODO +To be able to reliably store persistent configuration in `EEPROM`, we need to be +able to split up the available space for plugins to use. We also want to make +sure that we notice when the `EEPROM` contents and the firmware are out of sync. +This plugin provides the tools to do that. + +It does not guard against errors, it merely provides the means to discover them, +and let the firmware Sketch handle the case in whatever way it finds reasonable. +It's a building block, and not much else. All Kaleidoscope plugins that need to +store data in `EEPROM` are encouraged to make use of this library. ## Using the plugin -TODO +There are a few steps one needs to take to use the plugin: we must first +register it, then either let other plugins request slices of `EEPROM`, or do so +ourselves. And finally, seal it, to signal that we are done setting up. At that +point, we can verify whether the contents of the `EEPROM` agree with our +firmware. ```c++ #include #include +static uint16_t settingsBase; +static struct { + bool someSettingFlag; +} testSettings; + void setup () { Kaleidoscope.setup (); USE_PLUGINS (&EEPROMSettings); - // TODO + /* Use other plugins that make use of the EEPROM */ + + settingsBase = EEPROMSettings.requestSlice (sizeof (testSettings)); + + EEPROMSettings.seal (); + + if (!EEPROMSettings.isValid ()) { + // Handle the case where the settings are out of sync... + // Flash LEDs, for example. + + return; + } + + EEPROM.get (settingsBase, testSettings); } ``` @@ -32,7 +62,66 @@ void setup () { The plugin provides the `EEPROMSettings` object, which has the following methods: -**TODO** +### `cycleThrough(keys...)` + +> Cycles through all the possibilities given in `keys` (starting from the +> beginning once it reached the end). This should be used from +> the [`cycleAction`][cycleaction] function, once it is determined what sequence +> to cycle through. + +### `update()` + +> Updates the `EEPROM` header with the current status quo, including the version +> and the CRC checksum. +> +> This should be called when upgrading from one version to another, or when +> fixing up an out-of-sync case. + +### `isValid()` + +> Returns whether the `EEPROM` header is valid, that is, if it has the expected +> CRC checksum. +> +> Should only be called after calling `seal()`. + +### `invalidate()` + +> Invalidates the `EEPROM` header. Use when the version does not match what the +> firmware would expect. This signals to other plugins that the contents of +> `EEPROM` should not be trusted. + +### `version([newVersion])` + +> Sets or returns the version of the `EEPROM` layout. This is purely for use by +> the firmware, so it can attempt to upgrade the contents, if need be, or alert +> the user in there's a mismatch. Plugins do not use this property. +> +> Should only be called after calling `seal()`. + +### `requestSlice(size)` + +> Requests a slice of the `EEPROM`, and returns the starting address (or 0 on +> error, including when the request arrived after sealing the layout). +> +> Should only be called **before** calling `seal()`. + +### `seal()` + +> Seal the `EEPROM` layout, so no new slices can be requested. The CRC checksum +> is considered final at this time, and the `isValid()`, `crc()`, `used()` and +> `version()` methods can be used from this point onwards. + +### `crc()` + +> Returns the CRC checksum of the layout. Should only be used after calling +> `seal()`. + +### `used()` + +> Returns the amount of space requested so far. +> +> Should only be used after calling `seal()`. + ## Dependencies From b811e1f973ff7c4ba954f92dc367150db50fe101 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 6 Apr 2017 19:47:16 +0200 Subject: [PATCH 171/792] Document the Focus hooks too Signed-off-by: Gergely Nagy --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dcb503a3..bc2ed1ed 100644 --- a/README.md +++ b/README.md @@ -122,10 +122,17 @@ The plugin provides the `EEPROMSettings` object, which has the following methods > > Should only be used after calling `seal()`. +## Focus Hooks + +The plugin provides two [Focus][focus] hooks: `FOCUS_HOOK_SETTINGS`, and +`FOCUS_HOOK_EEPROM`, that register commands that allow one to work with the +settings, and with the contents of the `EEPROM` through Focus. + + [focus]: https://github.com/keyboardio/Kaleidoscope-Focus ## Dependencies -* [Kaleidoscope-Focus](https://github.com/keyboardio/Kaleidoscope-Focus) +* [Kaleidoscope-Focus][focus] ## Further reading From 957866fb841759f22f470dc1b2d9b08e99f0c960 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 7 Apr 2017 12:22:12 +0200 Subject: [PATCH 172/792] README: Drop a left over sample from another plugin Signed-off-by: Gergely Nagy --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index bc2ed1ed..63d333ca 100644 --- a/README.md +++ b/README.md @@ -62,13 +62,6 @@ void setup () { The plugin provides the `EEPROMSettings` object, which has the following methods: -### `cycleThrough(keys...)` - -> Cycles through all the possibilities given in `keys` (starting from the -> beginning once it reached the end). This should be used from -> the [`cycleAction`][cycleaction] function, once it is determined what sequence -> to cycle through. - ### `update()` > Updates the `EEPROM` header with the current status quo, including the version From 664df896e0a6757c65defb1acf78a99aabc1f318 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 7 Apr 2017 12:23:18 +0200 Subject: [PATCH 173/792] README: Rearrange the methods a bit Signed-off-by: Gergely Nagy --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 63d333ca..00be48d8 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,19 @@ void setup () { The plugin provides the `EEPROMSettings` object, which has the following methods: +### `requestSlice(size)` + +> Requests a slice of the `EEPROM`, and returns the starting address (or 0 on +> error, including when the request arrived after sealing the layout). +> +> Should only be called **before** calling `seal()`. + +### `seal()` + +> Seal the `EEPROM` layout, so no new slices can be requested. The CRC checksum +> is considered final at this time, and the `isValid()`, `crc()`, `used()` and +> `version()` methods can be used from this point onwards. + ### `update()` > Updates the `EEPROM` header with the current status quo, including the version @@ -91,19 +104,6 @@ The plugin provides the `EEPROMSettings` object, which has the following methods > > Should only be called after calling `seal()`. -### `requestSlice(size)` - -> Requests a slice of the `EEPROM`, and returns the starting address (or 0 on -> error, including when the request arrived after sealing the layout). -> -> Should only be called **before** calling `seal()`. - -### `seal()` - -> Seal the `EEPROM` layout, so no new slices can be requested. The CRC checksum -> is considered final at this time, and the `isValid()`, `crc()`, `used()` and -> `version()` methods can be used from this point onwards. - ### `crc()` > Returns the CRC checksum of the layout. Should only be used after calling From 55c42928f94ac38bd39b5bc0949388c24c1b0916 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 21 Apr 2017 12:16:57 +0200 Subject: [PATCH 174/792] Add a `led.theme` Focus command Allows setting all of the LEDs to custom, distinct colors (as opposed to `led.setAll`, which sets them all to the same color). This allows one to upload a theme in one go, without having to set each LED one by one. Fixes #5. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 31 ++++++++++++++++++++++++++++++- src/Kaleidoscope-LEDControl.h | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 24047283..f91697b6 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -161,7 +161,8 @@ LEDControl_::focusHook (const char *command) { enum { SETALL, MODE, - AT + AT, + THEME, } subCommand; if (strncmp_P (command, PSTR ("led."), 4) != 0) @@ -172,6 +173,8 @@ LEDControl_::focusHook (const char *command) { subCommand = SETALL; else if (strcmp_P (command + 4, PSTR ("mode")) == 0) subCommand = MODE; + else if (strcmp_P (command + 4, PSTR ("theme")) == 0) + subCommand = THEME; else return false; @@ -226,6 +229,32 @@ LEDControl_::focusHook (const char *command) { } break; } + case THEME: + { + if (Serial.peek () == '\n') { + for (uint8_t idx = 0; idx < LED_COUNT; idx++) { + cRGB c = LEDControl.led_get_crgb_at (idx); + + Focus.printColor (c); + Focus.printSpace (); + } + Serial.println (); + break; + } + + uint8_t idx = 0; + while (idx < LED_COUNT && Serial.peek() != '\n') { + cRGB color; + + color.r = Serial.parseInt (); + color.g = Serial.parseInt (); + color.b = Serial.parseInt (); + + LEDControl.led_set_crgb_at (idx, color); + idx++; + } + break; + } } return true; diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 6a25bfc8..49b0c8df 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -59,4 +59,5 @@ extern LEDControl_ LEDControl; #define FOCUS_HOOK_LEDCONTROL FOCUS_HOOK (LEDControl.focusHook, \ "led.at\n" \ "led.setAll\n" \ + "led.theme\n" \ "led.mode") From 2f7c38a15d4faf4e872fe2974a7a49542d1e37c6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 24 Apr 2017 09:43:03 +0200 Subject: [PATCH 175/792] Focus: Fix the `keymap.transfer` docs Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap-Focus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Focus.h index eac8f2fa..23bfb61f 100644 --- a/src/Kaleidoscope/EEPROM-Keymap-Focus.h +++ b/src/Kaleidoscope/EEPROM-Keymap-Focus.h @@ -24,4 +24,4 @@ #define FOCUS_HOOK_KEYMAP FOCUS_HOOK(EEPROMKeymap.focusKeymap, "keymap.map") #define FOCUS_HOOK_KEYMAP_TRANSFER FOCUS_HOOK(EEPROMKeymap.focusKeymapTransfer, \ - "keymap.transfer layer") + "keymap.transfer") From da4c057fba15ecb99e9bc4c62539f383297c19ec Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 1 May 2017 11:16:02 +0200 Subject: [PATCH 176/792] Moved the wdt_disable() call to the hardware plugins See keyboardio/Kaleidoscope#129 for a discussion why. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 27ffd021..36db551e 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -64,6 +64,8 @@ void Model01::enable_high_power_leds(void) { } void Model01::setup(void) { + wdt_disable(); + delay(100); enable_scanner_power(); // Consider not doing this until 30s after keyboard From 63835fa1bde984fc9f9c185c6cd09fc855a006c5 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 3 May 2017 00:29:29 -0700 Subject: [PATCH 177/792] Update to use new Focus.printColor API --- src/Kaleidoscope-LEDControl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index f91697b6..77b80b48 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -186,7 +186,7 @@ LEDControl_::focusHook (const char *command) { if (Serial.peek () == '\n') { cRGB c = LEDControl.led_get_crgb_at (idx); - Focus.printColor (c); + Focus.printColor (c.r, c.g, c.b); Serial.println (); } else { cRGB c; @@ -235,7 +235,7 @@ LEDControl_::focusHook (const char *command) { for (uint8_t idx = 0; idx < LED_COUNT; idx++) { cRGB c = LEDControl.led_get_crgb_at (idx); - Focus.printColor (c); + Focus.printColor (c.r, c.g, c.b); Focus.printSpace (); } Serial.println (); From ca74d9b6b76f33f4d70b5cd961539a4e5a76fb22 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 9 May 2017 12:33:20 +0200 Subject: [PATCH 178/792] Do gamma correction elsewhere Instead of doing gamma correction when setting a LED color, do it elsewhere, when talking to the LED hardware. This way, both the programmer, and the end-user will deal with the unaltered, raw RGB values, and neither has to care about when and how gamma correction is applied. The counterpart of this will be in KeyboardioScanner, that re-introduces gamma correction on that end. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 36db551e..8c6e9614 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -12,25 +12,6 @@ static constexpr uint8_t key_led_map[4][16] = { {0,7, 8,15,16,23,31,30, 33,32,40,47,48,55,56,63}, }; -const uint8_t PROGMEM gamma8[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, - 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, - 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, - 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, - 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, - 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, - 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, - 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, - 90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114, - 115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142, - 144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175, - 177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213, - 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 -}; - Model01::Model01(void) { } @@ -79,13 +60,7 @@ void Model01::setup(void) { } -void Model01::led_set_crgb_at(uint8_t i, cRGB crgb_) { - cRGB crgb; - - crgb.r = pgm_read_byte(&gamma8[crgb_.r]); - crgb.g = pgm_read_byte(&gamma8[crgb_.g]); - crgb.b = pgm_read_byte(&gamma8[crgb_.b]); - +void Model01::led_set_crgb_at(uint8_t i, cRGB crgb) { if(i<32) { cRGB oldColor = led_get_crgb_at(i); isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); From 59aaa0cc6fb34d0d2699341bc44ad7051cd4c85a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 21 May 2017 21:37:57 -0700 Subject: [PATCH 179/792] Add KeyboardioHID to the Model 01 hardware definition So we can try to remove it from the Kaleidoscope core --- src/Kaleidoscope-Hardware-Model01.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 8c6e9614..4af44fcc 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -1,4 +1,5 @@ #include +#include #include KeyboardioScanner Model01::leftHand(0); From ca71ff2c759ed4e3655067b80c8b6eb198b3deee Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 21 May 2017 21:57:35 -0700 Subject: [PATCH 180/792] Fix the name of the numlock key --- src/Kaleidoscope-Numlock.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 253cee89..fc4e8393 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -32,7 +32,7 @@ NumLock_::update (void) { for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookup (r, c); - if (k.raw < Key_NumLock.raw || k.raw > Key_KeypadDot.raw) + if (k.raw < Key_KeypadNumLock.raw || k.raw > Key_KeypadDot.raw) continue; LEDControl.led_set_crgb_at(r, c, numpad_color); @@ -62,7 +62,7 @@ NumLock_::toggle (byte row_, byte col_, uint8_t numPadLayer) { Layer.on (numPadLayer); } - return MACRO(T(NumLock), END); + return MACRO(T(KeypadNumLock), END); } NumLock_ NumLock; From c7eb22c3ec501799c46c46f7766d273fe2637726 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 22 May 2017 00:26:12 -0700 Subject: [PATCH 181/792] Update example to match the new Keymap --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index 24cdf9bf..cd3fb4dc 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -27,9 +27,9 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, M(0), Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, @@ -37,7 +37,7 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_skip ), }; From a5a3bb65216abfdd3a2defd23c75f93e036b1f3f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 22 May 2017 01:01:43 -0700 Subject: [PATCH 182/792] Update to new Keymap --- examples/EEPROM-Settings/EEPROM-Settings.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino index 7ca1700a..7eed1f01 100644 --- a/examples/EEPROM-Settings/EEPROM-Settings.ino +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -25,9 +25,9 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, @@ -35,7 +35,7 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_skip ), }; From 543c3b09f27a4942b3d865093376f7dc55d81b8f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 22 May 2017 01:03:40 -0700 Subject: [PATCH 183/792] Update example to match new keymap --- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index b2d8be40..eaa58201 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -26,9 +26,9 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, Key_skip, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, @@ -36,7 +36,7 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_skip ), }; From 07b3f9a9cd6bb18e8fbd9e493bdb5d709ca3daea Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 22 May 2017 10:44:56 -0700 Subject: [PATCH 184/792] Update example to new keymap --- examples/LED-Stalker/LED-Stalker.ino | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index 1e8df10a..d3a5e276 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -20,25 +20,26 @@ #include #include "LED-Off.h" + const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED ( Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, - Key_skip, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_NoKey, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, - Key_skip - ), + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_NoKey + ), }; void setup () { From 6d232fb7c75cd905a3e880ba914bbfd5a805c641 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 22 May 2017 13:13:30 -0700 Subject: [PATCH 185/792] Update to new key api --- examples/MagicCombo/MagicCombo.ino | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index 4f70ecb1..d2114326 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -34,25 +34,26 @@ static const KaleidoscopePlugins::MagicCombo::dictionary_t dictionary[] PROGMEM {0, 0} }; + const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED ( - Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDn, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Esc, + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LCtrl, Key_Backspace, Key_LGUI, Key_LShift, - Key_skip, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_NoKey, Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RShift, Key_RAlt, Key_Space, Key_RCtrl, - Key_skip - ), + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_NoKey + ), }; void setup () { From 59c361e6c8cd908c55e473f7bea57b720d716053 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 23 May 2017 20:00:23 -0700 Subject: [PATCH 186/792] New build infrastructure --- .travis.yml | 28 ++++++++++++++++------------ Makefile | 12 ++++++++++++ 2 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml index ed2b2e3b..e7030acf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,21 @@ -language: cpp dist: trusty -sudo: required +sudo: false os: - linux -before_install: - - pushd .. - - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz - - tar xf arduino-1.6.11-linux64.tar.xz - - popd install: - - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr script: - - export DEFAULT_SKETCH=$(cd examples; basename *) - - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 - - export BOARD_HARDWARE_PATH=$(pwd)/hardware - - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 2b332664520de08ebad2d5eaae82d1ef272fda1f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 23 May 2017 20:05:15 -0700 Subject: [PATCH 187/792] New build infrastructure --- .travis.yml | 29 ++++++++++++++++------------- Makefile | 12 ++++++++++++ 2 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml index 77431b24..e7030acf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,21 @@ -language: cpp dist: trusty -sudo: required +sudo: false os: - linux -before_install: - - pushd .. - - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz - - tar xf arduino-1.6.11-linux64.tar.xz - - popd install: - - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr script: - - export DEFAULT_SKETCH=$(cd examples; basename *) - - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 - - export BOARD_HARDWARE_PATH=$(pwd)/hardware - - export EXTRA_BUILDER_ARGS="-libraries ." - - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 90f5c513864414fb8aaec7653c3a81f380b7f2e4 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 23 May 2017 20:07:37 -0700 Subject: [PATCH 188/792] New build infrastructure --- .travis.yml | 29 ++++++++++++++++------------- Makefile | 12 ++++++++++++ 2 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml index 77431b24..e7030acf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,21 @@ -language: cpp dist: trusty -sudo: required +sudo: false os: - linux -before_install: - - pushd .. - - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz - - tar xf arduino-1.6.11-linux64.tar.xz - - popd install: - - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr script: - - export DEFAULT_SKETCH=$(cd examples; basename *) - - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 - - export BOARD_HARDWARE_PATH=$(pwd)/hardware - - export EXTRA_BUILDER_ARGS="-libraries ." - - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 124b70ec009c1c82ef4c6d8cfa4c5006349fa521 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 23 May 2017 20:09:06 -0700 Subject: [PATCH 189/792] New build infrastructure --- .travis.yml | 29 ++++++++++++++++------------- Makefile | 12 ++++++++++++ 2 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml index 77431b24..e7030acf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,21 @@ -language: cpp dist: trusty -sudo: required +sudo: false os: - linux -before_install: - - pushd .. - - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz - - tar xf arduino-1.6.11-linux64.tar.xz - - popd install: - - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr script: - - export DEFAULT_SKETCH=$(cd examples; basename *) - - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 - - export BOARD_HARDWARE_PATH=$(pwd)/hardware - - export EXTRA_BUILDER_ARGS="-libraries ." - - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 0e0f3037e507d7ca3bf8b2198e0ea822b17dcda1 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 23 May 2017 21:11:34 -0700 Subject: [PATCH 190/792] Modernize build and test infra --- Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From a0cebeb0ee87ccd0662097f41f5ce779b7958f83 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 23 May 2017 21:19:23 -0700 Subject: [PATCH 191/792] Switch to modern build infrastructure --- .travis.yml | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed2b2e3b..e7030acf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,21 @@ -language: cpp dist: trusty -sudo: required +sudo: false os: - linux -before_install: - - pushd .. - - wget http://downloads.arduino.cc/arduino-1.6.11-linux64.tar.xz - - tar xf arduino-1.6.11-linux64.tar.xz - - popd install: - - git clone --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr script: - - export DEFAULT_SKETCH=$(cd examples; basename *) - - export ARDUINO_PATH=$(pwd)/../arduino-1.6.11 - - export BOARD_HARDWARE_PATH=$(pwd)/hardware - - hardware/keyboardio/avr/libraries/Kaleidoscope/tools/kaleidoscope-builder build + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true From 97008a28f07e7ff7b5adbd56f0547622770a0000 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 26 May 2017 15:41:19 -0700 Subject: [PATCH 192/792] "make astyle --- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 54 +++++------ src/Kaleidoscope/EEPROM-Keymap.cpp | 116 +++++++++++------------ src/Kaleidoscope/EEPROM-Keymap.h | 4 +- 3 files changed, 87 insertions(+), 87 deletions(-) diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index eaa58201..e3480f37 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -21,45 +21,45 @@ #include const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + [0] = KEYMAP_STACKED + ( + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_skip, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_skip, - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_skip - ), + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_skip + ), }; void setup () { - Serial.begin (9600); + Serial.begin (9600); - Kaleidoscope.setup (); + Kaleidoscope.setup (); - USE_PLUGINS (&EEPROMKeymap, &Focus); + USE_PLUGINS (&EEPROMKeymap, &Focus); - Focus.addHook (FOCUS_HOOK_SETTINGS); - Focus.addHook (FOCUS_HOOK_KEYMAP); - Focus.addHook (FOCUS_HOOK_KEYMAP_TRANSFER); - Focus.addHook (FOCUS_HOOK_HELP); - Focus.addHook (FOCUS_HOOK_VERSION); + Focus.addHook (FOCUS_HOOK_SETTINGS); + Focus.addHook (FOCUS_HOOK_KEYMAP); + Focus.addHook (FOCUS_HOOK_KEYMAP_TRANSFER); + Focus.addHook (FOCUS_HOOK_HELP); + Focus.addHook (FOCUS_HOOK_VERSION); - Layer.getKey = EEPROMKeymap.getKeyOverride; + Layer.getKey = EEPROMKeymap.getKeyOverride; - EEPROMKeymap.reserveSpace (1); - EEPROMSettings.seal (); + EEPROMKeymap.reserveSpace (1); + EEPROMSettings.seal (); } void loop () { - Kaleidoscope.loop (); + Kaleidoscope.loop (); } diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 11b0fc8a..314b65a2 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -21,29 +21,29 @@ #include namespace KaleidoscopePlugins { - uint16_t EEPROMKeymap::keymapBase; - uint8_t EEPROMKeymap::maxLayers; +uint16_t EEPROMKeymap::keymapBase; +uint8_t EEPROMKeymap::maxLayers; - EEPROMKeymap::EEPROMKeymap (void) { - } +EEPROMKeymap::EEPROMKeymap (void) { +} - void - EEPROMKeymap::begin (void) { +void +EEPROMKeymap::begin (void) { USE_PLUGINS (&::EEPROMSettings); - } +} - void - EEPROMKeymap::reserveSpace (uint8_t layers) { +void +EEPROMKeymap::reserveSpace (uint8_t layers) { maxLayers = layers; keymapBase = ::EEPROMSettings.requestSlice (maxLayers * ROWS * COLS * 2); - } +} - Key - EEPROMKeymap::getKey (uint8_t layer, byte row, byte col) { +Key +EEPROMKeymap::getKey (uint8_t layer, byte row, byte col) { Key key; if (layer >= maxLayers) - return Key_NoKey; + return Key_NoKey; uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col) * 2; @@ -51,89 +51,89 @@ namespace KaleidoscopePlugins { key.keyCode = EEPROM.read (keymapBase + pos + 1); return key; - } +} - Key - EEPROMKeymap::getKeyOverride (uint8_t layer, byte row, byte col) { +Key +EEPROMKeymap::getKeyOverride (uint8_t layer, byte row, byte col) { Key key; key = getKey (layer, row, col); if (key == Key_Transparent) - key = Layer.getKeyFromPROGMEM (layer, row, col); + key = Layer.getKeyFromPROGMEM (layer, row, col); return key; - } +} - uint16_t - EEPROMKeymap::base (void) { +uint16_t +EEPROMKeymap::base (void) { return keymapBase; - } +} - void - EEPROMKeymap::updateKey (uint16_t basePos, Key key) { +void +EEPROMKeymap::updateKey (uint16_t basePos, Key key) { EEPROM.update (keymapBase + basePos * 2, key.flags); EEPROM.update (keymapBase + basePos * 2 + 1, key.keyCode); - } +} - Key - EEPROMKeymap::parseKey (void) { +Key +EEPROMKeymap::parseKey (void) { Key key; key.raw = Serial.parseInt (); return key; - } +} - void - EEPROMKeymap::printKey (Key k) { +void +EEPROMKeymap::printKey (Key k) { ::Focus.printNumber (k.raw); - } +} - bool - EEPROMKeymap::focusKeymap (const char *command) { +bool +EEPROMKeymap::focusKeymap (const char *command) { if (strcmp_P (command, PSTR ("keymap.map")) != 0) - return false; + return false; if (Serial.peek () == '\n') { - for (uint8_t layer = 0; layer < maxLayers; layer++) { - for (uint8_t row = 0; row < ROWS; row++) { - for (uint8_t col = 0; col < COLS; col++) { - Key k = getKey (layer, row, col); - - printKey (k); - ::Focus.printSpace (); - } + for (uint8_t layer = 0; layer < maxLayers; layer++) { + for (uint8_t row = 0; row < ROWS; row++) { + for (uint8_t col = 0; col < COLS; col++) { + Key k = getKey (layer, row, col); + + printKey (k); + ::Focus.printSpace (); + } + } } - } - Serial.println (); + Serial.println (); } else { - uint16_t i = 0; - while ((Serial.peek () != '\n') && (i < ROWS * COLS * maxLayers)) { - updateKey (i, parseKey ()); - i++; - } + uint16_t i = 0; + while ((Serial.peek () != '\n') && (i < ROWS * COLS * maxLayers)) { + updateKey (i, parseKey ()); + i++; + } } return true; - } +} - bool - EEPROMKeymap::focusKeymapTransfer (const char *command) { +bool +EEPROMKeymap::focusKeymapTransfer (const char *command) { if (strcmp_P (command, PSTR ("keymap.transfer")) != 0) - return false; + return false; uint8_t layer = Serial.parseInt (); for (uint8_t row = 0; row < ROWS; row++) { - for (uint8_t col = 0; col < COLS; col++) { - Key k = Layer.getKeyFromPROGMEM (layer, row, col); - uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); + for (uint8_t col = 0; col < COLS; col++) { + Key k = Layer.getKeyFromPROGMEM (layer, row, col); + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); - updateKey (pos, k); - } + updateKey (pos, k); + } } return true; - } +} }; diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 65574d23..511cab35 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -22,7 +22,7 @@ #include namespace KaleidoscopePlugins { - class EEPROMKeymap : public KaleidoscopePlugin { +class EEPROMKeymap : public KaleidoscopePlugin { public: EEPROMKeymap (void); @@ -45,7 +45,7 @@ namespace KaleidoscopePlugins { static Key parseKey (void); static void printKey (Key key); - }; +}; }; extern KaleidoscopePlugins::EEPROMKeymap EEPROMKeymap; From e3dc58f38453a3822d0c772411636ac7c0a0a250 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 26 May 2017 16:20:21 -0700 Subject: [PATCH 193/792] make astyle --- examples/EEPROM-Settings/EEPROM-Settings.ino | 54 ++++++------ src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 82 +++++++++--------- src/Kaleidoscope/EEPROM-Settings-Focus.h | 4 +- src/Kaleidoscope/EEPROM-Settings.cpp | 88 ++++++++++---------- src/Kaleidoscope/EEPROM-Settings.h | 10 +-- src/Kaleidoscope/crc.cpp | 53 ++++++------ src/Kaleidoscope/crc.h | 14 ++-- 7 files changed, 153 insertions(+), 152 deletions(-) diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino index 7eed1f01..ef8fcc2d 100644 --- a/examples/EEPROM-Settings/EEPROM-Settings.ino +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -20,41 +20,41 @@ #include const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_skip, - - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_skip - ), + [0] = KEYMAP_STACKED + ( + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_skip + ), }; void setup () { - Serial.begin (9600); + Serial.begin (9600); - Kaleidoscope.setup (); + Kaleidoscope.setup (); - USE_PLUGINS (&EEPROMSettings); + USE_PLUGINS (&EEPROMSettings); - while (!Serial) { - } + while (!Serial) { + } - Serial.println (EEPROMSettings.isValid () ? F("valid EEPROM settings") : F("invalid EEPROM settings")); - Serial.println (EEPROMSettings.crc (), HEX); - Serial.println (EEPROMSettings.version ()); + Serial.println (EEPROMSettings.isValid () ? F("valid EEPROM settings") : F("invalid EEPROM settings")); + Serial.println (EEPROMSettings.crc (), HEX); + Serial.println (EEPROMSettings.version ()); } void loop () { - Kaleidoscope.loop (); + Kaleidoscope.loop (); } diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index b892b8dd..4a187e7e 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -21,79 +21,79 @@ #include "crc.h" namespace FocusHooks { - bool settings (const char *command) { +bool settings (const char *command) { enum { - ISVALID, - GETVERSION, - CRC, + ISVALID, + GETVERSION, + CRC, } subCommand; if (strncmp_P (command, PSTR ("settings."), 9) != 0) - return false; + return false; if (strcmp_P (command + 9, PSTR ("valid?")) == 0) - subCommand = ISVALID; + subCommand = ISVALID; else if (strcmp_P (command + 9, PSTR ("version")) == 0) - subCommand = GETVERSION; + subCommand = GETVERSION; else if (strcmp_P (command + 9, PSTR ("crc")) == 0) - subCommand = CRC; + subCommand = CRC; else - return false; + return false; switch (subCommand) { case ISVALID: - Focus.printBool (EEPROMSettings.isValid ()); - Serial.println (); - break; + Focus.printBool (EEPROMSettings.isValid ()); + Serial.println (); + break; case GETVERSION: - Serial.println (EEPROMSettings.version ()); - break; + Serial.println (EEPROMSettings.version ()); + break; case CRC: - Serial.print (::CRC.crc, HEX); - Serial.print (F("/")); - Serial.println (EEPROMSettings.crc (), HEX); - break; + Serial.print (::CRC.crc, HEX); + Serial.print (F("/")); + Serial.println (EEPROMSettings.crc (), HEX); + break; } return true; - } +} - bool eeprom (const char *command) { +bool eeprom (const char *command) { enum { - CONTENTS, - FREE, + CONTENTS, + FREE, } subCommand; if (strcmp_P (command, PSTR ("eeprom.contents")) == 0) - subCommand = CONTENTS; + subCommand = CONTENTS; else if (strcmp_P (command, PSTR ("eeprom.free")) == 0) - subCommand = FREE; + subCommand = FREE; else - return false; + return false; switch (subCommand) { case CONTENTS: { - if (Serial.peek () == '\n') { - for (uint16_t i = 0; i < EEPROM.length (); i++) { - uint8_t d = EEPROM[i]; - Focus.printNumber (d); - Focus.printSpace (); - } - Serial.println (); - } else { - for (uint16_t i = 0; i < EEPROM.length () && Serial.peek () != '\n'; i++) { - uint8_t d = Serial.parseInt (); - EEPROM.update (i, d); + if (Serial.peek () == '\n') { + for (uint16_t i = 0; i < EEPROM.length (); i++) { + uint8_t d = EEPROM[i]; + Focus.printNumber (d); + Focus.printSpace (); + } + Serial.println (); + } else { + for (uint16_t i = 0; i < EEPROM.length () && Serial.peek () != '\n'; i++) { + uint8_t d = Serial.parseInt (); + EEPROM.update (i, d); + } } - } - break; + break; } case FREE: - Serial.println (EEPROM.length () - EEPROMSettings.used ()); - break; + Serial.println (EEPROM.length () - EEPROMSettings.used ()); + break; } return true; - } +} }; diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index 32c9fb13..00e9ea6d 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -21,8 +21,8 @@ #include namespace FocusHooks { - bool settings (const char *command); - bool eeprom (const char *command); +bool settings (const char *command); +bool eeprom (const char *command); }; #define FOCUS_HOOK_SETTINGS FOCUS_HOOK(FocusHooks::settings, \ diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 5ef289f9..d81bb9f2 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -20,54 +20,54 @@ #include "crc.h" namespace KaleidoscopePlugins { - struct EEPROMSettings::settings EEPROMSettings::settings; - bool EEPROMSettings::_isValid; - bool EEPROMSettings::sealed; - uint16_t EEPROMSettings::nextStart = sizeof (EEPROMSettings::settings); +struct EEPROMSettings::settings EEPROMSettings::settings; +bool EEPROMSettings::_isValid; +bool EEPROMSettings::sealed; +uint16_t EEPROMSettings::nextStart = sizeof (EEPROMSettings::settings); - EEPROMSettings::EEPROMSettings (void) { - } +EEPROMSettings::EEPROMSettings (void) { +} - void - EEPROMSettings::begin (void) { +void +EEPROMSettings::begin (void) { EEPROM.get (0, settings); - } +} - bool - EEPROMSettings::isValid (void) { +bool +EEPROMSettings::isValid (void) { return _isValid; - } +} - uint16_t - EEPROMSettings::crc (void) { +uint16_t +EEPROMSettings::crc (void) { if (sealed) - return settings.crc; + return settings.crc; return 0; - } +} - void - EEPROMSettings::seal (void) { +void +EEPROMSettings::seal (void) { sealed = true; CRC.finalize (); if (settings.magic[0] != 'K' || settings.magic[1] != 'S') { - settings.magic[0] = 'K'; - settings.magic[1] = 'S'; - settings.version = 0; - settings.crc = CRC.crc; + settings.magic[0] = 'K'; + settings.magic[1] = 'S'; + settings.version = 0; + settings.crc = CRC.crc; - return update (); + return update (); } if (settings.crc != CRC.crc) - _isValid = false; - } + _isValid = false; +} - uint16_t - EEPROMSettings::requestSlice (uint16_t size) { +uint16_t +EEPROMSettings::requestSlice (uint16_t size) { if (sealed) - return 0; + return 0; uint16_t start = nextStart; nextStart += size; @@ -75,36 +75,36 @@ namespace KaleidoscopePlugins { CRC.update ((const void *)&size, sizeof (size)); return start; - } +} - void - EEPROMSettings::invalidate (void) { +void +EEPROMSettings::invalidate (void) { _isValid = false; - } +} - uint16_t - EEPROMSettings::used (void) { +uint16_t +EEPROMSettings::used (void) { return nextStart; - } +} - void - EEPROMSettings::update (void) { +void +EEPROMSettings::update (void) { settings.crc = CRC.crc; EEPROM.put (0, settings); _isValid = true; - } +} - uint8_t - EEPROMSettings::version (void) { +uint8_t +EEPROMSettings::version (void) { return settings.version; - } +} - void - EEPROMSettings::version (uint8_t ver) { +void +EEPROMSettings::version (uint8_t ver) { settings.version = ver; update (); - } +} }; KaleidoscopePlugins::EEPROMSettings EEPROMSettings; diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 3cd95e82..4c9e2c48 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -22,7 +22,7 @@ #include namespace KaleidoscopePlugins { - class EEPROMSettings : public KaleidoscopePlugin { +class EEPROMSettings : public KaleidoscopePlugin { public: EEPROMSettings (void); @@ -45,11 +45,11 @@ namespace KaleidoscopePlugins { static bool sealed; static struct settings { - char magic[2]; - uint8_t version; - uint16_t crc; + char magic[2]; + uint8_t version; + uint16_t crc; } settings; - }; +}; }; extern KaleidoscopePlugins::EEPROMSettings EEPROMSettings; diff --git a/src/Kaleidoscope/crc.cpp b/src/Kaleidoscope/crc.cpp index f8403548..a3a1a5e8 100644 --- a/src/Kaleidoscope/crc.cpp +++ b/src/Kaleidoscope/crc.cpp @@ -31,41 +31,40 @@ void CRC_::reflect (uint8_t len) { - uint8_t i; - uint16_t newCRC; + uint8_t i; + uint16_t newCRC; - newCRC = crc & 0x01; - for (i = 1; i < len; i++) { - crc >>= 1; - newCRC = (newCRC << 1) | (crc & 0x01); - } + newCRC = crc & 0x01; + for (i = 1; i < len; i++) { + crc >>= 1; + newCRC = (newCRC << 1) | (crc & 0x01); + } - crc = newCRC; + crc = newCRC; } void -CRC_::update (const void *data, uint8_t len) -{ - const uint8_t *d = (const uint8_t *)data; - uint8_t i; - bool bit; - uint8_t c; +CRC_::update (const void *data, uint8_t len) { + const uint8_t *d = (const uint8_t *)data; + uint8_t i; + bool bit; + uint8_t c; - while (len--) { - c = *d++; - for (i = 0x01; i & 0xff; i <<= 1) { - bit = crc & 0x8000; - if (c & i) { - bit = !bit; - } - crc <<= 1; - if (bit) { - crc ^= 0x8005; - } + while (len--) { + c = *d++; + for (i = 0x01; i & 0xff; i <<= 1) { + bit = crc & 0x8000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x8005; + } + } + crc &= 0xffff; } crc &= 0xffff; - } - crc &= 0xffff; } CRC_ CRC; diff --git a/src/Kaleidoscope/crc.h b/src/Kaleidoscope/crc.h index f3db42a9..f0f919b7 100644 --- a/src/Kaleidoscope/crc.h +++ b/src/Kaleidoscope/crc.h @@ -32,14 +32,16 @@ #include class CRC_ { - public: - uint16_t crc = 0; + public: + uint16_t crc = 0; - CRC_ (void) {}; + CRC_ (void) {}; - void update (const void *data, uint8_t len); - void finalize (void) { reflect (16); }; - void reflect (uint8_t len); + void update (const void *data, uint8_t len); + void finalize (void) { + reflect (16); + }; + void reflect (uint8_t len); }; extern CRC_ CRC; From 3adb8c28af7040f0a3f742f814cda0362e4da959 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 26 May 2017 16:20:22 -0700 Subject: [PATCH 194/792] make astyle --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 120 ++++----- src/Kaleidoscope/AlphaSquare-Effect.cpp | 70 ++--- src/Kaleidoscope/AlphaSquare-Effect.h | 28 +- src/Kaleidoscope/AlphaSquare-Symbols.h | 14 +- src/Kaleidoscope/LED-AlphaSquare.cpp | 270 +++++++++---------- src/Kaleidoscope/LED-AlphaSquare.h | 44 ++- 6 files changed, 283 insertions(+), 263 deletions(-) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index cd3fb4dc..963ebabd 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -22,83 +22,83 @@ #include const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, M(0), - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + [0] = KEYMAP_STACKED + ( + Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, M(0), + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_skip, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_skip, - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_skip - ), + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_skip + ), }; const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { - if (!key_toggled_on (keyState)) - return MACRO_NONE; + if (!key_toggled_on (keyState)) + return MACRO_NONE; - if (macroIndex == 0) { - for (uint8_t i = Key_A.keyCode; i <= Key_0.keyCode; i++) { - LEDControl.set_all_leds_to (0, 0, 0); - LEDControl.led_sync (); - delay (100); + if (macroIndex == 0) { + for (uint8_t i = Key_A.keyCode; i <= Key_0.keyCode; i++) { + LEDControl.set_all_leds_to (0, 0, 0); + LEDControl.led_sync (); + delay (100); - uint8_t col = 2; - if (i % 2) - col = 10; + uint8_t col = 2; + if (i % 2) + col = 10; - for (uint8_t step = 0; step <= 0xf0; step += 8) { - AlphaSquare.color = { step, step, step }; - AlphaSquare.display ({i, 0}, col); - delay (10); - } - for (uint8_t step = 0xff; step >= 8; step -= 8) { - AlphaSquare.color = { step, step, step }; - AlphaSquare.display ({i, 0}, col); - delay (10); - } - delay (100); - } + for (uint8_t step = 0; step <= 0xf0; step += 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display ({i, 0}, col); + delay (10); + } + for (uint8_t step = 0xff; step >= 8; step -= 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display ({i, 0}, col); + delay (10); + } + delay (100); + } - LEDControl.set_all_leds_to (0, 0, 0); - LEDControl.led_sync (); - delay (100); - for (uint8_t step = 0; step <= 0xf0; step += 8) { - AlphaSquare.color = { step, step, step }; - AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); - AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); - delay (10); - } - for (uint8_t step = 0xff; step >= 8; step -= 8) { - AlphaSquare.color = { step, step, step }; - AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); - AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); - delay (10); - } - delay (100); + LEDControl.set_all_leds_to (0, 0, 0); + LEDControl.led_sync (); + delay (100); + for (uint8_t step = 0; step <= 0xf0; step += 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); + AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); + delay (10); + } + for (uint8_t step = 0xff; step >= 8; step -= 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); + AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); + delay (10); + } + delay (100); - } - LEDControl.set_all_leds_to (0, 0, 0); + } + LEDControl.set_all_leds_to (0, 0, 0); - return MACRO_NONE; + return MACRO_NONE; } void setup () { - Kaleidoscope.setup (); + Kaleidoscope.setup (); - USE_PLUGINS (&AlphaSquare, &AlphaSquareEffect, &Macros); - AlphaSquare.color = { 0xcb, 0xc0, 0xff }; + USE_PLUGINS (&AlphaSquare, &AlphaSquareEffect, &Macros); + AlphaSquare.color = { 0xcb, 0xc0, 0xff }; } void loop () { - Kaleidoscope.loop (); + Kaleidoscope.loop (); } diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index efbe1d7b..2e5ff942 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -19,67 +19,67 @@ #include namespace KaleidoscopePlugins { - namespace LEDEffects { - uint16_t AlphaSquareEffect::length = 1000; - uint32_t AlphaSquareEffect::endTimeLeft, AlphaSquareEffect::endTimeRight; - Key AlphaSquareEffect::lastKeyLeft, AlphaSquareEffect::lastKeyRight; - uint8_t AlphaSquareEffect::us; +namespace LEDEffects { +uint16_t AlphaSquareEffect::length = 1000; +uint32_t AlphaSquareEffect::endTimeLeft, AlphaSquareEffect::endTimeRight; +Key AlphaSquareEffect::lastKeyLeft, AlphaSquareEffect::lastKeyRight; +uint8_t AlphaSquareEffect::us; - AlphaSquareEffect::AlphaSquareEffect (void) { - } +AlphaSquareEffect::AlphaSquareEffect (void) { +} - void - AlphaSquareEffect::begin (void) { - Kaleidoscope.useEventHandlerHook (eventHandlerHook); - Kaleidoscope.use (&LEDControl, NULL); - us = LEDControl.mode_add (this); - } +void +AlphaSquareEffect::begin (void) { + Kaleidoscope.useEventHandlerHook (eventHandlerHook); + Kaleidoscope.use (&LEDControl, NULL); + us = LEDControl.mode_add (this); +} - void - AlphaSquareEffect::update (void) { - if (endTimeLeft && millis () > endTimeLeft) { +void +AlphaSquareEffect::update (void) { + if (endTimeLeft && millis () > endTimeLeft) { ::AlphaSquare.clear (lastKeyLeft); endTimeLeft = 0; - } - if (endTimeRight && millis () > endTimeRight) { + } + if (endTimeRight && millis () > endTimeRight) { ::AlphaSquare.clear (lastKeyRight, 10); endTimeRight = 0; - } } +} - Key - AlphaSquareEffect::eventHandlerHook (Key key, byte row, byte col, uint8_t keyState) { - if (LEDControl.get_mode () != us) +Key +AlphaSquareEffect::eventHandlerHook (Key key, byte row, byte col, uint8_t keyState) { + if (LEDControl.get_mode () != us) return key; - if (keyState & INJECTED) + if (keyState & INJECTED) return key; - if (key < Key_A || key > Key_0) + if (key < Key_A || key > Key_0) return key; - if (!key_is_pressed (keyState)) + if (!key_is_pressed (keyState)) return key; - uint8_t displayCol = 2; - Key prevKey = lastKeyLeft; + uint8_t displayCol = 2; + Key prevKey = lastKeyLeft; - if (col < COLS / 2) { + if (col < COLS / 2) { lastKeyLeft = key; endTimeLeft = millis () + length; - } else { + } else { prevKey = lastKeyRight; lastKeyRight = key; endTimeRight = millis () + length; displayCol = 10; - } + } - if (prevKey != key) + if (prevKey != key) ::AlphaSquare.clear (prevKey, displayCol); - ::AlphaSquare.display (key, displayCol); - return key; - } - }; + ::AlphaSquare.display (key, displayCol); + return key; +} +}; }; KaleidoscopePlugins::LEDEffects::AlphaSquareEffect AlphaSquareEffect; diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 77da2a76..7ffbec73 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -22,23 +22,23 @@ #include namespace KaleidoscopePlugins { - namespace LEDEffects { - class AlphaSquareEffect : public LEDMode { - public: - AlphaSquareEffect (void); +namespace LEDEffects { +class AlphaSquareEffect : public LEDMode { + public: + AlphaSquareEffect (void); - virtual void begin (void) final; - virtual void update (void) final; + virtual void begin (void) final; + virtual void update (void) final; - static uint16_t length; - private: - static uint32_t endTimeLeft, endTimeRight; - static Key lastKeyLeft, lastKeyRight; - static uint8_t us; + static uint16_t length; + private: + static uint32_t endTimeLeft, endTimeRight; + static Key lastKeyLeft, lastKeyRight; + static uint8_t us; - static Key eventHandlerHook (Key key, uint8_t row, uint8_t col, uint8_t keyState); - }; - }; + static Key eventHandlerHook (Key key, uint8_t row, uint8_t col, uint8_t keyState); +}; +}; }; extern KaleidoscopePlugins::LEDEffects::AlphaSquareEffect AlphaSquareEffect; diff --git a/src/Kaleidoscope/AlphaSquare-Symbols.h b/src/Kaleidoscope/AlphaSquare-Symbols.h index 52133e27..80f5b09e 100644 --- a/src/Kaleidoscope/AlphaSquare-Symbols.h +++ b/src/Kaleidoscope/AlphaSquare-Symbols.h @@ -21,11 +21,11 @@ #include namespace KaleidoscopePlugins { - namespace AlphaSquareSymbols { - /* λ */ - static constexpr uint16_t Lambda = SYM4x4(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 1, 1, 0, - 1, 0, 0, 1); - }; +namespace AlphaSquareSymbols { +/* λ */ +static constexpr uint16_t Lambda = SYM4x4(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 1, 1, 0, + 1, 0, 0, 1); +}; }; diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 9fda9d51..2a2c02ba 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -20,198 +20,198 @@ namespace KaleidoscopePlugins { - static const uint16_t alphabet[] PROGMEM = { +static const uint16_t alphabet[] PROGMEM = { SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 1), // A + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 1), // A SYM4x4(1, 1, 1, 1, - 1, 0, 1, 1, - 1, 1, 0, 1, - 1, 1, 1, 1), // B + 1, 0, 1, 1, + 1, 1, 0, 1, + 1, 1, 1, 1), // B SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // C + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // C SYM4x4(1, 1, 1, 0, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 0), // D + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0), // D SYM4x4(1, 1, 1, 1, - 1, 1, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // E + 1, 1, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // E SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 1, 1, 1, 0, - 1, 0, 0, 0), // F + 1, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 0), // F SYM4x4(1, 1, 1, 0, - 1, 0, 0, 0, - 1, 0, 0, 1, - 1, 1, 1, 1), // G + 1, 0, 0, 0, + 1, 0, 0, 1, + 1, 1, 1, 1), // G SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 0, 1), // H + 1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1), // H SYM4x4(1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 1, 1, 1, 1), // I + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 1, 1, 1), // I SYM4x4(1, 1, 1, 1, - 0, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // J + 0, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // J SYM4x4(1, 0, 0, 1, - 1, 1, 0, 0, - 1, 1, 0, 0, - 1, 0, 1, 1), // K + 1, 1, 0, 0, + 1, 1, 0, 0, + 1, 0, 1, 1), // K SYM4x4(1, 0, 0, 0, - 1, 0, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // L + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // L SYM4x4(1, 0, 1, 1, - 1, 1, 1, 1, - 1, 1, 0, 1, - 1, 0, 0, 1), // M + 1, 1, 1, 1, + 1, 1, 0, 1, + 1, 0, 0, 1), // M SYM4x4(1, 0, 0, 1, - 1, 1, 0, 1, - 1, 0, 1, 1, - 1, 0, 0, 1), // N + 1, 1, 0, 1, + 1, 0, 1, 1, + 1, 0, 0, 1), // N SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 1), // O + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1), // O SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 0), // P + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 0), // P SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 1, 1, - 1, 1, 1, 1), // Q + 1, 0, 0, 1, + 1, 0, 1, 1, + 1, 1, 1, 1), // Q SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 0, - 1, 0, 1, 1), // R + 1, 0, 0, 1, + 1, 1, 1, 0, + 1, 0, 1, 1), // R SYM4x4(1, 1, 1, 1, - 1, 1, 0, 0, - 0, 0, 1, 1, - 1, 1, 1, 1), // S + 1, 1, 0, 0, + 0, 0, 1, 1, + 1, 1, 1, 1), // S SYM4x4(1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 0, 1, 1, 0), // T + 0, 1, 1, 0, + 0, 1, 1, 0, + 0, 1, 1, 0), // T SYM4x4(1, 0, 0, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 1), // U + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1), // U SYM4x4(1, 0, 0, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // V + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // V SYM4x4(1, 0, 0, 1, - 1, 0, 1, 1, - 1, 1, 1, 1, - 1, 0, 1, 1), // W + 1, 0, 1, 1, + 1, 1, 1, 1, + 1, 0, 1, 1), // W SYM4x4(1, 0, 0, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 1, 0, 0, 1), // X + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 0, 0, 1), // X SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0), // Y + 1, 1, 1, 1, + 0, 1, 1, 0, + 0, 1, 1, 0), // Y SYM4x4(1, 1, 1, 1, - 0, 0, 1, 1, - 1, 1, 0, 0, - 1, 1, 1, 1), // Z + 0, 0, 1, 1, + 1, 1, 0, 0, + 1, 1, 1, 1), // Z // --------------------- SYM4x4(0, 1, 1, 0, - 1, 0, 1, 0, - 0, 0, 1, 0, - 1, 1, 1, 1), // 1 + 1, 0, 1, 0, + 0, 0, 1, 0, + 1, 1, 1, 1), // 1 SYM4x4(0, 1, 1, 0, - 1, 0, 0, 1, - 0, 0, 1, 0, - 1, 1, 0, 1), // 2 + 1, 0, 0, 1, + 0, 0, 1, 0, + 1, 1, 0, 1), // 2 SYM4x4(1, 1, 1, 1, - 0, 0, 1, 1, - 0, 0, 0, 1, - 1, 1, 1, 1), // 3 + 0, 0, 1, 1, + 0, 0, 0, 1, + 1, 1, 1, 1), // 3 SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 0, 0, 0, 1, - 0, 0, 0, 1), // 4 + 1, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 0, 1), // 4 SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 0, 1, 1, 1, - 1, 1, 1, 1), // 5 + 1, 0, 0, 0, + 0, 1, 1, 1, + 1, 1, 1, 1), // 5 SYM4x4(0, 1, 1, 0, - 1, 0, 0, 0, - 1, 1, 1, 1, - 1, 1, 1, 1), // 6 + 1, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1), // 6 SYM4x4(1, 1, 1, 1, - 0, 0, 0, 1, - 0, 0, 1, 0, - 0, 1, 0, 0), // 7 + 0, 0, 0, 1, + 0, 0, 1, 0, + 0, 1, 0, 0), // 7 SYM4x4(1, 1, 1, 0, - 1, 0, 1, 1, - 1, 1, 0, 1, - 0, 1, 1, 1), // 8 + 1, 0, 1, 1, + 1, 1, 0, 1, + 0, 1, 1, 1), // 8 SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 0, 0, 0, 1), // 9 + 1, 0, 0, 1, + 1, 1, 1, 1, + 0, 0, 0, 1), // 9 SYM4x4(0, 1, 1, 0, - 1, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // 0 - }; + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // 0 +}; - cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; +cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; - AlphaSquare::AlphaSquare (void) { - } +AlphaSquare::AlphaSquare (void) { +} - void - AlphaSquare::begin (void) { - } +void +AlphaSquare::begin (void) { +} - void - AlphaSquare::display (Key key, uint8_t row, uint8_t col, cRGB keyColor) { +void +AlphaSquare::display (Key key, uint8_t row, uint8_t col, cRGB keyColor) { if (key < Key_A || key > Key_0) - return; + return; uint8_t index = key.keyCode - Key_A.keyCode; uint16_t symbol = pgm_read_word (&alphabet[index]); display (symbol, row, col, keyColor); - } +} - void - AlphaSquare::display (Key key, uint8_t row, uint8_t col) { +void +AlphaSquare::display (Key key, uint8_t row, uint8_t col) { display (key, row, col, color); - } +} - void - AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor) { +void +AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor) { for (uint8_t r = 0; r < 4; r++) { - for (uint8_t c = 0; c < 4; c++) { - uint8_t pixel = bitRead (symbol, r * 4 + c); - if (!pixel) - continue; + for (uint8_t c = 0; c < 4; c++) { + uint8_t pixel = bitRead (symbol, r * 4 + c); + if (!pixel) + continue; - LEDControl.led_set_crgb_at (row + r, col + c, keyColor); - } + LEDControl.led_set_crgb_at (row + r, col + c, keyColor); + } } LEDControl.led_sync (); - } +} - void - AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col) { +void +AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col) { display (symbol, row, col, color); - } +} }; KaleidoscopePlugins::AlphaSquare AlphaSquare; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index a26b5b3a..71588c78 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -35,7 +35,7 @@ ) namespace KaleidoscopePlugins { - class AlphaSquare : public KaleidoscopePlugin { +class AlphaSquare : public KaleidoscopePlugin { public: AlphaSquare (void); @@ -43,24 +43,44 @@ namespace KaleidoscopePlugins { static void display (Key key, uint8_t row, uint8_t col, cRGB keyColor); static void display (Key key, uint8_t row, uint8_t col); - static void display (Key key) { display (key, 0, 2); }; - static void display (Key key, uint8_t col) { display (key, 0, col); }; + static void display (Key key) { + display (key, 0, 2); + }; + static void display (Key key, uint8_t col) { + display (key, 0, col); + }; static void display (uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor); static void display (uint16_t symbol, uint8_t row, uint8_t col); - static void display (uint16_t symbol) { display (symbol, 0, 2); }; - static void display (uint16_t symbol, uint8_t col) { display (symbol, 0, col); }; + static void display (uint16_t symbol) { + display (symbol, 0, 2); + }; + static void display (uint16_t symbol, uint8_t col) { + display (symbol, 0, col); + }; - static void clear (Key key, uint8_t row, uint8_t col) { display (key, row, col, {0, 0, 0}); }; - static void clear (Key key, uint8_t col) { clear (key, 0, col); }; - static void clear (Key key) { clear (key, 0, 2); }; + static void clear (Key key, uint8_t row, uint8_t col) { + display (key, row, col, {0, 0, 0}); + }; + static void clear (Key key, uint8_t col) { + clear (key, 0, col); + }; + static void clear (Key key) { + clear (key, 0, 2); + }; - static void clear (uint16_t symbol, uint8_t row, uint8_t col) { display (symbol, row, col, {0, 0, 0}); }; - static void clear (uint16_t symbol, uint8_t col) { clear (symbol, 0, col); }; - static void clear (uint16_t symbol) { clear (symbol, 0, 2); }; + static void clear (uint16_t symbol, uint8_t row, uint8_t col) { + display (symbol, row, col, {0, 0, 0}); + }; + static void clear (uint16_t symbol, uint8_t col) { + clear (symbol, 0, col); + }; + static void clear (uint16_t symbol) { + clear (symbol, 0, 2); + }; static cRGB color; - }; +}; }; extern KaleidoscopePlugins::AlphaSquare AlphaSquare; From 46d40dd3d58c3c08ccef13768f59df702cb8c3a2 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 26 May 2017 16:20:22 -0700 Subject: [PATCH 195/792] make astyle --- examples/LED-Stalker/LED-Stalker.ino | 46 +++--- src/Kaleidoscope/LED-Stalker.cpp | 213 ++++++++++++++------------- src/Kaleidoscope/LED-Stalker.h | 70 ++++----- 3 files changed, 166 insertions(+), 163 deletions(-) diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index d3a5e276..3b82cbeb 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -22,35 +22,35 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_NoKey, - - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_NoKey - ), + [0] = KEYMAP_STACKED + ( + Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_NoKey, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_NoKey + ), }; void setup () { - Kaleidoscope.setup (); + Kaleidoscope.setup (); - StalkerEffect.configure (STALKER (BlazingTrail, NULL)); - USE_PLUGINS (&LEDOff, &StalkerEffect); + StalkerEffect.configure (STALKER (BlazingTrail, NULL)); + USE_PLUGINS (&LEDOff, &StalkerEffect); - StalkerEffect.activate (); + StalkerEffect.activate (); } void loop () { - Kaleidoscope.loop (); + Kaleidoscope.loop (); } diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index f7db1aa5..adc9b518 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -20,132 +20,133 @@ #include namespace KaleidoscopePlugins { - namespace LEDEffects { - uint8_t StalkerEffect::map[ROWS][COLS]; - StalkerEffect::ColorComputer *StalkerEffect::colorComputer; - uint16_t StalkerEffect::stepLength = 50; - uint32_t StalkerEffect::stepEndTime; - - StalkerEffect::StalkerEffect (void) { - } - - void - StalkerEffect::configure (ColorComputer *colorComputer_) { - colorComputer = colorComputer_; - } - - void - StalkerEffect::begin (void) { - event_handler_hook_use (eventHandlerHook); - LEDMode::begin (); - } - - void - StalkerEffect::init (void) { - memset (map, 0, sizeof (map)); - } - - Key - StalkerEffect::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) { - if (row >= ROWS || col >= COLS) +namespace LEDEffects { +uint8_t StalkerEffect::map[ROWS][COLS]; +StalkerEffect::ColorComputer *StalkerEffect::colorComputer; +uint16_t StalkerEffect::stepLength = 50; +uint32_t StalkerEffect::stepEndTime; + +StalkerEffect::StalkerEffect (void) { +} + +void +StalkerEffect::configure (ColorComputer *colorComputer_) { + colorComputer = colorComputer_; +} + +void +StalkerEffect::begin (void) { + event_handler_hook_use (eventHandlerHook); + LEDMode::begin (); +} + +void +StalkerEffect::init (void) { + memset (map, 0, sizeof (map)); +} + +Key +StalkerEffect::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) { + if (row >= ROWS || col >= COLS) return mappedKey; - if (key_is_pressed (keyState)) { + if (key_is_pressed (keyState)) { map[row][col] = 0xff; - } - - return mappedKey; } - void - StalkerEffect::update (void) { - if (!colorComputer) + return mappedKey; +} + +void +StalkerEffect::update (void) { + if (!colorComputer) return; - bool timeOut = millis () >= stepEndTime; + bool timeOut = millis () >= stepEndTime; - for (byte r = 0; r < ROWS; r++) { + for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { - uint8_t step = map[r][c]; - if (step) { - LEDControl.led_set_crgb_at (r, c, colorComputer->compute (&step)); - } + uint8_t step = map[r][c]; + if (step) { + LEDControl.led_set_crgb_at (r, c, colorComputer->compute (&step)); + } - bool wasZero = (map[r][c] == 0); + bool wasZero = (map[r][c] == 0); - if (timeOut) { - map[r][c] = step; - } + if (timeOut) { + map[r][c] = step; + } - if (!wasZero && !map[r][c]) - LEDControl.led_set_crgb_at (r, c, (cRGB){0, 0, 0}); + if (!wasZero && !map[r][c]) + LEDControl.led_set_crgb_at (r, c, (cRGB) { + 0, 0, 0 + }); } - } + } - if (timeOut) + if (timeOut) stepEndTime = millis () + stepLength; +} + +namespace Stalker { + +cRGB Haunt::highlightColor; + +// Haunt +Haunt::Haunt (const cRGB highlightColor_) { + highlightColor = highlightColor_; +} + +cRGB +Haunt::compute (uint8_t *step) { + cRGB color = CRGB((uint8_t)min(*step * highlightColor.r / 255, 255), + (uint8_t)min(*step * highlightColor.g / 255, 255), + (uint8_t)min(*step * highlightColor.b / 255, 255)); + + if (*step >= 0xf0) + *step -= 1; + else if (*step >= 0x40) + *step -= 16; + else if (*step >= 32) + *step -= 32; + else + *step = 0; + + return color; +} + +// BlazingTrail +BlazingTrail::BlazingTrail (...) { +} + +cRGB +BlazingTrail::compute (uint8_t *step) { + cRGB color; + + if (*step >= 0xff - 30) { + color = hsv_to_rgb (0xff - *step, 255, 255); + } else { + color = hsv_to_rgb (30, 255, 255); + + color.r = min(*step * color.r / 255, 255); + color.g = min(*step * color.g / 255, 255); } - namespace Stalker { - - cRGB Haunt::highlightColor; + if (*step >= 0xf0 - 30) + *step -= 1; + else if (*step >= 0x40) + *step -= 16; + else if (*step >= 32) + *step -= 32; + else + *step = 0; - // Haunt - Haunt::Haunt (const cRGB highlightColor_) { - highlightColor = highlightColor_; - } + return color; +} - cRGB - Haunt::compute (uint8_t *step) { - cRGB color = CRGB((uint8_t)min(*step * highlightColor.r / 255, 255), - (uint8_t)min(*step * highlightColor.g / 255, 255), - (uint8_t)min(*step * highlightColor.b / 255, 255)); - - if (*step >= 0xf0) - *step -= 1; - else if (*step >= 0x40) - *step -= 16; - else if (*step >= 32) - *step -= 32; - else - *step = 0; - - return color; - } - - // BlazingTrail - BlazingTrail::BlazingTrail (...) { - } - - cRGB - BlazingTrail::compute (uint8_t *step) { - cRGB color; - - if (*step >= 0xff - 30) { - color = hsv_to_rgb (0xff - *step, 255, 255); - } - else { - color = hsv_to_rgb (30, 255, 255); - - color.r = min(*step * color.r / 255, 255); - color.g = min(*step * color.g / 255, 255); - } - - if (*step >= 0xf0 - 30) - *step -= 1; - else if (*step >= 0x40) - *step -= 16; - else if (*step >= 32) - *step -= 32; - else - *step = 0; - - return color; - } - - }; +}; - }; +}; }; KaleidoscopePlugins::LEDEffects::StalkerEffect StalkerEffect; diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 89c9ab3c..de5e1ee4 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -22,54 +22,56 @@ #define STALKER(n, ...) (({static KaleidoscopePlugins::LEDEffects::Stalker::n _effect (__VA_ARGS__); &_effect;})) namespace KaleidoscopePlugins { - namespace LEDEffects { - class StalkerEffect : public LEDMode { - public: - class ColorComputer { +namespace LEDEffects { +class StalkerEffect : public LEDMode { + public: + class ColorComputer { public: virtual cRGB compute (uint8_t *step) = 0; - }; + }; - StalkerEffect (void); + StalkerEffect (void); - virtual void begin (void) final; - virtual void init (void) final; - virtual void update (void) final; + virtual void begin (void) final; + virtual void init (void) final; + virtual void update (void) final; - static void configure (ColorComputer *colorComputer); - static uint16_t stepLength; + static void configure (ColorComputer *colorComputer); + static uint16_t stepLength; - private: - static uint32_t stepEndTime; - static ColorComputer *colorComputer; - static uint8_t map[ROWS][COLS]; + private: + static uint32_t stepEndTime; + static ColorComputer *colorComputer; + static uint8_t map[ROWS][COLS]; - static Key eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState); - }; + static Key eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState); +}; - namespace Stalker { +namespace Stalker { - class Haunt : public StalkerEffect::ColorComputer { - public: - Haunt (const cRGB highlightColor); - Haunt (void) : Haunt ({0x40, 0x80, 0x80}) {}; - Haunt (void *) : Haunt () {}; +class Haunt : public StalkerEffect::ColorComputer { + public: + Haunt (const cRGB highlightColor); + Haunt (void) : Haunt ( { + 0x40, 0x80, 0x80 + }) {}; + Haunt (void *) : Haunt () {}; - virtual cRGB compute (uint8_t *step) final; - private: - static cRGB highlightColor; - }; + virtual cRGB compute (uint8_t *step) final; + private: + static cRGB highlightColor; +}; - class BlazingTrail : public StalkerEffect::ColorComputer { - public: - BlazingTrail (...); +class BlazingTrail : public StalkerEffect::ColorComputer { + public: + BlazingTrail (...); - virtual cRGB compute (uint8_t *step) final; - }; + virtual cRGB compute (uint8_t *step) final; +}; - }; +}; - }; +}; }; extern KaleidoscopePlugins::LEDEffects::StalkerEffect StalkerEffect; From 26e7e187dfe5f23c08b8b4f157af3f4c52ecf5fa Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 26 May 2017 16:20:23 -0700 Subject: [PATCH 196/792] make astyle --- examples/MagicCombo/MagicCombo.ino | 59 +++++++++++++++--------------- src/Kaleidoscope/MagicCombo.cpp | 54 +++++++++++++-------------- src/Kaleidoscope/MagicCombo.h | 6 +-- 3 files changed, 60 insertions(+), 59 deletions(-) diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index d2114326..b216cd5f 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -20,51 +20,52 @@ #include void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { - switch (comboIndex) { - case 0: - Serial.println ("It's a kind of magic!"); - break; - } + switch (comboIndex) { + case 0: + Serial.println ("It's a kind of magic!"); + break; + } } static const KaleidoscopePlugins::MagicCombo::dictionary_t dictionary[] PROGMEM = { - {R1C3 | R2C1 | R2C4 | R2C7, // left hand, - R0C11 | R1C12 | R2C14 //right hand - }, - {0, 0} + { + R1C3 | R2C1 | R2C4 | R2C7, // left hand, + R0C11 | R1C12 | R2C14 //right hand + }, + {0, 0} }; const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + [0] = KEYMAP_STACKED + ( + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_NoKey, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_NoKey, - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_NoKey - ), + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_NoKey + ), }; void setup () { - Serial.begin (9600); + Serial.begin (9600); - MagicCombo.configure (dictionary); + MagicCombo.configure (dictionary); - Kaleidoscope.setup (KEYMAP_SIZE); - Kaleidoscope.use (&MagicCombo, NULL); + Kaleidoscope.setup (KEYMAP_SIZE); + Kaleidoscope.use (&MagicCombo, NULL); } void loop () { - Kaleidoscope.loop (); + Kaleidoscope.loop (); } diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index 50b34b91..85b9f200 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -30,47 +30,47 @@ namespace KaleidoscopePlugins { - const MagicCombo::dictionary_t *MagicCombo::dictionary; - uint16_t MagicCombo::minInterval = 500; - uint32_t MagicCombo::endTime; +const MagicCombo::dictionary_t *MagicCombo::dictionary; +uint16_t MagicCombo::minInterval = 500; +uint32_t MagicCombo::endTime; - MagicCombo::MagicCombo (void) { - } +MagicCombo::MagicCombo (void) { +} - void - MagicCombo::begin (void) { +void +MagicCombo::begin (void) { loop_hook_use (this->loopHook); - } +} - void - MagicCombo::configure (const MagicCombo::dictionary_t dictionary_[]) { +void +MagicCombo::configure (const MagicCombo::dictionary_t dictionary_[]) { dictionary = (dictionary_t *)dictionary_; - } +} - void - MagicCombo::loopHook (bool postClear) { +void +MagicCombo::loopHook (bool postClear) { if (!dictionary || postClear) - return; + return; for (byte i = 0;; i++) { - dictionary_t combo; + dictionary_t combo; - combo.leftHand = pgm_read_dword (&(dictionary[i].leftHand)); - combo.rightHand = pgm_read_dword (&(dictionary[i].rightHand)); + combo.leftHand = pgm_read_dword (&(dictionary[i].leftHand)); + combo.rightHand = pgm_read_dword (&(dictionary[i].rightHand)); - if (combo.leftHand == 0 && combo.rightHand == 0) - break; + if (combo.leftHand == 0 && combo.rightHand == 0) + break; - if (LEFTHANDSTATE.all == combo.leftHand && - RIGHTHANDSTATE.all == combo.rightHand) { - if (millis () >= endTime) { - magicComboActions (i, combo.leftHand, combo.rightHand); - endTime = millis () + minInterval; + if (LEFTHANDSTATE.all == combo.leftHand && + RIGHTHANDSTATE.all == combo.rightHand) { + if (millis () >= endTime) { + magicComboActions (i, combo.leftHand, combo.rightHand); + endTime = millis () + minInterval; + } + break; } - break; - } } - } +} }; diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 4d505d0b..d7234c5b 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -21,10 +21,10 @@ #include namespace KaleidoscopePlugins { - class MagicCombo : public KaleidoscopePlugin { +class MagicCombo : public KaleidoscopePlugin { public: typedef struct { - uint32_t leftHand, rightHand; + uint32_t leftHand, rightHand; } dictionary_t; MagicCombo (void); @@ -39,7 +39,7 @@ namespace KaleidoscopePlugins { static uint32_t endTime; static void loopHook (bool postClear); - }; +}; }; void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand); From ede5fdba6c96e70fefc5243a0edb49601a2bd9aa Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 26 May 2017 16:38:02 -0700 Subject: [PATCH 197/792] astyle with astyle 3.0, which matters for this code --- src/Kaleidoscope/AlphaSquare-Effect.h | 4 +- src/Kaleidoscope/LED-AlphaSquare.cpp | 216 +++++++++++++------------- src/Kaleidoscope/LED-AlphaSquare.h | 2 +- 3 files changed, 111 insertions(+), 111 deletions(-) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 7ffbec73..3d4f79a7 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -24,14 +24,14 @@ namespace KaleidoscopePlugins { namespace LEDEffects { class AlphaSquareEffect : public LEDMode { - public: +public: AlphaSquareEffect (void); virtual void begin (void) final; virtual void update (void) final; static uint16_t length; - private: +private: static uint32_t endTimeLeft, endTimeRight; static Key lastKeyLeft, lastKeyRight; static uint8_t us; diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 2a2c02ba..6b64d10b 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -22,150 +22,150 @@ namespace KaleidoscopePlugins { static const uint16_t alphabet[] PROGMEM = { SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 1), // A + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 1), // A SYM4x4(1, 1, 1, 1, - 1, 0, 1, 1, - 1, 1, 0, 1, - 1, 1, 1, 1), // B + 1, 0, 1, 1, + 1, 1, 0, 1, + 1, 1, 1, 1), // B SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // C + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // C SYM4x4(1, 1, 1, 0, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 0), // D + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0), // D SYM4x4(1, 1, 1, 1, - 1, 1, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // E + 1, 1, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // E SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 1, 1, 1, 0, - 1, 0, 0, 0), // F + 1, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 0), // F SYM4x4(1, 1, 1, 0, - 1, 0, 0, 0, - 1, 0, 0, 1, - 1, 1, 1, 1), // G + 1, 0, 0, 0, + 1, 0, 0, 1, + 1, 1, 1, 1), // G SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 0, 1), // H + 1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1), // H SYM4x4(1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 1, 1, 1, 1), // I + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 1, 1, 1), // I SYM4x4(1, 1, 1, 1, - 0, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // J + 0, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // J SYM4x4(1, 0, 0, 1, - 1, 1, 0, 0, - 1, 1, 0, 0, - 1, 0, 1, 1), // K + 1, 1, 0, 0, + 1, 1, 0, 0, + 1, 0, 1, 1), // K SYM4x4(1, 0, 0, 0, - 1, 0, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // L + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // L SYM4x4(1, 0, 1, 1, - 1, 1, 1, 1, - 1, 1, 0, 1, - 1, 0, 0, 1), // M + 1, 1, 1, 1, + 1, 1, 0, 1, + 1, 0, 0, 1), // M SYM4x4(1, 0, 0, 1, - 1, 1, 0, 1, - 1, 0, 1, 1, - 1, 0, 0, 1), // N + 1, 1, 0, 1, + 1, 0, 1, 1, + 1, 0, 0, 1), // N SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 1), // O + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1), // O SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 0), // P + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 0), // P SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 1, 1, - 1, 1, 1, 1), // Q + 1, 0, 0, 1, + 1, 0, 1, 1, + 1, 1, 1, 1), // Q SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 0, - 1, 0, 1, 1), // R + 1, 0, 0, 1, + 1, 1, 1, 0, + 1, 0, 1, 1), // R SYM4x4(1, 1, 1, 1, - 1, 1, 0, 0, - 0, 0, 1, 1, - 1, 1, 1, 1), // S + 1, 1, 0, 0, + 0, 0, 1, 1, + 1, 1, 1, 1), // S SYM4x4(1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 0, 1, 1, 0), // T + 0, 1, 1, 0, + 0, 1, 1, 0, + 0, 1, 1, 0), // T SYM4x4(1, 0, 0, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 1), // U + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1), // U SYM4x4(1, 0, 0, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // V + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // V SYM4x4(1, 0, 0, 1, - 1, 0, 1, 1, - 1, 1, 1, 1, - 1, 0, 1, 1), // W + 1, 0, 1, 1, + 1, 1, 1, 1, + 1, 0, 1, 1), // W SYM4x4(1, 0, 0, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 1, 0, 0, 1), // X + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 0, 0, 1), // X SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0), // Y + 1, 1, 1, 1, + 0, 1, 1, 0, + 0, 1, 1, 0), // Y SYM4x4(1, 1, 1, 1, - 0, 0, 1, 1, - 1, 1, 0, 0, - 1, 1, 1, 1), // Z + 0, 0, 1, 1, + 1, 1, 0, 0, + 1, 1, 1, 1), // Z // --------------------- SYM4x4(0, 1, 1, 0, - 1, 0, 1, 0, - 0, 0, 1, 0, - 1, 1, 1, 1), // 1 + 1, 0, 1, 0, + 0, 0, 1, 0, + 1, 1, 1, 1), // 1 SYM4x4(0, 1, 1, 0, - 1, 0, 0, 1, - 0, 0, 1, 0, - 1, 1, 0, 1), // 2 + 1, 0, 0, 1, + 0, 0, 1, 0, + 1, 1, 0, 1), // 2 SYM4x4(1, 1, 1, 1, - 0, 0, 1, 1, - 0, 0, 0, 1, - 1, 1, 1, 1), // 3 + 0, 0, 1, 1, + 0, 0, 0, 1, + 1, 1, 1, 1), // 3 SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 0, 0, 0, 1, - 0, 0, 0, 1), // 4 + 1, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 0, 1), // 4 SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 0, 1, 1, 1, - 1, 1, 1, 1), // 5 + 1, 0, 0, 0, + 0, 1, 1, 1, + 1, 1, 1, 1), // 5 SYM4x4(0, 1, 1, 0, - 1, 0, 0, 0, - 1, 1, 1, 1, - 1, 1, 1, 1), // 6 + 1, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1), // 6 SYM4x4(1, 1, 1, 1, - 0, 0, 0, 1, - 0, 0, 1, 0, - 0, 1, 0, 0), // 7 + 0, 0, 0, 1, + 0, 0, 1, 0, + 0, 1, 0, 0), // 7 SYM4x4(1, 1, 1, 0, - 1, 0, 1, 1, - 1, 1, 0, 1, - 0, 1, 1, 1), // 8 + 1, 0, 1, 1, + 1, 1, 0, 1, + 0, 1, 1, 1), // 8 SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 0, 0, 0, 1), // 9 + 1, 0, 0, 1, + 1, 1, 1, 1, + 0, 0, 0, 1), // 9 SYM4x4(0, 1, 1, 0, - 1, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // 0 + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // 0 }; cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index 71588c78..a980f979 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -36,7 +36,7 @@ namespace KaleidoscopePlugins { class AlphaSquare : public KaleidoscopePlugin { - public: +public: AlphaSquare (void); virtual void begin (void) final; From 356dd681f92336632505ecd98126b4e3ce38499f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 26 May 2017 16:41:36 -0700 Subject: [PATCH 198/792] astyle 3.0 fixups --- src/Kaleidoscope/AlphaSquare-Effect.h | 4 ++-- src/Kaleidoscope/LED-AlphaSquare.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 3d4f79a7..7ffbec73 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -24,14 +24,14 @@ namespace KaleidoscopePlugins { namespace LEDEffects { class AlphaSquareEffect : public LEDMode { -public: + public: AlphaSquareEffect (void); virtual void begin (void) final; virtual void update (void) final; static uint16_t length; -private: + private: static uint32_t endTimeLeft, endTimeRight; static Key lastKeyLeft, lastKeyRight; static uint8_t us; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index a980f979..71588c78 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -36,7 +36,7 @@ namespace KaleidoscopePlugins { class AlphaSquare : public KaleidoscopePlugin { -public: + public: AlphaSquare (void); virtual void begin (void) final; From 733511fc3753dc8591118ef1c857d55c96f85ab2 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 1 Jun 2017 15:54:20 +0200 Subject: [PATCH 199/792] Add a `get_led_index` function Given a `row`/`col` coordinate, this new function returns the index of the LED under that key. To be used with the `led_set_crgb_at(i, crgb)` function. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 4 ++++ src/Kaleidoscope-Hardware-Model01.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 4af44fcc..07c95730 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -82,6 +82,10 @@ void Model01::led_set_crgb_at(byte row, byte col, cRGB color) { led_set_crgb_at(key_led_map[row][col], color); } +uint8_t Model01::get_led_index(byte row, byte col) { + return key_led_map[row][col]; +} + cRGB Model01::led_get_crgb_at(uint8_t i) { if(i<32) { return leftHand.ledData.leds[i]; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 045df7fe..f43b7bff 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -18,6 +18,7 @@ class Model01 { void led_set_crgb_at(uint8_t i, cRGB crgb); cRGB led_get_crgb_at(uint8_t i); cRGB get_key_color(byte row, byte col); + uint8_t get_led_index(byte row, byte col); void scan_matrix(void); void read_matrix(void); From ba6128dddc989ca7494ff4a69ef727d769d19313 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 3 Jun 2017 10:07:48 +0200 Subject: [PATCH 200/792] Kaleidoscope Style Guide conformance Updated the code to conform to the latest style guide. And added a bit of documentation too, while there. Signed-off-by: Gergely Nagy --- README.md | 78 ++++++++++-- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 62 +++++----- src/Kaleidoscope/EEPROM-Keymap.cpp | 148 +++++++++++------------ src/Kaleidoscope/EEPROM-Keymap.h | 35 +++--- 4 files changed, 185 insertions(+), 138 deletions(-) diff --git a/README.md b/README.md index 2c6c1285..7f17b417 100644 --- a/README.md +++ b/README.md @@ -5,26 +5,54 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap - [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 -TODO +While keyboards usually ship with a keymap programmed in, to be able to change +that keymap, without flashing new firmware, we need a way to place the keymap +into a place we can update at run-time, and which persists across reboots. +Fortunately, we have a bit of `EEPROM` on the keyboard, and can use it to store +either the full keymap (and saving space in the firmware then), or store an +overlay there. In the latter case, whenever there is a non-transparent key on +the overlay, we will use that instead of the keyboard default. + +In short, this plugin allows us to change our keymaps, without having to compile +and flash new firmware. It does so through the use of the [Focus][plugin:focus] +plugin. + + [plugin:focus]: https://github.com/keyboardio/Kaleidoscope-Focus ## Using the plugin -TODO +Using the plugin is reasonably simple: after including the header, enable the +plugin, and let the `Layer` object know that we'll be using `EEPROMKeymap` to +figure out which keys to use. We can either use the `getKeyOverride` or the +`getKey` method, depending on whether we want to override, or fully replace the +built-in keymap. Then we need to set at most how many layers we want to store in +`EEPROM`, and that is about it. + +We can then update the keymap via [Focus][plugin:focus]. ```c++ #include #include +#include +#include -void setup () { - Kaleidoscope.setup (); +void setup() { + Serial.begin(9600); + USE_PLUGINS(&EEPROMKeymap, &Focus); - USE_PLUGINS (&EEPROMKeymap); + Kaleidoscope.setup(); + + Focus.addHook(FOCUS_HOOK_KEYMAP); + Focus.addHook(FOCUS_HOOK_KEYMAP_TRANSFER); + + Layer.getKey = EEPROMKeymap.getKeyOverride; - // TODO + EEPROMKeymap.max_layers(1); + EEPROMSettings.seal(); } ``` @@ -32,7 +60,37 @@ void setup () { The plugin provides the `EEPROMKeymap` object, which has the following methods: -**TODO** +### `.max_layers(max)` + +> Tells the extension to reserve space in EEPROM for up to `max` layers. Can +> only be called once, any subsequent call will be a no-op. + +## Focus commands + +The plugin provides two `Focus` hooks: `FOCUS_HOOK_KEYMAP`, and +`FOCUS_HOOK_KEYMAP_TRANSFER`. Together, they make the following commands +available, respectively: + +### `keymap.map [codes...]` + +> Without arguments, displays the keymap currently in effect. Each key is +> printed as its raw, 16-bit keycode. +> +> With arguments, it stores as many keys as given. One does not need to set all +> keys, on all layers: the command will start from the first key on the first +> layer, and go on as long as it has input. It will not go past the layer set +> via the `.max_layers()` method. + +### `keymap.transfer LAYER` + +> Transfers the `LAYER` from the built-in memory of the keyboard into `EEPROM` +> storage. +> +> Useful mostly when one wants to remove the built-in keymap, and wants to +> easily transfer it into `EEPROM` first. +> +> This is generally not needed, and it is recommended to not enable this +> command, unless the feature this command implements is truly needed. ## Dependencies diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index e3480f37..207d7bae 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -21,45 +21,43 @@ #include const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_skip, - - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_skip - ), + [0] = KEYMAP_STACKED + (Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_skip), }; -void setup () { - Serial.begin (9600); +void setup() { + Serial.begin(9600); - Kaleidoscope.setup (); + USE_PLUGINS(&EEPROMKeymap, &Focus); - USE_PLUGINS (&EEPROMKeymap, &Focus); + Kaleidoscope.setup(); - Focus.addHook (FOCUS_HOOK_SETTINGS); - Focus.addHook (FOCUS_HOOK_KEYMAP); - Focus.addHook (FOCUS_HOOK_KEYMAP_TRANSFER); - Focus.addHook (FOCUS_HOOK_HELP); - Focus.addHook (FOCUS_HOOK_VERSION); + Focus.addHook(FOCUS_HOOK_SETTINGS); + Focus.addHook(FOCUS_HOOK_KEYMAP); + Focus.addHook(FOCUS_HOOK_KEYMAP_TRANSFER); + Focus.addHook(FOCUS_HOOK_HELP); + Focus.addHook(FOCUS_HOOK_VERSION); - Layer.getKey = EEPROMKeymap.getKeyOverride; + Layer.getKey = EEPROMKeymap.getKeyOverride; - EEPROMKeymap.reserveSpace (1); - EEPROMSettings.seal (); + EEPROMKeymap.max_layers(1); + EEPROMSettings.seal(); } -void loop () { - Kaleidoscope.loop (); +void loop() { + Kaleidoscope.loop(); } diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 314b65a2..7acbfdb0 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -20,121 +20,111 @@ #include #include -namespace KaleidoscopePlugins { -uint16_t EEPROMKeymap::keymapBase; -uint8_t EEPROMKeymap::maxLayers; +namespace kaleidoscope { +uint16_t EEPROMKeymap::keymap_base_; +uint8_t EEPROMKeymap::max_layers_; -EEPROMKeymap::EEPROMKeymap (void) { +EEPROMKeymap::EEPROMKeymap(void) { } -void -EEPROMKeymap::begin (void) { - USE_PLUGINS (&::EEPROMSettings); +void EEPROMKeymap::begin(void) { + USE_PLUGINS(&::EEPROMSettings); } -void -EEPROMKeymap::reserveSpace (uint8_t layers) { - maxLayers = layers; - keymapBase = ::EEPROMSettings.requestSlice (maxLayers * ROWS * COLS * 2); +void EEPROMKeymap::max_layers(uint8_t max) { + max_layers_ = max; + keymap_base_ = ::EEPROMSettings.requestSlice(max_layers_ * ROWS * COLS * 2); } -Key -EEPROMKeymap::getKey (uint8_t layer, byte row, byte col) { - Key key; +Key EEPROMKeymap::getKey(uint8_t layer, byte row, byte col) { + Key key; - if (layer >= maxLayers) - return Key_NoKey; + if (layer >= max_layers_) + return Key_NoKey; - uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col) * 2; + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col) * 2; - key.flags = EEPROM.read (keymapBase + pos); - key.keyCode = EEPROM.read (keymapBase + pos + 1); + key.flags = EEPROM.read(keymap_base_ + pos); + key.keyCode = EEPROM.read(keymap_base_ + pos + 1); - return key; + return key; } -Key -EEPROMKeymap::getKeyOverride (uint8_t layer, byte row, byte col) { - Key key; +Key EEPROMKeymap::getKeyOverride(uint8_t layer, byte row, byte col) { + Key key; - key = getKey (layer, row, col); - if (key == Key_Transparent) - key = Layer.getKeyFromPROGMEM (layer, row, col); - return key; + key = getKey(layer, row, col); + if (key == Key_Transparent) + key = Layer.getKeyFromPROGMEM(layer, row, col); + return key; } -uint16_t -EEPROMKeymap::base (void) { - return keymapBase; +uint16_t EEPROMKeymap::keymap_base(void) { + return keymap_base_; } -void -EEPROMKeymap::updateKey (uint16_t basePos, Key key) { - EEPROM.update (keymapBase + basePos * 2, key.flags); - EEPROM.update (keymapBase + basePos * 2 + 1, key.keyCode); +void EEPROMKeymap::updateKey(uint16_t base_pos, Key key) { + EEPROM.update(keymap_base_ + base_pos * 2, key.flags); + EEPROM.update(keymap_base_ + base_pos * 2 + 1, key.keyCode); } -Key -EEPROMKeymap::parseKey (void) { - Key key; +Key EEPROMKeymap::parseKey(void) { + Key key; - key.raw = Serial.parseInt (); + key.raw = Serial.parseInt(); - return key; + return key; } -void -EEPROMKeymap::printKey (Key k) { - ::Focus.printNumber (k.raw); +void EEPROMKeymap::printKey(Key k) { + ::Focus.printNumber(k.raw); } -bool -EEPROMKeymap::focusKeymap (const char *command) { - if (strcmp_P (command, PSTR ("keymap.map")) != 0) - return false; - - if (Serial.peek () == '\n') { - for (uint8_t layer = 0; layer < maxLayers; layer++) { - for (uint8_t row = 0; row < ROWS; row++) { - for (uint8_t col = 0; col < COLS; col++) { - Key k = getKey (layer, row, col); - - printKey (k); - ::Focus.printSpace (); - } - } - } - Serial.println (); - } else { - uint16_t i = 0; - while ((Serial.peek () != '\n') && (i < ROWS * COLS * maxLayers)) { - updateKey (i, parseKey ()); - i++; +bool EEPROMKeymap::focusKeymap(const char *command) { + if (strcmp_P(command, PSTR("keymap.map")) != 0) + return false; + + if (Serial.peek() == '\n') { + for (uint8_t layer = 0; layer < max_layers_; layer++) { + for (uint8_t row = 0; row < ROWS; row++) { + for (uint8_t col = 0; col < COLS; col++) { + Key k = getKey(layer, row, col); + + printKey(k); + ::Focus.printSpace(); } + } } + Serial.println(); + } else { + uint16_t i = 0; + while ((Serial.peek() != '\n') && (i < ROWS * COLS * max_layers_)) { + updateKey(i, parseKey()); + i++; + } + } - return true; + return true; } -bool -EEPROMKeymap::focusKeymapTransfer (const char *command) { - if (strcmp_P (command, PSTR ("keymap.transfer")) != 0) - return false; +bool EEPROMKeymap::focusKeymapTransfer(const char *command) { + if (strcmp_P(command, PSTR("keymap.transfer")) != 0) + return false; - uint8_t layer = Serial.parseInt (); + uint8_t layer = Serial.parseInt(); - for (uint8_t row = 0; row < ROWS; row++) { - for (uint8_t col = 0; col < COLS; col++) { - Key k = Layer.getKeyFromPROGMEM (layer, row, col); - uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); + for (uint8_t row = 0; row < ROWS; row++) { + for (uint8_t col = 0; col < COLS; col++) { + Key k = Layer.getKeyFromPROGMEM(layer, row, col); + uint16_t pos =((layer * ROWS * COLS) + (row * COLS) + col); - updateKey (pos, k); - } + updateKey(pos, k); } + } - return true; + return true; } -}; +} -KaleidoscopePlugins::EEPROMKeymap EEPROMKeymap; +kaleidoscope::EEPROMKeymap EEPROMKeymap; diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 511cab35..b1e7de81 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -21,31 +21,32 @@ #include #include -namespace KaleidoscopePlugins { +namespace kaleidoscope { class EEPROMKeymap : public KaleidoscopePlugin { - public: - EEPROMKeymap (void); + public: + EEPROMKeymap(void); - virtual void begin (void) final; + static void max_layers(uint8_t max); - static void reserveSpace (uint8_t layers); - static uint16_t base (void); + void begin(void) final; - static Key getKey (uint8_t layer, byte row, byte col); - static Key getKeyOverride (uint8_t layer, byte row, byte col); + static uint16_t keymap_base(void); - static bool focusKeymap (const char *command); - static bool focusKeymapTransfer (const char *command); + static Key getKey(uint8_t layer, byte row, byte col); + static Key getKeyOverride(uint8_t layer, byte row, byte col); - static void updateKey (uint16_t basePos, Key key); + static bool focusKeymap(const char *command); + static bool focusKeymapTransfer(const char *command); - private: - static uint16_t keymapBase; - static uint8_t maxLayers; + static void updateKey(uint16_t base_pos, Key key); - static Key parseKey (void); - static void printKey (Key key); + private: + static uint16_t keymap_base_; + static uint8_t max_layers_; + + static Key parseKey(void); + static void printKey(Key key); }; }; -extern KaleidoscopePlugins::EEPROMKeymap EEPROMKeymap; +extern kaleidoscope::EEPROMKeymap EEPROMKeymap; From 8782cea7c1cbf374986e8ff76d449d11cd3a8d54 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 3 Jun 2017 10:09:06 +0200 Subject: [PATCH 201/792] Focus: When printing the keymap, use the effective layout Instead of printing the keymap from EEPROM, print the effective layout. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 7acbfdb0..2411b4f3 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -88,7 +88,7 @@ bool EEPROMKeymap::focusKeymap(const char *command) { for (uint8_t layer = 0; layer < max_layers_; layer++) { for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t col = 0; col < COLS; col++) { - Key k = getKey(layer, row, col); + Key k = Layer.getKey(layer, row, col); printKey(k); ::Focus.printSpace(); From 18fe127ac2be3678bef18d2e2dc6580456fed2dc Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:46:56 -0700 Subject: [PATCH 202/792] astyle with current project style guidelines --- src/Kaleidoscope-Numlock.cpp | 68 ++++++++++++++++++------------------ src/Kaleidoscope-Numlock.h | 10 +++--- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index fc4e8393..15fe07a8 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -10,59 +10,59 @@ byte NumLock_::row = 255, NumLock_::col = 255; cRGB numpad_color; -NumLock_::NumLock_ (void) { +NumLock_::NumLock_(void) { } void -NumLock_::begin (void) { - us = LEDControl.mode_add (this); - numpad_color.r=255; +NumLock_::begin(void) { + us = LEDControl.mode_add(this); + numpad_color.r=255; } void -NumLock_::init (void) { - if (!isActive) { - LEDControl.next_mode(); - } +NumLock_::init(void) { + if (!isActive) { + LEDControl.next_mode(); + } } void -NumLock_::update (void) { - for (uint8_t r = 0; r < ROWS; r++) { - for (uint8_t c = 0; c < COLS; c++) { - Key k = Layer.lookup (r, c); +NumLock_::update(void) { + for (uint8_t r = 0; r < ROWS; r++) { + for (uint8_t c = 0; c < COLS; c++) { + Key k = Layer.lookup(r, c); - if (k.raw < Key_KeypadNumLock.raw || k.raw > Key_KeypadDot.raw) - continue; + if (k.raw < Key_KeypadNumLock.raw || k.raw > Key_KeypadDot.raw) + continue; - LEDControl.led_set_crgb_at(r, c, numpad_color); - } + LEDControl.led_set_crgb_at(r, c, numpad_color); } + } - if (row > ROWS || col > COLS) - return; + if (row > ROWS || col > COLS) + return; - cRGB color = breath_compute(); - LEDControl.led_set_crgb_at (row, col, color); + cRGB color = breath_compute(); + LEDControl.led_set_crgb_at(row, col, color); } const macro_t * -NumLock_::toggle (byte row_, byte col_, uint8_t numPadLayer) { - row = row_; - col = col_; +NumLock_::toggle(byte row_, byte col_, uint8_t numPadLayer) { + row = row_; + col = col_; - if (Layer.isOn (numPadLayer)) { - isActive = false; - LEDControl.set_mode (previousLEDMode); - Layer.off (numPadLayer); - } else { - isActive = true; - previousLEDMode = LEDControl.get_mode (); - LEDControl.set_mode (us); - Layer.on (numPadLayer); - } + if (Layer.isOn(numPadLayer)) { + isActive = false; + LEDControl.set_mode(previousLEDMode); + Layer.off(numPadLayer); + } else { + isActive = true; + previousLEDMode = LEDControl.get_mode(); + LEDControl.set_mode(us); + Layer.on(numPadLayer); + } - return MACRO(T(KeypadNumLock), END); + return MACRO(T(KeypadNumLock), END); } NumLock_ NumLock; diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-Numlock.h index b118f411..3dc27052 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -9,14 +9,14 @@ class NumLock_ : public LEDMode { public: - NumLock_ (void); + NumLock_(void); - virtual void begin (void) final; + virtual void begin(void) final; - virtual void update (void) final; - virtual void init (void) final; + virtual void update(void) final; + virtual void init(void) final; - static const macro_t *toggle (byte row, byte col, uint8_t numPadLayer); + static const macro_t *toggle(byte row, byte col, uint8_t numPadLayer); private: static uint8_t previousLEDMode; From 8786adbc84740afce66a9c6a9d6f1598376763eb Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:47:24 -0700 Subject: [PATCH 203/792] astyle with current project style guidelines --- src/Kaleidoscope-MouseKeys.cpp | 139 ++++++++++++++++----------------- src/Kaleidoscope-MouseKeys.h | 32 ++++---- src/MouseWrapper.cpp | 114 +++++++++++++-------------- src/MouseWrapper.h | 40 +++++----- 4 files changed, 162 insertions(+), 163 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index d330c051..2f4f6926 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -20,100 +20,99 @@ uint32_t MouseKeys_::endTime; uint32_t MouseKeys_::wheelEndTime; void MouseKeys_::scrollWheel(uint8_t keyCode) { - if (millis() < wheelEndTime) - return; + if (millis() < wheelEndTime) + return; - wheelEndTime = millis() + wheelDelay; + wheelEndTime = millis() + wheelDelay; - if (keyCode & KEY_MOUSE_UP) - Mouse.move(0, 0, wheelSpeed); - else if (keyCode & KEY_MOUSE_DOWN) - Mouse.move(0, 0, -wheelSpeed); + if (keyCode & KEY_MOUSE_UP) + Mouse.move(0, 0, wheelSpeed); + else if (keyCode & KEY_MOUSE_DOWN) + Mouse.move(0, 0, -wheelSpeed); } void MouseKeys_::loopHook(bool postClear) { - if (postClear) { - mouseMoveIntent = 0; - return; - } + if (postClear) { + mouseMoveIntent = 0; + return; + } - if (mouseMoveIntent == 0) { - MouseWrapper.accelStep = 0; - endTime = 0; - accelEndTime = 0; - return; - } + if (mouseMoveIntent == 0) { + MouseWrapper.accelStep = 0; + endTime = 0; + accelEndTime = 0; + return; + } - if (millis() < endTime) - return; + if (millis() < endTime) + return; - endTime = millis() + speedDelay; + endTime = millis() + speedDelay; - int8_t moveX = 0, moveY = 0; + int8_t moveX = 0, moveY = 0; - if (millis() >= accelEndTime) { - if (MouseWrapper.accelStep < 255 - accelSpeed) - MouseWrapper.accelStep += accelSpeed; - } + if (millis() >= accelEndTime) { + if (MouseWrapper.accelStep < 255 - accelSpeed) + MouseWrapper.accelStep += accelSpeed; + } - if (mouseMoveIntent & KEY_MOUSE_UP) - moveY = -speed; - else if (mouseMoveIntent & KEY_MOUSE_DOWN) - moveY = speed; + if (mouseMoveIntent & KEY_MOUSE_UP) + moveY = -speed; + else if (mouseMoveIntent & KEY_MOUSE_DOWN) + moveY = speed; - if (mouseMoveIntent & KEY_MOUSE_LEFT) - moveX = -speed; - else if (mouseMoveIntent & KEY_MOUSE_RIGHT) - moveX = speed; + if (mouseMoveIntent & KEY_MOUSE_LEFT) + moveX = -speed; + else if (mouseMoveIntent & KEY_MOUSE_RIGHT) + moveX = speed; - MouseWrapper.move(moveX, moveY); + MouseWrapper.move(moveX, moveY); } Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) { - if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY)) - return mappedKey; - - if (mappedKey.keyCode & KEY_MOUSE_BUTTON && !(mappedKey.keyCode & KEY_MOUSE_WARP)) { - uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; - - if (key_toggled_on(keyState)) { - MouseWrapper.press_button(button); - } else if (key_toggled_off(keyState)) { - MouseWrapper.release_button(button); - } - } else if (!(mappedKey.keyCode & KEY_MOUSE_WARP)) { - if (key_toggled_on(keyState)) { - endTime = millis() + speedDelay; - accelEndTime = millis() + accelDelay; - wheelEndTime = 0; - } - if (key_is_pressed(keyState)) { - if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { - scrollWheel (mappedKey.keyCode); - } - else - mouseMoveIntent |= mappedKey.keyCode; - } - } else if (key_toggled_on(keyState)) { - if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { - // we don't pass in the left and up values because those are the - // default, "no-op" conditionals - MouseWrapper.warp( ((mappedKey.keyCode & KEY_MOUSE_WARP_END) ? WARP_END : 0x00) | - ((mappedKey.keyCode & KEY_MOUSE_DOWN) ? WARP_DOWN : 0x00) | - ((mappedKey.keyCode & KEY_MOUSE_RIGHT) ? WARP_RIGHT : 0x00) ); - } + if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY)) + return mappedKey; + + if (mappedKey.keyCode & KEY_MOUSE_BUTTON && !(mappedKey.keyCode & KEY_MOUSE_WARP)) { + uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; + + if (key_toggled_on(keyState)) { + MouseWrapper.press_button(button); + } else if (key_toggled_off(keyState)) { + MouseWrapper.release_button(button); + } + } else if (!(mappedKey.keyCode & KEY_MOUSE_WARP)) { + if (key_toggled_on(keyState)) { + endTime = millis() + speedDelay; + accelEndTime = millis() + accelDelay; + wheelEndTime = 0; + } + if (key_is_pressed(keyState)) { + if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { + scrollWheel(mappedKey.keyCode); + } else + mouseMoveIntent |= mappedKey.keyCode; + } + } else if (key_toggled_on(keyState)) { + if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { + // we don't pass in the left and up values because those are the + // default, "no-op" conditionals + MouseWrapper.warp(((mappedKey.keyCode & KEY_MOUSE_WARP_END) ? WARP_END : 0x00) | + ((mappedKey.keyCode & KEY_MOUSE_DOWN) ? WARP_DOWN : 0x00) | + ((mappedKey.keyCode & KEY_MOUSE_RIGHT) ? WARP_RIGHT : 0x00)); } + } - return Key_NoKey; + return Key_NoKey; } MouseKeys_::MouseKeys_(void) { } void -MouseKeys_::begin (void) { - event_handler_hook_use(eventHandlerHook); - loop_hook_use(loopHook); +MouseKeys_::begin(void) { + event_handler_hook_use(eventHandlerHook); + loop_hook_use(loopHook); } MouseKeys_ MouseKeys; diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index 4b309cd7..ee71fb0d 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -4,27 +4,27 @@ #include "MouseKeyDefs.h" class MouseKeys_ : public KaleidoscopePlugin { - public: - MouseKeys_ (void); + public: + MouseKeys_(void); - virtual void begin(void) final; + virtual void begin(void) final; - static uint8_t speed; - static uint16_t speedDelay; - static uint8_t accelSpeed; - static uint16_t accelDelay; - static uint8_t wheelSpeed; - static uint16_t wheelDelay; + static uint8_t speed; + static uint16_t speedDelay; + static uint8_t accelSpeed; + static uint16_t accelDelay; + static uint8_t wheelSpeed; + static uint16_t wheelDelay; private: - static uint8_t mouseMoveIntent; - static uint32_t endTime; - static uint32_t accelEndTime; - static uint32_t wheelEndTime; + static uint8_t mouseMoveIntent; + static uint32_t endTime; + static uint32_t accelEndTime; + static uint32_t wheelEndTime; - static void scrollWheel(uint8_t keyCode); - static void loopHook(bool postClear); - static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); + static void scrollWheel(uint8_t keyCode); + static void loopHook(bool postClear); + static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); }; extern MouseKeys_ MouseKeys; diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 553a5356..b6495cc7 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -13,102 +13,102 @@ boolean MouseWrapper_::is_warping; uint8_t MouseWrapper_::accelStep; MouseWrapper_::MouseWrapper_(void) { - Mouse.begin(); - AbsoluteMouse.begin(); + Mouse.begin(); + AbsoluteMouse.begin(); } void MouseWrapper_::press_button(uint8_t button) { - Mouse.press(button); - end_warping(); + Mouse.press(button); + end_warping(); } void MouseWrapper_::release_button(uint8_t button) { - Mouse.release(button); + Mouse.release(button); } void MouseWrapper_::warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width) { - uint16_t x_center = left + width/2; - uint16_t y_center = top + height/2; - AbsoluteMouse.moveTo(x_center, y_center); + uint16_t x_center = left + width/2; + uint16_t y_center = top + height/2; + AbsoluteMouse.moveTo(x_center, y_center); } void MouseWrapper_::begin_warping() { - section_left = WARP_ABS_LEFT; - section_top = WARP_ABS_TOP; - next_width = MAX_WARP_WIDTH; - next_height = MAX_WARP_HEIGHT; - is_warping = true; + section_left = WARP_ABS_LEFT; + section_top = WARP_ABS_TOP; + next_width = MAX_WARP_WIDTH; + next_height = MAX_WARP_HEIGHT; + is_warping = true; } void MouseWrapper_::end_warping() { - is_warping= false; + is_warping= false; } void MouseWrapper_::warp(uint8_t warp_cmd) { - if (is_warping == false) { - begin_warping(); - } + if (is_warping == false) { + begin_warping(); + } - if (warp_cmd & WARP_END) { - end_warping(); - return; - } + if (warp_cmd & WARP_END) { + end_warping(); + return; + } - next_width = next_width/2; - next_height = next_height/2; + next_width = next_width/2; + next_height = next_height/2; - if (warp_cmd & WARP_UP) { + if (warp_cmd & WARP_UP) { // Serial.print(" - up "); - } else if (warp_cmd & WARP_DOWN) { + } else if (warp_cmd & WARP_DOWN) { // Serial.print(" - down "); - section_top = section_top + next_height; - } + section_top = section_top + next_height; + } - if (warp_cmd & WARP_LEFT) { - // Serial.print(" - left "); - } else if (warp_cmd & WARP_RIGHT) { - // Serial.print(" - right "); - section_left = section_left + next_width; - } + if (warp_cmd & WARP_LEFT) { + // Serial.print(" - left "); + } else if (warp_cmd & WARP_RIGHT) { + // Serial.print(" - right "); + section_left = section_left + next_width; + } - warp_jump(section_left, section_top, next_height,next_width); + warp_jump(section_left, section_top, next_height,next_width); } // cubic wave function based on code from FastLED uint8_t MouseWrapper_::acceleration(uint8_t cycles) { - uint8_t i = cycles; + uint8_t i = cycles; - if( i & 0x80) { - i = 255 - i; - } + if (i & 0x80) { + i = 255 - i; + } - i = i << 1; + i = i << 1; - uint8_t ii = (i*i) >> 8; - uint8_t iii = (ii*i) >> 8; + uint8_t ii = (i*i) >> 8; + uint8_t iii = (ii*i) >> 8; - i = (( (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii))) / 2) + ACCELERATION_FLOOR; + i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + ACCELERATION_FLOOR; - if (i > ACCELERATION_CEIL) { - i = ACCELERATION_CEIL; - } - return i; + if (i > ACCELERATION_CEIL) { + i = ACCELERATION_CEIL; + } + return i; } void MouseWrapper_::move(int8_t x, int8_t y) { - int16_t moveX =0; - int16_t moveY = 0; - if (x != 0 ) { - moveX = (x * acceleration(accelStep)); - } - if (y != 0) { - moveY = (y * acceleration(accelStep)); - } - - end_warping(); - Mouse.move(moveX, moveY, 0); + int16_t moveX =0; + int16_t moveY = 0; + if (x != 0) { + moveX = (x * acceleration(accelStep)); + } + if (y != 0) { + moveY = (y * acceleration(accelStep)); + } + + end_warping(); + Mouse.move(moveX, moveY, 0); } MouseWrapper_ MouseWrapper; diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index fc2f8126..4bb82b1a 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -28,26 +28,26 @@ #define ACCELERATION_CEIL 50 class MouseWrapper_ { - public: - MouseWrapper_(void); - - static void move(int8_t x, int8_t y); - static void warp(uint8_t warp_cmd); - static void press_button(uint8_t button); - static void release_button(uint8_t button); - static uint8_t accelStep; - - private: - static uint16_t next_width; - static uint16_t next_height; - static uint16_t section_top; - static uint16_t section_left; - static boolean is_warping; - - static uint8_t acceleration(uint8_t cycles); - static void begin_warping(); - static void end_warping(); - static void warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width); + public: + MouseWrapper_(void); + + static void move(int8_t x, int8_t y); + static void warp(uint8_t warp_cmd); + static void press_button(uint8_t button); + static void release_button(uint8_t button); + static uint8_t accelStep; + + private: + static uint16_t next_width; + static uint16_t next_height; + static uint16_t section_top; + static uint16_t section_left; + static boolean is_warping; + + static uint8_t acceleration(uint8_t cycles); + static void begin_warping(); + static void end_warping(); + static void warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width); }; extern MouseWrapper_ MouseWrapper; From b75b3ac9605567e198a05dc2eed14e7a3f2216a1 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:48:07 -0700 Subject: [PATCH 204/792] astyle with current project style guidelines --- examples/LED-Stalker/LED-Stalker.ino | 50 ++++----- src/Kaleidoscope/LED-Stalker.cpp | 162 +++++++++++++-------------- src/Kaleidoscope/LED-Stalker.h | 58 +++++----- 3 files changed, 135 insertions(+), 135 deletions(-) diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index 3b82cbeb..80bbd351 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -22,35 +22,35 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_NoKey, - - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_NoKey - ), + [0] = KEYMAP_STACKED + ( + Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_NoKey, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_NoKey + ), }; -void setup () { - Kaleidoscope.setup (); +void setup() { + Kaleidoscope.setup(); - StalkerEffect.configure (STALKER (BlazingTrail, NULL)); - USE_PLUGINS (&LEDOff, &StalkerEffect); + StalkerEffect.configure(STALKER(BlazingTrail, NULL)); + USE_PLUGINS(&LEDOff, &StalkerEffect); - StalkerEffect.activate (); + StalkerEffect.activate(); } -void loop () { - Kaleidoscope.loop (); +void loop() { + Kaleidoscope.loop(); } diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index adc9b518..9aa14db7 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -26,66 +26,66 @@ StalkerEffect::ColorComputer *StalkerEffect::colorComputer; uint16_t StalkerEffect::stepLength = 50; uint32_t StalkerEffect::stepEndTime; -StalkerEffect::StalkerEffect (void) { +StalkerEffect::StalkerEffect(void) { } void -StalkerEffect::configure (ColorComputer *colorComputer_) { - colorComputer = colorComputer_; +StalkerEffect::configure(ColorComputer *colorComputer_) { + colorComputer = colorComputer_; } void -StalkerEffect::begin (void) { - event_handler_hook_use (eventHandlerHook); - LEDMode::begin (); +StalkerEffect::begin(void) { + event_handler_hook_use(eventHandlerHook); + LEDMode::begin(); } void -StalkerEffect::init (void) { - memset (map, 0, sizeof (map)); +StalkerEffect::init(void) { + memset(map, 0, sizeof(map)); } Key -StalkerEffect::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) { - if (row >= ROWS || col >= COLS) - return mappedKey; +StalkerEffect::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) { + if (row >= ROWS || col >= COLS) + return mappedKey; - if (key_is_pressed (keyState)) { - map[row][col] = 0xff; - } + if (key_is_pressed(keyState)) { + map[row][col] = 0xff; + } - return mappedKey; + return mappedKey; } void -StalkerEffect::update (void) { - if (!colorComputer) - return; - - bool timeOut = millis () >= stepEndTime; - - for (byte r = 0; r < ROWS; r++) { - for (byte c = 0; c < COLS; c++) { - uint8_t step = map[r][c]; - if (step) { - LEDControl.led_set_crgb_at (r, c, colorComputer->compute (&step)); - } - - bool wasZero = (map[r][c] == 0); - - if (timeOut) { - map[r][c] = step; - } - - if (!wasZero && !map[r][c]) - LEDControl.led_set_crgb_at (r, c, (cRGB) { - 0, 0, 0 - }); - } +StalkerEffect::update(void) { + if (!colorComputer) + return; + + bool timeOut = millis() >= stepEndTime; + + for (byte r = 0; r < ROWS; r++) { + for (byte c = 0; c < COLS; c++) { + uint8_t step = map[r][c]; + if (step) { + LEDControl.led_set_crgb_at(r, c, colorComputer->compute(&step)); + } + + bool wasZero = (map[r][c] == 0); + + if (timeOut) { + map[r][c] = step; + } + + if (!wasZero && !map[r][c]) + LEDControl.led_set_crgb_at(r, c, (cRGB) { + 0, 0, 0 + }); } + } - if (timeOut) - stepEndTime = millis () + stepLength; + if (timeOut) + stepEndTime = millis() + stepLength; } namespace Stalker { @@ -93,55 +93,55 @@ namespace Stalker { cRGB Haunt::highlightColor; // Haunt -Haunt::Haunt (const cRGB highlightColor_) { - highlightColor = highlightColor_; +Haunt::Haunt(const cRGB highlightColor_) { + highlightColor = highlightColor_; } cRGB -Haunt::compute (uint8_t *step) { - cRGB color = CRGB((uint8_t)min(*step * highlightColor.r / 255, 255), - (uint8_t)min(*step * highlightColor.g / 255, 255), - (uint8_t)min(*step * highlightColor.b / 255, 255)); - - if (*step >= 0xf0) - *step -= 1; - else if (*step >= 0x40) - *step -= 16; - else if (*step >= 32) - *step -= 32; - else - *step = 0; - - return color; +Haunt::compute(uint8_t *step) { + cRGB color = CRGB((uint8_t)min(*step * highlightColor.r / 255, 255), + (uint8_t)min(*step * highlightColor.g / 255, 255), + (uint8_t)min(*step * highlightColor.b / 255, 255)); + + if (*step >= 0xf0) + *step -= 1; + else if (*step >= 0x40) + *step -= 16; + else if (*step >= 32) + *step -= 32; + else + *step = 0; + + return color; } // BlazingTrail -BlazingTrail::BlazingTrail (...) { +BlazingTrail::BlazingTrail(...) { } cRGB -BlazingTrail::compute (uint8_t *step) { - cRGB color; - - if (*step >= 0xff - 30) { - color = hsv_to_rgb (0xff - *step, 255, 255); - } else { - color = hsv_to_rgb (30, 255, 255); - - color.r = min(*step * color.r / 255, 255); - color.g = min(*step * color.g / 255, 255); - } - - if (*step >= 0xf0 - 30) - *step -= 1; - else if (*step >= 0x40) - *step -= 16; - else if (*step >= 32) - *step -= 32; - else - *step = 0; - - return color; +BlazingTrail::compute(uint8_t *step) { + cRGB color; + + if (*step >= 0xff - 30) { + color = hsv_to_rgb(0xff - *step, 255, 255); + } else { + color = hsv_to_rgb(30, 255, 255); + + color.r = min(*step * color.r / 255, 255); + color.g = min(*step * color.g / 255, 255); + } + + if (*step >= 0xf0 - 30) + *step -= 1; + else if (*step >= 0x40) + *step -= 16; + else if (*step >= 32) + *step -= 32; + else + *step = 0; + + return color; } }; diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index de5e1ee4..9954c674 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -24,49 +24,49 @@ namespace KaleidoscopePlugins { namespace LEDEffects { class StalkerEffect : public LEDMode { - public: - class ColorComputer { - public: - virtual cRGB compute (uint8_t *step) = 0; - }; + public: + class ColorComputer { + public: + virtual cRGB compute(uint8_t *step) = 0; + }; - StalkerEffect (void); + StalkerEffect(void); - virtual void begin (void) final; - virtual void init (void) final; - virtual void update (void) final; + virtual void begin(void) final; + virtual void init(void) final; + virtual void update(void) final; - static void configure (ColorComputer *colorComputer); - static uint16_t stepLength; + static void configure(ColorComputer *colorComputer); + static uint16_t stepLength; - private: - static uint32_t stepEndTime; - static ColorComputer *colorComputer; - static uint8_t map[ROWS][COLS]; + private: + static uint32_t stepEndTime; + static ColorComputer *colorComputer; + static uint8_t map[ROWS][COLS]; - static Key eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState); + static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); }; namespace Stalker { class Haunt : public StalkerEffect::ColorComputer { - public: - Haunt (const cRGB highlightColor); - Haunt (void) : Haunt ( { - 0x40, 0x80, 0x80 - }) {}; - Haunt (void *) : Haunt () {}; - - virtual cRGB compute (uint8_t *step) final; - private: - static cRGB highlightColor; + public: + Haunt(const cRGB highlightColor); + Haunt(void) : Haunt( { + 0x40, 0x80, 0x80 + }) {}; + Haunt(void *) : Haunt() {}; + + virtual cRGB compute(uint8_t *step) final; + private: + static cRGB highlightColor; }; class BlazingTrail : public StalkerEffect::ColorComputer { - public: - BlazingTrail (...); + public: + BlazingTrail(...); - virtual cRGB compute (uint8_t *step) final; + virtual cRGB compute(uint8_t *step) final; }; }; From a9f59b131e98ff51b9c5603a844355a6a4dc4b6d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:48:42 -0700 Subject: [PATCH 205/792] astyle with current project style guidelines --- src/Kaleidoscope-Model01-TestMode.cpp | 174 +++++++++++++------------- src/Kaleidoscope-Model01-TestMode.h | 20 +-- 2 files changed, 97 insertions(+), 97 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 4b1626d2..c94687f9 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -13,118 +13,118 @@ TestMode_::TestMode_(void) { void TestMode_::begin(void) { - red.r=101; - blue.b=101; - green.g=101; - loop_hook_use (this->loopHook); + red.r=101; + blue.b=101; + green.g=101; + loop_hook_use(this->loopHook); } -void TestMode_::loopHook (bool postClear) { - if ( postClear) - return; - if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6 ) +void TestMode_::loopHook(bool postClear) { + if (postClear) + return; + if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6) // && KeyboardHardware.rightHandState.all == combo.rightHand - ) { - run_tests(); - } + ) { + run_tests(); + } } void TestMode_::wait_for_keypress() { - delay(25); - while (1) { - KeyboardHardware.read_matrix(); - if (KeyboardHardware.leftHandState.all == R3C6 - && KeyboardHardware.previousLeftHandState.all == 0 ) { - break; - } -} + delay(25); + while (1) { + KeyboardHardware.read_matrix(); + if (KeyboardHardware.leftHandState.all == R3C6 + && KeyboardHardware.previousLeftHandState.all == 0) { + break; + } + } } void TestMode_::set_leds(uint8_t r, uint8_t g, uint8_t b) { - LEDControl.set_all_leds_to(r,g,b); - LEDControl.led_sync(); - wait_for_keypress(); + LEDControl.set_all_leds_to(r,g,b); + LEDControl.led_sync(); + wait_for_keypress(); } void TestMode_::test_leds(void) { - // make all LEDs dim red - set_leds(50,0,0); - // make all LEDs dim blue - set_leds(0,50,0); - // make all LEDs dim green - set_leds(0,0,50); - // make all LEDs dim white - set_leds(50,50,50); - // make all the LEDs bright red - set_leds(200,0,0); - // make all the LEDs bright green - set_leds(0,200,0); - // make all the LEDs bright blue - set_leds(0,0,200); - // make all the LEDs bright white (1.6A) - set_leds(160,160,160); - // rainbow for 10 seconds - for(auto i=0; i<1000; i++ ) { - LEDRainbowEffect.update(); - LEDControl.led_sync(); - } - // set all the keys to red + // make all LEDs dim red + set_leds(50,0,0); + // make all LEDs dim blue + set_leds(0,50,0); + // make all LEDs dim green + set_leds(0,0,50); + // make all LEDs dim white + set_leds(50,50,50); + // make all the LEDs bright red + set_leds(200,0,0); + // make all the LEDs bright green + set_leds(0,200,0); + // make all the LEDs bright blue + set_leds(0,0,200); + // make all the LEDs bright white (1.6A) + set_leds(160,160,160); + // rainbow for 10 seconds + for (auto i=0; i<1000; i++) { + LEDRainbowEffect.update(); + LEDControl.led_sync(); + } + // set all the keys to red } -void TestMode_::test_matrix () { - LEDControl.set_all_leds_to(50,0,0); - while(1) { - KeyboardHardware.read_matrix(); - if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6 ) ) { - break; - } - for (byte row = 0; row < 4; row++) { - for (byte col = 0; col < 8; col++) { - - uint8_t keynum = (row*8)+(col); - - uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | - (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); - - if(keyState ==3 ) { - Serial.print(" Key: "); - Serial.print(keynum); - Serial.print(" value "); - Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 7-col, green); - } else if (keyState ==1) { - KeyboardHardware.led_set_crgb_at(row,7-col, blue); - } - - keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | - (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); - - if(keyState ==3 ) { - Serial.print(" Key: "); - Serial.print(keynum); - Serial.print(" value "); - Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 15-col, green); - } else if (keyState ==1) { - KeyboardHardware.led_set_crgb_at(row,15-col, blue); - } - } +void TestMode_::test_matrix() { + LEDControl.set_all_leds_to(50,0,0); + while (1) { + KeyboardHardware.read_matrix(); + if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6)) { + break; + } + for (byte row = 0; row < 4; row++) { + for (byte col = 0; col < 8; col++) { + + uint8_t keynum = (row*8)+(col); + + uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | + (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); + + if (keyState ==3) { + Serial.print(" Key: "); + Serial.print(keynum); + Serial.print(" value "); + Serial.println(keyState); + KeyboardHardware.led_set_crgb_at(row, 7-col, green); + } else if (keyState ==1) { + KeyboardHardware.led_set_crgb_at(row,7-col, blue); } - LEDControl.led_sync(); + + keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | + (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); + + if (keyState ==3) { + Serial.print(" Key: "); + Serial.print(keynum); + Serial.print(" value "); + Serial.println(keyState); + KeyboardHardware.led_set_crgb_at(row, 15-col, green); + } else if (keyState ==1) { + KeyboardHardware.led_set_crgb_at(row,15-col, blue); + } + } } + LEDControl.led_sync(); + } } void TestMode_::run_tests() { - Serial.println("Running tests"); - test_leds(); - test_matrix(); - Serial.println("Done running tests"); + Serial.println("Running tests"); + test_leds(); + test_matrix(); + Serial.println("Done running tests"); } TestMode_ TestMode; diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index ad423e79..eac6cbcb 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -4,17 +4,17 @@ #include "Kaleidoscope.h" class TestMode_ : public KaleidoscopePlugin { - public: - TestMode_(void); - void begin(); + public: + TestMode_(void); + void begin(); - private: - static void run_tests(); - static void test_leds(); - static void test_matrix(); - static void wait_for_keypress(); - static void loopHook(bool postClear); - static void set_leds(uint8_t r, uint8_t g, uint8_t b); + private: + static void run_tests(); + static void test_leds(); + static void test_matrix(); + static void wait_for_keypress(); + static void loopHook(bool postClear); + static void set_leds(uint8_t r, uint8_t g, uint8_t b); }; extern TestMode_ TestMode; From fcd1743f3b71a4f754cee2009137dfbaeec104be Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:49:05 -0700 Subject: [PATCH 206/792] astyle with current project style guidelines --- examples/MagicCombo/MagicCombo.ino | 66 +++++++++++++++--------------- src/Kaleidoscope/MagicCombo.cpp | 54 ++++++++++++------------ src/Kaleidoscope/MagicCombo.h | 26 ++++++------ 3 files changed, 73 insertions(+), 73 deletions(-) diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index b216cd5f..eb49e9d3 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -19,53 +19,53 @@ #include #include -void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { - switch (comboIndex) { - case 0: - Serial.println ("It's a kind of magic!"); - break; - } +void magicComboActions(uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { + switch (comboIndex) { + case 0: + Serial.println("It's a kind of magic!"); + break; + } } static const KaleidoscopePlugins::MagicCombo::dictionary_t dictionary[] PROGMEM = { - { - R1C3 | R2C1 | R2C4 | R2C7, // left hand, - R0C11 | R1C12 | R2C14 //right hand - }, - {0, 0} + { + R1C3 | R2C1 | R2C4 | R2C7, // left hand, + R0C11 | R1C12 | R2C14 //right hand + }, + {0, 0} }; const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + [0] = KEYMAP_STACKED + ( + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_NoKey, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_NoKey, - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_NoKey - ), + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_NoKey + ), }; -void setup () { - Serial.begin (9600); +void setup() { + Serial.begin(9600); - MagicCombo.configure (dictionary); + MagicCombo.configure(dictionary); - Kaleidoscope.setup (KEYMAP_SIZE); - Kaleidoscope.use (&MagicCombo, NULL); + Kaleidoscope.setup(KEYMAP_SIZE); + Kaleidoscope.use(&MagicCombo, NULL); } -void loop () { - Kaleidoscope.loop (); +void loop() { + Kaleidoscope.loop(); } diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index 85b9f200..5f529189 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -34,49 +34,49 @@ const MagicCombo::dictionary_t *MagicCombo::dictionary; uint16_t MagicCombo::minInterval = 500; uint32_t MagicCombo::endTime; -MagicCombo::MagicCombo (void) { +MagicCombo::MagicCombo(void) { } void -MagicCombo::begin (void) { - loop_hook_use (this->loopHook); +MagicCombo::begin(void) { + loop_hook_use(this->loopHook); } void -MagicCombo::configure (const MagicCombo::dictionary_t dictionary_[]) { - dictionary = (dictionary_t *)dictionary_; +MagicCombo::configure(const MagicCombo::dictionary_t dictionary_[]) { + dictionary = (dictionary_t *)dictionary_; } void -MagicCombo::loopHook (bool postClear) { - if (!dictionary || postClear) - return; - - for (byte i = 0;; i++) { - dictionary_t combo; - - combo.leftHand = pgm_read_dword (&(dictionary[i].leftHand)); - combo.rightHand = pgm_read_dword (&(dictionary[i].rightHand)); - - if (combo.leftHand == 0 && combo.rightHand == 0) - break; - - if (LEFTHANDSTATE.all == combo.leftHand && - RIGHTHANDSTATE.all == combo.rightHand) { - if (millis () >= endTime) { - magicComboActions (i, combo.leftHand, combo.rightHand); - endTime = millis () + minInterval; - } - break; - } +MagicCombo::loopHook(bool postClear) { + if (!dictionary || postClear) + return; + + for (byte i = 0;; i++) { + dictionary_t combo; + + combo.leftHand = pgm_read_dword(&(dictionary[i].leftHand)); + combo.rightHand = pgm_read_dword(&(dictionary[i].rightHand)); + + if (combo.leftHand == 0 && combo.rightHand == 0) + break; + + if (LEFTHANDSTATE.all == combo.leftHand && + RIGHTHANDSTATE.all == combo.rightHand) { + if (millis() >= endTime) { + magicComboActions(i, combo.leftHand, combo.rightHand); + endTime = millis() + minInterval; + } + break; } + } } }; __attribute__((weak)) void -magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { +magicComboActions(uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { } KaleidoscopePlugins::MagicCombo MagicCombo; diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index d7234c5b..0db57feb 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -22,26 +22,26 @@ namespace KaleidoscopePlugins { class MagicCombo : public KaleidoscopePlugin { - public: - typedef struct { - uint32_t leftHand, rightHand; - } dictionary_t; + public: + typedef struct { + uint32_t leftHand, rightHand; + } dictionary_t; - MagicCombo (void); + MagicCombo(void); - virtual void begin (void) final; + virtual void begin(void) final; - static void configure (const dictionary_t dictionary[]); - static uint16_t minInterval; + static void configure(const dictionary_t dictionary[]); + static uint16_t minInterval; - private: - static const dictionary_t *dictionary; - static uint32_t endTime; + private: + static const dictionary_t *dictionary; + static uint32_t endTime; - static void loopHook (bool postClear); + static void loopHook(bool postClear); }; }; -void magicComboActions (uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand); +void magicComboActions(uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand); extern KaleidoscopePlugins::MagicCombo MagicCombo; From 1ef902c27ee8e8b3bb11d663847486117f2b3617 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:49:37 -0700 Subject: [PATCH 207/792] astyle with current project style guidelines --- src/Kaleidoscope-Macros.cpp | 140 ++++++++++++++++++------------------ src/Kaleidoscope-Macros.h | 10 +-- src/MacroSteps.h | 18 ++--- 3 files changed, 84 insertions(+), 84 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 069e300f..6680c30f 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -2,94 +2,94 @@ __attribute__((weak)) const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { - return MACRO_NONE; + return MACRO_NONE; } byte Macros_::row, Macros_::col; -static void readKeyCodeAndPlay (const macro_t *macro_p, uint8_t flags, uint8_t keyStates) { - Key key; - key.flags = flags; - key.keyCode = pgm_read_byte(macro_p++); - - if (keyStates & IS_PRESSED) { - handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); - Keyboard.sendReport(); - } - if (keyStates & WAS_PRESSED) { - handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); - Keyboard.sendReport(); - } +static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t keyStates) { + Key key; + key.flags = flags; + key.keyCode = pgm_read_byte(macro_p++); + + if (keyStates & IS_PRESSED) { + handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); + Keyboard.sendReport(); + } + if (keyStates & WAS_PRESSED) { + handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); + Keyboard.sendReport(); + } } void Macros_::play(const macro_t *macro_p) { - macro_t macro = END; - uint8_t interval = 0; - uint8_t flags; - - if (!macro_p) - return; - - while (true) { - switch (macro = pgm_read_byte(macro_p++)) { - case MACRO_ACTION_STEP_INTERVAL: - interval = pgm_read_byte(macro_p++); - break; - case MACRO_ACTION_STEP_WAIT: { - uint8_t wait = pgm_read_byte(macro_p++); - delay(wait); - break; - } - case MACRO_ACTION_STEP_KEYDOWN: - flags = pgm_read_byte(macro_p++); - readKeyCodeAndPlay (macro_p++, flags, IS_PRESSED); - break; - case MACRO_ACTION_STEP_KEYUP: - flags = pgm_read_byte(macro_p++); - readKeyCodeAndPlay (macro_p++, flags, WAS_PRESSED); - break; - case MACRO_ACTION_STEP_TAP: - flags = pgm_read_byte(macro_p++); - readKeyCodeAndPlay (macro_p++, flags, IS_PRESSED | WAS_PRESSED); - break; - - case MACRO_ACTION_STEP_KEYCODEDOWN: - readKeyCodeAndPlay (macro_p++, 0, IS_PRESSED); - break; - case MACRO_ACTION_STEP_KEYCODEUP: - readKeyCodeAndPlay (macro_p++, 0, WAS_PRESSED); - break; - case MACRO_ACTION_STEP_TAPCODE: - readKeyCodeAndPlay (macro_p++, 0, IS_PRESSED | WAS_PRESSED); - break; - - case END: - default: - return; - } - - delay(interval); + macro_t macro = END; + uint8_t interval = 0; + uint8_t flags; + + if (!macro_p) + return; + + while (true) { + switch (macro = pgm_read_byte(macro_p++)) { + case MACRO_ACTION_STEP_INTERVAL: + interval = pgm_read_byte(macro_p++); + break; + case MACRO_ACTION_STEP_WAIT: { + uint8_t wait = pgm_read_byte(macro_p++); + delay(wait); + break; } + case MACRO_ACTION_STEP_KEYDOWN: + flags = pgm_read_byte(macro_p++); + readKeyCodeAndPlay(macro_p++, flags, IS_PRESSED); + break; + case MACRO_ACTION_STEP_KEYUP: + flags = pgm_read_byte(macro_p++); + readKeyCodeAndPlay(macro_p++, flags, WAS_PRESSED); + break; + case MACRO_ACTION_STEP_TAP: + flags = pgm_read_byte(macro_p++); + readKeyCodeAndPlay(macro_p++, flags, IS_PRESSED | WAS_PRESSED); + break; + + case MACRO_ACTION_STEP_KEYCODEDOWN: + readKeyCodeAndPlay(macro_p++, 0, IS_PRESSED); + break; + case MACRO_ACTION_STEP_KEYCODEUP: + readKeyCodeAndPlay(macro_p++, 0, WAS_PRESSED); + break; + case MACRO_ACTION_STEP_TAPCODE: + readKeyCodeAndPlay(macro_p++, 0, IS_PRESSED | WAS_PRESSED); + break; + + case END: + default: + return; + } + + delay(interval); + } } static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { - if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) - return mappedKey; + if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) + return mappedKey; - Macros_::row = row; - Macros_::col = col; - const macro_t *m = macroAction(mappedKey.keyCode, keyState); + Macros_::row = row; + Macros_::col = col; + const macro_t *m = macroAction(mappedKey.keyCode, keyState); - Macros.play(m); - return Key_NoKey; + Macros.play(m); + return Key_NoKey; } -Macros_::Macros_ (void) { +Macros_::Macros_(void) { } void -Macros_::begin (void) { - event_handler_hook_use (handleMacroEvent); +Macros_::begin(void) { + event_handler_hook_use(handleMacroEvent); } Macros_ Macros; diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index 0354d077..d37befd7 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -8,14 +8,14 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); class Macros_ : public KaleidoscopePlugin { - public: - Macros_(void); + public: + Macros_(void); - virtual void begin(void) final; + virtual void begin(void) final; - void play(const macro_t *macro_p); + void play(const macro_t *macro_p); - static byte row, col; + static byte row, col; }; extern Macros_ Macros; diff --git a/src/MacroSteps.h b/src/MacroSteps.h index 7b92f526..be21676f 100644 --- a/src/MacroSteps.h +++ b/src/MacroSteps.h @@ -1,18 +1,18 @@ #pragma once typedef enum { - MACRO_ACTION_END, + MACRO_ACTION_END, - MACRO_ACTION_STEP_INTERVAL, - MACRO_ACTION_STEP_WAIT, + MACRO_ACTION_STEP_INTERVAL, + MACRO_ACTION_STEP_WAIT, - MACRO_ACTION_STEP_KEYDOWN, - MACRO_ACTION_STEP_KEYUP, - MACRO_ACTION_STEP_TAP, + MACRO_ACTION_STEP_KEYDOWN, + MACRO_ACTION_STEP_KEYUP, + MACRO_ACTION_STEP_TAP, - MACRO_ACTION_STEP_KEYCODEDOWN, - MACRO_ACTION_STEP_KEYCODEUP, - MACRO_ACTION_STEP_TAPCODE, + MACRO_ACTION_STEP_KEYCODEDOWN, + MACRO_ACTION_STEP_KEYCODEUP, + MACRO_ACTION_STEP_TAPCODE, } MacroActionStepType; typedef uint8_t macro_t; From 90d21fb6276060f71ae036471882953d1f17e7f9 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:50:03 -0700 Subject: [PATCH 208/792] astyle with current project style guidelines --- src/Kaleidoscope-LEDEffect-SolidColor.cpp | 8 ++++---- src/Kaleidoscope-LEDEffect-SolidColor.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.cpp b/src/Kaleidoscope-LEDEffect-SolidColor.cpp index 4a49b8ef..7549fb8a 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.cpp +++ b/src/Kaleidoscope-LEDEffect-SolidColor.cpp @@ -1,13 +1,13 @@ #include "Kaleidoscope-LEDEffect-SolidColor.h" -LEDSolidColor::LEDSolidColor (uint8_t r, uint8_t g, uint8_t b) { +LEDSolidColor::LEDSolidColor(uint8_t r, uint8_t g, uint8_t b) { this->r = r; this->g = g; this->b = b; - LEDControl.mode_add (this); + LEDControl.mode_add(this); } void -LEDSolidColor::init (void) { - LEDControl.set_all_leds_to (r, g, b); +LEDSolidColor::init(void) { + LEDControl.set_all_leds_to(r, g, b); } diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.h b/src/Kaleidoscope-LEDEffect-SolidColor.h index 0feb2ae2..1c341de9 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.h +++ b/src/Kaleidoscope-LEDEffect-SolidColor.h @@ -4,9 +4,9 @@ class LEDSolidColor : public LEDMode { public: - LEDSolidColor (uint8_t r, uint8_t g, uint8_t b); + LEDSolidColor(uint8_t r, uint8_t g, uint8_t b); - virtual void init (void) final; + virtual void init(void) final; private: uint8_t r, g, b; From b0dbab884821994a90b18060f211378d0d5d2ff5 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:50:39 -0700 Subject: [PATCH 209/792] astyle with current project style guidelines --- src/Kaleidoscope-LEDEffect-Chase.cpp | 4 ++-- src/Kaleidoscope-LEDEffect-Chase.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp index 54c601cd..c8298dbd 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -1,10 +1,10 @@ #include "Kaleidoscope-LEDEffect-Chase.h" -LEDChaseEffect_::LEDChaseEffect_ (void) { +LEDChaseEffect_::LEDChaseEffect_(void) { } void -LEDChaseEffect_::update (void) { +LEDChaseEffect_::update(void) { if (current_chase_counter++ < chase_threshold) { return; } diff --git a/src/Kaleidoscope-LEDEffect-Chase.h b/src/Kaleidoscope-LEDEffect-Chase.h index e1989fae..856644bd 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.h +++ b/src/Kaleidoscope-LEDEffect-Chase.h @@ -5,9 +5,9 @@ class LEDChaseEffect_ : public LEDMode { public: - LEDChaseEffect_ (void); + LEDChaseEffect_(void); - virtual void update (void) final; + virtual void update(void) final; private: uint8_t pos = 0; From 0c8d6d3c2e68f4d4686b11711065d67fb16cdf4d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:50:57 -0700 Subject: [PATCH 210/792] astyle with current project style guidelines --- src/Kaleidoscope-LEDEffect-Breathe.cpp | 6 +++--- src/Kaleidoscope-LEDEffect-Breathe.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp index b5129474..feba2ca9 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -1,12 +1,12 @@ #include "Kaleidoscope-LEDEffect-Breathe.h" -LEDBreatheEffect_::LEDBreatheEffect_ (void) { +LEDBreatheEffect_::LEDBreatheEffect_(void) { } void -LEDBreatheEffect_::update (void) { +LEDBreatheEffect_::update(void) { cRGB color = breath_compute(); - LEDControl.set_all_leds_to (color); + LEDControl.set_all_leds_to(color); } LEDBreatheEffect_ LEDBreatheEffect; diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index ead866c0..12af4f1f 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -5,9 +5,9 @@ class LEDBreatheEffect_ : public LEDMode { public: - LEDBreatheEffect_ (void); + LEDBreatheEffect_(void); - virtual void update (void) final; + virtual void update(void) final; }; extern LEDBreatheEffect_ LEDBreatheEffect; From 89c79ef6fe5f1c44e23a0fbe0e7f916d84000b00 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:52:07 -0700 Subject: [PATCH 211/792] astyle with current project style guidelines --- src/BootAnimation.cpp | 6 +- src/Kaleidoscope-LEDControl.cpp | 160 ++++++++++++++++---------------- src/Kaleidoscope-LEDControl.h | 56 +++++------ src/LED-Off.cpp | 4 +- src/LED-Off.h | 4 +- src/LEDUtils.cpp | 26 +++--- src/LEDUtils.h | 2 +- 7 files changed, 127 insertions(+), 131 deletions(-) diff --git a/src/BootAnimation.cpp b/src/BootAnimation.cpp index 3ba6d40f..af04676d 100644 --- a/src/BootAnimation.cpp +++ b/src/BootAnimation.cpp @@ -17,9 +17,9 @@ type_letter(uint8_t letter) { #endif void -bootAnimation (void) { +bootAnimation(void) { #ifdef ARDUINO_AVR_MODEL01 - if (EEPROM.read (EEPROM_BOOT_ANIMATION_LOCATION)) + if (EEPROM.read(EEPROM_BOOT_ANIMATION_LOCATION)) return; LEDControl.set_all_leds_to(0, 0, 0); @@ -38,6 +38,6 @@ bootAnimation (void) { type_letter(LED_PERIOD); type_letter(LED_9); - EEPROM.update (EEPROM_BOOT_ANIMATION_LOCATION, 1); + EEPROM.update(EEPROM_BOOT_ANIMATION_LOCATION, 1); #endif } diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 77b80b48..be82deae 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -7,8 +7,8 @@ uint16_t LEDControl_::syncDelay = 16; uint32_t LEDControl_::syncTimer; void -LEDMode::activate (void) { - LEDControl.activate (this); +LEDMode::activate(void) { + LEDControl.activate(this); } void @@ -19,11 +19,11 @@ LEDMode::begin(void) { LEDControl_::LEDControl_(void) { mode = previousMode = 0; - memset (modes, 0, LED_MAX_MODES * sizeof (modes[0])); + memset(modes, 0, LED_MAX_MODES * sizeof(modes[0])); } void -LEDControl_::next_mode (void) { +LEDControl_::next_mode(void) { mode++; if (mode >= LED_MAX_MODES) { @@ -38,32 +38,32 @@ LEDControl_::next_mode (void) { } void -LEDControl_::update (void) { +LEDControl_::update(void) { if (previousMode != mode) { - set_all_leds_to ({0, 0, 0}); + set_all_leds_to({0, 0, 0}); if (modes[mode]) - (modes[mode]->init) (); + (modes[mode]->init)(); } if (modes[mode]) - (modes[mode]->update) (); + (modes[mode]->update)(); previousMode = mode; } void -LEDControl_::set_mode (uint8_t mode_) { +LEDControl_::set_mode(uint8_t mode_) { if (mode_ < LED_MAX_MODES) mode = mode_; } uint8_t -LEDControl_::get_mode (void) { +LEDControl_::get_mode(void) { return mode; } void -LEDControl_::activate (LEDMode *mode) { +LEDControl_::activate(LEDMode *mode) { for (uint8_t i = 0; i < LED_MAX_MODES; i++) { if (modes[i] == mode) return set_mode(i); @@ -71,7 +71,7 @@ LEDControl_::activate (LEDMode *mode) { } int8_t -LEDControl_::mode_add (LEDMode *mode) { +LEDControl_::mode_add(LEDMode *mode) { for (int i = 0; i < LED_MAX_MODES; i++) { if (modes[i]) continue; @@ -119,8 +119,8 @@ LEDControl_::led_sync(void) { } void -LEDControl_::begin (void) { - set_all_leds_to ({0, 0, 0}); +LEDControl_::begin(void) { + set_all_leds_to({0, 0, 0}); for (uint8_t i = 0; i < LED_MAX_MODES; i++) { if (modes[i]) @@ -134,7 +134,7 @@ LEDControl_::begin (void) { } Key -LEDControl_::eventHandler (Key mappedKey, byte row, byte col, uint8_t keyState) { +LEDControl_::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) return mappedKey; @@ -145,7 +145,7 @@ LEDControl_::eventHandler (Key mappedKey, byte row, byte col, uint8_t keyState) } void -LEDControl_::loopHook (bool postClear) { +LEDControl_::loopHook(bool postClear) { if (postClear) return; @@ -157,7 +157,7 @@ LEDControl_::loopHook (bool postClear) { } bool -LEDControl_::focusHook (const char *command) { +LEDControl_::focusHook(const char *command) { enum { SETALL, MODE, @@ -165,96 +165,92 @@ LEDControl_::focusHook (const char *command) { THEME, } subCommand; - if (strncmp_P (command, PSTR ("led."), 4) != 0) + if (strncmp_P(command, PSTR("led."), 4) != 0) return false; - if (strcmp_P (command + 4, PSTR ("at")) == 0) + if (strcmp_P(command + 4, PSTR("at")) == 0) subCommand = AT; - else if (strcmp_P (command + 4, PSTR ("setAll")) == 0) + else if (strcmp_P(command + 4, PSTR("setAll")) == 0) subCommand = SETALL; - else if (strcmp_P (command + 4, PSTR ("mode")) == 0) + else if (strcmp_P(command + 4, PSTR("mode")) == 0) subCommand = MODE; - else if (strcmp_P (command + 4, PSTR ("theme")) == 0) + else if (strcmp_P(command + 4, PSTR("theme")) == 0) subCommand = THEME; else return false; switch (subCommand) { - case AT: - { - uint8_t idx = Serial.parseInt (); + case AT: { + uint8_t idx = Serial.parseInt(); - if (Serial.peek () == '\n') { - cRGB c = LEDControl.led_get_crgb_at (idx); + if (Serial.peek() == '\n') { + cRGB c = LEDControl.led_get_crgb_at(idx); - Focus.printColor (c.r, c.g, c.b); - Serial.println (); - } else { - cRGB c; + Focus.printColor(c.r, c.g, c.b); + Serial.println(); + } else { + cRGB c; - c.r = Serial.parseInt (); - c.g = Serial.parseInt (); - c.b = Serial.parseInt (); + c.r = Serial.parseInt(); + c.g = Serial.parseInt(); + c.b = Serial.parseInt(); - LEDControl.led_set_crgb_at (idx, c); - } - break; + LEDControl.led_set_crgb_at(idx, c); } - case SETALL: - { - cRGB c; + break; + } + case SETALL: { + cRGB c; - c.r = Serial.parseInt (); - c.g = Serial.parseInt (); - c.b = Serial.parseInt (); + c.r = Serial.parseInt(); + c.g = Serial.parseInt(); + c.b = Serial.parseInt(); - LEDControl.set_all_leds_to (c); + LEDControl.set_all_leds_to(c); - break; + break; + } + case MODE: { + char peek = Serial.peek(); + if (peek == '\n') { + Serial.println(LEDControl.get_mode()); + } else if (peek == 'n') { + LEDControl.next_mode(); + Serial.read(); + } else if (peek == 'p') { + // TODO + Serial.read(); + } else { + uint8_t mode = Serial.parseInt(); + + LEDControl.set_mode(mode); } - case MODE: - { - char peek = Serial.peek (); - if (peek == '\n') { - Serial.println (LEDControl.get_mode ()); - } else if (peek == 'n') { - LEDControl.next_mode (); - Serial.read (); - } else if (peek == 'p') { - // TODO - Serial.read (); - } else { - uint8_t mode = Serial.parseInt (); - - LEDControl.set_mode (mode); + break; + } + case THEME: { + if (Serial.peek() == '\n') { + for (uint8_t idx = 0; idx < LED_COUNT; idx++) { + cRGB c = LEDControl.led_get_crgb_at(idx); + + Focus.printColor(c.r, c.g, c.b); + Focus.printSpace(); } + Serial.println(); break; } - case THEME: - { - if (Serial.peek () == '\n') { - for (uint8_t idx = 0; idx < LED_COUNT; idx++) { - cRGB c = LEDControl.led_get_crgb_at (idx); - - Focus.printColor (c.r, c.g, c.b); - Focus.printSpace (); - } - Serial.println (); - break; - } - uint8_t idx = 0; - while (idx < LED_COUNT && Serial.peek() != '\n') { - cRGB color; + uint8_t idx = 0; + while (idx < LED_COUNT && Serial.peek() != '\n') { + cRGB color; - color.r = Serial.parseInt (); - color.g = Serial.parseInt (); - color.b = Serial.parseInt (); + color.r = Serial.parseInt(); + color.g = Serial.parseInt(); + color.b = Serial.parseInt(); - LEDControl.led_set_crgb_at (idx, color); - idx++; - } - break; + LEDControl.led_set_crgb_at(idx, color); + idx++; } + break; + } } return true; diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 49b0c8df..45753748 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -10,48 +10,48 @@ class LEDMode : public KaleidoscopePlugin { public: - virtual void begin (void); - virtual void setup (void) {}; - virtual void init (void) {}; - virtual void update (void) {}; - virtual void activate (void); + virtual void begin(void); + virtual void setup(void) {}; + virtual void init(void) {}; + virtual void update(void) {}; + virtual void activate(void); }; class LEDControl_ : public KaleidoscopePlugin { - public: - LEDControl_(void); + public: + LEDControl_(void); - virtual void begin(void) final; + virtual void begin(void) final; - static void next_mode(void); - static void setup(void); - static void update(void); - static void set_mode(uint8_t mode); - static uint8_t get_mode(); + static void next_mode(void); + static void setup(void); + static void update(void); + static void set_mode(uint8_t mode); + static uint8_t get_mode(); - static int8_t mode_add (LEDMode *mode); + static int8_t mode_add(LEDMode *mode); - static void led_set_crgb_at(uint8_t i, cRGB crgb); - static void led_set_crgb_at(byte row, byte col, cRGB color); - static cRGB led_get_crgb_at(uint8_t i); - static void led_sync(void); + static void led_set_crgb_at(uint8_t i, cRGB crgb); + static void led_set_crgb_at(byte row, byte col, cRGB color); + static cRGB led_get_crgb_at(uint8_t i); + static void led_sync(void); - static void set_all_leds_to(uint8_t r, uint8_t g, uint8_t b); - static void set_all_leds_to(cRGB color); + static void set_all_leds_to(uint8_t r, uint8_t g, uint8_t b); + static void set_all_leds_to(cRGB color); - static void activate (LEDMode *mode); + static void activate(LEDMode *mode); - static uint16_t syncDelay; + static uint16_t syncDelay; - static bool focusHook (const char *command); + static bool focusHook(const char *command); private: - static uint32_t syncTimer; - static LEDMode *modes[LED_MAX_MODES]; - static uint8_t previousMode, mode; + static uint32_t syncTimer; + static LEDMode *modes[LED_MAX_MODES]; + static uint8_t previousMode, mode; - static Key eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState); - static void loopHook (bool postClear); + static Key eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState); + static void loopHook(bool postClear); }; extern LEDControl_ LEDControl; diff --git a/src/LED-Off.cpp b/src/LED-Off.cpp index fa35f8bd..1cacc667 100644 --- a/src/LED-Off.cpp +++ b/src/LED-Off.cpp @@ -1,7 +1,7 @@ #include "LED-Off.h" -void LEDOff_::update (void) { - LEDControl.set_all_leds_to ({0, 0, 0}); +void LEDOff_::update(void) { + LEDControl.set_all_leds_to({0, 0, 0}); } LEDOff_ LEDOff; diff --git a/src/LED-Off.h b/src/LED-Off.h index 92d041e0..6b1d1313 100644 --- a/src/LED-Off.h +++ b/src/LED-Off.h @@ -4,9 +4,9 @@ class LEDOff_ : public LEDMode { public: - LEDOff_ (void) { }; + LEDOff_(void) { }; - virtual void update (void) final; + virtual void update(void) final; }; extern LEDOff_ LEDOff; diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp index 3897b5b8..f67772db 100644 --- a/src/LEDUtils.cpp +++ b/src/LEDUtils.cpp @@ -1,22 +1,22 @@ #include "LEDUtils.h" cRGB -breath_compute () { +breath_compute() { - // This code is adapted from FastLED lib8tion.h as of dd5d96c6b289cb6b4b891748a4aeef3ddceaf0e6 - // Eventually, we should consider just using FastLED + // This code is adapted from FastLED lib8tion.h as of dd5d96c6b289cb6b4b891748a4aeef3ddceaf0e6 + // Eventually, we should consider just using FastLED - uint8_t i = (uint16_t)millis()/12; + uint8_t i = (uint16_t)millis()/12; - if( i & 0x80) { - i = 255 - i; - } + if (i & 0x80) { + i = 255 - i; + } - i = i << 1; - uint8_t ii = (i*i)>>8; - uint8_t iii = (ii*i)>>8; + i = i << 1; + uint8_t ii = (i*i)>>8; + uint8_t iii = (ii*i)>>8; - i = (( (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii))) / 2) + 2; + i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + 2; return hsv_to_rgb(200, 255, i); } @@ -32,7 +32,7 @@ hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v) { * math */ uint16_t region, fpart, p, q, t; - if(s == 0) { + if (s == 0) { /* color is grayscale */ color.r = color.g = color.b = v; return color; @@ -49,7 +49,7 @@ hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v) { t = (v * (255 - ((s * (255 - fpart)) >> 8))) >> 8; /* assign temp vars based on color cone region */ - switch(region) { + switch (region) { case 0: color.r = v; color.g = t; diff --git a/src/LEDUtils.h b/src/LEDUtils.h index 7fbfd8c3..70929ce7 100644 --- a/src/LEDUtils.h +++ b/src/LEDUtils.h @@ -2,5 +2,5 @@ #include -cRGB breath_compute (void); +cRGB breath_compute(void); cRGB hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v); From b32d2737b81314e92d2f9871b9f32d3457c9d816 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:52:31 -0700 Subject: [PATCH 212/792] astyle with current project style guidelines --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 10 +++++----- src/Kaleidoscope-LEDEffect-Rainbow.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index bc194a1f..9d870489 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -1,10 +1,10 @@ #include "Kaleidoscope-LEDEffect-Rainbow.h" -LEDRainbowEffect_::LEDRainbowEffect_ (void) { +LEDRainbowEffect_::LEDRainbowEffect_(void) { } void -LEDRainbowEffect_::update (void) { +LEDRainbowEffect_::update(void) { if (rainbow_current_ticks++ < rainbow_ticks) { return; } else { @@ -24,11 +24,11 @@ LEDRainbowEffect_ LEDRainbowEffect; // --------- -LEDRainbowWaveEffect_::LEDRainbowWaveEffect_ (void) { +LEDRainbowWaveEffect_::LEDRainbowWaveEffect_(void) { } void -LEDRainbowWaveEffect_::update (void) { +LEDRainbowWaveEffect_::update(void) { if (rainbow_current_ticks++ < rainbow_wave_ticks) { return; } else { @@ -41,7 +41,7 @@ LEDRainbowWaveEffect_::update (void) { key_hue -= 255; } cRGB rainbow = hsv_to_rgb(key_hue, rainbow_saturation, rainbow_value); - LEDControl.led_set_crgb_at (i, rainbow); + LEDControl.led_set_crgb_at(i, rainbow); } rainbow_hue += rainbow_wave_steps; if (rainbow_hue >= 255) { diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 8a309dcf..113b10d3 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -5,9 +5,9 @@ class LEDRainbowEffect_ : public LEDMode { public: - LEDRainbowEffect_ (void); + LEDRainbowEffect_(void); - virtual void update (void) final; + virtual void update(void) final; private: uint16_t rainbow_hue = 0; //stores 0 to 614 @@ -25,9 +25,9 @@ extern LEDRainbowEffect_ LEDRainbowEffect; class LEDRainbowWaveEffect_ : public LEDMode { public: - LEDRainbowWaveEffect_ (void); + LEDRainbowWaveEffect_(void); - virtual void update (void) final; + virtual void update(void) final; private: uint16_t rainbow_hue = 0; //stores 0 to 614 From ecef342f1f0c1e7da62dacaf62da314652a14e60 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:52:50 -0700 Subject: [PATCH 213/792] astyle with current project style guidelines --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 124 +++---- src/Kaleidoscope/AlphaSquare-Effect.cpp | 76 ++--- src/Kaleidoscope/AlphaSquare-Effect.h | 20 +- src/Kaleidoscope/LED-AlphaSquare.cpp | 332 +++++++++---------- src/Kaleidoscope/LED-AlphaSquare.h | 76 ++--- 5 files changed, 314 insertions(+), 314 deletions(-) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index 963ebabd..9324d4d4 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -22,83 +22,83 @@ #include const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, M(0), - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + [0] = KEYMAP_STACKED + ( + Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, M(0), + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_skip, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_skip, - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_skip - ), + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_skip + ), }; const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { - if (!key_toggled_on (keyState)) - return MACRO_NONE; - - if (macroIndex == 0) { - for (uint8_t i = Key_A.keyCode; i <= Key_0.keyCode; i++) { - LEDControl.set_all_leds_to (0, 0, 0); - LEDControl.led_sync (); - delay (100); + if (!key_toggled_on(keyState)) + return MACRO_NONE; - uint8_t col = 2; - if (i % 2) - col = 10; + if (macroIndex == 0) { + for (uint8_t i = Key_A.keyCode; i <= Key_0.keyCode; i++) { + LEDControl.set_all_leds_to(0, 0, 0); + LEDControl.led_sync(); + delay(100); - for (uint8_t step = 0; step <= 0xf0; step += 8) { - AlphaSquare.color = { step, step, step }; - AlphaSquare.display ({i, 0}, col); - delay (10); - } - for (uint8_t step = 0xff; step >= 8; step -= 8) { - AlphaSquare.color = { step, step, step }; - AlphaSquare.display ({i, 0}, col); - delay (10); - } - delay (100); - } + uint8_t col = 2; + if (i % 2) + col = 10; - LEDControl.set_all_leds_to (0, 0, 0); - LEDControl.led_sync (); - delay (100); - for (uint8_t step = 0; step <= 0xf0; step += 8) { - AlphaSquare.color = { step, step, step }; - AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); - AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); - delay (10); - } - for (uint8_t step = 0xff; step >= 8; step -= 8) { - AlphaSquare.color = { step, step, step }; - AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); - AlphaSquare.display (KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); - delay (10); - } - delay (100); + for (uint8_t step = 0; step <= 0xf0; step += 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display({i, 0}, col); + delay(10); + } + for (uint8_t step = 0xff; step >= 8; step -= 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display({i, 0}, col); + delay(10); + } + delay(100); + } + LEDControl.set_all_leds_to(0, 0, 0); + LEDControl.led_sync(); + delay(100); + for (uint8_t step = 0; step <= 0xf0; step += 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); + AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); + delay(10); } - LEDControl.set_all_leds_to (0, 0, 0); + for (uint8_t step = 0xff; step >= 8; step -= 8) { + AlphaSquare.color = { step, step, step }; + AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); + AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); + delay(10); + } + delay(100); - return MACRO_NONE; + } + LEDControl.set_all_leds_to(0, 0, 0); + + return MACRO_NONE; } -void setup () { - Kaleidoscope.setup (); +void setup() { + Kaleidoscope.setup(); - USE_PLUGINS (&AlphaSquare, &AlphaSquareEffect, &Macros); - AlphaSquare.color = { 0xcb, 0xc0, 0xff }; + USE_PLUGINS(&AlphaSquare, &AlphaSquareEffect, &Macros); + AlphaSquare.color = { 0xcb, 0xc0, 0xff }; } -void loop () { - Kaleidoscope.loop (); +void loop() { + Kaleidoscope.loop(); } diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index 2e5ff942..4cbffa0a 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -25,59 +25,59 @@ uint32_t AlphaSquareEffect::endTimeLeft, AlphaSquareEffect::endTimeRight; Key AlphaSquareEffect::lastKeyLeft, AlphaSquareEffect::lastKeyRight; uint8_t AlphaSquareEffect::us; -AlphaSquareEffect::AlphaSquareEffect (void) { +AlphaSquareEffect::AlphaSquareEffect(void) { } void -AlphaSquareEffect::begin (void) { - Kaleidoscope.useEventHandlerHook (eventHandlerHook); - Kaleidoscope.use (&LEDControl, NULL); - us = LEDControl.mode_add (this); +AlphaSquareEffect::begin(void) { + Kaleidoscope.useEventHandlerHook(eventHandlerHook); + Kaleidoscope.use(&LEDControl, NULL); + us = LEDControl.mode_add(this); } void -AlphaSquareEffect::update (void) { - if (endTimeLeft && millis () > endTimeLeft) { - ::AlphaSquare.clear (lastKeyLeft); - endTimeLeft = 0; - } - if (endTimeRight && millis () > endTimeRight) { - ::AlphaSquare.clear (lastKeyRight, 10); - endTimeRight = 0; - } +AlphaSquareEffect::update(void) { + if (endTimeLeft && millis() > endTimeLeft) { + ::AlphaSquare.clear(lastKeyLeft); + endTimeLeft = 0; + } + if (endTimeRight && millis() > endTimeRight) { + ::AlphaSquare.clear(lastKeyRight, 10); + endTimeRight = 0; + } } Key -AlphaSquareEffect::eventHandlerHook (Key key, byte row, byte col, uint8_t keyState) { - if (LEDControl.get_mode () != us) - return key; +AlphaSquareEffect::eventHandlerHook(Key key, byte row, byte col, uint8_t keyState) { + if (LEDControl.get_mode() != us) + return key; - if (keyState & INJECTED) - return key; + if (keyState & INJECTED) + return key; - if (key < Key_A || key > Key_0) - return key; + if (key < Key_A || key > Key_0) + return key; - if (!key_is_pressed (keyState)) - return key; + if (!key_is_pressed(keyState)) + return key; - uint8_t displayCol = 2; - Key prevKey = lastKeyLeft; + uint8_t displayCol = 2; + Key prevKey = lastKeyLeft; - if (col < COLS / 2) { - lastKeyLeft = key; - endTimeLeft = millis () + length; - } else { - prevKey = lastKeyRight; - lastKeyRight = key; - endTimeRight = millis () + length; - displayCol = 10; - } + if (col < COLS / 2) { + lastKeyLeft = key; + endTimeLeft = millis() + length; + } else { + prevKey = lastKeyRight; + lastKeyRight = key; + endTimeRight = millis() + length; + displayCol = 10; + } - if (prevKey != key) - ::AlphaSquare.clear (prevKey, displayCol); - ::AlphaSquare.display (key, displayCol); - return key; + if (prevKey != key) + ::AlphaSquare.clear(prevKey, displayCol); + ::AlphaSquare.display(key, displayCol); + return key; } }; }; diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 7ffbec73..66179084 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -24,19 +24,19 @@ namespace KaleidoscopePlugins { namespace LEDEffects { class AlphaSquareEffect : public LEDMode { - public: - AlphaSquareEffect (void); + public: + AlphaSquareEffect(void); - virtual void begin (void) final; - virtual void update (void) final; + virtual void begin(void) final; + virtual void update(void) final; - static uint16_t length; - private: - static uint32_t endTimeLeft, endTimeRight; - static Key lastKeyLeft, lastKeyRight; - static uint8_t us; + static uint16_t length; + private: + static uint32_t endTimeLeft, endTimeRight; + static Key lastKeyLeft, lastKeyRight; + static uint8_t us; - static Key eventHandlerHook (Key key, uint8_t row, uint8_t col, uint8_t keyState); + static Key eventHandlerHook(Key key, uint8_t row, uint8_t col, uint8_t keyState); }; }; }; diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 6b64d10b..903a2eb2 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -21,196 +21,196 @@ namespace KaleidoscopePlugins { static const uint16_t alphabet[] PROGMEM = { - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 1), // A - SYM4x4(1, 1, 1, 1, - 1, 0, 1, 1, - 1, 1, 0, 1, - 1, 1, 1, 1), // B - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // C - SYM4x4(1, 1, 1, 0, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 0), // D - SYM4x4(1, 1, 1, 1, - 1, 1, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // E - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 1, 1, 1, 0, - 1, 0, 0, 0), // F - SYM4x4(1, 1, 1, 0, - 1, 0, 0, 0, - 1, 0, 0, 1, - 1, 1, 1, 1), // G - SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 0, 1), // H - SYM4x4(1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 1, 1, 1, 1), // I - SYM4x4(1, 1, 1, 1, - 0, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // J - SYM4x4(1, 0, 0, 1, - 1, 1, 0, 0, - 1, 1, 0, 0, - 1, 0, 1, 1), // K - SYM4x4(1, 0, 0, 0, - 1, 0, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // L - SYM4x4(1, 0, 1, 1, - 1, 1, 1, 1, - 1, 1, 0, 1, - 1, 0, 0, 1), // M - SYM4x4(1, 0, 0, 1, - 1, 1, 0, 1, - 1, 0, 1, 1, - 1, 0, 0, 1), // N - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 1), // O - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 0), // P - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 1, 1, - 1, 1, 1, 1), // Q - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 0, - 1, 0, 1, 1), // R - SYM4x4(1, 1, 1, 1, - 1, 1, 0, 0, - 0, 0, 1, 1, - 1, 1, 1, 1), // S - SYM4x4(1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 0, 1, 1, 0), // T - SYM4x4(1, 0, 0, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 1), // U - SYM4x4(1, 0, 0, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // V - SYM4x4(1, 0, 0, 1, - 1, 0, 1, 1, - 1, 1, 1, 1, - 1, 0, 1, 1), // W - SYM4x4(1, 0, 0, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 1, 0, 0, 1), // X - SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0), // Y - SYM4x4(1, 1, 1, 1, - 0, 0, 1, 1, - 1, 1, 0, 0, - 1, 1, 1, 1), // Z - // --------------------- - SYM4x4(0, 1, 1, 0, - 1, 0, 1, 0, - 0, 0, 1, 0, - 1, 1, 1, 1), // 1 - SYM4x4(0, 1, 1, 0, - 1, 0, 0, 1, - 0, 0, 1, 0, - 1, 1, 0, 1), // 2 - SYM4x4(1, 1, 1, 1, - 0, 0, 1, 1, - 0, 0, 0, 1, - 1, 1, 1, 1), // 3 - SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 0, 0, 0, 1, - 0, 0, 0, 1), // 4 - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 0, 1, 1, 1, - 1, 1, 1, 1), // 5 - SYM4x4(0, 1, 1, 0, - 1, 0, 0, 0, - 1, 1, 1, 1, - 1, 1, 1, 1), // 6 - SYM4x4(1, 1, 1, 1, - 0, 0, 0, 1, - 0, 0, 1, 0, - 0, 1, 0, 0), // 7 - SYM4x4(1, 1, 1, 0, - 1, 0, 1, 1, - 1, 1, 0, 1, - 0, 1, 1, 1), // 8 - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 0, 0, 0, 1), // 9 - SYM4x4(0, 1, 1, 0, - 1, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // 0 + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 1), // A + SYM4x4(1, 1, 1, 1, + 1, 0, 1, 1, + 1, 1, 0, 1, + 1, 1, 1, 1), // B + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // C + SYM4x4(1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0), // D + SYM4x4(1, 1, 1, 1, + 1, 1, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // E + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 0), // F + SYM4x4(1, 1, 1, 0, + 1, 0, 0, 0, + 1, 0, 0, 1, + 1, 1, 1, 1), // G + SYM4x4(1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1), // H + SYM4x4(1, 1, 1, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 1, 1, 1), // I + SYM4x4(1, 1, 1, 1, + 0, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // J + SYM4x4(1, 0, 0, 1, + 1, 1, 0, 0, + 1, 1, 0, 0, + 1, 0, 1, 1), // K + SYM4x4(1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1), // L + SYM4x4(1, 0, 1, 1, + 1, 1, 1, 1, + 1, 1, 0, 1, + 1, 0, 0, 1), // M + SYM4x4(1, 0, 0, 1, + 1, 1, 0, 1, + 1, 0, 1, 1, + 1, 0, 0, 1), // N + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1), // O + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 0), // P + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 1, 1, + 1, 1, 1, 1), // Q + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 1, 1, 0, + 1, 0, 1, 1), // R + SYM4x4(1, 1, 1, 1, + 1, 1, 0, 0, + 0, 0, 1, 1, + 1, 1, 1, 1), // S + SYM4x4(1, 1, 1, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, + 0, 1, 1, 0), // T + SYM4x4(1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1), // U + SYM4x4(1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // V + SYM4x4(1, 0, 0, 1, + 1, 0, 1, 1, + 1, 1, 1, 1, + 1, 0, 1, 1), // W + SYM4x4(1, 0, 0, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 0, 0, 1), // X + SYM4x4(1, 0, 0, 1, + 1, 1, 1, 1, + 0, 1, 1, 0, + 0, 1, 1, 0), // Y + SYM4x4(1, 1, 1, 1, + 0, 0, 1, 1, + 1, 1, 0, 0, + 1, 1, 1, 1), // Z + // --------------------- + SYM4x4(0, 1, 1, 0, + 1, 0, 1, 0, + 0, 0, 1, 0, + 1, 1, 1, 1), // 1 + SYM4x4(0, 1, 1, 0, + 1, 0, 0, 1, + 0, 0, 1, 0, + 1, 1, 0, 1), // 2 + SYM4x4(1, 1, 1, 1, + 0, 0, 1, 1, + 0, 0, 0, 1, + 1, 1, 1, 1), // 3 + SYM4x4(1, 0, 0, 1, + 1, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 0, 1), // 4 + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 0, + 0, 1, 1, 1, + 1, 1, 1, 1), // 5 + SYM4x4(0, 1, 1, 0, + 1, 0, 0, 0, + 1, 1, 1, 1, + 1, 1, 1, 1), // 6 + SYM4x4(1, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 1, 0, + 0, 1, 0, 0), // 7 + SYM4x4(1, 1, 1, 0, + 1, 0, 1, 1, + 1, 1, 0, 1, + 0, 1, 1, 1), // 8 + SYM4x4(1, 1, 1, 1, + 1, 0, 0, 1, + 1, 1, 1, 1, + 0, 0, 0, 1), // 9 + SYM4x4(0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0), // 0 }; cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; -AlphaSquare::AlphaSquare (void) { +AlphaSquare::AlphaSquare(void) { } void -AlphaSquare::begin (void) { +AlphaSquare::begin(void) { } void -AlphaSquare::display (Key key, uint8_t row, uint8_t col, cRGB keyColor) { - if (key < Key_A || key > Key_0) - return; +AlphaSquare::display(Key key, uint8_t row, uint8_t col, cRGB keyColor) { + if (key < Key_A || key > Key_0) + return; - uint8_t index = key.keyCode - Key_A.keyCode; - uint16_t symbol = pgm_read_word (&alphabet[index]); + uint8_t index = key.keyCode - Key_A.keyCode; + uint16_t symbol = pgm_read_word(&alphabet[index]); - display (symbol, row, col, keyColor); + display(symbol, row, col, keyColor); } void -AlphaSquare::display (Key key, uint8_t row, uint8_t col) { - display (key, row, col, color); +AlphaSquare::display(Key key, uint8_t row, uint8_t col) { + display(key, row, col, color); } void -AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor) { - for (uint8_t r = 0; r < 4; r++) { - for (uint8_t c = 0; c < 4; c++) { - uint8_t pixel = bitRead (symbol, r * 4 + c); - if (!pixel) - continue; +AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor) { + for (uint8_t r = 0; r < 4; r++) { + for (uint8_t c = 0; c < 4; c++) { + uint8_t pixel = bitRead(symbol, r * 4 + c); + if (!pixel) + continue; - LEDControl.led_set_crgb_at (row + r, col + c, keyColor); - } + LEDControl.led_set_crgb_at(row + r, col + c, keyColor); } + } - LEDControl.led_sync (); + LEDControl.led_sync(); } void -AlphaSquare::display (uint16_t symbol, uint8_t row, uint8_t col) { - display (symbol, row, col, color); +AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col) { + display(symbol, row, col, color); } }; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index 71588c78..f63ea287 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -36,50 +36,50 @@ namespace KaleidoscopePlugins { class AlphaSquare : public KaleidoscopePlugin { - public: - AlphaSquare (void); + public: + AlphaSquare(void); - virtual void begin (void) final; + virtual void begin(void) final; - static void display (Key key, uint8_t row, uint8_t col, cRGB keyColor); - static void display (Key key, uint8_t row, uint8_t col); - static void display (Key key) { - display (key, 0, 2); - }; - static void display (Key key, uint8_t col) { - display (key, 0, col); - }; + static void display(Key key, uint8_t row, uint8_t col, cRGB keyColor); + static void display(Key key, uint8_t row, uint8_t col); + static void display(Key key) { + display(key, 0, 2); + }; + static void display(Key key, uint8_t col) { + display(key, 0, col); + }; - static void display (uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor); - static void display (uint16_t symbol, uint8_t row, uint8_t col); - static void display (uint16_t symbol) { - display (symbol, 0, 2); - }; - static void display (uint16_t symbol, uint8_t col) { - display (symbol, 0, col); - }; + static void display(uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor); + static void display(uint16_t symbol, uint8_t row, uint8_t col); + static void display(uint16_t symbol) { + display(symbol, 0, 2); + }; + static void display(uint16_t symbol, uint8_t col) { + display(symbol, 0, col); + }; - static void clear (Key key, uint8_t row, uint8_t col) { - display (key, row, col, {0, 0, 0}); - }; - static void clear (Key key, uint8_t col) { - clear (key, 0, col); - }; - static void clear (Key key) { - clear (key, 0, 2); - }; + static void clear(Key key, uint8_t row, uint8_t col) { + display(key, row, col, {0, 0, 0}); + }; + static void clear(Key key, uint8_t col) { + clear(key, 0, col); + }; + static void clear(Key key) { + clear(key, 0, 2); + }; - static void clear (uint16_t symbol, uint8_t row, uint8_t col) { - display (symbol, row, col, {0, 0, 0}); - }; - static void clear (uint16_t symbol, uint8_t col) { - clear (symbol, 0, col); - }; - static void clear (uint16_t symbol) { - clear (symbol, 0, 2); - }; + static void clear(uint16_t symbol, uint8_t row, uint8_t col) { + display(symbol, row, col, {0, 0, 0}); + }; + static void clear(uint16_t symbol, uint8_t col) { + clear(symbol, 0, col); + }; + static void clear(uint16_t symbol) { + clear(symbol, 0, 2); + }; - static cRGB color; + static cRGB color; }; }; From 959e20b6787a767fd34474120ad8889652920d56 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:55:02 -0700 Subject: [PATCH 214/792] astyle with current project style guidelines --- src/Kaleidoscope-Hardware-Model01.cpp | 226 +++++++++++++------------- src/Kaleidoscope-Hardware-Model01.h | 56 +++---- 2 files changed, 141 insertions(+), 141 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 07c95730..5853d562 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -18,12 +18,12 @@ Model01::Model01(void) { } void Model01::enable_scanner_power(void) { - // PC7 - //pinMode(13, OUTPUT); - //digitalWrite(13, HIGH); - // Turn on power to the LED net - DDRC |= _BV(7); - PORTC |= _BV(7); + // PC7 + //pinMode(13, OUTPUT); + //digitalWrite(13, HIGH); + // Turn on power to the LED net + DDRC |= _BV(7); + PORTC |= _BV(7); } @@ -31,174 +31,174 @@ void Model01::enable_scanner_power(void) { // the host. That violates the USB spec. But it sure // is pretty looking void Model01::enable_high_power_leds(void) { - // PE6 - // pinMode(7, OUTPUT); - // digitalWrite(7, LOW); - DDRE |= _BV(6); - PORTE &= ~_BV(6); + // PE6 + // pinMode(7, OUTPUT); + // digitalWrite(7, LOW); + DDRE |= _BV(6); + PORTE &= ~_BV(6); - // Set B4, the overcurrent check to an input with an internal pull-up - DDRB &= ~_BV(4); // set bit, input - PORTB &= ~_BV(4); // set bit, enable pull-up resistor + // Set B4, the overcurrent check to an input with an internal pull-up + DDRB &= ~_BV(4); // set bit, input + PORTB &= ~_BV(4); // set bit, enable pull-up resistor } void Model01::setup(void) { - wdt_disable(); - delay(100); - enable_scanner_power(); - - // Consider not doing this until 30s after keyboard - // boot up, to make it easier to rescue things - // in case of power draw issues. - enable_high_power_leds(); - leftHandState.all = 0; - rightHandState.all = 0; - - TWBR=12; // This is 400mhz, which is the fastest we can drive the ATTiny + wdt_disable(); + delay(100); + enable_scanner_power(); + + // Consider not doing this until 30s after keyboard + // boot up, to make it easier to rescue things + // in case of power draw issues. + enable_high_power_leds(); + leftHandState.all = 0; + rightHandState.all = 0; + + TWBR=12; // This is 400mhz, which is the fastest we can drive the ATTiny } void Model01::led_set_crgb_at(uint8_t i, cRGB crgb) { - if(i<32) { - cRGB oldColor = led_get_crgb_at(i); - isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); - - leftHand.ledData.leds[i] = crgb; - } else if (i<64) { - cRGB oldColor = led_get_crgb_at(i); - isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); - - rightHand.ledData.leds[i-32] = crgb; - } else { - // TODO how do we want to handle debugging assertions about crazy user - // code that would overwrite other memory? - } + if (i<32) { + cRGB oldColor = led_get_crgb_at(i); + isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); + + leftHand.ledData.leds[i] = crgb; + } else if (i<64) { + cRGB oldColor = led_get_crgb_at(i); + isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); + + rightHand.ledData.leds[i-32] = crgb; + } else { + // TODO how do we want to handle debugging assertions about crazy user + // code that would overwrite other memory? + } } void Model01::led_set_crgb_at(byte row, byte col, cRGB color) { - led_set_crgb_at(key_led_map[row][col], color); + led_set_crgb_at(key_led_map[row][col], color); } uint8_t Model01::get_led_index(byte row, byte col) { - return key_led_map[row][col]; + return key_led_map[row][col]; } cRGB Model01::led_get_crgb_at(uint8_t i) { - if(i<32) { - return leftHand.ledData.leds[i]; - } else if (i<64) { - return rightHand.ledData.leds[i-32] ; - } else { - return {0, 0, 0}; - } + if (i<32) { + return leftHand.ledData.leds[i]; + } else if (i<64) { + return rightHand.ledData.leds[i-32] ; + } else { + return {0, 0, 0}; + } } void Model01::led_sync() { - if (!isLEDChanged) - return; + if (!isLEDChanged) + return; - leftHand.sendLEDData(); - rightHand.sendLEDData(); + leftHand.sendLEDData(); + rightHand.sendLEDData(); - leftHand.sendLEDData(); - rightHand.sendLEDData(); + leftHand.sendLEDData(); + rightHand.sendLEDData(); - leftHand.sendLEDData(); - rightHand.sendLEDData(); + leftHand.sendLEDData(); + rightHand.sendLEDData(); - leftHand.sendLEDData(); - rightHand.sendLEDData(); + leftHand.sendLEDData(); + rightHand.sendLEDData(); - isLEDChanged = false; + isLEDChanged = false; } boolean Model01::led_power_fault() { - if (PINB & _BV(4)) { - return true; - } else { - return false; - } + if (PINB & _BV(4)) { + return true; + } else { + return false; + } } void debug_keyswitch_event(keydata_t state, keydata_t previousState, uint8_t keynum, uint8_t row, uint8_t col) { - if (bitRead(state.all, keynum) != bitRead(previousState.all, keynum )) { - Serial.print("Looking at row "); - Serial.print(row); - Serial.print(", col "); - Serial.print(col); - Serial.print(" key # "); - Serial.print(keynum); - Serial.print(" "); - Serial.print(bitRead(previousState.all, keynum)); - Serial.print(" -> "); - Serial.print(bitRead(state.all, keynum )); - Serial.println(); - } + if (bitRead(state.all, keynum) != bitRead(previousState.all, keynum)) { + Serial.print("Looking at row "); + Serial.print(row); + Serial.print(", col "); + Serial.print(col); + Serial.print(" key # "); + Serial.print(keynum); + Serial.print(" "); + Serial.print(bitRead(previousState.all, keynum)); + Serial.print(" -> "); + Serial.print(bitRead(state.all, keynum)); + Serial.println(); + } } void Model01::read_matrix() { - //scan the Keyboard matrix looking for connections - previousLeftHandState = leftHandState; - previousRightHandState = rightHandState; + //scan the Keyboard matrix looking for connections + previousLeftHandState = leftHandState; + previousRightHandState = rightHandState; - if (leftHand.readKeys()) { - leftHandState = leftHand.getKeyData(); - } + if (leftHand.readKeys()) { + leftHandState = leftHand.getKeyData(); + } - if (rightHand.readKeys()) { - rightHandState = rightHand.getKeyData(); - } + if (rightHand.readKeys()) { + rightHandState = rightHand.getKeyData(); + } } void Model01::act_on_matrix_scan() { - for (byte row = 0; row < 4; row++) { - for (byte col = 0; col < 8; col++) { + for (byte row = 0; row < 4; row++) { + for (byte col = 0; col < 8; col++) { - uint8_t keynum = (row*8)+(col); + uint8_t keynum = (row*8)+(col); - uint8_t keyState = (bitRead(previousLeftHandState.all, keynum) << 0) | - (bitRead(leftHandState.all, keynum) << 1); - handle_keyswitch_event(Key_NoKey, row, 7-col, keyState); + uint8_t keyState = (bitRead(previousLeftHandState.all, keynum) << 0) | + (bitRead(leftHandState.all, keynum) << 1); + handle_keyswitch_event(Key_NoKey, row, 7-col, keyState); - keyState = (bitRead(previousRightHandState.all, keynum) << 0) | - (bitRead(rightHandState.all, keynum) << 1); + keyState = (bitRead(previousRightHandState.all, keynum) << 0) | + (bitRead(rightHandState.all, keynum) << 1); - handle_keyswitch_event(Key_NoKey, row, (15- col), keyState); - } + handle_keyswitch_event(Key_NoKey, row, (15- col), keyState); } + } } void Model01::scan_matrix() { - read_matrix(); - act_on_matrix_scan(); + read_matrix(); + act_on_matrix_scan(); } void Model01::reboot_bootloader() { - // Set the magic bits to get a Caterina-based device - // to reboot into the bootloader and stay there, rather - // than run move onward - // - // These values are the same as those defined in - // Caterina.c + // Set the magic bits to get a Caterina-based device + // to reboot into the bootloader and stay there, rather + // than run move onward + // + // These values are the same as those defined in + // Caterina.c - uint16_t bootKey = 0x7777; - uint16_t *const bootKeyPtr = (uint16_t *)0x0800; + uint16_t bootKey = 0x7777; + uint16_t *const bootKeyPtr = (uint16_t *)0x0800; - // Stash the magic key - *bootKeyPtr = bootKey; + // Stash the magic key + *bootKeyPtr = bootKey; - // Set a watchdog timer - wdt_enable(WDTO_120MS); + // Set a watchdog timer + wdt_enable(WDTO_120MS); - while (1) {} // This infinite loop ensures nothing else - // happens before the watchdog reboots us + while (1) {} // This infinite loop ensures nothing else + // happens before the watchdog reboots us } HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index f43b7bff..5a12845d 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -11,34 +11,34 @@ #define CRGB(r,g,b) (cRGB){b, g, r} class Model01 { - public: - Model01(void); - void led_sync(void); - void led_set_crgb_at(byte row, byte col, cRGB color); - void led_set_crgb_at(uint8_t i, cRGB crgb); - cRGB led_get_crgb_at(uint8_t i); - cRGB get_key_color(byte row, byte col); - uint8_t get_led_index(byte row, byte col); - - void scan_matrix(void); - void read_matrix(void); - void act_on_matrix_scan(void); - void setup(); - void enable_high_power_leds(void); - void enable_scanner_power(void); - void reboot_bootloader(); - - boolean led_power_fault(void); - - keydata_t leftHandState; - keydata_t rightHandState; - keydata_t previousLeftHandState; - keydata_t previousRightHandState; - - private: - static bool isLEDChanged; - static KeyboardioScanner leftHand; - static KeyboardioScanner rightHand; + public: + Model01(void); + void led_sync(void); + void led_set_crgb_at(byte row, byte col, cRGB color); + void led_set_crgb_at(uint8_t i, cRGB crgb); + cRGB led_get_crgb_at(uint8_t i); + cRGB get_key_color(byte row, byte col); + uint8_t get_led_index(byte row, byte col); + + void scan_matrix(void); + void read_matrix(void); + void act_on_matrix_scan(void); + void setup(); + void enable_high_power_leds(void); + void enable_scanner_power(void); + void reboot_bootloader(); + + boolean led_power_fault(void); + + keydata_t leftHandState; + keydata_t rightHandState; + keydata_t previousLeftHandState; + keydata_t previousRightHandState; + + private: + static bool isLEDChanged; + static KeyboardioScanner leftHand; + static KeyboardioScanner rightHand; }; #define SCANBIT(row,col) ((uint32_t)1 << (row * 8 + (7 - col))) From a0b2d400dbed4c706144fc51a69c979b9d1ef7b0 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 22:56:30 -0700 Subject: [PATCH 215/792] astyle with current project style guidelines --- examples/EEPROM-Settings/EEPROM-Settings.ino | 58 ++++----- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 128 +++++++++---------- src/Kaleidoscope/EEPROM-Settings-Focus.h | 4 +- src/Kaleidoscope/EEPROM-Settings.cpp | 84 ++++++------ src/Kaleidoscope/EEPROM-Settings.h | 52 ++++---- src/Kaleidoscope/crc.cpp | 54 ++++---- src/Kaleidoscope/crc.h | 16 +-- 7 files changed, 198 insertions(+), 198 deletions(-) diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino index ef8fcc2d..09c6e59e 100644 --- a/examples/EEPROM-Settings/EEPROM-Settings.ino +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -20,41 +20,41 @@ #include const Key keymaps[][ROWS][COLS] PROGMEM = { - [0] = KEYMAP_STACKED - ( - Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_skip, - - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_skip - ), + [0] = KEYMAP_STACKED + ( + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_skip + ), }; -void setup () { - Serial.begin (9600); +void setup() { + Serial.begin(9600); - Kaleidoscope.setup (); + Kaleidoscope.setup(); - USE_PLUGINS (&EEPROMSettings); + USE_PLUGINS(&EEPROMSettings); - while (!Serial) { - } + while (!Serial) { + } - Serial.println (EEPROMSettings.isValid () ? F("valid EEPROM settings") : F("invalid EEPROM settings")); - Serial.println (EEPROMSettings.crc (), HEX); - Serial.println (EEPROMSettings.version ()); + Serial.println(EEPROMSettings.isValid() ? F("valid EEPROM settings") : F("invalid EEPROM settings")); + Serial.println(EEPROMSettings.crc(), HEX); + Serial.println(EEPROMSettings.version()); } -void loop () { - Kaleidoscope.loop (); +void loop() { + Kaleidoscope.loop(); } diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 4a187e7e..3bdee5b3 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -21,79 +21,79 @@ #include "crc.h" namespace FocusHooks { -bool settings (const char *command) { - enum { - ISVALID, - GETVERSION, - CRC, - } subCommand; +bool settings(const char *command) { + enum { + ISVALID, + GETVERSION, + CRC, + } subCommand; - if (strncmp_P (command, PSTR ("settings."), 9) != 0) - return false; + if (strncmp_P(command, PSTR("settings."), 9) != 0) + return false; - if (strcmp_P (command + 9, PSTR ("valid?")) == 0) - subCommand = ISVALID; - else if (strcmp_P (command + 9, PSTR ("version")) == 0) - subCommand = GETVERSION; - else if (strcmp_P (command + 9, PSTR ("crc")) == 0) - subCommand = CRC; - else - return false; + if (strcmp_P(command + 9, PSTR("valid?")) == 0) + subCommand = ISVALID; + else if (strcmp_P(command + 9, PSTR("version")) == 0) + subCommand = GETVERSION; + else if (strcmp_P(command + 9, PSTR("crc")) == 0) + subCommand = CRC; + else + return false; - switch (subCommand) { - case ISVALID: - Focus.printBool (EEPROMSettings.isValid ()); - Serial.println (); - break; - case GETVERSION: - Serial.println (EEPROMSettings.version ()); - break; - case CRC: - Serial.print (::CRC.crc, HEX); - Serial.print (F("/")); - Serial.println (EEPROMSettings.crc (), HEX); - break; - } + switch (subCommand) { + case ISVALID: + Focus.printBool(EEPROMSettings.isValid()); + Serial.println(); + break; + case GETVERSION: + Serial.println(EEPROMSettings.version()); + break; + case CRC: + Serial.print(::CRC.crc, HEX); + Serial.print(F("/")); + Serial.println(EEPROMSettings.crc(), HEX); + break; + } - return true; + return true; } -bool eeprom (const char *command) { - enum { - CONTENTS, - FREE, - } subCommand; - - if (strcmp_P (command, PSTR ("eeprom.contents")) == 0) - subCommand = CONTENTS; - else if (strcmp_P (command, PSTR ("eeprom.free")) == 0) - subCommand = FREE; - else - return false; +bool eeprom(const char *command) { + enum { + CONTENTS, + FREE, + } subCommand; - switch (subCommand) { - case CONTENTS: { - if (Serial.peek () == '\n') { - for (uint16_t i = 0; i < EEPROM.length (); i++) { - uint8_t d = EEPROM[i]; - Focus.printNumber (d); - Focus.printSpace (); - } - Serial.println (); - } else { - for (uint16_t i = 0; i < EEPROM.length () && Serial.peek () != '\n'; i++) { - uint8_t d = Serial.parseInt (); - EEPROM.update (i, d); - } - } + if (strcmp_P(command, PSTR("eeprom.contents")) == 0) + subCommand = CONTENTS; + else if (strcmp_P(command, PSTR("eeprom.free")) == 0) + subCommand = FREE; + else + return false; - break; - } - case FREE: - Serial.println (EEPROM.length () - EEPROMSettings.used ()); - break; + switch (subCommand) { + case CONTENTS: { + if (Serial.peek() == '\n') { + for (uint16_t i = 0; i < EEPROM.length(); i++) { + uint8_t d = EEPROM[i]; + Focus.printNumber(d); + Focus.printSpace(); + } + Serial.println(); + } else { + for (uint16_t i = 0; i < EEPROM.length() && Serial.peek() != '\n'; i++) { + uint8_t d = Serial.parseInt(); + EEPROM.update(i, d); + } } - return true; + break; + } + case FREE: + Serial.println(EEPROM.length() - EEPROMSettings.used()); + break; + } + + return true; } }; diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index 00e9ea6d..42beef42 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -21,8 +21,8 @@ #include namespace FocusHooks { -bool settings (const char *command); -bool eeprom (const char *command); +bool settings(const char *command); +bool eeprom(const char *command); }; #define FOCUS_HOOK_SETTINGS FOCUS_HOOK(FocusHooks::settings, \ diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index d81bb9f2..02dabacb 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -23,87 +23,87 @@ namespace KaleidoscopePlugins { struct EEPROMSettings::settings EEPROMSettings::settings; bool EEPROMSettings::_isValid; bool EEPROMSettings::sealed; -uint16_t EEPROMSettings::nextStart = sizeof (EEPROMSettings::settings); +uint16_t EEPROMSettings::nextStart = sizeof(EEPROMSettings::settings); -EEPROMSettings::EEPROMSettings (void) { +EEPROMSettings::EEPROMSettings(void) { } void -EEPROMSettings::begin (void) { - EEPROM.get (0, settings); +EEPROMSettings::begin(void) { + EEPROM.get(0, settings); } bool -EEPROMSettings::isValid (void) { - return _isValid; +EEPROMSettings::isValid(void) { + return _isValid; } uint16_t -EEPROMSettings::crc (void) { - if (sealed) - return settings.crc; - return 0; +EEPROMSettings::crc(void) { + if (sealed) + return settings.crc; + return 0; } void -EEPROMSettings::seal (void) { - sealed = true; +EEPROMSettings::seal(void) { + sealed = true; - CRC.finalize (); + CRC.finalize(); - if (settings.magic[0] != 'K' || settings.magic[1] != 'S') { - settings.magic[0] = 'K'; - settings.magic[1] = 'S'; - settings.version = 0; - settings.crc = CRC.crc; + if (settings.magic[0] != 'K' || settings.magic[1] != 'S') { + settings.magic[0] = 'K'; + settings.magic[1] = 'S'; + settings.version = 0; + settings.crc = CRC.crc; - return update (); - } + return update(); + } - if (settings.crc != CRC.crc) - _isValid = false; + if (settings.crc != CRC.crc) + _isValid = false; } uint16_t -EEPROMSettings::requestSlice (uint16_t size) { - if (sealed) - return 0; +EEPROMSettings::requestSlice(uint16_t size) { + if (sealed) + return 0; - uint16_t start = nextStart; - nextStart += size; + uint16_t start = nextStart; + nextStart += size; - CRC.update ((const void *)&size, sizeof (size)); + CRC.update((const void *)&size, sizeof(size)); - return start; + return start; } void -EEPROMSettings::invalidate (void) { - _isValid = false; +EEPROMSettings::invalidate(void) { + _isValid = false; } uint16_t -EEPROMSettings::used (void) { - return nextStart; +EEPROMSettings::used(void) { + return nextStart; } void -EEPROMSettings::update (void) { - settings.crc = CRC.crc; +EEPROMSettings::update(void) { + settings.crc = CRC.crc; - EEPROM.put (0, settings); - _isValid = true; + EEPROM.put(0, settings); + _isValid = true; } uint8_t -EEPROMSettings::version (void) { - return settings.version; +EEPROMSettings::version(void) { + return settings.version; } void -EEPROMSettings::version (uint8_t ver) { - settings.version = ver; - update (); +EEPROMSettings::version(uint8_t ver) { + settings.version = ver; + update(); } }; diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 4c9e2c48..8f2d81a0 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -23,32 +23,32 @@ namespace KaleidoscopePlugins { class EEPROMSettings : public KaleidoscopePlugin { - public: - EEPROMSettings (void); - - virtual void begin (void) final; - - static void update (void); - static bool isValid (void); - static void invalidate (void); - static uint8_t version (void); - static void version (uint8_t ver); - - static uint16_t requestSlice (uint16_t size); - static void seal (void); - static uint16_t crc (void); - static uint16_t used (void); - - private: - static uint16_t nextStart; - static bool _isValid; - static bool sealed; - - static struct settings { - char magic[2]; - uint8_t version; - uint16_t crc; - } settings; + public: + EEPROMSettings(void); + + virtual void begin(void) final; + + static void update(void); + static bool isValid(void); + static void invalidate(void); + static uint8_t version(void); + static void version(uint8_t ver); + + static uint16_t requestSlice(uint16_t size); + static void seal(void); + static uint16_t crc(void); + static uint16_t used(void); + + private: + static uint16_t nextStart; + static bool _isValid; + static bool sealed; + + static struct settings { + char magic[2]; + uint8_t version; + uint16_t crc; + } settings; }; }; diff --git a/src/Kaleidoscope/crc.cpp b/src/Kaleidoscope/crc.cpp index a3a1a5e8..4ae8d23f 100644 --- a/src/Kaleidoscope/crc.cpp +++ b/src/Kaleidoscope/crc.cpp @@ -30,41 +30,41 @@ #include "crc.h" void -CRC_::reflect (uint8_t len) { - uint8_t i; - uint16_t newCRC; +CRC_::reflect(uint8_t len) { + uint8_t i; + uint16_t newCRC; - newCRC = crc & 0x01; - for (i = 1; i < len; i++) { - crc >>= 1; - newCRC = (newCRC << 1) | (crc & 0x01); - } + newCRC = crc & 0x01; + for (i = 1; i < len; i++) { + crc >>= 1; + newCRC = (newCRC << 1) | (crc & 0x01); + } - crc = newCRC; + crc = newCRC; } void -CRC_::update (const void *data, uint8_t len) { - const uint8_t *d = (const uint8_t *)data; - uint8_t i; - bool bit; - uint8_t c; +CRC_::update(const void *data, uint8_t len) { + const uint8_t *d = (const uint8_t *)data; + uint8_t i; + bool bit; + uint8_t c; - while (len--) { - c = *d++; - for (i = 0x01; i & 0xff; i <<= 1) { - bit = crc & 0x8000; - if (c & i) { - bit = !bit; - } - crc <<= 1; - if (bit) { - crc ^= 0x8005; - } - } - crc &= 0xffff; + while (len--) { + c = *d++; + for (i = 0x01; i & 0xff; i <<= 1) { + bit = crc & 0x8000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x8005; + } } crc &= 0xffff; + } + crc &= 0xffff; } CRC_ CRC; diff --git a/src/Kaleidoscope/crc.h b/src/Kaleidoscope/crc.h index f0f919b7..cba1d21d 100644 --- a/src/Kaleidoscope/crc.h +++ b/src/Kaleidoscope/crc.h @@ -32,16 +32,16 @@ #include class CRC_ { - public: - uint16_t crc = 0; + public: + uint16_t crc = 0; - CRC_ (void) {}; + CRC_(void) {}; - void update (const void *data, uint8_t len); - void finalize (void) { - reflect (16); - }; - void reflect (uint8_t len); + void update(const void *data, uint8_t len); + void finalize(void) { + reflect(16); + }; + void reflect(uint8_t len); }; extern CRC_ CRC; From 002174a4f1ad72bf7ddb6b4c73715a8a83c2e348 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:16:13 -0700 Subject: [PATCH 216/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From dda023cad829568a4d575d21e983ac6dce5a52a5 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:18:24 -0700 Subject: [PATCH 217/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 286bafae49ebfc31599df5e547a983ba40ebc481 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:19:41 -0700 Subject: [PATCH 218/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 194d038532a56903335635f5d7ef603eae62d940 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:19:54 -0700 Subject: [PATCH 219/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From b04570b9dd5d1bb2fa6e32fd506cd5e39f84df7e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:20:06 -0700 Subject: [PATCH 220/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 980f4338445bdecac5f98c6d849afa78ed36d1bd Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:20:28 -0700 Subject: [PATCH 221/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 20b52f91bfedb3afbe6672f9bbc800d1d3f9235b Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:20:44 -0700 Subject: [PATCH 222/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 6dadb862e58e112c4a96e0b8a19b02877ff3762e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:20:58 -0700 Subject: [PATCH 223/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 135f91dfa35bf99de66196efeba71b67bd5e9f7a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:21:24 -0700 Subject: [PATCH 224/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 42c833c81a271ce4ce7064ac9302b02658dc815a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:24:52 -0700 Subject: [PATCH 225/792] linter cleanup --- src/Kaleidoscope-Numlock.cpp | 2 +- src/Kaleidoscope-Numlock.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 15fe07a8..1fc5ba7f 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -16,7 +16,7 @@ NumLock_::NumLock_(void) { void NumLock_::begin(void) { us = LEDControl.mode_add(this); - numpad_color.r=255; + numpad_color.r = 255; } void diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-Numlock.h index 3dc27052..eaa448b4 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -11,10 +11,10 @@ class NumLock_ : public LEDMode { public: NumLock_(void); - virtual void begin(void) final; + void begin(void) final; - virtual void update(void) final; - virtual void init(void) final; + void update(void) final; + void init(void) final; static const macro_t *toggle(byte row, byte col, uint8_t numPadLayer); From 91da0ae68e48f52ca4fb7e5908b02ab24d5a7577 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:27:51 -0700 Subject: [PATCH 226/792] Make the linter happy --- src/Kaleidoscope-LEDControl.cpp | 8 ++++---- src/Kaleidoscope-LEDControl.h | 10 +++++----- src/LED-Off.h | 4 ++-- src/LEDUtils.cpp | 1 - 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index be82deae..bdc76ba4 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -85,9 +85,9 @@ LEDControl_::mode_add(LEDMode *mode) { void LEDControl_::set_all_leds_to(uint8_t r, uint8_t g, uint8_t b) { cRGB color; - color.r=r; - color.g=g; - color.b=b; + color.r = r; + color.g = g; + color.b = b; set_all_leds_to(color); } @@ -217,7 +217,7 @@ LEDControl_::focusHook(const char *command) { LEDControl.next_mode(); Serial.read(); } else if (peek == 'p') { - // TODO + // TODO(algernon) Serial.read(); } else { uint8_t mode = Serial.parseInt(); diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 45753748..6dbf92f7 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -4,16 +4,16 @@ #define LED_MAX_MODES 24 -#define LED_TOGGLE B00000001 // Synthetic, internal +#define LED_TOGGLE B00000001 // Synthetic, internal #define Key_LEDEffectNext (Key) { 0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } class LEDMode : public KaleidoscopePlugin { public: virtual void begin(void); - virtual void setup(void) {}; - virtual void init(void) {}; - virtual void update(void) {}; + virtual void setup(void) {} + virtual void init(void) {} + virtual void update(void) {} virtual void activate(void); }; @@ -21,7 +21,7 @@ class LEDControl_ : public KaleidoscopePlugin { public: LEDControl_(void); - virtual void begin(void) final; + void begin(void) final; static void next_mode(void); static void setup(void); diff --git a/src/LED-Off.h b/src/LED-Off.h index 6b1d1313..19d65cde 100644 --- a/src/LED-Off.h +++ b/src/LED-Off.h @@ -4,9 +4,9 @@ class LEDOff_ : public LEDMode { public: - LEDOff_(void) { }; + LEDOff_(void) { } - virtual void update(void) final; + void update(void) final; }; extern LEDOff_ LEDOff; diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp index f67772db..7601ba3d 100644 --- a/src/LEDUtils.cpp +++ b/src/LEDUtils.cpp @@ -2,7 +2,6 @@ cRGB breath_compute() { - // This code is adapted from FastLED lib8tion.h as of dd5d96c6b289cb6b4b891748a4aeef3ddceaf0e6 // Eventually, we should consider just using FastLED From d515f0088b5520e3ea0c6228744dec78e61b8e0f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:32:58 -0700 Subject: [PATCH 227/792] Make the linter happy --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 7 +- src/Kaleidoscope/AlphaSquare-Effect.h | 4 +- src/Kaleidoscope/LED-AlphaSquare.cpp | 72 ++++++++++---------- src/Kaleidoscope/LED-AlphaSquare.h | 28 ++++---- 4 files changed, 55 insertions(+), 56 deletions(-) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index 9324d4d4..94553ba9 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -38,8 +38,7 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_skip - ), + Key_skip), }; const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { @@ -72,12 +71,14 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { LEDControl.set_all_leds_to(0, 0, 0); LEDControl.led_sync(); delay(100); + for (uint8_t step = 0; step <= 0xf0; step += 8) { AlphaSquare.color = { step, step, step }; AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); delay(10); } + for (uint8_t step = 0xff; step >= 8; step -= 8) { AlphaSquare.color = { step, step, step }; AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); @@ -85,8 +86,8 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { delay(10); } delay(100); - } + LEDControl.set_all_leds_to(0, 0, 0); return MACRO_NONE; diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 66179084..f4426bfa 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -27,8 +27,8 @@ class AlphaSquareEffect : public LEDMode { public: AlphaSquareEffect(void); - virtual void begin(void) final; - virtual void update(void) final; + void begin(void) final; + void update(void) final; static uint16_t length; private: diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 903a2eb2..df8c2173 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -24,148 +24,148 @@ static const uint16_t alphabet[] PROGMEM = { SYM4x4(1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 0, 0, 1), // A + 1, 0, 0, 1), // A SYM4x4(1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1), // B + 1, 1, 1, 1), // B SYM4x4(1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, - 1, 1, 1, 1), // C + 1, 1, 1, 1), // C SYM4x4(1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, - 1, 1, 1, 0), // D + 1, 1, 1, 0), // D SYM4x4(1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, - 1, 1, 1, 1), // E + 1, 1, 1, 1), // E SYM4x4(1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 0, 0, 0), // F + 1, 0, 0, 0), // F SYM4x4(1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, - 1, 1, 1, 1), // G + 1, 1, 1, 1), // G SYM4x4(1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, - 1, 0, 0, 1), // H + 1, 0, 0, 1), // H SYM4x4(1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, - 1, 1, 1, 1), // I + 1, 1, 1, 1), // I SYM4x4(1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, - 0, 1, 1, 0), // J + 0, 1, 1, 0), // J SYM4x4(1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, - 1, 0, 1, 1), // K + 1, 0, 1, 1), // K SYM4x4(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, - 1, 1, 1, 1), // L + 1, 1, 1, 1), // L SYM4x4(1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, - 1, 0, 0, 1), // M + 1, 0, 0, 1), // M SYM4x4(1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, - 1, 0, 0, 1), // N + 1, 0, 0, 1), // N SYM4x4(1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, - 1, 1, 1, 1), // O + 1, 1, 1, 1), // O SYM4x4(1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 0, 0, 0), // P + 1, 0, 0, 0), // P SYM4x4(1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, - 1, 1, 1, 1), // Q + 1, 1, 1, 1), // Q SYM4x4(1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, - 1, 0, 1, 1), // R + 1, 0, 1, 1), // R SYM4x4(1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1), // S + 1, 1, 1, 1), // S SYM4x4(1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, - 0, 1, 1, 0), // T + 0, 1, 1, 0), // T SYM4x4(1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, - 1, 1, 1, 1), // U + 1, 1, 1, 1), // U SYM4x4(1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, - 0, 1, 1, 0), // V + 0, 1, 1, 0), // V SYM4x4(1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1), // W + 1, 0, 1, 1), // W SYM4x4(1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, - 1, 0, 0, 1), // X + 1, 0, 0, 1), // X SYM4x4(1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, - 0, 1, 1, 0), // Y + 0, 1, 1, 0), // Y SYM4x4(1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1), // Z + 1, 1, 1, 1), // Z // --------------------- SYM4x4(0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, - 1, 1, 1, 1), // 1 + 1, 1, 1, 1), // 1 SYM4x4(0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, - 1, 1, 0, 1), // 2 + 1, 1, 0, 1), // 2 SYM4x4(1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, - 1, 1, 1, 1), // 3 + 1, 1, 1, 1), // 3 SYM4x4(1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, - 0, 0, 0, 1), // 4 + 0, 0, 0, 1), // 4 SYM4x4(1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 1, 1), // 5 + 1, 1, 1, 1), // 5 SYM4x4(0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1), // 6 + 1, 1, 1, 1), // 6 SYM4x4(1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 0), // 7 + 0, 1, 0, 0), // 7 SYM4x4(1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, - 0, 1, 1, 1), // 8 + 0, 1, 1, 1), // 8 SYM4x4(1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 0, 0, 0, 1), // 9 + 0, 0, 0, 1), // 9 SYM4x4(0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, - 0, 1, 1, 0), // 0 + 0, 1, 1, 0), // 0 }; cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index f63ea287..32e060b4 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -25,59 +25,57 @@ p00, p01, p02, p03, \ p10, p11, p12, p13, \ p20, p21, p22, p23, \ - p30, p31, p32, p33 \ - ) \ + p30, p31, p32, p33) \ (uint16_t) ( \ p00 << 0 | p01 << 1 | p02 << 2 | p03 << 3 | \ p10 << 4 | p11 << 5 | p12 << 6 | p13 << 7 | \ p20 << 8 | p21 << 9 | p22 << 10 | p23 << 11 | \ - p30 << 12 | p31 << 13 | p32 << 14 | p33 << 15 \ - ) + p30 << 12 | p31 << 13 | p32 << 14 | p33 << 15 ) namespace KaleidoscopePlugins { class AlphaSquare : public KaleidoscopePlugin { public: AlphaSquare(void); - virtual void begin(void) final; + void begin(void) final; static void display(Key key, uint8_t row, uint8_t col, cRGB keyColor); static void display(Key key, uint8_t row, uint8_t col); static void display(Key key) { display(key, 0, 2); - }; + } static void display(Key key, uint8_t col) { display(key, 0, col); - }; + } static void display(uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor); static void display(uint16_t symbol, uint8_t row, uint8_t col); static void display(uint16_t symbol) { display(symbol, 0, 2); - }; + } static void display(uint16_t symbol, uint8_t col) { display(symbol, 0, col); - }; + } static void clear(Key key, uint8_t row, uint8_t col) { display(key, row, col, {0, 0, 0}); - }; + } static void clear(Key key, uint8_t col) { clear(key, 0, col); - }; + } static void clear(Key key) { clear(key, 0, 2); - }; + } static void clear(uint16_t symbol, uint8_t row, uint8_t col) { display(symbol, row, col, {0, 0, 0}); - }; + } static void clear(uint16_t symbol, uint8_t col) { clear(symbol, 0, col); - }; + } static void clear(uint16_t symbol) { clear(symbol, 0, 2); - }; + } static cRGB color; }; From 78b3739a4edc15ecc2f44273697a2c25704d7f65 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:41:43 -0700 Subject: [PATCH 228/792] partially satisfying the cpplint complaints --- src/Kaleidoscope-MouseKeys.cpp | 3 ++- src/MouseKeyDefs.h | 8 ++++---- src/MouseWrapper.cpp | 1 - 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 2f4f6926..7a6017b6 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -90,8 +90,9 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS if (key_is_pressed(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { scrollWheel(mappedKey.keyCode); - } else + } else { mouseMoveIntent |= mappedKey.keyCode; + } } } else if (key_toggled_on(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index 4b998dc0..83ca84d3 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -1,11 +1,11 @@ #pragma once -#define IS_MOUSE_KEY B00010000 +#define IS_MOUSE_KEY B00010000 // Synthetic, not internal -#define KEY_MOUSE_BTN_L 0x01 // Synthetic key -#define KEY_MOUSE_BTN_M 0x02 // Synthetic key -#define KEY_MOUSE_BTN_R 0x03 // Synthetic key +#define KEY_MOUSE_BTN_L 0x01 // Synthetic key +#define KEY_MOUSE_BTN_M 0x02 // Synthetic key +#define KEY_MOUSE_BTN_R 0x03 // Synthetic key #define KEY_MOUSE_UP B0000001 diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index b6495cc7..2e09a600 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -20,7 +20,6 @@ MouseWrapper_::MouseWrapper_(void) { void MouseWrapper_::press_button(uint8_t button) { Mouse.press(button); end_warping(); - } void MouseWrapper_::release_button(uint8_t button) { From 5de9053fd27cbda060cc611603d64d5aa02bde35 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:42:34 -0700 Subject: [PATCH 229/792] Make cpplint happy --- src/Kaleidoscope-MouseKeys.h | 2 +- src/MouseWrapper.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index ee71fb0d..255a0888 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -7,7 +7,7 @@ class MouseKeys_ : public KaleidoscopePlugin { public: MouseKeys_(void); - virtual void begin(void) final; + void begin(void) final; static uint8_t speed; static uint16_t speedDelay; diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 2e09a600..5aa522b6 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -27,8 +27,8 @@ void MouseWrapper_::release_button(uint8_t button) { } void MouseWrapper_::warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width) { - uint16_t x_center = left + width/2; - uint16_t y_center = top + height/2; + uint16_t x_center = left + width / 2; + uint16_t y_center = top + height / 2; AbsoluteMouse.moveTo(x_center, y_center); } @@ -41,7 +41,7 @@ void MouseWrapper_::begin_warping() { } void MouseWrapper_::end_warping() { - is_warping= false; + is_warping = false; } void MouseWrapper_::warp(uint8_t warp_cmd) { @@ -54,8 +54,8 @@ void MouseWrapper_::warp(uint8_t warp_cmd) { return; } - next_width = next_width/2; - next_height = next_height/2; + next_width = next_width / 2; + next_height = next_height / 2; if (warp_cmd & WARP_UP) { // Serial.print(" - up "); @@ -71,7 +71,7 @@ void MouseWrapper_::warp(uint8_t warp_cmd) { section_left = section_left + next_width; } - warp_jump(section_left, section_top, next_height,next_width); + warp_jump(section_left, section_top, next_height, next_width); } // cubic wave function based on code from FastLED @@ -84,8 +84,8 @@ uint8_t MouseWrapper_::acceleration(uint8_t cycles) { i = i << 1; - uint8_t ii = (i*i) >> 8; - uint8_t iii = (ii*i) >> 8; + uint8_t ii = (i * i) >> 8; + uint8_t iii = (ii * i) >> 8; i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + ACCELERATION_FLOOR; @@ -97,7 +97,7 @@ uint8_t MouseWrapper_::acceleration(uint8_t cycles) { void MouseWrapper_::move(int8_t x, int8_t y) { - int16_t moveX =0; + int16_t moveX = 0; int16_t moveY = 0; if (x != 0) { moveX = (x * acceleration(accelStep)); From 9dc8703308418608fb35e256132d253d37ed5642 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:49:57 -0700 Subject: [PATCH 230/792] astyle to pad operators --- src/Kaleidoscope-Hardware-Model01.cpp | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 5853d562..8c4af4f6 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -7,10 +7,10 @@ KeyboardioScanner Model01::rightHand(3); bool Model01::isLEDChanged = true; static constexpr uint8_t key_led_map[4][16] = { - {3,4,11,12,19,20,26,27, 36,37,43,44,51,52,59,60}, - {2,5,10,13,18,21,25,28, 35,38,42,45,50,53,58,61}, - {1,6, 9,14,17,22,24,29, 34,39,41,46,49,54,57,62}, - {0,7, 8,15,16,23,31,30, 33,32,40,47,48,55,56,63}, + {3, 4, 11, 12, 19, 20, 26, 27, 36, 37, 43, 44, 51, 52, 59, 60}, + {2, 5, 10, 13, 18, 21, 25, 28, 35, 38, 42, 45, 50, 53, 58, 61}, + {1, 6, 9, 14, 17, 22, 24, 29, 34, 39, 41, 46, 49, 54, 57, 62}, + {0, 7, 8, 15, 16, 23, 31, 30, 33, 32, 40, 47, 48, 55, 56, 63}, }; Model01::Model01(void) { @@ -57,21 +57,21 @@ void Model01::setup(void) { leftHandState.all = 0; rightHandState.all = 0; - TWBR=12; // This is 400mhz, which is the fastest we can drive the ATTiny + TWBR = 12; // This is 400mhz, which is the fastest we can drive the ATTiny } void Model01::led_set_crgb_at(uint8_t i, cRGB crgb) { - if (i<32) { + if (i < 32) { cRGB oldColor = led_get_crgb_at(i); isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); leftHand.ledData.leds[i] = crgb; - } else if (i<64) { + } else if (i < 64) { cRGB oldColor = led_get_crgb_at(i); isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); - rightHand.ledData.leds[i-32] = crgb; + rightHand.ledData.leds[i - 32] = crgb; } else { // TODO how do we want to handle debugging assertions about crazy user // code that would overwrite other memory? @@ -87,10 +87,10 @@ uint8_t Model01::get_led_index(byte row, byte col) { } cRGB Model01::led_get_crgb_at(uint8_t i) { - if (i<32) { + if (i < 32) { return leftHand.ledData.leds[i]; - } else if (i<64) { - return rightHand.ledData.leds[i-32] ; + } else if (i < 64) { + return rightHand.ledData.leds[i - 32] ; } else { return {0, 0, 0}; } @@ -160,16 +160,16 @@ void Model01::act_on_matrix_scan() { for (byte row = 0; row < 4; row++) { for (byte col = 0; col < 8; col++) { - uint8_t keynum = (row*8)+(col); + uint8_t keynum = (row * 8) + (col); uint8_t keyState = (bitRead(previousLeftHandState.all, keynum) << 0) | (bitRead(leftHandState.all, keynum) << 1); - handle_keyswitch_event(Key_NoKey, row, 7-col, keyState); + handle_keyswitch_event(Key_NoKey, row, 7 - col, keyState); keyState = (bitRead(previousRightHandState.all, keynum) << 0) | (bitRead(rightHandState.all, keynum) << 1); - handle_keyswitch_event(Key_NoKey, row, (15- col), keyState); + handle_keyswitch_event(Key_NoKey, row, (15 - col), keyState); } } } From 36a0632d6d8903bd5514e5e185e966cc271b6c70 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:49:57 -0700 Subject: [PATCH 231/792] astyle to pad operators --- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 2411b4f3..a56b17ca 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -116,7 +116,7 @@ bool EEPROMKeymap::focusKeymapTransfer(const char *command) { for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t col = 0; col < COLS; col++) { Key k = Layer.getKeyFromPROGMEM(layer, row, col); - uint16_t pos =((layer * ROWS * COLS) + (row * COLS) + col); + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); updateKey(pos, k); } From 0308c89cb4143af0a8992651c349d6eb2e36dd26 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:49:58 -0700 Subject: [PATCH 232/792] astyle to pad operators --- src/LEDUtils.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp index 7601ba3d..c4cc98fc 100644 --- a/src/LEDUtils.cpp +++ b/src/LEDUtils.cpp @@ -5,15 +5,15 @@ breath_compute() { // This code is adapted from FastLED lib8tion.h as of dd5d96c6b289cb6b4b891748a4aeef3ddceaf0e6 // Eventually, we should consider just using FastLED - uint8_t i = (uint16_t)millis()/12; + uint8_t i = (uint16_t)millis() / 12; if (i & 0x80) { i = 255 - i; } i = i << 1; - uint8_t ii = (i*i)>>8; - uint8_t iii = (ii*i)>>8; + uint8_t ii = (i * i) >> 8; + uint8_t iii = (ii * i) >> 8; i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + 2; @@ -38,9 +38,9 @@ hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v) { } /* make hue 0-5 */ - region = (h *6) >> 8; + region = (h * 6) >> 8; /* find remainder part, make it from 0-255 */ - fpart = (h*6) - (region <<8); + fpart = (h * 6) - (region << 8); /* calculate temp vars, doing integer multiplication */ p = (v * (255 - s)) >> 8; From 0c645e957be3e1b4b791d44d2ba283bac8565bbe Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:49:58 -0700 Subject: [PATCH 233/792] astyle to pad operators --- src/Kaleidoscope-LEDEffect-Chase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp index c8298dbd..76455f64 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -9,7 +9,7 @@ LEDChaseEffect_::update(void) { return; } current_chase_counter = 0; - LEDControl.led_set_crgb_at(pos - (chase_sign* chase_pixels), {0, 0, 0}); + LEDControl.led_set_crgb_at(pos - (chase_sign * chase_pixels), {0, 0, 0}); LEDControl.led_set_crgb_at(pos, {0, 0, 0}); pos += chase_sign; From d790a01bb22abc912262963044079e902905f863 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:49:58 -0700 Subject: [PATCH 234/792] astyle to pad operators --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index 9d870489..58b85125 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -36,7 +36,7 @@ LEDRainbowWaveEffect_::update(void) { } for (uint8_t i = 0; i < LED_COUNT; i++) { - uint16_t key_hue = rainbow_hue +16*(i/4); + uint16_t key_hue = rainbow_hue + 16 * (i / 4); if (key_hue >= 255) { key_hue -= 255; } From 4ae6bff15df6024c09c4eac3715ce1dbf5209854 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:49:58 -0700 Subject: [PATCH 235/792] astyle to pad operators --- src/Kaleidoscope-Model01-TestMode.cpp | 46 +++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index c94687f9..61c18580 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -13,9 +13,9 @@ TestMode_::TestMode_(void) { void TestMode_::begin(void) { - red.r=101; - blue.b=101; - green.g=101; + red.r = 101; + blue.b = 101; + green.g = 101; loop_hook_use(this->loopHook); } @@ -43,7 +43,7 @@ void TestMode_::wait_for_keypress() { } void TestMode_::set_leds(uint8_t r, uint8_t g, uint8_t b) { - LEDControl.set_all_leds_to(r,g,b); + LEDControl.set_all_leds_to(r, g, b); LEDControl.led_sync(); wait_for_keypress(); @@ -51,23 +51,23 @@ void TestMode_::set_leds(uint8_t r, uint8_t g, uint8_t b) { void TestMode_::test_leds(void) { // make all LEDs dim red - set_leds(50,0,0); + set_leds(50, 0, 0); // make all LEDs dim blue - set_leds(0,50,0); + set_leds(0, 50, 0); // make all LEDs dim green - set_leds(0,0,50); + set_leds(0, 0, 50); // make all LEDs dim white - set_leds(50,50,50); + set_leds(50, 50, 50); // make all the LEDs bright red - set_leds(200,0,0); + set_leds(200, 0, 0); // make all the LEDs bright green - set_leds(0,200,0); + set_leds(0, 200, 0); // make all the LEDs bright blue - set_leds(0,0,200); + set_leds(0, 0, 200); // make all the LEDs bright white (1.6A) - set_leds(160,160,160); + set_leds(160, 160, 160); // rainbow for 10 seconds - for (auto i=0; i<1000; i++) { + for (auto i = 0; i < 1000; i++) { LEDRainbowEffect.update(); LEDControl.led_sync(); } @@ -78,7 +78,7 @@ void TestMode_::test_leds(void) { void TestMode_::test_matrix() { - LEDControl.set_all_leds_to(50,0,0); + LEDControl.set_all_leds_to(50, 0, 0); while (1) { KeyboardHardware.read_matrix(); if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6)) { @@ -87,32 +87,32 @@ void TestMode_::test_matrix() { for (byte row = 0; row < 4; row++) { for (byte col = 0; col < 8; col++) { - uint8_t keynum = (row*8)+(col); + uint8_t keynum = (row * 8) + (col); uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); - if (keyState ==3) { + if (keyState == 3) { Serial.print(" Key: "); Serial.print(keynum); Serial.print(" value "); Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 7-col, green); - } else if (keyState ==1) { - KeyboardHardware.led_set_crgb_at(row,7-col, blue); + KeyboardHardware.led_set_crgb_at(row, 7 - col, green); + } else if (keyState == 1) { + KeyboardHardware.led_set_crgb_at(row, 7 - col, blue); } keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); - if (keyState ==3) { + if (keyState == 3) { Serial.print(" Key: "); Serial.print(keynum); Serial.print(" value "); Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 15-col, green); - } else if (keyState ==1) { - KeyboardHardware.led_set_crgb_at(row,15-col, blue); + KeyboardHardware.led_set_crgb_at(row, 15 - col, green); + } else if (keyState == 1) { + KeyboardHardware.led_set_crgb_at(row, 15 - col, blue); } } } From 34ea7200ac70bbdf0f51de2794aeb6843782ae4c Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 3 Jun 2017 23:56:26 -0700 Subject: [PATCH 236/792] Add build infrastructure --- .travis.yml | 21 +++++++++++++++++++++ Makefile | 12 ++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce0c4a9 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk From 49887a2805440461d2f4550772c46c154d5cad83 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 4 Jun 2017 00:34:59 -0700 Subject: [PATCH 237/792] virtual void begin(void) final is redunant and makes the linter unhappy --- src/Kaleidoscope/EEPROM-Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 8f2d81a0..5f17938b 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -26,7 +26,7 @@ class EEPROMSettings : public KaleidoscopePlugin { public: EEPROMSettings(void); - virtual void begin(void) final; + void begin(void) final; static void update(void); static bool isValid(void); From 16ecc25dbe34c2bcac0b4142dfb0d88f3372a16d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 4 Jun 2017 00:35:00 -0700 Subject: [PATCH 238/792] virtual void begin(void) final is redunant and makes the linter unhappy --- src/Kaleidoscope/LED-Stalker.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 9954c674..6af2b1b8 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -32,7 +32,7 @@ class StalkerEffect : public LEDMode { StalkerEffect(void); - virtual void begin(void) final; + void begin(void) final; virtual void init(void) final; virtual void update(void) final; From 7da1fe702ace91ccef3aa11e2586a7aa40c9227f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 4 Jun 2017 00:35:00 -0700 Subject: [PATCH 239/792] virtual void begin(void) final is redunant and makes the linter unhappy --- src/Kaleidoscope/MagicCombo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 0db57feb..9b44c8e5 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -29,7 +29,7 @@ class MagicCombo : public KaleidoscopePlugin { MagicCombo(void); - virtual void begin(void) final; + void begin(void) final; static void configure(const dictionary_t dictionary[]); static uint16_t minInterval; From 6521013ca5f6f5c05bc772b7f29e0b127f65055f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 4 Jun 2017 00:35:00 -0700 Subject: [PATCH 240/792] virtual void begin(void) final is redunant and makes the linter unhappy --- src/Kaleidoscope-Macros.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index d37befd7..eddaef23 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -11,7 +11,7 @@ class Macros_ : public KaleidoscopePlugin { public: Macros_(void); - virtual void begin(void) final; + void begin(void) final; void play(const macro_t *macro_p); From 202860575baf726f3555f6a1ac58ce9f26aff383 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 4 Jun 2017 12:18:58 +0200 Subject: [PATCH 241/792] Kaleidoscope Style Guide conformance Signed-off-by: Gergely Nagy --- README.md | 41 ++++++++++--- src/Kaleidoscope/EEPROM-Settings.cpp | 90 +++++++++++++--------------- src/Kaleidoscope/EEPROM-Settings.h | 12 ++-- 3 files changed, 81 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 00be48d8..aa0e3fba 100644 --- a/README.md +++ b/README.md @@ -37,24 +37,24 @@ static struct { } testSettings; void setup () { - Kaleidoscope.setup (); + Kaleidoscope.setup(); - USE_PLUGINS (&EEPROMSettings); + USE_PLUGINS(&EEPROMSettings); /* Use other plugins that make use of the EEPROM */ - settingsBase = EEPROMSettings.requestSlice (sizeof (testSettings)); + settingsBase = EEPROMSettings.requestSlice(sizeof(testSettings)); - EEPROMSettings.seal (); + EEPROMSettings.seal(); - if (!EEPROMSettings.isValid ()) { + if (!EEPROMSettings.isValid()) { // Handle the case where the settings are out of sync... // Flash LEDs, for example. return; } - EEPROM.get (settingsBase, testSettings); + EEPROM.get(settingsBase, testSettings); } ``` @@ -115,13 +115,40 @@ The plugin provides the `EEPROMSettings` object, which has the following methods > > Should only be used after calling `seal()`. -## Focus Hooks +## Focus commands The plugin provides two [Focus][focus] hooks: `FOCUS_HOOK_SETTINGS`, and `FOCUS_HOOK_EEPROM`, that register commands that allow one to work with the settings, and with the contents of the `EEPROM` through Focus. [focus]: https://github.com/keyboardio/Kaleidoscope-Focus + +These provide the following `Focus` commands: + +### `settings.crc` + +> Returns the actual, and the expected checksum of the settings. + +### `settings.valid?` + +> Returns either `true` or `false`, depending on whether the sealed settings are +> to be considered valid or not. + +### `settings.version` + +> Returns the (user-set) version of the settings. + +### `eeprom.contents` + +> Without argument, displays the full contents of the `EEPROM`, including the +> settings header. +> +> With arguments, the command updates as much of the `EEPROM` as arguments are +> provided. It will discard any unnecessary arguments. + +### `eeprom.free` + +> Returns the amount of free bytes in `EEPROM`. ## Dependencies diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 02dabacb..9037c701 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -19,92 +19,84 @@ #include #include "crc.h" -namespace KaleidoscopePlugins { -struct EEPROMSettings::settings EEPROMSettings::settings; -bool EEPROMSettings::_isValid; -bool EEPROMSettings::sealed; -uint16_t EEPROMSettings::nextStart = sizeof(EEPROMSettings::settings); +namespace kaleidoscope { + +struct EEPROMSettings::settings EEPROMSettings::settings_; +bool EEPROMSettings::is_valid_; +bool EEPROMSettings::sealed_; +uint16_t EEPROMSettings::next_start_ = sizeof(EEPROMSettings::settings); EEPROMSettings::EEPROMSettings(void) { } -void -EEPROMSettings::begin(void) { - EEPROM.get(0, settings); +void EEPROMSettings::begin(void) { + EEPROM.get(0, settings_); } -bool -EEPROMSettings::isValid(void) { - return _isValid; +bool EEPROMSettings::isValid(void) { + return is_valid_; } -uint16_t -EEPROMSettings::crc(void) { - if (sealed) - return settings.crc; +uint16_t EEPROMSettings::crc(void) { + if (sealed_) + return settings_.crc; return 0; } -void -EEPROMSettings::seal(void) { - sealed = true; +void EEPROMSettings::seal(void) { + sealed_ = true; CRC.finalize(); - if (settings.magic[0] != 'K' || settings.magic[1] != 'S') { - settings.magic[0] = 'K'; - settings.magic[1] = 'S'; - settings.version = 0; - settings.crc = CRC.crc; + if (settings_.magic[0] != 'K' || settings_.magic[1] != 'S') { + settings_.magic[0] = 'K'; + settings_.magic[1] = 'S'; + settings_.version = 0; + settings_.crc = CRC.crc; return update(); } - if (settings.crc != CRC.crc) - _isValid = false; + if (settings_.crc != CRC.crc) + is_valid_ = false; } -uint16_t -EEPROMSettings::requestSlice(uint16_t size) { - if (sealed) +uint16_t EEPROMSettings::requestSlice(uint16_t size) { + if (sealed_) return 0; - uint16_t start = nextStart; - nextStart += size; + uint16_t start = next_start_; + next_start_ += size; CRC.update((const void *)&size, sizeof(size)); return start; } -void -EEPROMSettings::invalidate(void) { - _isValid = false; +void EEPROMSettings::invalidate(void) { + is_valid_ = false; } -uint16_t -EEPROMSettings::used(void) { - return nextStart; +uint16_t EEPROMSettings::used(void) { + return next_start_; } -void -EEPROMSettings::update(void) { - settings.crc = CRC.crc; +void EEPROMSettings::update(void) { + settings_.crc = CRC.crc; - EEPROM.put(0, settings); - _isValid = true; + EEPROM.put(0, settings_); + is_valid_ = true; } -uint8_t -EEPROMSettings::version(void) { - return settings.version; +uint8_t EEPROMSettings::version(void) { + return settings_.version; } -void -EEPROMSettings::version(uint8_t ver) { - settings.version = ver; +void EEPROMSettings::version(uint8_t ver) { + settings_.version = ver; update(); } -}; -KaleidoscopePlugins::EEPROMSettings EEPROMSettings; +} + +kaleidoscope::EEPROMSettings EEPROMSettings; diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 5f17938b..b58f6536 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -21,7 +21,7 @@ #include #include -namespace KaleidoscopePlugins { +namespace kaleidoscope { class EEPROMSettings : public KaleidoscopePlugin { public: EEPROMSettings(void); @@ -40,16 +40,16 @@ class EEPROMSettings : public KaleidoscopePlugin { static uint16_t used(void); private: - static uint16_t nextStart; - static bool _isValid; - static bool sealed; + static uint16_t next_start_; + static bool is_valid_; + static bool sealed_; static struct settings { char magic[2]; uint8_t version; uint16_t crc; - } settings; + } settings_; }; }; -extern KaleidoscopePlugins::EEPROMSettings EEPROMSettings; +extern kaleidoscope::EEPROMSettings EEPROMSettings; From da90c342fb9dfd918c0fe7ffe4afb928601a4b14 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 4 Jun 2017 12:20:19 +0200 Subject: [PATCH 242/792] Some more linter-triggered fixes Signed-off-by: Gergely Nagy --- examples/EEPROM-Settings/EEPROM-Settings.ino | 32 +++++++++----------- src/Kaleidoscope/crc.h | 2 +- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino index 09c6e59e..3e0fb16f 100644 --- a/examples/EEPROM-Settings/EEPROM-Settings.ino +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -21,23 +21,21 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED - ( - Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, - Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, - Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, - Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, - - Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, - Key_skip, - - Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, - Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, - Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, - - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_skip - ), + (Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_skip), }; void setup() { diff --git a/src/Kaleidoscope/crc.h b/src/Kaleidoscope/crc.h index cba1d21d..83e72187 100644 --- a/src/Kaleidoscope/crc.h +++ b/src/Kaleidoscope/crc.h @@ -40,7 +40,7 @@ class CRC_ { void update(const void *data, uint8_t len); void finalize(void) { reflect(16); - }; + } void reflect(uint8_t len); }; From 564b656162e795611a4f34f4c0e1805e4557bf0f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 4 Jun 2017 12:24:15 +0200 Subject: [PATCH 243/792] README.md: Minor style adjustment Signed-off-by: Gergely Nagy --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index aa0e3fba..617b3ddb 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,12 @@ static struct { } testSettings; void setup () { - Kaleidoscope.setup(); - USE_PLUGINS(&EEPROMSettings); /* Use other plugins that make use of the EEPROM */ + Kaleidoscope.setup(); + settingsBase = EEPROMSettings.requestSlice(sizeof(testSettings)); EEPROMSettings.seal(); From c5980dc5a689d93ef9873483f0d5aace79608471 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 4 Jun 2017 12:51:53 +0200 Subject: [PATCH 244/792] Local variables shall follow the style guide too Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 3bdee5b3..e8d06db9 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -21,26 +21,27 @@ #include "crc.h" namespace FocusHooks { + bool settings(const char *command) { enum { ISVALID, GETVERSION, CRC, - } subCommand; + } sub_command; if (strncmp_P(command, PSTR("settings."), 9) != 0) return false; if (strcmp_P(command + 9, PSTR("valid?")) == 0) - subCommand = ISVALID; + sub_command = ISVALID; else if (strcmp_P(command + 9, PSTR("version")) == 0) - subCommand = GETVERSION; + sub_command = GETVERSION; else if (strcmp_P(command + 9, PSTR("crc")) == 0) - subCommand = CRC; + sub_command = CRC; else return false; - switch (subCommand) { + switch (sub_command) { case ISVALID: Focus.printBool(EEPROMSettings.isValid()); Serial.println(); @@ -62,16 +63,16 @@ bool eeprom(const char *command) { enum { CONTENTS, FREE, - } subCommand; + } sub_command; if (strcmp_P(command, PSTR("eeprom.contents")) == 0) - subCommand = CONTENTS; + sub_command = CONTENTS; else if (strcmp_P(command, PSTR("eeprom.free")) == 0) - subCommand = FREE; + sub_command = FREE; else return false; - switch (subCommand) { + switch (sub_command) { case CONTENTS: { if (Serial.peek() == '\n') { for (uint16_t i = 0; i < EEPROM.length(); i++) { @@ -96,4 +97,5 @@ bool eeprom(const char *command) { return true; } -}; + +} From ae8cd514a2e45aeca6ef3822e1fe2494d1c2b1bf Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 4 Jun 2017 12:56:05 +0200 Subject: [PATCH 245/792] Focus hooks shall follow the style guide more closely Moved them to the a namespace much more fitting, and renamed the hooks too. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 17 +++++++------ src/Kaleidoscope/EEPROM-Settings-Focus.h | 28 +++++++++++++--------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index e8d06db9..66f536b7 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -20,9 +20,10 @@ #include #include "crc.h" -namespace FocusHooks { +namespace kaleidoscope { +namespace eeprom_settings { -bool settings(const char *command) { +bool settingsFocusHook(const char *command) { enum { ISVALID, GETVERSION, @@ -43,23 +44,23 @@ bool settings(const char *command) { switch (sub_command) { case ISVALID: - Focus.printBool(EEPROMSettings.isValid()); + Focus.printBool(::EEPROMSettings.isValid()); Serial.println(); break; case GETVERSION: - Serial.println(EEPROMSettings.version()); + Serial.println(::EEPROMSettings.version()); break; case CRC: Serial.print(::CRC.crc, HEX); Serial.print(F("/")); - Serial.println(EEPROMSettings.crc(), HEX); + Serial.println(::EEPROMSettings.crc(), HEX); break; } return true; } -bool eeprom(const char *command) { +bool eepromFocusHook(const char *command) { enum { CONTENTS, FREE, @@ -91,7 +92,7 @@ bool eeprom(const char *command) { break; } case FREE: - Serial.println(EEPROM.length() - EEPROMSettings.used()); + Serial.println(EEPROM.length() - ::EEPROMSettings.used()); break; } @@ -99,3 +100,5 @@ bool eeprom(const char *command) { } } + +} diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index 42beef42..fdd250df 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -20,16 +20,22 @@ #include -namespace FocusHooks { -bool settings(const char *command); -bool eeprom(const char *command); -}; +namespace kaleidoscope { +namespace eeprom_settings { -#define FOCUS_HOOK_SETTINGS FOCUS_HOOK(FocusHooks::settings, \ - "settings.valid?\n" \ - "settings.version\n" \ - "settings.crc") +bool settingsFocusHook(const char *command); +bool eepromFocusHook(const char *command); -#define FOCUS_HOOK_EEPROM FOCUS_HOOK(FocusHooks::eeprom, \ - "eeprom.free\n" \ - "eeprom.contents") +} +} + +#define FOCUS_HOOK_SETTINGS FOCUS_HOOK \ + (kaleidoscope::eeprom_settings::settingsFocusHook, \ + "settings.valid?\n" \ + "settings.version\n" \ + "settings.crc") + +#define FOCUS_HOOK_EEPROM FOCUS_HOOK \ + (kalediscope::eeprom_settings::eepromFocusHook, \ + "eeprom.free\n" \ + "eeprom.contents") From 33a19c3b51023a0c4c23a5601b2fc4885212a2a9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 4 Jun 2017 14:43:06 +0200 Subject: [PATCH 246/792] Fix the Focus hooks We need to reference the global `Focus` object, not a local one, to avoid confusion. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 66f536b7..9a14c0a1 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -44,7 +44,7 @@ bool settingsFocusHook(const char *command) { switch (sub_command) { case ISVALID: - Focus.printBool(::EEPROMSettings.isValid()); + ::Focus.printBool(::EEPROMSettings.isValid()); Serial.println(); break; case GETVERSION: @@ -78,8 +78,8 @@ bool eepromFocusHook(const char *command) { if (Serial.peek() == '\n') { for (uint16_t i = 0; i < EEPROM.length(); i++) { uint8_t d = EEPROM[i]; - Focus.printNumber(d); - Focus.printSpace(); + ::Focus.printNumber(d); + ::Focus.printSpace(); } Serial.println(); } else { From 583e916590dd60fa208389e27d046d7c91f4672f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 4 Jun 2017 18:58:20 +0200 Subject: [PATCH 247/792] Fix a typo Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index fdd250df..aac30d59 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -36,6 +36,6 @@ bool eepromFocusHook(const char *command); "settings.crc") #define FOCUS_HOOK_EEPROM FOCUS_HOOK \ - (kalediscope::eeprom_settings::eepromFocusHook, \ + (kaleidoscope::eeprom_settings::eepromFocusHook, \ "eeprom.free\n" \ "eeprom.contents") From 9e6b7e22f625ce1cf8d9dfa5f6a5334ad921ade3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 4 Jun 2017 19:28:31 +0200 Subject: [PATCH 248/792] Kaleidoscope Style Guide conformance Signed-off-by: Gergely Nagy --- README.md | 24 +++++--- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 17 +++--- src/Kaleidoscope/AlphaSquare-Effect.cpp | 60 ++++++++++---------- src/Kaleidoscope/AlphaSquare-Effect.h | 16 +++--- src/Kaleidoscope/AlphaSquare-Symbols.h | 11 ++-- src/Kaleidoscope/LED-AlphaSquare.cpp | 26 ++++----- src/Kaleidoscope/LED-AlphaSquare.h | 11 ++-- 7 files changed, 87 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index b2513975..dd0c5f70 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare - [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 An alphabet for your per-key LEDs, `AlphaSquare` provides a way to display 4x4 "pixel" symbols on your keyboard. With this building block, one can build some @@ -22,11 +22,11 @@ the `display` method. #include #include -void setup () { - Kaleidoscope.setup (); - - USE_PLUGINS (&AlphaSquare); +void setup() { + USE_PLUGINS(&AlphaSquare); + Kaleidoscope.setup(); + AlphaSquare.display (Key_A); } ``` @@ -78,6 +78,16 @@ The plugin provides the `AlphaSquare` object, which has the following methods: > values, a 4x4 square of zeroes and ones. Zeroes are transparent pixels, ones > will be colored. +## Extra symbols + +There is a growing number of extra symbols available in the +`kaleidoscope::alpha_square::symbols` namespace. Ok, growing may have been an +exaggeration, there is only one as of this writing: + +### `Lambda` + +> A lambda (`λ`) symbol. + ## Dependencies * [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index 94553ba9..5e7af7b6 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -41,11 +41,11 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip), }; -const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { - if (!key_toggled_on(keyState)) +const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) { + if (!key_toggled_on(key_state)) return MACRO_NONE; - if (macroIndex == 0) { + if (macro_index == 0) { for (uint8_t i = Key_A.keyCode; i <= Key_0.keyCode; i++) { LEDControl.set_all_leds_to(0, 0, 0); LEDControl.led_sync(); @@ -74,15 +74,15 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { for (uint8_t step = 0; step <= 0xf0; step += 8) { AlphaSquare.color = { step, step, step }; - AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); - AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); + AlphaSquare.display(kaleidoscope::alpha_square::symbols::Lambda, 2); + AlphaSquare.display(kaleidoscope::alpha_square::symbols::Lambda, 10); delay(10); } for (uint8_t step = 0xff; step >= 8; step -= 8) { AlphaSquare.color = { step, step, step }; - AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 2); - AlphaSquare.display(KaleidoscopePlugins::AlphaSquareSymbols::Lambda, 10); + AlphaSquare.display(kaleidoscope::alpha_square::symbols::Lambda, 2); + AlphaSquare.display(kaleidoscope::alpha_square::symbols::Lambda, 10); delay(10); } delay(100); @@ -94,9 +94,10 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { } void setup() { + USE_PLUGINS(&AlphaSquare, &AlphaSquareEffect, &Macros); + Kaleidoscope.setup(); - USE_PLUGINS(&AlphaSquare, &AlphaSquareEffect, &Macros); AlphaSquare.color = { 0xcb, 0xc0, 0xff }; } diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index 4cbffa0a..a8b71871 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -18,12 +18,12 @@ #include -namespace KaleidoscopePlugins { -namespace LEDEffects { +namespace kaleidoscope { + uint16_t AlphaSquareEffect::length = 1000; -uint32_t AlphaSquareEffect::endTimeLeft, AlphaSquareEffect::endTimeRight; -Key AlphaSquareEffect::lastKeyLeft, AlphaSquareEffect::lastKeyRight; -uint8_t AlphaSquareEffect::us; +uint32_t AlphaSquareEffect::end_time_left_, AlphaSquareEffect::end_time_right_; +Key AlphaSquareEffect::last_key_left_, AlphaSquareEffect::last_key_right_; +uint8_t AlphaSquareEffect::us_; AlphaSquareEffect::AlphaSquareEffect(void) { } @@ -32,54 +32,54 @@ void AlphaSquareEffect::begin(void) { Kaleidoscope.useEventHandlerHook(eventHandlerHook); Kaleidoscope.use(&LEDControl, NULL); - us = LEDControl.mode_add(this); + us_ = LEDControl.mode_add(this); } void AlphaSquareEffect::update(void) { - if (endTimeLeft && millis() > endTimeLeft) { - ::AlphaSquare.clear(lastKeyLeft); - endTimeLeft = 0; + if (end_time_left_ && millis() > end_time_left_) { + ::AlphaSquare.clear(last_key_left_); + end_time_left_ = 0; } - if (endTimeRight && millis() > endTimeRight) { - ::AlphaSquare.clear(lastKeyRight, 10); - endTimeRight = 0; + if (end_time_right_ && millis() > end_time_right_) { + ::AlphaSquare.clear(last_key_right_, 10); + end_time_right_ = 0; } } Key -AlphaSquareEffect::eventHandlerHook(Key key, byte row, byte col, uint8_t keyState) { - if (LEDControl.get_mode() != us) +AlphaSquareEffect::eventHandlerHook(Key key, byte row, byte col, uint8_t key_state) { + if (LEDControl.get_mode() != us_) return key; - if (keyState & INJECTED) + if (key_state & INJECTED) return key; if (key < Key_A || key > Key_0) return key; - if (!key_is_pressed(keyState)) + if (!key_is_pressed(key_state)) return key; - uint8_t displayCol = 2; - Key prevKey = lastKeyLeft; + uint8_t display_col = 2; + Key prev_key = last_key_left_; if (col < COLS / 2) { - lastKeyLeft = key; - endTimeLeft = millis() + length; + last_key_left_ = key; + end_time_left_ = millis() + length; } else { - prevKey = lastKeyRight; - lastKeyRight = key; - endTimeRight = millis() + length; - displayCol = 10; + prev_key = last_key_right_; + last_key_right_ = key; + end_time_right_ = millis() + length; + display_col = 10; } - if (prevKey != key) - ::AlphaSquare.clear(prevKey, displayCol); - ::AlphaSquare.display(key, displayCol); + if (prev_key != key) + ::AlphaSquare.clear(prev_key, display_col); + ::AlphaSquare.display(key, display_col); return key; } -}; -}; -KaleidoscopePlugins::LEDEffects::AlphaSquareEffect AlphaSquareEffect; +} + +kaleidoscope::AlphaSquareEffect AlphaSquareEffect; diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index f4426bfa..5b32ce12 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -21,8 +21,7 @@ #include #include -namespace KaleidoscopePlugins { -namespace LEDEffects { +namespace kaleidoscope { class AlphaSquareEffect : public LEDMode { public: AlphaSquareEffect(void); @@ -32,13 +31,12 @@ class AlphaSquareEffect : public LEDMode { static uint16_t length; private: - static uint32_t endTimeLeft, endTimeRight; - static Key lastKeyLeft, lastKeyRight; - static uint8_t us; + static uint32_t end_time_left_, end_time_right_; + static Key last_key_left_, last_key_right_; + static uint8_t us_; - static Key eventHandlerHook(Key key, uint8_t row, uint8_t col, uint8_t keyState); -}; -}; + static Key eventHandlerHook(Key key, uint8_t row, uint8_t col, uint8_t key_state); }; +} -extern KaleidoscopePlugins::LEDEffects::AlphaSquareEffect AlphaSquareEffect; +extern kaleidoscope::AlphaSquareEffect AlphaSquareEffect; diff --git a/src/Kaleidoscope/AlphaSquare-Symbols.h b/src/Kaleidoscope/AlphaSquare-Symbols.h index 80f5b09e..28be9510 100644 --- a/src/Kaleidoscope/AlphaSquare-Symbols.h +++ b/src/Kaleidoscope/AlphaSquare-Symbols.h @@ -20,12 +20,15 @@ #include -namespace KaleidoscopePlugins { -namespace AlphaSquareSymbols { +namespace kaleidoscope { +namespace alpha_square { +namespace symbols { + /* λ */ static constexpr uint16_t Lambda = SYM4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1); -}; -}; +} +} +} diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index df8c2173..845c3183 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -18,7 +18,7 @@ #include -namespace KaleidoscopePlugins { +namespace kaleidoscope { static const uint16_t alphabet[] PROGMEM = { SYM4x4(1, 1, 1, 1, @@ -173,45 +173,41 @@ cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; AlphaSquare::AlphaSquare(void) { } -void -AlphaSquare::begin(void) { +void AlphaSquare::begin(void) { } -void -AlphaSquare::display(Key key, uint8_t row, uint8_t col, cRGB keyColor) { +void AlphaSquare::display(Key key, uint8_t row, uint8_t col, cRGB key_color) { if (key < Key_A || key > Key_0) return; uint8_t index = key.keyCode - Key_A.keyCode; uint16_t symbol = pgm_read_word(&alphabet[index]); - display(symbol, row, col, keyColor); + display(symbol, row, col, key_color); } -void -AlphaSquare::display(Key key, uint8_t row, uint8_t col) { +void AlphaSquare::display(Key key, uint8_t row, uint8_t col) { display(key, row, col, color); } -void -AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor) { +void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col, cRGB key_color) { for (uint8_t r = 0; r < 4; r++) { for (uint8_t c = 0; c < 4; c++) { uint8_t pixel = bitRead(symbol, r * 4 + c); if (!pixel) continue; - LEDControl.led_set_crgb_at(row + r, col + c, keyColor); + LEDControl.led_set_crgb_at(row + r, col + c, key_color); } } LEDControl.led_sync(); } -void -AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col) { +void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col) { display(symbol, row, col, color); } -}; -KaleidoscopePlugins::AlphaSquare AlphaSquare; +} + +kaleidoscope::AlphaSquare AlphaSquare; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index 32e060b4..9595d87f 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -32,14 +32,14 @@ p20 << 8 | p21 << 9 | p22 << 10 | p23 << 11 | \ p30 << 12 | p31 << 13 | p32 << 14 | p33 << 15 ) -namespace KaleidoscopePlugins { +namespace kaleidoscope { class AlphaSquare : public KaleidoscopePlugin { public: AlphaSquare(void); void begin(void) final; - static void display(Key key, uint8_t row, uint8_t col, cRGB keyColor); + static void display(Key key, uint8_t row, uint8_t col, cRGB key_color); static void display(Key key, uint8_t row, uint8_t col); static void display(Key key) { display(key, 0, 2); @@ -48,7 +48,7 @@ class AlphaSquare : public KaleidoscopePlugin { display(key, 0, col); } - static void display(uint16_t symbol, uint8_t row, uint8_t col, cRGB keyColor); + static void display(uint16_t symbol, uint8_t row, uint8_t col, cRGB key_color); static void display(uint16_t symbol, uint8_t row, uint8_t col); static void display(uint16_t symbol) { display(symbol, 0, 2); @@ -79,6 +79,7 @@ class AlphaSquare : public KaleidoscopePlugin { static cRGB color; }; -}; -extern KaleidoscopePlugins::AlphaSquare AlphaSquare; +} + +extern kaleidoscope::AlphaSquare AlphaSquare; From 3b5363fea188f65f7a7d46284d5d06369b0adc35 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 09:11:46 +0200 Subject: [PATCH 249/792] bootAnimation: Just do it A while ago, we added a bit of code to `bootAnimation()` that only did the animation on first boot - this is not a desirable thing anymore, not in `bootAnimation()` itself. These days, one would use `Kaleidoscope-EEPROM-Settings`, and decide whether to do the boot animation there. Since `bootAnimation()` is an optional thing, just do the animation whenever the function is called, and remove the obsolete EEPROM bits. Signed-off-by: Gergely Nagy --- src/BootAnimation.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/BootAnimation.cpp b/src/BootAnimation.cpp index af04676d..be4d9cd4 100644 --- a/src/BootAnimation.cpp +++ b/src/BootAnimation.cpp @@ -1,8 +1,5 @@ #include "BootAnimation.h" #include "Kaleidoscope-LEDControl.h" -#include "EEPROM.h" - -#define EEPROM_BOOT_ANIMATION_LOCATION 1 #ifdef ARDUINO_AVR_MODEL01 static void @@ -19,9 +16,6 @@ type_letter(uint8_t letter) { void bootAnimation(void) { #ifdef ARDUINO_AVR_MODEL01 - if (EEPROM.read(EEPROM_BOOT_ANIMATION_LOCATION)) - return; - LEDControl.set_all_leds_to(0, 0, 0); type_letter(LED_K); type_letter(LED_E); @@ -37,7 +31,5 @@ bootAnimation(void) { type_letter(LED_0); type_letter(LED_PERIOD); type_letter(LED_9); - - EEPROM.update(EEPROM_BOOT_ANIMATION_LOCATION, 1); #endif } From 7ddb1130b402078a28719c8066fcfd5565e3274e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 10:34:37 +0200 Subject: [PATCH 250/792] Kaleidoscope Style Guide conformance Signed-off-by: Gergely Nagy --- README.md | 27 +++++---- examples/LED-Stalker/LED-Stalker.ino | 10 ++-- src/Kaleidoscope/LED-Stalker.cpp | 88 ++++++++++++---------------- src/Kaleidoscope/LED-Stalker.h | 47 +++++++-------- 4 files changed, 78 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index aba5be07..58c2eb30 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker - [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 The `StalkerEffect` plugin provides an interesting new typing experience: the LEDs light up as you tap keys, and play one of the selected effects: a haunting @@ -21,12 +21,13 @@ To use the plugin, one needs to include the header, and select the effect. #include #include -void setup () { - Kaleidoscope.setup (); +void setup (){ + USE_PLUGINS(&StalkerEffect); - StalkerEffect.configure (STALKER (Haunt, {0xff, 0, 0})); - USE_PLUGINS (&StalkerEffect); - StalkerEffect.activate (); + Kaleidoscope.setup(); + + StalkerEffect.variant = STALKER(Haunt, (CRGB(0, 128, 0))); + StalkerEffect.activate(); } ``` @@ -40,11 +41,13 @@ recommended. The plugin provides the `StalkerEffect` object, which has the following method: -### `.configure(effect)` +### `.variant` > Set the effect to use with the plugin. See below for a list. > > It is recommended to use the `STALKER` macro to declare the effect itself. +> +> Not a method itself, but a changeable value. ### `.stepLength` @@ -57,11 +60,11 @@ method: ## Plugin helpers -### `STALKER(effect, params...)` +### `STALKER(effect, params)` -> Returns an effect, to be used by the `.configure` method of the +> Returns an effect, to be used to assign a value the `.variant` property of the > `StalkerEffect` object. Any arguments given to the macro, are also passed on -> to the effect. If the effect takes no arguments, use `NULL`. +> to the effect. If the effect takes no arguments, use an empty `params` list. ## Plugin effects diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index 80bbd351..438ebac2 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -20,7 +20,6 @@ #include #include "LED-Off.h" - const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED ( @@ -38,16 +37,15 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_NoKey - ), + Key_NoKey), }; void setup() { - Kaleidoscope.setup(); - - StalkerEffect.configure(STALKER(BlazingTrail, NULL)); USE_PLUGINS(&LEDOff, &StalkerEffect); + Kaleidoscope.setup(); + + StalkerEffect.variant = STALKER(BlazingTrail); StalkerEffect.activate(); } diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 9aa14db7..e48b572d 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -19,89 +19,79 @@ #include #include -namespace KaleidoscopePlugins { -namespace LEDEffects { -uint8_t StalkerEffect::map[ROWS][COLS]; -StalkerEffect::ColorComputer *StalkerEffect::colorComputer; -uint16_t StalkerEffect::stepLength = 50; -uint32_t StalkerEffect::stepEndTime; +namespace kaleidoscope { -StalkerEffect::StalkerEffect(void) { -} +uint8_t StalkerEffect::map_[ROWS][COLS]; +StalkerEffect::ColorComputer *StalkerEffect::variant; +uint16_t StalkerEffect::step_length = 50; +uint32_t StalkerEffect::step_end_time_; -void -StalkerEffect::configure(ColorComputer *colorComputer_) { - colorComputer = colorComputer_; +StalkerEffect::StalkerEffect(void) { } -void -StalkerEffect::begin(void) { +void StalkerEffect::begin(void) { event_handler_hook_use(eventHandlerHook); LEDMode::begin(); } -void -StalkerEffect::init(void) { - memset(map, 0, sizeof(map)); +void StalkerEffect::init(void) { + memset(map_, 0, sizeof(map_)); } -Key -StalkerEffect::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) { +Key StalkerEffect::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state) { if (row >= ROWS || col >= COLS) - return mappedKey; + return mapped_key; - if (key_is_pressed(keyState)) { - map[row][col] = 0xff; + if (key_is_pressed(key_state)) { + map_[row][col] = 0xff; } - return mappedKey; + return mapped_key; } -void -StalkerEffect::update(void) { - if (!colorComputer) +void StalkerEffect::update(void) { + if (!variant) return; - bool timeOut = millis() >= stepEndTime; + bool time_out = millis() >= step_end_time_; for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { - uint8_t step = map[r][c]; + uint8_t step = map_[r][c]; if (step) { - LEDControl.led_set_crgb_at(r, c, colorComputer->compute(&step)); + LEDControl.led_set_crgb_at(r, c, variant->compute(&step)); } - bool wasZero = (map[r][c] == 0); + bool was_zero = (map_[r][c] == 0); - if (timeOut) { - map[r][c] = step; + if (time_out) { + map_[r][c] = step; } - if (!wasZero && !map[r][c]) + if (!was_zero && !map_[r][c]) LEDControl.led_set_crgb_at(r, c, (cRGB) { 0, 0, 0 }); } } - if (timeOut) - stepEndTime = millis() + stepLength; + if (time_out) + step_end_time_ = millis() + step_length; } -namespace Stalker { +namespace stalker { -cRGB Haunt::highlightColor; +cRGB Haunt::highlight_color_; // Haunt -Haunt::Haunt(const cRGB highlightColor_) { - highlightColor = highlightColor_; +Haunt::Haunt(const cRGB highlight_color) { + highlight_color_ = highlight_color; } -cRGB -Haunt::compute(uint8_t *step) { - cRGB color = CRGB((uint8_t)min(*step * highlightColor.r / 255, 255), - (uint8_t)min(*step * highlightColor.g / 255, 255), - (uint8_t)min(*step * highlightColor.b / 255, 255)); +cRGB Haunt::compute(uint8_t *step) { + cRGB color = CRGB((uint8_t)min(*step * highlight_color_.r / 255, 255), + (uint8_t)min(*step * highlight_color_.g / 255, 255), + (uint8_t)min(*step * highlight_color_.b / 255, 255)); if (*step >= 0xf0) *step -= 1; @@ -116,11 +106,10 @@ Haunt::compute(uint8_t *step) { } // BlazingTrail -BlazingTrail::BlazingTrail(...) { +BlazingTrail::BlazingTrail(void) { } -cRGB -BlazingTrail::compute(uint8_t *step) { +cRGB BlazingTrail::compute(uint8_t *step) { cRGB color; if (*step >= 0xff - 30) { @@ -144,9 +133,8 @@ BlazingTrail::compute(uint8_t *step) { return color; } -}; +} -}; -}; +} -KaleidoscopePlugins::LEDEffects::StalkerEffect StalkerEffect; +kaleidoscope::StalkerEffect StalkerEffect; diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 6af2b1b8..f4764b11 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -16,13 +16,14 @@ * along with this program. If not, see . */ +#pragma once + #include #include -#define STALKER(n, ...) (({static KaleidoscopePlugins::LEDEffects::Stalker::n _effect (__VA_ARGS__); &_effect;})) +#define STALKER(v, ...) ({static kaleidoscope::stalker::v _effect __VA_ARGS__; &_effect;}) -namespace KaleidoscopePlugins { -namespace LEDEffects { +namespace kaleidoscope { class StalkerEffect : public LEDMode { public: class ColorComputer { @@ -33,45 +34,39 @@ class StalkerEffect : public LEDMode { StalkerEffect(void); void begin(void) final; - virtual void init(void) final; - virtual void update(void) final; + void init(void) final; + void update(void) final; - static void configure(ColorComputer *colorComputer); - static uint16_t stepLength; + static ColorComputer *variant; + static uint16_t step_length; private: - static uint32_t stepEndTime; - static ColorComputer *colorComputer; - static uint8_t map[ROWS][COLS]; + static uint32_t step_end_time_; + static uint8_t map_[ROWS][COLS]; - static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); + static Key eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state); }; -namespace Stalker { +namespace stalker { class Haunt : public StalkerEffect::ColorComputer { public: - Haunt(const cRGB highlightColor); - Haunt(void) : Haunt( { - 0x40, 0x80, 0x80 - }) {}; - Haunt(void *) : Haunt() {}; + explicit Haunt(const cRGB highlight_color); + Haunt(void) : Haunt(CRGB(0x40, 0x80, 0x80)) {} - virtual cRGB compute(uint8_t *step) final; + cRGB compute(uint8_t *step) final; private: - static cRGB highlightColor; + static cRGB highlight_color_; }; class BlazingTrail : public StalkerEffect::ColorComputer { public: - BlazingTrail(...); - - virtual cRGB compute(uint8_t *step) final; -}; + BlazingTrail(void); + cRGB compute(uint8_t *step) final; }; -}; -}; +} +} -extern KaleidoscopePlugins::LEDEffects::StalkerEffect StalkerEffect; +extern kaleidoscope::StalkerEffect StalkerEffect; From e8f3495f7c40351b7e59a96256b2ec496de0e9e1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 10:56:08 +0200 Subject: [PATCH 251/792] Kaleidoscope Style Guide conformance Signed-off-by: Gergely Nagy --- README.md | 53 +++++++++++++++++++----------- examples/MagicCombo/MagicCombo.ino | 20 +++++------ src/Kaleidoscope/MagicCombo.cpp | 47 +++++++++++--------------- src/Kaleidoscope/MagicCombo.h | 23 ++++++------- 4 files changed, 74 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index d5b4406c..f8ec6b8e 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo - [st:stable]: https://img.shields.io/badge/stable-✔-black.png?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 The `MagicCombo` extension provides a way to perform custom actions when a particular set of keys are held down together. The functionality assigned to @@ -18,54 +18,67 @@ This can be used to tie complex actions to key chords. ## Using the extension -To use the extension, we must include the header, create a dictionary, and -configure the plugin to use it: +To use the extension, we must include the header, create an array of combos we +want to work with, let the plugin know we want to work with those, and then use +a special function to handle the combos: ```c++ #include #include -static const KaleidoscopePlugins::MagicCombo::dictionary_t dictionary[] PROGMEM = { +static const KaleidoscopePlugins::MagicCombo::combo_t magic_combos[] PROGMEM = { {R1C3 | R2C1 | R2C4 | R2C7, // left hand, R0C11 | R1C12 | R2C14 //right hand }, {0, 0} }; -void setup (void) { - MagicCombo.configure (dictionary); +void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand) { + switch (combo_index) { + case 0: + Serial.println("It's a kind of magic!"); + break; + } +} + +void setup() { + Serial.begin(9600); + + USE_PLUGINS(&MagicCombo); - Kaleidoscope.setup (KEYMAP_SIZE); - Kaleidoscope.use (&MagicCombo, NULL); + Kaleidoscope.setup(); + + MagicCombo.magic_combos = magic_combos; } ``` -The dictionary **must** reside in `PROGMEM`, and is a list of tuples. Each +The combo list **must** reside in `PROGMEM`, and is a list of tuples. Each element in the array has two fields: the left hand state, and the right hand state upon which to trigger the custom action. Both of these are bit fields, each bit set tells the extension that the key with that index must be held for the action to trigger. It is recommended to use the `RxCy` macros of the core `KaleidoscopeFirmware`, and *or* them together to form a bitfield. -The dictionary **must** end with an element containing zero values for both the +The combo list **must** end with an element containing zero values for both the left and the right halves. ## Extension methods -The extension provides a `MagicCombo` singleton object, with the following method: +The extension provides a `MagicCombo` singleton object, with the following +methods and properties: -### `.configure(dictionary)` +### `.magic_combos` -> Configures the extension to use the supplied dictionary. +> Setting this property lets the plugin know which combinations of key presses +> we are interested in. If any of these are found active, the +> `magicComboActions()` function will be called. -### `.minInterval` +### `.min_interval` > Restrict the magic action to fire at most once every `minInterval` > milliseconds. > > Defaults to 500. -> -> Not strictly a method, it is a variable one can assign a new value to. ## Overrideable methods @@ -73,12 +86,12 @@ Whenever an combination is found to be held, the extension will trigger an action, in each scan cycle until the keys remain held. This is done by calling the overrideable `magicComboActions` function: -### `magicComboActions(comboIndex, leftHand, rightHand)` +### `magicComboActions(combo_index, left_hand, right_hand)` > Called whenever a combination is found to be held. The function by default > does nothing, and it is recommended to override it from within the Sketch. > -> The first argument will be the index in the dictionary, the other two are the +> The first argument will be the index in the combo list, the other two are the > key states on the left and right halves, respectively. > > Plugins that build upon this extensions *should not* override this function, diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index eb49e9d3..ac581868 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -19,18 +19,18 @@ #include #include -void magicComboActions(uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { - switch (comboIndex) { +void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand) { + switch (combo_index) { case 0: Serial.println("It's a kind of magic!"); break; } } -static const KaleidoscopePlugins::MagicCombo::dictionary_t dictionary[] PROGMEM = { +static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { { - R1C3 | R2C1 | R2C4 | R2C7, // left hand, - R0C11 | R1C12 | R2C14 //right hand + R1C3 | R2C1 | R2C4 | R2C7, // left hand, + R0C11 | R1C12 | R2C14 // right hand }, {0, 0} }; @@ -53,17 +53,17 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - Key_NoKey - ), + Key_NoKey), }; void setup() { Serial.begin(9600); - MagicCombo.configure(dictionary); + USE_PLUGINS(&MagicCombo); - Kaleidoscope.setup(KEYMAP_SIZE); - Kaleidoscope.use(&MagicCombo, NULL); + Kaleidoscope.setup(); + + MagicCombo.magic_combos = magic_combos; } void loop() { diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index 5f529189..114e7026 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -28,44 +28,37 @@ #define RIGHTHANDSTATE KeyboardHardware.scanner.rightHandState #endif -namespace KaleidoscopePlugins { +namespace kaleidoscope { -const MagicCombo::dictionary_t *MagicCombo::dictionary; -uint16_t MagicCombo::minInterval = 500; -uint32_t MagicCombo::endTime; +const MagicCombo::combo_t *MagicCombo::magic_combos; +uint16_t MagicCombo::min_interval = 500; +uint32_t MagicCombo::end_time_; MagicCombo::MagicCombo(void) { } -void -MagicCombo::begin(void) { - loop_hook_use(this->loopHook); +void MagicCombo::begin(void) { + loop_hook_use(loopHook); } -void -MagicCombo::configure(const MagicCombo::dictionary_t dictionary_[]) { - dictionary = (dictionary_t *)dictionary_; -} - -void -MagicCombo::loopHook(bool postClear) { - if (!dictionary || postClear) +void MagicCombo::loopHook(bool is_post_clear) { + if (!magic_combos || is_post_clear) return; for (byte i = 0;; i++) { - dictionary_t combo; + combo_t combo; - combo.leftHand = pgm_read_dword(&(dictionary[i].leftHand)); - combo.rightHand = pgm_read_dword(&(dictionary[i].rightHand)); + combo.left_hand = pgm_read_dword(&(magic_combos[i].left_hand)); + combo.right_hand = pgm_read_dword(&(magic_combos[i].right_hand)); - if (combo.leftHand == 0 && combo.rightHand == 0) + if (combo.left_hand == 0 && combo.right_hand == 0) break; - if (LEFTHANDSTATE.all == combo.leftHand && - RIGHTHANDSTATE.all == combo.rightHand) { - if (millis() >= endTime) { - magicComboActions(i, combo.leftHand, combo.rightHand); - endTime = millis() + minInterval; + if (LEFTHANDSTATE.all == combo.left_hand && + RIGHTHANDSTATE.all == combo.right_hand) { + if (millis() >= end_time_) { + magicComboActions(i, combo.left_hand, combo.right_hand); + end_time_ = millis() + min_interval; } break; } @@ -74,9 +67,7 @@ MagicCombo::loopHook(bool postClear) { }; -__attribute__((weak)) -void -magicComboActions(uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand) { +__attribute__((weak)) void magicComboActions(uint8_t comboIndex, uint32_t left_hand, uint32_t right_hand) { } -KaleidoscopePlugins::MagicCombo MagicCombo; +kaleidoscope::MagicCombo MagicCombo; diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 9b44c8e5..2633ba91 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -20,28 +20,29 @@ #include -namespace KaleidoscopePlugins { +namespace kaleidoscope { + class MagicCombo : public KaleidoscopePlugin { public: typedef struct { - uint32_t leftHand, rightHand; - } dictionary_t; + uint32_t left_hand, right_hand; + } combo_t; MagicCombo(void); void begin(void) final; - static void configure(const dictionary_t dictionary[]); - static uint16_t minInterval; + static const combo_t *magic_combos; + static uint16_t min_interval; private: - static const dictionary_t *dictionary; - static uint32_t endTime; + static uint32_t end_time_; - static void loopHook(bool postClear); -}; + static void loopHook(bool is_post_clear); }; -void magicComboActions(uint8_t comboIndex, uint32_t leftHand, uint32_t rightHand); +} + +void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand); -extern KaleidoscopePlugins::MagicCombo MagicCombo; +extern kaleidoscope::MagicCombo MagicCombo; From ea3ec5b19ae48f067179318d336ad97b37f424d2 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 13:14:37 +0200 Subject: [PATCH 252/792] Make the linter happy Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Breathe.cpp | 3 +-- src/Kaleidoscope-LEDEffect-Breathe.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp index feba2ca9..5c2397f9 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -3,8 +3,7 @@ LEDBreatheEffect_::LEDBreatheEffect_(void) { } -void -LEDBreatheEffect_::update(void) { +void LEDBreatheEffect_::update(void) { cRGB color = breath_compute(); LEDControl.set_all_leds_to(color); } diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index 12af4f1f..c69e3168 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -7,7 +7,7 @@ class LEDBreatheEffect_ : public LEDMode { public: LEDBreatheEffect_(void); - virtual void update(void) final; + void update(void) final; }; extern LEDBreatheEffect_ LEDBreatheEffect; From 2c569de4788a4e3e9318a1a5efebb7223685116e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 13:15:34 +0200 Subject: [PATCH 253/792] Make the linter happy Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Chase.cpp | 3 +-- src/Kaleidoscope-LEDEffect-Chase.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp index 76455f64..8fb9b97d 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -3,8 +3,7 @@ LEDChaseEffect_::LEDChaseEffect_(void) { } -void -LEDChaseEffect_::update(void) { +void LEDChaseEffect_::update(void) { if (current_chase_counter++ < chase_threshold) { return; } diff --git a/src/Kaleidoscope-LEDEffect-Chase.h b/src/Kaleidoscope-LEDEffect-Chase.h index 856644bd..cfea5fab 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.h +++ b/src/Kaleidoscope-LEDEffect-Chase.h @@ -7,7 +7,7 @@ class LEDChaseEffect_ : public LEDMode { public: LEDChaseEffect_(void); - virtual void update(void) final; + void update(void) final; private: uint8_t pos = 0; From 07d919069de2541c3524e39f1d4a903dd7601e30 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 13:16:15 +0200 Subject: [PATCH 254/792] Make the linter happy Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-SolidColor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.h b/src/Kaleidoscope-LEDEffect-SolidColor.h index 1c341de9..88b0706c 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.h +++ b/src/Kaleidoscope-LEDEffect-SolidColor.h @@ -6,7 +6,7 @@ class LEDSolidColor : public LEDMode { public: LEDSolidColor(uint8_t r, uint8_t g, uint8_t b); - virtual void init(void) final; + void init(void) final; private: uint8_t r, g, b; From c564d298c75c2275cd37b356f68fe600a31e0cde Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 13:18:13 +0200 Subject: [PATCH 255/792] Make the linter happy Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 6 ++---- src/Kaleidoscope-LEDEffect-Rainbow.h | 12 ++++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index 58b85125..3ea8edc0 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -3,8 +3,7 @@ LEDRainbowEffect_::LEDRainbowEffect_(void) { } -void -LEDRainbowEffect_::update(void) { +void LEDRainbowEffect_::update(void) { if (rainbow_current_ticks++ < rainbow_ticks) { return; } else { @@ -27,8 +26,7 @@ LEDRainbowEffect_ LEDRainbowEffect; LEDRainbowWaveEffect_::LEDRainbowWaveEffect_(void) { } -void -LEDRainbowWaveEffect_::update(void) { +void LEDRainbowWaveEffect_::update(void) { if (rainbow_current_ticks++ < rainbow_wave_ticks) { return; } else { diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 113b10d3..8f98bcee 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -7,14 +7,14 @@ class LEDRainbowEffect_ : public LEDMode { public: LEDRainbowEffect_(void); - virtual void update(void) final; + void update(void) final; private: uint16_t rainbow_hue = 0; //stores 0 to 614 static const uint8_t rainbow_steps = 1; //number of hues we skip in a 360 range per update - long rainbow_current_ticks = 0; - static const long rainbow_ticks = 10; //delays between update + uint16_t rainbow_current_ticks = 0; + static const uint16_t rainbow_ticks = 10; //delays between update static const byte rainbow_saturation = 255; static const byte rainbow_value = 50; @@ -27,14 +27,14 @@ class LEDRainbowWaveEffect_ : public LEDMode { public: LEDRainbowWaveEffect_(void); - virtual void update(void) final; + void update(void) final; private: uint16_t rainbow_hue = 0; //stores 0 to 614 static const uint8_t rainbow_wave_steps = 1; //number of hues we skip in a 360 range per update - long rainbow_current_ticks = 0; - static const long rainbow_wave_ticks = 10; //delays between update + uint16_t rainbow_current_ticks = 0; + static const uint16_t rainbow_wave_ticks = 10; //delays between update static const byte rainbow_saturation = 255; static const byte rainbow_value = 50; From 82a7ceb75acfeadd89540b3874d52fc8a576c5ff Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 14:15:53 +0200 Subject: [PATCH 256/792] Augment a TODO item to make the linter happier Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 8c4af4f6..911e7d79 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -73,7 +73,8 @@ void Model01::led_set_crgb_at(uint8_t i, cRGB crgb) { rightHand.ledData.leds[i - 32] = crgb; } else { - // TODO how do we want to handle debugging assertions about crazy user + // TODO(anyone): + // how do we want to handle debugging assertions about crazy user // code that would overwrite other memory? } } From c3eb1af9dad369cac092220c9366f16289c7b9ee Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 14:20:27 +0200 Subject: [PATCH 257/792] reboot_bootloader: Use reinterpret_cast<> instead of C-style casting Makes the linter happy, and produces exactly the same code. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 911e7d79..c51b9661 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -190,7 +190,7 @@ void Model01::reboot_bootloader() { // Caterina.c uint16_t bootKey = 0x7777; - uint16_t *const bootKeyPtr = (uint16_t *)0x0800; + uint16_t *const bootKeyPtr = reinterpret_cast(0x0800); // Stash the magic key *bootKeyPtr = bootKey; From a6a2288c207cd34e2c3a8ceda613db081e44e23b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 16:01:11 +0200 Subject: [PATCH 258/792] README.md: Properties are not methods Signed-off-by: Gergely Nagy --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dd0c5f70..e5093f0a 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,8 @@ void setup() { ## Plugin methods -The plugin provides the `AlphaSquare` object, which has the following methods: +The plugin provides the `AlphaSquare` object, which has the following methods +and properties: ### `.display(key)` ### `.display(key, row, col)` @@ -66,8 +67,6 @@ The plugin provides the `AlphaSquare` object, which has the following methods: > The color to use to draw the pixels. > -> Not a method itself, but a changeable value. -> > Defaults to { 0x80, 0x80, 0x80 }. ## Plugin helpers From ac1b302ea0a68554785f76e7594fc15baf42f3a8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 5 Jun 2017 16:04:47 +0200 Subject: [PATCH 259/792] README.md: Properties are not methods Signed-off-by: Gergely Nagy --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 58c2eb30..f000271a 100644 --- a/README.md +++ b/README.md @@ -39,23 +39,19 @@ recommended. ## Plugin methods The plugin provides the `StalkerEffect` object, which has the following -method: +properties: ### `.variant` > Set the effect to use with the plugin. See below for a list. > > It is recommended to use the `STALKER` macro to declare the effect itself. -> -> Not a method itself, but a changeable value. ### `.stepLength` > The length - in milliseconds - of each step of the animation. An animation > lasts 256 steps. > -> Not a method itself, but a changeable value. -> > Defaults to 50. ## Plugin helpers From 4c2b9e8e55ea28ce340b55f74c2a50694ea93791 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 8 Jun 2017 11:24:59 +0200 Subject: [PATCH 260/792] Add a way to type ASCII strings, as if pressing keys Adds a `Macros.type()` method, which expects a string in PROGMEM, iterates through it, and simulates key presses. It converts ASCII codes to Key codes during the process. Assumes an US QWERTY layout on the host, supports all printable chars, and a few control codes too. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 97 +++++++++++++++++++++++++++++++++++++ src/Kaleidoscope-Macros.h | 1 + 2 files changed, 98 insertions(+) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 6680c30f..7688b1ba 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -71,6 +71,103 @@ void Macros_::play(const macro_t *macro_p) { delay(interval); } } +static const Key ascii_to_key_map[] PROGMEM = { + // 0x21 - 0x30 + LSHIFT(Key_1), + LSHIFT(Key_Quote), + LSHIFT(Key_3), + LSHIFT(Key_4), + LSHIFT(Key_5), + LSHIFT(Key_7), + Key_Quote, + LSHIFT(Key_9), + LSHIFT(Key_0), + LSHIFT(Key_8), + LSHIFT(Key_Equals), + Key_Comma, + Key_Minus, + Key_Period, + Key_Slash, + Key_0, + + // 0x3a ... 0x40 + LSHIFT(Key_Semicolon), + Key_Semicolon, + LSHIFT(Key_Comma), + Key_Equals, + LSHIFT(Key_Period), + LSHIFT(Key_Slash), + LSHIFT(Key_2), + + // 0x5b ... 0x5f + Key_LeftBracket, + Key_Backslash, + Key_RightBracket, + LSHIFT(Key_6), + LSHIFT(Key_Minus), + Key_Backtick, + + // 0x7b ... 0x7e + LSHIFT(Key_LeftBracket), + LSHIFT(Key_Backslash), + LSHIFT(Key_RightBracket), + LSHIFT(Key_Backtick), +}; + +void Macros_::type(const char *string) { + while (true) { + uint8_t ascii_code = pgm_read_byte(string++); + if (!ascii_code) + break; + + Key key = Key_NoKey; + + switch (ascii_code) { + case 0x08 ... 0x09: + key.keyCode = Key_Backspace.keyCode + ascii_code - 0x08; + break; + case 0x0A: + key.keyCode = Key_Enter.keyCode; + break; + case 0x1B: + key.keyCode = Key_Escape.keyCode; + break; + case 0x20: + key.keyCode = Key_Spacebar.keyCode; + break; + case 0x21 ... 0x30: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x21]); + break; + case 0x31 ... 0x39: + key.keyCode = Key_1.keyCode + ascii_code - 0x31; + break; + case 0x3A ... 0x40: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x3A + 16]); + break; + case 0x41 ... 0x5A: + key.flags = SHIFT_HELD; + key.keyCode = Key_A.keyCode + ascii_code - 0x41; + break; + case 0x5B ... 0x5F: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x5B + 23]); + break; + case 0x61 ... 0x7A: + key.keyCode = Key_A.keyCode + ascii_code - 0x61; + break; + case 0x7B ... 0x7E: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x7B + 29]); + break; + } + + if (key.raw == Key_NoKey.raw) + continue; + + handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); + Keyboard.sendReport(); + handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); + Keyboard.sendReport(); + } +} static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index eddaef23..92b14fd9 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -14,6 +14,7 @@ class Macros_ : public KaleidoscopePlugin { void begin(void) final; void play(const macro_t *macro_p); + void type(const char *string); static byte row, col; }; From bddcc4912b9fb0e8ee1b30d7c8f043335aad42db Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 9 Jun 2017 16:33:55 -0700 Subject: [PATCH 261/792] extract out the key combo --- src/Kaleidoscope-Model01-TestMode.cpp | 6 ++---- src/Kaleidoscope-Model01-TestMode.h | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 61c18580..80f72020 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -6,8 +6,6 @@ cRGB red; cRGB blue; cRGB green; -#define LED_TEST_DELAY 2000 - TestMode_::TestMode_(void) { } @@ -23,7 +21,7 @@ void TestMode_::begin(void) { void TestMode_::loopHook(bool postClear) { if (postClear) return; - if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6) + if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO // && KeyboardHardware.rightHandState.all == combo.rightHand ) { run_tests(); @@ -81,7 +79,7 @@ void TestMode_::test_matrix() { LEDControl.set_all_leds_to(50, 0, 0); while (1) { KeyboardHardware.read_matrix(); - if (KeyboardHardware.leftHandState.all == (R0C0 | R0C6 | R3C6)) { + if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { break; } for (byte row = 0; row < 4; row++) { diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index eac6cbcb..f9a0fb02 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -3,6 +3,8 @@ #include #include "Kaleidoscope.h" +#define TEST_MODE_KEY_COMBO (R0C0 | R0C6 | R3C6) + class TestMode_ : public KaleidoscopePlugin { public: TestMode_(void); From 891bab11ecf7200e2b1dfc206930db521ace94bc Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 9 Jun 2017 18:42:21 -0700 Subject: [PATCH 262/792] Extract the typeface out into its own file --- src/Kaleidoscope/LED-AlphaSquare-4x4.h | 167 ++++++++++++++++++++++ src/Kaleidoscope/LED-AlphaSquare.cpp | 184 ++++++------------------- 2 files changed, 206 insertions(+), 145 deletions(-) create mode 100644 src/Kaleidoscope/LED-AlphaSquare-4x4.h diff --git a/src/Kaleidoscope/LED-AlphaSquare-4x4.h b/src/Kaleidoscope/LED-AlphaSquare-4x4.h new file mode 100644 index 00000000..5b2f189f --- /dev/null +++ b/src/Kaleidoscope/LED-AlphaSquare-4x4.h @@ -0,0 +1,167 @@ + * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#ifndef KALEIDOSCOPE_LED_FONT +#define KALEIDOSCOPE_LED_FONT + +#define ALPHASQUARE_SYMBOL_A SYM4x4(1, 1, 1, 1, \ + 1, 0, 0, 1, \ + 1, 1, 1, 1, \ + 1, 0, 0, 1) +#define ALPHASQUARE_SYMBOL_B SYM4x4(1, 1, 1, 1, \ + 1, 0, 1, 1, \ + 1, 1, 0, 1, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_C SYM4x4(1, 1, 1, 1, \ + 1, 0, 0, 0, \ + 1, 0, 0, 0, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_D SYM4x4(1, 1, 1, 0, \ + 1, 0, 0, 1, \ + 1, 0, 0, 1, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_E SYM4x4(1, 1, 1, 1, \ + 1, 1, 0, 0, \ + 1, 0, 0, 0, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_F SYM4x4(1, 1, 1, 1, \ + 1, 0, 0, 0, \ + 1, 1, 1, 0, \ + 1, 0, 0, 0) +#define ALPHASQUARE_SYMBOL_G SYM4x4(1, 1, 1, 0, \ + 1, 0, 0, 0, \ + 1, 0, 0, 1, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_H SYM4x4(1, 0, 0, 1, \ + 1, 1, 1, 1, \ + 1, 0, 0, 1, \ + 1, 0, 0, 1) +#define ALPHASQUARE_SYMBOL_I SYM4x4(1, 1, 1, 1, \ + 0, 1, 1, 0, \ + 0, 1, 1, 0, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_J SYM4x4(1, 1, 1, 1, \ + 0, 0, 0, 1, \ + 1, 0, 0, 1, \ + 0, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_K SYM4x4(1, 0, 0, 1, \ + 1, 1, 0, 0, \ + 1, 1, 0, 0, \ + 1, 0, 1, 1) +#define ALPHASQUARE_SYMBOL_L SYM4x4(1, 0, 0, 0, \ + 1, 0, 0, 0, \ + 1, 0, 0, 0, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_M SYM4x4(1, 0, 1, 1, \ + 1, 1, 1, 1, \ + 1, 1, 0, 1, \ + 1, 0, 0, 1) +#define ALPHASQUARE_SYMBOL_N SYM4x4(1, 0, 0, 1, \ + 1, 1, 0, 1, \ + 1, 0, 1, 1, \ + 1, 0, 0, 1) +#define ALPHASQUARE_SYMBOL_O SYM4x4(1, 1, 1, 1, \ + 1, 0, 0, 1, \ + 1, 0, 0, 1, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_P SYM4x4(1, 1, 1, 1, \ + 1, 0, 0, 1, \ + 1, 1, 1, 1, \ + 1, 0, 0, 0) +#define ALPHASQUARE_SYMBOL_Q SYM4x4(1, 1, 1, 1, \ + 1, 0, 0, 1, \ + 1, 0, 1, 1, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_R SYM4x4(1, 1, 1, 1, \ + 1, 0, 0, 1, \ + 1, 1, 1, 0, \ + 1, 0, 1, 1) +#define ALPHASQUARE_SYMBOL_S SYM4x4(1, 1, 1, 1, \ + 1, 1, 0, 0, \ + 0, 0, 1, 1, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_T SYM4x4(1, 1, 1, 1, \ + 0, 1, 1, 0, \ + 0, 1, 1, 0, \ + 0, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_U SYM4x4(1, 0, 0, 1, \ + 1, 0, 0, 1, \ + 1, 0, 0, 1, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_V SYM4x4(1, 0, 0, 1, \ + 1, 0, 0, 1, \ + 1, 0, 0, 1, \ + 0, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_W SYM4x4(1, 0, 0, 1, \ + 1, 0, 1, 1, \ + 1, 1, 1, 1, \ + 1, 0, 1, 1) +#define ALPHASQUARE_SYMBOL_X SYM4x4(1, 0, 0, 1, \ + 0, 1, 1, 0, \ + 0, 1, 1, 0, \ + 1, 0, 0, 1) +#define ALPHASQUARE_SYMBOL_Y SYM4x4(1, 0, 0, 1, \ + 1, 1, 1, 1, \ + 0, 1, 1, 0, \ + 0, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_Z SYM4x4(1, 1, 1, 1, \ + 0, 0, 1, 1, \ + 1, 1, 0, 0, \ + 1, 1, 1, 1) + // --------------------- +#define ALPHASQUARE_SYMBOL_1 SYM4x4(0, 1, 1, 0, \ + 1, 0, 1, 0, \ + 0, 0, 1, 0, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_2 SYM4x4(0, 1, 1, 0, \ + 1, 0, 0, 1, \ + 0, 0, 1, 0, \ + 1, 1, 0, 1) +#define ALPHASQUARE_SYMBOL_3 SYM4x4(1, 1, 1, 1, \ + 0, 0, 1, 1, \ + 0, 0, 0, 1, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_4 SYM4x4(1, 0, 0, 1, \ + 1, 1, 1, 1, \ + 0, 0, 0, 1, \ + 0, 0, 0, 1) +#define ALPHASQUARE_SYMBOL_5 SYM4x4(1, 1, 1, 1, \ + 1, 0, 0, 0, \ + 0, 1, 1, 1, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_6 SYM4x4(0, 1, 1, 0, \ + 1, 0, 0, 0, \ + 1, 1, 1, 1, \ + 1, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_7 SYM4x4(1, 1, 1, 1, \ + 0, 0, 0, 1, \ + 0, 0, 1, 0, \ + 0, 1, 0, 0) +#define ALPHASQUARE_SYMBOL_8 SYM4x4(1, 1, 1, 0, \ + 1, 0, 1, 1, \ + 1, 1, 0, 1, \ + 0, 1, 1, 1) +#define ALPHASQUARE_SYMBOL_9 SYM4x4(1, 1, 1, 1, \ + 1, 0, 0, 1, \ + 1, 1, 1, 1, \ + 0, 0, 0, 1) +#define ALPHASQUARE_SYMBOL_0 SYM4x4(0, 1, 1, 0, \ + 1, 0, 0, 1, \ + 1, 0, 0, 1, \ + 0, 1, 1, 0) + +#endif diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 845c3183..f3f1cc3a 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -17,157 +17,51 @@ */ #include +#include namespace kaleidoscope { static const uint16_t alphabet[] PROGMEM = { - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 1), // A - SYM4x4(1, 1, 1, 1, - 1, 0, 1, 1, - 1, 1, 0, 1, - 1, 1, 1, 1), // B - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // C - SYM4x4(1, 1, 1, 0, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 0), // D - SYM4x4(1, 1, 1, 1, - 1, 1, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // E - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 1, 1, 1, 0, - 1, 0, 0, 0), // F - SYM4x4(1, 1, 1, 0, - 1, 0, 0, 0, - 1, 0, 0, 1, - 1, 1, 1, 1), // G - SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 0, 1), // H - SYM4x4(1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 1, 1, 1, 1), // I - SYM4x4(1, 1, 1, 1, - 0, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // J - SYM4x4(1, 0, 0, 1, - 1, 1, 0, 0, - 1, 1, 0, 0, - 1, 0, 1, 1), // K - SYM4x4(1, 0, 0, 0, - 1, 0, 0, 0, - 1, 0, 0, 0, - 1, 1, 1, 1), // L - SYM4x4(1, 0, 1, 1, - 1, 1, 1, 1, - 1, 1, 0, 1, - 1, 0, 0, 1), // M - SYM4x4(1, 0, 0, 1, - 1, 1, 0, 1, - 1, 0, 1, 1, - 1, 0, 0, 1), // N - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 1), // O - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 1, 0, 0, 0), // P - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 0, 1, 1, - 1, 1, 1, 1), // Q - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 0, - 1, 0, 1, 1), // R - SYM4x4(1, 1, 1, 1, - 1, 1, 0, 0, - 0, 0, 1, 1, - 1, 1, 1, 1), // S - SYM4x4(1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 0, 1, 1, 0), // T - SYM4x4(1, 0, 0, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 1, 1, 1, 1), // U - SYM4x4(1, 0, 0, 1, - 1, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // V - SYM4x4(1, 0, 0, 1, - 1, 0, 1, 1, - 1, 1, 1, 1, - 1, 0, 1, 1), // W - SYM4x4(1, 0, 0, 1, - 0, 1, 1, 0, - 0, 1, 1, 0, - 1, 0, 0, 1), // X - SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 0, 1, 1, 0, - 0, 1, 1, 0), // Y - SYM4x4(1, 1, 1, 1, - 0, 0, 1, 1, - 1, 1, 0, 0, - 1, 1, 1, 1), // Z - // --------------------- - SYM4x4(0, 1, 1, 0, - 1, 0, 1, 0, - 0, 0, 1, 0, - 1, 1, 1, 1), // 1 - SYM4x4(0, 1, 1, 0, - 1, 0, 0, 1, - 0, 0, 1, 0, - 1, 1, 0, 1), // 2 - SYM4x4(1, 1, 1, 1, - 0, 0, 1, 1, - 0, 0, 0, 1, - 1, 1, 1, 1), // 3 - SYM4x4(1, 0, 0, 1, - 1, 1, 1, 1, - 0, 0, 0, 1, - 0, 0, 0, 1), // 4 - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 0, - 0, 1, 1, 1, - 1, 1, 1, 1), // 5 - SYM4x4(0, 1, 1, 0, - 1, 0, 0, 0, - 1, 1, 1, 1, - 1, 1, 1, 1), // 6 - SYM4x4(1, 1, 1, 1, - 0, 0, 0, 1, - 0, 0, 1, 0, - 0, 1, 0, 0), // 7 - SYM4x4(1, 1, 1, 0, - 1, 0, 1, 1, - 1, 1, 0, 1, - 0, 1, 1, 1), // 8 - SYM4x4(1, 1, 1, 1, - 1, 0, 0, 1, - 1, 1, 1, 1, - 0, 0, 0, 1), // 9 - SYM4x4(0, 1, 1, 0, - 1, 0, 0, 1, - 1, 0, 0, 1, - 0, 1, 1, 0), // 0 + ALPHASQUARE_SYMBOL_A, + ALPHASQUARE_SYMBOL_B, + ALPHASQUARE_SYMBOL_C, + ALPHASQUARE_SYMBOL_D, + ALPHASQUARE_SYMBOL_E, + ALPHASQUARE_SYMBOL_F, + ALPHASQUARE_SYMBOL_G, + ALPHASQUARE_SYMBOL_H, + ALPHASQUARE_SYMBOL_I, + ALPHASQUARE_SYMBOL_J, + ALPHASQUARE_SYMBOL_K, + ALPHASQUARE_SYMBOL_L, + ALPHASQUARE_SYMBOL_M, + ALPHASQUARE_SYMBOL_N, + ALPHASQUARE_SYMBOL_O, + ALPHASQUARE_SYMBOL_P, + ALPHASQUARE_SYMBOL_Q, + ALPHASQUARE_SYMBOL_R, + ALPHASQUARE_SYMBOL_S, + ALPHASQUARE_SYMBOL_T, + ALPHASQUARE_SYMBOL_U, + ALPHASQUARE_SYMBOL_V, + ALPHASQUARE_SYMBOL_W, + ALPHASQUARE_SYMBOL_X, + ALPHASQUARE_SYMBOL_Y, + ALPHASQUARE_SYMBOL_Z, + ALPHASQUARE_SYMBOL_0, + ALPHASQUARE_SYMBOL_1, + ALPHASQUARE_SYMBOL_2, + ALPHASQUARE_SYMBOL_3, + ALPHASQUARE_SYMBOL_4, + ALPHASQUARE_SYMBOL_5, + ALPHASQUARE_SYMBOL_6, + ALPHASQUARE_SYMBOL_7, + ALPHASQUARE_SYMBOL_8, + ALPHASQUARE_SYMBOL_9, + ALPHASQUARE_SYMBOL_0 }; + cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; AlphaSquare::AlphaSquare(void) { From 23a890dd7fea01211bc8bc6e6515dbe27ce3ffee Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 9 Jun 2017 19:06:49 -0700 Subject: [PATCH 263/792] Add a first pass at a 3x4 font. --- src/Kaleidoscope/LED-AlphaSquare-3x4.h | 167 +++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 src/Kaleidoscope/LED-AlphaSquare-3x4.h diff --git a/src/Kaleidoscope/LED-AlphaSquare-3x4.h b/src/Kaleidoscope/LED-AlphaSquare-3x4.h new file mode 100644 index 00000000..4fc19aa5 --- /dev/null +++ b/src/Kaleidoscope/LED-AlphaSquare-3x4.h @@ -0,0 +1,167 @@ + * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#ifndef KALEIDOSCOPE_LED_FONT +#define KALEIDOSCOPE_LED_FONT + +#define ALPHASQUARE_SYMBOL_A SYM4x4(0, 1, 0, 0, \ + 1, 0, 1, 0, \ + 1, 1, 1, 0, \ + 1, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_B SYM4x4(1, 1, 0, 0, \ + 1, 1, 1, 0, \ + 1, 0, 1, 0, \ + 1, 1, 0, 0) +#define ALPHASQUARE_SYMBOL_C SYM4x4(0, 1, 1, 0, \ + 1, 0, 0, 0, \ + 1, 0, 0, 0, \ + 0, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_D SYM4x4(1, 1, 0, 0, \ + 1, 0, 1, 0, \ + 1, 0, 1, 0, \ + 1, 1, 0, 0) +#define ALPHASQUARE_SYMBOL_E SYM4x4(1, 1, 1, 0, \ + 1, 1, 0, 0, \ + 1, 0, 0, 0, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_F SYM4x4(1, 1, 1, 0, \ + 1, 0, 0, 0, \ + 1, 1, 0, 0, \ + 1, 0, 0, 0) +#define ALPHASQUARE_SYMBOL_G SYM4x4(0, 1, 1, 0, \ + 1, 0, 0, 0, \ + 1, 0, 1, 0, \ + 0, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_H SYM4x4(1, 0, 1, 0, \ + 1, 1, 1, 0, \ + 1, 0, 1, 0, \ + 1, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_I SYM4x4(1, 1, 1, 0, \ + 0, 1, 0, 0, \ + 0, 1, 0, 0, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_J SYM4x4(1, 1, 1, 0, \ + 0, 0, 1, 0, \ + 1, 0, 1, 0, \ + 0, 1, 0, 0) +#define ALPHASQUARE_SYMBOL_K SYM4x4(1, 0, 1, 0, \ + 1, 1, 0, 0, \ + 1, 1, 0, 0, \ + 1, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_L SYM4x4(1, 0, 0, 0, \ + 1, 0, 0, 0, \ + 1, 0, 0, 0, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_M SYM4x4(1, 0, 1, 0, \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ + 1, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_N SYM4x4(1, 0, 1, 0, \ + 1, 1, 1, 0, \ + 1, 0, 1, 0, \ + 1, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_O SYM4x4(0, 1, 0, 0, \ + 1, 0, 1, 0, \ + 1, 0, 1, 0, \ + 0, 1, 0, 0) +#define ALPHASQUARE_SYMBOL_P SYM4x4(1, 1, 0, 0, \ + 1, 0, 1, 0, \ + 1, 1, 0, 0, \ + 1, 0, 0, 0) +#define ALPHASQUARE_SYMBOL_Q SYM4x4(0, 1, 0, 0, \ + 1, 0, 1, 0, \ + 1, 0, 1, 0, \ + 0, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_R SYM4x4(1, 1, 0, 0, \ + 1, 0, 1, 0, \ + 1, 1, 0, 0, \ + 1, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_S SYM4x4(1, 1, 1, 0, \ + 1, 1, 0, 0, \ + 0, 0, 1, 0, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_T SYM4x4(1, 1, 1, 0, \ + 0, 1, 0, 0, \ + 0, 1, 0, 0, \ + 0, 1, 0, 0) +#define ALPHASQUARE_SYMBOL_U SYM4x4(1, 0, 1, 0, \ + 1, 0, 1, 0, \ + 1, 0, 1, 0, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_V SYM4x4(1, 0, 1, 0, \ + 1, 0, 1, 0, \ + 1, 0, 1, 0, \ + 0, 1, 0, 0) +#define ALPHASQUARE_SYMBOL_W SYM4x4(1, 0, 0, 0, \ + 1, 0, 1, 0, \ + 1, 1, 1, 0, \ + 1, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_X SYM4x4(1, 0, 1, 0, \ + 0, 1, 0, 0, \ + 0, 1, 0, 0, \ + 1, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_Y SYM4x4(1, 0, 1, 0, \ + 0, 1, 0, 0, \ + 0, 1, 0, 0, \ + 0, 1, 0, 0) +#define ALPHASQUARE_SYMBOL_Z SYM4x4(1, 1, 1, 0, \ + 0, 0, 1, 0, \ + 0, 1, 0, 0, \ + 1, 1, 1, 0) + // --------------------- +#define ALPHASQUARE_SYMBOL_1 SYM4x4(1, 1, 0, 0, \ + 0, 1, 0, 0, \ + 0, 1, 0, 0, + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_2 SYM4x4(1, 1, 0, 0, \ + 0, 0, 1, 0, \ + 0, 1, 0, 0, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_3 SYM4x4(1, 1, 1, 0, \ + 0, 1, 1, 0, \ + 0, 0, 1, 0, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_4 SYM4x4(1, 0, 1, 0, \ + 1, 1, 1, 0, \ + 0, 0, 1, 0, \ + 0, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_5 SYM4x4(1, 1, 1, 0, \ + 1, 1, 0, 0, \ + 0, 0, 1, 0, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_6 SYM4x4(0, 1, 1, 0, \ + 1, 0, 0, 0, \ + 1, 1, 1, 0, \ + 0, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_7 SYM4x4(1, 1, 1, 0, \ + 0, 0, 1, 0, \ + 0, 0, 1, 0, \ + 0, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_8 SYM4x4(1, 1, 1, 0, \ + 1, 1, 1, 0, \ + 1, 0, 1, 0, \ + 1, 1, 1, 0) +#define ALPHASQUARE_SYMBOL_9 SYM4x4(1, 1, 1, 0, \ + 1, 0, 1, 0, \ + 1, 1, 1, 0, \ + 0, 0, 1, 0) +#define ALPHASQUARE_SYMBOL_0 SYM4x4(1, 1, 1, 0, \ + 1, 0, 1, 0, \ + 1, 0, 1, 0, \ + 1, 1, 1, 0) + +#endif From a7622eff049cc18fa1397f13bafb0d63819db9f1 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 9 Jun 2017 19:07:36 -0700 Subject: [PATCH 264/792] Correct the description of 3x4 font --- src/Kaleidoscope/LED-AlphaSquare-3x4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/LED-AlphaSquare-3x4.h b/src/Kaleidoscope/LED-AlphaSquare-3x4.h index 4fc19aa5..93f2c5b4 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-3x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-3x4.h @@ -1,4 +1,4 @@ - * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet + * Kaleidoscope-LED-AlphaSquare -- 3x4 pixel LED alphabet * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify From ee4265ad77578c8fa478933999633371c1723f0e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 11 Jun 2017 08:45:26 +0800 Subject: [PATCH 265/792] fixes for cpplint, including a really embarssing mistake --- src/Kaleidoscope/LED-AlphaSquare-3x4.h | 5 ++++- src/Kaleidoscope/LED-AlphaSquare-4x4.h | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope/LED-AlphaSquare-3x4.h b/src/Kaleidoscope/LED-AlphaSquare-3x4.h index 93f2c5b4..67cf9379 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-3x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-3x4.h @@ -1,4 +1,4 @@ - * Kaleidoscope-LED-AlphaSquare -- 3x4 pixel LED alphabet +/* Kaleidoscope-LED-AlphaSquare -- 3x4 pixel LED alphabet * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -15,6 +15,9 @@ * along with this program. If not, see . */ + +#pragma once + #ifndef KALEIDOSCOPE_LED_FONT #define KALEIDOSCOPE_LED_FONT diff --git a/src/Kaleidoscope/LED-AlphaSquare-4x4.h b/src/Kaleidoscope/LED-AlphaSquare-4x4.h index 5b2f189f..ced5f75a 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-4x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-4x4.h @@ -1,4 +1,4 @@ - * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet +/* Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -15,6 +15,8 @@ * along with this program. If not, see . */ +#pragma once + #ifndef KALEIDOSCOPE_LED_FONT #define KALEIDOSCOPE_LED_FONT From af3cfba12412f454e44b2d1726f7752dfec34b40 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 11 Jun 2017 08:54:12 +0800 Subject: [PATCH 266/792] astyle didn't catch this whitespace issue --- src/Kaleidoscope/LED-AlphaSquare-3x4.h | 72 ++++++++++++------------- src/Kaleidoscope/LED-AlphaSquare-4x4.h | 74 +++++++++++++------------- 2 files changed, 73 insertions(+), 73 deletions(-) diff --git a/src/Kaleidoscope/LED-AlphaSquare-3x4.h b/src/Kaleidoscope/LED-AlphaSquare-3x4.h index 67cf9379..1b244c26 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-3x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-3x4.h @@ -24,7 +24,7 @@ #define ALPHASQUARE_SYMBOL_A SYM4x4(0, 1, 0, 0, \ 1, 0, 1, 0, \ 1, 1, 1, 0, \ - 1, 0, 1, 0) + 1, 0, 1, 0) #define ALPHASQUARE_SYMBOL_B SYM4x4(1, 1, 0, 0, \ 1, 1, 1, 0, \ 1, 0, 1, 0, \ @@ -32,139 +32,139 @@ #define ALPHASQUARE_SYMBOL_C SYM4x4(0, 1, 1, 0, \ 1, 0, 0, 0, \ 1, 0, 0, 0, \ - 0, 1, 1, 0) + 0, 1, 1, 0) #define ALPHASQUARE_SYMBOL_D SYM4x4(1, 1, 0, 0, \ 1, 0, 1, 0, \ 1, 0, 1, 0, \ - 1, 1, 0, 0) + 1, 1, 0, 0) #define ALPHASQUARE_SYMBOL_E SYM4x4(1, 1, 1, 0, \ 1, 1, 0, 0, \ 1, 0, 0, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_F SYM4x4(1, 1, 1, 0, \ 1, 0, 0, 0, \ 1, 1, 0, 0, \ - 1, 0, 0, 0) + 1, 0, 0, 0) #define ALPHASQUARE_SYMBOL_G SYM4x4(0, 1, 1, 0, \ 1, 0, 0, 0, \ 1, 0, 1, 0, \ - 0, 1, 1, 0) + 0, 1, 1, 0) #define ALPHASQUARE_SYMBOL_H SYM4x4(1, 0, 1, 0, \ 1, 1, 1, 0, \ 1, 0, 1, 0, \ - 1, 0, 1, 0) + 1, 0, 1, 0) #define ALPHASQUARE_SYMBOL_I SYM4x4(1, 1, 1, 0, \ 0, 1, 0, 0, \ 0, 1, 0, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_J SYM4x4(1, 1, 1, 0, \ 0, 0, 1, 0, \ 1, 0, 1, 0, \ - 0, 1, 0, 0) + 0, 1, 0, 0) #define ALPHASQUARE_SYMBOL_K SYM4x4(1, 0, 1, 0, \ 1, 1, 0, 0, \ 1, 1, 0, 0, \ - 1, 0, 1, 0) + 1, 0, 1, 0) #define ALPHASQUARE_SYMBOL_L SYM4x4(1, 0, 0, 0, \ 1, 0, 0, 0, \ 1, 0, 0, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_M SYM4x4(1, 0, 1, 0, \ 1, 1, 1, 0, \ 1, 1, 1, 0, \ - 1, 0, 1, 0) + 1, 0, 1, 0) #define ALPHASQUARE_SYMBOL_N SYM4x4(1, 0, 1, 0, \ 1, 1, 1, 0, \ 1, 0, 1, 0, \ - 1, 0, 1, 0) + 1, 0, 1, 0) #define ALPHASQUARE_SYMBOL_O SYM4x4(0, 1, 0, 0, \ 1, 0, 1, 0, \ 1, 0, 1, 0, \ - 0, 1, 0, 0) + 0, 1, 0, 0) #define ALPHASQUARE_SYMBOL_P SYM4x4(1, 1, 0, 0, \ 1, 0, 1, 0, \ 1, 1, 0, 0, \ - 1, 0, 0, 0) + 1, 0, 0, 0) #define ALPHASQUARE_SYMBOL_Q SYM4x4(0, 1, 0, 0, \ 1, 0, 1, 0, \ 1, 0, 1, 0, \ - 0, 1, 1, 0) + 0, 1, 1, 0) #define ALPHASQUARE_SYMBOL_R SYM4x4(1, 1, 0, 0, \ 1, 0, 1, 0, \ 1, 1, 0, 0, \ - 1, 0, 1, 0) + 1, 0, 1, 0) #define ALPHASQUARE_SYMBOL_S SYM4x4(1, 1, 1, 0, \ 1, 1, 0, 0, \ 0, 0, 1, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_T SYM4x4(1, 1, 1, 0, \ 0, 1, 0, 0, \ 0, 1, 0, 0, \ - 0, 1, 0, 0) + 0, 1, 0, 0) #define ALPHASQUARE_SYMBOL_U SYM4x4(1, 0, 1, 0, \ 1, 0, 1, 0, \ 1, 0, 1, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_V SYM4x4(1, 0, 1, 0, \ 1, 0, 1, 0, \ 1, 0, 1, 0, \ - 0, 1, 0, 0) + 0, 1, 0, 0) #define ALPHASQUARE_SYMBOL_W SYM4x4(1, 0, 0, 0, \ 1, 0, 1, 0, \ 1, 1, 1, 0, \ - 1, 0, 1, 0) + 1, 0, 1, 0) #define ALPHASQUARE_SYMBOL_X SYM4x4(1, 0, 1, 0, \ 0, 1, 0, 0, \ 0, 1, 0, 0, \ - 1, 0, 1, 0) + 1, 0, 1, 0) #define ALPHASQUARE_SYMBOL_Y SYM4x4(1, 0, 1, 0, \ 0, 1, 0, 0, \ 0, 1, 0, 0, \ - 0, 1, 0, 0) + 0, 1, 0, 0) #define ALPHASQUARE_SYMBOL_Z SYM4x4(1, 1, 1, 0, \ 0, 0, 1, 0, \ 0, 1, 0, 0, \ - 1, 1, 1, 0) - // --------------------- + 1, 1, 1, 0) +// --------------------- #define ALPHASQUARE_SYMBOL_1 SYM4x4(1, 1, 0, 0, \ 0, 1, 0, 0, \ 0, 1, 0, 0, - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_2 SYM4x4(1, 1, 0, 0, \ 0, 0, 1, 0, \ 0, 1, 0, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_3 SYM4x4(1, 1, 1, 0, \ 0, 1, 1, 0, \ 0, 0, 1, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_4 SYM4x4(1, 0, 1, 0, \ 1, 1, 1, 0, \ 0, 0, 1, 0, \ - 0, 0, 1, 0) + 0, 0, 1, 0) #define ALPHASQUARE_SYMBOL_5 SYM4x4(1, 1, 1, 0, \ 1, 1, 0, 0, \ 0, 0, 1, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_6 SYM4x4(0, 1, 1, 0, \ 1, 0, 0, 0, \ 1, 1, 1, 0, \ - 0, 1, 1, 0) + 0, 1, 1, 0) #define ALPHASQUARE_SYMBOL_7 SYM4x4(1, 1, 1, 0, \ 0, 0, 1, 0, \ 0, 0, 1, 0, \ - 0, 0, 1, 0) + 0, 0, 1, 0) #define ALPHASQUARE_SYMBOL_8 SYM4x4(1, 1, 1, 0, \ 1, 1, 1, 0, \ 1, 0, 1, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_9 SYM4x4(1, 1, 1, 0, \ 1, 0, 1, 0, \ 1, 1, 1, 0, \ - 0, 0, 1, 0) + 0, 0, 1, 0) #define ALPHASQUARE_SYMBOL_0 SYM4x4(1, 1, 1, 0, \ 1, 0, 1, 0, \ 1, 0, 1, 0, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #endif diff --git a/src/Kaleidoscope/LED-AlphaSquare-4x4.h b/src/Kaleidoscope/LED-AlphaSquare-4x4.h index ced5f75a..743f3268 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-4x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-4x4.h @@ -23,147 +23,147 @@ #define ALPHASQUARE_SYMBOL_A SYM4x4(1, 1, 1, 1, \ 1, 0, 0, 1, \ 1, 1, 1, 1, \ - 1, 0, 0, 1) + 1, 0, 0, 1) #define ALPHASQUARE_SYMBOL_B SYM4x4(1, 1, 1, 1, \ 1, 0, 1, 1, \ 1, 1, 0, 1, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_C SYM4x4(1, 1, 1, 1, \ 1, 0, 0, 0, \ 1, 0, 0, 0, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_D SYM4x4(1, 1, 1, 0, \ 1, 0, 0, 1, \ 1, 0, 0, 1, \ - 1, 1, 1, 0) + 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_E SYM4x4(1, 1, 1, 1, \ 1, 1, 0, 0, \ 1, 0, 0, 0, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_F SYM4x4(1, 1, 1, 1, \ 1, 0, 0, 0, \ 1, 1, 1, 0, \ - 1, 0, 0, 0) + 1, 0, 0, 0) #define ALPHASQUARE_SYMBOL_G SYM4x4(1, 1, 1, 0, \ 1, 0, 0, 0, \ 1, 0, 0, 1, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_H SYM4x4(1, 0, 0, 1, \ 1, 1, 1, 1, \ 1, 0, 0, 1, \ - 1, 0, 0, 1) + 1, 0, 0, 1) #define ALPHASQUARE_SYMBOL_I SYM4x4(1, 1, 1, 1, \ 0, 1, 1, 0, \ 0, 1, 1, 0, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_J SYM4x4(1, 1, 1, 1, \ 0, 0, 0, 1, \ 1, 0, 0, 1, \ - 0, 1, 1, 0) + 0, 1, 1, 0) #define ALPHASQUARE_SYMBOL_K SYM4x4(1, 0, 0, 1, \ 1, 1, 0, 0, \ 1, 1, 0, 0, \ - 1, 0, 1, 1) + 1, 0, 1, 1) #define ALPHASQUARE_SYMBOL_L SYM4x4(1, 0, 0, 0, \ 1, 0, 0, 0, \ 1, 0, 0, 0, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_M SYM4x4(1, 0, 1, 1, \ 1, 1, 1, 1, \ 1, 1, 0, 1, \ - 1, 0, 0, 1) + 1, 0, 0, 1) #define ALPHASQUARE_SYMBOL_N SYM4x4(1, 0, 0, 1, \ 1, 1, 0, 1, \ 1, 0, 1, 1, \ - 1, 0, 0, 1) + 1, 0, 0, 1) #define ALPHASQUARE_SYMBOL_O SYM4x4(1, 1, 1, 1, \ 1, 0, 0, 1, \ 1, 0, 0, 1, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_P SYM4x4(1, 1, 1, 1, \ 1, 0, 0, 1, \ 1, 1, 1, 1, \ - 1, 0, 0, 0) + 1, 0, 0, 0) #define ALPHASQUARE_SYMBOL_Q SYM4x4(1, 1, 1, 1, \ 1, 0, 0, 1, \ 1, 0, 1, 1, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_R SYM4x4(1, 1, 1, 1, \ 1, 0, 0, 1, \ 1, 1, 1, 0, \ - 1, 0, 1, 1) + 1, 0, 1, 1) #define ALPHASQUARE_SYMBOL_S SYM4x4(1, 1, 1, 1, \ 1, 1, 0, 0, \ 0, 0, 1, 1, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_T SYM4x4(1, 1, 1, 1, \ 0, 1, 1, 0, \ 0, 1, 1, 0, \ - 0, 1, 1, 0) + 0, 1, 1, 0) #define ALPHASQUARE_SYMBOL_U SYM4x4(1, 0, 0, 1, \ 1, 0, 0, 1, \ 1, 0, 0, 1, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_V SYM4x4(1, 0, 0, 1, \ 1, 0, 0, 1, \ 1, 0, 0, 1, \ - 0, 1, 1, 0) + 0, 1, 1, 0) #define ALPHASQUARE_SYMBOL_W SYM4x4(1, 0, 0, 1, \ 1, 0, 1, 1, \ 1, 1, 1, 1, \ - 1, 0, 1, 1) + 1, 0, 1, 1) #define ALPHASQUARE_SYMBOL_X SYM4x4(1, 0, 0, 1, \ 0, 1, 1, 0, \ 0, 1, 1, 0, \ - 1, 0, 0, 1) + 1, 0, 0, 1) #define ALPHASQUARE_SYMBOL_Y SYM4x4(1, 0, 0, 1, \ 1, 1, 1, 1, \ 0, 1, 1, 0, \ - 0, 1, 1, 0) + 0, 1, 1, 0) #define ALPHASQUARE_SYMBOL_Z SYM4x4(1, 1, 1, 1, \ 0, 0, 1, 1, \ 1, 1, 0, 0, \ - 1, 1, 1, 1) - // --------------------- + 1, 1, 1, 1) +// --------------------- #define ALPHASQUARE_SYMBOL_1 SYM4x4(0, 1, 1, 0, \ 1, 0, 1, 0, \ 0, 0, 1, 0, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_2 SYM4x4(0, 1, 1, 0, \ 1, 0, 0, 1, \ 0, 0, 1, 0, \ - 1, 1, 0, 1) + 1, 1, 0, 1) #define ALPHASQUARE_SYMBOL_3 SYM4x4(1, 1, 1, 1, \ 0, 0, 1, 1, \ 0, 0, 0, 1, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_4 SYM4x4(1, 0, 0, 1, \ 1, 1, 1, 1, \ 0, 0, 0, 1, \ - 0, 0, 0, 1) + 0, 0, 0, 1) #define ALPHASQUARE_SYMBOL_5 SYM4x4(1, 1, 1, 1, \ 1, 0, 0, 0, \ 0, 1, 1, 1, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_6 SYM4x4(0, 1, 1, 0, \ 1, 0, 0, 0, \ 1, 1, 1, 1, \ - 1, 1, 1, 1) + 1, 1, 1, 1) #define ALPHASQUARE_SYMBOL_7 SYM4x4(1, 1, 1, 1, \ 0, 0, 0, 1, \ 0, 0, 1, 0, \ - 0, 1, 0, 0) + 0, 1, 0, 0) #define ALPHASQUARE_SYMBOL_8 SYM4x4(1, 1, 1, 0, \ 1, 0, 1, 1, \ 1, 1, 0, 1, \ - 0, 1, 1, 1) + 0, 1, 1, 1) #define ALPHASQUARE_SYMBOL_9 SYM4x4(1, 1, 1, 1, \ 1, 0, 0, 1, \ 1, 1, 1, 1, \ - 0, 0, 0, 1) + 0, 0, 0, 1) #define ALPHASQUARE_SYMBOL_0 SYM4x4(0, 1, 1, 0, \ 1, 0, 0, 1, \ 1, 0, 0, 1, \ - 0, 1, 1, 0) + 0, 1, 1, 0) #endif From ea90ca09b045e041dc07dc6357588504bd7eca84 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 12 Jun 2017 09:13:05 +0800 Subject: [PATCH 267/792] Add a brightness API for the rainbow effects --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 8 ++++++++ src/Kaleidoscope-LEDEffect-Rainbow.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index 3ea8edc0..a929d9f0 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -19,6 +19,10 @@ void LEDRainbowEffect_::update(void) { LEDControl.set_all_leds_to(rainbow); } +void LEDRainbowEffect_::brightness(byte brightness) { + rainbow.value=brighness; +} + LEDRainbowEffect_ LEDRainbowEffect; // --------- @@ -47,4 +51,8 @@ void LEDRainbowWaveEffect_::update(void) { } } +void LEDRainbowWaveEffect_::brightness(byte brightness) { + rainbow.value=brighness; +} + LEDRainbowWaveEffect_ LEDRainbowWaveEffect; diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 8f98bcee..1af33c82 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -7,6 +7,7 @@ class LEDRainbowEffect_ : public LEDMode { public: LEDRainbowEffect_(void); + void brightness(byte); void update(void) final; private: @@ -27,6 +28,7 @@ class LEDRainbowWaveEffect_ : public LEDMode { public: LEDRainbowWaveEffect_(void); + void brightness(byte); void update(void) final; private: From ae8407016b2cd00b0948e0f38b66f0178c2e1ece Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 12 Jun 2017 09:17:30 +0800 Subject: [PATCH 268/792] wrong var name --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index a929d9f0..13103611 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -20,7 +20,7 @@ void LEDRainbowEffect_::update(void) { } void LEDRainbowEffect_::brightness(byte brightness) { - rainbow.value=brighness; + rainbow_value=brighness; } LEDRainbowEffect_ LEDRainbowEffect; @@ -52,7 +52,7 @@ void LEDRainbowWaveEffect_::update(void) { } void LEDRainbowWaveEffect_::brightness(byte brightness) { - rainbow.value=brighness; + rainbow_value=brighness; } LEDRainbowWaveEffect_ LEDRainbowWaveEffect; From 80c6e1f26c3d30dd776e3cc06b64a26f50f396c4 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 12 Jun 2017 09:20:13 +0800 Subject: [PATCH 269/792] 0 was duplicated --- src/Kaleidoscope/LED-AlphaSquare.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index f3f1cc3a..2376231a 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -48,7 +48,6 @@ static const uint16_t alphabet[] PROGMEM = { ALPHASQUARE_SYMBOL_X, ALPHASQUARE_SYMBOL_Y, ALPHASQUARE_SYMBOL_Z, - ALPHASQUARE_SYMBOL_0, ALPHASQUARE_SYMBOL_1, ALPHASQUARE_SYMBOL_2, ALPHASQUARE_SYMBOL_3, From 41ddb76fa81d0f80d9ef03c301b4b74c30ae81aa Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 12 Jun 2017 09:21:39 +0800 Subject: [PATCH 270/792] indent error --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index 13103611..b5698f16 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -20,7 +20,7 @@ void LEDRainbowEffect_::update(void) { } void LEDRainbowEffect_::brightness(byte brightness) { - rainbow_value=brighness; + rainbow_value=brighness; } LEDRainbowEffect_ LEDRainbowEffect; @@ -52,7 +52,7 @@ void LEDRainbowWaveEffect_::update(void) { } void LEDRainbowWaveEffect_::brightness(byte brightness) { - rainbow_value=brighness; + rainbow_value=brighness; } LEDRainbowWaveEffect_ LEDRainbowWaveEffect; From 0dabbc6f95cc67bbb9710f5b1978523bab77c60f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 12 Jun 2017 09:25:24 +0800 Subject: [PATCH 271/792] typo --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index b5698f16..4de93803 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -20,7 +20,7 @@ void LEDRainbowEffect_::update(void) { } void LEDRainbowEffect_::brightness(byte brightness) { - rainbow_value=brighness; + rainbow_value=brightness; } LEDRainbowEffect_ LEDRainbowEffect; @@ -52,7 +52,7 @@ void LEDRainbowWaveEffect_::update(void) { } void LEDRainbowWaveEffect_::brightness(byte brightness) { - rainbow_value=brighness; + rainbow_value=brightness; } LEDRainbowWaveEffect_ LEDRainbowWaveEffect; From d1fc67e45db08d8f3fab7ac40700daa89635890d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 12 Jun 2017 09:28:50 +0800 Subject: [PATCH 272/792] deconstify things we think we might want to let users configure --- src/Kaleidoscope-LEDEffect-Rainbow.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 1af33c82..0945b785 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -13,12 +13,12 @@ class LEDRainbowEffect_ : public LEDMode { private: uint16_t rainbow_hue = 0; //stores 0 to 614 - static const uint8_t rainbow_steps = 1; //number of hues we skip in a 360 range per update + static uint8_t rainbow_steps = 1; //number of hues we skip in a 360 range per update uint16_t rainbow_current_ticks = 0; - static const uint16_t rainbow_ticks = 10; //delays between update + static uint16_t rainbow_ticks = 10; //delays between update - static const byte rainbow_saturation = 255; - static const byte rainbow_value = 50; + static byte rainbow_saturation = 255; + static byte rainbow_value = 50; }; @@ -34,12 +34,12 @@ class LEDRainbowWaveEffect_ : public LEDMode { private: uint16_t rainbow_hue = 0; //stores 0 to 614 - static const uint8_t rainbow_wave_steps = 1; //number of hues we skip in a 360 range per update + static uint8_t rainbow_wave_steps = 1; //number of hues we skip in a 360 range per update uint16_t rainbow_current_ticks = 0; - static const uint16_t rainbow_wave_ticks = 10; //delays between update + static uint16_t rainbow_wave_ticks = 10; //delays between update - static const byte rainbow_saturation = 255; - static const byte rainbow_value = 50; + static byte rainbow_saturation = 255; + static byte rainbow_value = 50; }; extern LEDRainbowWaveEffect_ LEDRainbowWaveEffect; From 85b96e0e8581feb5d8408b90c023825843f3f0cf Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 12 Jun 2017 09:32:51 +0800 Subject: [PATCH 273/792] destaticify --- src/Kaleidoscope-LEDEffect-Rainbow.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 0945b785..28421ad8 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -13,12 +13,12 @@ class LEDRainbowEffect_ : public LEDMode { private: uint16_t rainbow_hue = 0; //stores 0 to 614 - static uint8_t rainbow_steps = 1; //number of hues we skip in a 360 range per update + uint8_t rainbow_steps = 1; //number of hues we skip in a 360 range per update uint16_t rainbow_current_ticks = 0; - static uint16_t rainbow_ticks = 10; //delays between update + uint16_t rainbow_ticks = 10; //delays between update - static byte rainbow_saturation = 255; - static byte rainbow_value = 50; + byte rainbow_saturation = 255; + byte rainbow_value = 50; }; @@ -34,12 +34,12 @@ class LEDRainbowWaveEffect_ : public LEDMode { private: uint16_t rainbow_hue = 0; //stores 0 to 614 - static uint8_t rainbow_wave_steps = 1; //number of hues we skip in a 360 range per update + uint8_t rainbow_wave_steps = 1; //number of hues we skip in a 360 range per update uint16_t rainbow_current_ticks = 0; - static uint16_t rainbow_wave_ticks = 10; //delays between update + uint16_t rainbow_wave_ticks = 10; //delays between update - static byte rainbow_saturation = 255; - static byte rainbow_value = 50; + byte rainbow_saturation = 255; + byte rainbow_value = 50; }; extern LEDRainbowWaveEffect_ LEDRainbowWaveEffect; From 953b58702cb79df65c7b55d1d7cf9ca28240d4aa Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 12 Jun 2017 11:25:27 +0800 Subject: [PATCH 274/792] cpplint-noisy cleanup --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 4 ++-- src/Kaleidoscope-LEDEffect-Rainbow.h | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index 4de93803..f0793f65 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -20,7 +20,7 @@ void LEDRainbowEffect_::update(void) { } void LEDRainbowEffect_::brightness(byte brightness) { - rainbow_value=brightness; + rainbow_value = brightness; } LEDRainbowEffect_ LEDRainbowEffect; @@ -52,7 +52,7 @@ void LEDRainbowWaveEffect_::update(void) { } void LEDRainbowWaveEffect_::brightness(byte brightness) { - rainbow_value=brightness; + rainbow_value = brightness; } LEDRainbowWaveEffect_ LEDRainbowWaveEffect; diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 28421ad8..6745bdbe 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -11,15 +11,14 @@ class LEDRainbowEffect_ : public LEDMode { void update(void) final; private: - uint16_t rainbow_hue = 0; //stores 0 to 614 + uint16_t rainbow_hue = 0; // stores 0 to 614 - uint8_t rainbow_steps = 1; //number of hues we skip in a 360 range per update + uint8_t rainbow_steps = 1; // number of hues we skip in a 360 range per update uint16_t rainbow_current_ticks = 0; - uint16_t rainbow_ticks = 10; //delays between update + uint16_t rainbow_ticks = 10; // delays between update byte rainbow_saturation = 255; byte rainbow_value = 50; - }; extern LEDRainbowEffect_ LEDRainbowEffect; @@ -32,11 +31,11 @@ class LEDRainbowWaveEffect_ : public LEDMode { void update(void) final; private: - uint16_t rainbow_hue = 0; //stores 0 to 614 + uint16_t rainbow_hue = 0; // stores 0 to 614 - uint8_t rainbow_wave_steps = 1; //number of hues we skip in a 360 range per update + uint8_t rainbow_wave_steps = 1; // number of hues we skip in a 360 range per update uint16_t rainbow_current_ticks = 0; - uint16_t rainbow_wave_ticks = 10; //delays between update + uint16_t rainbow_wave_ticks = 10; // delays between update byte rainbow_saturation = 255; byte rainbow_value = 50; From feda65117004d4639a4d721ed8dea98dbe7ceccd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 15 Jun 2017 08:35:44 +0200 Subject: [PATCH 275/792] Mark the plugin stable Signed-off-by: Gergely Nagy --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f17b417..a7f7fc6a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Kaleidoscope-EEPROM-Keymap -![status][st:experimental] [![Build Status][travis:image]][travis:status] +![status][st:stable] [![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap From 98b389411b29247a1a84ac722f150fcb229610ee Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 15 Jun 2017 08:35:57 +0200 Subject: [PATCH 276/792] Use Kaleidoscope.use instead of USE_PLUGINS Signed-off-by: Gergely Nagy --- README.md | 2 +- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 2 +- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a7f7fc6a..8ab29ee4 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ We can then update the keymap via [Focus][plugin:focus]. void setup() { Serial.begin(9600); - USE_PLUGINS(&EEPROMKeymap, &Focus); + Kaleidoscope.use(&EEPROMKeymap, &Focus); Kaleidoscope.setup(); diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index 207d7bae..1f3dd91d 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -42,7 +42,7 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { void setup() { Serial.begin(9600); - USE_PLUGINS(&EEPROMKeymap, &Focus); + Kaleidoscope.use(&EEPROMKeymap, &Focus); Kaleidoscope.setup(); diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index a56b17ca..e9a9de8d 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -28,7 +28,7 @@ EEPROMKeymap::EEPROMKeymap(void) { } void EEPROMKeymap::begin(void) { - USE_PLUGINS(&::EEPROMSettings); + Kaleidoscope.use(&::EEPROMSettings); } void EEPROMKeymap::max_layers(uint8_t max) { From beb159e86015221f8ccf2943d6293d473976f100 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 16 Jun 2017 10:34:32 +0800 Subject: [PATCH 277/792] brighten up the LEDs for testing --- src/Kaleidoscope-Model01-TestMode.cpp | 36 +++++++++++---------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 80f72020..01c96e54 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -11,9 +11,9 @@ TestMode_::TestMode_(void) { void TestMode_::begin(void) { - red.r = 101; - blue.b = 101; - green.g = 101; + red.r = 201; + blue.b = 201; + green.g = 201; loop_hook_use(this->loopHook); } @@ -48,14 +48,6 @@ void TestMode_::set_leds(uint8_t r, uint8_t g, uint8_t b) { } void TestMode_::test_leds(void) { - // make all LEDs dim red - set_leds(50, 0, 0); - // make all LEDs dim blue - set_leds(0, 50, 0); - // make all LEDs dim green - set_leds(0, 0, 50); - // make all LEDs dim white - set_leds(50, 50, 50); // make all the LEDs bright red set_leds(200, 0, 0); // make all the LEDs bright green @@ -76,7 +68,7 @@ void TestMode_::test_leds(void) { void TestMode_::test_matrix() { - LEDControl.set_all_leds_to(50, 0, 0); + LEDControl.set_all_leds_to(200, 0, 0); while (1) { KeyboardHardware.read_matrix(); if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { @@ -91,10 +83,10 @@ void TestMode_::test_matrix() { (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); if (keyState == 3) { - Serial.print(" Key: "); - Serial.print(keynum); - Serial.print(" value "); - Serial.println(keyState); + // Serial.print(" Key: "); + // Serial.print(keynum); + // Serial.print(" value "); + // Serial.println(keyState); KeyboardHardware.led_set_crgb_at(row, 7 - col, green); } else if (keyState == 1) { KeyboardHardware.led_set_crgb_at(row, 7 - col, blue); @@ -104,10 +96,10 @@ void TestMode_::test_matrix() { (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); if (keyState == 3) { - Serial.print(" Key: "); - Serial.print(keynum); - Serial.print(" value "); - Serial.println(keyState); + // Serial.print(" Key: "); + // Serial.print(keynum); + // Serial.print(" value "); + // Serial.println(keyState); KeyboardHardware.led_set_crgb_at(row, 15 - col, green); } else if (keyState == 1) { KeyboardHardware.led_set_crgb_at(row, 15 - col, blue); @@ -119,10 +111,10 @@ void TestMode_::test_matrix() { } void TestMode_::run_tests() { - Serial.println("Running tests"); + // Serial.println("Running tests"); test_leds(); test_matrix(); - Serial.println("Done running tests"); + // Serial.println("Done running tests"); } TestMode_ TestMode; From 869bd097b33ac9f65d6ac28a507736814918ec5c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 08:46:37 +0200 Subject: [PATCH 278/792] README.md: First stab at documenting the plugin Signed-off-by: Gergely Nagy --- README.md | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a357e99c..8d724250 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,180 @@ # Kaleidoscope-Macros -This is a plugin for [Kaleidoscope][fw], that adds support for macros. +![status][st:stable] [![Build Status][travis:image]][travis:status] - [fw]: https://github.com/keyboardio/Kaleidoscope + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-Macros.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-Macros + + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + +Macros are a standard feature on many keyboards, and Kaleidoscope-powered ones +are no exceptions. Macros are a way to have a single key-press do a whole lot of +things under the hood: conventionally, macros play back a key sequence, but with +Kaleidoscope, there are many more we can do. Nevertheless, playing back a +sequence of events is still the primary use of macros. + +Playing back a sequence means that when we press a macro key, we can have it +play pretty much any sequence. It can type some text for us, or invoke a +complicated shortcut - the possibilities are endless! + +## Using the plugin + +To use the plugin, we need to include the header, make sure we use the plugin, +place macros on the keymap, and create a special handler function +(`macroAction`) that will tell the plugin what shall happen when macro keys are +pressed. It is best illustrated with an example: + +```c++ +#include +#include + +// Give a name to the macros! +enum { + MACRO_MODEL01, + MACRO_HELLO, + MACRO_SPECIAL, +}; + +// Somewhere in the keymap: +M(MACRO_MODEL01), M(MACRO_HELLO), M(MACRO_SPECIAL) + +// later in the Sketch: +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { + switch (macroIndex) { + case MACRO_MODEL01: + return MACRODOWN(I(25), + D(LeftShift), T(M), U(LeftShift), T(O), T(D), T(E), T(L), + T(Spacebar), + W(100), + T(0), T(1), + END); + case MACRO_HELLO: + if (key_toggled_on(keyState)) { + Macros.type(PSTR("Hello world!")); + } + break; + case MACRO_SPECIAL: + if (key_toggled_on(keyState)) { + // Do something special + } + break; + } + return MACRO_NONE; +} + +void setup() { + Kaleidoscope.use(&Macros); + + Kaleidoscope.setup (); +} +``` + +## Keymap markup + +### `M(id)` + +> Places a macro key on the keymap, with the `id` identifier. Whenever this key +> has to be handled, the `macroAction` overrideable function will be called, +> with the identifier and key state as arguments. +> +> It is recommended to give a *name* to macros, by using an `enum`. + +## Plugin methods + +The plugin provides a `Macros` object, with the following methods and properties available: + +### `.play(macro)` + +> Plays back a macro, where a macro is a sequence created with the `MACRO()` +> helper discussed below. This method will be used by the plugin to play back +> the result of the `macroAction()` method, but is used rarely otherwise. +> +> The `macro` argument must be a sequence created with the `MACRO()` helper! + +### `.type(string)` + +> In cases where we only want to type a string, it is far more convenient to use +> this method: we do not have to use the `MACRO()` helper, but just give this +> one a string, and it will type it for us on the keyboard. +> +> The string is limited to a sequence of printable ASCII characters. No +> international symbols, or unicode, or anything like it: just plain ASCII. +> +> The `string` argument must also reside in program memory, and the easiest way +> to do that is to wrap the string in a `PSTR()` helper. See the program code at +> the beginning of this documentation for an example! + +### `.row`, `.col` + +> The `row` and `col` properties describe the physical position a macro was +> triggered from - if it was triggered by a key, that is. The playback functions +> do not use these properties, but they are available, would one want to create +> a macro that needs to know which key triggered it. + +## Macro helpers + +Macros need to be able to simulate key down and key up events for any key - even +keys that may not be on the keymap otherwise. For this reason and others, we +need to define them in a special way, using the `MACRO` helper (or its +`MACRODOWN()` variant, see below): + +### `MACRO(steps...)` + +> Defines a macro, that is built up from `steps` (explained below). The plugin +> will iterate through the sequence, and re-play the steps in order. +> +> The sequence must end with the `END` step, otherwise the playback will not be +> able to stop, and will have unpredictable behaviour. + +### `MACRODOWN(steps...)` + +> The same as the `MACRO()` helper above, but it will create a special sequence, +> where the steps are only played back when the triggering key was just pressed. +> That is, the macro will not be performed when the key is released, or held, or +> not pressed at all. +> +> Can only be used from the `macroAction()` overrideable method. + +## `MACRO` steps + +Macro steps can be divided into three groups: + +### Delays + +* `I(millis)`: Sets the interval between steps to `millis`. By default, there is + no delay between steps, and they are played back as fast as possible. Useful + when we want to see the macro being typed, or need to slow it down, to allow + the host to process it. +* `W(millis)`: Waits for `millis` milliseconds. For dramatic effects. + +### Key events + +Key event steps have two variants: one that prefixes its argument with `Key_`, +and one that does not. The latter are the `Dr`, `Ur`, and `Tr` variants. In most +cases, one is likely to use normal keys for the steps, so the `D`, `U`, and `T` +steps apply the `Key_` prefix. This allows us to write `MACRO(T(X), END)` +instead of `MACRO(Tr(Key_X), END)` - making the macro definition shorter, and +more readable. + +* `D(key)`, `Dr(key)`: Simulates a key being pressed (pushed down). +* `U(key)`, `Ur(key)`: Simulates a key being released (going up). +* `T(key)`, `Tr(key)`: Simulates a key being tapped (pressed first, then released). + +### The End + +* `END`: Signals the end of the macro. Anything past this step will be ignored. + But without this step, the plugin will continue trying to play the macro + further, and have unpredictable results. + +## Overrideable methods + +### `macroAction(macroIndex, keyState)` + +> The `macroAction` method is the brain of the macro support in Kaleidoscope: +> this function tells the plugin what sequence to play when given a macro index +> and a key state. +> +> It should return a macro sequence, or `MACRO_NONE` if nothing is to be played +> back. From e2e00c138ef04cd7c5a86779bbfbad28a0b4b127 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 08:49:51 +0200 Subject: [PATCH 279/792] library.properties: Fill out the paragraph section too. Signed-off-by: Gergely Nagy --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 624df636..af4a0447 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent sentence=Macro keys for Kaleidoscope. -paragraph=... +paragraph=Macro keys and supporting functions for Kaleidoscope. category=Communication url=https://github.com/keyboardio/Kaleidoscope-Macros architectures=avr From ab9127d8ea606dd997ffea5d9c4ebc663bc8a715 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 15:24:40 +0200 Subject: [PATCH 280/792] Fill out the paragraph= property in library.properties Signed-off-by: Gergely Nagy --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index d4df7f02..37481310 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent sentence=Mouse keys for Kaleidoscope. -paragraph=... +paragraph=Simulate a mouse with keys on a regular keyboard. category=Communication url=https://github.com/keyboardio/Kaleidoscope-MouseKeys architectures=avr From 964b6d2d4a4ac59d8a2b6421bfccffb07c0c814f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 16:14:42 +0200 Subject: [PATCH 281/792] README.md: Document the keys provided Signed-off-by: Gergely Nagy --- README.md | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce8ad7e8..bc883b29 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,139 @@ # Kaleidoscope-MouseKeys -This is a plugin for [Kaleidoscope][fw], that adds support for mouse keys. +![status][st:stable] [![Build Status][travis:image]][travis:status] - [fw]: https://github.com/keyboardio/Kaleidoscope + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MouseKeys.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MouseKeys + + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + +Have you ever wanted to control the mouse cursor from the comfort of your +keyboard? With this plugin, you can. While it may not replace the mouse in all +situations, there are plenty of cases where one will not have to lift their +hands off the keyboard just to nudge the mouse cursor away a little. + +Of course, there are a lot more one can do with the plugin than to nudge the +cursor! Mouse keys are provided for all four *and* diagonal movement; mouse +buttons; and a unique warping mechanism too. And not only these: the speed of +the cursor, the mouse wheel, and that of acceleration can all be configured to +match one's desired behaviour. + +## Using the plugin + +To use the plugin, simply include the header, make sure the `MouseKeys` object +is properly used, and place mouse keys on your keymap. It is best illustrated +with an example: + +```c++ +#include +#include + +// Somewhere in the keymap: +Key_mouseUp, Key_mouseDn, Key_mouseL, Key_mouseR, +Key_mouseBtnL, Key_mouseBtnR + +void setup() { + Kaleidoscope.use(&MouseKeys); + + Kaleidoscope.setup (); +} +``` + +## Keys provided by the plugin + +The plugin provides a number of keys one can put on the keymap, that allow +control of the mouse. They can be divided into a few groups: + +### Cursor movement + +The simplest set of keys are the mouse cursor movement keys. These move the +cursor one direction or the other, with speed and acceleration factored in. When +a mouse cursor movement key is held down, it will move `.speed` pixels each +`.speedDelay` milliseconds without acceleration. But when `.accelSpeed` is +non-zero (and it is not zero by default), the speed will increase by +`.accelSpeed` every `.accelDelay` milliseconds. Thus, unless configured +otherwise, holding a direction will move that way at increasing speed. + +One can hold more than one key down at the same time, and the cursor will move +towards a direction that is the combination of the keys held. For example, +holding the "mouse up" and "mouse right" keys together will move the cursor +diagonally up and right. + +The cursor movement keys are as follows: + +* `Key_mouseUp`, `Key_mouseDn`, `Key_mouseL`, `Key_mouseR`: Move the cursor up, + down, left, or right, respectively. +* `Key_mouseUpL`, `Key_mouseUpR`, `Key_mouseDnL`, `Key_mouseDnR`: Move the + cursor up-left, up-right, down-left, down-right, respectively. + +### Scroll wheel + +Controlling the scroll wheel is similarly simple. It does not have acceleration, +but one can control the speed with the `.wheelSpeed` and `.wheelDelay` +properties (see below). + +* `Key_mouseScrollUp`, `Key_mouseScrollDn`: Scroll the mouse wheel up or down, + respectively. + +### Buttons + +Buttons are even simpler than movement: there is no movement speed, nor +acceleration involved. One just presses them. + +* `Key_mouseBtnL`, `Key_mouseBtnM`, `Key_mouseBtnR`: The left, middle, and right + mouse buttons, respectively. + +### Warping + +Warping is one of the most interesting features of the plugin, and is a feature +unique to Kaleidoscope, as far as we can tell. The warping keys position the +mouse cursor within a quadrant of the screen on first press, and any subsequent +taps will warp within the previously selected quadrant. For example, pressing +the north-west warp key twice will first jump to the middle of the north-west +quadrant of your screen, then select the north-west quadrant of that, and jump +to the middle of it. + +To stop warping, use any other mouse key, or hit the "warp end" key. + +This features works out of the box on Windows and OSX. On Linux, a patch exists, +but has not been finalised and merged yet. + +The warping keys are the following: + +* `Key_mouseWarpNW`, `Key_mouseWarpNE`, `Key_mouseWarpSW`, `Key_mouseWarpSE`: + Warp towards the north-west, north-east, south-west, or south-east quadrants, + respectively. +* `Key_mouseWarpEnd`: End the warping sequence, resetting it to the default + state. Using any of the warping keys after this will start from the whole + screen again. + +## Plugin methods + +The plugin provides a `MouseKeys` object, with the following methods and +properties available: + +### `.speed` and `.speedDelay` + +> These two control the speed of the mouse cursor, when a movement key is held. +> The former, `.speed`, controls the amount of pixels the cursor moves, when it +> has to move, and defaults to 1. The latter, `.speedDelay` is the amount of +> time - in milliseconds - to wait between two movements, and defaults to 0, no +> delay. + +### `.accelSpeed` and `.accelDelay` + +> These two properties control the speed of acceleration. The former, +> `.accelSpeed`, controls how much the speed shall be increased at each step, +> while the second, `.accelDelay`, controls how often (in milliseconds) +> acceleration should be applied. +> +> They default to 1 pixel and 50 milliseconds, respectively. + +### `.wheelSpeed` and `.wheelDelay` + +> The last two properties supported by the plugin control the mouse wheel +> scrolling speed. The former, `.wheelSpeed`, controls the amount of ticks the +> wheel shall scroll, and defaults to 1. The second, `.wheelDelay`, controls the +> delay between two scroll events, and defaults to 50 milliseconds. From 9d8533a343b24391f741f4f7731bde6f77671d31 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 20:05:45 +0200 Subject: [PATCH 282/792] library.properties: Fill out the paragraph Signed-off-by: Gergely Nagy --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 8b7571e8..e9474c8e 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent sentence=Solid color LED effects for Kaleidoscope. -paragraph=... +paragraph=Tools to create solid-color LED effects. category=Communication url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-SolidColor architectures=avr From a4289bf936f2d599931a13b39562f6b6883ecec6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 20:06:28 +0200 Subject: [PATCH 283/792] README.md: A few words of documentation Signed-off-by: Gergely Nagy --- README.md | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a09cb3df..b4fc6d9f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,34 @@ # Kaleidoscope-LEDEffect-SolidColor -This is a plugin for [Kaleidoscope][fw], adding a solid color LED effect. +![status][st:stable] [![Build Status][travis:image]][travis:status] - [fw]: https://github.com/keyboardio/Kaleidoscope + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-SolidColor.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-SolidColor + + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + +This plugin provides tools to build LED effects that set the entire keyboard to +a single color. For show, and for backlighting purposes. + +## Using the extension + +To use the plugin, include the header, declare an effect using the +`LEDSolidColor` class, and tell the firmware to use the new effect: + +```c++ +#include + +static LEDSolidColor solidRed(160, 0, 0); + +void setup() { + Kaleidoscope.use(&solidRed); + + Kaleidoscope.setup(); +} +``` + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) From 40c9575183752444a18ddcad51e2503b18fbe052 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 20:19:26 +0200 Subject: [PATCH 284/792] library.properties: Fill out the paragraph. Signed-off-by: Gergely Nagy --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 6cc68c0f..c6419041 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent sentence=A Chase LED effect for Kaleidoscope. -paragraph=... +paragraph=A fun little LED effect where two colors chase each other. category=Communication url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-Chase architectures=avr From bbd155fa945c91bc4120fac1834aa513c137dd94 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 20:19:44 +0200 Subject: [PATCH 285/792] README.md: A few more words about the plugin Signed-off-by: Gergely Nagy --- README.md | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3c8e8c2d..78e59e6b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,36 @@ # Kaleidoscope-LEDEffect-Chase -This is a plugin for [Kaleidoscope][fw], adding a Chase LED effect. +![status][st:stable] [![Build Status][travis:image]][travis:status] - [fw]: https://github.com/keyboardio/Kaleidoscope + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Chase.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Chase + + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + +A simple LED effect where one color chases another across the keyboard and back, +over and over again. Playful colors they are. + +## Using the extension + +To use the plugin, include the header, and tell the firmware to use it: + +```c++ +#include + +void setup() { + Kaleidoscope.use(&LEDChaseEffect); + + Kaleidoscope.setup(); +} +``` + +## Plugin methods + +The plugin provides the `LEDChaseEffect` object, which has no public methods or +properties, outside of those provided by all LED modes. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) From 6b7bafc08f4eb6302131ab6d4a63d81ba8d0a0e3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 20:26:18 +0200 Subject: [PATCH 286/792] library.properties: Fill out the paragraph too. Signed-off-by: Gergely Nagy --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 2bbb13f0..97eb4e1f 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent sentence=A breathing effect on the LEDs, for Kaleidoscope. -paragraph=... +paragraph=A breathing effect on the LEDs, for Kaleidoscope. category=Communication url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-Breathe architectures=avr From 3276b97a2e1ea7f25e300a30b7b4c3de9a94e994 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 20:28:07 +0200 Subject: [PATCH 287/792] README.md: A few words about the plugin Signed-off-by: Gergely Nagy --- README.md | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 12bee0bf..69218c83 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,35 @@ # Kaleidoscope-LEDEffect-Breathe -This is a plugin for [Kaleidoscope][fw], adding a breathe LED effect. +![status][st:stable] [![Build Status][travis:image]][travis:status] - [fw]: https://github.com/keyboardio/Kaleidoscope + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Breathe.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Breathe + + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + +Provides a breathing effect for the keyboard. Breathe in, breathe out. + +## Using the extension + +To use the plugin, include the header, and tell the firmware to use it: + +```c++ +#include + +void setup() { + Kaleidoscope.use(&LEDBreatheEffect); + + Kaleidoscope.setup(); +} +``` + +## Plugin methods + +The plugin provides the `LEDBreatheEffect` object, which has no public methods or +properties, outside of those provided by all LED modes. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) From a78a89ed8baebb646351e144515a23c1626842d9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 20:29:31 +0200 Subject: [PATCH 288/792] library.properties: Fill out paragraph= too Signed-off-by: Gergely Nagy --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 1900dfa4..ab69a911 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent sentence=Rainbow LED effects for Kaleidoscope. -paragraph=... +paragraph=Provides two rainbow LED effects for Kaleidoscope. category=Communication url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-Rainbow architectures=avr From 0af034bde9e699cf18fdf9e65b3cbe4f3831ff0a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 21:00:17 +0200 Subject: [PATCH 289/792] README.md: Add a bit of documentation Signed-off-by: Gergely Nagy --- README.md | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d56ec4f7..a2c6fcc6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,42 @@ # Kaleidoscope-LEDEffect-Rainbow -This is a plugin for [Kaleidoscope][fw], adding some Rainbow LED effects. +![status][st:stable] [![Build Status][travis:image]][travis:status] - [fw]: https://github.com/keyboardio/Kaleidoscope + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Rainbow.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Rainbow + + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + +Two colorful rainbow effects are implemented by this plugin: one where the +rainbow waves through the keys, and another where the LEDs breathe though the +colors of a rainbow. The difference is that in the first case, we have all the +rainbow colors on display, and it waves through the keyboard. In the second +case, we have only one color at a time, for the whole board, and the color +cycles through the rainbow's palette. + +## Using the extension + +To use the plugin, include the header, and tell the firmware to use either (or +both!) of the effects: + +```c++ +#include + +void setup() { + Kaleidoscope.use(&LEDRainbowEffect, &LEDRainbowWaveEffect); + + Kaleidoscope.setup(); +} +``` + +## Plugin methods + +The plugin provides two objects: `LEDRainbowEffect`, and `LEDRainbowWaveEffect`, +neither of which have any public methods or properties, outside of those +provided by all LED modes. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) From f2bad8669c2a45b6e4658bee16f16512bc3c8890 Mon Sep 17 00:00:00 2001 From: James Cash Date: Fri, 16 Jun 2017 19:18:17 -0400 Subject: [PATCH 290/792] Minor copy-edits --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8d724250..b6d3f160 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 -Macros are a standard feature on many keyboards, and Kaleidoscope-powered ones +Macros are a standard feature on many keyboards and Kaleidoscope-powered ones are no exceptions. Macros are a way to have a single key-press do a whole lot of things under the hood: conventionally, macros play back a key sequence, but with -Kaleidoscope, there are many more we can do. Nevertheless, playing back a +Kaleidoscope, there is much more we can do. Nevertheless, playing back a sequence of events is still the primary use of macros. Playing back a sequence means that when we press a macro key, we can have it @@ -21,7 +21,7 @@ complicated shortcut - the possibilities are endless! ## Using the plugin -To use the plugin, we need to include the header, make sure we use the plugin, +To use the plugin, we need to include the header, make sure we `use` the plugin, place macros on the keymap, and create a special handler function (`macroAction`) that will tell the plugin what shall happen when macro keys are pressed. It is best illustrated with an example: @@ -109,7 +109,7 @@ The plugin provides a `Macros` object, with the following methods and properties ### `.row`, `.col` > The `row` and `col` properties describe the physical position a macro was -> triggered from - if it was triggered by a key, that is. The playback functions +> triggered from if it was triggered by a key. The playback functions > do not use these properties, but they are available, would one want to create > a macro that needs to know which key triggered it. From d0546744a9e0bb279e842473e2cdeb5442ee389a Mon Sep 17 00:00:00 2001 From: James Cash Date: Fri, 16 Jun 2017 19:25:57 -0400 Subject: [PATCH 291/792] Minor copy edits --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f000271a..ebd394c6 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,12 @@ [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 The `StalkerEffect` plugin provides an interesting new typing experience: the -LEDs light up as you tap keys, and play one of the selected effects: a haunting +LEDs light up as you tap keys and play one of the selected effects: a haunting trail of ghostly white lights, or a blazing trail of fire. ## Using the plugin -To use the plugin, one needs to include the header, and select the effect. +To use the plugin, one needs to include the header and select the effect. ```c++ #include @@ -33,8 +33,7 @@ void setup (){ It is recommended to place the activation of the plugin (the `USE_PLUGINS` call) as early as possible, so the plugin can catch all relevant key presses. The -configuration can happen at any time, but using the `STALKER` macro is highly -recommended. +configuration can happen at any time and should use the `STALKER` macro to do so. ## Plugin methods @@ -59,7 +58,7 @@ properties: ### `STALKER(effect, params)` > Returns an effect, to be used to assign a value the `.variant` property of the -> `StalkerEffect` object. Any arguments given to the macro, are also passed on +> `StalkerEffect` object. Any arguments given to the macro are passed on > to the effect. If the effect takes no arguments, use an empty `params` list. ## Plugin effects From f9ae733be501c59531884980507aa1157b7cd912 Mon Sep 17 00:00:00 2001 From: James Cash Date: Fri, 16 Jun 2017 19:48:37 -0400 Subject: [PATCH 292/792] Copy edits, symbol clarification --- README.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e5093f0a..8734aead 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ sweet animations, or just show off - the possibilities are almost endless! ## Using the plugin -To use the plugin, one needs to include the header, and one way or another, call -the `display` method. +To use the plugin, one needs to include the header, `use` the plugin, +and, one way or another, call the `display` method. ```c++ #include @@ -37,37 +37,40 @@ The plugin provides the `AlphaSquare` object, which has the following methods and properties: ### `.display(key)` -### `.display(key, row, col)` ### `.display(key, col)` +### `.display(key, row, col)` ### `.display(key, row, col, color)` > Display the symbol for `key` at the given row or column, with pixels set to > the specified `color`. If `row` is omitted, the first row - `0` is assumed. If -> the column is omitted too, then the third - `2` - column is used by default. +> the column is omitted, then the third column - `2` - is used. > If the `color` is omitted, the plugin will use the global `.color` property. > -> The plugin can display the English alphabet, and the numbers from 0 to 9. +> The plugin can display the English alphabet and the numbers from 0 to 9. ### `.display(symbol)` -### `.display(symbol, row, col)` ### `.display(symbol, col)` +### `.display(symbol, row, col)` ### `.display(symbol, row, col, color)` -> Almost the same as the previous function, but instead of a key, it expects a -> 4x4 bitmap. +> As the previous function, but instead of a key, it expects a 4x4 bitmap in +> the form of a 16-bit unsigned integer, where the low bit is the top-right +> corner, the second-lowest bit is to the right of that, and so on. +> +> The `SYM4x4` macro can be used to simplify creating these bitmaps. ### `.clear(key)`, `.clear(symbol)` ### `.clear(key, col)`, `.clear(symbol, col)` ### `.clear(key, col, row)`, `.clear(symbol, col, row)` > Just like the `.display()` counterparts, except these clear the symbol, by -> turning the LED pixels it is made up from, off. +> turning the LED pixels it is made up from off. ### `.color` > The color to use to draw the pixels. > -> Defaults to { 0x80, 0x80, 0x80 }. +> Defaults to `{ 0x80, 0x80, 0x80 }` (light gray). ## Plugin helpers @@ -79,7 +82,7 @@ and properties: ## Extra symbols -There is a growing number of extra symbols available in the +There is a growing number of pre-defined symbols available in the `kaleidoscope::alpha_square::symbols` namespace. Ok, growing may have been an exaggeration, there is only one as of this writing: From 500973eaf9f018a092a92a9015cb5e2e55ba7a19 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 17 Jun 2017 07:39:37 +0200 Subject: [PATCH 293/792] Fix ALPHASQUARE_SYMBOL_1 in the 3x4 font Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-AlphaSquare-3x4.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope/LED-AlphaSquare-3x4.h b/src/Kaleidoscope/LED-AlphaSquare-3x4.h index 1b244c26..84a0f526 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-3x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-3x4.h @@ -128,7 +128,7 @@ // --------------------- #define ALPHASQUARE_SYMBOL_1 SYM4x4(1, 1, 0, 0, \ 0, 1, 0, 0, \ - 0, 1, 0, 0, + 0, 1, 0, 0, \ 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_2 SYM4x4(1, 1, 0, 0, \ 0, 0, 1, 0, \ @@ -136,7 +136,7 @@ 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_3 SYM4x4(1, 1, 1, 0, \ 0, 1, 1, 0, \ - 0, 0, 1, 0, \ + 0, 0, 1, 0, \ 1, 1, 1, 0) #define ALPHASQUARE_SYMBOL_4 SYM4x4(1, 0, 1, 0, \ 1, 1, 1, 0, \ From 0808057864307ffdf02867eb8eac8edd30a26b57 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 17 Jun 2017 07:56:33 +0200 Subject: [PATCH 294/792] Documentation clarification Fixes #4. Signed-off-by: Gergely Nagy --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bc883b29..a0f82910 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ match one's desired behaviour. ## Using the plugin -To use the plugin, simply include the header, make sure the `MouseKeys` object -is properly used, and place mouse keys on your keymap. It is best illustrated -with an example: +To use the plugin, simply include the header in your Sketch, tell the firmware +to use the `MouseKeys` object, and place mouse keys on your keymap. It is best +illustrated with an example: ```c++ #include @@ -52,7 +52,8 @@ The simplest set of keys are the mouse cursor movement keys. These move the cursor one direction or the other, with speed and acceleration factored in. When a mouse cursor movement key is held down, it will move `.speed` pixels each `.speedDelay` milliseconds without acceleration. But when `.accelSpeed` is -non-zero (and it is not zero by default), the speed will increase by +non-zero (and it is not zero by default, +see [below](#accelspeed-and-acceldelay)), the speed will increase by `.accelSpeed` every `.accelDelay` milliseconds. Thus, unless configured otherwise, holding a direction will move that way at increasing speed. From 25093c7455ce40bc3b60c7d3c3064c69d136b35e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 17 Jun 2017 08:01:13 +0200 Subject: [PATCH 295/792] README.md: Improved the .row/.col documentation It now tells the reader that the value of `.row`/`.col` is unspecified if not triggered by a key. Addresses part of #9. Signed-off-by: Gergely Nagy --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b6d3f160..ee51a8e3 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ complicated shortcut - the possibilities are endless! ## Using the plugin -To use the plugin, we need to include the header, make sure we `use` the plugin, -place macros on the keymap, and create a special handler function +To use the plugin, we need to include the header, tell the firmware to `use` the +plugin, place macros on the keymap, and create a special handler function (`macroAction`) that will tell the plugin what shall happen when macro keys are pressed. It is best illustrated with an example: @@ -112,6 +112,9 @@ The plugin provides a `Macros` object, with the following methods and properties > triggered from if it was triggered by a key. The playback functions > do not use these properties, but they are available, would one want to create > a macro that needs to know which key triggered it. +> +> When the macro was not triggered by a key the value of these properties are +> unspecified. ## Macro helpers From 754647b6ca438dfc49bf9c32e13df00439660bba Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 17 Jun 2017 08:05:28 +0200 Subject: [PATCH 296/792] README.md: Improve the `MACRODOWN` docs Attempt to explain when and why to use it over `MACRO`. Fixes #9 together with the previous commit. Signed-off-by: Gergely Nagy --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index ee51a8e3..100b859e 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,11 @@ need to define them in a special way, using the `MACRO` helper (or its > That is, the macro will not be performed when the key is released, or held, or > not pressed at all. > +> Use this over `MACRO()` when you only want to perform an action when the key +> actuates, and no action should be taken when it is held, released, or when it +> is not pressed at all. For a lot of macros that emit a sequence without any +> other side effects, `MACRODOWN()` is usually the better choice. +> > Can only be used from the `macroAction()` overrideable method. ## `MACRO` steps From efa9cdf29154c657e00b88e30b4710f65a811ad7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 17 Jun 2017 08:07:43 +0200 Subject: [PATCH 297/792] Migrate to Kaleidoscope.use() Signed-off-by: Gergely Nagy --- README.md | 2 +- examples/LED-Stalker/LED-Stalker.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ebd394c6..5d103486 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ To use the plugin, one needs to include the header and select the effect. #include void setup (){ - USE_PLUGINS(&StalkerEffect); + Kaleidoscope.use(&StalkerEffect); Kaleidoscope.setup(); diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index 438ebac2..bbab98f8 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -41,7 +41,7 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { }; void setup() { - USE_PLUGINS(&LEDOff, &StalkerEffect); + Kaleidoscope.use(&LEDOff, &StalkerEffect); Kaleidoscope.setup(); From b3cb09268bd20275783b21d70537595d0e91841a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 17 Jun 2017 08:09:37 +0200 Subject: [PATCH 298/792] README.md: Clarify how colors can be specified While technically one can specify colors otherwise, for the sake of simplicity, mention only `CRGB`, but do mention it explicitly, so the reader does not need to look at the example to figure this out. Fixes #9. Signed-off-by: Gergely Nagy --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d103486..6ffdec09 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,8 @@ The plugin provides the following effects: ### `Haunt([color])` > A ghostly haunt effect, that trails the key taps with a ghostly white color -> (or any other color, if specified). +> (or any other color, if specified). Use the `CRGB(r,g,b)` macro to specify the +> color, if you want something else than the ghostly white. ### `BlazingTrail()` From 9317ec61e2f569481016bb9f994362e43f656753 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 17 Jun 2017 08:20:46 +0200 Subject: [PATCH 299/792] Migrate from USE_PLUGINS to Kaleidoscope.use Signed-off-by: Gergely Nagy --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 2 +- src/Kaleidoscope/AlphaSquare-Effect.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index 5e7af7b6..ca3a80e8 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -94,7 +94,7 @@ const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) { } void setup() { - USE_PLUGINS(&AlphaSquare, &AlphaSquareEffect, &Macros); + Kaleidoscope.use(&AlphaSquare, &AlphaSquareEffect, &Macros); Kaleidoscope.setup(); diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index a8b71871..47c4c28c 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -31,7 +31,7 @@ AlphaSquareEffect::AlphaSquareEffect(void) { void AlphaSquareEffect::begin(void) { Kaleidoscope.useEventHandlerHook(eventHandlerHook); - Kaleidoscope.use(&LEDControl, NULL); + Kaleidoscope.use(&LEDControl); us_ = LEDControl.mode_add(this); } From db8acdd520e7b2e43e32b05c84857b9eeeebae5c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 17 Jun 2017 08:24:25 +0200 Subject: [PATCH 300/792] README.md: Further clarifications Fixes #5. Signed-off-by: Gergely Nagy --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8734aead..82b6b5c2 100644 --- a/README.md +++ b/README.md @@ -15,15 +15,16 @@ sweet animations, or just show off - the possibilities are almost endless! ## Using the plugin -To use the plugin, one needs to include the header, `use` the plugin, -and, one way or another, call the `display` method. +To use the plugin, one needs to include the header in their Sketch, tell the +firmware to `use` the plugin, and one way or another, call the `display` method. +This can be done from a macro, or via the `AlphaSquareEffect` LED mode. ```c++ #include #include void setup() { - USE_PLUGINS(&AlphaSquare); + Kaleidoscope.use(&AlphaSquare, &AlphaSquareEffect); Kaleidoscope.setup(); @@ -33,8 +34,9 @@ void setup() { ## Plugin methods -The plugin provides the `AlphaSquare` object, which has the following methods -and properties: +The plugin provides the `AlphaSquare` object, which has its methods and +properties listed below, and an `AlphaSquareEffect` LED mode, which has no +methods or properties other than those provided by all LED modes. ### `.display(key)` ### `.display(key, col)` @@ -46,7 +48,11 @@ and properties: > the column is omitted, then the third column - `2` - is used. > If the `color` is omitted, the plugin will use the global `.color` property. > -> The plugin can display the English alphabet and the numbers from 0 to 9. +> The plugin can display the English alphabet, and the numbers from 0 to 9. The +> symbol will be drawn with the top-left corner at the given position. +> +> Please consult the appropriate hardware library of your keyboard to see how +> keys are laid out in rows and columns. ### `.display(symbol)` ### `.display(symbol, col)` From c8586985fdead83cb8ce4f85374e581952a801d8 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 21 Jun 2017 12:41:19 +0800 Subject: [PATCH 301/792] Add toggling on of the on-board green status LEDs. The factory needs this to verify the hardware during build --- src/Kaleidoscope-Model01-TestMode.cpp | 10 +++++++++- src/Kaleidoscope-Model01-TestMode.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 01c96e54..68f13c1f 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -1,7 +1,8 @@ #include "Kaleidoscope.h" #include "Kaleidoscope-Model01-TestMode.h" #include "Kaleidoscope-LEDEffect-Rainbow.h" - +#include +#include cRGB red; cRGB blue; cRGB green; @@ -110,8 +111,15 @@ void TestMode_::test_matrix() { } } +void TestMode_::toggle_programming_leds_on() { + PORTD |= (1<<5); + PORTB |= (1<<0); +} + void TestMode_::run_tests() { // Serial.println("Running tests"); + toggle_programming_leds_on(); + test_leds(); test_matrix(); // Serial.println("Done running tests"); diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index f9a0fb02..95a3275e 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -14,6 +14,7 @@ class TestMode_ : public KaleidoscopePlugin { static void run_tests(); static void test_leds(); static void test_matrix(); + static void toggle_programming_leds_on(); static void wait_for_keypress(); static void loopHook(bool postClear); static void set_leds(uint8_t r, uint8_t g, uint8_t b); From 95bd188a544338fbb58011816d7743b5d038b28c Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 21 Jun 2017 12:42:26 +0800 Subject: [PATCH 302/792] Make cpplint-noisy happy --- src/Kaleidoscope-Model01-TestMode.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 68f13c1f..e3c709b6 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -16,7 +16,6 @@ void TestMode_::begin(void) { blue.b = 201; green.g = 201; loop_hook_use(this->loopHook); - } void TestMode_::loopHook(bool postClear) { @@ -38,14 +37,12 @@ void TestMode_::wait_for_keypress() { break; } } - } void TestMode_::set_leds(uint8_t r, uint8_t g, uint8_t b) { LEDControl.set_all_leds_to(r, g, b); LEDControl.led_sync(); wait_for_keypress(); - } void TestMode_::test_leds(void) { @@ -77,7 +74,6 @@ void TestMode_::test_matrix() { } for (byte row = 0; row < 4; row++) { for (byte col = 0; col < 8; col++) { - uint8_t keynum = (row * 8) + (col); uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | From 51f37933f380b826e05a9587d808824d00088d64 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 21 Jun 2017 13:06:09 +0800 Subject: [PATCH 303/792] astyle 3.0 caught this style violation --- src/Kaleidoscope-Model01-TestMode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index e3c709b6..1d7175eb 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -108,8 +108,8 @@ void TestMode_::test_matrix() { } void TestMode_::toggle_programming_leds_on() { - PORTD |= (1<<5); - PORTB |= (1<<0); + PORTD |= (1 << 5); + PORTB |= (1 << 0); } void TestMode_::run_tests() { From 98bf56d09734ae1a61f22fc3dc6f3168ddbc73bd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 2 Jul 2017 18:22:01 +0200 Subject: [PATCH 304/792] Instead of acting as a strange LED mode, use a loop hook instead Having the LED effects of the NumLock layer as a special LED mode has a number of drawbacks, like not interacting well with led mode switching: one can't get back to the NumLock effect once switching away from it (but the mode remains active nevertheless). To avoid this and other issues, don't make the effect a LED mode. Instead, override the active LED mode with the numlock layer colors. This way, it is always in sync with the layer. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 30 ++++++++---------------------- src/Kaleidoscope-Numlock.h | 8 ++------ 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 1fc5ba7f..13bdf58c 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -3,31 +3,22 @@ #include "Kaleidoscope.h" #include "layers.h" -uint8_t NumLock_::previousLEDMode; -uint8_t NumLock_::us; bool NumLock_::isActive; byte NumLock_::row = 255, NumLock_::col = 255; -cRGB numpad_color; +cRGB numpad_color = CRGB(255, 0, 0); NumLock_::NumLock_(void) { } -void -NumLock_::begin(void) { - us = LEDControl.mode_add(this); - numpad_color.r = 255; +void NumLock_::begin(void) { + loop_hook_use(loopHook); } -void -NumLock_::init(void) { - if (!isActive) { - LEDControl.next_mode(); - } -} +void NumLock_::loopHook(bool postClear) { + if (!postClear || !isActive) + return; -void -NumLock_::update(void) { for (uint8_t r = 0; r < ROWS; r++) { for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookup(r, c); @@ -46,21 +37,16 @@ NumLock_::update(void) { LEDControl.led_set_crgb_at(row, col, color); } -const macro_t * -NumLock_::toggle(byte row_, byte col_, uint8_t numPadLayer) { +const macro_t *NumLock_::toggle(byte row_, byte col_, uint8_t numPadLayer) { row = row_; col = col_; if (Layer.isOn(numPadLayer)) { - isActive = false; - LEDControl.set_mode(previousLEDMode); Layer.off(numPadLayer); } else { - isActive = true; - previousLEDMode = LEDControl.get_mode(); - LEDControl.set_mode(us); Layer.on(numPadLayer); } + isActive = Layer.isOn(numPadLayer); return MACRO(T(KeypadNumLock), END); } diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-Numlock.h index eaa448b4..47b2a77e 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -7,20 +7,16 @@ #define TOGGLENUMLOCK 0 #define Key_ToggleNumlock M(TOGGLENUMLOCK) -class NumLock_ : public LEDMode { +class NumLock_ : public KaleidoscopePlugin { public: NumLock_(void); void begin(void) final; - void update(void) final; - void init(void) final; - static const macro_t *toggle(byte row, byte col, uint8_t numPadLayer); + static void loopHook(const bool postClear); private: - static uint8_t previousLEDMode; - static uint8_t us; static bool isActive; static byte row, col; }; From b6461e5f40b50f43e522dffd12113edeca7532ff Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 2 Jul 2017 18:37:54 +0200 Subject: [PATCH 305/792] Add LEDControl.init_mode() The new `init_mode()` method simply (re-)inits the current mode. Useful when a plugin that changes LEDs outside of LED modes wants to reset the active LED mode. Doubly useful when the active LED mode does all the work in its `init()` method. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 6 ++++++ src/Kaleidoscope-LEDControl.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index bdc76ba4..2cd78393 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -51,6 +51,12 @@ LEDControl_::update(void) { previousMode = mode; } +void +LEDControl_::init_mode(void) { + if (modes[mode]) + (modes[mode]->init)(); +} + void LEDControl_::set_mode(uint8_t mode_) { if (mode_ < LED_MAX_MODES) diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 6dbf92f7..528e147d 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -28,6 +28,7 @@ class LEDControl_ : public KaleidoscopePlugin { static void update(void); static void set_mode(uint8_t mode); static uint8_t get_mode(); + static void init_mode(void); static int8_t mode_add(LEDMode *mode); From 40328cd34262d2779a1ab8b980901c3d15dceba7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 2 Jul 2017 18:42:07 +0200 Subject: [PATCH 306/792] Re-init the active LED mode when NumLock is turned off To make sure that the active LED mode is restored to a good state, re-init it. Without this change, LED modes that do all their work in the `init()` method will not refresh when NumLock is turned off. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 13bdf58c..e5e19f4b 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -43,6 +43,7 @@ const macro_t *NumLock_::toggle(byte row_, byte col_, uint8_t numPadLayer) { if (Layer.isOn(numPadLayer)) { Layer.off(numPadLayer); + LEDControl.init_mode(); } else { Layer.on(numPadLayer); } From f2d3d91a733a10c83c4ae89c279bb942a8cf0fd9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 2 Jul 2017 22:40:01 +0200 Subject: [PATCH 307/792] Simplify the API Instead of requiring the NumLock key row and column, and the numpad layer index to be passed to `NumLock.toggle` on every call, derive the first two from Macros.row and Macros.col respectively, and the latter from a new class variable, which should be set in the `setup()` method of the sketch. This way, `NumLock.toggle()` becomes argument-less. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 12 +++++------- src/Kaleidoscope-Numlock.h | 5 +++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index e5e19f4b..decee6d9 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -3,11 +3,10 @@ #include "Kaleidoscope.h" #include "layers.h" -bool NumLock_::isActive; byte NumLock_::row = 255, NumLock_::col = 255; +uint8_t NumLock_::numPadLayer; cRGB numpad_color = CRGB(255, 0, 0); - NumLock_::NumLock_(void) { } @@ -16,7 +15,7 @@ void NumLock_::begin(void) { } void NumLock_::loopHook(bool postClear) { - if (!postClear || !isActive) + if (!postClear || !Layer.isOn(numPadLayer)) return; for (uint8_t r = 0; r < ROWS; r++) { @@ -37,9 +36,9 @@ void NumLock_::loopHook(bool postClear) { LEDControl.led_set_crgb_at(row, col, color); } -const macro_t *NumLock_::toggle(byte row_, byte col_, uint8_t numPadLayer) { - row = row_; - col = col_; +const macro_t *NumLock_::toggle() { + row = Macros.row; + col = Macros.col; if (Layer.isOn(numPadLayer)) { Layer.off(numPadLayer); @@ -47,7 +46,6 @@ const macro_t *NumLock_::toggle(byte row_, byte col_, uint8_t numPadLayer) { } else { Layer.on(numPadLayer); } - isActive = Layer.isOn(numPadLayer); return MACRO(T(KeypadNumLock), END); } diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-Numlock.h index 47b2a77e..1c9ebee4 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -13,11 +13,12 @@ class NumLock_ : public KaleidoscopePlugin { void begin(void) final; - static const macro_t *toggle(byte row, byte col, uint8_t numPadLayer); + static const macro_t *toggle(); static void loopHook(const bool postClear); + static uint8_t numPadLayer; + private: - static bool isActive; static byte row, col; }; From ebd9f35d62b3a30fd29ab31fd26f7cb67cd08601 Mon Sep 17 00:00:00 2001 From: Craig Disselkoen Date: Sat, 22 Jul 2017 13:54:42 -0700 Subject: [PATCH 308/792] Automatically add END to invocations of MACRO() and friends Requiring end-users to terminate macros with END strikes me as easy to mess up, and perhaps inelegant. This commit removes the requirement for end-users to terminate macros with END. As a result of this commit, end-users (including other plugins) who do use END will see a tiny amount of increased code size (1 byte per declared macro I believe), but functionality remains intact. Usage of END is hereby deprecated, and eventually #define END may be removed in a future commit. README.md has been modified with the new usage instructions, and a note that usage of END is deprecated. --- README.md | 21 ++++++++------------- src/MacroSteps.h | 2 +- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 100b859e..783ac7b1 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,7 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { D(LeftShift), T(M), U(LeftShift), T(O), T(D), T(E), T(L), T(Spacebar), W(100), - T(0), T(1), - END); + T(0), T(1) ); case MACRO_HELLO: if (key_toggled_on(keyState)) { Macros.type(PSTR("Hello world!")); @@ -128,8 +127,10 @@ need to define them in a special way, using the `MACRO` helper (or its > Defines a macro, that is built up from `steps` (explained below). The plugin > will iterate through the sequence, and re-play the steps in order. > -> The sequence must end with the `END` step, otherwise the playback will not be -> able to stop, and will have unpredictable behaviour. +> Note: In older versions of the Macros plugin, the sequence of steps had to end +> with a special step called END. This is no longer required. Existing macros +> that end with END will still work correctly, but new code should not use END; +> usage of END is deprecated. ### `MACRODOWN(steps...)` @@ -147,7 +148,7 @@ need to define them in a special way, using the `MACRO` helper (or its ## `MACRO` steps -Macro steps can be divided into three groups: +Macro steps can be divided into two groups: ### Delays @@ -162,20 +163,14 @@ Macro steps can be divided into three groups: Key event steps have two variants: one that prefixes its argument with `Key_`, and one that does not. The latter are the `Dr`, `Ur`, and `Tr` variants. In most cases, one is likely to use normal keys for the steps, so the `D`, `U`, and `T` -steps apply the `Key_` prefix. This allows us to write `MACRO(T(X), END)` -instead of `MACRO(Tr(Key_X), END)` - making the macro definition shorter, and +steps apply the `Key_` prefix. This allows us to write `MACRO(T(X))` +instead of `MACRO(Tr(Key_X))` - making the macro definition shorter, and more readable. * `D(key)`, `Dr(key)`: Simulates a key being pressed (pushed down). * `U(key)`, `Ur(key)`: Simulates a key being released (going up). * `T(key)`, `Tr(key)`: Simulates a key being tapped (pressed first, then released). -### The End - -* `END`: Signals the end of the macro. Anything past this step will be ignored. - But without this step, the plugin will continue trying to play the macro - further, and have unpredictable results. - ## Overrideable methods ### `macroAction(macroIndex, keyState)` diff --git a/src/MacroSteps.h b/src/MacroSteps.h index be21676f..242ba91a 100644 --- a/src/MacroSteps.h +++ b/src/MacroSteps.h @@ -18,7 +18,7 @@ typedef enum { typedef uint8_t macro_t; #define MACRO_NONE 0 -#define MACRO(...) ({static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; }) +#define MACRO(...) ({static const macro_t __m[] PROGMEM = { __VA_ARGS__, MACRO_ACTION_END }; &__m[0]; }) #define MACRODOWN(...) (key_toggled_on(keyState) ? MACRO(__VA_ARGS__) : MACRO_NONE) #define I(n) MACRO_ACTION_STEP_INTERVAL, n From c6af9a17e38a4c79de3ba258c234dd8258221906 Mon Sep 17 00:00:00 2001 From: Craig Disselkoen Date: Sat, 22 Jul 2017 14:32:40 -0700 Subject: [PATCH 309/792] Remove internal usage of END macro, in favor of MACRO_ACTION_END --- src/Kaleidoscope-Macros.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 7688b1ba..85756494 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -23,7 +23,7 @@ static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t ke } void Macros_::play(const macro_t *macro_p) { - macro_t macro = END; + macro_t macro = MACRO_ACTION_END; uint8_t interval = 0; uint8_t flags; @@ -63,7 +63,7 @@ void Macros_::play(const macro_t *macro_p) { readKeyCodeAndPlay(macro_p++, 0, IS_PRESSED | WAS_PRESSED); break; - case END: + case MACRO_ACTION_END: default: return; } From 4e46843f32b7709e03277e4162168facf0db4a52 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 23 Jul 2017 13:00:21 -0700 Subject: [PATCH 310/792] LED_G was missing. Caught by @cdisselkoen++ --- src/Kaleidoscope-Hardware-Model01.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 5a12845d..929d5db6 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -135,7 +135,7 @@ class Model01 { #define LED_4 19 #define LED_5 20 #define LED_T 21 -#define LED_REC_MACRO 22 +#define LED_G 22 #define LED_B 23 #define LED_ESC 24 #define LED_TAB 25 From ff4b316f769bb8ce5249d3f84f744dfc3bac5652 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 23 Jul 2017 13:01:07 -0700 Subject: [PATCH 311/792] REC became PROG and LED and PROG switched places for mass production --- src/Kaleidoscope-Hardware-Model01.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 929d5db6..fbe07bce 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -116,7 +116,7 @@ class Model01 { #define LED_PGDN 0 #define LED_PGUP 1 #define LED_BACKTICK 2 -#define LED_LED 3 +#define LED_PROG 3 #define LED_1 4 #define LED_Q 5 #define LED_A 6 @@ -139,7 +139,7 @@ class Model01 { #define LED_B 23 #define LED_ESC 24 #define LED_TAB 25 -#define LED_REC 26 +#define LED_LED 26 #define LED_L_FN 27 #define LED_L_CTRL 28 #define LED_DEL 29 From 2d7388e42fee27f16e6e2382a6495509d559eaa1 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 13:49:10 -0700 Subject: [PATCH 312/792] Update to 'new' keyswitch state API --- src/Kaleidoscope-MouseKeys.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 7a6017b6..5f49678c 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -76,25 +76,25 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS if (mappedKey.keyCode & KEY_MOUSE_BUTTON && !(mappedKey.keyCode & KEY_MOUSE_WARP)) { uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; - if (key_toggled_on(keyState)) { + if (keyToggledOn(keyState)) { MouseWrapper.press_button(button); - } else if (key_toggled_off(keyState)) { + } else if (keyToggledOff(keyState)) { MouseWrapper.release_button(button); } } else if (!(mappedKey.keyCode & KEY_MOUSE_WARP)) { - if (key_toggled_on(keyState)) { + if (keyToggledOn(keyState)) { endTime = millis() + speedDelay; accelEndTime = millis() + accelDelay; wheelEndTime = 0; } - if (key_is_pressed(keyState)) { + if (keyIsPressed(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { scrollWheel(mappedKey.keyCode); } else { mouseMoveIntent |= mappedKey.keyCode; } } - } else if (key_toggled_on(keyState)) { + } else if (keyToggledOn(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { // we don't pass in the left and up values because those are the // default, "no-op" conditionals From a8faa2d594858438e53233be3b3c05978d9f9246 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 13:51:14 -0700 Subject: [PATCH 313/792] Switch to new key toggle API --- src/Kaleidoscope-LEDControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 2cd78393..fd483ea0 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -144,7 +144,7 @@ LEDControl_::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) return mappedKey; - if (key_toggled_on(keyState)) + if (keyToggledOn(keyState)) LEDControl.next_mode(); return Key_NoKey; From f30af4d85d0f6322d0c9b3a2273d6720468775ce Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 13:59:44 -0700 Subject: [PATCH 314/792] keyToggledO* camelcasing --- README.md | 4 ++-- src/MacroSteps.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 783ac7b1..9462f369 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,12 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { W(100), T(0), T(1) ); case MACRO_HELLO: - if (key_toggled_on(keyState)) { + if (keyToggledOn(keyState)) { Macros.type(PSTR("Hello world!")); } break; case MACRO_SPECIAL: - if (key_toggled_on(keyState)) { + if (keyToggledOn(keyState)) { // Do something special } break; diff --git a/src/MacroSteps.h b/src/MacroSteps.h index 242ba91a..79e88f36 100644 --- a/src/MacroSteps.h +++ b/src/MacroSteps.h @@ -19,7 +19,7 @@ typedef uint8_t macro_t; #define MACRO_NONE 0 #define MACRO(...) ({static const macro_t __m[] PROGMEM = { __VA_ARGS__, MACRO_ACTION_END }; &__m[0]; }) -#define MACRODOWN(...) (key_toggled_on(keyState) ? MACRO(__VA_ARGS__) : MACRO_NONE) +#define MACRODOWN(...) (keyToggledOn(keyState) ? MACRO(__VA_ARGS__) : MACRO_NONE) #define I(n) MACRO_ACTION_STEP_INTERVAL, n #define W(n) MACRO_ACTION_STEP_WAIT, n From e6de1441989b8526ef3d926d99bf563765b6bcf1 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:00:23 -0700 Subject: [PATCH 315/792] keyToggledO* camelcasing --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index ca3a80e8..66107d79 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -42,7 +42,7 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { }; const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) { - if (!key_toggled_on(key_state)) + if (!keyToggledOn(key_state)) return MACRO_NONE; if (macro_index == 0) { From b3f1371fb5cb929ed95e64fcc1382d8a8352f2e4 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:14:51 -0700 Subject: [PATCH 316/792] CamelCase of KeyIsPressed and KeyWasPressed --- src/Kaleidoscope/LED-Stalker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index e48b572d..5826dfde 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -42,7 +42,7 @@ Key StalkerEffect::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t if (row >= ROWS || col >= COLS) return mapped_key; - if (key_is_pressed(key_state)) { + if (keyIsPressed(key_state)) { map_[row][col] = 0xff; } From 08501e59e06e0e97c66a24348700a13bb2cbcda5 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:15:04 -0700 Subject: [PATCH 317/792] CamelCase of KeyIsPressed and KeyWasPressed --- src/Kaleidoscope/AlphaSquare-Effect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index 47c4c28c..c960e104 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -58,7 +58,7 @@ AlphaSquareEffect::eventHandlerHook(Key key, byte row, byte col, uint8_t key_sta if (key < Key_A || key > Key_0) return key; - if (!key_is_pressed(key_state)) + if (!keyIsPressed(key_state)) return key; uint8_t display_col = 2; From 09e596a8a2db0e2c8521b624c2b76dc8ed5772a4 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:37:14 -0700 Subject: [PATCH 318/792] CamelCase of handle_*_key* --- src/Kaleidoscope-Hardware-Model01.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index c51b9661..fcf0795e 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -165,12 +165,12 @@ void Model01::act_on_matrix_scan() { uint8_t keyState = (bitRead(previousLeftHandState.all, keynum) << 0) | (bitRead(leftHandState.all, keynum) << 1); - handle_keyswitch_event(Key_NoKey, row, 7 - col, keyState); + handleKeyswitchEvent(Key_NoKey, row, 7 - col, keyState); keyState = (bitRead(previousRightHandState.all, keynum) << 0) | (bitRead(rightHandState.all, keynum) << 1); - handle_keyswitch_event(Key_NoKey, row, (15 - col), keyState); + handleKeyswitchEvent(Key_NoKey, row, (15 - col), keyState); } } } From 66ff95877dca5e81cdc4c4ea79142556468d5cf8 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:37:38 -0700 Subject: [PATCH 319/792] CamelCase of handle_*_key* --- src/Kaleidoscope-Macros.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 85756494..48f950a5 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -13,11 +13,11 @@ static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t ke key.keyCode = pgm_read_byte(macro_p++); if (keyStates & IS_PRESSED) { - handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); + handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); Keyboard.sendReport(); } if (keyStates & WAS_PRESSED) { - handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); + handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); Keyboard.sendReport(); } } @@ -162,9 +162,9 @@ void Macros_::type(const char *string) { if (key.raw == Key_NoKey.raw) continue; - handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); + handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); Keyboard.sendReport(); - handle_keyswitch_event(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); + handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); Keyboard.sendReport(); } } From 6b850c140d4ba9e25b92594339e86583fda50e79 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:39:54 -0700 Subject: [PATCH 320/792] Switch Macros to use an API rather than doing its own bitmath --- src/Kaleidoscope-Macros.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 48f950a5..2ea5954d 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -12,11 +12,11 @@ static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t ke key.flags = flags; key.keyCode = pgm_read_byte(macro_p++); - if (keyStates & IS_PRESSED) { + if (keyIsPressed(keyStates)) { handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); Keyboard.sendReport(); } - if (keyStates & WAS_PRESSED) { + if (keyWasPressed(keyStates)) { handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); Keyboard.sendReport(); } From ee0ccdd91d8d167b8544df82c0ec267ce603667a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:40:51 -0700 Subject: [PATCH 321/792] CamelCase of handle_*_key* --- src/Kaleidoscope-Model01-TestMode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 95a3275e..efd00026 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -22,4 +22,4 @@ class TestMode_ : public KaleidoscopePlugin { extern TestMode_ TestMode; -Key handle_keyswitch_event_test(Key mappedKey, byte row, byte col, uint8_t keyState); +Key handleKeyswitchEvent_test(Key mappedKey, byte row, byte col, uint8_t keyState); From b65f1753437a49d409a9db67d760bc9f9dc53cb1 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:58:57 -0700 Subject: [PATCH 322/792] CamelCaseifcation of LED related functions s/led_set_crgb_at/setCrgbAt/ s/hsv_to_rgb/hsvToRgb/ s/led_get_crgb_at/getCrgbAt/ s/led_sync/syncLeds/ s/get_led_index/getLedIndex/ s/send_led_data/sendLedData/ s/led_power_fault/ledPowerFault/ --- src/Kaleidoscope-Hardware-Model01.cpp | 18 +++++++++--------- src/Kaleidoscope-Hardware-Model01.h | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index fcf0795e..a22fc21b 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -61,14 +61,14 @@ void Model01::setup(void) { } -void Model01::led_set_crgb_at(uint8_t i, cRGB crgb) { +void Model01::setCrgbAt(uint8_t i, cRGB crgb) { if (i < 32) { - cRGB oldColor = led_get_crgb_at(i); + cRGB oldColor = getCrgbAt(i); isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); leftHand.ledData.leds[i] = crgb; } else if (i < 64) { - cRGB oldColor = led_get_crgb_at(i); + cRGB oldColor = getCrgbAt(i); isLEDChanged |= !(oldColor.r == crgb.r && oldColor.g == crgb.g && oldColor.b == crgb.b); rightHand.ledData.leds[i - 32] = crgb; @@ -79,15 +79,15 @@ void Model01::led_set_crgb_at(uint8_t i, cRGB crgb) { } } -void Model01::led_set_crgb_at(byte row, byte col, cRGB color) { - led_set_crgb_at(key_led_map[row][col], color); +void Model01::setCrgbAt(byte row, byte col, cRGB color) { + setCrgbAt(key_led_map[row][col], color); } -uint8_t Model01::get_led_index(byte row, byte col) { +uint8_t Model01::getLedIndex(byte row, byte col) { return key_led_map[row][col]; } -cRGB Model01::led_get_crgb_at(uint8_t i) { +cRGB Model01::getCrgbAt(uint8_t i) { if (i < 32) { return leftHand.ledData.leds[i]; } else if (i < 64) { @@ -97,7 +97,7 @@ cRGB Model01::led_get_crgb_at(uint8_t i) { } } -void Model01::led_sync() { +void Model01::syncLeds() { if (!isLEDChanged) return; @@ -116,7 +116,7 @@ void Model01::led_sync() { isLEDChanged = false; } -boolean Model01::led_power_fault() { +boolean Model01::ledPowerFault() { if (PINB & _BV(4)) { return true; } else { diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index fbe07bce..4ed076cd 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -13,12 +13,12 @@ class Model01 { public: Model01(void); - void led_sync(void); - void led_set_crgb_at(byte row, byte col, cRGB color); - void led_set_crgb_at(uint8_t i, cRGB crgb); - cRGB led_get_crgb_at(uint8_t i); + void syncLeds(void); + void setCrgbAt(byte row, byte col, cRGB color); + void setCrgbAt(uint8_t i, cRGB crgb); + cRGB getCrgbAt(uint8_t i); cRGB get_key_color(byte row, byte col); - uint8_t get_led_index(byte row, byte col); + uint8_t getLedIndex(byte row, byte col); void scan_matrix(void); void read_matrix(void); @@ -28,7 +28,7 @@ class Model01 { void enable_scanner_power(void); void reboot_bootloader(); - boolean led_power_fault(void); + boolean ledPowerFault(void); keydata_t leftHandState; keydata_t rightHandState; From 769470fbd643ce1e1348c8a083adafc3959b9b4d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:59:03 -0700 Subject: [PATCH 323/792] CamelCaseifcation of LED related functions s/led_set_crgb_at/setCrgbAt/ s/hsv_to_rgb/hsvToRgb/ s/led_get_crgb_at/getCrgbAt/ s/led_sync/syncLeds/ s/get_led_index/getLedIndex/ s/send_led_data/sendLedData/ s/led_power_fault/ledPowerFault/ --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 4 ++-- src/Kaleidoscope/LED-AlphaSquare.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index 66107d79..cabbdcce 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -48,7 +48,7 @@ const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) { if (macro_index == 0) { for (uint8_t i = Key_A.keyCode; i <= Key_0.keyCode; i++) { LEDControl.set_all_leds_to(0, 0, 0); - LEDControl.led_sync(); + LEDControl.syncLeds(); delay(100); uint8_t col = 2; @@ -69,7 +69,7 @@ const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) { } LEDControl.set_all_leds_to(0, 0, 0); - LEDControl.led_sync(); + LEDControl.syncLeds(); delay(100); for (uint8_t step = 0; step <= 0xf0; step += 8) { diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 2376231a..5327af83 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -90,11 +90,11 @@ void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col, cRGB key_co if (!pixel) continue; - LEDControl.led_set_crgb_at(row + r, col + c, key_color); + LEDControl.setCrgbAt(row + r, col + c, key_color); } } - LEDControl.led_sync(); + LEDControl.syncLeds(); } void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col) { From a84060e8d10b05c42fb4b0145418d34f79e89d1f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:59:04 -0700 Subject: [PATCH 324/792] CamelCaseifcation of LED related functions s/led_set_crgb_at/setCrgbAt/ s/hsv_to_rgb/hsvToRgb/ s/led_get_crgb_at/getCrgbAt/ s/led_sync/syncLeds/ s/get_led_index/getLedIndex/ s/send_led_data/sendLedData/ s/led_power_fault/ledPowerFault/ --- src/BootAnimation.cpp | 8 ++++---- src/Kaleidoscope-LEDControl.cpp | 28 ++++++++++++++-------------- src/Kaleidoscope-LEDControl.h | 8 ++++---- src/LEDUtils.cpp | 4 ++-- src/LEDUtils.h | 2 +- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/BootAnimation.cpp b/src/BootAnimation.cpp index be4d9cd4..396d438e 100644 --- a/src/BootAnimation.cpp +++ b/src/BootAnimation.cpp @@ -4,11 +4,11 @@ #ifdef ARDUINO_AVR_MODEL01 static void type_letter(uint8_t letter) { - LEDControl.led_set_crgb_at(letter, {255, 0, 0}); - LEDControl.led_sync(); + LEDControl.setCrgbAt(letter, {255, 0, 0}); + LEDControl.syncLeds(); delay(250); - LEDControl.led_set_crgb_at(letter, {0, 0, 0}); - LEDControl.led_sync(); + LEDControl.setCrgbAt(letter, {0, 0, 0}); + LEDControl.syncLeds(); delay(10); } #endif diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index fd483ea0..c0c1e2ce 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -100,28 +100,28 @@ LEDControl_::set_all_leds_to(uint8_t r, uint8_t g, uint8_t b) { void LEDControl_::set_all_leds_to(cRGB color) { for (uint8_t i = 0; i < LED_COUNT; i++) { - led_set_crgb_at(i, color); + setCrgbAt(i, color); } } void -LEDControl_::led_set_crgb_at(uint8_t i, cRGB crgb) { - KeyboardHardware.led_set_crgb_at(i, crgb); +LEDControl_::setCrgbAt(uint8_t i, cRGB crgb) { + KeyboardHardware.setCrgbAt(i, crgb); } void -LEDControl_::led_set_crgb_at(byte row, byte col, cRGB color) { - KeyboardHardware.led_set_crgb_at(row, col, color); +LEDControl_::setCrgbAt(byte row, byte col, cRGB color) { + KeyboardHardware.setCrgbAt(row, col, color); } cRGB -LEDControl_::led_get_crgb_at(uint8_t i) { - return KeyboardHardware.led_get_crgb_at(i); +LEDControl_::getCrgbAt(uint8_t i) { + return KeyboardHardware.getCrgbAt(i); } void -LEDControl_::led_sync(void) { - KeyboardHardware.led_sync(); +LEDControl_::syncLeds(void) { + KeyboardHardware.syncLeds(); } void @@ -156,7 +156,7 @@ LEDControl_::loopHook(bool postClear) { return; if (millis() > syncTimer) { - led_sync(); + syncLeds(); syncTimer = millis() + syncDelay; } update(); @@ -189,7 +189,7 @@ LEDControl_::focusHook(const char *command) { uint8_t idx = Serial.parseInt(); if (Serial.peek() == '\n') { - cRGB c = LEDControl.led_get_crgb_at(idx); + cRGB c = LEDControl.getCrgbAt(idx); Focus.printColor(c.r, c.g, c.b); Serial.println(); @@ -200,7 +200,7 @@ LEDControl_::focusHook(const char *command) { c.g = Serial.parseInt(); c.b = Serial.parseInt(); - LEDControl.led_set_crgb_at(idx, c); + LEDControl.setCrgbAt(idx, c); } break; } @@ -235,7 +235,7 @@ LEDControl_::focusHook(const char *command) { case THEME: { if (Serial.peek() == '\n') { for (uint8_t idx = 0; idx < LED_COUNT; idx++) { - cRGB c = LEDControl.led_get_crgb_at(idx); + cRGB c = LEDControl.getCrgbAt(idx); Focus.printColor(c.r, c.g, c.b); Focus.printSpace(); @@ -252,7 +252,7 @@ LEDControl_::focusHook(const char *command) { color.g = Serial.parseInt(); color.b = Serial.parseInt(); - LEDControl.led_set_crgb_at(idx, color); + LEDControl.setCrgbAt(idx, color); idx++; } break; diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 528e147d..5ece0b2a 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -32,10 +32,10 @@ class LEDControl_ : public KaleidoscopePlugin { static int8_t mode_add(LEDMode *mode); - static void led_set_crgb_at(uint8_t i, cRGB crgb); - static void led_set_crgb_at(byte row, byte col, cRGB color); - static cRGB led_get_crgb_at(uint8_t i); - static void led_sync(void); + static void setCrgbAt(uint8_t i, cRGB crgb); + static void setCrgbAt(byte row, byte col, cRGB color); + static cRGB getCrgbAt(uint8_t i); + static void syncLeds(void); static void set_all_leds_to(uint8_t r, uint8_t g, uint8_t b); static void set_all_leds_to(cRGB color); diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp index c4cc98fc..c8e98940 100644 --- a/src/LEDUtils.cpp +++ b/src/LEDUtils.cpp @@ -17,14 +17,14 @@ breath_compute() { i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + 2; - return hsv_to_rgb(200, 255, i); + return hsvToRgb(200, 255, i); } // From http://web.mit.edu/storborg/Public/hsvtorgb.c - talk to Scott about licensing cRGB -hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v) { +hsvToRgb(uint16_t h, uint16_t s, uint16_t v) { cRGB color; /* HSV to RGB conversion function with only integer diff --git a/src/LEDUtils.h b/src/LEDUtils.h index 70929ce7..f49e6200 100644 --- a/src/LEDUtils.h +++ b/src/LEDUtils.h @@ -3,4 +3,4 @@ #include cRGB breath_compute(void); -cRGB hsv_to_rgb(uint16_t h, uint16_t s, uint16_t v); +cRGB hsvToRgb(uint16_t h, uint16_t s, uint16_t v); From 6c723bee32c2fc774d1f53d8bd5946e6d476030d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:59:05 -0700 Subject: [PATCH 325/792] CamelCaseifcation of LED related functions s/led_set_crgb_at/setCrgbAt/ s/hsv_to_rgb/hsvToRgb/ s/led_get_crgb_at/getCrgbAt/ s/led_sync/syncLeds/ s/get_led_index/getLedIndex/ s/send_led_data/sendLedData/ s/led_power_fault/ledPowerFault/ --- src/Kaleidoscope-LEDEffect-Chase.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp index 8fb9b97d..99c6c95d 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -8,15 +8,15 @@ void LEDChaseEffect_::update(void) { return; } current_chase_counter = 0; - LEDControl.led_set_crgb_at(pos - (chase_sign * chase_pixels), {0, 0, 0}); - LEDControl.led_set_crgb_at(pos, {0, 0, 0}); + LEDControl.setCrgbAt(pos - (chase_sign * chase_pixels), {0, 0, 0}); + LEDControl.setCrgbAt(pos, {0, 0, 0}); pos += chase_sign; if (pos >= LED_COUNT || pos <= 0) { chase_sign = -chase_sign; } - LEDControl.led_set_crgb_at(pos, {0, 0, 255}); - LEDControl.led_set_crgb_at(pos - (chase_sign * chase_pixels), {255, 0, 0}); + LEDControl.setCrgbAt(pos, {0, 0, 255}); + LEDControl.setCrgbAt(pos - (chase_sign * chase_pixels), {255, 0, 0}); } LEDChaseEffect_ LEDChaseEffect; From 2e428d8cccef13a18102ea47473b9185127a0456 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:59:06 -0700 Subject: [PATCH 326/792] CamelCaseifcation of LED related functions s/led_set_crgb_at/setCrgbAt/ s/hsv_to_rgb/hsvToRgb/ s/led_get_crgb_at/getCrgbAt/ s/led_sync/syncLeds/ s/get_led_index/getLedIndex/ s/send_led_data/sendLedData/ s/led_power_fault/ledPowerFault/ --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index f0793f65..c0d1bac0 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -10,7 +10,7 @@ void LEDRainbowEffect_::update(void) { rainbow_current_ticks = 0; } - cRGB rainbow = hsv_to_rgb(rainbow_hue, rainbow_saturation, rainbow_value); + cRGB rainbow = hsvToRgb(rainbow_hue, rainbow_saturation, rainbow_value); rainbow_hue += rainbow_steps; if (rainbow_hue >= 255) { @@ -42,8 +42,8 @@ void LEDRainbowWaveEffect_::update(void) { if (key_hue >= 255) { key_hue -= 255; } - cRGB rainbow = hsv_to_rgb(key_hue, rainbow_saturation, rainbow_value); - LEDControl.led_set_crgb_at(i, rainbow); + cRGB rainbow = hsvToRgb(key_hue, rainbow_saturation, rainbow_value); + LEDControl.setCrgbAt(i, rainbow); } rainbow_hue += rainbow_wave_steps; if (rainbow_hue >= 255) { From 082b4090543a433c6410d1b45b3fdf9b9a95f18c Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:59:09 -0700 Subject: [PATCH 327/792] CamelCaseifcation of LED related functions s/led_set_crgb_at/setCrgbAt/ s/hsv_to_rgb/hsvToRgb/ s/led_get_crgb_at/getCrgbAt/ s/led_sync/syncLeds/ s/get_led_index/getLedIndex/ s/send_led_data/sendLedData/ s/led_power_fault/ledPowerFault/ --- src/Kaleidoscope/LED-Stalker.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 5826dfde..b3d40029 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -59,7 +59,7 @@ void StalkerEffect::update(void) { for (byte c = 0; c < COLS; c++) { uint8_t step = map_[r][c]; if (step) { - LEDControl.led_set_crgb_at(r, c, variant->compute(&step)); + LEDControl.setCrgbAt(r, c, variant->compute(&step)); } bool was_zero = (map_[r][c] == 0); @@ -69,7 +69,7 @@ void StalkerEffect::update(void) { } if (!was_zero && !map_[r][c]) - LEDControl.led_set_crgb_at(r, c, (cRGB) { + LEDControl.setCrgbAt(r, c, (cRGB) { 0, 0, 0 }); } @@ -113,9 +113,9 @@ cRGB BlazingTrail::compute(uint8_t *step) { cRGB color; if (*step >= 0xff - 30) { - color = hsv_to_rgb(0xff - *step, 255, 255); + color = hsvToRgb(0xff - *step, 255, 255); } else { - color = hsv_to_rgb(30, 255, 255); + color = hsvToRgb(30, 255, 255); color.r = min(*step * color.r / 255, 255); color.g = min(*step * color.g / 255, 255); From 978d04625d1af7f9256806befae36688dfd3ab36 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:59:11 -0700 Subject: [PATCH 328/792] CamelCaseifcation of LED related functions s/led_set_crgb_at/setCrgbAt/ s/hsv_to_rgb/hsvToRgb/ s/led_get_crgb_at/getCrgbAt/ s/led_sync/syncLeds/ s/get_led_index/getLedIndex/ s/send_led_data/sendLedData/ s/led_power_fault/ledPowerFault/ --- src/Kaleidoscope-Model01-TestMode.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 1d7175eb..7bef678a 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -41,7 +41,7 @@ void TestMode_::wait_for_keypress() { void TestMode_::set_leds(uint8_t r, uint8_t g, uint8_t b) { LEDControl.set_all_leds_to(r, g, b); - LEDControl.led_sync(); + LEDControl.syncLeds(); wait_for_keypress(); } @@ -57,7 +57,7 @@ void TestMode_::test_leds(void) { // rainbow for 10 seconds for (auto i = 0; i < 1000; i++) { LEDRainbowEffect.update(); - LEDControl.led_sync(); + LEDControl.syncLeds(); } // set all the keys to red } @@ -84,9 +84,9 @@ void TestMode_::test_matrix() { // Serial.print(keynum); // Serial.print(" value "); // Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 7 - col, green); + KeyboardHardware.setCrgbAt(row, 7 - col, green); } else if (keyState == 1) { - KeyboardHardware.led_set_crgb_at(row, 7 - col, blue); + KeyboardHardware.setCrgbAt(row, 7 - col, blue); } keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | @@ -97,13 +97,13 @@ void TestMode_::test_matrix() { // Serial.print(keynum); // Serial.print(" value "); // Serial.println(keyState); - KeyboardHardware.led_set_crgb_at(row, 15 - col, green); + KeyboardHardware.setCrgbAt(row, 15 - col, green); } else if (keyState == 1) { - KeyboardHardware.led_set_crgb_at(row, 15 - col, blue); + KeyboardHardware.setCrgbAt(row, 15 - col, blue); } } } - LEDControl.led_sync(); + LEDControl.syncLeds(); } } From 137ff3761054db3ca40cc304e35775428cb3e0a1 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 14:59:12 -0700 Subject: [PATCH 329/792] CamelCaseifcation of LED related functions s/led_set_crgb_at/setCrgbAt/ s/hsv_to_rgb/hsvToRgb/ s/led_get_crgb_at/getCrgbAt/ s/led_sync/syncLeds/ s/get_led_index/getLedIndex/ s/send_led_data/sendLedData/ s/led_power_fault/ledPowerFault/ --- src/Kaleidoscope-Numlock.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index decee6d9..9b251120 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -25,7 +25,7 @@ void NumLock_::loopHook(bool postClear) { if (k.raw < Key_KeypadNumLock.raw || k.raw > Key_KeypadDot.raw) continue; - LEDControl.led_set_crgb_at(r, c, numpad_color); + LEDControl.setCrgbAt(r, c, numpad_color); } } @@ -33,7 +33,7 @@ void NumLock_::loopHook(bool postClear) { return; cRGB color = breath_compute(); - LEDControl.led_set_crgb_at(row, col, color); + LEDControl.setCrgbAt(row, col, color); } const macro_t *NumLock_::toggle() { From c4fccab55b95a46332e91b4ca7210248282e13ee Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 15:06:26 -0700 Subject: [PATCH 330/792] get_key_color -> getKeyColor --- src/Kaleidoscope-Hardware-Model01.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 4ed076cd..47612c4d 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -17,7 +17,7 @@ class Model01 { void setCrgbAt(byte row, byte col, cRGB color); void setCrgbAt(uint8_t i, cRGB crgb); cRGB getCrgbAt(uint8_t i); - cRGB get_key_color(byte row, byte col); + cRGB getKeyColor(byte row, byte col); uint8_t getLedIndex(byte row, byte col); void scan_matrix(void); From 4712aabfd400872b00c2299beccac052558fb744 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 15:11:19 -0700 Subject: [PATCH 331/792] camelCasing of _matrix functions --- src/Kaleidoscope-Hardware-Model01.cpp | 10 +++++----- src/Kaleidoscope-Hardware-Model01.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index a22fc21b..d7550b72 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -141,7 +141,7 @@ void debug_keyswitch_event(keydata_t state, keydata_t previousState, uint8_t key } -void Model01::read_matrix() { +void Model01::readMatrix() { //scan the Keyboard matrix looking for connections previousLeftHandState = leftHandState; previousRightHandState = rightHandState; @@ -157,7 +157,7 @@ void Model01::read_matrix() { -void Model01::act_on_matrix_scan() { +void Model01::actOnMatrixScan() { for (byte row = 0; row < 4; row++) { for (byte col = 0; col < 8; col++) { @@ -176,9 +176,9 @@ void Model01::act_on_matrix_scan() { } -void Model01::scan_matrix() { - read_matrix(); - act_on_matrix_scan(); +void Model01::scanMatrix() { + readMatrix(); + actOnMatrixScan(); } void Model01::reboot_bootloader() { diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 47612c4d..111db050 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -20,9 +20,9 @@ class Model01 { cRGB getKeyColor(byte row, byte col); uint8_t getLedIndex(byte row, byte col); - void scan_matrix(void); - void read_matrix(void); - void act_on_matrix_scan(void); + void scanMatrix(void); + void readMatrix(void); + void actOnMatrixScan(void); void setup(); void enable_high_power_leds(void); void enable_scanner_power(void); From d0e85633b8cab99533e564993be9da3edd760b21 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 15:11:39 -0700 Subject: [PATCH 332/792] camelCasing of _matrix functions --- src/Kaleidoscope-Model01-TestMode.cpp | 8 ++++---- src/Kaleidoscope-Model01-TestMode.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 7bef678a..e7c4a882 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -31,7 +31,7 @@ void TestMode_::loopHook(bool postClear) { void TestMode_::wait_for_keypress() { delay(25); while (1) { - KeyboardHardware.read_matrix(); + KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == R3C6 && KeyboardHardware.previousLeftHandState.all == 0) { break; @@ -65,10 +65,10 @@ void TestMode_::test_leds(void) { -void TestMode_::test_matrix() { +void TestMode_::testMatrix() { LEDControl.set_all_leds_to(200, 0, 0); while (1) { - KeyboardHardware.read_matrix(); + KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { break; } @@ -117,7 +117,7 @@ void TestMode_::run_tests() { toggle_programming_leds_on(); test_leds(); - test_matrix(); + testMatrix(); // Serial.println("Done running tests"); } diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index efd00026..144bad52 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -13,7 +13,7 @@ class TestMode_ : public KaleidoscopePlugin { private: static void run_tests(); static void test_leds(); - static void test_matrix(); + static void testMatrix(); static void toggle_programming_leds_on(); static void wait_for_keypress(); static void loopHook(bool postClear); From 9573630c19baa59e471b4f978decdd5ffde3ad82 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 15:20:13 -0700 Subject: [PATCH 333/792] camelCasing of internal functions in Hardware file --- src/Kaleidoscope-Hardware-Model01.cpp | 12 ++++++------ src/Kaleidoscope-Hardware-Model01.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index d7550b72..00274a72 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -17,7 +17,7 @@ Model01::Model01(void) { } -void Model01::enable_scanner_power(void) { +void Model01::enableScannerPower(void) { // PC7 //pinMode(13, OUTPUT); //digitalWrite(13, HIGH); @@ -30,7 +30,7 @@ void Model01::enable_scanner_power(void) { // This lets the keyboard pull up to 1.6 amps from // the host. That violates the USB spec. But it sure // is pretty looking -void Model01::enable_high_power_leds(void) { +void Model01::enableHighPowerLeds(void) { // PE6 // pinMode(7, OUTPUT); // digitalWrite(7, LOW); @@ -48,12 +48,12 @@ void Model01::enable_high_power_leds(void) { void Model01::setup(void) { wdt_disable(); delay(100); - enable_scanner_power(); + enableScannerPower(); // Consider not doing this until 30s after keyboard // boot up, to make it easier to rescue things // in case of power draw issues. - enable_high_power_leds(); + enableHighPowerLeds(); leftHandState.all = 0; rightHandState.all = 0; @@ -124,7 +124,7 @@ boolean Model01::ledPowerFault() { } } -void debug_keyswitch_event(keydata_t state, keydata_t previousState, uint8_t keynum, uint8_t row, uint8_t col) { +void debugKeyswitchEvent(keydata_t state, keydata_t previousState, uint8_t keynum, uint8_t row, uint8_t col) { if (bitRead(state.all, keynum) != bitRead(previousState.all, keynum)) { Serial.print("Looking at row "); Serial.print(row); @@ -181,7 +181,7 @@ void Model01::scanMatrix() { actOnMatrixScan(); } -void Model01::reboot_bootloader() { +void Model01::rebootBootloader() { // Set the magic bits to get a Caterina-based device // to reboot into the bootloader and stay there, rather // than run move onward diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 111db050..4f76cbd7 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -24,9 +24,9 @@ class Model01 { void readMatrix(void); void actOnMatrixScan(void); void setup(); - void enable_high_power_leds(void); - void enable_scanner_power(void); - void reboot_bootloader(); + void enableHighPowerLeds(void); + void enableScannerPower(void); + void rebootBootloader(); boolean ledPowerFault(void); From 2c08dd867bf1ed059528996c1d2e324d807fb571 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 15:56:34 -0700 Subject: [PATCH 334/792] camelCasing press_button to pressButton --- src/Kaleidoscope-MouseKeys.cpp | 2 +- src/MouseWrapper.cpp | 2 +- src/MouseWrapper.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 5f49678c..4b7041b2 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -77,7 +77,7 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; if (keyToggledOn(keyState)) { - MouseWrapper.press_button(button); + MouseWrapper.pressButton(button); } else if (keyToggledOff(keyState)) { MouseWrapper.release_button(button); } diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 5aa522b6..697def1d 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -17,7 +17,7 @@ MouseWrapper_::MouseWrapper_(void) { AbsoluteMouse.begin(); } -void MouseWrapper_::press_button(uint8_t button) { +void MouseWrapper_::pressButton(uint8_t button) { Mouse.press(button); end_warping(); } diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 4bb82b1a..86079b52 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -33,7 +33,7 @@ class MouseWrapper_ { static void move(int8_t x, int8_t y); static void warp(uint8_t warp_cmd); - static void press_button(uint8_t button); + static void pressButton(uint8_t button); static void release_button(uint8_t button); static uint8_t accelStep; From 42cabcfa6f00bf50c31041f2f0fab7898e11b0f3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 24 Jul 2017 15:59:50 -0700 Subject: [PATCH 335/792] camelCasing wait_for_keypress --- src/Kaleidoscope-Model01-TestMode.cpp | 4 ++-- src/Kaleidoscope-Model01-TestMode.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index e7c4a882..c0a0473e 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -28,7 +28,7 @@ void TestMode_::loopHook(bool postClear) { } } -void TestMode_::wait_for_keypress() { +void TestMode_::waitForKeypress() { delay(25); while (1) { KeyboardHardware.readMatrix(); @@ -42,7 +42,7 @@ void TestMode_::wait_for_keypress() { void TestMode_::set_leds(uint8_t r, uint8_t g, uint8_t b) { LEDControl.set_all_leds_to(r, g, b); LEDControl.syncLeds(); - wait_for_keypress(); + waitForKeypress(); } void TestMode_::test_leds(void) { diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 144bad52..ea15d1d0 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -15,7 +15,7 @@ class TestMode_ : public KaleidoscopePlugin { static void test_leds(); static void testMatrix(); static void toggle_programming_leds_on(); - static void wait_for_keypress(); + static void waitForKeypress(); static void loopHook(bool postClear); static void set_leds(uint8_t r, uint8_t g, uint8_t b); }; From b87014c544e2f4f2f7ee3905d1c5becb637e54c1 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 11:09:58 -0700 Subject: [PATCH 336/792] Port to the new HID facade --- src/Kaleidoscope-MouseKeys.cpp | 4 ++-- src/MouseWrapper.cpp | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 4b7041b2..927d2e9d 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -26,9 +26,9 @@ void MouseKeys_::scrollWheel(uint8_t keyCode) { wheelEndTime = millis() + wheelDelay; if (keyCode & KEY_MOUSE_UP) - Mouse.move(0, 0, wheelSpeed); + kaleidoscope::hid::moveMouse(0, 0, wheelSpeed); else if (keyCode & KEY_MOUSE_DOWN) - Mouse.move(0, 0, -wheelSpeed); + kaleidoscope::hid::moveMouse(0, 0, -wheelSpeed); } void MouseKeys_::loopHook(bool postClear) { diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 697def1d..a0b7e993 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -3,6 +3,7 @@ // // #include "MouseWrapper.h" +#include "kaleidoscope/hid.h" uint16_t MouseWrapper_::next_width; uint16_t MouseWrapper_::next_height; @@ -13,23 +14,23 @@ boolean MouseWrapper_::is_warping; uint8_t MouseWrapper_::accelStep; MouseWrapper_::MouseWrapper_(void) { - Mouse.begin(); - AbsoluteMouse.begin(); + kaleidoscope::hid::initializeMouse(); + kaleidoscope::hid::initializeAbsoluteMouse(); } void MouseWrapper_::pressButton(uint8_t button) { - Mouse.press(button); + kaleidoscope::hid::pressMouseButtons(button); end_warping(); } void MouseWrapper_::release_button(uint8_t button) { - Mouse.release(button); + kaleidoscope::hid::releaseMouseButtons(button); } void MouseWrapper_::warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width) { uint16_t x_center = left + width / 2; uint16_t y_center = top + height / 2; - AbsoluteMouse.moveTo(x_center, y_center); + kaleidoscope::hid::moveAbsoluteMouseTo(x_center, y_center, 0); } void MouseWrapper_::begin_warping() { @@ -107,7 +108,7 @@ void MouseWrapper_::move(int8_t x, int8_t y) { } end_warping(); - Mouse.move(moveX, moveY, 0); + kaleidoscope::hid::moveMouse(moveX, moveY, 0); } MouseWrapper_ MouseWrapper; From cf08f96d1ca57392387ef24cd9673b414d4129c9 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 11:11:00 -0700 Subject: [PATCH 337/792] Port to new HID facade --- src/Kaleidoscope-Macros.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 2ea5954d..b59095d3 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -1,4 +1,5 @@ #include "Kaleidoscope-Macros.h" +#include "kaleidoscope/hid.h" __attribute__((weak)) const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { @@ -14,11 +15,11 @@ static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t ke if (keyIsPressed(keyStates)) { handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); - Keyboard.sendReport(); + kaleidoscope::hid::sendKeyboardReport(); } if (keyWasPressed(keyStates)) { handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); - Keyboard.sendReport(); + kaleidoscope::hid::sendKeyboardReport(); } } @@ -163,9 +164,9 @@ void Macros_::type(const char *string) { continue; handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); - Keyboard.sendReport(); + kaleidoscope::hid::sendKeyboardReport(); handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); - Keyboard.sendReport(); + kaleidoscope::hid::sendKeyboardReport(); } } From b19fd73f1ff0df8a2f96be78a1cddff1fdc3ccd4 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 11:20:28 -0700 Subject: [PATCH 338/792] astyle --- src/MouseWrapper.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index a0b7e993..4da39c0a 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -14,17 +14,17 @@ boolean MouseWrapper_::is_warping; uint8_t MouseWrapper_::accelStep; MouseWrapper_::MouseWrapper_(void) { - kaleidoscope::hid::initializeMouse(); - kaleidoscope::hid::initializeAbsoluteMouse(); + kaleidoscope::hid::initializeMouse(); + kaleidoscope::hid::initializeAbsoluteMouse(); } void MouseWrapper_::pressButton(uint8_t button) { - kaleidoscope::hid::pressMouseButtons(button); + kaleidoscope::hid::pressMouseButtons(button); end_warping(); } void MouseWrapper_::release_button(uint8_t button) { - kaleidoscope::hid::releaseMouseButtons(button); + kaleidoscope::hid::releaseMouseButtons(button); } void MouseWrapper_::warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width) { From 30ebf9599f9685d35a2c9eedd171240f3ef44432 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:05 -0700 Subject: [PATCH 339/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From ceaded3eb4acd1fba61be3b1a61ca0ec62a1390b Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:05 -0700 Subject: [PATCH 340/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From 07b3bb66676e354278bf30e0f1262beac44fc469 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:07 -0700 Subject: [PATCH 341/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From 1a5717d8389c95b73eef36cc2dabb11693493657 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:10 -0700 Subject: [PATCH 342/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From b078a29d238123e517e8e1c629e9d11848c948d3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:10 -0700 Subject: [PATCH 343/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From d342b6eb04fba36f19c3119c2388cb7ce684bdd7 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:11 -0700 Subject: [PATCH 344/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From f364a389b19bf07e01328a2f06482da1a5ed3414 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:12 -0700 Subject: [PATCH 345/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From 9b4668024008c272b6e5052afd193bf71c7c3415 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:12 -0700 Subject: [PATCH 346/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From 93b4bfc120ebe4c2b7f8bceb7fb097a5537d930e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:14 -0700 Subject: [PATCH 347/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From 43b768cabb666d8612096750555238d1746689c3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:14 -0700 Subject: [PATCH 348/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From d7a889f25e0176312d4635bc8abe3c4b63214e8d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:15 -0700 Subject: [PATCH 349/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From 243b1ada1a5e644362584d502fac3086222c4a7e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:16 -0700 Subject: [PATCH 350/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From 50b993b2f68663787ec8a7fe92ff471008e8aa1a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:16 -0700 Subject: [PATCH 351/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From 5f3b3486ed8cccb6c9830b6ba0607b7768aca999 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:17 -0700 Subject: [PATCH 352/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From 401e9326a050316b54777fe0fab7273aa983c44d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 25 Jul 2017 15:52:17 -0700 Subject: [PATCH 353/792] Update Makefile to fix OS X build --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9ce0c4a9..2b04143a 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Library/Arduino/hardware +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/*.mk +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk From ef47dc54479102985532711f4478e936efd35715 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 26 Jul 2017 20:31:55 -0700 Subject: [PATCH 354/792] switch mouse button constants to those defined in the HID library. This is a leakage from the KeyboardioHID library --- src/MouseKeyDefs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index 83ca84d3..0485db12 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -3,9 +3,9 @@ #define IS_MOUSE_KEY B00010000 // Synthetic, not internal -#define KEY_MOUSE_BTN_L 0x01 // Synthetic key -#define KEY_MOUSE_BTN_M 0x02 // Synthetic key -#define KEY_MOUSE_BTN_R 0x03 // Synthetic key +#define KEY_MOUSE_BTN_L MOUSE_LEFT // Synthetic key +#define KEY_MOUSE_BTN_M MOUSE_MIDDLE // Synthetic key +#define KEY_MOUSE_BTN_R MOUSE_RIGHT // Synthetic key #define KEY_MOUSE_UP B0000001 From 5e79b16923f38c55d13726c6921d88dc87be0a19 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Wed, 26 Jul 2017 20:33:32 -0700 Subject: [PATCH 355/792] switch around our constants so we have more room for mouse buttons in the bit vector --- src/MouseKeyDefs.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index 0485db12..9f5bdbc9 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -12,10 +12,11 @@ #define KEY_MOUSE_DOWN B0000010 #define KEY_MOUSE_LEFT B0000100 #define KEY_MOUSE_RIGHT B0001000 -#define KEY_MOUSE_BUTTON B0010000 +#define KEY_MOUSE_WHEEL B0010000 #define KEY_MOUSE_WARP B0100000 -#define KEY_MOUSE_WARP_END B0010000 -#define KEY_MOUSE_WHEEL B1000000 +#define KEY_MOUSE_WARP_END B1000000 +// all buttons end warp. also, we're out of bits +#define KEY_MOUSE_BUTTON B1000000 #define Key_mouseWarpNW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } From 4f7e60ec52efedcf969b4cb42b6abbcfdc7e17c4 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 28 Jul 2017 08:24:36 +0200 Subject: [PATCH 356/792] Highlight changed keys on the NumLock layer, not just NumPad ones As there are - or at least may be - other keys on the layer, not just NumPad ones, those should be highlighted too. Addresses the bulk of keyboardio/Kaleidoscope#149, by comparing the looked up key with what is directly on the `numPadLayer`: if they are the same, then it is a key that we assume changed, and do the coloring. If they are different (in other words, the key on the `numPadLayer` is transparent or off), we skip the highlight. The downside is that we highlight layer switching keys too, which we may not want. That will be addressed separately. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 9b251120..430d7f2b 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -21,8 +21,9 @@ void NumLock_::loopHook(bool postClear) { for (uint8_t r = 0; r < ROWS; r++) { for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookup(r, c); + Key layer_key = Layer.getKey(numPadLayer, r, c); - if (k.raw < Key_KeypadNumLock.raw || k.raw > Key_KeypadDot.raw) + if ((k != layer_key)) continue; LEDControl.setCrgbAt(r, c, numpad_color); From 23b341e2b3d5a3c5337acdd25116fd8ff685db66 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 28 Jul 2017 08:34:49 +0200 Subject: [PATCH 357/792] Skip layer switching keys when it comes to highlighting Together with the previous, this fixes keyboardio/Kaleidoscope#149. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 430d7f2b..c6c03c50 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -23,7 +23,7 @@ void NumLock_::loopHook(bool postClear) { Key k = Layer.lookup(r, c); Key layer_key = Layer.getKey(numPadLayer, r, c); - if ((k != layer_key)) + if ((k != layer_key) || ((k.flags == (SYNTHETIC | SWITCH_TO_KEYMAP)) && !(k.flags & RESERVED))) continue; LEDControl.setCrgbAt(r, c, numpad_color); From 65fee12dad3504c28c10148bcd357faa09c0b357 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 28 Jul 2017 17:12:43 +0200 Subject: [PATCH 358/792] Move Mouse & AbsoluteMouse initialization to MouseWrapper.begin To avoid issues with static initialization order, move the Mouse & AbsoluteMouse initialization from the MouseWrapper constructor to MouseWrapper.begin, which will be called from MouseKeys.begin. Thus, user code does not need to change. This fixes keyboardio/Kaleidoscope#140. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-MouseKeys.cpp | 1 + src/MouseWrapper.cpp | 3 +++ src/MouseWrapper.h | 1 + 3 files changed, 5 insertions(+) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 927d2e9d..70572429 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -112,6 +112,7 @@ MouseKeys_::MouseKeys_(void) { void MouseKeys_::begin(void) { + MouseWrapper.begin(); event_handler_hook_use(eventHandlerHook); loop_hook_use(loopHook); } diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 4da39c0a..f5aec4c3 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -14,6 +14,9 @@ boolean MouseWrapper_::is_warping; uint8_t MouseWrapper_::accelStep; MouseWrapper_::MouseWrapper_(void) { +} + +void MouseWrapper_::begin(void) { kaleidoscope::hid::initializeMouse(); kaleidoscope::hid::initializeAbsoluteMouse(); } diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 86079b52..b1c0cefa 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -31,6 +31,7 @@ class MouseWrapper_ { public: MouseWrapper_(void); + static void begin(void); static void move(int8_t x, int8_t y); static void warp(uint8_t warp_cmd); static void pressButton(uint8_t button); From 92050c2ab7b91b4ad72db762b2d715e384423d68 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 30 Jul 2017 09:22:19 +0200 Subject: [PATCH 359/792] Highlight only those keys that have no flag set Instead of trying to exclude layer keys, exclude everything with a flag. Thus, only the basic keys will receive the highlighting treatment, and the rest, `Prog`, `Any` and the layer keys will not. Thanks to @chughes87 for the report! Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index c6c03c50..54db9122 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -23,7 +23,7 @@ void NumLock_::loopHook(bool postClear) { Key k = Layer.lookup(r, c); Key layer_key = Layer.getKey(numPadLayer, r, c); - if ((k != layer_key) || ((k.flags == (SYNTHETIC | SWITCH_TO_KEYMAP)) && !(k.flags & RESERVED))) + if ((k != layer_key) || (k.flags != KEY_FLAGS)) continue; LEDControl.setCrgbAt(r, c, numpad_color); From 40e6656f6e0730663aeea69f295e90ebca0f005b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 30 Jul 2017 10:48:43 +0200 Subject: [PATCH 360/792] Add helpers to aid in implementing key masking There are situations when one wants to ignore key events for a while, and mask them out. These newly introduced functions help do that. They are in the Hardware plugin, because this is where it is most efficient to implement the masks: the hardware library knows how many bits it needs, and how best to represent the masks. We use a 32-bit bitmap here, other keyboards may use a different size, or an entirely different approach too. This is one part of the fix to address keyboardio/Kaleidoscope#150. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 40 +++++++++++++++++++++++++++ src/Kaleidoscope-Hardware-Model01.h | 8 ++++++ 2 files changed, 48 insertions(+) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 00274a72..1f2e8c7f 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -5,6 +5,8 @@ KeyboardioScanner Model01::leftHand(0); KeyboardioScanner Model01::rightHand(3); bool Model01::isLEDChanged = true; +uint32_t Model01::leftHandMask; +uint32_t Model01::rightHandMask; static constexpr uint8_t key_led_map[4][16] = { {3, 4, 11, 12, 19, 20, 26, 27, 36, 37, 43, 44, 51, 52, 59, 60}, @@ -202,4 +204,42 @@ void Model01::rebootBootloader() { // happens before the watchdog reboots us } +void Model01::maskKey(byte row, byte col) { + if (row >= ROWS || col >= COLS) + return; + + if (col >= 8) { + rightHandMask |= SCANBIT(row, col - 8); + } else { + leftHandMask |= SCANBIT(row, col); + } +} + +void Model01::unMaskKey(byte row, byte col) { + if (row >= ROWS || col >= COLS) + return; + + if (col >= 8) { + rightHandMask &= ~(SCANBIT(row, col - 8)); + } else { + leftHandMask &= ~(SCANBIT(row, col)); + } +} + +bool Model01::isKeyMasked(byte row, byte col) { + if (row >= ROWS || col >= COLS) + return false; + + if (col >= 8) { + return rightHandMask & SCANBIT(row, col - 8); + } else { + return leftHandMask & SCANBIT(row, col); + } +} + +void Model01::maskHeldKeys(void) { + rightHandMask = rightHandState.all; + leftHandMask = leftHandState.all; +} + HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 4f76cbd7..d8c47e22 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -30,6 +30,11 @@ class Model01 { boolean ledPowerFault(void); + void maskKey(byte row, byte col); + void unMaskKey(byte row, byte col); + bool isKeyMasked(byte row, byte col); + void maskHeldKeys(void); + keydata_t leftHandState; keydata_t rightHandState; keydata_t previousLeftHandState; @@ -39,6 +44,9 @@ class Model01 { static bool isLEDChanged; static KeyboardioScanner leftHand; static KeyboardioScanner rightHand; + + static uint32_t leftHandMask; + static uint32_t rightHandMask; }; #define SCANBIT(row,col) ((uint32_t)1 << (row * 8 + (7 - col))) From cd847a7ead3d90a5f8c9ec4fc71373a74907de5a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 1 Aug 2017 00:45:47 -0700 Subject: [PATCH 361/792] extract our ascii lookup table function. (saves 16 bytes) --- src/Kaleidoscope-Macros.cpp | 17 ++++++++++++----- src/Kaleidoscope-Macros.h | 3 +++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index b59095d3..391c0bdf 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -115,12 +115,8 @@ static const Key ascii_to_key_map[] PROGMEM = { LSHIFT(Key_Backtick), }; -void Macros_::type(const char *string) { - while (true) { - uint8_t ascii_code = pgm_read_byte(string++); - if (!ascii_code) - break; +Key Macros_::lookupAsciiCode(uint8_t ascii_code) { Key key = Key_NoKey; switch (ascii_code) { @@ -159,6 +155,17 @@ void Macros_::type(const char *string) { key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x7B + 29]); break; } + return key; +} + +void Macros_::type(const char *string) { + while (true) { + uint8_t ascii_code = pgm_read_byte(string++); + if (!ascii_code) + break; + + Key key = lookupAsciiCode(ascii_code); + if (key.raw == Key_NoKey.raw) continue; diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index 92b14fd9..c55e190e 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -17,6 +17,9 @@ class Macros_ : public KaleidoscopePlugin { void type(const char *string); static byte row, col; + + private: + Key lookupAsciiCode(uint8_t ascii_code); }; extern Macros_ Macros; From a9068d16d430971e5b84ae2767644dd48e954470 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 1 Aug 2017 01:09:10 -0700 Subject: [PATCH 362/792] Unify repeated code to a codepath. Saves us 16 bytes --- src/Kaleidoscope-Macros.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 391c0bdf..e56f7724 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -8,18 +8,21 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { byte Macros_::row, Macros_::col; +void playMacroKeyswitchEvent(Key key, uint8_t flags) { + handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, INJECTED | flags); + kaleidoscope::hid::sendKeyboardReport(); +} + static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t keyStates) { Key key; key.flags = flags; key.keyCode = pgm_read_byte(macro_p++); if (keyIsPressed(keyStates)) { - handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); - kaleidoscope::hid::sendKeyboardReport(); + playMacroKeyswitchEvent(key, IS_PRESSED); } if (keyWasPressed(keyStates)) { - handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); - kaleidoscope::hid::sendKeyboardReport(); + playMacroKeyswitchEvent(key, WAS_PRESSED); } } @@ -165,15 +168,14 @@ void Macros_::type(const char *string) { break; Key key = lookupAsciiCode(ascii_code); - + if (key.raw == Key_NoKey.raw) continue; - handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED); - kaleidoscope::hid::sendKeyboardReport(); - handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED); - kaleidoscope::hid::sendKeyboardReport(); + playMacroKeyswitchEvent(key, IS_PRESSED); + playMacroKeyswitchEvent(key, WAS_PRESSED); + } } From 1206a3cafb4cc0b878813697740bc0032bee5028 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 1 Aug 2017 01:09:55 -0700 Subject: [PATCH 363/792] astyle --- src/Kaleidoscope-Macros.cpp | 78 ++++++++++++++++++------------------- src/Kaleidoscope-Macros.h | 2 +- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index e56f7724..7a1ad506 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -120,45 +120,45 @@ static const Key ascii_to_key_map[] PROGMEM = { Key Macros_::lookupAsciiCode(uint8_t ascii_code) { - Key key = Key_NoKey; - - switch (ascii_code) { - case 0x08 ... 0x09: - key.keyCode = Key_Backspace.keyCode + ascii_code - 0x08; - break; - case 0x0A: - key.keyCode = Key_Enter.keyCode; - break; - case 0x1B: - key.keyCode = Key_Escape.keyCode; - break; - case 0x20: - key.keyCode = Key_Spacebar.keyCode; - break; - case 0x21 ... 0x30: - key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x21]); - break; - case 0x31 ... 0x39: - key.keyCode = Key_1.keyCode + ascii_code - 0x31; - break; - case 0x3A ... 0x40: - key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x3A + 16]); - break; - case 0x41 ... 0x5A: - key.flags = SHIFT_HELD; - key.keyCode = Key_A.keyCode + ascii_code - 0x41; - break; - case 0x5B ... 0x5F: - key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x5B + 23]); - break; - case 0x61 ... 0x7A: - key.keyCode = Key_A.keyCode + ascii_code - 0x61; - break; - case 0x7B ... 0x7E: - key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x7B + 29]); - break; - } - return key; + Key key = Key_NoKey; + + switch (ascii_code) { + case 0x08 ... 0x09: + key.keyCode = Key_Backspace.keyCode + ascii_code - 0x08; + break; + case 0x0A: + key.keyCode = Key_Enter.keyCode; + break; + case 0x1B: + key.keyCode = Key_Escape.keyCode; + break; + case 0x20: + key.keyCode = Key_Spacebar.keyCode; + break; + case 0x21 ... 0x30: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x21]); + break; + case 0x31 ... 0x39: + key.keyCode = Key_1.keyCode + ascii_code - 0x31; + break; + case 0x3A ... 0x40: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x3A + 16]); + break; + case 0x41 ... 0x5A: + key.flags = SHIFT_HELD; + key.keyCode = Key_A.keyCode + ascii_code - 0x41; + break; + case 0x5B ... 0x5F: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x5B + 23]); + break; + case 0x61 ... 0x7A: + key.keyCode = Key_A.keyCode + ascii_code - 0x61; + break; + case 0x7B ... 0x7E: + key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x7B + 29]); + break; + } + return key; } void Macros_::type(const char *string) { diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index c55e190e..91a2ace8 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -19,7 +19,7 @@ class Macros_ : public KaleidoscopePlugin { static byte row, col; private: - Key lookupAsciiCode(uint8_t ascii_code); + Key lookupAsciiCode(uint8_t ascii_code); }; extern Macros_ Macros; From c575fd0d5216e726fa1d196dd38de8ed4793e389 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Thu, 3 Aug 2017 18:10:18 +0900 Subject: [PATCH 364/792] When in numlock, we should only light up the numpad keys, not everything else --- src/Kaleidoscope-Numlock.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 54db9122..7e04b63d 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -6,6 +6,7 @@ byte NumLock_::row = 255, NumLock_::col = 255; uint8_t NumLock_::numPadLayer; cRGB numpad_color = CRGB(255, 0, 0); +cRGB off_color = CRGB(0, 0, 0); NumLock_::NumLock_(void) { } @@ -23,10 +24,11 @@ void NumLock_::loopHook(bool postClear) { Key k = Layer.lookup(r, c); Key layer_key = Layer.getKey(numPadLayer, r, c); - if ((k != layer_key) || (k.flags != KEY_FLAGS)) - continue; - - LEDControl.setCrgbAt(r, c, numpad_color); + if ((k != layer_key) || (k.flags != KEY_FLAGS)) { + LEDControl.setCrgbAt(r, c, off_color); + } else { + LEDControl.setCrgbAt(r, c, numpad_color); + } } } From 14197de8e658cce23a53d7ca9b8fcc3bd323530b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 3 Aug 2017 12:15:37 +0200 Subject: [PATCH 365/792] Add a few words about masking as in-code comments. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index d8c47e22..2e58fd23 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -30,6 +30,15 @@ class Model01 { boolean ledPowerFault(void); + /* Key masking + * ----------- + * + * There are situations when one wants to ignore key events for a while, and + * mask them out. These functions help do that. In isolation, they do nothing, + * plugins and the core firmware is expected to make use of these. + * + * See `handleKeyswitchEvent` in the Kaleidoscope sources for a use-case. + */ void maskKey(byte row, byte col); void unMaskKey(byte row, byte col); bool isKeyMasked(byte row, byte col); From a120c63e961e7d584d8f682b37b9b897af5fcb4f Mon Sep 17 00:00:00 2001 From: Craig Disselkoen Date: Sat, 5 Aug 2017 16:56:53 -0700 Subject: [PATCH 366/792] Avoid duplicated effects in LEDMode rotation Before this commit, any SolidColor effects would appear in the LEDMode rotation twice (e.g. in the stock Model01-Firmware). They would be added to the rotation both on construction and in Kaleidoscope.use(). This removes the duplication, and makes SolidColor effects behave similarly to other effects. --- src/Kaleidoscope-LEDEffect-SolidColor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.cpp b/src/Kaleidoscope-LEDEffect-SolidColor.cpp index 7549fb8a..9dc62dc7 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.cpp +++ b/src/Kaleidoscope-LEDEffect-SolidColor.cpp @@ -4,7 +4,6 @@ LEDSolidColor::LEDSolidColor(uint8_t r, uint8_t g, uint8_t b) { this->r = r; this->g = g; this->b = b; - LEDControl.mode_add(this); } void From 0a566eb58fb626e2413a31aceefaf6e8cb51a169 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 6 Aug 2017 06:59:01 +0200 Subject: [PATCH 367/792] Fix masking of the right-hand side. The `SCANBIT` macro was not using `row` and `col` properly: if either was anything else than a number (such as `col - 8`), the macro did not expand them correctly, preserving operator precedence. As such, the right-hand side SCANBITs were broken when used with masking, because the masking code uses `SCANBIT(row, col - 8)`, and the `(7 - col)` part would expand to `(7 - col - 8)` which is very different than `(7 - (col - 8))`. This patch addresses the issue. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 2e58fd23..e2fe552d 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -58,7 +58,7 @@ class Model01 { static uint32_t rightHandMask; }; -#define SCANBIT(row,col) ((uint32_t)1 << (row * 8 + (7 - col))) +#define SCANBIT(row,col) ((uint32_t)1 << ((row) * 8 + (7 - (col)))) #define R0C0 SCANBIT(0, 0) #define R0C1 SCANBIT(0, 1) From 8e98e30f62832ccc4f0695e3764983758fe86fda Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 6 Aug 2017 08:12:00 +0200 Subject: [PATCH 368/792] masking: use 4 8-bit uints instead of one 32bit one Dealing with 32-bit numbers on Atmega32u4 is very costy, so lets try to avoid that, and use four 8-bit uints instead. This save us about a hundred bytes of progmem. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 26 ++++++++++++++++---------- src/Kaleidoscope-Hardware-Model01.h | 4 ++-- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 1f2e8c7f..682a0480 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -5,8 +5,8 @@ KeyboardioScanner Model01::leftHand(0); KeyboardioScanner Model01::rightHand(3); bool Model01::isLEDChanged = true; -uint32_t Model01::leftHandMask; -uint32_t Model01::rightHandMask; +uint8_t Model01::leftHandMask[4]; +uint8_t Model01::rightHandMask[4]; static constexpr uint8_t key_led_map[4][16] = { {3, 4, 11, 12, 19, 20, 26, 27, 36, 37, 43, 44, 51, 52, 59, 60}, @@ -209,9 +209,9 @@ void Model01::maskKey(byte row, byte col) { return; if (col >= 8) { - rightHandMask |= SCANBIT(row, col - 8); + rightHandMask[row] |= 1 << (col - 8); } else { - leftHandMask |= SCANBIT(row, col); + leftHandMask[row] |= 1 << (col); } } @@ -220,9 +220,9 @@ void Model01::unMaskKey(byte row, byte col) { return; if (col >= 8) { - rightHandMask &= ~(SCANBIT(row, col - 8)); + rightHandMask[row] &= ~(1 << (col - 8)); } else { - leftHandMask &= ~(SCANBIT(row, col)); + leftHandMask[row] &= ~(1 << col); } } @@ -231,15 +231,21 @@ bool Model01::isKeyMasked(byte row, byte col) { return false; if (col >= 8) { - return rightHandMask & SCANBIT(row, col - 8); + return rightHandMask[row] & (1 << (col - 8)); } else { - return leftHandMask & SCANBIT(row, col); + return leftHandMask[row] & (1 << col); } } void Model01::maskHeldKeys(void) { - rightHandMask = rightHandState.all; - leftHandMask = leftHandState.all; + for (byte row = 0; row < ROWS; row++) { + for (byte col = 0; col < COLS / 2; col++) { + if (leftHandState.all & SCANBIT(row, col)) + leftHandMask[row] |= 1 << col; + if (rightHandState.all & SCANBIT(row, col)) + rightHandMask[row] |= 1 << col; + } + } } HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index e2fe552d..04b41eb4 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -54,8 +54,8 @@ class Model01 { static KeyboardioScanner leftHand; static KeyboardioScanner rightHand; - static uint32_t leftHandMask; - static uint32_t rightHandMask; + static uint8_t leftHandMask[4]; + static uint8_t rightHandMask[4]; }; #define SCANBIT(row,col) ((uint32_t)1 << ((row) * 8 + (7 - (col)))) From 7e092363068976b949ad34b719b39592f97e238b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 6 Aug 2017 08:22:57 +0200 Subject: [PATCH 369/792] masking: Follow the hand state bit layout more closely By not using 32-bit ints, we already saved a noticeable amount of space. If we follow the `*HandState` bit layout more closely, we can shave off some more bytes too. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 682a0480..13b19350 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -209,9 +209,9 @@ void Model01::maskKey(byte row, byte col) { return; if (col >= 8) { - rightHandMask[row] |= 1 << (col - 8); + rightHandMask[row] |= 1 << (7 - (col - 8)); } else { - leftHandMask[row] |= 1 << (col); + leftHandMask[row] |= 1 << (7 - col); } } @@ -220,9 +220,9 @@ void Model01::unMaskKey(byte row, byte col) { return; if (col >= 8) { - rightHandMask[row] &= ~(1 << (col - 8)); + rightHandMask[row] &= ~(1 << (7 - (col - 8))); } else { - leftHandMask[row] &= ~(1 << col); + leftHandMask[row] &= ~(1 << (7 - col)); } } @@ -231,21 +231,15 @@ bool Model01::isKeyMasked(byte row, byte col) { return false; if (col >= 8) { - return rightHandMask[row] & (1 << (col - 8)); + return rightHandMask[row] & (1 << (7 - (col - 8))); } else { - return leftHandMask[row] & (1 << col); + return leftHandMask[row] & (1 << (7 - col)); } } void Model01::maskHeldKeys(void) { - for (byte row = 0; row < ROWS; row++) { - for (byte col = 0; col < COLS / 2; col++) { - if (leftHandState.all & SCANBIT(row, col)) - leftHandMask[row] |= 1 << col; - if (rightHandState.all & SCANBIT(row, col)) - rightHandMask[row] |= 1 << col; - } - } + memcpy(leftHandMask, leftHandState.rows, sizeof(leftHandMask)); + memcpy(rightHandMask, rightHandState.rows, sizeof(rightHandMask)); } HARDWARE_IMPLEMENTATION KeyboardHardware; From 2e48ea3a0e61185ce9dd6482fe1a793230f6cdf0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 6 Aug 2017 08:29:24 +0200 Subject: [PATCH 370/792] masking: Use keydata_t instead of uint8_t[4] Since we have a nice keydata_t union, use that, to convey it even more clearly that we are mimicking the hand states in a way. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 20 ++++++++++---------- src/Kaleidoscope-Hardware-Model01.h | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 13b19350..d23e63bc 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -5,8 +5,8 @@ KeyboardioScanner Model01::leftHand(0); KeyboardioScanner Model01::rightHand(3); bool Model01::isLEDChanged = true; -uint8_t Model01::leftHandMask[4]; -uint8_t Model01::rightHandMask[4]; +keydata_t Model01::leftHandMask; +keydata_t Model01::rightHandMask; static constexpr uint8_t key_led_map[4][16] = { {3, 4, 11, 12, 19, 20, 26, 27, 36, 37, 43, 44, 51, 52, 59, 60}, @@ -209,9 +209,9 @@ void Model01::maskKey(byte row, byte col) { return; if (col >= 8) { - rightHandMask[row] |= 1 << (7 - (col - 8)); + rightHandMask.rows[row] |= 1 << (7 - (col - 8)); } else { - leftHandMask[row] |= 1 << (7 - col); + leftHandMask.rows[row] |= 1 << (7 - col); } } @@ -220,9 +220,9 @@ void Model01::unMaskKey(byte row, byte col) { return; if (col >= 8) { - rightHandMask[row] &= ~(1 << (7 - (col - 8))); + rightHandMask.rows[row] &= ~(1 << (7 - (col - 8))); } else { - leftHandMask[row] &= ~(1 << (7 - col)); + leftHandMask.rows[row] &= ~(1 << (7 - col)); } } @@ -231,15 +231,15 @@ bool Model01::isKeyMasked(byte row, byte col) { return false; if (col >= 8) { - return rightHandMask[row] & (1 << (7 - (col - 8))); + return rightHandMask.rows[row] & (1 << (7 - (col - 8))); } else { - return leftHandMask[row] & (1 << (7 - col)); + return leftHandMask.rows[row] & (1 << (7 - col)); } } void Model01::maskHeldKeys(void) { - memcpy(leftHandMask, leftHandState.rows, sizeof(leftHandMask)); - memcpy(rightHandMask, rightHandState.rows, sizeof(rightHandMask)); + memcpy(leftHandMask.rows, leftHandState.rows, sizeof(leftHandMask)); + memcpy(rightHandMask.rows, rightHandState.rows, sizeof(rightHandMask)); } HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 04b41eb4..b652e66a 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -54,8 +54,8 @@ class Model01 { static KeyboardioScanner leftHand; static KeyboardioScanner rightHand; - static uint8_t leftHandMask[4]; - static uint8_t rightHandMask[4]; + static keydata_t leftHandMask; + static keydata_t rightHandMask; }; #define SCANBIT(row,col) ((uint32_t)1 << ((row) * 8 + (7 - (col)))) From 306e4504968d2221dd45e31bacb9e706891bad13 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 08:55:37 +0200 Subject: [PATCH 371/792] Make the .type method return MACRO_NONE This way it can be used in place of a `return MACRO(...)` construct. Signed-off-by: Gergely Nagy --- README.md | 2 +- src/Kaleidoscope-Macros.cpp | 4 +++- src/Kaleidoscope-Macros.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9462f369..b2944447 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { T(0), T(1) ); case MACRO_HELLO: if (keyToggledOn(keyState)) { - Macros.type(PSTR("Hello world!")); + return Macros.type(PSTR("Hello world!")); } break; case MACRO_SPECIAL: diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 7a1ad506..72a4155d 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -161,7 +161,7 @@ Key Macros_::lookupAsciiCode(uint8_t ascii_code) { return key; } -void Macros_::type(const char *string) { +const macro_t *Macros_::type(const char *string) { while (true) { uint8_t ascii_code = pgm_read_byte(string++); if (!ascii_code) @@ -177,6 +177,8 @@ void Macros_::type(const char *string) { playMacroKeyswitchEvent(key, WAS_PRESSED); } + + return MACRO_NONE; } static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index 91a2ace8..7693dbdb 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -14,7 +14,7 @@ class Macros_ : public KaleidoscopePlugin { void begin(void) final; void play(const macro_t *macro_p); - void type(const char *string); + const macro_t *type(const char *string); static byte row, col; From 23fec81b2868bfb4e6bdbc5eacd00dca7c70047e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 16 Jun 2017 09:10:13 +0200 Subject: [PATCH 372/792] Allow type() to take any number of arguments To make it easier to type a set of strings, apply some template magic to the `Macros.type()` method. The same trick that is used in `Kaleidoscope.use()`. Signed-off-by: Gergely Nagy --- README.md | 19 ++++++++++--------- src/Kaleidoscope-Macros.h | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b2944447..3bc1bbbf 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { T(0), T(1) ); case MACRO_HELLO: if (keyToggledOn(keyState)) { - return Macros.type(PSTR("Hello world!")); + return Macros.type(PSTR("Hello "), PSTR("world!")); } break; case MACRO_SPECIAL: @@ -92,18 +92,19 @@ The plugin provides a `Macros` object, with the following methods and properties > > The `macro` argument must be a sequence created with the `MACRO()` helper! -### `.type(string)` +### `.type(strings...)` -> In cases where we only want to type a string, it is far more convenient to use -> this method: we do not have to use the `MACRO()` helper, but just give this -> one a string, and it will type it for us on the keyboard. +> In cases where we only want to type some strings, it is far more convenient to +> use this method: we do not have to use the `MACRO()` helper, but just give +> this one a set of strings, and it will type them for us on the keyboard. We +> can use as many strings as we want, and all of them will be typed in order. > -> The string is limited to a sequence of printable ASCII characters. No +> Each string is limited to a sequence of printable ASCII characters. No > international symbols, or unicode, or anything like it: just plain ASCII. > -> The `string` argument must also reside in program memory, and the easiest way -> to do that is to wrap the string in a `PSTR()` helper. See the program code at -> the beginning of this documentation for an example! +> Each of `strings` arguments must also reside in program memory, and the +> easiest way to do that is to wrap the string in a `PSTR()` helper. See the +> program code at the beginning of this documentation for an example! ### `.row`, `.col` diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index 7693dbdb..d750f996 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -14,7 +14,21 @@ class Macros_ : public KaleidoscopePlugin { void begin(void) final; void play(const macro_t *macro_p); + + /* What follows below, is a bit of template magic that allows us to use + Macros.type() with any number of arguments, without having to use a + sentinel. See the comments on Kaleidoscope.use() for more details - this is + the same trick. + */ + inline const macro_t *type() { + return MACRO_NONE; + } const macro_t *type(const char *string); + template + const macro_t *type(const char *first, Strings&&... strings) { + type(first); + return type(strings...); + } static byte row, col; From 5f4ee21790c56d0e8d65556698c4c00b927b5a24 Mon Sep 17 00:00:00 2001 From: Selene Scriven Date: Mon, 7 Aug 2017 16:24:24 -0600 Subject: [PATCH 373/792] Upgraded mouse acceleration. Uses mickeys (1/16th subpixel units) now instead of pixels. Much smoother! Added "speedLimit" config var to set maximum cursor speed. Ensured default values are sane. --- src/Kaleidoscope-MouseKeys.cpp | 4 ++-- src/MouseWrapper.cpp | 38 ++++++++++++++++++++-------------- src/MouseWrapper.h | 6 +----- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 70572429..b3e5b733 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -7,10 +7,10 @@ uint8_t MouseKeys_::mouseMoveIntent; uint8_t MouseKeys_::speed = 1; -uint16_t MouseKeys_::speedDelay = 0; +uint16_t MouseKeys_::speedDelay = 1; uint8_t MouseKeys_::accelSpeed = 1; -uint16_t MouseKeys_::accelDelay = 50; +uint16_t MouseKeys_::accelDelay = 64; uint8_t MouseKeys_::wheelSpeed = 1; uint16_t MouseKeys_::wheelDelay = 50; diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index f5aec4c3..15c6a8c6 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -12,6 +12,7 @@ uint16_t MouseWrapper_::section_left; boolean MouseWrapper_::is_warping; uint8_t MouseWrapper_::accelStep; +uint8_t MouseWrapper_::speedLimit = 127; MouseWrapper_::MouseWrapper_(void) { } @@ -79,23 +80,20 @@ void MouseWrapper_::warp(uint8_t warp_cmd) { } // cubic wave function based on code from FastLED +// produces a shape similar to a sine curve from 0 to 255 +// (slow growth at 0, fast growth in the middle, slow growth at 255) +// http://www.wolframalpha.com/input/?i=((3((x)**2)%2F256)+-+((2((x)(x)(x%2F256))%2F256)))+%2B+1 uint8_t MouseWrapper_::acceleration(uint8_t cycles) { - uint8_t i = cycles; + uint16_t i = cycles; - if (i & 0x80) { - i = 255 - i; - } - - i = i << 1; + uint16_t ii = (i * i) >> 8; + uint16_t iii = (ii * i) >> 8; - uint8_t ii = (i * i) >> 8; - uint8_t iii = (ii * i) >> 8; + i = ((3 * ii) - (2 * iii)) + 1; - i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + ACCELERATION_FLOOR; + // Just in case (may go up to 256 at peak) + if (i > 255) i = 255; - if (i > ACCELERATION_CEIL) { - i = ACCELERATION_CEIL; - } return i; } @@ -103,15 +101,25 @@ uint8_t MouseWrapper_::acceleration(uint8_t cycles) { void MouseWrapper_::move(int8_t x, int8_t y) { int16_t moveX = 0; int16_t moveY = 0; + static int8_t remainderX = 0; + static int8_t remainderY = 0; if (x != 0) { - moveX = (x * acceleration(accelStep)); + moveX = remainderX + (x * acceleration(accelStep)); + if (moveX > (int16_t)speedLimit) moveX = speedLimit; + else if (moveX < -(int16_t)speedLimit) moveX = -speedLimit; } if (y != 0) { - moveY = (y * acceleration(accelStep)); + moveY = remainderY + (y * acceleration(accelStep)); + if (moveY > (int16_t)speedLimit) moveY = speedLimit; + else if (moveY < -(int16_t)speedLimit) moveY = -speedLimit; } end_warping(); - kaleidoscope::hid::moveMouse(moveX, moveY, 0); + // move by whole pixels, not subpixels + kaleidoscope::hid::moveMouse(moveX>>4, moveY>>4, 0); + // save leftover subpixel movements for later + remainderX = moveX & 0x0f; + remainderY = moveY & 0x0f; } MouseWrapper_ MouseWrapper; diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index b1c0cefa..99a9adbd 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -22,11 +22,6 @@ // Mouse acceleration -// we want the whole s curve, not just the bit -// that's usually above the x and y axes; -#define ACCELERATION_FLOOR 2 -#define ACCELERATION_CEIL 50 - class MouseWrapper_ { public: MouseWrapper_(void); @@ -37,6 +32,7 @@ class MouseWrapper_ { static void pressButton(uint8_t button); static void release_button(uint8_t button); static uint8_t accelStep; + static uint8_t speedLimit; private: static uint16_t next_width; From ff95f30ade92a6614b1c831ad3f6f4ec45e17807 Mon Sep 17 00:00:00 2001 From: Selene Scriven Date: Mon, 7 Aug 2017 18:27:23 -0600 Subject: [PATCH 374/792] Fix style issue pointed out by travis --- src/MouseWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 15c6a8c6..9476a237 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -116,7 +116,7 @@ void MouseWrapper_::move(int8_t x, int8_t y) { end_warping(); // move by whole pixels, not subpixels - kaleidoscope::hid::moveMouse(moveX>>4, moveY>>4, 0); + kaleidoscope::hid::moveMouse(moveX >> 4, moveY >> 4, 0); // save leftover subpixel movements for later remainderX = moveX & 0x0f; remainderY = moveY & 0x0f; From afce335f3008c16b51f817d04993a7ba76684a94 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 10 Aug 2017 15:22:48 +0200 Subject: [PATCH 375/792] Drop the getKeyColor function from the header It has no implementation, so lets not pretend we have it. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index b652e66a..c51a1037 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -17,7 +17,6 @@ class Model01 { void setCrgbAt(byte row, byte col, cRGB color); void setCrgbAt(uint8_t i, cRGB crgb); cRGB getCrgbAt(uint8_t i); - cRGB getKeyColor(byte row, byte col); uint8_t getLedIndex(byte row, byte col); void scanMatrix(void); From 0c1b7236503cf2071908dfaeb42ae734351b9d06 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 12 Aug 2017 23:35:09 -0700 Subject: [PATCH 376/792] Explicitly set LEDs that aren't active to zero. Otherwise, plugins like numlock won't get de-initialized --- src/Kaleidoscope/LED-Stalker.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index b3d40029..691f47fe 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -62,13 +62,11 @@ void StalkerEffect::update(void) { LEDControl.setCrgbAt(r, c, variant->compute(&step)); } - bool was_zero = (map_[r][c] == 0); - if (time_out) { map_[r][c] = step; } - if (!was_zero && !map_[r][c]) + if (!map_[r][c]) LEDControl.setCrgbAt(r, c, (cRGB) { 0, 0, 0 }); From 6dc23db20b7be741c6849f976debe5d13c3c0e7b Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 12 Aug 2017 23:36:42 -0700 Subject: [PATCH 377/792] When figuring out which keys to light up with LEDs: Switch to looking up the numpad keys based on the currently active layer --- src/Kaleidoscope-Numlock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 7e04b63d..60246e4f 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -21,7 +21,7 @@ void NumLock_::loopHook(bool postClear) { for (uint8_t r = 0; r < ROWS; r++) { for (uint8_t c = 0; c < COLS; c++) { - Key k = Layer.lookup(r, c); + Key k = Layer.lookupOnActiveLayer(r, c); Key layer_key = Layer.getKey(numPadLayer, r, c); if ((k != layer_key) || (k.flags != KEY_FLAGS)) { From 9fa29b709dc78fe0b6d1c7cf4a0be8d0c2dee031 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 12 Aug 2017 23:53:38 -0700 Subject: [PATCH 378/792] Turn off the LEDs when exiting NumLock mode. --- src/Kaleidoscope-Numlock.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 60246e4f..b27fe8ca 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -45,6 +45,9 @@ const macro_t *NumLock_::toggle() { if (Layer.isOn(numPadLayer)) { Layer.off(numPadLayer); + // Reset all LEDs to off to hopefully give the previous LED effect + // a better starting state + LEDControl.set_all_leds_to({0, 0, 0}); LEDControl.init_mode(); } else { Layer.on(numPadLayer); From bed648ce2831e5f55f12c1f587dd2e682ea4af0f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 13 Aug 2017 19:48:45 +0200 Subject: [PATCH 379/792] Initial import Signed-off-by: Gergely Nagy --- COPYING | 339 ++++++++++++++++++++ Makefile | 13 + README.md | 34 ++ library.properties | 10 + src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 52 +++ src/Kaleidoscope-LEDEffect-BootGreeting.h | 36 +++ 6 files changed, 484 insertions(+) create mode 100644 COPYING create mode 100644 Makefile create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Kaleidoscope-LEDEffect-BootGreeting.cpp create mode 100644 src/Kaleidoscope-LEDEffect-BootGreeting.h diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..ff8404b7 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Darwin) +BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +else +BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +endif + +include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk diff --git a/README.md b/README.md new file mode 100644 index 00000000..26bc6b28 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# Kaleidoscope-LEDEffect-BootGreeting + +![status][st:stable] + + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + +If you want to have your keyboard signal when it turns on, but you don't want to +use any more complicated LED modes, this plugin is for you. It will make the +`LEDEffectNext` key on your keymap slowly breathe for about ten seconds after +plugging the keyboard in (without blocking the normal functionality of the +keyboard, of course). + +## Using the plugin + +To use the plugin, include the header, and tell `Kaleidoscope` to use the plugin: + +```c++ +#include +#include + +void setup() { + Kaleidoscope.use(&BootGreeting, &LEDOff); + + Kaleidoscope.setup(); +} +``` + +The plugin provides no methods or properties, the above is all it can do. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..e01ffae9 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Kaleidoscope-LEDEffect-BootGreeting +version=0.0.1 +author=Gergely Nagy +maintainer=Gergely Nagy +sentence=A boot-time LED greeting +paragraph=Makes the LED button breathe for a short while after keyboard boot. +category=Communication +url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-BootGreeting +architectures=avr +dot_a_linkage=true diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp new file mode 100644 index 00000000..386058c8 --- /dev/null +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -0,0 +1,52 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include "Kaleidoscope-LEDEffect-BootGreeting.h" +#include "LEDUtils.h" + +namespace kaleidoscope { + + bool BootGreetingEffect::done_; + + void BootGreetingEffect::begin (void) { + Kaleidoscope.useLoopHook(loopHook); + } + + void BootGreetingEffect::loopHook(const bool post_clear) { + if (!post_clear || done_) + return; + + if (millis() > 10000) { + done_ = true; + return; + } + + for (uint8_t r = 0; r < ROWS; r++) { + for (uint8_t c = 0; c < COLS; c++) { + Key k = Layer.lookupOnActiveLayer(r, c); + + if (k == Key_LEDEffectNext) { + cRGB color = breath_compute(); + LEDControl.setCrgbAt(r, c, color); + } + } + } + } +} + +kaleidoscope::BootGreetingEffect BootGreetingEffect; diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h new file mode 100644 index 00000000..76a4a267 --- /dev/null +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -0,0 +1,36 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope-LEDControl.h" + +namespace kaleidoscope { + class BootGreetingEffect : public KaleidoscopePlugin { + public: + BootGreetingEffect (void) {}; + + void begin(void) final; + + private: + static void loopHook(const bool post_clear); + static bool done_; + }; +} + +extern kaleidoscope::BootGreetingEffect BootGreetingEffect; From f11189edc2e18bffd8404c6e16bf5c9af05c0cb7 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 13 Aug 2017 14:27:54 -0700 Subject: [PATCH 380/792] Update README to match code. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26bc6b28..4fd9ccaf 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ To use the plugin, include the header, and tell `Kaleidoscope` to use the plugin #include void setup() { - Kaleidoscope.use(&BootGreeting, &LEDOff); + Kaleidoscope.use(&BootGreetingEffect, &LEDOff); Kaleidoscope.setup(); } From 20c5b8e77941ce5edeffd63fd37618a89067482a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 13 Aug 2017 14:54:51 -0700 Subject: [PATCH 381/792] Make out breathing blue a little bit purer blue. Slight brighten up the breathe color so it's visible under keycaps --- src/LEDUtils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp index c8e98940..734771ce 100644 --- a/src/LEDUtils.cpp +++ b/src/LEDUtils.cpp @@ -15,9 +15,9 @@ breath_compute() { uint8_t ii = (i * i) >> 8; uint8_t iii = (ii * i) >> 8; - i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + 2; + i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + 80; - return hsvToRgb(200, 255, i); + return hsvToRgb(170, 255, i); } From f3094e15383ccbad0785c3edc7e161ef82f3899f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 14 Aug 2017 00:15:43 +0200 Subject: [PATCH 382/792] Initial attempt at chatter detection For every key we press, we keep a map of its state each cycle (for 8 cycles). When the key is released, we color it white if we had more than two state changes (ie, chatter), otherwise we turn it blue (all is well). Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Model01-TestMode.cpp | 80 ++++++++++++++++++++++++++- src/Kaleidoscope-Model01-TestMode.h | 7 +++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index c0a0473e..357dddbb 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -3,9 +3,16 @@ #include "Kaleidoscope-LEDEffect-Rainbow.h" #include #include + +#define SERIAL_DEBUG 0 + cRGB red; cRGB blue; cRGB green; +cRGB white; + + +TestMode_::chatter_test_state_t TestMode_::chatter_test_state_[ROWS][COLS]; TestMode_::TestMode_(void) { } @@ -15,6 +22,9 @@ void TestMode_::begin(void) { red.r = 201; blue.b = 201; green.g = 201; + white.r = 160; + white.g = 160; + white.b = 160; loop_hook_use(this->loopHook); } @@ -67,6 +77,7 @@ void TestMode_::test_leds(void) { void TestMode_::testMatrix() { LEDControl.set_all_leds_to(200, 0, 0); + memset(chatter_test_state_, 0, sizeof(chatter_test_state_)); while (1) { KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { @@ -79,6 +90,17 @@ void TestMode_::testMatrix() { uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); + if (keyState == 2 && chatter_test_state_[row][col].scan_count < 8) { + bitSet(chatter_test_state_[row][col].scan_map, + chatter_test_state_[row][col].scan_count); + } + + if (chatter_test_state_[row][col].scan_map != 0 && + chatter_test_state_[row][col].scan_count < 8) { + chatter_test_state_[row][col].scan_count++; + } + + if (keyState == 3) { // Serial.print(" Key: "); // Serial.print(keynum); @@ -86,12 +108,44 @@ void TestMode_::testMatrix() { // Serial.println(keyState); KeyboardHardware.setCrgbAt(row, 7 - col, green); } else if (keyState == 1) { - KeyboardHardware.setCrgbAt(row, 7 - col, blue); + bitSet(chatter_test_state_[row][col].scan_map, + chatter_test_state_[row][col].scan_count); + + uint8_t toggle_count = 0; + for (uint8_t i = 1; i < 8; i++) { + if (bitRead(chatter_test_state_[row][col].scan_map, i - 1) == 1 && + bitRead(chatter_test_state_[row][col].scan_map, i) == 0) + toggle_count++; + } +#if SERIAL_DEBUG + Serial.print(" key: "); + Serial.print(keynum); + Serial.print(" toggle_count: "); + Serial.print(toggle_count); + Serial.print(" state#: "); + Serial.print(chatter_test_state_[row][col].scan_count); + Serial.print(" state: "); + Serial.println(chatter_test_state_[row][col].scan_map, BIN); +#endif + if (toggle_count > 2) + KeyboardHardware.setCrgbAt(row, 7 - col, white); + else + KeyboardHardware.setCrgbAt(row, 7 - col, blue); } keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); + if (keyState == 2 && chatter_test_state_[row][col + 8].scan_count < 8) { + bitSet(chatter_test_state_[row][col + 8].scan_map, + chatter_test_state_[row][col + 8].scan_count); + } + + if (chatter_test_state_[row][col + 8].scan_map != 0 && + chatter_test_state_[row][col + 8].scan_count < 8) { + chatter_test_state_[row][col + 8].scan_count++; + } + if (keyState == 3) { // Serial.print(" Key: "); // Serial.print(keynum); @@ -99,7 +153,29 @@ void TestMode_::testMatrix() { // Serial.println(keyState); KeyboardHardware.setCrgbAt(row, 15 - col, green); } else if (keyState == 1) { - KeyboardHardware.setCrgbAt(row, 15 - col, blue); + bitSet(chatter_test_state_[row][col + 8].scan_map, + chatter_test_state_[row][col + 8].scan_count); + + uint8_t toggle_count = 0; + for (uint8_t i = 1; i < 8; i++) { + if (bitRead(chatter_test_state_[row][col + 8].scan_map, i - 1) == 1 && + bitRead(chatter_test_state_[row][col + 8].scan_map, i) == 0) + toggle_count++; + } +#if SERIAL_DEBUG + Serial.print(" key: "); + Serial.print(keynum); + Serial.print(" toggle_count: "); + Serial.print(toggle_count); + Serial.print(" state#: "); + Serial.print(chatter_test_state_[row][col + 8].scan_count); + Serial.print(" state: "); + Serial.println(chatter_test_state_[row][col + 8].scan_map, BIN); +#endif + if (toggle_count > 2) + KeyboardHardware.setCrgbAt(row, 15 - col, white); + else + KeyboardHardware.setCrgbAt(row, 15 - col, blue); } } } diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index ea15d1d0..d7cbc82f 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -11,6 +11,11 @@ class TestMode_ : public KaleidoscopePlugin { void begin(); private: + typedef struct { + uint8_t scan_map; + uint8_t scan_count; + } chatter_test_state_t; + static void run_tests(); static void test_leds(); static void testMatrix(); @@ -18,6 +23,8 @@ class TestMode_ : public KaleidoscopePlugin { static void waitForKeypress(); static void loopHook(bool postClear); static void set_leds(uint8_t r, uint8_t g, uint8_t b); + + static chatter_test_state_t chatter_test_state_[ROWS][COLS]; }; extern TestMode_ TestMode; From 580953a39a609a098534d25ca2457fd46a3771ae Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 13 Aug 2017 15:43:34 -0700 Subject: [PATCH 383/792] astyle --- src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 36 ++++++++++----------- src/Kaleidoscope-LEDEffect-BootGreeting.h | 16 ++++----- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index 386058c8..2b3ff973 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -21,32 +21,32 @@ namespace kaleidoscope { - bool BootGreetingEffect::done_; +bool BootGreetingEffect::done_; - void BootGreetingEffect::begin (void) { - Kaleidoscope.useLoopHook(loopHook); - } +void BootGreetingEffect::begin(void) { + Kaleidoscope.useLoopHook(loopHook); +} - void BootGreetingEffect::loopHook(const bool post_clear) { - if (!post_clear || done_) - return; +void BootGreetingEffect::loopHook(const bool post_clear) { + if (!post_clear || done_) + return; - if (millis() > 10000) { - done_ = true; - return; - } + if (millis() > 10000) { + done_ = true; + return; + } - for (uint8_t r = 0; r < ROWS; r++) { - for (uint8_t c = 0; c < COLS; c++) { - Key k = Layer.lookupOnActiveLayer(r, c); + for (uint8_t r = 0; r < ROWS; r++) { + for (uint8_t c = 0; c < COLS; c++) { + Key k = Layer.lookupOnActiveLayer(r, c); - if (k == Key_LEDEffectNext) { - cRGB color = breath_compute(); - LEDControl.setCrgbAt(r, c, color); - } + if (k == Key_LEDEffectNext) { + cRGB color = breath_compute(); + LEDControl.setCrgbAt(r, c, color); } } } } +} kaleidoscope::BootGreetingEffect BootGreetingEffect; diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index 76a4a267..c92dbf43 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -21,16 +21,16 @@ #include "Kaleidoscope-LEDControl.h" namespace kaleidoscope { - class BootGreetingEffect : public KaleidoscopePlugin { - public: - BootGreetingEffect (void) {}; +class BootGreetingEffect : public KaleidoscopePlugin { + public: + BootGreetingEffect(void) {}; - void begin(void) final; + void begin(void) final; - private: - static void loopHook(const bool post_clear); - static bool done_; - }; + private: + static void loopHook(const bool post_clear); + static bool done_; +}; } extern kaleidoscope::BootGreetingEffect BootGreetingEffect; From 588fa211484146159432a57539f42ad70918d6cd Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 13 Aug 2017 15:54:49 -0700 Subject: [PATCH 384/792] fix a lint issue --- src/Kaleidoscope-LEDEffect-BootGreeting.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index c92dbf43..ace51843 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -23,7 +23,7 @@ namespace kaleidoscope { class BootGreetingEffect : public KaleidoscopePlugin { public: - BootGreetingEffect(void) {}; + BootGreetingEffect(void) {} void begin(void) final; From aab19f505ac643e5d419e68ac8864fe11743a621 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 13 Aug 2017 21:00:07 -0700 Subject: [PATCH 385/792] Tweak the bootgreeting timeout so that it turns off at the bottom end of a pulse --- src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index 2b3ff973..9ea34e8e 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -31,7 +31,7 @@ void BootGreetingEffect::loopHook(const bool post_clear) { if (!post_clear || done_) return; - if (millis() > 10000) { + if (millis() > 9200) { done_ = true; return; } From b4c07442ac8a432db8a6c34b746a3564b111e197 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 Aug 2017 22:24:27 +0200 Subject: [PATCH 386/792] Major update of how LED modes work There were a number of issues with the model we had before, namely that plugins that changed LED colors outside of LED modes had no way to signal "go back to whatever color this key was". To this end, the `LEDMode.refreshAt` method is introduced, which these plugins can call to tell the mode to update a given key. As part of this, the API was redesigned, with code that is common between all LED modes moving to the base class, among other things, much better names, and a flow of control that is easier to follow. In the new setup, there are four methods a LED mode can implement: - `setup()` to do boot-time initialization (registering hooks, etc). - `onActivate()` called every time the mode is activated. - `update()` called each cycle. - `refreshAt()` may be called by other plugins to refresh a particular key. All of these are protected methods, to be called via `LEDControl` only. Much of the new API design was done by @cdisselkoen, huge thanks for his work! Fixes #9. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 144 ++++++++++++++------------------ src/Kaleidoscope-LEDControl.h | 96 ++++++++++++++++++--- src/LED-Off.cpp | 12 ++- src/LED-Off.h | 12 ++- 4 files changed, 167 insertions(+), 97 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index c0c1e2ce..be12b6fb 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -1,83 +1,77 @@ #include "Kaleidoscope-LEDControl.h" #include "Kaleidoscope-Focus.h" -LEDMode *LEDControl_::modes[LED_MAX_MODES]; -uint8_t LEDControl_::previousMode, LEDControl_::mode; -uint16_t LEDControl_::syncDelay = 16; -uint32_t LEDControl_::syncTimer; +namespace kaleidoscope { -void -LEDMode::activate(void) { - LEDControl.activate(this); +LEDMode *LEDControl::modes[LED_MAX_MODES]; +uint8_t LEDControl::mode; +uint16_t LEDControl::syncDelay = 16; +uint32_t LEDControl::syncTimer; + +void LEDMode::activate(void) { + ::LEDControl.activate(this); } -void -LEDMode::begin(void) { - Kaleidoscope.use(&LEDControl, NULL); - LEDControl.mode_add(this); +void LEDMode::begin(void) { + Kaleidoscope.use(&::LEDControl); + ::LEDControl.mode_add(this); + setup(); } -LEDControl_::LEDControl_(void) { - mode = previousMode = 0; +LEDControl::LEDControl(void) { + mode = 0; memset(modes, 0, LED_MAX_MODES * sizeof(modes[0])); } -void -LEDControl_::next_mode(void) { +void LEDControl::next_mode(void) { mode++; - if (mode >= LED_MAX_MODES) { - mode = 0; - return; + if (mode >= LED_MAX_MODES || !modes[mode]) { + return set_mode(0); } - if (modes[mode]) - return; - - mode = 0; + return set_mode(mode); } -void -LEDControl_::update(void) { - if (previousMode != mode) { - set_all_leds_to({0, 0, 0}); - if (modes[mode]) - (modes[mode]->init)(); - } - +#if 0 +void LEDControl::update(void) { if (modes[mode]) (modes[mode]->update)(); - - previousMode = mode; } -void -LEDControl_::init_mode(void) { +void LEDControl::refreshAt(byte row, byte col) { if (modes[mode]) - (modes[mode]->init)(); + modes[mode]->refreshAt(row, col); } +#endif void -LEDControl_::set_mode(uint8_t mode_) { - if (mode_ < LED_MAX_MODES) - mode = mode_; +LEDControl::set_mode(uint8_t mode_) { + if (mode_ >= LED_MAX_MODES) + return; + + set_all_leds_to({0, 0, 0}); + mode = mode_; + if (modes[mode]) + modes[mode]->onActivate(); } -uint8_t -LEDControl_::get_mode(void) { +uint8_t LEDControl::get_mode_index(void) { return mode; } -void -LEDControl_::activate(LEDMode *mode) { +LEDMode *LEDControl::get_mode(void) { + return modes[mode]; +} + +void LEDControl::activate(LEDMode *mode) { for (uint8_t i = 0; i < LED_MAX_MODES; i++) { if (modes[i] == mode) return set_mode(i); } } -int8_t -LEDControl_::mode_add(LEDMode *mode) { +int8_t LEDControl::mode_add(LEDMode *mode) { for (int i = 0; i < LED_MAX_MODES; i++) { if (modes[i]) continue; @@ -88,8 +82,7 @@ LEDControl_::mode_add(LEDMode *mode) { return -1; } -void -LEDControl_::set_all_leds_to(uint8_t r, uint8_t g, uint8_t b) { +void LEDControl::set_all_leds_to(uint8_t r, uint8_t g, uint8_t b) { cRGB color; color.r = r; color.g = g; @@ -97,35 +90,29 @@ LEDControl_::set_all_leds_to(uint8_t r, uint8_t g, uint8_t b) { set_all_leds_to(color); } -void -LEDControl_::set_all_leds_to(cRGB color) { +void LEDControl::set_all_leds_to(cRGB color) { for (uint8_t i = 0; i < LED_COUNT; i++) { setCrgbAt(i, color); } } -void -LEDControl_::setCrgbAt(uint8_t i, cRGB crgb) { +void LEDControl::setCrgbAt(uint8_t i, cRGB crgb) { KeyboardHardware.setCrgbAt(i, crgb); } -void -LEDControl_::setCrgbAt(byte row, byte col, cRGB color) { +void LEDControl::setCrgbAt(byte row, byte col, cRGB color) { KeyboardHardware.setCrgbAt(row, col, color); } -cRGB -LEDControl_::getCrgbAt(uint8_t i) { +cRGB LEDControl::getCrgbAt(uint8_t i) { return KeyboardHardware.getCrgbAt(i); } -void -LEDControl_::syncLeds(void) { +void LEDControl::syncLeds(void) { KeyboardHardware.syncLeds(); } -void -LEDControl_::begin(void) { +void LEDControl::begin(void) { set_all_leds_to({0, 0, 0}); for (uint8_t i = 0; i < LED_MAX_MODES; i++) { @@ -133,25 +120,23 @@ LEDControl_::begin(void) { (modes[i]->setup)(); } - event_handler_hook_use(eventHandler); - loop_hook_use(loopHook); + Kaleidoscope.useEventHandlerHook(eventHandler); + Kaleidoscope.useLoopHook(loopHook); syncTimer = millis() + syncDelay; } -Key -LEDControl_::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) { +Key LEDControl::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) return mappedKey; if (keyToggledOn(keyState)) - LEDControl.next_mode(); + next_mode(); return Key_NoKey; } -void -LEDControl_::loopHook(bool postClear) { +void LEDControl::loopHook(bool postClear) { if (postClear) return; @@ -162,8 +147,7 @@ LEDControl_::loopHook(bool postClear) { update(); } -bool -LEDControl_::focusHook(const char *command) { +bool LEDControl::focusHook(const char *command) { enum { SETALL, MODE, @@ -189,9 +173,9 @@ LEDControl_::focusHook(const char *command) { uint8_t idx = Serial.parseInt(); if (Serial.peek() == '\n') { - cRGB c = LEDControl.getCrgbAt(idx); + cRGB c = getCrgbAt(idx); - Focus.printColor(c.r, c.g, c.b); + ::Focus.printColor(c.r, c.g, c.b); Serial.println(); } else { cRGB c; @@ -200,7 +184,7 @@ LEDControl_::focusHook(const char *command) { c.g = Serial.parseInt(); c.b = Serial.parseInt(); - LEDControl.setCrgbAt(idx, c); + setCrgbAt(idx, c); } break; } @@ -211,16 +195,16 @@ LEDControl_::focusHook(const char *command) { c.g = Serial.parseInt(); c.b = Serial.parseInt(); - LEDControl.set_all_leds_to(c); + set_all_leds_to(c); break; } case MODE: { char peek = Serial.peek(); if (peek == '\n') { - Serial.println(LEDControl.get_mode()); + Serial.println(get_mode_index()); } else if (peek == 'n') { - LEDControl.next_mode(); + next_mode(); Serial.read(); } else if (peek == 'p') { // TODO(algernon) @@ -228,17 +212,17 @@ LEDControl_::focusHook(const char *command) { } else { uint8_t mode = Serial.parseInt(); - LEDControl.set_mode(mode); + set_mode(mode); } break; } case THEME: { if (Serial.peek() == '\n') { for (uint8_t idx = 0; idx < LED_COUNT; idx++) { - cRGB c = LEDControl.getCrgbAt(idx); + cRGB c = getCrgbAt(idx); - Focus.printColor(c.r, c.g, c.b); - Focus.printSpace(); + ::Focus.printColor(c.r, c.g, c.b); + ::Focus.printSpace(); } Serial.println(); break; @@ -252,7 +236,7 @@ LEDControl_::focusHook(const char *command) { color.g = Serial.parseInt(); color.b = Serial.parseInt(); - LEDControl.setCrgbAt(idx, color); + setCrgbAt(idx, color); idx++; } break; @@ -262,4 +246,6 @@ LEDControl_::focusHook(const char *command) { return true; } -LEDControl_ LEDControl; +} + +kaleidoscope::LEDControl LEDControl; diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 5ece0b2a..e38012a9 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -8,27 +8,100 @@ #define Key_LEDEffectNext (Key) { 0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } +namespace kaleidoscope { +/** Base class for LED modes. + * + * LED modes are a special kind of plugin, they are in charge of updating LED + * colors, setting a theme. While it is possible to have other plugins + * override the mode's colors, the LED mode is the baseline. + * + * Most of its functionality is called via @ref LEDControl, with only a few + * public methods. + * + * A LED mode **must** implement at least one of @ref onActivate or @ref + * update, and possibly @ref refreshAt too. + */ class LEDMode : public KaleidoscopePlugin { - public: - virtual void begin(void); + friend class LEDControl; + protected: + // These methods should only be called by LEDControl. + + /** One-time setup, called at keyboard boot. + * + * Any hooks that need registering, any one-time setup that needs to be + * performed, shall be done here. This is purely for preparation purposes, the + * LEDs should not be touched yet at this time. + */ virtual void setup(void) {} - virtual void init(void) {} + + /** Function to call whenever the mode is activated. + * + * Like @ref setup, this method need not touch LEDs, @ref update will be + * called right after it. The purpose of this callback is to allow a plugin to + * do some preparation whenever it is activated, instead of only on boot, or + * always at each cycle. + * + * However, unlike @ref setup, this method can change LED colors, if so + * desired. Either to provide an initial state, or a static color set. In the + * latter case, consider implementing @ref refreshAt too, because other + * plugins may override some of the colors set at activation time, and @ref + * refreshAt can be used to restore them when needed. + * + * Before the callback runs, LEDs will be blanked. + */ + virtual void onActivate(void) {} + + /** Update the LEDs once per cycle. + * + * Usually the brains of the plugin, which updates the LEDs each cycle. It is + * called after the matrix has been scanned, once per cycle. + */ virtual void update(void) {} - virtual void activate(void); + + /** Refresh the color of a given key. + * + * If we have another plugin that overrides colors set by the active LED mode + * (either at @onActivate time, or via @ref update), if that plugin wants to + * restore whatever color the mode would set the key color to, this is the + * method it will call. + * + * @param row is the row coordinate of the key to refresh the color of. + * @param col is the column coordinate of the key to refresh the color of. + */ + virtual void refreshAt(byte row, byte col) {} + + public: + /** Activate the current object as the LED mode. + */ + void activate(void); + + /** Plugin initialization. + * + * Called via `Kaleidoscope.use()`, registers the LED mode, and does the + * necessary initialization steps. Calls @ref setup at the end. + */ + void begin(void) final; }; -class LEDControl_ : public KaleidoscopePlugin { +class LEDControl : public KaleidoscopePlugin { public: - LEDControl_(void); + LEDControl(void); void begin(void) final; static void next_mode(void); static void setup(void); - static void update(void); + static void update(void) { + if (modes[mode]) + modes[mode]->update(); + } + static void refreshAt(byte row, byte col) { + if (modes[mode]) + modes[mode]->refreshAt(row, col); + } static void set_mode(uint8_t mode); - static uint8_t get_mode(); - static void init_mode(void); + static uint8_t get_mode_index(); + static LEDMode *get_mode(); static int8_t mode_add(LEDMode *mode); @@ -49,13 +122,14 @@ class LEDControl_ : public KaleidoscopePlugin { private: static uint32_t syncTimer; static LEDMode *modes[LED_MAX_MODES]; - static uint8_t previousMode, mode; + static uint8_t mode; static Key eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState); static void loopHook(bool postClear); }; +} -extern LEDControl_ LEDControl; +extern kaleidoscope::LEDControl LEDControl; #define FOCUS_HOOK_LEDCONTROL FOCUS_HOOK (LEDControl.focusHook, \ "led.at\n" \ diff --git a/src/LED-Off.cpp b/src/LED-Off.cpp index 1cacc667..25a74c04 100644 --- a/src/LED-Off.cpp +++ b/src/LED-Off.cpp @@ -1,7 +1,13 @@ #include "LED-Off.h" -void LEDOff_::update(void) { - LEDControl.set_all_leds_to({0, 0, 0}); +namespace kaleidoscope { +void LEDOff::onActivate(void) { + ::LEDControl.set_all_leds_to({0, 0, 0}); } -LEDOff_ LEDOff; +void LEDOff::refreshAt(byte row, byte col) { + ::LEDControl.setCrgbAt(row, col, {0, 0, 0}); +} +} + +kaleidoscope::LEDOff LEDOff; diff --git a/src/LED-Off.h b/src/LED-Off.h index 19d65cde..1da39edf 100644 --- a/src/LED-Off.h +++ b/src/LED-Off.h @@ -2,11 +2,15 @@ #include "Kaleidoscope-LEDControl.h" -class LEDOff_ : public LEDMode { +namespace kaleidoscope { +class LEDOff : public LEDMode { public: - LEDOff_(void) { } + LEDOff(void) { } - void update(void) final; + protected: + void onActivate(void) final; + void refreshAt(byte row, byte col) final; }; +} -extern LEDOff_ LEDOff; +extern kaleidoscope::LEDOff LEDOff; From 0d22199cac975ab2ae22a5ab94dc3d20c41fe259 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 Aug 2017 22:47:28 +0200 Subject: [PATCH 387/792] Updated to use the new LEDMode/LEDControl API Signed-off-by: Gergely Nagy --- src/Kaleidoscope/AlphaSquare-Effect.cpp | 17 ++++------------- src/Kaleidoscope/AlphaSquare-Effect.h | 8 ++++---- src/Kaleidoscope/LED-AlphaSquare.cpp | 4 ++-- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index c960e104..dc1bc208 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -23,20 +23,12 @@ namespace kaleidoscope { uint16_t AlphaSquareEffect::length = 1000; uint32_t AlphaSquareEffect::end_time_left_, AlphaSquareEffect::end_time_right_; Key AlphaSquareEffect::last_key_left_, AlphaSquareEffect::last_key_right_; -uint8_t AlphaSquareEffect::us_; -AlphaSquareEffect::AlphaSquareEffect(void) { -} - -void -AlphaSquareEffect::begin(void) { +void AlphaSquareEffect::setup(void) { Kaleidoscope.useEventHandlerHook(eventHandlerHook); - Kaleidoscope.use(&LEDControl); - us_ = LEDControl.mode_add(this); } -void -AlphaSquareEffect::update(void) { +void AlphaSquareEffect::update(void) { if (end_time_left_ && millis() > end_time_left_) { ::AlphaSquare.clear(last_key_left_); end_time_left_ = 0; @@ -47,9 +39,8 @@ AlphaSquareEffect::update(void) { } } -Key -AlphaSquareEffect::eventHandlerHook(Key key, byte row, byte col, uint8_t key_state) { - if (LEDControl.get_mode() != us_) +Key AlphaSquareEffect::eventHandlerHook(Key key, byte row, byte col, uint8_t key_state) { + if (::LEDControl.get_mode() != &::AlphaSquareEffect) return key; if (key_state & INJECTED) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 5b32ce12..0f60a452 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -24,16 +24,16 @@ namespace kaleidoscope { class AlphaSquareEffect : public LEDMode { public: - AlphaSquareEffect(void); + AlphaSquareEffect(void) {} - void begin(void) final; + static uint16_t length; + protected: + void setup(void) final; void update(void) final; - static uint16_t length; private: static uint32_t end_time_left_, end_time_right_; static Key last_key_left_, last_key_right_; - static uint8_t us_; static Key eventHandlerHook(Key key, uint8_t row, uint8_t col, uint8_t key_state); }; diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 5327af83..9a7184f0 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -90,11 +90,11 @@ void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col, cRGB key_co if (!pixel) continue; - LEDControl.setCrgbAt(row + r, col + c, key_color); + ::LEDControl.setCrgbAt(row + r, col + c, key_color); } } - LEDControl.syncLeds(); + ::LEDControl.syncLeds(); } void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col) { From 8bb7a5b1e41849c4853e5a5926d5e0b2d91b64a1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 Aug 2017 22:51:17 +0200 Subject: [PATCH 388/792] Updated to use the new LEDMode/LEDControl API Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.cpp | 14 +++++--------- src/Kaleidoscope/LED-Stalker.h | 11 ++++++----- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 691f47fe..055b7978 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -26,15 +26,11 @@ StalkerEffect::ColorComputer *StalkerEffect::variant; uint16_t StalkerEffect::step_length = 50; uint32_t StalkerEffect::step_end_time_; -StalkerEffect::StalkerEffect(void) { +void StalkerEffect::setup(void) { + Kaleidoscope.useEventHandlerHook(eventHandlerHook); } -void StalkerEffect::begin(void) { - event_handler_hook_use(eventHandlerHook); - LEDMode::begin(); -} - -void StalkerEffect::init(void) { +void StalkerEffect::onActivate(void) { memset(map_, 0, sizeof(map_)); } @@ -59,7 +55,7 @@ void StalkerEffect::update(void) { for (byte c = 0; c < COLS; c++) { uint8_t step = map_[r][c]; if (step) { - LEDControl.setCrgbAt(r, c, variant->compute(&step)); + ::LEDControl.setCrgbAt(r, c, variant->compute(&step)); } if (time_out) { @@ -67,7 +63,7 @@ void StalkerEffect::update(void) { } if (!map_[r][c]) - LEDControl.setCrgbAt(r, c, (cRGB) { + ::LEDControl.setCrgbAt(r, c, (cRGB) { 0, 0, 0 }); } diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index f4764b11..99caed29 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -31,15 +31,16 @@ class StalkerEffect : public LEDMode { virtual cRGB compute(uint8_t *step) = 0; }; - StalkerEffect(void); - - void begin(void) final; - void init(void) final; - void update(void) final; + StalkerEffect(void) {} static ColorComputer *variant; static uint16_t step_length; + protected: + void setup(void) final; + void onActivate(void) final; + void update(void) final; + private: static uint32_t step_end_time_; static uint8_t map_[ROWS][COLS]; From a7f9207ceccd2c514fb675d4e556868fd187accd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 Aug 2017 22:53:25 +0200 Subject: [PATCH 389/792] Updated to use the new LEDMode/LEDControl API Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index 9ea34e8e..9475e9d4 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -42,7 +42,7 @@ void BootGreetingEffect::loopHook(const bool post_clear) { if (k == Key_LEDEffectNext) { cRGB color = breath_compute(); - LEDControl.setCrgbAt(r, c, color); + ::LEDControl.setCrgbAt(r, c, color); } } } From de54b5b279bbcb953da976536bbe1bc42d1e1bab Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 Aug 2017 22:55:22 +0200 Subject: [PATCH 390/792] Updated to use the new LEDMode/LEDControl API Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Breathe.cpp | 11 +++++------ src/Kaleidoscope-LEDEffect-Breathe.h | 9 ++++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp index 5c2397f9..6551bfbb 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -1,11 +1,10 @@ #include "Kaleidoscope-LEDEffect-Breathe.h" -LEDBreatheEffect_::LEDBreatheEffect_(void) { -} - -void LEDBreatheEffect_::update(void) { +namespace kaleidoscope { +void LEDBreatheEffect::update(void) { cRGB color = breath_compute(); - LEDControl.set_all_leds_to(color); + ::LEDControl.set_all_leds_to(color); +} } -LEDBreatheEffect_ LEDBreatheEffect; +kaleidoscope::LEDBreatheEffect LEDBreatheEffect; diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index c69e3168..b9cad307 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -3,11 +3,14 @@ #include "Kaleidoscope-LEDControl.h" #include "LEDUtils.h" -class LEDBreatheEffect_ : public LEDMode { +namespace kaleidoscope { +class LEDBreatheEffect : public LEDMode { public: - LEDBreatheEffect_(void); + LEDBreatheEffect(void) {} + protected: void update(void) final; }; +} -extern LEDBreatheEffect_ LEDBreatheEffect; +extern kaleidoscope::LEDBreatheEffect LEDBreatheEffect; From 7f705c43b5716dc959c9dce06544e99e96ba89d8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 Aug 2017 22:57:19 +0200 Subject: [PATCH 391/792] Updated to use the new LEDMode/LEDControl API Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Chase.cpp | 17 ++++++++--------- src/Kaleidoscope-LEDEffect-Chase.h | 9 ++++++--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp index 99c6c95d..c021b5a8 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -1,22 +1,21 @@ #include "Kaleidoscope-LEDEffect-Chase.h" -LEDChaseEffect_::LEDChaseEffect_(void) { -} - -void LEDChaseEffect_::update(void) { +namespace kaleidoscope { +void LEDChaseEffect::update(void) { if (current_chase_counter++ < chase_threshold) { return; } current_chase_counter = 0; - LEDControl.setCrgbAt(pos - (chase_sign * chase_pixels), {0, 0, 0}); - LEDControl.setCrgbAt(pos, {0, 0, 0}); + ::LEDControl.setCrgbAt(pos - (chase_sign * chase_pixels), {0, 0, 0}); + ::LEDControl.setCrgbAt(pos, {0, 0, 0}); pos += chase_sign; if (pos >= LED_COUNT || pos <= 0) { chase_sign = -chase_sign; } - LEDControl.setCrgbAt(pos, {0, 0, 255}); - LEDControl.setCrgbAt(pos - (chase_sign * chase_pixels), {255, 0, 0}); + ::LEDControl.setCrgbAt(pos, {0, 0, 255}); + ::LEDControl.setCrgbAt(pos - (chase_sign * chase_pixels), {255, 0, 0}); +} } -LEDChaseEffect_ LEDChaseEffect; +kaleidoscope::LEDChaseEffect LEDChaseEffect; diff --git a/src/Kaleidoscope-LEDEffect-Chase.h b/src/Kaleidoscope-LEDEffect-Chase.h index cfea5fab..1002b8ac 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.h +++ b/src/Kaleidoscope-LEDEffect-Chase.h @@ -3,10 +3,12 @@ #include "Kaleidoscope-LEDControl.h" #include "LEDUtils.h" -class LEDChaseEffect_ : public LEDMode { +namespace kaleidoscope { +class LEDChaseEffect : public LEDMode { public: - LEDChaseEffect_(void); + LEDChaseEffect(void) {} + protected: void update(void) final; private: @@ -16,5 +18,6 @@ class LEDChaseEffect_ : public LEDMode { uint8_t current_chase_counter = 0; static const uint8_t chase_threshold = 20; }; +} -extern LEDChaseEffect_ LEDChaseEffect; +extern kaleidoscope::LEDChaseEffect LEDChaseEffect; From 25cb263e6a8c8e556cf04694ea389eb7470746cc Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 Aug 2017 22:59:03 +0200 Subject: [PATCH 392/792] Updated to use the new LEDMode/LEDControl API Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 23 ++++++++++------------- src/Kaleidoscope-LEDEffect-Rainbow.h | 14 ++++++++------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index c0d1bac0..2de7618e 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -1,9 +1,8 @@ #include "Kaleidoscope-LEDEffect-Rainbow.h" -LEDRainbowEffect_::LEDRainbowEffect_(void) { -} +namespace kaleidoscope { -void LEDRainbowEffect_::update(void) { +void LEDRainbowEffect::update(void) { if (rainbow_current_ticks++ < rainbow_ticks) { return; } else { @@ -16,21 +15,17 @@ void LEDRainbowEffect_::update(void) { if (rainbow_hue >= 255) { rainbow_hue -= 255; } - LEDControl.set_all_leds_to(rainbow); + ::LEDControl.set_all_leds_to(rainbow); } -void LEDRainbowEffect_::brightness(byte brightness) { +void LEDRainbowEffect::brightness(byte brightness) { rainbow_value = brightness; } -LEDRainbowEffect_ LEDRainbowEffect; // --------- -LEDRainbowWaveEffect_::LEDRainbowWaveEffect_(void) { -} - -void LEDRainbowWaveEffect_::update(void) { +void LEDRainbowWaveEffect::update(void) { if (rainbow_current_ticks++ < rainbow_wave_ticks) { return; } else { @@ -43,7 +38,7 @@ void LEDRainbowWaveEffect_::update(void) { key_hue -= 255; } cRGB rainbow = hsvToRgb(key_hue, rainbow_saturation, rainbow_value); - LEDControl.setCrgbAt(i, rainbow); + ::LEDControl.setCrgbAt(i, rainbow); } rainbow_hue += rainbow_wave_steps; if (rainbow_hue >= 255) { @@ -51,8 +46,10 @@ void LEDRainbowWaveEffect_::update(void) { } } -void LEDRainbowWaveEffect_::brightness(byte brightness) { +void LEDRainbowWaveEffect::brightness(byte brightness) { rainbow_value = brightness; } +} -LEDRainbowWaveEffect_ LEDRainbowWaveEffect; +kaleidoscope::LEDRainbowEffect LEDRainbowEffect; +kaleidoscope::LEDRainbowWaveEffect LEDRainbowWaveEffect; diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 6745bdbe..98307109 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -3,9 +3,10 @@ #include "Kaleidoscope-LEDControl.h" #include "LEDUtils.h" -class LEDRainbowEffect_ : public LEDMode { +namespace kaleidoscope { +class LEDRainbowEffect : public LEDMode { public: - LEDRainbowEffect_(void); + LEDRainbowEffect(void) {} void brightness(byte); void update(void) final; @@ -21,11 +22,10 @@ class LEDRainbowEffect_ : public LEDMode { byte rainbow_value = 50; }; -extern LEDRainbowEffect_ LEDRainbowEffect; -class LEDRainbowWaveEffect_ : public LEDMode { +class LEDRainbowWaveEffect : public LEDMode { public: - LEDRainbowWaveEffect_(void); + LEDRainbowWaveEffect(void) {} void brightness(byte); void update(void) final; @@ -40,5 +40,7 @@ class LEDRainbowWaveEffect_ : public LEDMode { byte rainbow_saturation = 255; byte rainbow_value = 50; }; +} -extern LEDRainbowWaveEffect_ LEDRainbowWaveEffect; +extern kaleidoscope::LEDRainbowEffect LEDRainbowEffect; +extern kaleidoscope::LEDRainbowWaveEffect LEDRainbowWaveEffect; From 75edd6425e1f13a19f866152733ea6cce3b138db Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 Aug 2017 23:00:30 +0200 Subject: [PATCH 393/792] Updated to use the new LEDMode/LEDControl API Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-SolidColor.cpp | 11 ++++++++--- src/Kaleidoscope-LEDEffect-SolidColor.h | 6 +++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.cpp b/src/Kaleidoscope-LEDEffect-SolidColor.cpp index 9dc62dc7..94d98470 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.cpp +++ b/src/Kaleidoscope-LEDEffect-SolidColor.cpp @@ -1,12 +1,17 @@ #include "Kaleidoscope-LEDEffect-SolidColor.h" +namespace kaleidoscope { LEDSolidColor::LEDSolidColor(uint8_t r, uint8_t g, uint8_t b) { this->r = r; this->g = g; this->b = b; } -void -LEDSolidColor::init(void) { - LEDControl.set_all_leds_to(r, g, b); +void LEDSolidColor::onActivate(void) { + ::LEDControl.set_all_leds_to(r, g, b); +} + +void LEDSolidColor::refreshAt(byte row, byte col) { + ::LEDControl.setCrgbAt(row, col, CRGB(r, g, b)); +} } diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.h b/src/Kaleidoscope-LEDEffect-SolidColor.h index 88b0706c..1590caf3 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.h +++ b/src/Kaleidoscope-LEDEffect-SolidColor.h @@ -2,12 +2,16 @@ #include "Kaleidoscope-LEDControl.h" +namespace kaleidoscope { class LEDSolidColor : public LEDMode { public: LEDSolidColor(uint8_t r, uint8_t g, uint8_t b); - void init(void) final; + protected: + void onActivate(void) final; + void refreshAt(byte row, byte col) final; private: uint8_t r, g, b; }; +} From da0c998760529ab41d61858f6ab9fc7062bc070a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 15 Aug 2017 23:04:32 +0200 Subject: [PATCH 394/792] Updated to use the new LEDMode/LEDControl API Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 13 +++---------- src/Kaleidoscope-Numlock.h | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index b27fe8ca..744ffd49 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -6,13 +6,9 @@ byte NumLock_::row = 255, NumLock_::col = 255; uint8_t NumLock_::numPadLayer; cRGB numpad_color = CRGB(255, 0, 0); -cRGB off_color = CRGB(0, 0, 0); - -NumLock_::NumLock_(void) { -} void NumLock_::begin(void) { - loop_hook_use(loopHook); + Kaleidoscope.useLoopHook(loopHook); } void NumLock_::loopHook(bool postClear) { @@ -25,7 +21,7 @@ void NumLock_::loopHook(bool postClear) { Key layer_key = Layer.getKey(numPadLayer, r, c); if ((k != layer_key) || (k.flags != KEY_FLAGS)) { - LEDControl.setCrgbAt(r, c, off_color); + LEDControl.refreshAt(r, c); } else { LEDControl.setCrgbAt(r, c, numpad_color); } @@ -45,10 +41,7 @@ const macro_t *NumLock_::toggle() { if (Layer.isOn(numPadLayer)) { Layer.off(numPadLayer); - // Reset all LEDs to off to hopefully give the previous LED effect - // a better starting state - LEDControl.set_all_leds_to({0, 0, 0}); - LEDControl.init_mode(); + LEDControl.set_mode(LEDControl.get_mode_index()); } else { Layer.on(numPadLayer); } diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-Numlock.h index 1c9ebee4..c11a36ce 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -9,7 +9,7 @@ class NumLock_ : public KaleidoscopePlugin { public: - NumLock_(void); + NumLock_(void) {} void begin(void) final; From 1b6dc98703e04ee3b8cbbd596d4c5da709b9a689 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 17 Aug 2017 11:48:20 +0200 Subject: [PATCH 395/792] Use `Kaleidoscope.use` instead of `USE_PLUGINS` The latter is being obsoleted, so use the former, newer API. Signed-off-by: Gergely Nagy --- README.md | 16 ++++++++-------- examples/EEPROM-Settings/EEPROM-Settings.ino | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 617b3ddb..cff535be 100644 --- a/README.md +++ b/README.md @@ -37,23 +37,23 @@ static struct { } testSettings; void setup () { - USE_PLUGINS(&EEPROMSettings); + Kaleidoscope.use(&EEPROMSettings); /* Use other plugins that make use of the EEPROM */ - + Kaleidoscope.setup(); - + settingsBase = EEPROMSettings.requestSlice(sizeof(testSettings)); - + EEPROMSettings.seal(); - + if (!EEPROMSettings.isValid()) { // Handle the case where the settings are out of sync... // Flash LEDs, for example. - + return; } - + EEPROM.get(settingsBase, testSettings); } ``` @@ -122,7 +122,7 @@ The plugin provides two [Focus][focus] hooks: `FOCUS_HOOK_SETTINGS`, and settings, and with the contents of the `EEPROM` through Focus. [focus]: https://github.com/keyboardio/Kaleidoscope-Focus - + These provide the following `Focus` commands: ### `settings.crc` diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino index 3e0fb16f..9c8db0b0 100644 --- a/examples/EEPROM-Settings/EEPROM-Settings.ino +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -43,7 +43,7 @@ void setup() { Kaleidoscope.setup(); - USE_PLUGINS(&EEPROMSettings); + Kaleidoscope.use(&EEPROMSettings); while (!Serial) { } From a4daa45e49f6bbd7d1cc24817d6b2e2217065c63 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 17 Aug 2017 12:06:21 +0200 Subject: [PATCH 396/792] Use `Kaleidoscope.use` in the README too Signed-off-by: Gergely Nagy --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6ffdec09..946292c7 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,10 @@ void setup (){ } ``` -It is recommended to place the activation of the plugin (the `USE_PLUGINS` call) -as early as possible, so the plugin can catch all relevant key presses. The -configuration can happen at any time and should use the `STALKER` macro to do so. +It is recommended to place the activation of the plugin (the `Kaleidoscope.use` +call) as early as possible, so the plugin can catch all relevant key presses. +The configuration can happen at any time and should use the `STALKER` macro to +do so. ## Plugin methods From 3e2812889eba7f6e9cdd8e0973a6a95cc02bbdd1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 17 Aug 2017 12:07:27 +0200 Subject: [PATCH 397/792] Stop using deprecated interfaces Use `Kaleidoscope.useEventHandlerHook` instead of `event_handler_hook_use`, which is getting deprecated. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 72a4155d..1155ef46 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -198,7 +198,7 @@ Macros_::Macros_(void) { void Macros_::begin(void) { - event_handler_hook_use(handleMacroEvent); + Kaleidoscope.useEventHandlerHook(handleMacroEvent); } Macros_ Macros; From 532b1129de936aac810bf8e483e014600da6e45e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 17 Aug 2017 12:08:47 +0200 Subject: [PATCH 398/792] Stop using deprecated interfaces As `USE_PLUGINS` and `loop_hook_use` are getting deprecated, use the newer APIs: `Kaleidoscope.use` and `Kaleidoscope.useLoopHook`. Signed-off-by: Gergely Nagy --- README.md | 2 +- examples/MagicCombo/MagicCombo.ino | 2 +- src/Kaleidoscope/MagicCombo.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f8ec6b8e..d1987766 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_h void setup() { Serial.begin(9600); - USE_PLUGINS(&MagicCombo); + Kaleidoscope.use(&MagicCombo); Kaleidoscope.setup(); diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index ac581868..77e51103 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -59,7 +59,7 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { void setup() { Serial.begin(9600); - USE_PLUGINS(&MagicCombo); + Kaleidoscope.use(&MagicCombo); Kaleidoscope.setup(); diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index 114e7026..ef016687 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -38,7 +38,7 @@ MagicCombo::MagicCombo(void) { } void MagicCombo::begin(void) { - loop_hook_use(loopHook); + Kaleidoscope.useLoopHook(loopHook); } void MagicCombo::loopHook(bool is_post_clear) { From 4aa7dbe0b5e2556bc9628052301cadf8be9f8971 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 17 Aug 2017 12:10:59 +0200 Subject: [PATCH 399/792] Stop using deprecated interfaces Use `Kaleidoscope.useLoopHook` instead of `loop_hook_use` (which is getting deprecated). Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Model01-TestMode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 357dddbb..ab3e613f 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -25,7 +25,7 @@ void TestMode_::begin(void) { white.r = 160; white.g = 160; white.b = 160; - loop_hook_use(this->loopHook); + Kaleidoscope.useLoopHook(this->loopHook); } void TestMode_::loopHook(bool postClear) { From b249c505057795498bced9659513ead7ef653b5a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 17 Aug 2017 12:29:53 +0200 Subject: [PATCH 400/792] Stop using deprecated interfaces Use `Kaleidoscope.useEventHandlerHook` and `Kaleidoscope.useLoopHook` instead of the deprecated `event_handler_hook_use` and `loop_hook_use` interfaces. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-MouseKeys.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index b3e5b733..778e3eb6 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -113,8 +113,8 @@ MouseKeys_::MouseKeys_(void) { void MouseKeys_::begin(void) { MouseWrapper.begin(); - event_handler_hook_use(eventHandlerHook); - loop_hook_use(loopHook); + Kaleidoscope.useEventHandlerHook(eventHandlerHook); + Kaleidoscope.useLoopHook(loopHook); } MouseKeys_ MouseKeys; From c8c5cc0b026a0015a3b13a84fbd12ee31f4f23ed Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:22:52 -0700 Subject: [PATCH 401/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 50c92bddf7a751604063fe55b0d6a6e57c7f7dde Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:23:02 -0700 Subject: [PATCH 402/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From b9af46b1ef7bbde9183b9add87542a81bb030355 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:23:25 -0700 Subject: [PATCH 403/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 50073dc27bfe4a8f67e1423151913e825436d93d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:23:53 -0700 Subject: [PATCH 404/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From b0701de77124481bc62c095887f5f61860a912e5 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:23:58 -0700 Subject: [PATCH 405/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 74b79d60f608e86d3f641c86b190a52391d514e4 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:03 -0700 Subject: [PATCH 406/792] Update Makefile with OSX fixes and new paths --- Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index ff8404b7..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ -# This stub makefile for a Kaleidoscope plugin pulls in +# This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 8c9acb2be5acc10fc45dc99bb74e6e6c5e80f5f3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:07 -0700 Subject: [PATCH 407/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From c761bf70a98cbaa31bf7442e5719a8e4294ccbf4 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:12 -0700 Subject: [PATCH 408/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 77a3f9a6116b642635a2219855312a00362b6028 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:17 -0700 Subject: [PATCH 409/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From eb4bd2ad767a28556da3a79f632403ea8d1e4513 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:26 -0700 Subject: [PATCH 410/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From ad15c4798d0d4a1c4479a96dc616345c849f9988 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:35 -0700 Subject: [PATCH 411/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 5b72c95227fab90b5007cca805868cd7ce18ac31 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:40 -0700 Subject: [PATCH 412/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 9ee2330b1a8da161fd102df89c5aa41067f66608 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:45 -0700 Subject: [PATCH 413/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From da79e1a91be6b0ae9d4dbacb23f674cfd619cad1 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:49 -0700 Subject: [PATCH 414/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 4b3aa0127a398cda596a4307bfb47b4c7c8bc758 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:54 -0700 Subject: [PATCH 415/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 74bd0d88a231d921620e5d09d5d467f41841254f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 21 Aug 2017 22:24:58 -0700 Subject: [PATCH 416/792] Update Makefile with OSX fixes and new paths --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b04143a..8f830f44 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ # This stub makefile for a Kaleidoscope plugin pulls in # all targets from the Kaleidoscope-Plugin library -MAKEFILE_PREFIX=keyboardio/avr/libraries/Kaleidoscope-Plugin/build UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Darwin) -BOARD_HARDWARE_PATH ?= $(HOME)/Documents/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ else -BOARD_HARDWARE_PATH ?= $(HOME)/Arduino/hardware +SKETCHBOOK_DIR ?= $(HOME)/Arduino endif -include $(BOARD_HARDWARE_PATH)/$(MAKEFILE_PREFIX)/rules.mk +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk From 5015b4e9ebd5108906f8f29e6e7efd3f23bf364a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 12 Sep 2017 17:26:51 -0700 Subject: [PATCH 417/792] make doxygen not complain about big tables of macros in the Model 01 hardware --- src/Kaleidoscope-Hardware-Model01.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index c51a1037..bf8a5702 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -59,6 +59,10 @@ class Model01 { #define SCANBIT(row,col) ((uint32_t)1 << ((row) * 8 + (7 - (col)))) + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + #define R0C0 SCANBIT(0, 0) #define R0C1 SCANBIT(0, 1) #define R0C2 SCANBIT(0, 2) @@ -194,6 +198,9 @@ class Model01 { #define LED_APOSTROPHE 62 #define LED_MINUS 63 +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ + + #define KEYMAP_STACKED( \ r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, \ r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, \ From 1d1affb71b3569843f1c55f1bc9976939445a53b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 1 Oct 2017 01:10:28 +0200 Subject: [PATCH 418/792] Use an event loop hook instead of requiring a macro to detect NumLock Requiring the end-user to use a macro to have the NumLock effect is a bit confusing. We can do better than that, by using an event handler hook, and catching `Keypad_NumLock` presses, and toggle on keypress. This way, the macro is not necessary, and all the user has to do, is to use the plugin, configure `numPadLayer`, and done. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 12 ++++++++---- src/Kaleidoscope-Numlock.h | 9 +++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 744ffd49..1de648e3 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -9,6 +9,7 @@ cRGB numpad_color = CRGB(255, 0, 0); void NumLock_::begin(void) { Kaleidoscope.useLoopHook(loopHook); + Kaleidoscope.useEventHandlerHook(eventHandlerHook); } void NumLock_::loopHook(bool postClear) { @@ -35,9 +36,12 @@ void NumLock_::loopHook(bool postClear) { LEDControl.setCrgbAt(row, col, color); } -const macro_t *NumLock_::toggle() { - row = Macros.row; - col = Macros.col; +Key NumLock_::eventHandlerHook(Key key, byte row, byte col, uint8_t key_state) { + if (key != Key_KeypadNumLock) + return key; + + if (!key_toggled_on(key_state)) + return key; if (Layer.isOn(numPadLayer)) { Layer.off(numPadLayer); @@ -46,7 +50,7 @@ const macro_t *NumLock_::toggle() { Layer.on(numPadLayer); } - return MACRO(T(KeypadNumLock), END); + return key; } NumLock_ NumLock; diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-Numlock.h index c11a36ce..d9d42871 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -4,21 +4,18 @@ #include "Kaleidoscope-Macros.h" #include "LEDUtils.h" -#define TOGGLENUMLOCK 0 -#define Key_ToggleNumlock M(TOGGLENUMLOCK) - class NumLock_ : public KaleidoscopePlugin { public: NumLock_(void) {} void begin(void) final; - static const macro_t *toggle(); - static void loopHook(const bool postClear); - static uint8_t numPadLayer; private: + static void loopHook(const bool postClear); + static Key eventHandlerHook(Key key, byte row, byte col, uint8_t key_state); + static byte row, col; }; From 86ebc8de022d8dc549ce878658a7c8ebc363a231 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 2 Oct 2017 15:58:21 -0700 Subject: [PATCH 419/792] Revert f3094e15383ccbad0785c3edc7e161ef82f3899f Chatter detection wasn't actually detecting chatter. We may reinistate similar code in the future --- src/Kaleidoscope-Model01-TestMode.cpp | 85 +-------------------------- src/Kaleidoscope-Model01-TestMode.h | 7 --- 2 files changed, 2 insertions(+), 90 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index ab3e613f..0c76a594 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -4,16 +4,12 @@ #include #include -#define SERIAL_DEBUG 0 cRGB red; cRGB blue; cRGB green; -cRGB white; -TestMode_::chatter_test_state_t TestMode_::chatter_test_state_[ROWS][COLS]; - TestMode_::TestMode_(void) { } @@ -22,9 +18,6 @@ void TestMode_::begin(void) { red.r = 201; blue.b = 201; green.g = 201; - white.r = 160; - white.g = 160; - white.b = 160; Kaleidoscope.useLoopHook(this->loopHook); } @@ -77,7 +70,6 @@ void TestMode_::test_leds(void) { void TestMode_::testMatrix() { LEDControl.set_all_leds_to(200, 0, 0); - memset(chatter_test_state_, 0, sizeof(chatter_test_state_)); while (1) { KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { @@ -90,92 +82,19 @@ void TestMode_::testMatrix() { uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); - if (keyState == 2 && chatter_test_state_[row][col].scan_count < 8) { - bitSet(chatter_test_state_[row][col].scan_map, - chatter_test_state_[row][col].scan_count); - } - - if (chatter_test_state_[row][col].scan_map != 0 && - chatter_test_state_[row][col].scan_count < 8) { - chatter_test_state_[row][col].scan_count++; - } - - if (keyState == 3) { - // Serial.print(" Key: "); - // Serial.print(keynum); - // Serial.print(" value "); - // Serial.println(keyState); KeyboardHardware.setCrgbAt(row, 7 - col, green); } else if (keyState == 1) { - bitSet(chatter_test_state_[row][col].scan_map, - chatter_test_state_[row][col].scan_count); - - uint8_t toggle_count = 0; - for (uint8_t i = 1; i < 8; i++) { - if (bitRead(chatter_test_state_[row][col].scan_map, i - 1) == 1 && - bitRead(chatter_test_state_[row][col].scan_map, i) == 0) - toggle_count++; - } -#if SERIAL_DEBUG - Serial.print(" key: "); - Serial.print(keynum); - Serial.print(" toggle_count: "); - Serial.print(toggle_count); - Serial.print(" state#: "); - Serial.print(chatter_test_state_[row][col].scan_count); - Serial.print(" state: "); - Serial.println(chatter_test_state_[row][col].scan_map, BIN); -#endif - if (toggle_count > 2) - KeyboardHardware.setCrgbAt(row, 7 - col, white); - else - KeyboardHardware.setCrgbAt(row, 7 - col, blue); + KeyboardHardware.setCrgbAt(row, 7 - col, blue); } keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); - if (keyState == 2 && chatter_test_state_[row][col + 8].scan_count < 8) { - bitSet(chatter_test_state_[row][col + 8].scan_map, - chatter_test_state_[row][col + 8].scan_count); - } - - if (chatter_test_state_[row][col + 8].scan_map != 0 && - chatter_test_state_[row][col + 8].scan_count < 8) { - chatter_test_state_[row][col + 8].scan_count++; - } - if (keyState == 3) { - // Serial.print(" Key: "); - // Serial.print(keynum); - // Serial.print(" value "); - // Serial.println(keyState); KeyboardHardware.setCrgbAt(row, 15 - col, green); } else if (keyState == 1) { - bitSet(chatter_test_state_[row][col + 8].scan_map, - chatter_test_state_[row][col + 8].scan_count); - - uint8_t toggle_count = 0; - for (uint8_t i = 1; i < 8; i++) { - if (bitRead(chatter_test_state_[row][col + 8].scan_map, i - 1) == 1 && - bitRead(chatter_test_state_[row][col + 8].scan_map, i) == 0) - toggle_count++; - } -#if SERIAL_DEBUG - Serial.print(" key: "); - Serial.print(keynum); - Serial.print(" toggle_count: "); - Serial.print(toggle_count); - Serial.print(" state#: "); - Serial.print(chatter_test_state_[row][col + 8].scan_count); - Serial.print(" state: "); - Serial.println(chatter_test_state_[row][col + 8].scan_map, BIN); -#endif - if (toggle_count > 2) - KeyboardHardware.setCrgbAt(row, 15 - col, white); - else - KeyboardHardware.setCrgbAt(row, 15 - col, blue); + KeyboardHardware.setCrgbAt(row, 15 - col, blue); } } } diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index d7cbc82f..ea15d1d0 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -11,11 +11,6 @@ class TestMode_ : public KaleidoscopePlugin { void begin(); private: - typedef struct { - uint8_t scan_map; - uint8_t scan_count; - } chatter_test_state_t; - static void run_tests(); static void test_leds(); static void testMatrix(); @@ -23,8 +18,6 @@ class TestMode_ : public KaleidoscopePlugin { static void waitForKeypress(); static void loopHook(bool postClear); static void set_leds(uint8_t r, uint8_t g, uint8_t b); - - static chatter_test_state_t chatter_test_state_[ROWS][COLS]; }; extern TestMode_ TestMode; From 706401d0cc30f61fbd34dd8a0bfe7ef2b7b201e0 Mon Sep 17 00:00:00 2001 From: Craig Disselkoen Date: Fri, 6 Oct 2017 21:17:11 -0700 Subject: [PATCH 420/792] Add deprecation message for END Note: END has officially been deprecated since commit ebd9f35 on Jul 22 --- src/MacroSteps.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MacroSteps.h b/src/MacroSteps.h index 79e88f36..f3e668f2 100644 --- a/src/MacroSteps.h +++ b/src/MacroSteps.h @@ -35,4 +35,4 @@ typedef uint8_t macro_t; #define Uc(k) MACRO_ACTION_STEP_KEYCODEUP, (Key_ ## k).keyCode #define Tc(k) MACRO_ACTION_STEP_TAPCODE, (Key_ ## k).keyCode -#define END MACRO_ACTION_END +__attribute__((deprecated("END is no longer required to end macros"))) const MacroActionStepType END = MACRO_ACTION_END; From 339db0a0b3ead3f2e2b98af656ee88f141f317bd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 7 Oct 2017 07:49:22 +0200 Subject: [PATCH 421/792] Remove some dead code that were accidentally left in When implementing `.refreshAt` before, some dead code was left in Kaleidoscope-LEDControl.cpp, code that is now implemented in the header. As these are implemented elsewhere, and are `#if 0`'d out anyway, drop them. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index be12b6fb..db9a835a 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -33,18 +33,6 @@ void LEDControl::next_mode(void) { return set_mode(mode); } -#if 0 -void LEDControl::update(void) { - if (modes[mode]) - (modes[mode]->update)(); -} - -void LEDControl::refreshAt(byte row, byte col) { - if (modes[mode]) - modes[mode]->refreshAt(row, col); -} -#endif - void LEDControl::set_mode(uint8_t mode_) { if (mode_ >= LED_MAX_MODES) From 3ad18bf5e7a6fe85c57ae2c3d4bb3da8e605cec7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 7 Oct 2017 08:04:43 +0200 Subject: [PATCH 422/792] Add LEDControl.reactivate() Intended to force-reactivate the current LED mode, in case we want to refresh the whole board, and make sure we do so even if the current mode's update is a no-op. This can happen when we overrode some keys, and it becomes less costly to update everything than to iterate over the updated keys. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 4 +--- src/Kaleidoscope-LEDControl.h | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index be12b6fb..3abd6f12 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -50,10 +50,8 @@ LEDControl::set_mode(uint8_t mode_) { if (mode_ >= LED_MAX_MODES) return; - set_all_leds_to({0, 0, 0}); mode = mode_; - if (modes[mode]) - modes[mode]->onActivate(); + reactivate(); } uint8_t LEDControl::get_mode_index(void) { diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index e38012a9..a49195f8 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -102,6 +102,11 @@ class LEDControl : public KaleidoscopePlugin { static void set_mode(uint8_t mode); static uint8_t get_mode_index(); static LEDMode *get_mode(); + static void reactivate() { + set_all_leds_to({0, 0, 0}); + if (modes[mode]) + modes[mode]->onActivate(); + } static int8_t mode_add(LEDMode *mode); From 5780bccc6a59d8ed97b29ad2d33d6cd61f406473 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 7 Oct 2017 21:27:13 +0200 Subject: [PATCH 423/792] Rename reactivate() to refreshAll() As requested by @obra, because `refreshAll()` describes behaviour better. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 2 +- src/Kaleidoscope-LEDControl.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 42371bc7..d170b76b 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -39,7 +39,7 @@ LEDControl::set_mode(uint8_t mode_) { return; mode = mode_; - reactivate(); + refreshAll(); } uint8_t LEDControl::get_mode_index(void) { diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index a49195f8..caae5406 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -102,7 +102,7 @@ class LEDControl : public KaleidoscopePlugin { static void set_mode(uint8_t mode); static uint8_t get_mode_index(); static LEDMode *get_mode(); - static void reactivate() { + static void refreshAll() { set_all_leds_to({0, 0, 0}); if (modes[mode]) modes[mode]->onActivate(); From 393bba00ba7c21764b786ffd9e8f8b3b21ce9e9b Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sat, 14 Oct 2017 22:42:31 -0700 Subject: [PATCH 424/792] Fix for a deprecated API --- src/Kaleidoscope-Numlock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 1de648e3..c0d31150 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -40,7 +40,7 @@ Key NumLock_::eventHandlerHook(Key key, byte row, byte col, uint8_t key_state) { if (key != Key_KeypadNumLock) return key; - if (!key_toggled_on(key_state)) + if (!keyToggledOn(key_state)) return key; if (Layer.isOn(numPadLayer)) { From 7a5f52c299f5333903409f0e327065d1dd001697 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Mon, 16 Oct 2017 11:42:44 -0400 Subject: [PATCH 425/792] Include a diagram showing what the RxCy coordinates mean --- README.md | 5 +++++ docs/rc_layout.png | Bin 0 -> 229216 bytes 2 files changed, 5 insertions(+) create mode 100644 docs/rc_layout.png diff --git a/README.md b/README.md index d1987766..65e2baea 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ state upon which to trigger the custom action. Both of these are bit fields, each bit set tells the extension that the key with that index must be held for the action to trigger. It is recommended to use the `RxCy` macros of the core `KaleidoscopeFirmware`, and *or* them together to form a bitfield. +See below for a diagram showing how the `RxCy` coordinates coorespond to your keyboad. The combo list **must** end with an element containing zero values for both the left and the right halves. @@ -103,4 +104,8 @@ the overrideable `magicComboActions` function: Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. +`RxCy` coordinates for a Model01: + +![rxcy layout][./docs/rc_layout.png] + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino diff --git a/docs/rc_layout.png b/docs/rc_layout.png new file mode 100644 index 0000000000000000000000000000000000000000..37b0043c7d4f64af401ce2cf4e97c641c3e544b3 GIT binary patch literal 229216 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%0DR@dP1&J%_6-6%>f&_A#f$wH{ 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

S{|k8goEKi$j9mW- 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

v=zA;J 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 Date: Mon, 16 Oct 2017 11:45:28 -0400 Subject: [PATCH 426/792] Try to remember how markdown images work --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65e2baea..b31cef4c 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,6 @@ started with the plugin. `RxCy` coordinates for a Model01: -![rxcy layout][./docs/rc_layout.png] +![rxcy layout](./docs/rc_layout.png) [plugin:example]: https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino From 741cafd6ece33afe4f1eb64112c2c7c540f240c4 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Mon, 16 Oct 2017 13:14:01 -0400 Subject: [PATCH 427/792] Change wording to make it clear that Model 01 is one possible layout Don't want to rule out other units running Kaleidoscope --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b31cef4c..fda4cc26 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,9 @@ state upon which to trigger the custom action. Both of these are bit fields, each bit set tells the extension that the key with that index must be held for the action to trigger. It is recommended to use the `RxCy` macros of the core `KaleidoscopeFirmware`, and *or* them together to form a bitfield. -See below for a diagram showing how the `RxCy` coordinates coorespond to your keyboad. +To see how the `RxCy` coordinates correspond to the physical keys of your +keyboard, you'll have to consult the documentation for the keyboard. +Below, you can find a diagram showing the layout for the Keyboardio Model 01. The combo list **must** end with an element containing zero values for both the left and the right halves. From a2509992c621d9fe3a062f64f0495acf301d1a66 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Mon, 16 Oct 2017 13:39:51 -0400 Subject: [PATCH 428/792] Remove extra lines from keyboard diagram --- docs/rc_layout.png | Bin 229216 -> 90762 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/rc_layout.png b/docs/rc_layout.png index 37b0043c7d4f64af401ce2cf4e97c641c3e544b3..00cfb9792c7c116c0bf6a634b2d43829cdfda6e5 100644 GIT binary patch literal 90762 zcmXtf1z3~s_dYSYyI~;BBt+?u7U>=$NJ%Il-L=u9L6JsERBEJ@FmfOWPCmj&>5%S* z|Lga6{kg`)#bEDK=Q-!T&$&;6p}rOcDJv-s4i1I(6Ln)89MB*R4xTA7A@I&Z8!H9y z1LUKsZAuJ$g%Uf)1HY4aKC$!x{(th{H?FE+ULf!$i?0UM*W`_pZ-AZmOPqj!08v+u z*FFw*o-ak;csu9qDzM_(oB=r_ zjitr|5z7=$M$fAXl5qR>i1E^^fhm7bKNW=GkjNar8iqEn3R^YvS$Ui7-F(Ua!?n(_ zv%T%s-rmr#8d~UF^iA?=bfn!Uz-ja<%z%a+?e%}J{2Fx(4a(8hIFQSz`E!_mS?pQw z;}=j)Tm|95WwT2OCT8-PSJ<(^{jaf3VT(skBXml}jC=otz-~~KwqLL(!$Z$z`QLs(D2E-_J=hF^tYL9P7)sV|rUhp911U18nY!Dy zU*L}~53`1Ei%v5AZ#wx^hQ9RTiXEDhb(=J{A%Q#8D^K2?_HNFw+h%|R-dPA_$1D9i+pn^H?e1sw)2oe%X^_2Q*vOZc-%W2I34SRhZRa9}q{52E zo6ncE3I@|4pQY&u73twI;!Zl-ZTF{0;!1ubj3l8?bY7K~Y{qAs%l7`aD+1ccai?et zNBOr65|p@kkw11eaLYGzZQ@a!2|T>WBLL-cKjrRP~L)+Tt4(f_eqf8@KC3D@kS7QHXj<$36@^{ zU7nyU*Gl;~8R}Fp+Nm+i|4Giz9Mz2Ug*G1`I7m*%GYuzv-UR$Pkag1z= zp86dFpJlZQ;74kveY-fRY89NO8tGHG{Vv_G_wC!GZ~t3=1#P#!Y@&V0{ijz*T;YQd_3-; zP4Wc~75~+_B7c=MH3UDwjl>*p3NCRy7nIKCGf3^|eBa85l*HR2n7LwECS|#iQG?0; zqRPV{xa~}E3zivKZFdp4kbd1ZUI=144b~7d^)*1^CK3nvkM;LF3c!nl-$<8yvb4hs z<629=nw{1yH`4w)eG)-AV)nQMhUPE(C{~(~7e>3q3{JC}#NG~T9J{*Da<8haNfzH% zW^6H7)00>Imh~O}x7l*J3mBgVF)KS)un>`;aG^G0on*t`_@6AO9lJ^n@bGT3J(tVC zgUJXR97tlVg)g}$ji+^W&ui>j3-v^v=G$J6uu30NdHsq7yqx9#9tZwpHwf;}Q?iv@ zJMsJUJ$%&6Hwv7}J3%I{miF?clpjLm`N#Wb58<=L8wwh!A{I`H(UB0jHW&78&}1GqjB=j&4y z)z$H)#dp6*3h?q-q8oX&BF(;K++jDZpM!mZW5MtrJc_uN+#^vRd3~#=h`lYSC6<1N z@)LVUOrZUP;Te{L;wDPwY07VBo}~Gq+WP!UBU|mV6h>_p!i(&Dfzz9gN&8~Y+Ao{a zj5o|i;{uv0+X&Qfj&*(+t&Csblztsn2-QRVfQttevFcH)rme?{kMhpc%{muGjco=3 zb7(_|e^4f=#L00~mU4hf;Rcg^W=3qvP#`rht_f+WQ@um(Oirvi(KF(`ErM^wQ?Ue9 z{+JQKZiZMj1ndj%jA|;C+#)-r5|>Hp%`r!Ug-^U|1uHC*KF#yKP<^PP{YirT25}1Tsf`t&$B#hyZq@PYWK@97yn_!eWXnDVdSJfYi-x4fmH5bJY7O zc-lI|zUaMQ0I*C}ZUu`qdsp$2^%+LU*=rGvFJ%F`Gl{H0)Q5lD0bqv>I z`0@jMn{YR&*5nu)ZS;`z=)qC+K+3X=zA%C_&Wtcs9UcWeyvDycA@#JXHV08DyT7fW zexYXCt+r?uU4ma0Qn1tSUEueZd2G`Y*ivtS5z!G`egP%9q}J7D1;Q=@a-)3l39ovd zuPZI^DxwLkVLS7Sl{A5YT+~{Xs{KEQcdCVPkWhixo8<9#1z;+qG=JK08tQM+I0|gq zIA=yms_t&cTp!2tZom#I zBsXnUMp!s^Rn{IBJh*t{3^;j4_|B$${zt$cj6YPJ`qQ8NrE4m=2*HlSzdA>Pc9n+P zHuF5AtT|nG>7JPX#sAI)xbgY)a7CG-9+_pMuOuO)XJDUaa4=gW1;XaTMyH|cxECuB zSt^90zhoQ{v~urt`Vt#aK0td3Q$OEHT`Mv2eFiy*Q1*OpQSAp^{{($7ekoeG#ArgKCPoNUN@VC67z))Vfi6vnuA=EkY z)whrYSzKV=hYN<&Pc_DRJD?_H5rT5GGTImtjmpJ&VTTtLI$p3UG>LRf5UK_Hms?j` znR=QS`51$NLky_*z%$g|ogK@jrMl#&UGXJfT+y@> zX2d8+pEU6b$x?VF((e|xf(;OoGsoxmU`eS#8{-T+ zXhNTW%g3X@Ifv78^tqvTcKO!+iwsGV4H8#(gD|iw44BfQzZ+>jWTVJu6yYI|%IZ{Z z3}^!}4Yp;2V}B%7vqqU+Fq;dOfv@PTi#I}R)u((*@*PFfWcBHY=d;gHMs?c?8e9x3 zb)g|^fQywCl;gpij$Vd6MTYlF>q&SAO4TRO*+T+k_uk)D~Qo@p#Fmj%NCvuiQ8? zM-D`Z0N%JmpV`A*=VfDarrD^eO`L>}MU#ee~JQc6s4 z&!Rp5_5;uN2Q#Ic|8w6ivMZAE_f|ZU4&S>ot}H5CuA8C>>M6l3?uELGcaKPQWU?n? z$`MZ!`&w)kablhtrYt+gttWW0S5%PTHw$6G)fxAt*;@WVl{VskwgwIodrekwZ$&^S z)@juE_<7YB-Zr(P8Rw19Q`bbU6qBS9pGa3bqeyG$qh|jg>^3gH?TvSCFD`^AXIVy; zhPF)$N%GmK5m%z=Q)%Yi zuUdPp2z|q2$OsAHHs`nc?HfLC@z;v`Iix!P~b{&?lP zX+M%u#a?=$4g;HXGz5f#Dfx31!Gl>7zT<#pNx(O{K-uI9kikRsOfA*+Rz#ublLy63 z6+b;=dx?R8yJS*`Z5$bBYN*r#%n}!Gksnqb{<2~iIEat}EDo<{ zVJjLL7$15R_b3Uhh8Xx(z?1p_Kw;=jL3mt$)w3^+1Y`3}c20X8$enL0>OO#9V$d)k z_=v~$x7uEGaN4l15AbM4(NdIeeDd}0tw_i}yKjOqLS64uBCXSYxBAwQdBGs~wA`7b zvww!*PzpD+lQ7p<`#s>8{2oxXv=>tJjLhrdAV$f~uHE5PLmwi5zq~Z^1$j#SOkJ&V z<#jFzxsmztII=e=pvSB2T^i|13SfZZ@^oYsTx7ExUtHySQ3Un;A2vW$zs4L#Ru6V5 z$#UF?RZfNEr1ruATuL5A0^ere9WeUMt&wVUOgo};&QI0l%PycpUl31n9fsODm`$KS zj+;2i=%F%?<@L!(WJgl;Ple^IFnn6d&DSqEQ!MX^rcp$tiTpLyEhdnOzuCXGTLA8P z6mdNb_LGY;WBBKXZ+`xjNx_dS8HZ)U3Ql5;CQzbPPg{YweJ>F3@k2B!oOqn@(u-ln zz8(o_-ylb;-j>Ja_Yk9~?+&T`P8uEzjuD;z!|tqQpEW}RMQ7;`GYc3%4Gi26z`UHH zf^zYCqaHMlmQHa8b+B<6z^%x*s}8>K4{2oQ;T$D8C9UV_Dr^$FrG}_IZ0Q~~;@Wp1 zl=K63^T$B)ugk%*V7Gn2PCAH}KXHGAVcL!*`5*w2G{I$fk@B2+C0mziBs0W3%#yMuf{GFLOF3OOP@Ju)d^SU>Fbq59({|8TodC z&sG3((L+!VQeod3{uwq00J2RLkR{274OfId?(V)eGumsZFJte`7`Hb-iYi!Ih%6nF z2xAX-)dkX*{G@SO(BTZAshW+Bjw_4@u%F+_nb7}$NEP*pl8o?M3Y@Po>@+FM$AZPI z=RAir14}KB*B&B5(jEbT>O_(g%VAXrQphlQA(!0yPRZ2wfjAT0x5A^7EW&<`kmRXP?mHr!M zl&wQbM_~Cow@^04L?Et?t)9(Vf07#X$BLe#VuKILv->FMY}hM*n}p;%wby&TS?#4S zRh@4x3|Pv5;KJkif(>zgT&mT%1j_QhC|yjZMEb!-nI1L!UTTx9HU@wZKj6N}pJv|S zS$Y!W$Iaz)F|A}_o$2VmG5gRwe{aDB#OS)U3#cdVc*Z^LHTZ0KC6aikbbAvBisR|2(aP_ z{j@n01!B~~6cnUz>ebKuyn>iwy|z>g#~GT0qmMIS7pwVT=v>g2TS}ypsf7%Sjb7#? zLHp;|Xr!H>f;E@~=!y9FwgGQNmvUPGin^cn8LtA)0{aDBpC zNMlZ9`R;|nz6-~nF*V4Rz(vSW$ke{9;_h?PWNH!`hT^|OjDm8cSmD8Gx3=v29LiYJ z<0R^=dJvRvu-XW3o`#dnU9?f!}K0bcnk|U4jL~nvK-|M+rzDd1w6cVC*{sc89yPe$7`{|46AVx z0}Pm1Lx5=SClRPse(&~ew;H6tDXocU>d6A9?E`-P`=~>MusAqyd0F=v7KTv|N7C&% zor(s6NcJV&jL(8lvM9EmLj(JrTS~fhCwvQg8#nD+{6GRHgW7?<`gSB9d(#qLPNqOF zBNM@t*r0Xs&k-AqF_YtK!`8VWT8&hbV_JRFt)_96#*MTuqwYYbiP`0y@&H0}?? z{i00g2)XnX+2IBD8e9(oC6Z9Qyj4~_n|Ce&xK5x@_Uu#^9HPi|-svz3y1w}&61#iI zocc4|$!Mu%ScQFIzU{mt7wMIJBB7zL&8Ksw`&Vy72{bAMgN@y$#!QkJp9kn^VPp}7 zY~QoxQ^xHCgFlv3tk0#sIzK9XP;h=dh_AsE6FradZWtT4fW1ucv#^))cpiTVVhm?V z%?@Tja>?*R#(Mgi#@@+JWMKc4_Fj#6R*9HQi+zAPa>nT?M0_2&#U)+}I{tcB^S7_| z$6}`U?&#$fyB~h<2-!Xjbgj&F~2uJPKq5qiCsnbN29|wYL%70|I{2y6~cmEK57r4U)%9jxPMG; zdc2+XUhtX6Y0xFVXPEum3%lmEYi!$#xMr`l7=HuG;k_Pyuhi=0bAjkEh4z8dKRrE< zOpJUTL$5a{t#2AJO;cWthqFR*Pcc65k3OO1XxF#RR2Ig^Z>d#-V!_fR-VI>3+`#x! zQ51KP`Aku!|Kl`#C?ulKf8_U+D;K5RfKh&)xSCMS{EO(;G_>`ri1<~S#M=t7fkTPV zu8}%nKDr1>r%+z!tG|3()WbQb+5KF-gFX4=R;bJ07_-YqEP=)@?P=c$cd*Dmn@xVQ z3}fv-V~D*Ur)|MV4iW&0HBG0njw?WN7@~3tL=V;j>fs4V20E*fNhde>q2AkR#?nYJ z+*AkI2+sbViwxa?9^y%d%yKHcnMg4_AJse(RF}Pwguiho-ok4bSBwKC?)%^S1-vVK z-x2B1J27+#*d|s(^10Sv4807^RzUv!#W3-XqQruVr`orf>dk)lHA?w$-rJrA$SRcm zawStOQ+1M^B9IjvJT%N-`%t0-hfbK=ymS{L6q37t$cWEL=ja-17CuYuLMi`wTVtiM zFp8ect~634@=8$Qzbj-1`4FP!b#Dm0cL$D6@pcC8Th@;3qcwL`=*2ZL0pRLMu>P&PM8$p%o z_UwZ^yP~J+#y(>8IX?K}ojndrH9pq;*a^BcL{?XlIKml-H+r}Gy@Al%NH#7mq38pe zqApDTikryr?J>sTi~A($^iwdIY-|>eiT%9&5NVKpNPS{Y?|>^6rJZEhq^)M3Vm8^u zYkPNoyEE9zw*SLk#@75Z2OD_PAYpndxxc|(2=Wcx;iPmQ2an4^L<-t9Y%TL>qq-&A#^yQ(~8os{Msd75%@O!N(G8X zV~d0g$lR%^7FQ&~R^hw?g>nQ;gNKWDkT=_Vkzeg%(h6y>Lh1MAbgA1p8xn50q&}a1 zgtm8~d&KUT8(v5`NX=7Z%P^8yv%xBG?;`oq#n5c9Nrz3D=@_MLg&(MG>^e?`gI$(a zvyq%sg2M5=v3hIz!}Q-zdDA$merk%h@3TPpemwm>YYq09j#1ez#5{moOx=e=@CSr~ zi%Wc-O~vs7uo7_^*J00u!=}pc{Wky&K2uQ{xa&~bQ*E4NZ`5;1W^kr7P0>vA^*Y=e zd;5fbM&0%IP5;v>{0in*BGC7F|Go&E^!p>puO}tBqCV7Dw0oI0>M)GT-#6E1659qUVW8CTMYc}Fe z8ce&yUlV$iemRARxhM6kdyBX_VnHKla49PG0(!2N|Hpy*-BHh>k3@0x^U-Gfgw=>{ zRi1E(?Ls-l1n?Q2JiVgyUZ;$HEv-{~MJ&s{{(u_f$QiP)3Q^u}syi`)WjWSV`PGdP z_Wlvs^w2cQ71)%_p1YE+^Xuv00iTYI08Bdsz*3mDRK;L#t z*8Ru&+mot(ZP`A;o!nlZn#SF09yCSYBW4lzb2y99$gTD9#|;S;<~){;eh;#Ft(5WC z^vVh;<^SEtTq-;;Ht5e-n#d?S6~bQJ%`Ey&ZTf+N z*d=*t27y$-_-ny7oDHUx!j7w7yZ~j56SLH#Du=%)=VhOK#xX0Ik#?^TIij`~JOJE~ktO!m=e+$GbmiPuODyRZ2{andHlc z9Vn4XlAJjV*(k>)DF5kJ=v}j2gonVm@C`sptSJpFbm&`!#&2J`_r?*_!=K_+`i!gK z&e66F?b>Smhs23V;~3N~Yl<|D%&^v$I=on&~2R`Ay z@UXbLPBwBt3@@4AhKCLI6Wyo(LGElLPF zebckuMum45t)bCDuMQ(5(p zH81E&tm={n`eZ#IvZ2nf?_@FXMZePl>!SD+nd7AWkPQ)XYGBM^eNAW4r=PsaakTjp z{3ZP*68Gx%cc8SCRj9Im5lC``u=kMkntSiRcp#T{!?CZf5h3v8K4%iZ)A2Rd@vY!Q z&R-X}vo2`(Hi>jz*Wn#ar-E|OJy+}_6FklAH-rJU#Zhyd-giYWC*BMo==*|jhKJ3Q zUlPn{Hw^n2abBB4ipLw>Ct26`5rl5SIA1HfG zPvF;pG_*w8o?tYOC|@E){L zT5KhvB$Gi=wt0Kz?gu?O zLtfvU+|CASS(gHT9bWBL(cEDf^b@dr-Xd~zScu!4L8O4mpfsVBe2_E&{*g#F@>G`8 z?mdlzAajoxDjfe{G7Ku3fuXlx_sh>E-aVYOYc&QaF%M!C|CHnq`g@=tAp~F{FM2x$ zZn+^MQm$uk2})r`Z-EZgNWf9J(PoXKfqoz zN)H;Cx$LO-HfrQ^vUxO=e+tI;Jd7gd*Wz7DjNvU8qsJu|bTO(c(fupM@V91a$tTK) z)#h`Vtj3dzserl7mmpct?57QlptF9jHUf=QB2BVG+xf7ec>Ts1`GP2DQ@>xri5j$J z!ITt(bC(d5rAXJHsA(S)zLe=Yq&oHN|7!tAJ05g6IryUm>aOd7fXB66o^9(-Je+<~ zwvW)_8X?;nCB9J*f_(LhP8&DTEs+thej%{(+dDT3d_~a8$?RfId-rh_OePvMqedjp zs1i&6<5y)xo~POui4t~4eRoIe{==>(W4H$_Zn3A15Hyw&(zmb!JsJ9utu;lFu#;t% zVE-cF-Rl=P3h*D-{Av%ELsn|tuE<0^x@ zFskZgyN7@3*SSYv|3z@1nW{t{e@>E;_Wjn@PHLN!@fvc&K@3qi)s{9W2waxaO5RdT zlip|t)5YM9=q#D5oSMJhlS!fJ!x{yhl|~K9^&RFu*a|Qt_KL?w$B39Zu=Tg9yeh`L zDq0wT(NQ~AmeA2FTBZ>l?xrsL@*qe(KZ1u6(meW#xPWpGEuEk!e1WdN_c12jH?S_= z5ECZknNSiyQXeLBKNwozv${lpH->4*@;IrVL= zY&FT@fX)V#|LWJ@QI{Qh?xruWMXiJ0d-cxqeJo6ao9WP(=_~-r!!RSsd~1x{RF4_ytm4EDK}DWcq$%d z#}ExI(nA-;8A=^6S-B|}onxB0WwtPnphqapHDK@3 z?2A_{H@zaN|GkJ;1h!oiDZ99b4^uq!vz<;nhOYD1$d<>)4aVwgTMsKQ*;)lcZ(kO5u@H!YOJuk^)vB!EJWWBLe=iP;wDXhE?PFm;_g@ff{Zk+|=1VhT~Fv@qP}|U!HAN zB|^5l*%Y(HH>b?Q+SG@y1`^ql7|ZgRr_+hO-!-ngkH^#^##vtSV3QlQrq_asZR<8X_HK>fwRCb(RM96Dn zF0!K3Uh-BBY}D#HHfp(T-%>4li4pUsA$E&&T7-9WQuf{SsW3tx;JR4vhSBlbx-Cay z$!K$X0`e4X*DLRBIaa(=yO-;k7pEY$*{YPCfEO~OnGQQyXr)vek+>_qjP=sVa4kgP z_8ANMGlhoOXggK4Iwl<~`wzng@FMlisy1rvF=;inBqa{S=XvQ5Bidt zH1^)sA@A$JL^8-6M_H%wM#=vNdGu-!7UUc{Ba~f=5_W?~(TF(uSz>RO>m1w&ZgFPe z)@avRcyetg+hqgM`F$zZXLPqAY@CQfTJ?ID*4JZsC5a3Lg}+C|{tmG7FP5G3XIX-{UvUmGMHTltlMHpo#ik|w#2E8ZhQ(fg#ud09%B7)R%|iWbdTba!&yd9P7AYq zxT_^%)F`F~+ZIXi`$LeCE_g?(5UuB}d7Zr^jPa?{9)2zOLuZ;u;a;->^L&wN5N!K3 zN|B!5NDHTns76ofcwNiAEMI`j!VJ9p=Qniw>)mwUB^OS>K$d_5&%_IX=^N=aGe$24 z{@fozJ{_4o?S}iBH}c=LXn9MgM!Vex9V3R9CRg_jkMqxEzRUpo$0Q>6F?jgWKeym8 zOS0R?S-g2$`jAzdm@y0?I=b(+WkBlwnO~u~X(% z%(vxzN7wTQ7S#Vxed(H_FNUJx?RnGZ4IZ&qhEE6Zrp{=$<`bFQ zTyVT;{F6KDM(UPqT!*!py5nNlj6ZCsYcQ?NQK4O(gN>e;`>M~T3`4`$t=AuZC6-v7 zmmtd)`lxv~|K~2e?{u%1oe~AwIC*O`{5w#2v-rm<7AN$>#DGxOSD!5z^RZuvXObGV zpUSQE7#8UZ@ZIRkmPOd!+R<&=sp@kOduO|4e&Rwosq#=7iI*)gozT@y_5bOc2;<62 z4}1kp>5;7ESNy!f{TPXX>IGD@7oi3(%f;CPFKA@!kG|+ zudM1tnZJxgUddn%tM#XyF|5tkLPY(w)2)f&*z8{{42uPpW4S|=tW(I8$?YsJDC(R{*Xxei+2*juH5O{BOxdho$Q(flC;A#+ zM*p4PxoLOh(2}(xhslGjt-bn8TiH`(U-pW(M)0@8IpaSZWr3X2IpbPFC{Yowb7e?yZsqW@=X|B2?=k=ISJz?dMDWW_yhF8UjURBz+ z0x7)Q@#+-2d#8r8mes}M#wB@M?V+*8a^DKe|Mb6P(0dD8u zkyM?vDYdIb;2*89#dq(pbn}%Qk~~7-;PP**)Q+_!%M3eAWsC+Th1_LguVSSgWlR2? zrq(Ic+g_Z6rz9)eGd^uSlFS?g|6=F|&`C_1F4KH63IU)_k$ zlsV3n{kd>3_s554^xW5u_VYKMPvbpmiiiMU%A`!7lf@OW;Bilpyi%+=b>m}*@zZv1 z1*Rj;5DIgc5ZUv6Z55zk=NSJr4*Idwah+gaenEA_^8%Drxm1N+kE_c$TUp?1GE(s;!m zzZFPlvY;QTr>#_&N(%Sr-A1oSl&-Ge2n&HP%beu+dWylrkv>bZMIi-gYYXHm85qcq z#zmfPk#K{n`}+}CsPH9)GX4CrY(cm8fabeiuI`$IU>`Fxy1{0gul6zcg|OtESNgy9 zWO^4UHO7R`>@2AsXr$scxBS{`q`~|+QH5xRlk;bVQL(LPh<3e3UfbUjY9WZC__aqC zA=c0N_`NM(e5Dsb*2v);N;>X_;!A@j<^n!z^3C9A42P|A7Zz)ISFCSO!(AAODZ(JPQUwArFdJ$oKs`z+^^A@pc63nxf z!|p}kr1LT8l(=x&1xj3RiUGJ@x@vCHN~`Ylu2EiKJ2&Zk1Wmi3ezmt@T5zfQGfiga zqS$1udR{#+{yA?}=60&MSba#{tYd9&$Bz_S``@7p)^=L~_DB2jI#NTpbRay{$11;Wgh0j`i z`@HO{IAjhc*qtXfS-rPx_bESdDs@Uvc*psAn=9uY(;VA=62@u z#Gn3B<~I+7sU^9No?97o-`gR>I&L*Y-t`L?cj3_CX7Co7r2?h8% zdM(SJt;pd+dG6}gUKx2*w{<20b?l~&d42K-%UsFTo|R%dxn?)wFCU#SM+)id+Y2l_ za*p-CdoZ#mpWvou-cGA=^|?AtRoaVgjUve8Fv=95NK^EL4^qZO)uVRK@!v>Gjh|~k z63)Cw8de$I_QROg+OD+S{5RX{-2X(*9p6RHt?c!6yeW+Sk*iKPG1uDr_pbapJ(; zOpkd;7hM$%_MeXW9zIX|_BQzYm7}ZNq(id_t3mGsa8-JZhA&a*@_M()flU3+%C(6ynCjz`5$2mb6$B1xUQ3m?CLVeZH`?R!q!7R zABXJr&j{BQY-iK~-Rdkj(0{RpQ|!JVxaK?kc`jL{aIs1e$^Up#T;l<1MDDC@{TI{xeXPiqCw@cZreHpKZiNZg7)!b@cJSwgA6&dqrn#eq$;2c2kAb$vSq2?VhTWBJ z{CJ8&{M=(Mohs!dzMouW3%@!TWtbB8xDrdBNL1oWwS-^pE0e`d3cEtpX|DJ3c8ly}Xgt z%F#TyE2(7?$t9~-Ua1!0(Gyaz0i-HFEBt#!FpbJv5@J~oCya9gwCk9IEA)FHsvQ}x zmHTD;_>DvFT%4fm-TRz;FTa_j1zwdB*FXAn$Al++@=Hy^RGAgk@p-_3(As<{d%T}G zqiO`uvT6*v{?|kdHWzk@ccVBju+}N~EZyK#RxU#TU(0<0Vj0UF~v92!IE`COp!rg`%xLyid zO)OPoP3aYNFj4Sx^>7E>4~;)_O$rW_{H0ZQ_m1M{h%z`G$zXX_)0L-obRR#qJvQf> zsmo#N8qAF^akjNl`FfgRVVbe9+YS*X6MgbZ_4eoP#Kh^SR~sTEvH|%#DP`Q}zqe&y z&-Q(c5g{`Z+D~vL-hP#t&<8Z=`!Wg|X+UkPB8mkwyj(`O9}*&=v3@V7Z}&+pD{;3E zgwxm`9QdE?yD6C2b;7=30iltvlKJfgW7j5IG34AU=&Tpen^6zU`j9*WSI zdIjYeJjb$pOVU)CVw38*v+TTm*kfkx4z8bjX*#%qjeRQlH^^$eg_tuQ%A=u8%|?Yy zG$>6KPN9Zx2B%r;9vTL8D@w?}@be4rd~+W$WOUjqZY6Q~%z-aYeA%p!*9M|#W&$3N zZ4?NXX)qSe62vd&?hKl$+MxZQ4kjb)x1`^7b&Yi`S9o!+S86pWV{wfWzn$?rOAnD? z(U}p!l+9X$>OB#O2pgBZE{+PCQ-Jj{To7~KEf_HqJW68PM5BQY1f>EpECz(vZ1Pm?h-?D}iO^^DmcH%Nlc$_tEqDfgea z1(EZ6%e>3cuY0`4tVL$l`q+F#b6acqVJsW9nc*?i_HmjYkmcX>0LkJddDVi62i9T% zA>o=E3TVLcBCRs^wVN++!7s#_%>YE!HD&6bm{#;5uIE7rQIgtL#Hf)kqQt~|!@1q7 z1AH)RnF-?v^7|OYyz{xqSeDg(v!=V>4VTeyP|FMG&$El%d@B&-5b*>P1h4vDF71ve z!OJJtC1@t`)*7|;4vu??qGPxT6YQP$0T~6ifxoWKz4zCorZ^KuZxUR8wINVx2Gnhs z#K^pm9Tr-C^EI5wt3Z^i6e8uLZZWkACm~SqFGxzB6TrWx%8OvX!Lq+daon$=_cqno zlRs?ZR4wlwj%1_bqFBiMFuMP5dU%%PDkRxK(s3ZTvfvUKzY( z%5V9kKE84de9p{9WjlGZf()+7jZil)d45cZyx&1(JFUUxX^o(er`eatl7uYDrI9(l zn~Dy)2JVmm9Ae>{4oKQX{uaC>#-F*}&sANP6)(vcx}x2>itNpP)gjjLhREN)J#gWe zagnuy<}pB@3G6WLycGN#S-UOviM;acu@SN_mB_>2!fu;&x|C7T0?=_TXl#Mp0K@=tgq29Rq#r0sT zIlU@{c%xgxZE3|tWi0#D+O8t46n~+IaDZ@-zlOw@!FAa}Bq36Iy_1sBoKNtvdj6mo zRs7x`5?Rfuy(oP*P2MkGyq`a*4|+mPW#;M4ZK^EC*v{D|+viP%G@`D3wE{#j9PW}O z2x$WIa->YAiMu>lqiW5?ZSfLnK9a>oV?(vVZ7QSK?eeQO&+FT1UZq(! z8GMQlF~50g?GR0EE~aGs_@DTfgt%TH-oP*Yfr())*&D^O)?JT^6EkQtjDgVbm~`PQ zr_$d>_&&9QG{gg!laaSFddMACLI(rXh!i@%A|mF)fX2wphpK#N2bfhb#>wcIT%#h` z&tCxlsVan_09PT)AYi&k+@oC|GtBU38VD-99Ko9pagx7+YDV~Is8A<`=8mU9hsyguOfje zvf_-0r5qqpNdXk%L-6COYM#NT8tXzpb)z{Y%Tq3;k=?OD;d>c>7H*52pWUrXeySObL{gjBwGkoCBAiHg}F@3R50NXgs^?d z`haM;mCxA2o^)uxMuh|;nRh{=1A}GdMnc^xw}#g01Y3obEOvMas{Uy{$PIAIIM*y2 z$E0Du^NtmWj&>ijEw1;t5`@3_!olS*fd(Umnzu{rNj*UC>j|>60tDnZG?*M}YV`>~ zQ{=j-)pC)1ZGQP5KWsez;N0^b$j584qZ9VKRR~lAS3iEC2#LEXhQfeYDe!<}TrQvV zpRk)>*E)GWaBUGI@I-scUf^8|ObO7j>HFje4>otmF9OCE+mdXNZ3=zmRG zUMWk@G{cgp`vee`3(8+WD*q*r(aWpxJ*;@3eQ(^_=CwdL2PcZwUrxVa|8*U+GEj7s zX~M+)kz8i)M(gYQc%{#KO_Lk^dQp&!l7Ipq^S_Q&R)~!x0eTTOg=e$H2FCt{boW5w zS3(|tk^3kMs|-?;F&u0}VYDB>5raK>QkKx2Z8 z{;iX?{X1oT)rz`|H| z!U;Xa_}^*_D}y>I^GVgsmeBZJ-L#8$RGuXJACYs`31Nkx4ss}Ho5&nz67Q??F-N}K zzG3ERIaMI*zW>5SSt36jObnk2&%%yr(JcGRO~+3sxqX`Lk9F*1On%e!DwKHt2XBDU zDMi!x4vrROcF??}quf87sL866;uU&RDq4_#W+H=745$|l%jY4mRQ}U5RbAo`DaM*0 zX(Y(U^TM}k?g%!9uS{C2lY8(o|1Y5S-(rTfT2b1U{C2Ej9o-YU|8+X`^PsbRO&$|o z1epQ>mUZUOS>(9H9`a9LvocjS$89)$cFgCQH@zK$prSe#=h<^_*6vz&zzfWt<4@wez@LBO#o1sI zdDfpL*5?~#jVi(~`uuB578Rg&Rbj}dm0J=<-|;7(Sv0LF1(SWXqNE!%k7%_xbx^)6 zLQi)p9pHfezZQU{J#w_aqgTH#x;_FlPd%-`Wb)~bm~Lummfgmd>5VDO<=$Gs!x;F_ zH5vW0MZ%7MeY%38#0>vX*>on*-EQ{7k(#b{K3ewc2t`E1BZwASnc&>ieuk*7?#xja z|J-UsVy*fuDYUY#!-*z>Ze9%C2v2_N4B=1F>y55|MoO$(@t-ytFe3AME}xrg$bL7{ z18?7IVHwo}omt0I?iCe|jDv~c?4dePrw$%DR3^eHW;|_3Lf6j6%`Y(FDyPyxUBKb~ zvo56;u<1X9JaAho~(i*$D*4bolje!jo!{R5u!oNLaRnS1VuQ(8kN zS{ZO$@H`8Fsa?7byIFG65nB8CF3U4h~7p07zD=%@q{FcxRzg$)k4P}2U}O=PsC)U z2G&(2ux3dGlym#5m9-_V#nk? z8c)_wW~q6%_sh4DZy&ycmB!x8cSd5aVHj-hB?*`rEMIUvQY!^^J@Gw%`5yq;5qr!2 zv}aiTArPmLg6PScaNUtdAzP20-`M?sJQXF%Z+ydp6aZI>0)K9&Dj&(LmQ*RWELeq1 ztTd;f+OxwBsl0<*p~DtdtySW|qJ{6POW!h3#D7?OZ-!U3+}>a1scFthKQkjY^dj_4 z=W@CTw839I!b*d#-qsRp>`j$cs^L6|&4nlq)y0oN^R?9es*fiNYR%{hiM0*WtStKa zpf|aT&6OS()H>s{|IvCZ>(X;eQGU7i7+3l$Gq5(@oFm2JG!6ECOK@IR-`Zf+%%DAh z=c2ToavYVGz!xjju2x-BNsjcv($CJ8YQvFT6~bx@{}rd$@s@oLl1NaUY#CZ?W;u*o z`iQoklc1UI6Q$h6#Ti|RKNN(7=fjoh|ET(zwSiso>dakX^`%`gSHG7M0$_E3iuUr1 z65%J0@-y*#e?0dkuMbU~?joP=pPIElCqyh}%y`|Dnx@ZJHeR3$<)}XjAJ36!{}1uW z&@@<`*icK*v&M&)$OBH_UR&laR;32{i}Sd^ZV|0?C308vM~(x(*J@_y4?b3TPh$i_ z32cO(1jTt!+4?|oLMoqn^UssyM?fC)C)W&abgu|3Wq9o6)s9KF77yNO{wx3QvN4=y)nNRoHwJVRU|MFc-nKs9EHl0$=Bj{x9D0~dfvNSx}{E58F z#~;*}aUo&S)S%bBczjepSTd56W)%M_g(plPf%{qaIs=mimC2{>`&s8DBmX=FMi;-O z+7YDgEdWyK`Vp2|>!+RddqxRfVV{kpLXCVnH&%lv+&%!733Mi2humi~Sx|X@IY50% zVClq;oEHY2&*m&Ph;*!q&-})Ck#lK5$80gbW&U_3+j+Zg+PFI|43hpNoAFs*Zpy+1 znT}jeuVQ=gEZ=<3hA!p9;GgfRsg@5BGfnyyf-7wKD~`8TPPn=v;);X4Qkcy<_fNas zFXuaNt_H7~s}NB09(2lo?-&trY5c!f%7H^GAkWHyPDZ5b6CD3FI06ZF{g<>W~UFTH@_$l2i3Y~{~HKte?B&}2xLbdfJdgGgE)W!?6 z`<@SZL*>khn;8b$FU7xIijMxZSG5*o&X-o+brvs8-E)=B_xBkB<5r&3atKT$GF)#1 zqrL5q0rDS+={%KYpvqc`leSe;%PG{<1q0u{s6j&74AFH%)5q+aKfe{&F#{I#lofwP zC(V4fPf?=%eO8u79(!v$@b2F)YV7J>D`zvOd9PHwKB`L0tCo=lV{zsNs1e9ro@eam z>wwE~ioa304#n23UCDpdx9lW&I3F;mS|B0O(QMr+YTwP54}Z^u*FURA)U{uyHVi$P z>8>TzhFoeB=G2glTUKe28&AX+-$|?O)VZ_pq-LnC_OKxEn7QAv2UyHZqxzUXYKKDv zI^t@XO3ozpd5o@>w9ci1Iu`sRL*!}Z;yeENtyg`#FdSP9AwXqC-78*9jXC^h;r=A* zQH51=6NNevhO4|azvyBVp!~~3UD)9#D3Jysl>i1xAC1F;67ZJdb<5TL{HCm^U|H=w zZ`Ui|DsGuuXv+dgKg9ToNE|~*X|>MnV1&wL*4*AhDdvx{-KOtzT@wXggXZ&sycJ#< zRxWsNT!7-|e@4Y49_n7J7Ji%|x%2rZacRLh%V&yTV6G?C&-eClymHS)Mk1l{c?)Y7 zb37-h#q_BR;WsgaPE}+2lO!cHdRdVS0iCzvUQyzVIuc(jepR`DNw}V&QPS8tqyQsQ zj=zz_^jKb`|^JcDOvNPImVs74? zo~k058R&Y&-&M~m#dhob0UG`i!Eoy7WYQKnIN{XZwyvjBsn<06Aqnb=wJg>7(9 z>hxRg2lYReCYHE%j9DbN0=z2dNLEU(#O+Nr%oh3-n<}vF^M(9MN(3Q@R)*#!I!n$=?0p%C zZTNkBx7^^=_iH&KUG6b4baAX~)kk-QZU-+?s~-l{Waws_Zw4P$JEXpyl#^H{6Mkst zqd$Qs>l)Swy#Qin*&NXA+C2y2bz6g>v!n&eeJ{{Gu{@dS3UR?a<^xWm)G5>2qurTqjiS`p!kcD$CF zPd-FFNsB+V-dC8i2R4w|%X}G~IduW#CxbK-I*9MQV2_W4wrUPDg^#4ng0I6|mzS9^%R%8vcvw?)Y|I!OOC#S*f7_}im#`6_pde5|=A6x*mwy~{)RwyD z$>JwM`Sj*Ya3J=P#FQ0YQpLUF5Xbp$WKP>Xzwb3vKkdF7da1krcxEjy*6z+|f!`eQ z)Ls4?(yyj5nB|K+bWM6{+We+F9k{IswOk+ZORd331qNf{6ovp{bxR*l=m%;9H!p4|2&Fr+6Mgpcx-KGtjcf9sNvMT> ztu{)UtIXxjG$mJtJ^B>7B$4fjgqFS)s96_FSEc5C#vB_?y7bm2y_TVK&{R3x_Obtrx{1_$tmq#Ruk=Z6 zqj*>0o^d|3Zag+b1m^;<4IysroAje$Omq^6uExy@i*_qpyo4zRku^XXAyBdA$&{4`szRWGz--bwe32u11LxONrbCiyM&&DZ>en2BKrY#N`q%e>453UNmu@Uxca1 zKu|H9ix=2+T*P%xbhfaFBSm#uDH_*Sz!Y!57KZCEtgaw%+~+Nutqj-C{`go{L^$`| zP@QXy^RM#MP3e^$92%)Q9R1}Nf=m<> z6jf*BrZk!t{Vq%O!NGOFlo#EnSh$^*R=4yQ<~M01fCpFkc$;%Ji84wNVf?aKxXVRZ z@854?2($i*U=P|n5^g0tS6z<&EasvFkYUUDOSFkROVT)ErJ7#?Qj7nXQY_<1d=f3U z($MQ0%pzP%VPlw;JEpjm{_-a5o<)9Qo%c*JaZA68{O@@Uwm1(dm;@@Cn6t4_Wphb< z`YHz)k4nt3h8|rpOcumzF}|Jpy*#$EenHYV_(8cK=cyq*gi(=0UMGk;#{U|yBU!YK zn|6`N7>AvWC~Wzjj>}ep$TggH2c938QYXE5HhArAq{RnM`YLO*S?Er$l@S}~`54Pd z;U9(~JH1-88uw=Dv0srs!~X_u`EF!paV=D2LB558`PjdYRNHtQyejRDF&B0;%>(^9 zqnEXd)5~f1xYyyA_h?X^K9;pQRfx$%z%5S;at-(FM||ch%N+Ucvh8|s`MJId71UF> z^Bh~P9aG6c<}+PN5Ua;_^YRZ`M4UTqWAb?}%UApF6Rh6Ba0_7#YtgZ2p@7A%X)%dM%puRl9 zA1US;e8WC#_!gDhUPx1P=*t_U5KHGjFXXi4>nWe9n-5(B@?UfNFS&fX=rCj}rU1th z6}?;-29Z2eyzoy9W{m!@ta_b|;yT{js5+m5r$0s-JW0`y^z+HVZ6~wpR|s)&YUac_ zF&yg;+O+wCB6Dxd9n&X)Gvpap{fuS3V*?rfFs$o=8zMRR=>p%TK1x!P)KR{RL?~m8 zTqc@JP|(1na6xW*D$^Hr8dnTZ@K(L5Wb3O<8W<5{gVF4DFVetsz)^&l1?BNaVp44G zyA81W6MO#FD8#<&*^pP!sDebP2PLD^jc$)O7jy_Ya(eOnY=54Wz{~7CafHPgiy_VV zm8gx3*6-I0>5^oNk6iOf-*W=MWl?Lr3LFf7su>pPz)utkc}-(%q~qmSmsKgOtPK6{ zpBf+vS%o%=~e%>H`Wn_1k_I)wIYv+TF9%^(TN;%ohL`FDEJjU1xBM ztRN&C!@F!bu&StD)4P{2&U&U8^yIV&m0z4U!--OMVi-_1J$K0N{Wo`wFzEKDM%$}e zMP2{V4yozfj=x_L?PeLRxhNa<=4e3n`bxv?!;#aj!0VnK4h1&gmDU?Z2{&AX`QB16j42hUfu zUyj0MzoU6zNHp|n@qI|_G>e9I&XM825sOFFYj1%D)}w_L%E>wNKVdIZwBpvAo^b*&id+{6i1b#AIw z-(F1_t5@7@k~orNtS2AKmSfoMYM6#j!y4V}{sPkQJp737Jm$56Cmi(D0sYs{ftELJ z)T1<2^j=aZ?y1-UuH?~t>nkqqD5Hip+IkX7yGOOXLQy7gFqg|1f~DB{_9?fP+5p!g zv#(qX{uiUaGv3k)r&=(_dpFYuJPm`Lf>e7wze9+1S+Zni4^tbV}I;{D&G%M{`JzNJ8EIKTJc zB7FRA}ElgB%j7K}++h%!dMjTviPbUa=yLN>8x zycnn4(^cKlhxuQ-Qin=K?LLSaM#@M#N@Qgkr;8KA>8EnGtMCj6&!#)?X6?CFHB1}J$*%R+l-GR(rlfn_WL zbM^3@UluagTG}>?lve_dYD;k~1A6cUBJ8RNJ`66vWP=Vi`K;n zNg7!rWBwlK=Xa~VSv!6q4{@|y%HjE%Z#8WVk%OeZ}e{ zrii65w>_^80FSW6i=~cjUM-R^&jWbtv!@bBV8z1mxrL?t4@gWxEGv`=2 z2oxH@Db##wPG<|ma0;(#`LGJ zsQVL_!LlOE@!p>Bh@HN!+woAYk)mEA;6Y9U)(Wnt6AAnULuh$x-fW8neZ=V782j5y z)nD?Bn4qb9oGVw$--bXECt63>MWuR-#wSPRm3Ia!e`Zb$!~gB9-ZKEq*TUyYtvcOM`J#xQTd;o58mqIPGv!lWCIq zRSCS%GW!TXb8f^-I?9^&?DBy=+Ap#04XhmlBzE8}Z!kV!EycM+DYQJqwWzY<31Tgg z$$c@Rzff{8s8HQ8mbU?H*sPGiX@39sT46lV@tgIE-;o%!AF4GntituhB)c|SZ0U1L zzy;}eNg`^>1elKxh9|jas(>#dEa<`Oz~a+OTru)bR#yRXlqCwJZ<*ixqh7(9=$Rt~ zMdcA#SEvoAY#D&Iae#|^vF%KJeogn7Gq^NbGZbFE$yl?VuoHhFEvf)_bFDP05FCu6V1Ul_W%&4P0CrUmf!&3+;&gSVBp*+pRgV3hy-IkvB#)?~#^25$C zDC-_mtMz_%-u&eNI6m81^TSEX#@(llHPDuw%7&b2t(ZkV&8>FRpXp!ydOrclaS$V< z>Mc%|^Gor+qb;NV%pf?$2kSH|5fW71F^qi5Kin#mmLM}+lE_e}iZ$&Fv{P6zdnDO? ztBAQD-V*o~YZhn?lg097YWh>5%DE7b)OaC9iSF8gvxIF_sIzj2?nv(;73jfFMG5^D z14-qNF2V4`8iPnqOES-cg)kW@q-gym-^$ww3qM|AMS)-}$`W{S4m?SNRrYS7n`Nf|Ano_#SXyuxC!1bsdg zjh*EceT|n3(Ps^a`g?Kmx>tuNIIFA))=OO?4|xN-#^$%I1**YlRLF4Z_*fBE3Eh#| z3O6;R(|f1v)HIqz#0)FP0Op~VUL*9h3>lm2-=vp$D7FaJpCqVtRL;vbYnaK~eAb8y z50T1=)oNmzTdL9c3u`eM{HE&tTxxmIwCK-H3?*r#h8YUi18T&2Itwi7*!W`i~yl*!6FB3z^A59YJhLHo`kJ|5%UkslT^h%(&>R&)&l$*@P8hw$x zmyOfSFXs7xCzK1hb~6Q)@%F;NB~9_rQoGb;Lm7t$-Y#HK zjCfRI*}JFe2ODqXCMAl6?qhS8%cq^N7Il2tQS?>$db1qF0SE zbEMHzp~znD^?gk1I`gGAtfvRjm>P2;h2wh0i(o2|`$C(B2>K&RF?%C52^4y8d{U{> z9gvcr=LN%{%M;)3pc2vFuDS zV_81R&dqY&+WbdXfKU{(i-VZZnKoV0Qr7U?kd%2Ou{*z?Q*K--2&5K(iEZJ+dJP{3 zXFuGuv9g`_D|3D*xQ8O0Pp$&K6dZquEa9>AW&|`<2Hp_LLBuM{kc&xy!>h0S?^xPH zSrO4=gWYf-=i^%Lx5o-)x>42mg-3y19VGU-3b}F2j_!ww;mIraqT^FD+(a&fb<9Z0KkG&?YP>>PB5ckSIA!S&sY#VPd$M7=OMS zbIjbXW+>bX*owff#?^=KSX+CZ_@ z&+#qkcfNf0$=QDJ!9WaOwOIFA*0#3XcWQ^8h9ZBdvID@TGGAGa_OlgC(}O4Uzw7;OBm7(uB3t?F$TMR;TFZZHm96S=E2n3+rdJh-{rtaM zGKQc0@T~I;r@eW1VF=zUT8~c)m)Pj)y0e!lvwBTyv3d-cuU#?ba^IkGiAO2Aa+*b( zXJ$@$f5N#?jpX=HmS=h_?s?yu@O9=~gu9QKqF^~XCUY?i7c2>2Q^84Y3n#QxOG=rK z*f}j~u^kJXVt=PIFMd}h8PxQw9Ko7;>x!v!cJ=JnK~_BjsDOsQU~)YRR|xmtS)XEA zn(v+GN?Lt9`^T3}=3LvWZS^0+|KwRXavj-wuB(WRVHAsbN)s}*$=PHGgqAWHBjmWZ z?4WAlm?;3)f<`S-%~!s6){*JU*#`|I9G~`;xUnz0uP6Tz^FG?YYwgm#d5lx(7Xs}( zKfn6C7%ija?y=cY3gUYCV(;xR+Flny!6fuTV4SZI%s@7Is*{tCE5V7sA3nTTs^GQk z29R+Wvj2Z_I6L-FqA1=p(=tcG=I zeWg(21L~@^W6{tjK_fkg2v4H4$Lw6&WUEteWryJ}N%;2=>LPbe%3h2I{5v5xg6f%6 zrj%vMI)d-v8}DPf4&ybP6cn5u&8(9!wHn@k32Uba#@+JI` zPKR*M4*%n;s&-PC%ZUT4wPBmP;CbEPPRVw29gJ!Ik@ZS2hO;?AOSK1>r7)QHNV(!u zgnY>83V?@L8GLaP)+%I*T|I%xx=42p3PM`cjR<*twhQQ! zO0gIb2~8mZ&vUuwjaFQR*Nc#ewcme!;pEfLKbia012r(t*UzEu;}-2Lx2y#e%iP|} zC{!?}aK4CUp@P4#M}_u+lLKibccpLNoDoZtfvQ919!FPD>@P8F{bve)SDowOLI_*X zRgaP!(7yH1@0gE50Un`q0fcj zrs~CFRZNSMh(ea-Jg3T@y67bD7a{W; z5NGN;tz$6vFizviXzixYgO$&roqSu_|AiPznyrBihEE^TMG zH>s;6MDAZ=@_g%;hqNG{ka)|c9g|+Fu?0;f11(RjG|pZ}f{FA=5B1e9|J00J(|Jj; z;weORo)zW*Kl`mdHe`RiaC^D2Z@uCQ^mkV0E_wzAm!q+LYsUccDMM5+|?65yovC(Tj- zW3>Hru0Xih+a0#)46biQ<1?eHE_{wwuijNW*#W08ne9~Tzj(ehyarvJeA8n< z_h;V^3E8e(q07tbbTSKQUbWJB4Cl*p8G>kf2jeH}k3MjUeCJN2OC3@^wQ6y-{rzNL zp||kU#F57Aj;xv#txzWs$B{rrua>QB;cLb26hFybw_z|GLa~J@nL8Rs7VbyJk#o>s zakFe+>%q`e`HG#w-pjP!jrkvgb&NyaikrUg9mm<1%T5;X2Y5i5{sv2ZIJ-6caJsC0Q$5q6+Jwty9wV$_R3hpL7c zIsDfJ)n?sCig}9ZkVvD7T#AQgq~}*_Hp^#Pn6h+r8xc8}>AY0^nel<5$z54Ci@o|6 zSg_4=F@K4T4OXb)z^Y5RRR%;;Bdc_4h5_u#FseT4>l}$J!*9}MU`4QuNq@Q&3ZOp_ zf09QvZAq?`4w+irt$U~WB+pzhJJMfmwkQ#$ugt}pR7@KlR*+9r{%=*`GKSwF^|+Yu zkJv!dWdD(Lb3r(d{~ZTULjL+OJoFFgrEhBHWHx@Y569}ZQ1mr2F>3};1du1@>wWqw z&fbxM(f8+#JgXw>%&*rQvwG|=S2H%;9(4v9Jf4D2e8a}3Vq=M!Tzv*KX1A$T*6$&w z4b-fP0AJxgEd0;2{~RdrGqmPJ#pQx8aW>B_uzj>wj=2mxFY!H}89UoWzASjg=a)#5 zYv&O6r!>6Q<`s9!tdh;m(g{{I10izG={hPQnWbVk47T;W87-dn)m<$w7cpt)dac<0 zSYJbU3toS*smub=D&RKml`hh=G2bC4ngbi77JQyAGiE1%uf0u?lsVoWhBB z>gU`F33Lbxmmrm#&n4IPy;Cs74jGkRh>U6XygO&B=4zrm*aQ0~o-=(0de)#^DRin? z98nX=owB&mlJPNEYz+19^p!Kv^kV>Q6r-<+Bdo&^urswBM{i>sr8rQ7^l7CNI-*)c)N<)p7ZL$Jmn0h*u|~r=;5(v zFdg7FM4A;5Aj@4)1l3u^nG&0x4w&W&5zJe@?vc zDo@6@oU~|;6%zpox=m4Rl{W||F*$cqUql_)!wDTX5_JyJS)huQv+)vV-WEOLZzT+_&p z+PYRZ{qIDJ8aovo1?F}Ap0FT`G=Z;Fqqx%#+~O|`ocL56@BRTNCvZdJ5;|AkA6-qd z29w8JnL_6TDz_+VK9d{b6cR{bvA_ z6P=_~Kerw!^E2Fg(~7TBl;`z?ZqfT|d&7wE1Dzg=$JQvN^h&b=KfGb72 zaE}T0ztC(ke6M^E^^t(h%~H7sJso4Nl*O9h0|*YpkYg>6@D$v*(0k9Kq+ zC@AIy)<2?nY%cQ7!}TW>-*a0``q_pLFT@?mjWXT~yO)L`%k=XO3)YUu4SruX zZmBYA>eq=)8TMJZisv3SRAy?4fxVdjIlSy15RN0|&U2;S7@uIPB(*11v1yEkmGV{3 zvB$fZl)~K~boxWiNgH@JkHv@9eU$2%eQebVJ*{!o#FR2+ z#k|}_g=?N(F&#K;M0?cWgJ5Y&wqjp@W$Z^9g-_sF2nR2+F^nkCs3jz{uk%LOtD=c_ zbOaZ}spcvfAo)7ed_b`xIkQ6qT9MzL%#pgH0Y&g-I#Y*<$wrT9Qjs2*GJuoa8sk|H zn?o2(&odYD)L;x?uI-|`Bbg$5sjysjJdDR(wP2#iH~0c)R~)RtwaCSh{h;T>NPBfT zh(M+M?5}XRfu|XKAKb(FSOc!b%#F&jfvHPA^J?T3ovy~OF2)Y{VaMVEskzKg3wuEK z4(0#}xh%;yXxK=Q!mk;Yah!I$^zugyN=0nMh@sHPSAYS}#$XBO$k$eRk?lDj=i;>F9^6(C_g$vVE-iC_$bh@WoHeM0Cw2#(eI;^n zYCp&Um$ZStad6$|)K`bQABrODF0SSEqn@FQBIK7I_)^L$;d>_>`O)}s{#E->VW!o6 z{~WQf@v`viFL}AHoa!>^e2Nm|EH2(P-UT4DwPU!|_*5dWaLw2EPPv^WgFhj(*fCsV zAWfW3A`YSglPa zY}5ePoW&jPyRU377US}g?@zC-g0QrNGfDKPz65pPQKg^@|HA6R`f;;l0535dIzvY1ylwjztd*w=LQ^w+1rXADfdOU10FQ%j3Q2DdC zwsyguxzwUmsP(L;tjo7j_4tdZC#;HXX0qeB`=oLs`x*8$D*hWIwug}xXB3N@$Tw&U zlpPoXs)>)v2;sFHr)Bx37sx)IV3;Abu-@(lT~?f7qYpKpUjK81SWMrwA~M&k@yTVW zj1^>Kl7m!&=+Ee>EK637Z#jo?;SztSwPhQ|qS?L|hMLW&ig5Z35xYs1RNByIM0+iK z6zyHlAc)2w*54sA!RHsbuu1y{@b-a|tfmesUAI0fuB)`1R;y@+AgWXNSs@SzEKrA1M z(#LxxyYS-&5tBJziWgO}7Kz@khgo;uJ8E->ZYM5H^(@|q(N*rl=t~SdK!b$Ehu0Cp zsn@>UPHfPURaD9pf-iw!L=F1AP9gtIFq+4HuIW2?{uW2H!h;b6ny1Ra)Z~XA0}ON_0;)M-*3(U}Bgh5Set3ax>=^=2z&6z73HJc}P1$ey; zW!^TRgifvwnE(AM_-96ebBQrB-5X_Z{%W5KedS95 zlQO#`qaKN*de^71$h@@F?1XvQe&|F21B}W^Mc`3%+$Y@w}By&a%jl>iJWIliVozh_>5THTt z*DM}&-yBBK`oNqt9iQnwEWLn8ZxuxcCTMS`@StCF3GWtOEtH^Dwxu8J@N%5ea7EWN z;z=#YKpXf!FklbEWAqx3@&t0|I3eIp57ueNA&d19Cx-EL0{D2~ZDq~Q@Mpa&@~~>W z^j0?Xsu81`=;9b>0rcyAVH$()3=EVeF5+*%i?Ei4lyF49F0n|QrEuuLwg>v&+a9Wl z9$l>hY0TkBv&nCn7UnzN@b3n8#Zv$EAP$5&?Cjq<7AR8oZ(4$F2RYOJUC9qqXM zx|h?QFhRh{zn8<3k6=8sB`3 z<9VqC(ZMA)G_5CLLF@JcZEI)4>gPg#xiU-&CqLY!CZ>Ky4x(=c+SmmS`GdE=yjhmz zrHxL?n&^uI^Ei+pzl1R9GHZ8t4xd`^rN|?_s-`E~=;<;*NIJ-rehkm{8fD;yhz!8^>HfTB)2v z@=d2S?FST>_wVgFZYJzT(5Ez5<^868brbW2WsN|0HTpnPph;qXJP|DT_v%!yJ=Tsj zE#|PRWhxVFA+#9Dmg5&nrBDLWOBM7l!_5fdTrTu#F;gtf6q7?rci&`0EjFVO$%)k( zSX$v2A^)P-io*Jup4jvz+mPCdPpE5hayoo_j)AK8)0*2Ju%ftej1#ik$(k@Zi%;zM z|CbsXv+Ao1NJ3w7hzI(%>1^-kJb?mrfu^ZzVF3bdnr7yU`>xV`(0?}{2MrV+!JzA@=y ze-G;2h(ZhJAjV59APV^m&?6S0NNA2xNmcpri=v&)mxkqkrFaoy0lae<+ErrcHHqOg zmDK%nrr2f*xK=#(zcr6%_&+a(APva}tXJUefOdxH4KNlPZX51f(w`rWAk?AnJX+g1 zd;Qg)DpKPCDzHh_e&zIsel(;ZH+X`6niQ3t-i`?QPIGn5Bo8qVSf0&=7uQhS+k$DB zhaw|$|7TagqG;3h-{Fu^_3m16cjJA~Q2~_=5ss5yVIDnMAvAYSMLcsOJYufos>E}1 z>5)J`B|w%M4OzwuMPPlm;H!HU3rehGdxPPMsSvGJE_R`$GNT{zE@ZWxc!jNf9{JoV zq%4Feq=ZjM$pE{5hmFEJNTq0q($(7e!Z#L%MyhB+*8ZIidr1Na?H?1gr}TmnztzcbT0 zb#x;BF`z{8tfcmjNoh-Y!mZ4WxQ(J!`#zz`No3>ZE41eCEz{h$Ed!aQK7XCly^1?P zKBC*cNgtu=9QmMX=4iiHM)h`RV!rBIV7Xocs+nDwu`?n3KS7DH1}shWaP}GyZ{mjYXm;jK5t9zU7CZRnOLfasj_2U(q_6<^ zfKcSkd2ET0%S0@J^`M>9(F<-<`H--Dt57JH$bQUBbpwV8$9VhfcCOAR8OoL=y$zh2 z#IqP$qNK`K);Qm2+Rr}MPe!X{TJxX>2%T`xPoNQwh?CkpT7JTev1t86Z*Hs#)^`(~ zrH*8FdDk(YMeGE)!#Bm%Q4Kn&NMtz@iT)a7_*1k~=7W}>tNhXR%$d#VAu)HN4Ja@4 zW)A^2bP^58H%<}vN0&Vf+KCty1b-fQP-1yV4-w^~>xEDRAei3uY9@f`9G_R0GM2Zd$>G>H2C|`Tb$6q58%e^#!uNi zMxRic^!4+U(qF0vjf`9J^S$xvR*WG4PxkJQtX43u0woA|vzpCt(Y=apVl=#{IgX)|w1VG0^JsZvvR-H)62+gze%`%r;|w2NtVn5Dx@UakML3dn8k{|qRoz|>!qHs(`EWi*+8Z5_oOxpJ|N3 z9F?Fwq@9U&x6VI1L6K)D?|;}!=q6(ttU%H$Tg%_7hA}$=E4uB5#`V|Wl}nA&D>BN( z_h#*F7csABdkc&fk&ZlWTt{L?0Tp}8(!^H`N5Q=#|0q}Xw*T%D5NSf^cApU? za^9N3F7GfXlb6h_GHR*&)kms+Z8bQc&!nJNMT-mz8Zmte1Z;h5ubg>~49SAG4SE3AH{Y*pINV0?<313ie!0u2 zP-Y$ZV%g6ebz}Vj(3Vl<+ML55P6zm)v}8ORzygF$`g21oN zmz7zqO+uG8s87@~ze$xdHh%H->tM9SsAU!=HGb>SSvl13oTc*`X;8BDDglCEff$WU zi$$!;cvt)|?YEbq9*yW&UD^5UigRp*miKtrbwpf> zEq-?)B1TnhzLh#-{t?p!v=JMuSCt?Atb6P~gA!+Jfn~NliW7)SKqZ^qn>ilpVc8!C zzW+0BsP3;gQE~HZS4~}tTjq|Oz=}=D!Qv5nh$IU@S?xkNUIEb4nytu4VjI_7t+`Zj z{`(;*2!htPAh9OPd;Ez8J+RF^CV^C8&t@wn2+YD#Fb+X|$Zor0Wyt#O{oeXI?H#^c z=*=h|m$D<_PA8QHRW#l1(>{Ql^P?@t@@eTZk9Myt4Z$dHPTMBBzjGf6EaH1F?kRdi zwlb{2r1{kR(wkbqOQ@K?3D-eW_T@d;%=fO8wak=_E;rc@uxlWs{^8%(u1~V;H4PpH z;Ss3k^*(QWCn?`%D&?B~M9n=1o=d@HMfa&JU&b8W$i^7l zif>46ALfkAdW=NPfwpDtRV)MW;7L)4oXDWXSCJJ ziRY_2M%%S*PqvwJW|kgn?N5oj;nW@U>K)8S$C)b4)Q^M; z5z*I0RUM^=CKMgv{n!xbzw3NwSpQ`x^Z3_=>8P=?pun+Q4%ZM@CVoMfNDvpb7(U+U z&TV5Lar`es>knV}2Z0N~(KtB!FC4fm2@x&S#a7p@Il`2W+jsBO>U~^(Yg2#2p5!$o6t=p7tHeCwpSuy&Am?~ik5NjIg6C6zXQAuItOmp%LGBP&rZO5xx^_$i!tP@aAT zVg>rJSkM#=>UjsN`DYQT`YT?W@FFa%Y@+?Q3lB z10dB?+HUO-gz;hoSVfGYh-SI_lw*6#yP+=-Jy2UKYNg& zjMmr&O(g%H$r@FvCX;=;X$7Ghxy%+u72+m{Yh=4=nY>Bb_)N;3_IMVIKdUdz%`y#F zf;CKY+%0Ctk7-_;IEq9~kY_p&-R9oYYM`-CJ+|WHky!P6Kb0TtQM7!y{A+nA_Zp7*pHZ-0 z5ORJ@J9duMU*5ctIx~btGr*{qdFC@Gi9tGx=32DqqE2qa#G;!+OH4c7z+Qg37vQoU z6 zbJW+5)fbEs9iGJKGE^jwZr~40MBtP15K({h(@-f`4 zTIVXU13Zf8;>G0YT_zv#AuHsOJ#*MU))Y!C;DjhphxAIP#d7tSk_}3fhEZ-L%XPfH zVZ33mll>BUAv`HsZrLUBKjnx|{+O-EQQxU{*OeIRF&V-XiFXhT~`IAS+ zO7V$@#!9)0%I7L%RnGmzHqb_M)syYNYLB^(R`TIV8@{?w8a~nwnF<`2nNx(C?^(6u?v^9*Kb|`!W$AiCGAPr5g;ezEysYO^h*nzz=g!$=<6fUaD_f-xv&zZIuOGHO`VTB+an1Jgk^bFTAzXzgN)Jpw&_z86bMkWx z?T)cDRLBcl|U*>D0f*DkOD!eW5PAfntYl1tMndS+KA{HO;}*d#&dR*$$Q zViGlfAOT}a9I(kzD!(B>!S{|@A^yaE$emV2`F|z`Cu2P8#p^5VOz<0v=b89p4i~t5IVNgBwl~xPFszhIJvJlCtXSNh( z4rNZ_tmp26OyGT9*bz8U?#o_o!kC%OwYv7%18dY@Y~7D+|4TwxAy-t#a(2$I2wn@?!6@cofa(5TyBh!e*I}ixht=L5-o50iY@$pFP9oTSl+e^;=4(# zT5UD^_^4b1hv*ek@CANItw4t$YfWlaKF3EUO2N9-k)CY)ig&f2D~lC=evPMBk}wFztKZ z*4#5sy$M+g3Xn@Btn5U~;sXvRAADvn`cf6=iEt=FYkEB<6@*Ys4Qt1T_p)s=E3Xl? z>oy?o#M$g|0(nxk&i)9cX)08R&4cFxQSvdTE4&5N?q#yv-%T_G@C^ zRBYe}-0Zme(!8FrHz5!qmS%TMdXD70U?(44cug$_BM@I*vd?NpwG9uGP~I+_o3k%} z-S>+p7`|>>BWwl-AY{6w3xD|_2WGna1Y~0{46cEr#gYud$xrBW0X4sEWm&7ihr_B- zSGIpF`RdKn9Gh1+K&w$SwjVFqz}I}=`~6g`l&nOMB$M|2Y>?>a!=(vq68Szy9_fUD zdY0fo{=R|nBCNuTH>u`M{>y^{KnMD2mATR=L04T|;0?*EX3;L=v@qJ;JV;^vYHa<+ zSW6a}CssjY43KuM=&QWvJ9uhAAn6hht;ifuf5$RIB6Y@&^1eDKauF*t!TTcu^dteY z2?7kx1E6#9kTUu<0NCF@@#SNn4RkT6^PqK$Mwmpw0T zo&A$WyEp(YJn$MhDgP zL_gjT-z5tt-SYJ!{6p7()*f)flkoirHG6oG8iPv75^^T9mXo*l-)5>j@#(eZKm->7 zOnibA()sX|^0dD`=aDY?4XE=oFZ+C4*sDI!4*+~5`uiuP5)qJXLXvueEuVY8pBr`n z4IWkHbN_izO)m&W5AwG{To|6PKB?PeV9G*ToezLD8c@Y2wAi8&g*ULp@ERaX$h9B# zDdSZmeWy5))tn|dCnClVZK*hGq69GfU7I30f&~<*-Uw4U^mo*}gwmSC%PXM~K zQCVDz5AjL!j#_iW;r-)BmqWMCgcqAJ_kDMh;y1uJ%7aUv{vyjzbv0V4q3WaGE`Qh* zDYD_><~?1f70}G6sG+ZX*kog#S6l=oQ5@ywWeZ{5VMkucjNrN?u2Vk#b)!^%N&r=x z@+IRWX2%@pjAQaZVea=D8pottqodtYMGG-z>(~>fyK;=`zp-1T6AHadSyHp${`uDo zRZa@Ab2X)rcTm)iNFs1rBpg<|N(1LT*UXzB=WbgN=t^vmNd0p$@Hy;Nv~@|ELSkv# zBSvNU@n^7s_J;cv*+E)E1?p(!d~&pl0$}@llf|gZJFtPAkcLKcyVQ`b))LO8YGdIK zAX{yO)XBx3@zO#CU4G_Ng*@-F?!{YOMh3&1EW}RUt4B;Xs3a=zYN`S{oe|otr(3Q8 zfK-?WQF?{8Q4%2Q#paDPfM=t|qS;!=ny6kRu)SyvV}S*~@?9_O)thYuqI5s-Osz%$ zdtIVlng9F7jR6X{aC!pXYm8z^I<%Dw)A5_PbV`V^;%T~fj3qfZC774`yjAz^JI>9h znC-84sE)Yjg@D8M&>xepGKokBvC?a`p|8F&5ARBJJ@j1gZu#n>{-CR3xXw)-A7Ad; zZXEo{TiY8rXfH6b`_Juz@#tC{p*hjeC@<}_KmI^W9;ha2SEb-n<_i$70ZTH$^gd@u zUJGxSO-cD{w4B4Zq{*Vf4(1i|5NV0xThtH(>HiGV(v1$)=dh(=Yv1%AsP9|M!}NW!zu+xcJGT2%w|nM4mkd-B5p{ePP8+6y zUNi}0X^Uga>E8Rrm?EGu(oAj=+A8Bkh+F?2x>*cfCIN3di5FY}cT=c~|5ubwhAO)1 zS)hGNz$l1!<4aig>dB>#&kIgs-b-TlpWnJIwF+`kMc`N<-vJ!I&r7FKi34$4*ETZT zGc1ST7yVMR|3wAR5f*G{EfJc9^8Mn-w<%87(BC545Z-`-Cgfn`;acEBf}Rr^9qLUC zKGUqP?;k9$FPM{zimbfCP)Lw1h`-!&v>UL`$xYh^g0UK_oLg3Sf3%N4ZmiE5U31aw zWF`hpZen7+1igKUxM4CP97-l3j90-&NM}ck!N|I6bHkZ zJTd%6IES-Z)5OZn$QjUEom^|p{^7VUH&f9ZJ7mHul4}#`liNNRGEnOxHN@Xf8!-N= zZW+Mu1b;!KWIwH_z?u@|E6FjqFgG`VWsGdZe!(^*=2}~&P^tv&!u~yp9owhOck!3d zp4oIs{2ciO`y}d#-B!JKxXtloWanLWBv2wG?e)ay@aJ%bxET-R_F*+B_ah;BSo^z)w$Sx={t}c$t~6QN zLutlcb!d|#+)U}y=j@nV;en=$GWUF#)d@nFIKeM0t`;6rnE6}>9(o9(O1q=(@*8Xi zdtzvOL+zL=Nj0NC16|_3>i5td{QE}l#L2BsiSQ!edq>~-soOhjlJZevW&+O5DN6>k z{9OI*#Z%zoJAddoGL1h6}IJyJv|vOrDrR z5r-z?$HVW4hBy8uxtnta+90n!Y|{XY4o|v(gcjg{teGJ(ozTH2A5i_{Py{7*9Odq% z2vmJp>iMEWAwkc-y6x^9P!wdJkRHT>cP$<`_O8e`*M?;93%3&WxQ);B@!^&i^dbf- zuMHTwQlvamJXm`6s?RKQvlI1i(G75K?vE>P@Xc2|4Ef|k4oD_n86IExx9y>j3hj3{ z9*;JNpvIkFJ+$Qmh9~QFIEO&^KgiA&)fMw|bAM4tU_ksu>=*u*cNSjFJE@riJ<>f&@Za#>(~?|QXX|^rYA=L?_Pv#73lwjA;jC6=quiydxb-3BBSu5Ol6D2Leu`m&BosCy> zR7y=+O^TPxhj3@hjyKt4DI4Je6``~g9R;RLxq9>MQ!e%F3t|9UeaVn_NJ5V9N4vF1 zP>lpr6Ic}QS)yh-Lbj@2`$tA2OyvHu_F|>7sK4V3qkq?C7TR^*&7eKg?XTK9Yn*0F z(PJkTPy|jcfB2DxGYo>U9lFu{MF9JI-Gzr()E+6e=(f{%;mNS*f4cKufJgFYE}6jF z1WBC_PF!#l9Xz|nYq%aT@}4gSUc;kzob}G`Jes5-hnuoS(t9+`p84~%SdBHXBlqXK zhsbL*>M2XpOql`r+$450HPvTkG>j=JGv(F|2)O?lKMdWrM!FhcK(mj z!Sp!o`x};g@DhUSd)l_sAiv8M&)Lm`pV%5a_6>gah1_MHB%xP43E#!TpCI<|-<%H^ zL_-j0&^MqK>%fpcfuj8dRaIwlz?@l^cTxow)zvEnc_n?n>*~Qz)F0Bl%O!M*d91!K zItIAGDPho#m8T$dK93et&u=jN?uX)?^Fm(edzXl*fC52KCrwh`xO7+64_EA5PDr_x zPTIA|lbbk<^iqpof4-vKL~O=xqb!`S!|MPW^5={lq7O)%zJt!o&tO||$wNv(OPf9< z%f4bxNSx@aqvvSNN$2H8Xw6N=##C_VVEEFHzJ3aYSgXUT45W8?730Jx6L#Y`>9f zN;=KV?y z(e8M4fB2*0lVF66^xx$!>`rJkT`8pL5@AQDExa@;)W>f;_+HsySb}{Tme>`~7l%$$ za72ZhoDZf{ziTnhjwS^3!;zvY2c*FapeNa} z>KZBj>bAe*hxwt1li)5{_7tpdlH5&jJ8_09G|f3&_KlYYb9(da`r%Z}-!|N*;o!7i zH$1P?FbZf;t1kbTGb_1b!EnHKgP#nF~nY9$nk3R6v%%oHnR@dAo(ILdP?J zv6`h`#RbxLspOtauQO35O(k(`f?e5mU)}SDyOk(QkF& zv9PNh5>%b?wT1-j9kirJM5}dj%vAVfFH4AhPld~JI7;ly&ir&u?MfMm5MHVfK^iHn zxGta2S}B`ZZLdBwmD;%<{iy$)3vaa>DOdG5Q{h6bJ9pa^<_h~WxsM}!lA)ZKx!*(j z&3j~#?ZAzJ!t%;fO9EU_Yy5@q_5RU4iq;Hy z^3;?^*8W&(H&@KFNvv^s)%Jx86?%p~C} zQfSQJ+{7pbT_R^~2e8%9@7^``=8aMoY8(>IhBJf!4V84;M#?pbR}7TlN*6Fb#Iqwm{~-tPrG|{0-Rf zny;#`Ym(kAo2tAUI%*vyI#Ihe02NQ7sG1H6RFAs{cG(^n-r%g8C9lpdLaeugZ-SJlX7&!ovlEBq?eJMJuHnF}5r&NpX&;I3k}- znz*D1abI)-(O+L{(^j%b486XEoCXzM!Gx7Jr5Qq-o!Xqn5gDceiO5)9y#HSdAQ^(@ z%=22Aqp&z1pOt*ya2UjCAnGqnUrnEt2TYB{_u)vDZseE!R|i#A4=a>(JZ}EJ8+{xxEt!nQ* z$Vs@fyETlaLWG?ZwHEVqKX{eAewop0MFng3d_eBNUENp*d+WYCPJsFl|F??sOHG;5 z`uSOVW-dNCipoJzq>9ZqO%1N?7~`0fuxwbj9D0aj=i6c{j$8z{90>=(k}n)fK7T` z1AcwJzTDppdBsU+jj9oV8RtJqCL|EEVy>1RZkj2o22{4I=1fr1&nv_5BX<#)8_prt zm@rU}r&*YGl7PNEkAetrc&(qso+LV8Zb$X}VOog<$qVr;7Q?Sf>v#fFOYe`h-DUm8 zFlRcJyae(7m63bkJV`+JV%8;Grl6|}e#tkBvOkE)id9 z)IB)CeIIgx1$Tw?jgLlYS|dn+6Kb*%4DlQNupU3Q!$L@ZD$eMjp|eTIptBO?fk)}C z3bEOAvqJlVa-P+_SGdI6_mI%=YbjwZ^IgYC6G|URHR@E@CP~PJ!fj}~hr#s-(t6P` zf}7_b?156H{TCHsh4+K_GPTQL`98TH7Z@KY?>;Rs_PjReEHHX?m}Q$`*gCH#1*vZ# z67EAFO<&_=T}H~Qn(!d0s?dIN?PPr|Dx{y4!t&rrN%UWZv}qkjp7UVkw!aTm_Oz|K z8PF=%l_l-k9?m`PR5yfBy*L-K+m&ztBXLq|kdkc}YbTDyCrXg9l|Z|yv&v`aV=1p4 z@G0BAa6?SzkN%$i4p^u3%DT;dt+P{88#}V&lm5k_%zAyVM&0k|10D$>oHGSOj1Aas zEG2&aXa^;tnD>a%18K6bp6KT?@RjVXv%tn&%I}qFgsx`bRRyw41GJh&_plFY+rX=v zx)9|>dE$=(h@?p0wjFOBmxDuU)^jG_&vPSEnXK~CSIGMEW>X*_;3=ys8$@2<=RDR$ zEggl~azvDu=8G}!_jHEB&Djp!lSpD@4L@#94Su1)2o6pEc-q*7}xOR6Me zUnl*M*q{k!o|R|yq4oa2>>Q~{4)wbAMGz*pF<&#g6hYUR?3-vyPUMuyj7K|Gp^5}4 zX44y{N?263%jOwxjI+5iIZI3vA(G zR_r$KFJr(71q01`=XR-t693=gk1a%Z`Ir4f+vkn60o`=X4I1JGqb4l+RxcF5pQADf z%(P6h%#0&4_XP1&mzAKc<2b9DR*cmTbJYLXHhnjCX0FX>-oR#!us|Y;aOKf+IdtCn z+-EJe6yto~kq(s|;Di@3T6AZK5#4O%z5ar%*K?FwZp5guf^Pt7ngo5RbACd+ug6{! zM~={B%cL6*oZkLR))rSEBA~`AM;-E#bRfJ6Kbmj`))CweG@TSZ-kyQ75q*^J>4Kcv zjQbPtQLPpXJF6s{shqj{|tzh2g|pZtiGo>z)O zZhMi+x$O##!x5yx*9{p+ZYs?iFw5TZ7`YUPWPpIRc%mcA1y>_!DvY8Zo9c9JOSRSi z;3F}2u;Jd(!A2Qj!Z(dHmxsJjuk8FeLrT}%*R~18{m+v}1D=TtZeme{%YjI4+0sPw z%)GijNUJFnls%SAxC3}g1~0kYUQ<;D@SBtF0tKr*Z>4&;Zqb8r%Fkq137(2CLa5+x z?ew+lG-z-n1Nhs9JL9)Lya!PBv{^gPSuIc{YArVOu+ZxJJ0`}NzAa&6{>P=r0T26g z*ml)FeNDrY@6XW+IPit$nK5Gt=w`9g!cz>dBDuW{=Xr?D-V7Luus>IszRd4F2p@g^ z8s5h~PsI}KQquACg~yBM@%OugOg2~Qg?RLfk1l_q4PSG=FTn3iqmy>v7dQFqyY-dU z?DW0`x^O^v-ar}{bk$h&u6Hxpj)@)b3}BL3q18WT6gJ)LYgC_DmK^(@zyKJ zQ1upCZbs`O^7~auu!3DQv2lkxYDrCIj*B8seHxXx!`*ypdhuZrugqfw7nx4#MP(s-zTc=AyBt1u}WH6QiD3B*ZH*zk&+XqRjWU1#t^M>_s zofZ7pvTeS1GRk-f$yVgYk;La`Nvk~s3-Rv*;phn)Zz_p*TG);G5wkXZO@p20#um?T zM?9@=WX092a@K(Yxroh_bIvF0lWy;tW$0!(19xAGv)+lpL9UuWO`&uM8^EW1?s&hM z_|YJFJK>?^`{&Zp0RFh&f!mlqG&p;oR(()##Z2zurP;Q0W6n|}siSB!5jo>$1ZLooZ_FtErW<;xVNgXS?HIT>`jG#cr(pCZm-Y$)-~9xde`s zy?pmwOgghyKjSPn@(*)fs;LCAo|V~V=?kDraj|iqRSnDJj`{LmZaZWk;}eGYk0UpT z@TX6`@)V5){*D&(qgnJ?^$3YqNfoi_cX1_*d_1SiRU}OGenv%u zTZ|nzM@saslDJ}r63s`RIR?hJmqEMxzpMhA7?o}*!dv^YZbcz@*30Y)W9f#0KZyk5AB95ndUH{W^=Ka}Q(SNvDr> zL$5~pS06@hvCya7`!B&WQCp}_%QP`TE3rZpLXn9M{`cF)yUn;e&<`^mWdv%ktQY^n z=>a+{G!$HhY6uGX#TWiPu8i(E*Ii}%KJo+SKK&Ug+{Orm^1|*e>X9U=M1jbJ4iks2 zG`pf5Z>rVu%O6wscR3Sn9{m8;bMozuTXNdkJ0Vv8%GRR1Vz)7}NSPcpzG>_|BD%Gn z)n97Fh9^*WOm`FW2kq(HsFslzEuxiUg|=>qEpys=Z2Ys}D_@QPlgCO;?xJRy=w%s) zjLIHTPoZ;ZF`Yw^e3w3M*n!6VB<`Q_RCMU#d&}U%X{TR5D;W+h%H7a>$nMxZ7}otM zl({_W)kc-t(PyrrXUU1s+VpgnV!`-t7>sL`?{CBa=}09{9nIF_@Z;P!LrPm|yt z6h}sg7e|I>trCgZg#uV@X&%XiY>}j;Yt~0@+2qj%4o;f2#9h5riXce;`HtuP9WxA5 z%{&weFT{u$va}OG^rZeR> zUJz4Jo*Y#%=eHB)4qT1V)X2gJrEaq!LEgc~NXN88MYxx8g<@DT2u&80jlNLT)lcY= z>i&2!SvU(DMGb9PUd& z{$r;&313`%L27~7bCe{4&~+Q+^nps0;FThbH>ipRhfwb4+cTz*L(4LhW4R55gBoiE zRtGtKYFUOd9}*XytOm0CUQ<6TO5RGV#9o}M*(>KfYLv-jK1UFOtb^>L_aB5~rxA58 z@kyi0Xji9;?pzVL9N)aVv1~m)|A&z&mS338FOsDajVUWFvMv(PZ>%Bs_+8EE-Ntgl zv%2#iZgdwUc)^;4A8y>wJwug>MbpRflahNCpJl|y0dmfus;n)kU;hJ&jdqKfL|=}C zAI0Q(uAS24@#u;Y)N>I7*avVuk6az&#a`t|eT^-+ zvD37ouqP?r6ei|s@)#Z>u+XQGcKIyNwfOx*b_(J4{rnLCu?V5d*J%8XulV=H@u)T7 z&%h)ckw?jem~=$pQBwkLY-OivR^)C5c(ukBa)Su$KFuDor-V|K4?(5&HvduPrdOLJ z3AyYrxOLUGVUc9_w%6=MLL=5Yj6enue*@-mu9kQ5P#b+$|**N6T+lcqiVtR z)KR|v2Gi{>8{LY!eW?W5z3{r-AR$7}dXzPeXGJWkYr)M_rLvRS>_Nqb^Jy#ENf);Ri$Znj(9#lerHyAHiPu|xH-tZY%tz{1YA&MmVLNvNTG zB>0zE^jJ;qh=d4TKTjRvc+CEi2>z>L@vaZxwqq^x^#0hgyahck^A)27)K1K5{cqzq zM8EdnY~eTG+#CBz@DkZ#iBK9l`MWPNF_z)Ym2R|Bev_hoJ9OL__fNbuy<`lk$}`Sx z!ZKmrt({ol8%5~cSDH;#a^A_*Vzdq_XJk|fp~h*jxa!SDVt}(hRBw(!#uO2(Pc2n_wowUkGZuN&b zi+#(Aokl4`(&{;14koM*7tCIzh;+u+2r5p!9ET8YU-kT@`_0zF{{^2Xekukd)Xv6c z93QdQwWAH*Nj^P|ht7$ov#$oh>lI4lRGNfP;Uok3N2*MN9)m8l?Kw>{2WB=`JSeE87%4-L0+w$g|d-PDi5gtfI!8}n>E`J6seCF1*q9qm(M zP-vXppuHJz6xwAk97d->O?nJSj{bVy{M0U5OF%^Z%Z|P7cdkk;c=mX{cu8GK#%xtg zS&b8>ZVO^}5U_-Sx@T91M5i~KCCDwPs*K#;Bg26nsJ^y#<}OGMiAGW#-0y&0g3zH)+KAX{u zL0XP<3;3%YTes%?IF&1sbnUOMzz}Gr0Z-gO-i%sseU6`9{cmSZYtJ!EM;fjfi_+>B zNzrtALHo5#Dr6Q3GpLGNC&4X9nGAJh;!I9Zl?5dfGYqkt;l^9mJ4Qd14CR{Tq!z!5 zXEd|KA)H}{H2vnO-m`!Nh|XZz+3U1Xqr6b% zuH^0CnYpI*8s%A~ert60cp-Adkk&pMdZxw5l*ZLqK2*4jJ2LBzllx@ zmaDy`t_e&%0V7w|IxaHLny$`chVCrnFR7+z%RI#Hf>)ug=V-;2D51+3B3)Hk1X38w zq$*>MWmV(Vo!g2@ZH6@ZL1Yvti)G%iJXRQ_SR*K*$IGk9qWbhBB+$?7$YNfWiECgb}@8Uz+efKQ-0+53@j73BsotcT{CaXAAl%vJyP=(K^InI>(4=?uo$G@X-*k9>xkm!U_Pw0bU9Pqq0{@x zRO0&$QXG7AW~Ii_={-8`78{zg=Ir(s@)r9*#makv)7{r|z}IihWF2%uQdcum{;@hY z3OyR0uIPH@DDx|>_`$cdedjc2z&T{bn*|(f1u|1 z^ybrgp+JO&>)HB=;GcgXNH(q}M(Sn& z-jQt_kp-|({sR0*memg#$3M1YcEIMwahGJe3G}!cH9~#*Cfr*t%~BM*T}Sx!0aRpG zI9G+*=^x}|K((^?VT*VmLp1r<`dXFP(key2HGSAA67+qkChFx1l+;E2f=IS})&Px| zWYhTk#YjBSP-)&_+A&+ht`dA{)#ar6jddxjgzBwnWEh8YlK^ZPmWbS+Y>>y5!onCA zl{YXu(SbMKEKGz0UoxQCv{ni}iadld{j|m zsiZ3WDUzJs!a~1%)iwYdP6Z>CaQ^ULf?N5qVEr*pNblciofeJOd2t$u`M*_FPQ#nE zEs^zG({R;Kbx)$NAdsQ0tek}js@8JZQEs%mH|A@hgwltRBe7cjFTB%?DQ>Pb`J*h8 zr>T$Ag86_}rs?Cc!VlX7(*!#TU9g)GjZn`~9E;gm+KC(}w$)JBxgMydwUUh`v(`zg zF}G;Mre3slUlq2kAu1ChGx6P92rc0qiJ2^Z7g7Qxvm4Y&$ZQr`!f`;J?W9c>FFQHZ z8K*G#Ta1#2}@d8Zl1WKmF8v3B0a^yV8fmN&i#X&)8)Rq z7e?znN?1VPiJ-S%!*d~3fT1RDbE`yWXppjWj<8XwK=#Z7Txi8FU6H4D18x{?v~&st z@qj2`{IC|7-u$sIQXig8HU|3q3TSk4#~k$P$$erVoggEb7Sb(2)$y&uS@L2J=b#bi z3{_K_3)v7uTjuYNTnYo;1Za4F1@0r@NI_Vf-V_(?yp|FY^{Xd7QaF{N*ja36K@ zC6io9uRQskn5Jy+{?Yn;4nsG~946l2-M9z!I%7g*HQ_OE?;>Xcl%DKPDn|<+CJ^7y zHbk741M<)>@e{H9`Qf9#EmbA<5t1o%oHHlppTg;JMM~}os@h%*8Zj9z{5vENUc}2c z@N|#d7R>C6kX-oU*O-=qbb>r0vt}aFZ%--Pr6Y7F?Q-l`*pLZV4)az#!qxHN)!+O@ zh~=%^?7W%>E#i^(qLSe5)<@UW3A=`!S|bSx3+Ryan)n3gSV$Ew2Bfs6kdhvLm}$rl zf`WKmH9nB`!7b;h=mL>8N>33dvR>+l?s%ekT2P}0>=QSZHrW?TU7oka4yU4J3k-kS7qDUYgY25Cx>T;9U@3Fw*fCkwl`wjUgxJ*Uc>_>_6TKolB6XOvS5l zOV*IfZwV#6?t8$Az>G`LOimA^vz((}s}>+R!ktOy%~ONut`ZNfqg@Ish*6W>@(?N|*G56HPgHJPRv$f$AsEjcIu zc(G;N8GBH4L)Yw2UYvQOSy1=ilXB(p$whVRA_S~BQ50S`4683K3jz>%uvNxt{~^)_ zLKWGvF2l1{6%T#@wx1_1>b@h=rVEZ5Lu5P1ZRlwq-U&vfGJ|+13Lp5=%v957aoVGA zf{5~6r32q##-tLyWOH15H|7l`-Eu;ti*(bv1373l*m1{;G#7u{Eqn4?z~0R-CVx9k z|Fy`E?MeRBL6?**k+`^Tb3?MG`p?lG0c}Z$Fw#CiYJT^NcJDPp!8yze0s$W}d3JVa zMIo;|Y=8dyI=8C|dt@A}*9-|Xh5BS){1@Kq61E2UNZl|_b!u6|%8PoHy%?{ zT;D#&z{x#79cPB>a0z53F% z;ek)0=o>tk)}pfhbn^C2WajWItS>6+7d>~FG4OAUboFpA_~w6fH0v$uD3?VK3n(wi zQV|tzVr8m(B0Kwx-;I$;=YDyg?K6h_mm^)Ado%gR{fWuW9^yTGAq(w`ca(kW4To8e zU4EmlJ@3~r|K}HEnaj1$Y~*f}J!zHK4u^_YiMR&iE9T(yapgSXfkLgXzh21xLmA~7 z)(c(}$>?m&q1E!mxw>1LXY8GvOGfM8E4R+dt@BFB_xa_C_bW4AN8yMqyOv+QuWQ*isxbF?R{cUaFX`kqCI8{|{nXS!)NqD%L?H2?-|A9)?6 zPgOiA)1G$=4Y8n|hRyl|Z*Oej;_w|Z7o_H_bLlQ)?heuBu!dce1=el`?d4Labkif= z!~hWIO|+oLEq%oG7^;C53G8 zDXbOW#%kxQ!Y1;co>sCyWh#;y>2bO0tFW8v`A5)}oFlybDWqZGv zTSZtRJeSK(*v*#s0^xg}`ECkvoS%=)vXIq}%=v~@&E-a!?N5QxpgVWfg}5n{yviIQ zy|c_;&gTEW79eA)LuS@`S||;26BbC5H71|8Ptdt)g_Vg?Z`~fcr~MA!3h)asjNAKM zIpUR_{o~!>$%F325bxceV+#Dk%QJEzndJO@8D_ZH_@I_mPQxfbj%F2)xA=F@wW-K- z-n=ODXPMoEh%u4^6f5s2lb3nQSI_@RqM-%w;~P7y@I_6mxGUG zl4)G*b0IB%Kp2hCHO+9JhLFcgw3VBQvlU<8HA)`SI%760)k8Gl2Vqhb zf3Espa2-5K`SHza7+xdsWy^RreC@0?|XUckb3OH{v3Bmi0M=exKt2$$Xa%(Yxb ze(6EWGaul_i2^O}Q8{TF3yfkVn*x*um09!tN!)h^W_$tvI57oF~BV6O&`I!+$aX(Iv3=PCRusrZa+T)>r0 zV_wzp?@6MA&jV`qJ~v>00X&#rIWr9%S_8F)*uF4eWb#0SN*^YIO$xbE7u9D)(ZMW| zonyMfAJe5B0W$OB?H^-RDyj=?h5>b5-w2yg&GbHaNwgb-o~oDINZ|0Ye-6y5e7wt! zddld<;FMp3xVD5CKli!(fmccmp!pSjU3|87Y76Nj``6?}N5QBRZx-OTy&Uel zgnaOnKCizQdfEa-AWfO-ko9^b$ZAs^0C8jP^*8!Mm8u1iVR+q6_};IL#^h{m7}yH= zk!QayoxqvHb)aj8s)>F0SC=nVdi(6zcEN*gwm)8V-?QHVRQsw1ErAn&UOkx8klbz;}58QK`m;cjhss}s^RoR@|;|UaW`BpE>dt?7sD07 zjklu1(V?xsBd@~1v8!diRjq-BM#NVwPBt-O%=WYL?bnVl2RL~e*t?mbmd5X2bE6tj zKO`sw@b_9|71JaLm7=u}{9(>vx_l%|oO?pN`a~lEkv*gA-~O*k+)vVc zLw$KDZN|p~d;}UGwUR(M@WQC8EvfOERHYht#|x<*Fyy5dpyw2%mZSI@WaZ062)h0 zq}V%9!8WC;mqHB2Ekz^Yrs`adHULw;_Qme_n%3H)>D$T_e*Fw}YM_@WDvFvJVT_x# zXk@gRWc!m|!N`=}($XuODtgB|8qUB6S&P>TIsWJ~)PHf)vHL0>f!%O-Mq3kS-h4vA zAlcA8nWoei#%n#{4+!M)<(0lVsSZQhEMt3&84FkLyZ@Kv3)9XP3Z=^d{jpQITbyqZ z>Xa%T9XB68FMn!$ zBV&M}ztX3OY?xTghePzGwVx)OUx@^1`wQJb$0y#zvdzon*`zI%H*tk?Y9eig(T%$& zr@r$XjHR1~IMcZl>i+>n(QW$f^r0x)-U&BprRHt-z&V1Eis3QOo0k#*}&t8UGqVYM)B15vbqu5 zWMA8?l(NrH^b9#>|7~+Oza&s30?0o zLz?o`mN!bTA7X-I%zx?!oaxw-%z8=qj!UFHN7$(uvEj3iA&U&oo{%n5vC@+Cd2-Gw zrkHLoo>km`OTahQ(Q7BxjVni4BUJ=rpU1QhzfqQ3ds8v_eT0w1mPxs!H9L?QnNIO zD74F2RTLRPRL1FkgZ->|pbs@ZIbDw(mn6NQ8vY4zTK5vhabhOZi!m!un2z+aQT@Ve z$W!(ipN>*}plN9!ds?-`*t59Gdre+*>jn(lJo~>3xu737GW_>P4e->_x{^l`IdYT|gP}cIM|6>P(5gIb^(Yh&mp2+FeoPwPiPUI^l?yv{WA) z&rpqxXBu=b=c?^umKi$gHkl+e*rs|+MQQf6K$9tVf{RZ723hT-L6be?O%i7*lVk@W zYI26-YUx}FyLeMdv`d%fXW2@j;Op6sKS=l(v2^!et7llGDHu%bul(@3t{Kzy@)+LO zrKuN57=0*ICG4YP#FsFWLm{7_dkF2XPhx^N?p9IIJTQ=S!)g)M7G}$SKgvB8C0sR< zw_m-|HX4C~IOR+B`urT-+m>A6QmY2Jcl+zRM16k`&Ueuu;lEgovg9q&GqyKlotxNK zN4U*AovQGkpBOlcCMxM(R8cpn)BzW&Z*LMFH)YlcS1{=~Zaf3wNm(%`7pY7XNaB#0ULndo zIv%`5*|SN%y&YFDV^-4^X)6UTD42LcUS2~1NR}`Z31*x;TLEPL6c3>uUeu8!oC$@)a75?g1P}gH*Kz?kPi7RM(5#VP z$qqp{zjf0n!*!}!cRjq*-1nx?9sAX6__KUjwi+^&Ra-Ya=)o{4Tc5&@2D zd_LGpmIu3}=yRi$KQn94-xai-OP5=Uha(c|0YLJV0PxKAZkU}0KZOaHc{(<<0Dq>H z3Rs=-SFHNb8m~5M9i}t!x^R?%7CBKuDtLFNo~&6X<3zgr`;msJh6k~F>1XM0|Git& z@E1Z>PFHF?@1x3H9r02NqeaPEI^tOn+M67E!C_DCIE{4U7OYu7uilK*!NW}3HU5Y~ z04mO(8p)%Zf_b-xLWWFt4MVF2tS$lsqjf^ig7^v zI={a9CEnOy70Rs-LyRRGmTT4NHX|X_v^_)=2W=F-I_lC(cOLtMK3E7q7DmHw{Iiw! z@^AaYqn$1~=umG<+J-50@*o4KVJKA99Hp4-$!2~h013qkB4N=qHuK9Jg$v7!IM}A0 zqCC0Uil}&jE>~+-3hcmxb@@H*Fimd|hljEQUDo!Ud}BK}8lGG__k7Q;nahOH4kcDd z7*PJukuM4EVhFwY;ns7i@$acpqv9q2&;D*sF0c;Ko%hlLufZQjX-O=3)~>aBL>QZ= z?l&^Zjen8*8_(aSN;jwgGQg=0!~4G_E&bY#g8&Gj1A0?_&1@VaFOcmNFG5aeoHpL) z{0;6eBzG=oYBTH~*6uM=?u+jsekd5+iLvW!Ax`j~OHslEy!^^jm)YCBH9my1+7?gU zbqKWFJ=L+KWlPqvRUUpLvZ{$8RSdVmaFn*7Sqr(Css=Xv&2V-V?q~??v;sW z#P1`9At*wLL+_ebgsa_p;c)2IM@P-C~4HvuvQ6rwZJ4S=tXMFvI#2{iglVa*YBR6hWN5jbv`p;L$ z74g120Cb}Nt|HRXN~en&Xz#UJS*rL}9|>I}_ASG}fl`P!`(v z@PH5;)5w6vds$7P+Qg)j^1u(VYijXRAY2fI&|}iFzYM!g>t4B<-&xKNr$fB7yZ3Jn zH2kd1#_*ZkJ{kFTsk%Pxp11{<%FADtqm_h()jqr_th+=|J_r!|1i>5()k^Lz+}RC6 zCqnZE3SZ+W>rxR?O~qZ%xWs}e>%a2vCvc)XHM8b>czy%KDsL|E-+~7oY&k20eh|!wCB?tvc9R8nM}|gB zR5IcT8Ua~cCH9CZO6QYGKkHJlg}TI5poQPfFpo0Qk;Mq$`)&(j$lA2951bn)C&22Fl-OxGYss)c}mNTEgT}3J4q(AO@un|O~pfE zsT`45;A`?5G!O1PY+wQZ`*Pwj)L5F9*#Jf{oV>Up@wAi>T{awhvP-ioPFPlkjE|Z$ zaZwHdv9AtUlf9Si8lEjhw=cgJ>;3>QJvL#xKbyYQHo8Iw2=4v) z%z_c#fgwCw_XO1Vv(~EjGqm(GU&1%dkBd@C6s1TUj(X$ zB}+H>ESAHbSUAHX{Hylx(1@`A#52%ejtyt(tH)9w$A?E&oXtGR-Pynq`hVr)-BE+X zR{LMQxhqyp6UD5OdomVfX%at#SJ6|z0P7|~2kOW|Rw5G$d?v}h<+(^;>nTSmElf)& z1j~U47Zi&}K?m>+pBTs{5gMLHN&+!X*uU~DgF@qB<+YCE;hy_3>x*%&4?e7}J`P(w1*q#NmNNl|So>dZ1FtK6p_v4Q{)I}jTavPVq@^=FG=twr zum8LWUf1P@R@4Tg>jjuZ!BrB5S)d_3UoqK5RO+Lv7v4ldg2%s zg?oTa!Piqu!E<3$lQ7(r5ibBn-Fi%U25+&^P)Nd`Ua`o8n&(*@Og$K7A&(EIH~D>y zXx7h9#y}PZnTqJJMFRyH|u>ikapN<2d1>vWDi~p5ZO|!uC1&WC7?rJr3jW3VP=#0?Hfs z2Jynb|I`ak&q?gqJegPxo8qzUKmeNOA<7HP1w0#)Gpv_H+Ed!}U*!hBhT!!hu_mE!xW7#kC2jr*7unS_ z&x{^}ui6CN)`mmoNM5jWqyPICx@IW1LmzKocqE`TT`q15(mVQkgw$#hf>>P5ANA6E ze_>a#th!F5JK+vE7YRVk-d@m40dRprd-xfq7y1NrJR)T|hSA;rfHTY2r}U>7L}Lt8 z=zK;-06L=Lz>>q5%3i&hGhIH<-)PS~o=L=BP}xsPNUfnI``laO?R+B`eBc|lhYwV} zv{XC%cG5IZIwQ5mmKnHYod>~~fb~{(dSUuamls6+INIjYdXR6{he6Kg3 zNsn!9Yh!xqJTFKVI>!P%NP!}70sMCXxKQ1QtcCeKc$_m>ekQlJkTUr^VW9a2h*^5y zg$>>06P-iVnGc@OtL^s>3_Ig{gQl|7_>@MpMx$vdYoXZ3Tm@R;jM>4|;$D93soDf_ z%&O@Oy?jn{9D^2u7_ZWzdO3bp0^u&jJS=Xsgl4u%S7VAxHq?}#lqpAMA+;JTiJu&$ zc6sp3NGuufLva>u@*r&Q>s?Z7N*rgsk7C{k{lDk$IeXRIoO7BYxXy_psMRRY!XxpO z%j7lUHubbah$5}IX=mTeigSE36MSR@RCA506kwXbKa803nLLyyo%a z4O=8FJ{Q!W6@zG6nzGe?uidGXMyE*jC=b;X{RL~Y2uC3ti*aR+hJ~IpvdIUc{@xVR zwt+aBtwz<1;is2KL2m|ujbUJ!`jlE8AnO->w-UR2iZ#lVd|XNrZ$1Xi^p_ix%=4S% z;1wQ+cuKb%zEor>ko@ixGEY)F5sHa{81PVFZzkYc_E;Em^uw{TXl*G*vy5xPFOHsP z|7v#U<&<6kP=gCGes>nO!9ZO2Vo)<#;@P*K|n-V|H8}XI7XGxqX7^=G2u-jV1pfVTfdagnDP{Th$d`5 zB7JlJC8V{WZ?L|%U}TGW2RXga_^Z`95ncc*In1Uy8G!je&~`p9scBF&ExIkU-IY$j zo24ZA%C)UL631m>OPkCaYHuf!au=_fcM*Uoqyi9APO8OI$)l%lMX*bQL4Fqw>F zNwQ#wX#Qks|bJlB7%?Xdvj2rveIt#3Fug90qz)&swlUj zE=^@$bLA??^PShWFVgf#ebA>A`Lb*XK7^MlLgcf@iFjq8^*fIqHzfp!Ppm+Atc+2V zNR%(qq8;zN2Ivd%8ZbFI+@NasAXLU0wXeQ>T%zPaL|wFGg^b*7ba`@1=q%z#!dN6D z-107^YrPQR>5AjLk;cQNvTp_}Wyb$4R?*Kyk%VUrNFah?&Ugdq(_o^E+|$vJr5HJ+ zoAG`$@}zOyX~C$UI46U%b0~~ABnxd0Eghs!D&jOgS0?jsff*Vgm3Rbfr62M! zz88M)j&XFjm+6B)f@3cZkWrRGWGeYIX(M8Ve4GuD(j;v7U zR6ddxl86f}@Y|eFOxa2L9b6SO>N8a3@sPhwl}z?;+&aDv3DUM`OJR(rkta4XR20SC zu~9b-^Ih~L9YSa_zL(7PN_;KcoHQ_eZ-;Qh-^;97zDIi$M2D(g6Cph#aUo*$!8=OxFWK{U+ZuM7Mpjs{K?ypus>-|n5MhTx z_U%RDYoAyIb@-fPaWa#q_;0-c999WushiX)mnjK@SeZI9uC>wu5V`1~2jEW*2dhm0 zAp&XufsbW`<&T2sQlhIT5szH5_#vleuEGvzaLM5<>qEd-7^K3%2jfvxD_|W{B##%Fr;J*$ zd)%5Y?3z(_G&J?#VSpify4r00)d_L_=-4Zb4^4L zo{2j;(`33UIfl(T~yM-U7Tv z&+?2YDs=uS`J~5nGS$G);@RpT{J|Qo07Tq5QmD(ZROi{O&p8O4GCU2j=e_ixnG@}p zxM3|7-3!qu&vN9&Y)H%u{}54;5UDDw>HCI9_jGDk^q^lEgBTiBIEihJ&jB1lu{y~f zIO%ntmiRlUlXy|&Dq1Cb5Tz~&Xcgvu`A1B#RCuuunx;J8@VQ&kt^5ArZ?@mhAiM}) znoGa!Le!Ukp*0Csm-jRtT{(z3X^jwPyys|^xfFr>z2|K7N8Z2C#X)(++K`@8h%99c$%Cp(!;8x&2 z|8(TWnUtf190j5B@gfzJO?hx8@)th6o-c^$jrNdu5EGVxkR2LkE4g5GM($GQg-wh97rMkTzxbb z?!PIV+4vk=$yXvx396wR8k}u91?-gAv@|O#1OxR718#?rp0fU^QoWh1#!Ec}C(ZV~ zhlf{-YLspzjZ=$<=<3Yk-X#H|^4H(cLb8(|{aBQ+eJF57CKGB~5!;A8Wx&(kFXni< ze|a*3ZhKr;r$m~vAZ|QutFa_Z|n)6^9X4xoC)rQZ0OBP3f2|OwSii|*FkFMH?8*cH=v1*@VLIv+yWJk}eHnjmj_E1zcw!VMb{T5_CjpCX`n2Pf1{E zG{T8)$YdDct?+?EXV`GZnYHywq&7FraxnY*G`BFoSq7!Vc*f{4gb~~74ae6&6u%2yc z)4hMg@M`m_5KKejhs+Ycb?NuwMs0 zqjCT73!0Obj@$?rG}CXpwNNV(;B$@5t3tr%A_{zLD1^K?7f4)IcydT52~mdDWkl7m zO~+Z){VS(d!+q|nDFu8I>9m+7LVyQJPl=|!nKE!^gXLKJSVk|xLDtdDSO%hns)Kz0}bbIQr4)T59KmwW*Vl$%laRI z0@c*3HbksR(O?`#F_>r`G(z7s+BuhtG6cyd-+n#}WCRC{=YV-A3`-?1TmAV~s)8Q= zREDv(8`?&s>9=x~u^ zMib!*0V*v1!@kwy_hKqIgAOec;q+mQY;t79KZ`XQp1Fx%XbvW@$<+TJk8&c@;NDRn zu;iXK48LyKLcGF~mB$XnWtHWWRm5J=7SLPl-O#j_4LDwBF=AC)$EXVrlhHKhUj^1j zAD5K#*bdTCdvlZuQc?Q=G> zyj&AGff^oFd2ZGy0X>dZ9zkJoq6aA9LEzaVPeBfZ+TNY{Nx5t0J|T(D?pfy4Yzz`I zup8O`C4KI<)4WSl(A#hO5X~dZ9ED>=*K)Yv`->vUtd~O_TDW=3pE)DGJxH_-4c7lQ zKvi+_rpc+H<~;Gf&XlQ#eU&m#YH1qyk3J$D?yLLLTQP2vMCqP$$cb-{q2{!XaAxFG zYA9SCwyG)S!GMJ@m_aD*`a4UtOd=v}>K{}&eoc$DSim)%sEyW5eDdF4kzlJvDU!Z& z-)6zRHcLEA^ksl0%cE|V)}adhM1r!a7?GsN5P^$d--B2&7#ce9E!qNfa?`j_S4Cy1 z{zYE`U#t=8@E+D}Ee*TcrTl({hxH%$#J+tc{Zl6f&I7DxyctolAkq;ZuJ9ys`;@?q zX-#!01-^Y2HEWjRd$Jm{r>)c^+WNlWZY+hCvvU`~im>x}F-x=+b?Hw_S=srWn$6lN5k{3ktFUjnNf^1@g>&r7;Y0hNx! z_|&~03Wu4Gu$vR}kq1tqK>PA3QUxtmoo+gm`$0*79X{}VLW)(A+zeFd`kWd1>}$LI zd7)Y4Zpt31a#|G{G_krIE%L_?njB6Z{ZioW>PhK1xyG)`urgQ&X7mVpD+8S(Ef%=9 zQ~6pk9iXGE*EKrjMA3ETM~4pfUW8O~y>yZK;Ac(WQ;CPWhjh4`y0cw6Z)@Du52^ye<;tgF1zzbkV(XOl_?w9UZ-Cet-Yz)bwjL zh+OipDNLt#^4wX5Fa_C4I`*echh@MoMNGbznWLVr^--%U;Er1pHRvH|jmo8!({5T| zsBUH-6ZtEO9$)%H503tdB-LbN$cxrgYvI&>TJhoa7ard>^xO++-~#|80jJ;p5Ykhi zcqYVS(TymO_$B2G0(%62z;}ny&G{F`Tr^IH6Z3Gs3%g=on$YHuA)JN$XR=pn(fYWi zBE9q$(R(hjJH~?^W7H#SS&-RF5kdhs{LAzdZ#y`omRi#3({FxqpiCo*U2-t&^>z-1 zNW^pQ*q(ph)}{Kf#7T}_qlKkm{Wbw1y0;tz0yTCsCwU(G-@mRa8F5BjHB6hWzi z^Y-(){x+6;x1G>q$gVNE?s7NS#!lN8| z8{nBEMu^c8jS~@Di4h^|2v^8qAuE2?ksfEU96h3iqM7(mGhJHc;7!{Q`a(%7ZX!bD zY^^E&qV7$EhC_GJ*pG^jWU(;HXjVuCcFEzOf{~O~0ENQ&jVe!{sOSy38DicKzxSSz zhl66gc%vTSZS`$|Npt;_=O@kWPrWmE@C|3p?Jy=sM^pu;L{^elpJ;1xQ&yKkNPvWc zM{9s7q|LYi&gotV&US8_#3D=Vp$w2?stz}V8S$pjt<_V zs-LxZkp<06+gIaB(2o){LBYhmU*(_j`?OiI!Mfn*F9^z|Ld+>6msU^_d3u6}>-Qmj z33GxcCu7v{)BNL#NNn-BxvTp8)%QrJBwd+dr?t;QFs2ABOh4od!TzL5Znq!pcAID} zM@xPWF%p^QM~nFi$uZ?l7qT;UpmE=cY6c~YZLIXj%xFs*O?+s9yQ*#~ znJMBW*RS8;a}9?_^;zv$Z74%~MwB+2?HaER(@_8P=STsSOrEQ!Hcxp^w^mbzMcQ?P|CT^%69CrayhBx)J))HlR4V%kW!Mjriy;Ac@Vxfgo-3H!q zWWz)(+%s=(-rI9_B9BK*FCf%_Y^lGSVpm7f?ecg&cnO#vaBTZ09NeMAt81L_t^gpcQB9qT-(85`u2$Dg0e5pOF%b&k26mD=|bdk4B^o&hV z-Pfay#3;lu=5)ZgV<;nT#AviLV%3!2uGaUL$`kVbAcTWNX;~c>cArn+-%})Yj?};g zWvz-4wG~7@C^N<6#uQHe1DGZaw8)Mejkx73a^&nnN4znR`T1tP(Zlvg;QyILgedMC zG~4}{P(T*PNDy{GG6lkOA8(J`I1kjFgcP3<$42iJt{JT{mFhNZ+G>vEkP%|x>Z1RG zk<4|(Rk0*7=3t(Jhh}{XuomkA9mNa}ez(Rr5ka5UjQHV2RGt+3=!Y2%8Z4G)K|#TR zo4I+e-K*CN)q0I~YOH^bhc80SxN&$Q#1wbm&@PR^HFpt-tNoQoBU<~gJg`K6YfA&* zhXrWOi7tg=6F~fwDOJQVZV!SZ$0Xa1`^p|nP#2sUvm%sHh^kNxLiBN(?B1KqKYmyN!}$hm_Y;}mcoPtB+> z{<}1z;;;43uptx_sCqP&AYe#4Y}f^p8=Eykqm}z^jS3S9Bdcy6+Zu>`>;mXY) zc5jIG=e~c%y`XRJVkoKuF4DMdCfvbWxjpSgoPzzVjT$|GG_zfPo?*dvwv)TsuA!^p!n>c zd4a_XGz2H@fhY1jUZgS=x&Ec|wi$qhT&cmd%~uF?`hBfUQ3tifwluj($0;X^FViRU zYrwF{(Y=0f`Od_LFfVSC=Qh~f0wc~Jy!nMnR}pIYVKRMPi zPt%ZR>D-e>O>nJLy5~ZHyigdQ3%d=Mx#s~3tmBb;J2R=_jxTrjhZP=BMRRu^N=#E; z>?KHd__FL=u4)8)0ayeolPq=J0zlGouktY7FzhkG9RiIP3nSCQg8w{w>4EI9kT98l zSPw6s|F%8k+co;n^x6wtdhQ4BL)}1a*pJ^b&r7v0A38Ixp)zgUgJJ~*f3nLj+tzMt z6dLdbLf_qkw*?if!~u^~N?m96=-H70>#5!D7_L9`l0ArJDMb`jpb-anuI3f7_San` zh%Bt!l6f5x59hgi5Xi(YsZqS&k)btPIvrLS}s zS;)(?mz$ukZPkJIZlw1xR^75fEx;Jrmdh697bbc-`3XzoKj&}MF8rT0R_9?q*W7m~ zuiM_5Z`Gkq#_aLHLu!7^R_}3xONxi2qKI2u{!2Re9&Pz-0yVI!Q6;iUKl=)=&DnqS zQZS6;JiAnS5gxQ^uwv3m+UBK*@L0;(JrI}-`Ey6AtXo+K>ElUQSWk4@<$$YAznp%KrsBqQ`2@@IMHOj2g)`bAWbQ~P0( zhDbf&=AnkSe5iu6z^-HPbzUBC`_@CQ^VN9yAK!m0%|?QSFiazZ3M$0~yd;Y*!WJ&R z`A7r9CUn%LIrtf{Gnv5$P3sVWGKpDJEas-w!v3RHxST9)IHu&{;!iT%>QkKFE!cs* zC5ZhKndft3;ppOFOm5BVUq4|HBr}bX(Tt~ZTn25MCi(r>S!cqgIe3snV}&tVJ+I8d zZAQFK%%(s-{q|u+j&eMX(bKxiDmQQ66r5=H;JxM+DNv9XTLx`$B;l74%TMeChz=2( z8^4~&6t*9oNwigLIJpUheH7$lWln@0xZeHrX$WJDd|AB4k^UAoNsjwHBPEd|4mU4w z&lWCoZu4BK9a_i_Yu)_%QumP$zxY#Vc)f4^H}f%0M*^j!d2ON^c5;<@LzVLEndo~# z=`aa>`(^1!vZNtt<_hxtTc(wYJkx_lMJO~A$;eM#V@p10L`8{aOP2kzzwG$AaKjDf zegb!x2^)C|=94{X4vA>yM|@-wlGiNgCrN*glw*`>-2YWKMu5lL zSe|mBdGID*Fxq<}I9({wRxGQkZ@oMqaf#qj8clo0r;8>IV?y#SN+hsW6l$Zs14|^T z%<@xf$+*xIc&53Hg-3QUKdjXx1O-%yUC@G6z1RTOkQa+HC3H zy+D_u77=gPL|rb|rVVUco@C!zY*DE2}$O{z&Yb+xDXRa4cPiUVni!)+7`*&EDP;P`>7 z_kSRBSut6FK<+X(>F2o9thl-!#4;7>FyLh*HM@D3Df7)=n3xXYP-nl>AuC{GX=?Vd zzxLK@rDw_ED7gGeJ%aqIGDE1yG ze526lggTn8p#HIBii${wO`}B;*pR^zy(N6ry+jfsju=F|j82;Pq6aJ9+c*xL!w!3i zv;9|SEf>RaxCd=31gT4yDtKLlu&q`4<=nF|i}lA6iAU6}gzHr>EIUHW(49Xp7_ga$ z^bmyjXuHk%%Cau9ikW;M8qF_#z6N8!qh^L8@~ijfZK{lr%Eavmr?9my9rp*&U}ZYy zDMMo?PwRzsq*Hw5(y$dmQEY0&sho+1j7&(;mYEBuqY1T%;A}%=ZodY5t+3FQ3B8&S z+t`MO9)94s%xJ2@4`>8~5M5H6r06Iy7X{|D?Uq?j7=6X7**5yN_};w{@DsXqf)o7v zhewvWn1Zu8#a^S!y#xA7mg%SZiKXFdL=|vj1_1yU$b4DV$0@>$w%fD*%kjXH0uE8a!3C#x7VPTZ(FdJ5Li0+jTu-v>?Mx$D&GMZ z7yp4yV!52*)w+^^p6$FW2IkWdB{*TdS~uW)PF>)3Y_|~JwavEBmNTnNe#^soStB$f zjWTjJ;`vh3WdgG2z5O|oKkfeJ0~V#z^b5|iX#Cdt3A{+uBD(o<ZMShP26`_93VcFRNP2g zWZye>DQ4@w*RnM9JL+m6m7kYm@d&18;3_QwMm`Bi_n_vqu~M>HM7P>1xqKy{xdrB; z-%Nsj7Xp3(_8@JB$T#%?%#L6nFvf7N@JT+wq-`k$pP!Ckdt!SydXm?s27NZX_-1-N z(XCBM;l1#lUb124qfDr5p;-zH)L#So1% z6+DL-XD@J0hy{oljMRc{(kBMiE}AUGg5pIGK#%r_m;OGwD^EpL9V8dp8533SJliY1 zwR^*hnNdJYD45YR2HJuGxfXjsGybjOXpeaBCcgARIVN8>IaVj`@cVrdrYa8ge zI|K+rzcluQ1UvLn9N_fQLNMC9nOleUVPr3Ees0=h)Y4H?XJW4b=kw4Rr57K#hPa3@ zVQ#erQ^dS~IkiiyWZ6-<`BET^+Dr$9IFg%E`-%s3iV(FC_=xeQY46njsoga&ySc=z zoU$#$e!mHc3YkK0tbP4+MlpEtRG*syXH^Nrgrk57@(;JR-9cfK%|cPh?*X_d1GBSD z%1@xD@&~E-bE;PAS%mv1@@hmES|7em`m@|SUDTUP!{Y$VJXTT?6c-P4_bYa`(Qf1! zi2w{&eIREF)eQJ7_3XC=+P6=1mOy3ZoW6Ska0Z>$jG2gxjGt0KPwl>ct_2#ALrw6< zwyLDYfqy)Xl0|RavT~^kdf=J(2GbAe2i$=+v-{&=p5sXG*pFxdk)wLMu#L)pS%e85 z2?M^QfCgVu4#v3ocX8!;Z}QSVrJ)msWF~+nNC%u`* zv}*W?oBC!D0a*GersyvPq{4% zo7nX7#@uQk4S!R=_0T-dR_*#Dxa5Ww>Z8N0@@&*w$8;(ib-i~%# za0R+S1~e~G&%>iAj|`?M53t))mpBt@c`T+O!$Nt4KfHI|#-{qxoVlh3mF2jT0Fdw> zm5bRro*zt|>>lA!M6XE4Nt$3*$O9af27M$>UVNGaDv9#KrtIorKyF|7FFjvlW=3&a z;)9&T`%ViQ%WipI2mJ{)@#+>;Iy1MaULkL!uP(20>%mw_8T>SH;Zv3&04q219@L-t zy+0Mc;+$|MPOur_Cm2u+V*box&2$|69(k_*%f-{&jGEfylV9(@L2h-W2}*89R_Qk< z7nNT|qw8k;e}S3j#Ze3JqkJE^(t9ebMi7ELO`7eVF${ zGR1vm6hSq7Dd5I_xFl3mG;?puJm z)dps#BqZR+WQ@ehdqaQ?K~R>?S$! z!#d7G{zbOIH#nVdbItA6;$s@GyU64km7a9uYrg!KLIH(+ph0L7ET?0YMK*~^H`b?~ zdU1>-o^Alh^9taT{5L%7;2k}<;T@M8!EJfS*0)80o;?SAV~K%zERhV%^?vcMSI|Vf zYbU>OKN|4Pn%z1=&$d|3Xn2@Y#-mJAi<4M6+4#s1hg-nt-L>&>*zQxlzbf<)h@;M@ z*xT;owQPHda`FBVGm&h__Q!ZtFW@W1{$t1zya>2r5d>&mXn!m6dEJfk$=N&ic{*&p zwEVjl>iUU{+lAq2sK9weGuYxh=I^l-2?){ z{7a;Tzi?Y^%$4}^;wPdxvbpMuL26l&Uq^m9s%BrIXhx06;sqCd?IS%Q-NHIQN0NIH zbX_ZCnB!_t(>))5x>9dC+Z(@%0BWgUf_*p+rG4-XszI>-5ZDICu*^c~7mbHC1a11c zXSEzlH^X84FJ}jqwlnoX{mhI1hHQI9{=K#T8a|>75(!4GRr3F+-do;!Zr$6nH~jiz zn=^Bv{e|78EKs`$ikr-|kGjRJ%WfM#oexy33O+J5y1i}qP#!LQYYilO6n<6w{s#Da zSJM8yAd|AUDAnMXJFNjv8z0O!&-E5;mw!u%VUKC$8znj3fM&>T((c?$5amDN&<8sI z=z{d=(p_MG@WFEL67wbD3-i^8;N#w-bz;I}5Pgd;e_o1rvRK~WYye*=#v=ssierO` zP4uS?jyU~3`voIARUru)C`Jl;e*W|53)fZ{O)fM;a{f{e`lQJQp}h?3B8*n3jFa*=l&JNbwZ3XE$g3}@s&i68fij_ajHupATGpvP9 z(QclLj>g`8%u7gr(t3?QMDr2Z)&u7HYz_HeW>Sh%jE(m<4&_CIK- zDE>Cj-1_f%HzqtKrYR&1r~NkZc7NTo^r^my@WDE(_AxxEyxLygdmI3`3>Pglp9XOR zmF)KQ`z0-%Uumar!vPuj8$4easAOrPaFN$H!0U#=QW3y}ID^K7!Mc zbqdDc96REC{WXx1CCkR|7;6C)?3p4)JiqAGL|C*kvG?01oM^ZCiX*t@6%s z`VI;8_L~*;f-ucu`tm#GmltK4%JIv_T2#AOg<@(WN5S{5zeq9jqv&T~Cx0Soq7J>m zzPmb{6Krt9!yrwhs_HMbpy4xz7!QzzvPOssQ$|+?jfNK-YI^gYVkc<%4*KrFvu|}4 zZsyKx(nHAH*@DKm5?TD2DbhQzYq|V+hml6Eoe|l-l(oKqeOing-?|$l%(^b7%=)vR zD24#m!Qnrw#3B&CaA{h6(@xuCl#2-*$%_y-5Q~1G>VUyqe;wi&n~DQP^nShKHk^ui zxgTf=Dt@mRew2^oTHvxBd}ie(Y|hGL{#uL41uhvj7&-I%B+B$(Nfv3RYxI{zjXFUq zICak&BsdXtKM;;2T=ewbA3Ds#yD9ADtu3D9Rc4lq9vkFaL((F)877zQTeWhYXTF^A zXz!Pb2QJB+Qv30IP|ubsc2rCvoA20aF)_Zp{7=lkklhm>J=elu_x9MpzKGC>G|gs`B4Yctc}e6b>|{EMRdHr zxKdq?Ku=!A+)-GpzHcGMqq|{9=C?L{?bk6M;#37p+S!O04@t+bM(|@LNiEKRH8H#k zvLgW6m$f)K6HS?480{r5FF=aH7mc+Q1y0F7CC92fG%0KeAe%8;gT5}*4u<=tnr%fFouFziS{n4kl9#7z>h z8@GWW~!>&%j!UG^z;qoaFD-_ysv?&FggcaK9|L|JyRB^nw& zv}?k9GLh~uCw@>&!^i{J>FT9zg%v56YvdQHjL2EP@HC~ZFE+k{a-wCI@xhCq_q3zX#R2Wksth~H%UuFuajCLOH+mt1IhX@4_J4=n*$;I+pUiR zd(5^kBajPWBvOxFLRUAglKQN-apE0`z5Nw^Q;1pkpBPEf)p`Ow)f<+&nxCaJ3434K zuZHnK-^Z#<%$g4TDQ3N-lT5!hzOxVvafry*VPp=OW|JgM##Rh_wQYOzQ6ZhJsw@}bKb9YUgP*s?_Sl=ffi3-#^ggbe)BT@T+-j9g%zb(@QZ~f?r7C#!V7-5fB;X@?y`MVckp^ z{?+jE-N%|Obg2~mOGL{8qs7HlCQR(j9ac}cs+8?H@+mJrp>x$fPYqx@=1($0h_^;e9XWz_t5+Ah^)tY$G-AZeFMqE zZYv9bjt5hKv3c<_j}rqjpOd(1lit`q(&4f1uf>Et({FwC+^SznISAGia^;WroE5`Yn#dQ^wDQ_-xx?}O=4gQV(rxI z4b(4F%8u+U*V8qXYVuEL1I%Ahw}|(Ph=}PXn|{`JvIPM1q|-$@R*iK-;W6QV(|`DT zV7mu{@meLs35m1**VF6Cwd3zJ|p?b_k9a zKQhJ>3~;`(k-^Y=+XwC9#m~st;uVnZ=<2UU%H1$QS`UYeOCG4g{Dp?+t^b}ovp`%U~#U5MjdAPjtsT#D)H+m=J z&c&m;cBz@&gT&qPDC*>)UV+z0AcYaboBd<*r4L@Zjct-q7?c*DbuB|Y&2MvviKw;2 zp6A!E-WJ7-4io>JmMJB^`cnBGaB9%P8hoCk*_th4$KEQ>bq?qoUqLFj zttG?_Z^+8Oi1L%}eV3=tmV_Svgd_Ie#W%T^9MqaL9QeSz-R1J#!1V><;^07ztD+7G z2MP6PbA0&5uq8Kf*$R4QrZ6;51SJ}9o1bY#E#s#DBeH%Zby_Mub9|_4;4@D-3pc5& zL5ho-Qi9s6K#hSbS3{qY_08Y$4r7{P)-6eTo4d}eLbQK_`^>4CBYM`p6y!WwX1f21 zCjeee{JUJ1hl?V2`2vd7%9 zr+p;K-`zFTNnF`Ji5e?!k8JFGAJqUfp(7P6nN5zGq)$$PzR$P_RSk==ws8v${j{(` zA^*cdAxyNS_S4B+8s~lUIdAwN`R0(_gzm1=e76Z?I~Gjp(#Rg<4xX{a%avZxhcC&6 z`CV33u87yszA-w3o`Da=YjA`}q`vDs)w)QfEjEBaBRCWsVx==0vP_*g1P&V(hJH(U zEywVO4Z|pU<_&A7ga@ijYX*PA0mp&Byb`Zxq?PKcWBo#Vh_t3Q?2@XZ40)l8pr}T+ zPH->Ile|w8XuX3MkW9N_Ny6IZZi7|hbM%cUf;jfcK!P5}8uFYI_KsLh$27<@X5FD0 ztp`>QV?@JBhDpR>GS2H{j^u^0$1`txCdiS!%8wpPFqJPTIWm4R-U_eI!xrN{7RYt< z(V(QXJOxV>D#c{q8r(}QlXl2(UUBRa(8MjM8p1j!zamzC36DQ!a_YEt1Fkws3C?&r9pQYb}PaT-(c6ed7a?LNYs1tG+tT z%qyQ?=KfYjyJL(z>Zb)W82CmTW2Wep1^6i+T8(7;B-~t)a&%JWl3X{(3=?mrp|Qnc zUQi>l9=G10V`LS-+o~#Wo{({Mm9Qm<+*Z_ZJgWBh}sv2J!R|hiTpo30>5AEAe$P1JWiHMjzSvf)r2# z#={B-Exj^*lTgM3)nd7ZPkWkSLuoOeK1j;8K~S-LXuE{nF-yuzTmAzv;mj*-mW|(> zkrgx+1qv3q@!#WDWAo{4Smx4th$ik%(J;~F69+`sDq)s58i1fGfD6;GBwm|hf0LBY z!`u@qUO<0Iu@Ev<3A!UM3DZ750H*8fzmgIISGqdvO1THk6l|>9l;p5CRDND8V{cG( zbA~}Xzs>Kd`M7Gr4dr2vR46JdK*nS9XJJNT3zt@c;9{xHpFQCP=6fOimf^Oq7oIq4 zjR*dq*}BNmpX~5O0XSgIkOI za%1!kyxO3I>pH39ml+xu*=BXvHSi2@L=k(%7V9cb5u67xhsj+^J=~YzLnKkQJq-iy z=}{<%{@bYgslgKGi|-{!UEpFpq%rtXN;WG+PzFevz_aelde*TXJho7-2e$LT2BK5@ z6wZynsfaZshEqy&LxBd&W6dS4zX2-FT|*Ttuu~-{K356bzR2&ij$S zawhl^f>#}dgnUL+!#!cqAHeOO5h>eBHtZ9|0GCfcjIm-6hF`-iZUYwMNzj1BNvzt1 zRw4x3BnyRn#oJ&<^uXofhcHpn1T*_bcJtn$Y{&I9i)?vp^Z61%j?gkWuYV9eI7&KIHms? z)-I`~hq}~MvUh)vZrB`O1gweOR!ewb=10b|Y4GZtyZNp?J_klBY=q$cN2 z>f3{e?Rh<$_I-5cr z^_wuEIMuk#4Kz4$$o_H$(~VJHJQ64!C3%G5XSp+p%^`Bljv&(WtBQKtTe>Bb{j*j$ z4woCFw=iy84eyh{NW0I7(1IwYp5)A(g;f^xi`6^V!3C@`m##{~_-9YF;laD8DZ~-r z`z{>D9>(?WURmMBjQ?o&1SOnDu@E@gy!A>>t`q$IOXJqPXs(eY1X#If3u^G2W@xsM zH}SQ4VL#?k-vsHFR4U(mwOu`EKbz*{_gH{sW!z}Jc9)0)h<8~~q^gBFae3}hAumx$ zp-BlV?gN($(N-if1i=6jFB756_<-2G5QnM)Ai^GtTd{;!gBco%C0z7MX#EdHq+vW! z<2wzBaG}uyI^`=099s_l(L<2~bjo}kgX(}asUPSwnb68ztOiUM>GxZug)p$)jf~A} z6FgW12fUgRX~~vGZ1v)Mrp*>5w<`7C{kd#>?=B8i3DO4g4IbFf&1+olCw-a;&KW1% zTr7Mr8CVg75{QF;s%e(6$Eke^&mOhUoD`P@Cir&>a5T6+S!C@wIY0f8&6KgEbtx<# zB9MZde$+hBI>2MS)vtCzadsB{rIRv#mlN}j9cVn>Xf7fr_YC$Q@|>EQ@v4;qQXaIx z;wyAh%&w87pAZR5zQZ+XV#je`5Wev0)VQ~i+u#C~<2Vv=JyduksVZGk z!hjj)l)Emzl~#rSI&RG(puKB-Z4?;6-kmVJS1hr?a+RZjS6t$1yu^{%C^d5#QLfI` zK)140Jv>$hZ?6fN7dJv|}q-{`qm za`w*Ul0%Gb+_7)JO79%wu3aTcqI<4%3l(XibiZ}l6k{}?Chxv!;}vP2z}8FB>h8=> zdR>j~Am6xl@?bC=Vfen;GZ_N4F)Vj22<+u-s91VhZ^1zfK7(BP_HHLjRkDT3%P@7I zET!R8a*CZtz>Q)j>6uO@9dN0r>eA4GjdgSz{R>8M&Tg8-yVhIT)<%>JL?bQ_M=P`0 z8*qs2r^$MnEf2_s8ou9XO+ExUVOI(`9R#!tTx`gCv({wb!U-pKEqZa(#98s)Vcb#UT z>)aUDD~ReD9JMJXs9wG0+yy&)I3q%gltLE~tM>>PHFJd!9p+lfvwtQXNa84r-_1X) ziE#5AHLOiMXtQIYT*-CLNsX6*wO(ic9&B=F$F$FcQFHLb;{6+BUyP7~#=bc|3NL~# zA_-ra&-DQ-$nmOiw+6kkNF3?)^=&R)uY)wSA~QtYGHx+-{i4^RSQ`pA*i0DkH;80i zL%xw7_yjMwzZdfHzN2#C)%}2L7k1~3G0zAiwlUP`3rgF$VFucBwQJx=el;^BS@Fhp z2TrD|R6(~@MxUV~Ol9xG_lt^$3A-%#Qw1WdyM1uDhe7ouiY}i5M&@Ny5?3q+obaTK zIckzjE6{La(sLQ{3pJms1Y10urdRfrZ$dz~r2dV{Fv%JIVP?Q+^wKL|X)1m1DKHuc zw_}9Kuh(g|RK531+RZzBtH#wNnNcX{-kRV7SAB?0)@-rjxV^_WN(vV40w;=zxgx*r2gEFiayj~*xCCO#)V6a?4Zb>d$eRpjRfoFJq9t zPL0=22rw?|$zc=d$iWv?<8%op%qt&-d%nG|p-OjUUh&0)i7-a}qt&sLu^z2^cp>Dh z5y?`Iq47Ml0NC@ErJN)ahi2Iihsin61RIG1r5fEUGt~MGyif?^3vUxgLMhXB*HP1v zsO&SP<}DENs)B^Lgz&KppPH3~G|b&aeERE}K$&J91S{%z)dx6mYLyqra(F+0?%;!nx|*ptdgYaibZqwOF%l)_e1BMJQwV)t$IzB zZsb%XZyxqSVdrib*9P|P5pKi{vy|Gw$CTl$r8~0pSWcdyiBY0@@I=4OSZ}r*ZGmn_ zUpb_l_n_s}zVkNgk>4)Qy-?Q_st2CQ1C`2OWd=JbwF)}q55P}EAN+3Q2yz;FrqeFL377vm z2rk+ahjw~Qj6f^T$eJjdgpt#lnu&fiJ|4HGCZ7}yl@Ccz(wqtgN74~ERQAHI`zRA& z_@dZa>8!dedC*9*s_mEi#Qc1t#c)+zHOI#*Q`tIm$pa|nl{{qdOC5Rk{X331kY_9_ zC$3v&CEw_jIV4U10R^pftFf#+%g_pvw+Er9zpROr8RafUl5aT?6XwuIXrB2qjM`JE zS+sO^C_~i8U*C#hYvOnVyhE(#A#{~pzPRGbq8tv?7{> zqo)0>*Y;t76Yq>JBD!F1Y`@Vsjq{x{9;=F0CA`a=;qZzQ~;i$678`n_DhdZV#OUKhm|GWoi%R6Hq?#92#*` zWMx$9pgNpG1Gi#TwoTv#p1fP~I-vr67(`xEqnQ4VSGyo-qGLq38e!BOig1Ttp0PKK z-}G;f2Ohe&j|YU#i7$}nB>1>P+`-y*hhQiVnvuv|20B7|E*E@Of5>*$NypG0LIzd==+cnp1tvK1qx1z?MDHZuk`6Q0=Od z2Bm=%;@PK^14Qq&&Pd@45(q2%vD*5FiS4P>3s|Zrh6}248@bGz7owd#$2Fn=v?g6C_l>qRJ{pQZ_uQ6 zMM(n^se7D?QrnO440VV4!I{Ml!$xns<_`KkU9t-IF+Ct-VfFCpaG z+M?{hP~x5g_k?=v$TgK|j#DYwgA`17K|8bh!zSg1#@gBb3`M!G2ztzgZk$k#s$9nu zL)Kf(^<6Kj$%Nz{#NN!y6ld)D^kPj|N^l%&zo>dVRDW5lS3NFDEO;tEW@@$SA_yL~ zA=)j|ciuAWms_wM&PcdKFpTIKVEiFtdoGsZ`g*K%`N?0-mynRUjPx>6WPhJNS87|< zvjpW_z4?8gC){hgL%8OG>adr!7kR14ziAJ}(GS)c|9wkSJrNgY1f1Z(3kxizkXCvd z%f0)Wt5Ps8mlVURkt@SV_78D%^&a%fZ&sxOGy9Hhn9~feUtk=1)H{v(XZ8(J)pd8k ztI3e^wt)>u{-`ub1H$->L~ync>gTYN(I>WQ8xXmiUyv(@9&DP%TFblLH-wSqyEA zB<(?a_dcU@Vzdd#ztp=?gEd56U0mBacZsF{2qA~U*Z8Il+%;_}az@KVePIcVzMzcp z5A5%LoNxOJeoW^_!80qcKP(~}=s85V!iSOu!Ye_>#oz&8zotSvxef;$a-O@Tm23h! z4ZVw{e-8AQExMVm+0+-WlpjOYqnQp_L3H7|L&zf18sIu0I+bt745--GB2DyJ?@l#TO zyPfyNTLuQpoZ9ke#%(OQ7#@c|MSd>Ple)9GTG9Je6cfZLrzmcvWaHVG5VLHGk#kA= zDyT+lYwJJ7gO|}eci(I<1gwAA_VdASKoL8C5)^Q2-X)>mOY6@je9R-VLpTTzB6>cv z`9<9MF)`04yv8|g|54x6%k90vqJnU3l|){`Na8?g_Ey#>#AV9Ufl5#k9Rtaa+bQgXIJJnF1@C&;)gyCv@?lMzpMM=@!xO%dFqcH9 zT)Mjb0m%QDtjg7_*6Ca%4!$jn=1IUGt~XWLyC@oFTW@x$#|_ssM{*NfBanG~%~QSj zNa6ImSN}*GwEEb%^OD?qrCdl)$JwJ_tP;%3I8yhyGAk8SSC7xrDmuWkzt( zQ309F`x(2XjU`s44Z#a;9*=@kWMHN)!VLN4lOFEV!PnE!DcqO1$5(Hs%T(ykf}%?XR@5V~WVt9?RE9^Y+Shct3ch!480Q zDOjV`)iPa2*1EPR|IiX#Ed{eJ8k|?44Ut7ee;_Yz^MiG{n$X5V7i3cRxG_N-a%$oS zTKo5_1-{tL}}X z*WWbpVR){(h*DIyR(4-rQ`-bW$|AK)FGDx@_1sCVt}~bjS+(kG{u!ZbeNi5w^3Gh9 zAMc8e)3}~VslqcNZo@MH#S2K+JcJT$-%lQq_CC24L3y7ida9u>&(>_O>CfkD3Io`( z#-)xMfFVoyv<`0{eXtVUd)fw9;_M*`I>xVDS zVA8M$W6poHifKgzZYT?L9?IF;vl|~gdcW@Y4v#vICgCPwUGxfhPIV!>^@DG75QbI$m!h1aN!Q<`__``%=`B-#j_-zs>vO*a+B0=FfN z=;+!wqbwY2rP;FE-^FfHPF{WZ>IM*sv;;L;WKj{u-Ja5aFA@1`K^84 z_ibaU-v93RMW>*l?q2FwC4N{-4u(;WNS+)(HXX>?H~`c!jeTl!#Z1={N6>SKK=0zW z#Oa{Ugyo^<6}`NRlHMB8Es&iGkiNVOEcjHdzNFWkWLERSIpp;^m720ob=r@`wd>?H zD7x|&==!?qXWOQS>O_-X9QOiqU0sNv0`G#lq1DF%iGK`3fDFcM%q7=T9v1ejS5gf* zBgZZmx+}{mO?$}oS`PhzM*Z59%wX7Z&zW(h{~U4K?r%AK0Wd&G0`K}NI`v@ek&Srx zx+Zz_T_~1$@8O#I5^A@=jZ{TZ3%Jy~fV@X<5Nwmtda8c7j;?3GZxwm7yKy-a=unyS z$Cn*>&ZBJaOAGr^6B=Lsd(;oBoUC)~^jXzr9&b13u~-osIRLLYQtF^c8bXuzcMr z?e;+>WlS20#K)7EtHkz-gGvkA8k4=N)ADQzJX;rsx7wI4Y_^{t&u0?e!_}0fBv^qo9~6Kiu1hM zYdL2xz3KCElLlpxsF7sPS)ys$Hi3ObFwjLJCn7EqUZqREUz?f8(NMKMI2M&P0M2*D zA}OrG1!hB{9}R6dP>S^c zM7#6XE_62=YWgb@t7=zL)N;U*`K}3KoRRc@OaM~`AgZ z5Hw>o@JpU8EA9h-;l;&pT{~MNNh4{eOn+F>M}2{4kUA4#^&O?{+jW1wLI?k~X>}p# zmyH|^t-tn({~7@>`fF}C(h(Pg=~>?7f?_#v#J=Ma?`TE;^hga#a}kJe)?zSkHG8K3 zGuVm3*J!Z;&{QFLe+d9u0^LI9e!Z!j|I6{g?vR3(uHr(^`)mO03JWUq&opAAFwp0;?OM1WsheNgAkS9Ig0Y_09DCxZ}kurIw zEbzD{FuYL}v<(SpI5kDXx|2#psR~ptC8r`c4rO%vsMp6ug8`$S1Iq5#9T+PcL3~<3x+p9T@$yxMHSQ5UtUs{H3@@Kb0WR>hvTT9;G? zOgH=S1^*QI4%pvC`!v7~XY`U$MIg#O-_e-7gJPO=o%_-CBj(qF38TbzEOg4sQ4+(* zl)U@F+T&#gO4mu)%H*1daT)YC-I{(|myfhHLRd9s-LO9?EW>$xkspHPJt!n_}yPR#+MNzxAHVis-ChZKxYZ)VK@J zrh%IR?_TGK3LH0-yD73DS{c+ZRp^XuS=YQ1SDPst0$=yeQbNdSSx&D~C9bra{au3M z4!2`%nj>ygT)aL^$%mePFz6AMIy?VS&3fz}3&tqL08`wRDc2BaI$o)p2n9ysMO75c zh6TaCox8%t#J!%JNw7KE&Ny0bCdFpdPbM9)&!rE( z*8b@nnPzT`4v-t5%Bm6aa5&>XXcCjI@(4@*bPffXOb^}db=J2{-8ojyJ>%6fm7r={9A6lmM(pM`1_GMozd0OhmS)iKd3 zUbwaQzYjEb67=@jgEZPd{pG!;5*op=gmT!dK{hx3JBZ;*}5)ig6auAt4R{1otHa=Nu z@9?kl$h5)=FJMl2ofG&lx)S^{T~A4JhLW4&93=7iSlmaC`efy0-(kKJRs|zxu8>Nd z!8^uwtM{$uibrXtljb*|M6!zv{}%XVEk-#et93&NeUO9=X{+hE>r?k#+6mK>Kcd!x z%ET4@I~hhxs5;h@9IZJcQ?d_G%28WFZ@6L1K8gfY6^si%VFX>R(Tl1{bX3DEe^fx% zL^OP)`pEqrso9vXnQOa9|C^pGXKgL`IV1^)d}&$dt(~nkPJp3R_=)*r8oVhG#Wcn= zl87CwC*tp0Hbgw&*a`>6=^V72!BfP-PX2Ad^!cyi4?>S!Gihe`-7xR&BFd7J^W}f= zSs&5mQKQ8|aIVG)2CYNBN9)q0IYWu-`HFy>uD8TuU_RPe0Rr@8n;EnNE|&ioH_(OF5p%@m#arr=WPtj6lM4YnoM2( zr;If0a{LU)U@p1hn2l1~ee5jrV^y12?U-7UBmR{I;E06M%sQ0MZ;x;$0JjuI-}}Hm zp|Niw4QPUZm1^n(c=gTolBNhtd2)+qzWhEs1R=*G$$?iyZ7FZi)=Oh(-q+PQWz^tc zNUev*V{#0u7KiJEs{B8pDlwG%{^jC{Ttl5m*nLBhH)-PvcoKYA+ZOf+P3%ZPU}!T~ zgZd3f5S_<6=SK%$!3-xeBZ^U%gNpl}ujpK~czxZ7?V{Q>7|O8=D#xJ<&<-~d>tZ2s z=WQs$M37CcLvu&Gv&|4J1&u8fRS^0|_DE5^{yg!Sex8u*0Q9+b2*)@vuwdCX>GJw= zJ9mEQ?=>`Ei0(x60-wFzb!6t!%Mor|{jIj-qpFBM0lL7h-lOtQ$$6IB-3-McSA5tc z>tbDNDbIy~lEArAr=WNv-$bWpB_t(Tz{VRw){`X#w3h;p^g}wEZw9YL^@Mvh(@L(8 zGeTtv*9hm+o(nNtF%zWMWknp|Irg*E0a`Hv3{6(O3xQ!{3y-pnTu3~CRdd0WwF3MC z@oLf5q{kNUz=a!Ect|>C@JNYIaWh54QEZGbhq%u3DL1SWhP7vLgI-i!9w`tW2Dkmo zWF{dEvi|*)%Yrg6y_&BP95`ohQm<~A-rwi661CihA5r(zObAVRtSKK+uX|#HPIvaZHe;!QQNSrdfc_^*2v*V<4s9M?A1>`L( z8FKj8a{)l~pR_5EINb){Yv`1_$Euo+G_B3lS9))t(Y|3%)>hx;d3v2t@bT_<@E^;O zAND4>wvehnOX|)ezPBoewwN9()oe>mx%szE5kcg46lf0_@gTf39_oLfN;yIkK1;PG z5D_#vsugqay{S#nK@NsZ_^Ms!aYFp}z>3$&iFZ3!EdX#Jj z#`6DA{e$zgM+0C{5uGTy5F__^qz% z#llR4aJ{jGhn6nC3oP~&5-;PNrxyGK^g^OZL;MS-I;l<#3tV}~Ybegy4-HT2L#aY^ z6P#74Ql_Bsud@bFvT~RRzvhRg5$(hv~~;|=~_%!?yV6F%DRKXMMipVjURij9#Blj zj@%1Xwf8&Xh1)@MW@Tr3_BV~Sp5SE1dhjg=?b zxodsSiYF&uZkf=UHrpY2d$za8Ny(eM@(2(UK*ayZs0Dq$6=n&5g!|) zTg}jeNP!O}So2ubw-nezu$q|R_hH-^jwks0JqVe%y^~*m&$4cii<57Xb)%FuA#q48fW;=iIi2_~??_6Bf z`SQ(ctaj``%(uL&nwG1qxgrIHGbrg9&KpU~3(bHCn}PHFqiq3L*gU_y6#b!y%C&tt zxU_gtA|?9V@#S7&EcB6EX~75(e0^Xk@koG_b*~p<$antP;y(Z-7WyeD_LN~OOgVkT zNtr_(adE`oAaylFV%GN5?z_Z*N-881c^3~?9YcKYRtvXpB>zkyrjRWKd%*fi78afv z`xXcEamsJoJBQ`~70cC7)!8_h8sQP17axc|HEoYnbN=JN0#<8tAS6Yhg3eVy z=EEb>&6kRf_ChgLJBoPbh>ywMez0=aa@X&wKe1vggF_~!2yqAMz0f6(@6!0G z5C@bxhnF43NET*7obvVLE*Wk9<_}AB6aY?fAZB615EQ0teHBHIHfQBYJyZ1>+Wg9F#hzTy`J-$h-a0#qeZ;qv3VJSTs4~llFJR zkx*%K(`I0dj-0R_G?={s=$-%P954x4a3hLlx?*}<@K-`QOT6dlKYJKbs-;o_ZrK*Z z(u#~{|I;Fhe(nAv>sm>en}FL+GLCCR7G{e(S(SwY8RGG#2sDD4z9uh5g1C|RPmIp+ z(rQppn+=88T>XCjKiT8&7jF#GovYbEzd)0sEAQGUSakqso3Jjq9}jyR%W;7wmbf|& zmT<$Y8{!EX^Bn-O=%y(n-j=*c=|>#F3yLRR{-;2y7$dp$GP?W+U7IYROX2JiTsG>H zG{967^oS5#Od>p{UHmb3=`J)$W3gMhVaAwl>JmrfH~Ois-4(STWrU;OmAo0d($zME zgT4A^Z@{D&L_N?QOz?6@95Fp&aQv>Je^bT575l*`i*cV8VCq{V(l}`)kESkRv#D(e0SRBX;I(%s3)cNy{~zP`!1^9#kn+_!mp=h&(VO+` zarTC31f1mgb(nLCn=~v1f})?|&KX(Fp0H}0ZM0Hl_-Cy%YFG?U8`&EGT|)LEgrrW~ z78h1rH^`b2sSxx^m}~(2rhqZ33=v&es1I~{vGBL-1LSnWGVJ`qo}P@5(9qJ`n2jkM z>kis0m3~;X@@aM_sU@e6#v&&WfJmZef zy#S!trGt_5!kC6D&980>I5_1R-ZmMHGHpxE&Z%eo?@wY~u5MWyQgOB^m91X@Yo&PjFKC2sngBO^%gxN4Qo)72(tlBGsaLQf-n9|BcrQIX5pa64a#1Ps`lMh7q6##@SnE0vj4r*|8{V4El zUc7sp@ieFfQXcR7&rOTh$$XnODu;R3fY>Y)l(CtE1({_6zykPlb7Y)cX4G)Wus{Z&mL55qzHqz^UB>r9Lkg#OQJtbpJfH(}N+0{{S{ z4kEzS(A51#l}CZjmj0AVuuUjTUK&;bF%}c96y)sO5_Ymt{dpUoBHI|r5W;KkjiA4C;_@e%u%F+BkOSUi1?B%BFE zbwWZg!e1lkI`Sgu4*BgL<1FJM6(&VClbhQ7o1QOHiF#z~{U>KY8^!qK^8u>VtCGOz z259{hmj~HY4A6GpKl!}g0TT!Eq?BzjG|0ObR#Z>5v<~>`fCYVBj?Rx+1JGMY>g$CJ zZCr=f?EP}ROFFru#oH0_#G2OYHGc|REdB?E-md(n|CVAZzwaWmk?e?*!vtyi0M@`? ze{#dUZFhrNWont#F??E{V+7P1_l8KvK@wI95m9a%nSt-!dF{*RLr(C-<3ix~H+B|g z(Apke`AL+0!(#5&Oy0E#iWf20=2ye3McjG*6Xj8Ix+#;7;K2&yXF90zJct!=bUps)5EFv+I%|!{o@cBBHAiv80XzxXyJ34R2;IxXXCO$Ab z{Qo<}^wu->=<#lC>gH|~_U=azJPX>)ecU<*%Ggf)^4@5Zo-;NG!)mSquZN3O`_XxZ z(1Wh!EA;!(Zo|5j367JWLeP8P-%^^pF)IE?j}>OPr^usk9ZsqgHsedruaUbcTpIsl4bX6HXDlJOS_rx^Ml*WZ!@E(a+0EAy`Af5UP(NhW< zy7YIXZvtN5qY-l*y%D4P>QjQVa$SK_Z`}fUZ)>&jg@X2YaplSS!LUl#QCp1cfaIRj8SmiILh;MqD~P>tPu(nd#lwPcQX^ za!9!7>ny*cirbWkEz0c)ja(tNJa|6!B`qBId)?p#;% zgT&Y6gILCjj#~LcXC_D)zbv?&E{x@0wVnOG$M^U3M6@^_zt?a6MEuHahot{@CAr8E*2~kIe)i*=k2E5nE5tT_iV%nf6~HzA&&P)dlO$=X=-@Gjk3Hr z=k`?YH5mI;^o=*=CaNg5hzwLF{Jb4>=#O_^NR^;Cm$ArLKZva*Ga^Ql=9C=zr zb@V&E$L-xe67!m}(RNgIIdx5t7?Xr6_cWSp_%+u%M^O7v62#19hK|2VY=C)N@9fw6 zZrM{SUP0EBPDNiQT$b!03MaMr;n5~lvDk26a;4v%WRqg{yXJd%(#Jo%yYcA$9;6xP zZF)sDD4FZzZiQ3du&=X&;aJugU&Y%=lsRhfcrst~r(<7g)GSJfSNo1qQu-NTE@tZ& zdpIqD39q`RJ`v14H~77^aQFdcAn_l$1*w|(UBXFo>?uy=EF>y|O=aDpSwrTU{AcxK zi`ON}kIk<*DiVxiJKqSum#y)doZY3Mh`i!=&Bdz7yEUs{BiBcb&c~^kQP7<}&f;@?(B2!KPQxuUC!tNXDv)uh`k2TtR=+C`LuE zS_gQF>B7wWQq%8<-92VJg#p7`@dtTrkNO^`bKS9&3+4Gs;G0gj<>0mxy*5!~ zO+5EyJ}Y(-pPIAC*XF#Oy)>%ViHf4ear+tG$x)|^kU@k$UYLpUp3{V&dnStWuny!FYIwG$@~yl6A01VgkqSTe;Yr$!W>+j5418z#UP&aM zQQ|3=!WP2dU%8I&k#P&|)t>Bw2CE*>w(&G&R`g=+D@wCQh;od7x9G=QkVL%t45c5| z!^kZDQ?v*(3H3JFpQCUu-Q*i#O{Kd|7$6qa6QFoxTSCE#AL;CDZ8ZN-vtBBqaJj~ zS8;n#!Z^^cFE-uIpIWhE>E7unB{~T$K@zREw;b%X^79tn!EEE+F*6};xp3EMkD(+# zuc_hh=bBp44}W|>9YIOpLigwnPwCVfY*FKd@B-ywPKJFPcg^ze5O24>rvdsE+gHxn z$6%d>w2DllJBxXLMMT$(2FL98VWe?}s;!_xaG#98@J=w9_=zo-v~`zZz2ar{iz|RJ zDB4pnwc>T=t!2y|AARu82;6;A#i%&`47hMY7=A`i(5e9ACRf_NaNL!Ve`ZJ*_1L}H z^}4>$2(|SkKkdGc{9D)miMAN;+U->NfTKWkYb>-pul?d0!ac8<^~p2{`QZ)hx|oY$ zUoJ-njPB6bJmq8#yK}E?fBBdq$@!l|zkX81@W?6WBgrWjK0M}%OdsmT&z|%;3h5y( z-kc}Xa+tYZEpsj88do3c+E2F&+kb+qL1TTz&ric|dNe52#DuNXi_ZGHU#iyLpw$1~ z>ofMLe4;+&V&JyXhrkPyE2g)-9#-bq^v#Dg!yYZ1|D%-*Gg75wd0_3G?_9OmdWB-` z6JSi>+;X@$LvvlxLDpY>s;-rnr*M#}?vMZ)W+{iahBb9U#$^77Ni zcpLYBJ>dJflwN0VYyAJD1m^kodWbTF-syX5zc@NwuqH1*@zJs`g_kz`h5o-^;s0=1 zdSF7FvH5z*u2RlYjXh_mP2Z?>$N3Vj!}8yc-amoSH2cA80Za0(++ejJorPBfx}A5$ z(Dm>C>vAga+T7VU+?gKYwURH;ZD;ZG?CW_{7;e~?_fF=oSlpn0l`e8S$Z+8m$B^7N zM=C{Tq-Uak4Gr!~t--%{kP5gM_bsw;D@$4s8^%?i@60H7)sgb%pA`Ii!6W>Wbw)*n z&E>lEOkSJG!P43HP~t*`MvUvs;6+P%wI>vCF#HY#bf4dpTm_l8+Mh6~Sqe%tvg@i| zMzSkt?gf8Ap=X}{Hf=2j2rZhf`~1OWBpH?phChXxu12R_09P!~MrCA|{J7WIxkbtP z^(^wLBR#=I6(qi|`9|f7qk-;od*@h#=ik}(24Byx(RC%Ei=Y0+Uap;?vZWB^kUteB z_(IuqM;+e>m)LzeIyf*MT2xhX5kq9|%vl$TW}Pf^n?ElR|FbeDlW9yGn$NsQ-gx(S zl40L%yl@4M8d{z`-;S+Z(|`Vs6-kXXvbfyZc(2f%U|*@|AQ|3v59GdT|Gea=mn8Q_ zdD(5bdwc0&9EUD%ROX(Art@hrPk$c~_o2uXXxd1o zEd*;DxB-He{MqzUiFk4~B}gz!Vh|rFQl8x}TJj*ze^aL12DNlA^5`hwO`GJ4?JQcd>CP7yNwH*{rO0Xp6k2_$xBBjnx=4d7hf zdN*0O{;Di?gtcGfTiYDik!MW0-(TxPnz4l>Z8ImkNLFXwa3t_fn&wxlv6yExi?FFs zeineS3@WyQj12|a&u^;y*`-@ap_UI#2&}@IjF&Rzg}L#rx|yKyzGN@E5Bq%@6$e3{ z{GZc*GINyglt~SrlksZDEYmD@G@u4G&n`h32_{gcKbo;xo<741T`d)5DUf0HQ~7D$ zzHndNPpoz;_^mkJFkm(zz549`TDtOhD7QXt-zIb~O?G!`Y-LHdyq0PdCWM3}L}$jGh~Q!*smSf?y=jh!$E?|JI_Yd#<6Ip_DB=lA=4mop0$ ziEb;4(rD4dboF_NR^ST|W+OBR2(UbTyd~180V{vni~19~*fdhCAFO-d1Kt-;ejt{Y zy9-)}*d;=O)vile_>GB9X>qdZlmqpDlxhf+q-+o)bH*-@0C=6y9e8zp(#J)>NpM5} z#xk6nyFWg>sPSKPka zgK_WN-_5L@o+06P$3RBHKO$!v>rVxHQK=g$B6M;81?7Dys57mbQ$OM7=Ehp?eqh z?M!S1OU|?Qk{@p34160&e8_TJEghzPu|f=P?P-8TW{(7M?{JIBI5~75Ybcwj3qxSg zR5dY~>d@-K(Bl|iYC0w0b-s^6W$A(pG&$cnstzK<$`5DJR6w`Z^R5UPZj8F`s<&zI z5Lr{6d&^+fRJA}IV@9?2X5zv4J~BkJto-Ilc%xlf-($Rm$)#Y)8^-ir8?@AUgx>3% zTL z1$g?fTf}8*Il^L?+AoSQLk$E;hUmr@rd{29V)!LE^{i_e)XK6v6jf5ypl z%4a1Sw5M)5f%_I*UwjV(%ES_t8Z^=eJ>XtEG2?F;*2(6wk$K|Qo%@cMy>W9Xm9^bi zDlWd!=W$4IItbF##Yl|gwBm7=>g|n@Iv1otektpEH4f)_9P}F-Dh_4~gOygS!<2BjN+oo-rmOY`l?POlN_5p>h{9fzepi&ft{ z(CW3yjSX0uRr0YA@BQ8z>KN5^c6ZmoEZa3awUN?i!izSIh+YQvzWobnXE+uGzT z60~4elw>GIu3tDv=ySyyv?{ASHj7n5Bn|(Hl4wGGhj(>u-;Bfg9Q|5J%%I6ENsRbR z=%U+>VeF}klz`+cd==gn%INh3Eh-ZGI-AefFzPRiekI9T4y)Ab2d)WB1&4Xwh*aeI zI}t{;ccO&O`lX(SY>o>A(+9jK(NcdPoMO6zRF-At=FN&6?}iczZ`C|kpDF1Onm&8e zV?-Z`4)6d?*tCO&3cU$#&V})H;k~4Ol=}rj{T7BAOEEDg%(S=6Tl5MD(D_HdYF>${ z2|9YKD_KhoiT-M%Y{liXcm!=igYG+FJ%06G#}N8I+iBS0Tmi?4U;#8Mtv5I(l;Mg< z92P;Kvy5OEg7y@uf@g72!ilfZL0O~bk>@`~T!FgI8?YiIu@n^wcYr!r?>vC0!f&;W z*10T+hI;F4BVCK2TX)eN%k+b%^%T%zTMoND7YN#MKa-k~!c};q)?HcG<1rp1XzkwI zw{%WIp`iGufYz7L?scU?JK-ZOH2rsKl}Y^Smn*%=x*6T(gre1()I;8hU_>@F!Upjy zHqoFR&h_f`qdQYg2UI-`;*eOsL!X$jDZl3VHOgfKHvKlWYO>XASU^j(F%DeW+vg&@ zvW6lgBtz4<%$~d=G~M5f1(v}r7dW@~Il)+NS_I@pvs#yYLLnyv zyb0F%fqO4UW_}vkEg5gzhH}AV!2*#%kwp=-jlg=?|Hg^`C)Yf&j3XDT^o2UiVK@Mu zXs>kx|Ii5Z;)etDhQGF6V9@g8s2g@(ACFv>+tJ`3@1ZuU`?rz{FJr zI{Fjq9Ipc^2IlXxwTSK9j<9O+1&w7{*olxZL8owk7K0-cgiHG@elSa?Te~^I_YaG* z5BfD)Z8j^tcS|Q|^8je?#g~MqL=s(bqRaFI-$;XHt=9GgpgKI;3w}h;^gVYF_$kUb z;Rgfmoc8kRS(CIf>s-Dox{;9N#*PcFNAhdz}?HZun~J7QX3 z5!}nB42@XXNZJ?Q9E12p4mnSy{~^0B=4bQ5EknQG84?~9z!9Uz?e=&6zRNTe1|MlX z$llvK4>@7l9*DtUNiTms`Vo?>);?}@=p^G+%xUa$bGZ;5PA0m}znBO|ODV41gnxZj zBFAVv)9*1K!dlt21D{5_+_BZd5s~Y;HA_%@0I(nX12P198^1Uf3Oe@tO-@9kbRMx1 zQdjbLa=pNeSXb3oZ|~CfRjb(bi?1M8KPXTPA<%aW9qc8}(Uz zRKr66%RkrUV%nv5d7YYF#_>jk%}u&JWYPMdbt3;*g^_4PK=mJ`#xE{Tn1E=dLJ?O( zusst~xR_ebR|EUaqHM0^+@$L*}Xb%b*-tCN&|h;r8IJ}tjImR`R7!L+xsRC-+= zYhcE`r?D(w9J(0A@T6_taxtwj_;FPSKgSi73gMtp57YV3ptX+HUd=XBq4m|Et1tg0 ztJUF`tp+8zJ$g-T?%naKLi)p+6r(9J2I5g!UN6YZ!^^{T%mKsY!x*nB>4ALs(B@5f-S!{AYS zlL(--wQA59VWqLpVr~>&bJ?01f1mxUiA1>C<{d$2nZY@tlRQISbtg;jqjr~M#TplV z1NOAs{_s<=_szIf{l?nG2lODFsV&5uNie_PVSBON5RN6DW;u4+U1p;^+mke&DMs(u za>=UYXyGp_-`^Pwmkvd>u``uH;KJ$Z1`g_2KeMs`-ij6Vmsw{wYMf~k=WEVQKWeq& zh_rDy0Jf?leQDovICLccbEev~Gad#sTn+ZR)5yb? zS@xc654Jh-|ImR4x9DgD6&U9t5%`s z)sIB|qKKH<#A5~}>6W?G8J=}}wL$tJe?j68=(y+VeYiyl>A1{`6XyMc)4YsZpi1Ta z_h6qNa%*S>O=JW#+)#h%`QqoZR*lQv0zDbdEhxaE8!F^C(+i_u`U6b2?HmeMG(5dDy=dbUFL8z-BQadMTpxlfLZQ9@eWY%!KSrGTeAsbb*sj4gO5yOL_J%Qo`)eaj zonf23|L%tiLy}YSlqHyHoR@C-o(&pAmb%+MBquEXB)xJAP z5@WLF;tk*nB*6oGsR=wdS@=RM?qmyBgr5}CS!k4d)S?D6lU;7dOZk|7hvrDNM|2vr zr^X$yoRC7ZYB--NG>F_wCee-Usym{dfdmyLx*rOumS$r~2|p*s{MvKL06GDwJX?Ev z2ro_@KUeeKpDE7VJ+&;ftP$h;;#hJ{b;6>7`-UZzsP1}Lt?qH*5&K6YNVpwJig}JqjiHEo3>q2J6epu8;>?(07U>mB!a4t?3Kj8VoviKU#N*A zKLhr$-EOC`dClBVMvUI((VNtCJcv6zUS^?VSAlqud-=poeS3{gr8kvJQ>LVs8ycKT zFRq0NE}N=nV-4+oH>!XW3?ph0nc%708enIkJ|PsL#FXBQK5l<^KD@nY#;K%Pd;zQN zC^1KQuRLXEenXcZU#J_OjjMA!-CAqgB{X-X4EXEFWm>bM=YRhVl;wEo!JDLM%WSSa zBal@FcDZXVBn6#Gm`yyX_H&4Cx+1Q@cQZ00e!iLA)3ZB%p|>nfRU*cHH;K4yz4wKu za$*j!W9kl>B*P?w|iBgAwP(hJkH{>oFD zIHME5PNh81{s?g$N)?40@SY#4_Ic?mG|C@^oFQBuF$$CIQBPTen+++Wnz&|9-`u2N{2RCB6CZok?mmJWx_QkIoT)jW5UqO)=gXR zb?r*6gWAExl_xME)b=FNn&xNEkTpkuoUH-`o{Wz)j!T1zt;8Z0r#c0?>VZ;lh*RIm zuGx@#q@CBl^uVIX*tYr>rwxH`LRqyttuVCM+VmyAV~ev{P4=1&A}O{S8reN2=@=Wc=;Rr2)egb`7y`C)SlJdvy+?ZXeqzu%ND(U z<{4GIkye_8teLMnLesXglh0z!<}?xr+OH0M@`y14itKXK5~wG_%rT5NH5H&dc%!J> zB}O%h zmcs09#MOi{aQ0Lppg+$iK+tAqhyI0bo4oH919TcAedSR}3m&KTnEyZR-RnoIHCvED z%8wgj+radQB-r!^h~X+iswBY)sHPYLTV;8v)7BamV-xg;mW04qQIN3)@BdrrQ39gq zgU;zTf|JWdtMdI1BRo*)A(Ab|m|H--W1q(1gz5dkskh+dv7ECC*i#TmP5>?*Z`p!G zxQxT#r5A7Q5C3`ER>MU0bTdC2m*3cX2{3rM_|?JItb-YA-Q(@3&_alv6MxB(-i64W z^Uu2S4*T<-$&YAujgYMbew>fOQ>1V{s!r^bWQgIpEs&G&|*znlx~xS%9VpY9gn zP5q*KQb%RVk_vv%OO|{}5xskuY%q0mL?3L5>xd)>p)j=6XQ-vLlbwp^_QtSk@J|qW ziK;ma_TTufU77-#6o)%dSFs@DEm-#-j6EcQz$I!^^>~Z=WYNg#ZG01A@RDCyU#I1+ z%@MR3%<&KZaH_+IJYn=ta@m6Fu63>Use#|_OAVeE0nVH$Ay2p4`Z`Uz1AWe%SY)^3=XP=|fcipo zm;_UD3ebp*b__{y)ndxj( z!(z>hsyl>BJ@I8(IEn)`|L?H$btmc<{8xm9qCRsKZ;N=DM@OQY{_wYlT(+mB_={_y zwU?l4{)xMOts6c!{N5OId5k%C2S#s4rS_kHHT@{N_6_Y#!NV0KTDT-bK@LVA4Nj*E z=u7y!{n~0|mvvL%%I9+iX9t+7M31{Ucf!o5+aGs6;=PLNuTsB-9k%dDLH7y>(q(}~ z^qo>|+408ti5?~AJfTmfCD6Rr(E9X>i=A@FMSq%vpSS}L4;vJ>UdN6)mk1|p&dbvV-XeVufCaq6fWBS)^V5d1hr)jjN?Da(nGvIvH6XC!E$Ju07zXLUe<6k zTpwFGP6Ds3Zmkr6}YP7V! z6YeIpb%kRmwiq_uJiAv9OySbS)1f-cNBpklW55B;dFlm*fZx7dUM6s|Zi4PMlevv$ zE0Q#h+{pUob(PDD6%FU~h-HE!Mh*BUt!iqu$PmoXUO6voc1{7^=6gMV{t$`(xW?

d$-CXj%tHj7A>FN6I4&ba2ixw4tU4kf$9b13M z%eKrn{8Heh!6(9%q(2d|w&il&378WQp2rMk{g5wWDZv4O8xLq|cfZ?&TL0j#)6cvZ z!!I+Q`oy4eA#v8S!r99dFMe#{uy1SR1=-E Sn4!V}{?O+yovT3Iy#IfW0NLaK literal 229216 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%0DR@dP1&J%_6-6%>f&_A#f$wH{ zZ#|j1OA5Tg6Vw7Nd=z7KP;P`mhs&~M_m_RU;|RM%zS*^?p7iUdne_3aoNb+P`>!L) zx+>cQMUb6}*4yIaPZjV`-0xv0E?O|e(HFp{Nh=r-epx(aWKKwH0t*(Yb8h9mfmo~B!-42s&UfzwpfNjs+JX& zSgb5nzH&;26M9Kd%W6WknCC}Yi=_iWHUpa#onuQsKso_bNNZdjCJqV`&p7RjL7%VX zHVklt_5l)t{4v+cik=K0$hakAY=X``mkE=pU)HFoSK};1dhA*#LFc}9Lcm%+jMlvr%D z&wG0mZLvGG9Bfr|np^KWjUcnj6ukk007<`zr&?Am&?K?g#3?=8ym>3_?MGqUIC8=J zfZOeJ!U}`PcHn3#Es$+)z**#Gvl}o2@D2=F_%b5C1I)q`{J{CDM;2;+eYFRTW+=VaLwhc*jA}PUnVeItByc%M0&+Cn2VVP{7 zgEJM~BFK8bbp+X{=vLrVO+D*!Ie6s~%a34!nQTOAu_FAH*zO1>TlGdoG{-_A(S-|Z zWW|cIWR&F0>_J^|8 zu|5go6yos(sII8wK@|;=#JETz+Wb#5zI%zqvSfQWvCCD5IvVq*~ znFlQtJq372kV?4i1x6Nmo$|&f0iftfipB$)I@nHozC!A0kXY=G8jW70ot=B>?tZe+ z*1PnLjj6c(+0xy8Pk{Bj_g@p4Mr-+D=AG%^FBEDc7AwA0TBMh3b3z^Mrm$aMJl~c$ zJk>5{aT~sQWBOVQ3Ah1~f@M@3F2}QYQdz1bgB$&g86*~aRxRsNjLvxadq#`wY+S

y&{zo7epjwVH&ay#PtQgT~v>06?r|q(6f=rey*`t<~PyZzo zsVc82jJmQsbO?IE4$^Lt2hOXV8iB(i9YR#C-) z4zEZr`7{m_iBP#Jq{LAx$*UXY7LC8Vx^|2dcqwO4*`nf^mgLHMRR?E6d zEo|n zt+z3P+<*U&UVr_wYFSq?IQW3vd+&tM<50_*4;(K&JsJ7}RT#*vx5l-zGec7$=Vy$Y zPu29IiYgebUd|fd+8q=VH~t+SP7)56g&->?rUQ`f?iaMP^JwktybRSrL^cx+?*sPG z+qg=CL*V6M@NGn$#MU8Hn&|CotZ|e{Q7(Ew0y90PO6Z> z$Xul6Y$GFk01ZL%zG-NPqZ(#p#K^SN)YOqoHkyMHN2uRuPpj4t3e`|syCO%$yBkgT zn?)6aX#^#wO2=f3Oi=O2QJwbfXte%2ANo+LNIlpKViA3s%$3vsbLZJxe9N0UQw(JKZ%E(9<*dVc3l^n|l)ub+794etoqKYaG3Me`S zmy?-|}Gi%i3aTCpQ~ORiL=_ zx!kD5R3`?hJ`CIcf|9Z2))>pTuA{RS0=5eBc9zd)%JiV;W84RmWNLSXd_Gr6;r?RQ z0aGO4KE`1(C-r@K#LrhNdW;}zA#0UXSz%YztS6TwP*-MA#u49dIP`m#x<{vvJC)00)a^Z>vPjQ-OoLAET)9N<1AyWY>2qS4kbcXpQUXe1=iF>+|z zw{Itr$PpB;o#q~Rc4IE;!pSx>k-J|ltAXa`b9B)n8J&!K10lb_D91X#`Ob#6E2DFI zNhF3yCU>zeWe8#N59JEv!CM7r(ofxvSQqh#bgHE!Ba0?4E^IrS9vEmgBi=J zC@X9?%ah1Lkl7Bf^GQ#PtOJe&R#*NAtEgf^BX?jPG{7G(Y}=Nky?xv?$PQrm#UN(` zPaf=v1(#vcyU2{;{VM6k&teyxa%}Je!5!B1OcEiX>0$7D)FKIpQ`+DU4sx`UR z@#3QY<<(z*kTb@SAlpF&+AalDGwr}fjBZw87p5S?9&6-@1*I8t-M3>hG`q8}t1TGP zsRi@EXd~5X5cEOgI8VNTdFT~$ZsLL*jFmNh!F}3ws%R~y>h6)TIi!gTK?W6lO3_mV znMgwGZ7B7myP#Gv0U^kcEw@lb6;)(`E?yjB_38j;F3&Ui#a+>d9 z91MpEM$DB5M$gLWIvGK`PN!(nErY;=RHEN`&v9rkNJrIu#OW_IM6h<|ibHz{W090H zwp;2|S2dHp6Q!U{xnFFY&Ai9Y%VW|N4$orm-eB_$(|tF9pYEG73)nnbF{WAvy~hDZ z`Ir)990jI2ZIi9jmfGdrckj~9&TQP#Yl_Yn#7*vvUMDr?xXb|W`QXuHBZ3l%7Kz2O z6AM8QT*N+AmM6hTf-9oYDftGq<6mSqMq?~+f9uT6Y@fb0qjYxcFqUnXDGj!AWC{kd z7#|%#mIQD_jw5g~IF112Aco}HRea`H+sP!z zyo0viw#POQS8am(nqZZEZjWk#a0ou+-1F|i#v6c?65N1!P)X$$ z0!H$!cjTYgJ$4fuz}$~h(v~P=GQqjv!)(1}EOs;zF;U%xs;FXO!8@VKt)u$ttMdql zi)r&2Gh|78maw@LZuvAX|M1h<+ingd`~%A8(ib@iQU}Lk9DrRbXbYwiH=70-nE98G zy_L=jCk_pQA%bg*jX0vz<$@qP?CRtos0H3a3OA+F4}74J=H^sP9gn+ZMEZ$D%sjBK zZ)mg~+HH2GItlJNlvMJr8MmGm%tuFuhA`&$bQa{(Ec3pO0JVrb9N?=BlSvNMC|ayr zV`-4lw&AfM%Juz#gvrW2ViAUYm_Pchv zASLG6*HL{R;OPEENDr*s4`W9#HR1D~-)j%abw>*{?J{xStYJ83GyLro_>l9EeA97T z)f;cDXLvXjP;A`TXKRfVkHUzXL=bl^n>1?5u}UuDy9sl?{gA5^K4kyPc0P*LHFE;M zVa#v&h9GV|$Ua3Igi)=;jDYHsKW4+<{CNM>{wM@jXSOp;?8=XFBEYlI$DyuDs#S5& zzuH6U8eYK!XXjZ!8>(g=V2pk2H+3(GL@G`Sg?5un zI{TeTB4O68udmZ+v=Ll-!~lyHasO$X+b(-<(VRTT*iSgTf#Kn;L9~pr!pwJqz|k#s z<2m3IMU$9wmalUK3hQ=p2w3Oea519pWkIS+&JTX^biSA+o3Q_Z(TX`dJe@=$f3;?A zw3Djh1nf%T{RO5v?F~Hb%mDu!jkbL$8g)B-HekN*DWAESWBIg(NEK!bV#dyW&Y)N? zi1%U?PnDOOjXRv49`}vz7GGO4?%E8Y&?ds+>A;)WR+;-I8_#;0)9x$xzLUxF6MijB zqBz%%;PA5MB5}K~y&TvL%)v{LiL5Hq_A3fI8yLm}9U)AhQfN7`VjgOxh^X%jT1A-+ zdeco2dV8l64j)1m!f5&Fo2Fc`a+bSNan^56+t7BU6GS8uN;GN)&cVR}R8vId^yy6+ zji#=fbmN2s$z%->rlw|{EL~cT47@ktIy`f)^Q6I0zlC-ND-%C z9&+uZ%nbYvLGj%IsHu5{k&$D7Y$fpTV4m?6aY3!3iv0j{fDN8y zpUy0IUNSFe^&+Hxe|NXe zAh6emmvGiE6qE6nCOS}(fs={Fa&iP=&(q8%#ohN^D;{!5G{E`UA59Gmnf4a&*3Brl zd`6yi6=n=#uK9hLSp(Gzfjyu9E=OakhyG-D#$Vic3=-8&wdBxyPubgtg_y8Q-oc+Dj`}}HpuO_@70cu z=A7#wiBFBFSI=v>WQ+T7cn7_`Qz@WzGcWp4?IA236GCKAeOhw7@FRU%6}=EsO;)U^ zqa)w6pVcRNEOCcq}XV75w0&4EDNNA>G|CsAZj@ z*IjprELrkS{!e7zl;^d%r&Z@-H1rO5#5$NlENzijBjpX?G+vbBx-*FjhK_ z6CQS^+B=ci49uWB?e$euG11}ooU2Y0YzUIDC$I-S?5c~rNzKhOnMAG@-LhiZ(GYSa zg_Td=7dEl#GIn@fVW+*>&VpV3si`pmeoKwJXX>@O~{y4?zf-)R7TbAG_nxB z4g$4U9(X#pLzs#~UxF+*Hf@T~*jRiI_E@2~A8jkpTQm8U#ryT34+K0!0tS=wDWm zf_Gfmf~hLoFD55dR59i_@FoTM@T#IG3;TyGMg{R6Aa5)yiXu5$bY0MEuWch9KbAzI zp4!^%RaePm5+Bor<)@!G<%*TF+!71ek{ChSEC*2SB@)@i(9o`2T9y6>uWt9qVq=R4 z9zsJcs|k_PjNrxr($%#}E$a%h8QkSY#+V|=Dn$=d^ej>_X0N^OZhM_EZKs`pIK<;( z-->;1T*w@+jWeQ`44XnCv7@|)mlfrEhU9r3HSS}|`HyB0WVKmZSVs}4#j?zp0L4Iq zm;`YV1X(y-TM?bDiGdx!iKGa!!dp!?ZQ4P5`>|y@9s!UuiR+r8`mQU1-57S&O^|tS zqBjFuJRd}`g;tNiw7>NV@=IAHeDE=1Qsg# zkWdlZ@(B-{l%6K!Hz&CDCT8*TJ*3)woU0r3+(z&l4y?l1|*QMd>-Q7pg-JLav ze(_{#-L(#ORoVWhD^W!iWx~IIoZ0+D!(kmU+7LNh zqfsMOl1Pjo5NUX_g&=Q{ z(vwBeR?InT1wwWwN-?7R#pozIV~O*3_jn~;ZH=}IfX6*=wGb=`IvtNFJurolk@6={ zl_tn&aU3(8|0r#dIIG8N{{`VhrURSMG1LlHbrbwKTP$-U5{Zyq%zD3uU1{NNzu5sy zCG#fAzKs2N{Ji?352YC?Q=f8qunRZ_S4pcEf^1iGuA;4iR7#AsY*5tEF>Aow z7>;Y9UyG+u+{4BB{A+^zsjOch96pCcB8YW#P&gH2mB%<`;`RFLXE8K%3L+z@##yr_ zglaFalcAxP3u;lVfM%Osef3m6@{udGu5OhqU7AZvF%axFnH9jzATY|Kn7xx%~z{ z!sj!B%qprlXz}{tGy}i&s{+ywe4vr~`r5MG``~}SmuU?6QZ(9}?>NIZYoLU#AR86k zf^pJwVxbX&YfTwl)XGg1+b{{-a!uIX`kb2tDO-%C(dca8C|R~F=QF0#uq(y}$Wkq= zH{BFr$Brx1vL2FHY^UEk&Za1>f-IeI4Tb7SB+6ewrYRy%*Dy*TtH#+ zDY;zB)8Lv@jcG@bJvVM4WrP7R-!3w$6e;KYg_Q9`3ub;21|IT>VVi*cZ+-9>!ELxgAt?0ekiv@*tUPv_(YAg*f*4))$yAr}(@E646u%eor4E61wktsoPrr?$4NPN1%RRW#<5SS+E@XrVDxV1jJCVBh=B zxaW|ig-FB{4LeSCNV)a-G_V7T&4)7P@uAQGX|Pv2OiiKM>Wa!|@{!(GT+vGES|~Rf zkczn-d(n=M)Q=xQwu5vBv~+|*5fX_5;sOfg>8}-J$V&#zUq|n8FEjn+15cl2C++QR z6i_Ya!hoU;w$S1z1bM+Gx=wZpK`SO`%atwY$2>6mFof01Rd5L5}WDh?K; zUF(X5KO4?5F-RmTIVq^(0Eb%EVbs)=w~L_CsHu54kL!4OE69?`I(F~gF9|XLq~Q5V zPJ+x%Xim3ZI&&rOylDv7hnYL=1x5s!NZm(8!=C@`FG-050zdx*hYUpW6h|~R`n9R< zk7!0Dqq5nLAlrs%N%2QK9w8jA#K2WvB$E~Ci$3)w)*k&TM~)*w)?cBv%bgfv)P1oF zsuEzZ--TiKGXy?u(kz$l@c|3l@u(T|@N2-3gFDLZx>;^bKp{D1{okR`5Q#)B-fKq# z`KJ_vbLr_RhmpZpqF*hmR${RUonfqE!Xh!2By<&3?B{6cYbIBWJDI`3^<#A~RUBXl zhmVr3uKykH!zcvO)wNwaI!?{8N+}g&nR5))I?g#K&i&<*)g6VuV`jNgcy)OMGRGW6 zrvpb~s^IfhZhAUz>TT^jzwR5aD{WB@k~aLha0Y<^LB`4va=(B+NDYG(xc-vKvd@;* zPvhA5)I7Rn;qY{J?_OW>&eYdfVJzVty9E3QGLZo^r=@c(!^7hyHWwJ-a8f~XiCoX# zKtHOJ3vo-i;33{wavf)u=OBwf<=QTH5)RM(|Jgh5_&BO_{eRCEY1O+e*#>N5z?crE z+JqKdXd!@P(Gp0wq!L01m;5M+Qz4WT!c8GSxPiEdBoJZ@gyI{F!C)X18%#AW*p_U| zR$Xm7zdzm??d}da#fv1mm(fx zWk`oqi8Suk&OKX?F{gcmkzxixqW5r=VX_%Yr^8DNF4xXdz#(&J?Z@l&5!*rM;(?|$ zS|#Z%!g(~lk3I0vRbTl4nY2h+k~tG-bPdpmybrr`ie)d*uGsY|V&x55`|_C&) z0t(oL;Pv~G1Tk)RF+ShUKS?|UFfu9*A*vP%6HVhRLi&@TQmuG_Qid*&a$|T^8vko# zEN7~9K2)gTs&JPvhRjpTMDk1pl~=QNw_B;%vxh?D;32+p;cz0+(6k8Kdt)gov^4#l zE7MbMSYZ?yFypE+#K*b9$Q&~Lmu1!5iUa_xSE$@9NAxgxEZb2+9UtV^3rvfUC8u}A zNMViHM^_Ca?r-I3E=;;T_q)dcv37ghf|8>_)N&L z9SMaBFiak58oifBABT)z(=CKxe?Iqx$3_@p6O*)4i*DOk!(1APlKy5p--$}9Djvkt zGuU5gI-g$@lZ_QdGwO#MXq44(OZP35u>pH6^4I~ zN7IW+S&_x@nvH4@M-pvlBFJ+WLDW@Ygn;W;s9`aD+!>%yevN(sAuJO4I>c|byCD+s zg$M(I@UKg;Zz)ps#Kv9zCe<&we6cw=Z5oEvwg?ed6pTv%aLcOoi z$Fh^#i4>3oYG^Dra)ie=Hmg&pPpm6w^npaZjIE?hy1zkGLK+b#M1U@%I^`}0g<7T2 z$7=MawtJWJ_p4u`l4I#s3T-?u=^4>$niOn#?rG-^SHmA z4u+qY3#dXQvz0h^P$A>@8ilg5{i|&OdqAVT3boU}V|hXVm#faUELR2D&{p0YW+>3w z<;vA3EVw6=V~sX#kiqMX5DF!HpAuBD++BU?3Mjx1dw-F9R(w~SWXT-~ z$0J4>`%tQjOmCy1+`m)s6hJIE*4mcuDPyw&b}p3U>RW8FwZZsZZCjR4I28i08~Nu- z(7lRyBBq}eAd0Z0vAH^qF8wAodL=$W`0?PQ8y^)0sbu}Tk5XW>nw+^e;;WC*2fP8i zampziyJ<2m7BU8jV-l&=BEaUsSl#0(S8Z*{d>C$j`8|R)|#UqcTXF8{;1Byy#aKMr$dB|y%B`;A) z31M|uQi)(76&a?NQ%^ZXbP=Hv7k(6-Y*DA+&!=2cqYnp`%jUESlY+KfV z6xP_C?^gr~d|tDWgS&J86^~$0<96>VQuqQ27;fy0ijtiMMtWt3ZP|f{VSWf97<(C7 z52Ah?s{G{%+iJ7_BevK|pHqI*`H4INwQw_DJAln;I?%sbGlPa4uy2kj->{OV!T3Fh8xQU3Aj{-~A_!5H)#qA9Z;A5=m*NB407kE;Y~&{FCjPEn zHMKS?xLg6k;f!O-!l2m(g&HtQS)1t6=nBK^*%_L>k)U1!?mOOoFEIBfll65My_~*J zfyT3K1pZr~`g=?9Q;si=;Ob%@z09JvslZPsn$@(wwU*8$b!@-8K0|K=O)*lzLOpu> z+IpjLfWgN1Uv-d{+Y<&9!^+^oneL6xOioUz2{EV^wK5d%YoIXGzyyOm~5JA%m3-X$gXLthT<@IBM?#0 z=YeLY7}JYflRbrUJ1VdK)7gw=V+k@r17=o*sK@$sb8``H_a~QJwJdoIt*J*d+BmMY z8fB#FGDdkKJeO>9wI2gGcoQY`Sqw^fRqdyh(#ziJKlYMY!>yV=}D8Nt!B z&j>Uwq;1HbA~_rmk|3`BU;;(poF1EqAj_8F-no#Ul)-jH3OY!TMO0j47PO`|&f`Po zwjRB|bp`zI6dX#qGXt$xLLw9Asne}1Vr>|~S-EEZEe3>& z@aJ0h+8mdnsZSq;%A&f3!>lYruSZG_jp3D1T?t?Hg3AX#?L}UkGV-HhOZ0mm;O}Xi zWdP{}cMe!Nca0hngVXr*uc51Axo0BoezY}H&jNke@Era>WzcI2GWPbvUc*xC<>g~3 z=jE71d)D*ec58GTNmxJu1tdU0K^B9!KL5-2aX4QZE`H&OdZ-CNSiw4@pie|WYc}K3 zjB(RXnZQlh)pCXBBX{hWI8!t3zyZ9iqX5kS*=H+ciNINE>|~RZ}%P3 zriHJ&^wJ;_OZgBIYMe3lNThU27B_`aaTUj%#xbd4g(~7j9wjIhn^qYP*WvMOO|qXe zfa6efAiTf|;2kXKo5j=F8qrKUVLC3Q2cPZsa>d(EKADzyr3j7JP>Gr8hDnvGy0x)0 z5jh61_Zq4o@#h(!&syPg^XF%bz~_4(C^KxL%03{`k1lhBvQVV?G^qJ#>RlAk`SC67R zu1gpSXxzX^#-@T@U@m8pcz{oJTZoOjpuGW!AXu#|3`O^t+jl6v6A<_|gy@BnerTqXwh#dQ~pJi-znhbL< zWR{H}+p`c3N65X%LjeWsF-TCjVoyb!PgG?WepGrXmU`yQVyderFfdR@QBmrC-4>+( z^N95oXT3h!9EbH8%WBSg{n6?~+oafcC*kl%s;w=pex~=AdZKMnL1CC545@PAM@Vd0bM&;eS|HM*W8G_SN_UA_{%(xz&`Fl@knBe|O=+ z^6x(WcxBRkMk30v^6A0l>Y%f8qgu4c*~?Emrc-8vB85tQzuoQ{-0o!e_Eg}%kir0s zz&Kzna5?Y-z>+6<+E};3Sa(8kIe}3}viFo}_`mimYEGEWc9T5QF0tBI3LWsU7m81e zl+SwN(>tC14{!ZaFqX%$6(Mkkab;Sd>#DnSu`6hKMm3dKL_+#~in*z11h5H}KKZuy zD~wk~yt?$CJnZ!O5=$lb+2DI|DhHJIaC-eTO8Sd9^tFF-eJ0m2h+r^4ak1UX2Y~nX zrX=0s{Q<2-7S#xBabzR1Qkdvl;Q zoA{j57}@FK;E19z?&VU#Qg>~qdfgjLSpFF0%w{X_Z=$mdrNBi9`+XuJD?P^XoYGg^ z^&l!IE32DbN2hf&avuYTeA5rKqvG?U^~{;Yl$Y1za*aZ%5BZX}1tl{wt^mXhtn9$2WBqTS6MIM{xj#QZWK-~^m&;yhYE)$gCa@EU; zDVM(R!m7k4u0m+-F;WI!RBdgkz50H+hsQI4fX3@B1pEaQkRJB%1|tqx8L8{$<|?#4 z5v95bg;wEqzpLiW%iQA-q9RX|WpcFt;)#C9aOGO+Byo(TJ=KqfX4+8rm&mM?^ z?m5H=|IvXkM|}J|mwenz>lxo?#qUS65hzCS2{0b`0&o~|uWv-L5cp48XRPtOy6@&= zjba0)TFZk&3TGy$7~lYRe@t3td5q85b}HEK(}~P@b*ugXqwu2$5T+bO02d+Sz4qWj z)2ohW$M8P6Pgp2^bths zB2*d-vw;~;@cy%>aw=AW%;Mz*xE9^EvBvQ8vdRlxM3r*eQE{xL+IS8#rcC4Fh{C=0 zeGdA+*Qp8B@j>rHw4E`UD&ysH1Kmct+pmEOfla{i$V)i_xB^&U{QpznX@vQ<&xS>z zb+11A>{9jEW7bY1VDZl~u^s84a+5s@K0>KgF{g3SMdN91-q#4=-MC!Zn0Xi=9BwBP zc`x1BzZfjA4XWlb>I>g~`O_p@qz&EDa*A$l{#3QKtxCOiVklHlqZ7@t=0C{QxVFyV z3q=uLqL@xsM84C~_3-j>Jo$PH4T*@}*--iLCCot6jdc1Y2*KA+v^0AU(s5K19b|Zo z&j)~h!~1R=;6m{sN`=u$)P~7nHkbwE2t8}oG?eO4^XC04ryVW8fBofeTA!f~hh>?a z+w9pc-hKBJJ!{q`HGlrwIi26`4!2tu6l4VykTwb?{qe}?e&}<~sQ^w=4?p~mAv&L| zq1xKEVpLey&CMt2=4P@W$qLU$?yxJ!N{sRO)=OH)j=%I9FC|MYORAzuLkQueBxPnw zr6UQesY1@Z6iq2na!vwtz##a>A&SQUA_g({bKuQx83q4{{7- zJfDx$yf_#Wn?1mX0J^!ki2C}^>npE(MBQ_bnWf_Nj-?_JtB5Bu(<2|1@~H%n7nD-gO80Ho|!gV+NH=n<841LD)c_Huzw!N3R~!4Ag^+TijQ?-NP^_T{o!;8C)hZ0i2mCJf8`;BCmPIl5P)%mDZXMmJraqrC ze%8<7)61y4cQhq0-NgY{eTh#GyTf=ttsd*$`0!Jwm$O+-PME3WPC7B7sX#M|*o;J% zg2oUuttw>`!cwIB&)oU(b0`el& zBZNU0qV_TyA-((`+>JDX3xR`x7ud$x9Lucgo4ACZ7{}PmXyAT?@H&Iobg82e&ntj+ zNae^7^5ULIf=ZdVTwAEDtR>bftiw28>i}XK(f}kcN1Fw7OUrb^;WetQEw`XN&BNtu zM{2=>=X7i9Y5LrAHyN`k@yF6S-n}lt?vj2gjqBiSnL);mBPzeGKuA>6n6i@S>{~I? z@eQu)fp!0Wihsu)=Lw)C@o7{-P*+llq(s{XEOs?rLUoP|Z%6pD}J{9Nmn zmd_H2EH{FQoepaD>5eh|cxe5VY0R^Oof`Tj-nct71 zqLXNAdu#~KC9hCzZU3h)xZo_v$Y(bzMcojh2+f#lH!%i1C~O!GD~w!WjSn56mr#M1 zdffOa!jGm5KVE$Fq6iYAk{~XuW8Db)nk|&HkECqLo7B)nNKLg(=11@_DT5f-3gv9* zZN(+6V>e#9Y2A!jZ!u0p@;HmCgC#UT}K8pFCBQAW`-xgDtu*Z0Y2a6K?>!%xPjb&C5 z&^EhazdFT;H8o9B{zK>Cx3MDOxva#`HavPIl2Kw-^8_xwg|ai&GxCOI2C3#k5kYex z8%;km6x}2c?id+`(Pu->eS>zPHQJ?!FD8*FkSy-3F<5G0%S$lGucvN_QAU{zT^Pwl zP1=!usA=+NnLg%*?Gxuy@opy4L7#6Ue*clg5@asK<7pGXsn4?Zz<1dDom^fjk=b^n zSgQzl8<{!Sgpg|E5u)P)h+%850*(MC10Qh}NAqj`cH^(P9=HsElQ;u71^6t)ksGfV zKOhh8pjjX?dr^ba42;XQl~8CjvBXyga4?nugi+};?+QcR+HDi)8jN={FLD% zh@zJOKEg)hrWs%b+f_^YD$+EOFvU`XA`%%2Q&=yWao28Qq~(6@=n~3V58!okb1ho; z?yTgP6{@Z6W!=(p22dc#62apsD98#ZAOjRU$YPKYA*9bfyA+RSyV_NVMx|Ehi!Rzv z&6$&~H}MW5$PPb`Gs}C4wIG-wzx-opIQc_*I%|!%?mSsu(Mxy0g=flJJoC$SSryzG zDkL-M4+9v)mNno_HSsEAT}{(xJB>iS5|3U%Exi<>DWQr1`lx0VF1?Im6#Y~XBt$8F zc<|D5>2D~%a5Z~>V;Mf&bQ4BnkZ*YD!G$77Ii-Xcpq~hy!F_L_o%=k=GLrJ)104f> z*=0U@dlP0#?Fvx$+!NF-E&Y1t%wofrEM@zl(H>&SopNwUvC9t{5c2Aq2q8Pp`1^l} z613&UI=`}Q`;nG7sT$~KF<(QT)o&9YD|~?Xnwhx9`287#D;QLo`0@I7?* zvE!LLNFJ0SMBd;R-L!!X2d!Y=Bau8u#08SXH(F$;|WYX3geO#Q?%V4EJZ7Oo&0|NSh_=5qXDfl^1Z zV8Jsx`ZO{?zdre7Pa6IednQ7mLS@$i3P>Nj2C*}|NS_e$`3|P9FFg;PodBw>?PJ~A zdK#o%yeo5pO#GAG0LyRKQf9;~CQQYDD)g64r#g|Z*7FvF>p0xPgoEB;f?)-d>iKr^ z+j2VZtj78lBs1yH*+;fNKv*5>oVlP^qSeH>do@TBOqoW{Lt|O<&2cg7*hvIOQG^CX zOCVXyly`y*zrPW$cc_$8==UjB`(@>~mKg$p*Qu&H1X!Nt7L~+4tEq~|WeXQVBy|Ai zBP7^JB%c4SWxa{Uy6@SxH=k!2hxKwI65}U&hn(V+2IF@$&GVv*stJd!*Z*52Wpf#D z3R)}ook^}Ly5F>X!D3)~4M%Y?iY7z=vL$J-ilGI z(?3A-N@jhpItVjWHzjnd^YWf@BLzAGg3PzEG0!h>j+hPGzBh;PqPrN4CPb8>i~#M4 z)N2>Fj@xj_Rm&0*dJ47estvj#Zt>8d1CeQ(=m8!DZbFP8&D6%x#LG;d)|#7vNx*9a z8AFQluMRNR9|6R9WvRBdux@Qlw_~#3?`;S>o?R||3w5!9M(`EH?eCpVkK|;*Fj`=(tckj=7hZM{7 z5sBn8c#o}Osj0wd=gxd(Me+aphr84^$jbyC*L3Q#8lW<0{5me116w>T0Q^HeNwLe! z{sU;emWGB=?7AwlIy63u0(#aO}DltF47c_N}}qmp+r4G za@`611$o|n1biL1o#?$OGJf07sm}P_M+J3sQ;9>7zZ4jWw8hcyIT)ow!KuOs$K z$0O;R?LhTjYh#sP8eKuG8mu^5VT%oy0|z1;KqErDJqLUlBP;Fsr1g9;m+vm4YWTj)ix2ImfYf8Ykhw`((EUjIZor{>aeon4nk zS144zJNb6xA-7^*M9pP=K+P%*R=f+~^>TPH$ZJT)km)Rol_1MEwj;z|b_AKr(g2*1h_&%bd&}`@yC>N*@D68{Rm)-`MT5kUnN-Z5oE!J;$u( z`C)QQ`}Fz=At{EVjdM(C%1?A~(+dPGR<9Q^8%QYlQES-Wt%mF<_BGsu^+wu70k(}x&vJKvk2cUlZVbmV-hS5H zGj*-eKiL$>A;rj-p5T{5ab78qnPO^aYz#2HXodutO(5(#lSex@VijbP8Po}M8XjJ2 zE$iCVTO*J$r8(Z)XkTaGT-HzhEMEu~p}pZ~JgYU{um6hjsng{>3xmgPNz>CVRPg`- z%Q!8a@#0{=ysmkM8|dJg7~7MapwVW~@7#}vLX{~hFlK-3<#-uRPrEd#t6NaT5O`rb zz*KLU6D8IF*jAlbfRdY;b(CE< z$pBx1zsrCQ6d$=^>dkWF09X%|TcG4n!xQZN&(Z&X-zKo`WLBZ*K^WrefmY>PwlItek@{~EC~9s#1W zAtpKjJ+hh+>pFm9*5KzX$f)t^Kpu>|6J!e2qlqb85YXsig&G#pDnHmZ%K>6v;4Wjv*$?=)-w<#QE?0y}Ug5{ySZ;Nn#`LMvxd+La~|nXRs648)@JoNcuv%<+DM=8JgyX#DfT> z+(1|_r<77MnWX~YXX_ccb}ThZRwf{*1{kSVCf@#QzoO=h^^CkB$vO#fOaE{d9>_Vp zVOS9g1t}`ZpTD0IVto|=$CQ&)@K>ElQOo1b6F2&PnodeUApT3wPI&+TAOJ~3K~x;Z zG@Zp*bmqa?wg3L0{LJS@RIwoDT;0ZdTR;H?#6nyC8cdBdkwc1Hspm{;mpsXXiB?Fa zLN*l0V~{alGW25f#|he~GE_!EWo87~uIP7|So!aS+&st{H~Vy=F+>vNGXA*wRYvT8 zG_@158Gm#UQOB_f>qN3nQ0OZ&B=aCkg+C!4%_bsc3n7)up@ zWE(e~y`H^)H<~Ww8v2Z2{7l3!{ct3Hy%zWv65yMC<W+IZfgtoSPsDR=Tq9l!qpLv14@=7n;wk3P6?4NlQ84+rr zwGpKV+(L*$g;UMIDH!;1`#~a;!!1w9nE_#TPZs}qK@x)fS zYHO$YU>z8t$8i5(dL_0GvUm#ey)!v z);5h~fCRC*8FVFkAeFUx!NS`&)H0VwWFPTHvwk@zeFDNCZys0(6;po;DDG@5=1;+GfhI~JnrhyJ0qy|R5XNr69c*=;M@v@U#nIN`f6xrxt1Lq*w zx8gFS;%F)IJaiyr@}PI!zn|d`h=lk|q+-ehnpnxF%sz8Hd*3Gm2~nWQan1p5L<&iO zJY%mS4VPKg{dJ_1@DmLl{(v-ILpcK*n__82U!RN0%7B_oAMvvH)X*?xHJyn97`+lw zq*!+T-exkH_Muyf_sevfJqD$vLBiowL1O^eKqtShD6%X6QoMKZ$Wi(C>I7;~yq4*9 zcQzjw1bXtE9#cR8yDO|ImSt(Y_vxm{jnJ-~#~a~H$Sub61q>ql?{Qyno7a{9(YF#gNQDEM4TX4=*B;xEvYV9*VD+br7FJQdn<9 z2sJCF6Z?)|fV|_CNDO-o@%Z8X3m1MBA*nkM#c2nlM_;j_DY5;LN28M)2CCSX|IF5= zt*C@)bXOQB*NDujfqXf)fgvi4;(w8wcL2Yjl<#l{k8>|7#;pG5NZ@`HvH8y*APO-v z5Izwh-mGSA_X2;v_k$0{B)qodu)b6s#(88?0cJB=k0!S9Y&XtvU*mrd@`62#%uJZq z_&Op}G*x&#oX8}e$6f9-9>7O=f(fiZ?(1i5=T>Pf{|R!hDv$@K0ck`pKxRp*5lLng z=^65;gY6`Kp?6<|!@aoO@v0J~G+Jjns2YIG6;B4vMTo40NC$8#GTZSBgrPTa64DU8 z4D3(01k~5RO!4)jX;(rfHX&-qUjg?3|AnYI>y6`FN0cD@8Ss+vxeLid{~u%7f-J8k z9VDz`NllHLP-xei-3D;EhMEA{brA>zNv*2bbK&<#aPL~8zyb=`Y2gWlvrz!uwU)XU z$56dA*|tekKo{Scg#!668*24Rn%GK@Q4z3!+>u>yX(;&&RiBw6m}yZ2i3IU zaD+{b=pvU48$m7#GHdn1KHwQdrFFIKv%eZY09WC5unszvV~~LT2E=2^#7n?Kz*Nh! zsYozB0~zbaW$!fjd}p_xeRf2(wV7g&+mV>=YlzA%8|2^EKV4Mf8iH!`&WJ=xaJdqZ zV5T4@Q`q0vTHuqowZh?K@AadI&|s5o`KQ3Gh{cnMuOaqMEAX(1_n8db`NBM2P?HAN z`9AO>!ee}uXn_zP@I{1Nwbu@8!0rPlDy~sTjAx1_OmRx;}9b2zb)$>g1n#4+xGZjI4oi*G(~v%79xnUlVc#o4Xnk^Ob+8) z#xb2La*k;9`Ic|=`)?rXk52=`uz~_wh<{@OmmB3vnx@hE!K>t-= zVCh$81N#yJJ`X&GNI4%vUe+;)r15Q{jY$onz}tW{`kRfvHzQ=iP&9tsM2WyX2cb|8 zZuefPSIh{hO!|`{gpj0Pw=DY=LS)~HG^QZA;(tRrlc&&zx>OTnB_1HacNmQ{Sa%`M zr-@Eu`TdqYav-OM|wI7MMNfI1C_ZvoTsZO$OGOT^s$DgMZ z2*d&kNDs*gkdVinr2;5;%%^Nmwrw&M(3EL(+RNOhJY;Lr);#z=Y6?|wt;jsZ(xO5% zRDD@Z9QU5fDW)BU9bf+yHKwnY9es~8c564!pwh0?8HWUF#9WZ8g3L}%rLr*bIBWyU zxfD^9{5rvQ*5YBN`MNpd6gMVpKjoBVC}mCm`~ZoE$EG;HWbm@12(saX)+M-HiN?2; z|*f$N)~Hn&5}F|KCBfXQs0cIHyizTi00y6g~$)56D7zFHhwR&Y`Xzr6;A^0;$FrZ z=ax=`?j~MAuo39~sJC~NKKW#iTD&;x;8vj`8XYqQzt_iXn))iEmL#a0re@EM=+;*I zpu%dBZ*JFvkcfXr2(P~*Wa6!e^6p5$%_hzVuDP;>?O&NaxWCoFF+ejS-yM(KuZw}F ziFQ6~NSCb2Q?)aN(uT2Q%-%IR{}o(zCLDQWFDqAOIy0CGNlp4wKuq*w@jOD9jfcUM zEo&PPRpht{5i&aG1$@p}?!@YYGjng^NF?p~r8LhwTc3~E6iXFVm0ow@{zX7%lC-$N zikHUmx7k;4&19W9K-C)6-%qLAOQ_h(K%xO^AdF|rM)q2>f~_bbNGG3Y=G0@H#{d>- za*RoT0WnaE7l(9n^RRie8A^=qjDt@N3*M(On-rO!gF7^Z>TH5tec4PO!M;(MZdX77 zdnocIqmRR`E95Lx!Hps}4>D)eU=-pqVA^OrfT)->z<(a$0mNJRb4X@Q15^1f&$HyL z^;G_D^k7`!LD7e(qAmp*UlTu{jmQM$ok+}8iewTTg{V8W8^7(ic-&);eG#}DQQ(}5 zC}46yt_rdmWL&9`jF`)jdzC2G^EfKV`Zye^D43}j1jlVgj#T*lRsv>kU|+o6yN&g; zXsb|ePTFsyTN*?ys1N@Z_Xi8F)YZXG0O#mh# z&+&Rh++#jJb%@}l9^pgIH-0_>CR)4`L&*EQfoQCF|G8g&Y^=IAvvkVO|4ommT%MvB zlu|X!ne)13iAj)s2_gI{5nr?`k!(Kmy(>1Z&06JC1GP#S6aQ}w63PF`5aQZVU2cskeiu^Alskp2(pnx2_Um#fR!vUzd(}#)o9!(-o{i> z^$#{c>8K^z5t*SK{;oivkJ{RJX`%%xf~3DWvC0W>;v1}5{w{|kBFK`QC&UtDAn9)p zBmPVak(q+o2$?V)@N+6HJi|X>kcI9>Q(+j<{n_}*3HqXo_CaeWhCbu_lK@>v@bARLy9fr84agoQHs#olkowmlvw%Fmi2p<+MckZrZUb4z~EUYUgoSOY!y z(Vv;dXA-S+_5V=!nQ1c7RMJC5k>wrT5-|$%I3GJiti=eBu#L(z$ShQCj7PrPPK6LY zzd$^NOOOfk`;am7Z!PPdii{@~0@u)sLh#!R+Nyz)fek4%+G z=Jm%DWWBxC0tQ70X}6L)@B9l=Xf9iVEW7IKyB13D`4VytnR;g#!j`m%Pu148QMa`0 zt1r4}A2nxABDGjn&`T+yB%y%d1LMaDuYkpyOP+&zlBZ{vAWE~15f}S7e4e!J8qv54<6UGlbO_LNWH5yk%kKqZG7heetia_9S_3*=wI(*zodiN*QpkX^gmc$ce z;cy?pU@1c@BbM{)Ccp;?iQ%C}P@^-iypqH55NYmjk@s*CqTu{CiNDW~(QrWtA^Ir= zAc8N+Hcr?IEJmK4a)bbWo>+NpBIGgvb>4Phz$}%W49_8+03i43w+L}|xMiIZq~U)M z_u`Eb@LhA=;BE%ZM=Xt-6JU4xEI@fe!{MoSo6VH`aWF9M7D4mL26Na1sU%? zL2O?(1|dDhAi>r{KuL=;kI5KEAK)A+p)&W6|1s^%-ZJTGZCo8H}~-$ORJ7WCssXAKhx?oNh+$ z)6xXncpVjFqO_~e@c4-pWPZQG=QG!tgM3e?an)53WIUctk&GSZK{lL-L`v!E>O-eb zY^6XYv1+BHPzx5kpqrbI(#_2W5{Yc0uI_Dh&pl4*d>KKVkT+YD09Ie~aM(!-U_CDbnZJ`G5M`Yc4h^)l9IWQedj|0-`!n!2`ueU&uzn0dmM@~fB!1=)n-Bhd z3{Nlv=HOyH(19Xocpil?8_b`vo?o*bNgcc+#c|E55r+{itvVj4+8zkJMmU^w*8SLJ zbTn?HX=4V#ze4G&Ln%zx<14FeL@;)N+OX{O9X%xlU$aU{QiqI)Kq+MvgdP z8_r5U@OXN0yGwCam*orcQoHG=hZ1%SL1tF794>+^L~LS53388<$%sQ}W1C3?dBq@Q zy>ue)W4a~2KOmZpIU6xuyp5>W-f+X6qLeep?7G=LeT?{0+=|RPm@`1n5;ci*R(VZf z3XDAq5U{MIoRWek>z8FbNa&lDHE?-Er1G28&o+g{Uhl zQ4CPY@BjD;_y5;^Y(xh9t5GOKefUje<{6~p{ukmYX{~5^p|Q*id^RD zhfo0pq=#$?kZH&}Xr`Wwgu#iDZvwp7Mn9t5z8RTZSwIC<1Izhi*K)qSY9){UauOTR zG@;mv^a&Rs#dF?8CTgxi2=3#N{^TUYhE_d_FNj?6t% zJ7__CW#3G&M&@2lN`*?jUf1?u&U}H1Ts+9EM*Q25G1D=?ZxEw!r-@Jx%0WR^%-i%O zBnFcmADk3v)zxZ4Pmd`IIT|<}84K5t{kVV6AjsVAVzp?|05TrV2dR`1K?b1O+Fk|F z&CLyTbxqOD&CxhsDUDJe6N#)=ZEZW$DoCGqUK1XV-FrQ=eMphUm^j!ILZuXNL?ZU* zz5yY}?Dyn8M9F$6(iSa7-q)`qA`Qh`Tnl)br}Njl<^X@>1Lp7^qVRIcvPpyyB)0I` zMAX{rCE$8sKDXXF4(C{S04O$1`t$YTbs`PM9HgNNApT=NL}o@zb<$f%19lj(K4dkR z^6yf@c(|7kHz6||_E~`v#Cz+{#(qCSg4uJ8i@P0IABLxJyOWmJJ^n@39Q7)PEfnvs z{6VRmE-2BnXS;akopC5N7Ns=dunVobR9o9$6Kz#p+X5RtsgUo&+KSF}v^AOd)9bS}! zf^0l(yv^^CzSb!Y8cBQ+xP%I_whulizUuYYe}srMK1otpg!+2BAUG+PV*Ll5T0SkEsH8y%D5u|05PxYu8pK_}mZFc#sz_UreY*g7F?C1qozEtr79m zc?Ee`yAd_X7mVfRTYn1CLBtmR%>$gkNytpd?a0HbksJC=WCs1uNRWR4(kQMo*4bbz z^Am}rYJ@xX`Go3BFE*l5K74C+YwK7wZ{F%m_nj*=C@#KuG=adrC>4E}SFDKOc7MdY zdC#iMT3h?I_8@uCalRK>q92bZ2*GhR zq87`F$&ljv6g6x%)bzufzR94`4$q;-VMN8JdR@Ox^}L> z42C?MgD6KXCblB%a^uJJqAWrNC-)*sZ4-kjU<$MzdXKgO3fOIs13_kmMgoDGkx3J&$lI@HXFO3~&V!^jpa>kiol|iO`4;ZnKG!4P8iZF^l{VWQ9cR zSPbR;_!TlHD?!E}|AWL(nV{VGomHjGgmAe+(|FTzBA1`ib_xi%|RpDTpu;cmz@I?F(FnjM>e!)&r2ZXK&;GG05caW+bjH zzT~Bs{;ZVRA5m~xy``+Gw@k68_1`|?C-2j_2ljWpPow}||6TWgsJ?aa#9sB6zhtCri#gV;Su=@5UQWJ}_LcuA z_8w}qJvOT+%GKn8EjSlx3n4-#EB=o3hcjqk1Z(+Vk+xz# zL`i+CvEF2)z(^<2tVO$Oumb2N9JaoDGXc$sC$8gx2b`{FFvT+8Xh#@#D{chNK@6(R zS??bpH{lP!pQ+<=WajO302CoK5oGr4+sLf>50IB;Int5bYdOZ-$W5P!JOHaO8_*Q# zB?=Y3I;8Cle?X&)6)IsGo=c}tOwFJFjz0hVb9Hm`+M$qR&RR0MV&1H&BhWg&M5)WA ziA2^@Q?oQ5In)j?{lxM^kokOl1OmgOAltDBlH6c1-*Bp8xdtJouLbTQn$~(M(g`&X zrWRvh@#lZ?7O;Wy=|SGZhY_;+4+!DifDHO)An9Qvkav3_LR8lxgxXl(%nZ&wzXX}f zS>|`xsNxJDG67=u7GVwz~UzQ98X3_Ei0Z1hPW7v ziJCB9Kn7t>GvN?bnM_6c+xw8dZ#*)9$b^V4pnw9R$R`1^zwz7Jr;I}aXRCkg24G`% zk7263kQ0$MBUMowbKGhVyu-lAce}bu$Q^|g%UBHM{rCeyh*l%1veS^bCzCO}Ii71u zx>n{0`#hd}#*B_BmKszVqJ|$6O=Y&?2Z*i3UdTAN66q65fM*OJ-BUMijq`#2G7?vQ z&DaM>ko`|$`|A6V%nK85S+;)=I542~G_-~&@gNn^M~?hEn>JY|v37R2(Cl^BTB-~S zBtO{`nwi41g0UiLyR6Zr#AjwWy{8puJ=wOu5W-z-MrB8+83pD(#Ns*0{Mag%Yp-c8 z=`0H#NGNoGZf#9Ji%F>vT6+wVt%ykE1=ZHJJ;he_lU8D1r-s;K51y

S{|k8goEKi$j9mW- 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

v=zA;J zlsysS@yEla$8GwtclG+ega(g#w?7j=F7nspV-xvCdq4euY4kA)e>_6Y%%jrXHgotE zSx{R~n1HJa6zcGqi5!%A9BY26{kc#4VH^Y=PBgJH=F_g)JlJPvNu< zY6ERCui_@X46~5~6q_D?no&D3n%_`Ucbqt3D#n+pj)FdwqGP%|lV}&Z0dfl;lP8Zl zc%@A6XBexcxVBhPMe1j>DxmY-w|K0~ENd;4(rJ!&_I-u09o$Z9KRTAEcLA66J1K!8 zw7nQr4WhN+dV#1S-G6e^>KiIl6SQ@s;ddjaN9pB3R2qvfrArG^w$Owi@sO?VK@jygJvDWEFY{Z6zCb00B?nQluP1;Dvy#ajxU4OM; z)P(;8ll>p}JX(s>B4CYTJp&4wYBpLyFKd1{a6b<*uk#;wfqgtwIS{)HdEfb%zseaT zUo-Ivc{l1GwYasJ%)U*XlpalDd^Y;@R8#qvfR<>CXlAGKi^e{yJ%Y*xtPUyNPLGXU zBYoSNF-@xH_hf+9uiRS=`FpnW4)g%ORm|7F9AOg89=3&w*Y!Szdp|_qPp*Ge zRA}YdKUeg2>Owxe>jc2~MFE^teR$45Ho?7#L`JQgTDu1wMdfBgY2Essq1r|)bO)6W@=f{>ufU)K)Yb5k)ar|bm8IaayneYW;s z7A%I|x^|oetTIsY{w!{GHLrlw;z4i0htg&~B9wjghp`{C4Cy4x3BX%yCqVa^+*&-L zco1soV7~v5fpuYIf?BHXS_Ym^Pc(DY7G#rOX``Exk&^g4unw~(=#^ua9LROF@ zdj7`ZCA8?6)Tv%^0Z58N!W%dJGDGl0MALyM7;|xnr%NRUA5b-J6^CdF)tm60?mIIt zS9d6Ic1f^OwK@TOc6p(rLkC;sFXIs9Dj3Y6y@jNdG?TZ0AL+p2LDS8UE``VHL8CG6W3G|1sg(b~Pd83Wd!m zq~|RV$8n+?*NF7V^B8Ka_<2I=1w`f3yZB?iZ`X(7!di&Wq3iBH5c2b^qx+iTxqw5g zsIr;5yL!{tXvU%n?i@9(smz9pi&FfaL<=@%4;0Zb=%6SzaJ)M_MDsj7Hu<#lY;r(l z{*fsQrsy4y&zywr$ImaJdO52L!7pG?YLt7$E$gm(a-2xz=vX&X{i;!g=oq-2HgtsM za9U7`v8ZQ)?)^2|uXT0HCh8h&H=pv_E1l+O*QP60e-vqTvtr{h3Vs&l8uu>jrcHDJ z7SEIFA?3u`NjZG#gwbgzs+pc^1ooQiCetBioo;UUUvkU~m4ZhF|C5 z`byTnUG{GE>DC;jr-E=+Lv`}Vpk5KAg&gl~Q+?G~TO~6B-wHCVL5WOBHX|JWHKOPd zpD(Jl0Sn*e!OsYaPE?XzJP8_8)BuVaq$kD(ERl^MqU-Ifi(m?o)z37VY>VBZ_mf}Y zC%l`%MLpayRE-~gI*QNL86%)h;X=RovwEE~qqjrg6i z1Nc&9rfM3?;f;tB3tX-TAXUG@rxKr}z*W|mVVDu);+}mGYk}oREZTI@#XEOKH>K65jnX-Fj8(9FWr-jZusF z^88W9uB&;ll=E)&NB?`NKg5(ZO^B1F#nGlQD!Ojmr-KY`F(QlhJC&!wcX|?G+x;|= z8<0$5f@F zq_0t&rN4#e{tuv@t0^Efl2ytZsc3)42X+V>>)aQ!Q^{4_)Bpp#YaXzPO@zpo%MTan zcv^|j0dEyb1T~dMLtl2f&Si|)P48bx_DYu2w~XvE`4@H(O20u3=5JGPbX;aqZM`L{6-j&U#>^oEd%?mbyeviqLt{5?-8Cu24cJNk#= zH7TvJU;ab)m`E#&gvksx)$+DV3FFqHx%x)4&-{Y(j}pE8!5n>#ybWD77QNv`q7d7yAxa7-Pt22eQyEc8{rjSF4uCkC9? zx{!6^bw>90h9y`FhFWkm;BZYEt9nElvi59Ab!{Qqh6qI<;Zj+l16-`noXwk_{PG4q z&XuFCW(83Y!;_9?rNZZXRKZiAaEXH|CzdR^~2E29~d_$M{tO!!&-xt3txi= z!)Bn+)%+GMAZ@oi*OWx?2p;5b3i*rBG+>Ug3d(`&%R;g$7|yEHBq2$F8j3np)`@hI zzm?u`(I^YA9}opieS#y$&LJ~+L*v9=fC0dPg~KfvB8Ln<;gr6YX9XjB2+7Ch&5kEp z`{(>emNn|_$^7kp6_544w#eqk1_fP{i21asNDIZ93^kpLoS1nNo zWvWVqamXYu>71?(t~`ggYvcQEFj_|Dk6-F~T9wX-iXXaPO-@gIU$lZ;Gt0zUUy z8DFXa#u{C}C~%p!PMLZfD(R3gB5pqJCEs}&WNbtcms<`S%!5s8M|#>oduY7H#A}<4 z!<%HqYrh7*6;Qh^pDVeq`Z{iT@#GWHEzz(^g`P5(MNS8}`GZtN+)3G_6hWI^bBc0} z6Kfm{UG}aA zgxONzSL$m)Yh%$WwsfsrgQC9zCOo4#Zv1tO&2KyH1U#Xjqnq3u&u+dWO(j` zMnBOnL-&FkCBA_j`~FK9J$h57#Hqd?gB=$TPbTOLmVT|Vqyn?cDOFz9(mT1ITzxOn zl@tZnv37~T=|?^xD*fO3Nt)(jG46iHeJeBx=+UhUi1+i`_S`F_sjzm^W9H9gLAn!w z+Y*#zD-oN;KSY?&ao)vkdo79EX=}Md3wnppBJ<8s1_cJZsiTx8_(Xr+RgPh-Cm&|s z&8iv5!`02lq>Jqwy9J zQ<!y^$j`}WHfPiLk@qk~K>pw~O}d*L&l{=C7MM&afZ%F6xVakJl z^=+;;CTv61$h4GntOcf)#QZ#dU5PH4a0hU(h#v8r7-so8-(C8x;5`a->{<n^!n zE&WqH`zNakxnLhOP9e9*0;;>XQP?fzA}>bq-B9MjA+6H}#n7XRv_^m@XA@Rl2KOKt z5P-QDXRTp~ZiD3tI*81GpTLOMh)6gJJ$>inCr<;}Bw?^(Xht&Prvzp7FD5@;>s1M{ z0I$lX2#)2;U19o~7F7FQ#3!%(n!&c0J_U9-Dd_Zlz-xvJp+eV{CS@J{`^Q+k*=|%; z_rE>`%)d{OBOQC1=5>DgCAkHd5GwPxBZsr5C$T(dmr*O6uA7tCYPUxH2x9*dGy&=- z>n8`?Ld)B55X)DojKN5Zc=K)}U&Q{ZN!DZw=`u>*8D_Dw!{(TkKk9o+)`E`lntBCL=?E~8@_1{R; z-JNwXIvYU^bE!nz&xp>xnIeB&FRfV{dU_LD`j6}ZLYAcI(u!UqX)_;U@Zmq9Jl&?W zXz0o=w;`!uUbtW|U+u`V@~hP%OP*zwQ1*+?=47;EvVA-$$pTi)>rgulO^cQhN3c)T zg#GSjc3r8d5?c0|jJ)ZBC*G@*0Bz6?$?nFp`b^1vn860a@%M4)FuJ4cqHQ#5(XzRl zaU^II@}pF)f?bbx`e%iFP$&di8wY@utW)KG0udYVL=2$$34X2gXFQK-@hwu*ZLm7> zq_uea4w(h$u2^6=~38k72EU?WsTQ{E+w=^%~}y z^qTfspns-cYM0#=Ua}^{E{`vIr>bhtqn}5+k-{D0T5)W>`*2;RhF(>Q4v3%3f-!P{ zR=#BA9c(*fXb=zPQ#2y1_KNeK+8>(nxMbyJ}P)) z?F*A^|K$Hm`n!M(+hI|4pNx~xz^~jg5l5KIi+g~Fqj&f+<;4+K@Q|wIxi=n8hZj5w z^QnQ1l_d1Rg2#;aKBA0DFDZ+Urs6Negdaxmb+zOMTF?7wQHdI)d3*V^t zejj~|0qbY!39A9tP<0O5rDJZfZs($EPUzyj=9=W)3T{q2j1agJ$G zqr4t2a_YKLYr)r$#mc z!O_-5=`&t-;%*{xEK)9kW9Dd$C=qTRPXCjmZazb>9o$F2*Fz7+vV(a_t5@SmonWIf zJPg@$E4SaGVFSvWXm9>~B@b{TWz>I>T+z4(QzYPkiFrvnAGd}$Yi;3{gM3rG0UAtc zkknv8A{7r(*q9^OW zt-#ej^!#~m=+1p+?0@3GF{~2+gZe*tQ(<*y5F)cJh>*`#IGZt(8N%29`pv$OzaZa$ zr;QP>l5Pak7MDkdmh?g3ZX!z<2*ujqe)1uxoYvn4y#eQsxAot0eN?s1zmo5hEzsl@ z(S@|n5m$Zt2^H5)ki)6QwuD)2YWHiR|g+1p83{*YHqY_rwm777kkJdQH& zG8T0rR7^`jOI&l0@WsP^|C)ZZdas#U}lH1?B|pN5DPa40F~GkNH$`)_lEYNb9a==B+%~j zy}xEO|5TJB(7EbC&H&z(lWXbX{^%Cxe^QYixAY8lxktNd)PUcVAKH8KjO=ye-(-v=55OnnrLv5Q@p2O?^fH}ehZGoEiHP_Pd^*O7kY3}7u$)mFvih+9mhxF>nzmp@(c`( z2yX4`_ePwx=IVq09Zx=R^qZxkGhCo3%?5( zzwQhnTSb8CNFFUt6Fx5iFWKeDuc7TD3^suxjl3pmZ((f|>|nzQV;QT)iGpWOW<%l; z)c)HG5NN2DTj07}?XJ(_L9VBj#4c0q9ZWHWH({<=STcI3nd3Vv_CuVa*vq8qM2YYAj?s+^u3A`?N#bGi#x42wlLD1@InvnZc++q2k<&ApYTa@M39z-oT~2 zwN2MeY>7ILqb(QFQ$<0sDfW_+8gJH)FX)(FYk;H^@YC4SGpjFUpz0CMn|wbD%4E=< z9h984a&#|C-65s(Y>az-d2hI|ZYqI*r!IM1?IRbpiNn%-Vh4{@33N5rA{4$Ssxr4gP5Q5{;_Af*>+8=_y#Oj zVe^5mrk*ALOKLaWldc(Q9aJ`}gPMR{nWq}}r>si(-AU>}Qx^x# zpX|K7NFF@cGIVs`mTQ;ch7}Li#JH#o?9lAJ4VX^5kOrP&Cov=tp8Y{v6!dACnL!Ux zq=lA9pLwpicA)A3$$_QW8hksQQ5h3r*_ORUaS7M#wl z7)UneM*6Q0s$sD$;BxhFRmCa&b|tHeRoB#@YZp6Du9VLfD;hBMcTKe&`C0thq~f+M zxwH*u6PKgLS0WU!TNx6JP*72M#4aqdvL3I;Tq=hvY{Wi;Y7^aoj~Cwhlv>9uQdB0Y zRC)4UhTamCbQ7e#KVyHw7jAXve0VIV<@5|xG(OWe+ep^D6!fnjf#dc`5>spV(0Y)3 zb1*q6pXOZ<9*>u!19dED1nefzF#EJb37kWiw}15H=<=f+LGuv{!3=XjSPeZ3KY++LN{ahCLp z5zYRLf|MlH7yIz}n2GIb5ARh+K8N}h$na<0aAi9^AZZm&IzLo4uJqBedQKn(Y+|7$ zvgJU=!vYTmlLoVUkbosEhyEE{t|te}hZWUy)69bUbonN{oZR8ph9sY4uaWIHX`^Yk z%xBU!vTLl7^AYrZy->$$(Hu;yPIxo9KQjFs8`NYPM-J1z#Cat(=l)&Jw$;+F=BFY{ zhrcX;e3chL1Fg?gi8AxjU-6#&$7r+GMe_=*92riyvICQ(8eO+G=`j(k8-L_jJWi@z zZkPp3+`bG^a-uzB?hX!5JA_HL*4K%_J%%9KIlZ6|n6}T7qBH^*s+KsMd)IUleL(?>h7uB2W%S zo8B&(x_>US>&6Yu(#(6v&{2tL`~p7_&Tj!*xM%2dYg7U^Kx0Mb-y)$*wY2H^14Ek00fzd7Q)hZzwW~!8E zj<$64{rI*I*VCi7ci>Hrtker9FhD?=O{BNXJ~E+6Zp;AavGtwgH-}g0HCgp%$rn`* zqt;kYSXdA%gi9OiOAZnSgdy|+C(pH~p96c6Q38gJu5bg{=H$KSE%_IK)*^Y$H(8u( zIpNhI7ul*MeTd*;)0%ok*Cx#%lg#XSDD1x>JL>_;@?hR?2jHxD4?90I7v^CGy&kJo zgca6^lrF>UK#3#Kx|~DYdjL=jA@#pX2rfPnb0t@NjL<4kp4=p7v$^F-=Mag7Th^0p z&b9)hN@8+qG3b}=A~^D_DDHI#qQSdKl_)Tr^bth{quTwvtiJW zf$p{4!;xk*%AN{6oU0DJI4u~is*PC|RRkfU7h-8B4KBO_{V``UOw__7NvZ@*6DWnH z*Fw4BUI9x?k-zQPHIeRJ8s`p&I|meNk}I<9w10>;U8Tq0-|GMLFF%?>ZDuaC1sJO^ za&d6nY$6As3#xF9_o26kI0SQ!2iGgkj6^cmSDm$JxNbSOjA`7xVSCTw+NA&ZuXF9^ zU1c5XcrfJ&!Rcn_QZ`LjoR_hG7elp=@0dh5r}uV7x8z7th(HQGdfE*y9J7NQ1| z2z_>Y5Jqjn&p3t8BSopJichLBprd1k^!Wtj*XZgNoj2Pc$-qj(C^#dW*#CY}oNZjbLWpgsh!~^6|7_s~LVBd$U@ybBDpc z?Tc>}G|oT_`>Ow1;oD#OEDs)5dh3`2+8oa?m1xxl(A>U(25U>)0kL!AgMSk>-8qVZ z^~6=#NrZFHRSdY9upRZYW8jnjh2QV}d|l#gOVqg%MHyI-=1Kg$Sw@q9_jX={lJBpr zy8lGlzF;b73)cnm=76EBdyLjGGCMVU%j2Pf79y%Zp`glO#imj1=u2ZjQ+ z7a1t$Ahm8T0Hjk*wnk1$|CnwIKZ8f?kVR85-B{9fvaBHInRd8QeBs9^`0FtAk)gWAgJi5sGSWZqb{ZVrLM4K~h!PB$C$g`%*`- zbNWshyPO~S&p9|4X?B48Ep3kI8KL+g(^#Am)h?krBt zVAvBh|DP6gaBxgBnVZa)h9f zVNZZdvS@>hi&LGl7&2GKc+Ty>goynU`W5MAbuAz%^!roK-X-|C zpZGlTz)KluGWEG%?X!E))8f}zmRaYfRaAJL4}#n`qO)>+cS=s#sj5rX0|-TDb*=Mv zMg?PIFANtXB~ste06$7BV~T(+`Ja5@lP}&yNe*l-?ECs9q8J^U^?}?<6LwnW5azV_ z4gXaHLiD}2BcAIbX0p2M`UdW8Ju8R1(_Y&zyV)Q&L*BhR!cd zJ(-+-EtOnd&`k1&3@4t`N+ZWN((2;ru~g7@eXk|dMZG2xbLCiqj5tKY9CP(QZM+*+ z_GGVVPo$+SK}gMpUjvs%ll;I=#3Z$iD`3{dV_X3&I9&uu;1bGXO13*q4Zq_@aQ!Xg zdZqMZogA0n-rrwooM&OP=DCC2&uXaUd;ItN*INnnO)#}Ttn_|;^I5Faq)YbuY)X!{ z!MX$C!Bhv=)ILo&sh((5SJX-#>YxSxQftl9C^`Hld|j6Lf{fjT)=YU?RgAY5GIc{2 zqwNl}V(r(Oqv^Us@JG-h9#Udua?MRKJ1Zgc>8>T6x1pC?v)X{IqKq-If<{hBSsjg1 zHKuf?9iF?z&n~*!1+6%H8|e&1GsFZ3AkK*2?03#T?{$f3L!PGIhD7r>ac4L1^WqI8 zX+0!EjB)E8@ee~vq!;?@cr&l2iXbem=`s}I06_;J5Mp^b;~+sgr!Ur3@90TI!^z2FH`$XqBwXAVhCUnV%d*W48N zXkgm7h8>78G<@?{X&vkmD6G9Ho|)_%Xxv}ETYvnx+Hi{$SqV@qrvQ2d{2=d3I&O3Q zZ>~c&>@8M+ecvH}00-9RCEKtVJ}=q5-;O-0CmpIii1l=eKV>2`!)vpjtj{y&ugmhk z!^q5_CF6;51__~ulA7g!73ni_(l^{Tkwu^KEYzU!lz9V<%U*ivvv*lY171p$I)1jP ztrC%qu83U+5Ts}ko6T#i7tRA3ZbBs=Wm?c+7$(a+=>JGnpvFh+7myy&*(C5KjRqLz zW;68D$J~KN-^Mwu3aANjpLxXC%B zzkP6?e2r^}IY5R>Jj~7qwo^ZiE}09dQ@7{~{N8XG;}Hqc9kO`u;a#d(UvpU`Z$;Kb z?>O)Nb#cyx%xVp0tfHarmBih2`RsUotO`HaZaV|G<;{%KRwmG&x-`|8HXrKlLFJk+ zH>R$B&(*A_S-(Z@63)wHvB>BgqDz5R>)(83#brE!H2XLLfDOC8eH>END-)`9#Dj)JwfK!jnZRp;Up+V?l&p zKgC7%UVb<|GOd)<18iUGT|qb-9tT2_Vq_DN`3d` zjw2>ks&aRgA7%r_pS%Ur3;kZs{z-eR;oR16XrD1}YXSF3s)yBamYuq?!a4rIwyA_D z-=xvJq;-rhTK-$;zvsmHLq9?yxi`3Mw03RJsboz4dh^4Cx{mee#W^C_#?tk4BfV02 zx2jC2mHb}JDO~}0CCzQ-)e+sbkv-NG?r7ofe?+I}$E?IG+%-$aRSDCU~`UFwHj`($vd1V^3n=17Ge$oJHv5_&m!2`|3 zhY=cN$~Zr%g2&xIeZX2bvD+xl{ki}DGut@Vt}hTqM=dRs6|7;8-RAglQNWZN36j0cP=Y=9)g$Ri$JXm#D-aX`k;BC& zc$FX5*v~?iK#5OTEVKlL)!?skHc*3DKjrXMIOHS#VMGZ8gJ+GAGx-2x}u!$VTw$u6qMpPiyaa_-+$tU>Z-^s)j4)sMI++{FMpJ#H0eqKCFzprMZJ*117`<^%x2egjkJjXu%vpHtlW0>u* z)eI^bYE7jxwR9xtGDE{B81Ikp>{ZL5&Q}3r-IFC@qbi8prt~G z8uQ%}R&`0{ke|BlNXxaIB@7=kcWg{fzHWp}Kq0g9&R}*Cg`hJA~35ct8iLVC!d$sou$Q#>b|1f8tsmyHm3!o zE$y@2iqH*KedyCm^IJHr7zFP9Z<}_q>C*-3<_GGc*a(F^>H)Xf4-=N-qD_+njf{YT z-7E3TvYe78SvcZVIffAhAxndxcPN%=53xT`F>AORj=&e(W&}*k9zLn@vv&y=A^d?#5=fhY77F8_6C*o1&-X@5c zs3Wh&^VM;f)*mQ*-lGKS{-*xO%7kyDgr^+Yf@=Em0C{04)<10dp6F7Rl7e>pmb@)b zGAqkrH}Qt|D>g86YJ_H7z6Cqh=e-lxcB@k1#}^9 zx`It>Mz0H)JS>hGh3V3q;s+5LTiGAJR57?2RODgwB=vN|$%m_;Nm91c)apq($%Vx5 zQ_;;YsVZ?wf|v9SE5wrnxvN zmw6%c0g`(RD3v(QI2xc7$mMomSb{P4&p|hBZ{v)};!^AfE_HX4uo43ywo2)F5s7ix z!Vq5El>P6llxfE1rd?#3cQuA!?h|7dU!;2&Z2Q-+<1h|I4B5L6mYd-cWj@w1zi(lI zRdRdz;~6#^?z`mdhM{~+7BQ94qIs6XSc?=GN4O>bVzJp*6!`GZJK*iXolJa%Nex;H zx`qaW5p^c^<2dH)Z4@+NNrZMJuk-|A54c5mH~40p(FV50Sfw597#PQu?$Bo;<>FW@ zWv5eWNu!7jqG;m*%9+$cWQGRjorh)fDQg{$ClT_}Z)A3?-tY96d_Nk|V^M`g?nXvt z&|RwV5OR1|1|vUXbq^bF9xLqt_22_hMHG+^RO{j|mQ)10w{2~wr_+us4_WbDaI(xN z=QG*JLuxCdct`()BDp5WtYb`TWiG~BL)<%Iep|Jj26nARjk{JUmwW)?`8R;GMU&SK z*;l{URMx#;E4-;5-)+fLo4Ii$v%t;Izt`pNjhv_O-104@SZm@x@53=*Oh&!tPb?Z< z^(wva4DGqmP^V13C?b==^+Eq2yPP&YTGxpwgM|frNae9Oy&}VvtRr*JQV8L;5uMqM z)o+13)U9qc$Xn*TxA)ZowbhXd;|AGMW zsKUySov`44Gyn9#-E#Gx@vo|@(xHq+o`~(#)n-v%qx`P()UV#%Nx#bZuOYYsNKyHe zT7kzEn6mKNSlQyn31#Zl;+ksX*iy#=&*8h1h-_iIV93Ixi$yra18^ORQu=$yd438& z^n&PH97f5F4ecEw*Yt+r7N3+O#+f?DOGP%6GeaAyYM*o`vn^gNd}czLVaGF=hKOdr zTfFMhC7wVTr^*<=T@G`TH|GcI6qeK2Qj9YctvWs#XKwKre*ExUN@an;QaJZ*pebRP zU(lf>pXm1G5EvPktbaDvV~b*TN8Xba6aX)#c>haRPZ6H(mO#21J<(sX>z4+v+hOB* z-3=pQ@&B;6xU0VYkUH{|5H2t#&OjE_M_K|pi#}xrH#CZ5i+nN+Vh4=Y-lzk-E&aih z9k{ae2h%yJMb|V0uZ>{zOhQ>1s{&Mhx|&*M7II zLfp(T#Uc6Ig#=WmlK8?yyMc=nNAjDg0|2x>TALZ`%Q#{oWup7Mo}Z|;+2kKL0M}21 zG+(LrkWb^^SnZ$!r8W5vP`AzpKP%aMsJr@6NEHh<(+8*Q7a?Q}tcJK`Prg%vX_qL> zddJ}AyjE#JsD5ac?D4|up_v)$X1Qei$R(Y(1h75Xuee*o#2rM0OjS!`oOZNe-M`z+ z>iN_YZ9kpCvbi5}1{StIMOau&RoEcqOiM@UKs()cAJI@^o>Fy+d!QSg$8fAZnf0>wR$F}Em_>F0a`As1m^K;ok?N8p#$|eZe<=T~snjHeR zbbV!yXW(!3{TthNy@Q{KYDmwuGI9ZN>ftDnoC}IJ@>Whu#&yHy!ic@1Edtv2yy}_43I45F6vs7=!(y_Dv?R_j}g(?p?Nu9 z*=`?ovviN__w|zSqUFvk4lrbDvpG;#2dHcS+SZ%v@yE?tuoy4uD*iVoBr7)6aLMiviG0p}m40eeE*ql*l;!jHoL zfCVqE?jCUX?6EHlpZUH)%pEy1gJSA6nqs!WmY{%E(TST2cIUwlhB}8-v)h>|wj9<5 zW~qx0pl|=<0>~ZV?L&6wDaS{2N66FI<bo%j9WWI@y?4%;(qdmb>+7 zI|iLgv21>@c-#tY%31uP={ct*I0c872T?StY@yY+5hJaCb9;%rSb7SLDwjJ=<>hN$ z4pRcHL+8y_wC;bpn*Jl&_}ZBnk)3reTrst zUoE8h7$tc|!Wfbl{X*_}mi`qY&pEI4h30l~N|)($VW2j4k8CX3ycz(0qB4_Ruk=zu z$qS9feX^Tku*uCg!;R>qX01z&30KK3J!vEv!O2eF{Y5%r*Hd!<_Z}B4wcFn##q$&C z7mE*56=h`!@3}G+eXSWcT4+qI0a@973;NhajT{m*JHhR9pZTz$Kx{Ve0+jFYJogu_=kl+3fzPNrR0_wHYsFSkTclP!v= zGI0)LswqcR6ywYL#h$dueNZ24pYRSPG6k%nAn9rW^PGP^a8^wTrab-1+%jA^1hL#i zjr+u^^;&khO^0q#IqvtDjPRgzy{mU2pQ{vhv$|0_*8Ir^ zD&_@<(sdLfNP^eth4Skr1&0mq=$px9R^JtMJQPLQJZ#)SAX4*&x9=PkvU}D z5&n$6g*zTcO#BY8XMRqf%vP-wqi+uLk=3)pm%9i^BlXo}j;%EEJRvGSO;ERa;fIm? zzlSqh*34|cN?lM<3Dnj4`NIgkp>B&afh*1-n{S>4qZ4hY1HBv>*wc;@yjY1xo)(S_x9CpX-k!cWGoI%0f^dQS-pokhJK}V3dN>cc4U)#- zYn`VPJ6r?(-IiaTW37Z-|3<)M^pOCG-*M^vWhX5dw7d2hNM)pc=IkG@qOQqYq4Q8> zDG$xE-nG_M409+P8CbM#az8N>kc9FMvOj^O4C1=D zuo90%1WNG~wai@=aR&X62sh?uq#F3?>~bBc^)a^fYFEHKNQZ58pE3*jRML;*Q5%zF zuzB{Wfk8YWpi|#`*Qz@1x!a{~QgeX1snG{n+BI!!90gi&l;rM!bENgW+W!6!^g6Lk z_8$})rk;ddSqE=ES$Y=fSdk9UL873lIA0o7JNi?jv;F-zFDv9H3fh8_5Pl7$S zIQYjQdnov!IyT6Myu^f=!3@Z3&^lxsfdUc|b`r%ewy!i%09Vi(4y0P;66XHWMK;v) zg^J0vr<0HUCDK}LF_cX7?Mk<}LfyuRwPRSY#evm01C0%1%oZ(;E17VhkZV{VA7JHnckJ^a!6~hI_`@n>ExB9`LTXZL~dwB(NtGm~2 zy~gl`LLfQyducXy+iCE*a`u>oiTuK%dJo{` z6me#;OB38(oh?1!b2z|8PGac-9s%1A=)1ugIWW<~rNlNAOdh8^^!jD>1(BhL=*{x7 zVAq3J#JiPJwCAG#zsPMiWe=wty3iJQQFo;7vBbJYwlk z5mW>rv-Ipj-vJBu4h?9DUl2(WJyBh-0r(eL5q_Q!|Ks%%`!Q=y+Qx?qB(E2#8fY{= z$g6f)%pr99se?OO&Z%%gQ^1V!Kd~Xt>rl-2xzVptMcUwBHKiwkdz&pYc!l=(Z9jLH zFnlu-3au9vOY%HaTLLF4U}09cQ%#McO&VO)!w!%8;?VRMFWoL0*4tG-TMds{c9Pp+}H` zwKKC_7luTTH8ow8K>Jcj^1jHW}DaJ z;2vMo+e^x*kCTbl&deT0Sy=Fr;108W!;aWv%21^}efRU?g@oW}vKz}iStrM0e8@FI z$=V{vc3jdeE!Le<1Fk}_y9zU$A&qKg?~=L_@aBERl_im`mpG~5=6O&x45KFrSjuh} zv!a(%F!j-BPrO^w&FDIGi=Bm6vSY@xmrH#{t>@nm$~l)pZ^@E(L9QKg8-MN;?>mCaN>jtinLsgi?utDd0}ynm9=DUfAqS z;F(pNN@f8wT{83r!x+$vdgjf0hT4Xo`Vm?-7Jdu!L`-656?Fox=wAnO5Y6B$?M|V2 zO*DL4ixNWSH#2T*ZdkV%;!u|{%Fj7D^^6_e?J#cqw(i-bAqg*brgE8~*N;wZUsFWZ z`z)o>yCW@2hfRpmgw#eJ&;lLd19Uca)D&f`tr_&my$3hC%yLo8GXPm?d61w*>pyvb zbFQx586=dGP-8n?1|VGQ7hqszVZN0<_L*U40x?<=|J0 z2iz{oS%@JNhljzU6L-_}b$=>G$Fe{91&0IZv`R&%@Hxe|ekL;t+5p`j(X|u^!WB1nP82Hqv zmKX-dD41{3dV2{G*FY6|TKUO`3d;P@pBn1TDEG{i%fvjj{=zeKg>F^Gha{SK znZg!ttj|+&YF*U+I9zYZ_pRE(c!#5D0#>Eet?v)v=fd5PErn-eq#wYK1fuzk)H%df zySWb`LFizYc(rHSV2IqK(5@@P)|7I*1Do~<7JK9wK=_J zA*?}o1Ly?!F-D`xDRl>x58O64#qmwemQMP+gU5_no4rFKRu2cC{v7jCQCkEXc|Da0 zeYmfX2*|)FcJzW?l^nfPs6*^v2lrtL=(F$}x>qCIED**pZC$-yWcv$ zj?vUVrX<@{c4yi3KMvG&9$A^nBG`}h-C1pnc`E#xpv#?BSGv_=;~VO$y0ZzthJMV zDM0?4_r0f3wD=7dQu+ahBw`><&1EWO1N+CKj67eljTkOyZPH-tF zVbX*>c1q5>MAyA62_3QZw{B{B939t9LYX`~VVl2>B(Gm~@H;MpJk`ANR#C4Uf*U=I zxTytB<7Ucyyb@#CCDC~u#M>Yw%IIjUN{+f$C!%Z2GiM6m^?2hiIdY0)Rl@y%duIRn z3UqHlY>Axm-JhdcS+m zXhxNJisX@asQZx8ghg`LO+mV2GLaL0Ac-$dQFWEmuq+B--;?qWtX5>|mlT??~T$=&fZ% zGocNy0@4tF3^w9MC3nNiffxaG>IO2J;}Bqr%B`z|+f5sx1?3T~s>n68foERuyOBaP z^$vV3OYK3?CpluY925HQ1WRLca(=vL9aO(a$cVy&847VLW;u^#QCHEU9mBT9x_S?i z@~9*H%rNp@bm!|O+t6(?0H6RC#}l}*m=#7IUaoG}-he|5++@wG#GP>MR@~Dsko8Ql zynln~JuV?d_v$v3!IO{nhDdkdBRYFQ9Lr@n}# z2;%x&t2xo|C09{AX~5b$$C*k5jyKs#r%7GaeRMn_GrPs1Hq@4t_(L?qGVrU+i0z6C z;0D(ZbwuIw&Wpx%p|deZ=%IBhSSFK;@Xby*X2`XeoDbBwZi6#ZHUc_lnE?SSQ`38R z;ttb6Wr`tFt9s*+sp%U`GjL^p0#yO)pvd>7b>9YjW%#4X>$&I(^;@mtA+N!`i;V$W zcMbe|>6ttOC$Bi-vnT}eJckIPLO`ZEvapF}4Ywramo6ScZ8r>i>_a;~Fco;I z)|Gm=YSc;KhLJ}u;C@JQUq4E*oxh;AQ$^-q0i3kz&i#7J^ z$1q4twfT#$>MM)%lybpb}f{yFafz|X<#XQ zQ#h`nGS(fHioG|cYimH4+-~*i<<1(lNCRy~xUzm%aEl;a3^Pli$@#PHp(H9`{ibFQ zS;<)60sXKo{(L@+rB@dO7EP;lS*-Y(qOFj-5Lx#n;E%I)rbEIt)8M~|e9)FRl_*jE z33>KF!**1ED-E68_)j6rw|K~P(94MqA8_RU8FQ`QNc5X;4oa&ofA3?KKzQ%38MkEM zHba99=;P38Q$;K4!g0A8l=Y@4A$272QA*S{hxOf;eW)S-qRLf)%QDBP;Bq!(>K1Ia zHwNuVc)`CP$(-VPx3<%{oTARvF@mtm8|6mS_|y2Qbi5T86pJ^~;$@0%rC6o-mZ`!` z83LbQ6HaJ12s4+L?d_IV*D|+-@dRE+)$6y1O-w*@%-vIy?au+eqK0u2U_4#=Lx{6N zcJxlo?`O3!*Gujm^PZaLT$+||4%LqFN9ixXX9cCV1es=ep8!Y;ZEWOq;~JJ@|7vsG zjtE-1rd`WpV(3nIC;{>Wu7R4^Z+4`H>*C)AX}s@k#nD7w`6Ax4Q*!?zdr#Je+0O<; zUZjtuF~fN!tLMedB8wid^Y$6aFY%G^ix~2BO3qBYl`d9G;}W9Mar0ERAnh&k2vRH4 zw3bQBgkFMmDSJXyS1S0hZ$z(G9DXQ;zGSQA#eQ_mRyFJ;uVRa;{xJpEr|b{_q|Z{8(OT$6JpgyClep3S{amocW_ilk`d#%fNo;2R8p% zv!ERSPTqy0{4{0xB1wNtT>1!$a28 z8bQanfaTDcqG$j-;CLHL@)>{+bg}NNgnTh|7+MvQY2%}|2ej2lk`jH}?>aPYIzk81 z#igY6u}$%-3&3>-xCegn6dCvMiFILEehw_xC znVbtMe@VJ4c5jU=cIon}6FdJbH6G=u&Ri#rrEi z2*snCj24+x)iehK_m{{8dUB+mnW?0kU~m3Xex4(@AKC3Xf-9y}hmVC5SK|R5w;M$# zA0Ii+DW4wqj94;(e28ovS212Doz{fDEdnYz!M^o4YkcYoVsCX>f6Zv$l^V8)d(@4P ztZ+WJ)XAtP2{1s^PU6~clN-wGb;XXd(qaIgBCfyl+Q_ciplX3s!L7rIDA{-{;cYr^ zK92h6FwZoWERJX_#bVtqcdvY=E^K8zK9fHB%LdfPv}RlaS>A>6We7Bh=tR*sXq0H_ zeSS=k9gDB*;R4JrG6MX+7vK$6mLl9OE(Dq_<)_CVAV8q;zn)WU2GQ(CQRy{<$SXoh z19$paH-1+;I}+-ny0WMSavRwX0&YApsfehoI0jtc8@dR{HVePzS3P=Q=A6@)uvdhX zU*&iX-*_nU%w3Aa_ZtaUVM$o)ebGc;;w`?=@xWGK6h}Rwd{}32VRf=z(j%2r8*`AR zbf*G-`mXV)_8rIdap_*@$-B$Xfe*Q|;+p7Bhy`HL zGE|Pi1|W;T`le%l|IOnhV>S)jMWk?a%^2n;(((;kb5!w`i5d|{6Y5|@Ega~kgNRBV zND|m(PLxfINkj747+qZ_%58HHObk&XQX0% zFw<$*_){Nu^ds7XWhIQzL|y2oj#u|23)8xTk@IlBM7KKK=r52jV2aKg2ZRg)uQNvt zM|>ygc%>%)n6K=sKo+WT1&(^|)Iz?(PKJ7)4OBqQ$IooRSNjr6X56)LNs5F&M~&j% z1**@tmVnaEa<&%rCfyu<4S!8hT6+4h8tnJ z<(%R=amMY_+qzPzI_oY88kojz_A&nkm0{oS2A8t=N4DDCrG7Vqy=Bc9PIgJa9yM{Z ziahIhg0?11%YVfMJe_}yHs>|wC!LN?2Xpt9T9{8T%-T0#r&vX!G$Nl)f-E3*!J1F{ z=Z!(gjrvHlT48CY-nvIW<#Y!x=aJW>(azyTdz8ovXxSzB-q%NCEBBCha<{4$D-)re z$7+ea*@d&+b8mceSd@}BpNhI$N2Blhw}+d;US^B}K9BCDB3FJB(-(C8EF;szwXTf( ze#)eSInS_2a~uNSD}&fm?u{d<6m1Qjld3@ANJhiV;4n8QkuKVL1mvg>iCHUn&aN%> z=D}4rw|ZaKLAx7)I#WB})=gw1d=D}OU)f+XovNf~EaC52Ap^fBbSiVrce?2et?J1W zYL=oL9&KV4!YBHxhMd%R$(x^E!w|wnpJWQIPcdAuZVu?a1i@>7KOM42cdg!;3DZ4w z(w)8&N*9d%n&Cu*&&TXX@Gq(gEgt03G$?_*hm6u7GWh_(BAzg zVco*mm`mFcyn=~+6An8N1z>&2j}Bt=FgRIBUaI&jWa1szM0pC1&C`!3P~F8%Y7yb4 zH+{g3w8Tal%#Tye)H4`J04qIKhh7$!9>XAt*9Z{$ApXV1EWv>}zLzPACm@@Ag>V+R z-K!V07N)DC85y~DuHtEl(8)?~U1(<-?Y|V!9f8UE5ENv6@@JPlfik>x@u+0{s`Vk# z!)>M}*o8v@O?Op54awfZ$WQ!D$DnTbe87-Cm5`#5x`wAyH$G4ufEF@JioSSAf^D#H z;gtM*d z7K>!kJT->2id|F9-B{51^>vL1=fYUDp6r2(ey;bNEW_~AtKeCdOj2!bGbS@^8>YIM z>6&JoF(bp*;>t7t#i0*z(gSn447Zk*CdxHGjvd8K<34KfK;lC;g2H<~bJ^T(RQ< zE=0ckbXhTEHv1OR?LFN;9mR4t=Zb*~bp!&g-|Xu(Mlr8{_+IxmQ@UX2eI)ZTTw2@> zS-8UOdG2YHn3Ns|$(QizGFW|)ua=GSpl!VS2?e9&aYYFS_x@U%GYs}JWdo&ol}js_ zC%9n|lZ}w-D;&k!VgAGIyTA>q2onkgGFSXwb&t=RLZh%b2spb>2$Gfl0PN>b&<>uf z>_mM`mD?TxCC{TTntgS0fz<>Grry#a_KaEK7-@|ird-?W;Xp^2-_lMx%!r?AN_7jAto7<6&8O?suy#EEtg6_m;+n0TrCJxHcspVc;eSjmEwpmDqGbI> z7ydV*2zp02WgsjWW%Bwn#Wpz_J5}k-P>-))(+KULA zFx7lc5WMBqZgL}b>U=f=ULeD%7N0g}_A}J;oIl6{(6ci+yGu7~lGvo3e=_#+1baR3 z^zPoFgF~7~?0Y(Ud}y-L@!M?6Rt9Q+JlQeSE_5*!6|C4UhW`aRsPLgsvCzIrL1vXC zV|KTa=bqjX#+h@;!+b5B;zmENA;f@c4y`Qbb~@WjWSTymlx=bx;R#&>+=%o`4=Z9? zl|y6r4hQ8{xY%al$&gfFXe79uNVje}O8PEm1G{0x%oif;w!RxnjXTf}gP9ar=#iOhj~3@80cm4~ zjGjsI<%u8d9q0NE>qGJg5#|#pkIrxn3=b|DpYdku>ZA|@XG4@)ExsCZgY7OW6UX>) zGC6%y)pUekZ=@4Yb`ng7qYAn|#7_KP{XA7!l91G_2GYL%TPXyrKSAazV0^%_6d#wu zWl@Wgdw03Te^o#uk&=AHV+Vk4|Hnl{5m~1s-W7wfDjf=C?*JsLylZQhn?e%u$B!89CoCD2HMt2WYqKn-NIhBk(W$B3qWSK?THN?l94P_Im+`xtZmZkFk*w3JQK^vP|AY7FJ??Fq4^w zi--H2H09^;YQ}eEEJ98&_wot4B4X{_>Q|xriXZXoX2yCrz-YU~U*aJt*9ASEDEa%% zC}%yYFx3SvxQGe!G{84Y1C(a>8H`hQRTnSJLhFCd?XWXl5>s43BRzkvk@30>hZ2*u zN}U#=yt(j&H^Av>CD4G(xIRc6HWysH@A&$ObaXLKIEJfayX6>n8P9)u?!lMeocF?g z^UY>bPcdWL&~jiJ3D{u@jPQIw}z zMIYHF9ROvcIYaR3?x6<>b2&4GYlhFVH9lLT;&^{Orj-v2+}Zgc+4i-1HLPM9 zcbZe|4>-%LJhXKl^^qd_8P+PVl)P4{@Sy6|u-m*|>R+gvrrb&5MRGqeigvKe(5@dG zXZE03*N15bqY)^7$2`AyCCf`3}h4bFN-wKp-V0#f%~Bd z8=86K$D+arFy|ypo3I!0g--G81lt{9^faABA1NfSvGk5wYF3Hk4tqQu|D8*EM?&1d zwK1&^0OmT?dE_#+IDL^SVw-q~68IGVwzhiSPk63$=GXg)#`Af$LT20cbmQ3Vg}UQY z?4zg{RnB)`qW^8Mg$A10-RT02{N@g7ApL)w5K|OLu&`771QG}di{X6?;ah06FGj5R z*_R*FI=Ha*RWYIJTUTIaLY3_3iIt6IN-0aLG@ZdH>%pIxHO_V2v?yMfYmY#iv6)Q5 zAd9p4X$*~rWxG|Iu1BW*gHWs_=&j-pJOiiGcK25^szvm3QEsfGlb^WL3|L$%v@JYa z|3Csz(XrzkVGAX2^1rRSDo%J*(?95LIKPT+q*65E-m*GeI$0{k0KFi?OW!&mvl192_|;ia+c)O%2Ye_W3fZ$X zvJHi(!8e_JkAR$@Did4%I>Klpuo)kiY}RU>f7I*Bh^#mx`%BjQt+A07?c94hx;P_k ziEO{p;Fsxn=yym80IsABz+%jhwvby3cO1Xx^Mg~(+-ci#BXjRCf%(jvu0N?AG=iR_ z;?V{f4y{I2oJH_;%ajP4J1Bv43T_X-t5S;uC|FeKLz^N?iTBwEGV`2s|Bv)Uy0MR{ z)Eru6ORDWEmO|3BO4`*_K*egq7N-lPq0}ZyPI3F@Ap8r&) zpctPm^kl?Zj>n=-H07;?-VRB>c4Z-t5=_muCdBRg$hF6}n-dJ^2PksIt|N7e; zVj9A7~z`=$=rKXXbG>cVq_cWp5xu$-AkX z&0Ng!f6)lY_FsiUxWM?48(9@J+dcKI?8ThOP*yW`rfoMgQ_RKR`!BHT%J%b2^*?qj zn_mxc&S^{6i{std@YHr{HX;oV)&YE18qHm(wU79JZQUkZ2Gr(Vu~2_U9EbhL_#!TU z>v(xL960RyBUi9l_#bV5`F(pPG8%W)asI2hZJLy1?EsNPf_<^A_MEi#^(y~Js)cZ5 z#p39_Ky7%_=N;nVEIMZbJ!31gJeH;c2Iu6#kr4}7YieedxZQ!_`C1yzLS%IWR<-1k z*al_j42`IKxkS9djbG}Ho*RZY^PTRF3!Q5izr^p?z1K1`BZJi`aD05cjoJe7w2U-ZH^}<+XX~u&_E4T3i!WC9 zD?P>8KntrTt`KsYh5GxamqiW#f>1t~dX}zwk@E^EZti0|q;KQn6*M8QH(_d0uf4B~ zQrP(bwt+N-ODK*BsoR|fb2k&?6|E3W2Vonvlb<0!Y{@$oh@xTZtKYs=^*A!NvhsL# z{$~wLv<;CB;oqABRq5Yuob-wM$bGVu>PbQw(ah;8&RDvs_?os_mn<2UquLB#4U0wp zw)V9$H+TIE871_u0`f#+7mH|8g0D02LM?ncV%Nz!ua(stDzSNc;1vB^)n>0VWSfmz z42knT4qptfS6)I?-UWlUm@vbE3qi~%Bh7|_8{^}4x$qWNR!wiIIQU?F8L1ww2qsBs zSyS|-9)o#)D@F0z5*&_AS>t}zRWJ@ftKrSQGFx)b$j~=tuoYJ{SiaAAedU>SOQZNZ z{bOPS<8Rl-AP(?N4<*N|>+eQ%RIDq%K1M#>z|qS;Y5LC)TUuGoGyP}tSgBxmk$kDB zyuS|o0v2Y#UqNqfNKfc6zV!F&F`nTXeV|+}&U`f<5(h7eG9qPpW^QG56VjCE@8tDG zJuD3Z`#$}e|Irm?dfXUPp6HH{t;_xWW=%-E>| zNkB3a!t$Lus^mJni9;MAS~s>6 zf%#Z>jPR!%OxTWm@8VFawpu#w`Z<)LF=4g^EHFC zjDH?rKLF+^A0qup(2t5^el3l5+N3^g9h*T|O$7K9a_eF3Y-Lrhde7Qfe$Z?L%7Rn^ zKAC>O;{23;bOe}f97oL|TwZ)XsfPTu@_26=AmqCUdUajy#^5;MhB=d3u8$#Iqm#kE(U zx2A9#;su*GqwPN8p~WJv;bd-3VVy-9S?G@~_9JEWZFqo3)JTqu$N%$#^XZThNUS?M z;AS|y4^6gzot>P%Np`3SJg5u``5HPosJh^hW|)~#6mk}Gla9Ac?I!gj#Fs+##Y*5U}4#|$<#MTo&3OPx0rTAMoG67lbstbZh_C2f9~t%zRo?*=Q-zj&npV_ zLj_S(IdbKNWkELwZT!TO=}X;sJ<8m2Y@7k~bD*W{%kCdaKhoOwU$^syg?Cf-&}!r` zLKVW}J^W2CHm>43&BQHfJ=f(Z!m4x0=UkuN;U2ew7wQX0n}Di;uJ`B>8TAD#ng!UdGoA?IVDO4ja5=#^o%IY zHM#BJA7ERN(M0kA#8Cu!#&QM#a;+R<9s&3n~QZalr zFKk8)f+qOhEEz7|Jf8?X;+e1NimX~_u^fqBsTMfasQr{$W72?v+1J^BB!l1pmNSA( z%OL0$aU0UInqD)sA%ULcRwB&*45PvTw+4)%P^xd(IOu%3wYGMi_P!wBjF?@5*t;*5 zxgV1@?D>L$NmOZ2vzbJ&FOCVz)|bQPSQFam2I@WnzBSFpFj|JO$h}z0S0t2`_LViW zh`hvA7rgQ-gT}J1zbJw$0_k9Q71$YrZ}<7fQ28QNK1$Z2VvQ!gh8?059jo!>S7{XP zaGS*cGXO*C@CM`R31NLzSJBBf1Zc#1C%vz_-C&iHh)0&w*0;HFlUOx|IZaxSTRGVT zEPks@8~R{|afi`$-E(|pgH3pV`>=8F?}fdl=?2Y`JVsE&Jkao$1sf)L3O=Vn@XokV@z`Sx7 zw}HC#yLM~}R@?N#c_33kw!D$NGirG_s;hH(V9v^$anEWyKOB`7r;J#~q{kqVo~Jyv zL{vbpE}M)T^JzNDv1!EKZ&k>N=3h~hPk2%K4Wo&f(ALq$Ev*XO@mhL4J~DDKb0-L` zi=EObA!N^re_;O9pux2XB$tb^P11gLGFI>7w4yE_eRU0P$QyH+Md`+@(G}EXT%MDa#l`M)ee6?S2w#m& zP5vV&tV(%OMYJwRa(=*H{PW8Pf#Yj-33=(yh^hEX5S%TqhrHAv`qv#SOA@%FL_S6< z^HM0bTYD~!X9eu3S(f`=XY4=1XIcFh|0dR0fPUNEk)x$ct&QsWcq}93ewZkJ(-i5F zr!f?VNN~C@ZKg9;8MC@Phd4oaX$#RLdWugm_wp9z2VQ};$$9WU{mHk+W&VP zM6@2WMG-KBZ=0;dmWqdhd2}%EiXAeXYaC!Rvg$i|Z#^rc(hMgF9sZeUPorgT(X_{d zp&V_c?Snk6Mz!&Syc1=A=p`H~+!yDg2-;9h1n^BCJFS0ia>we-mDPyZ@t#RQ(qKaw ztBJKdMW-7Y8P^*l?Z%=Q<%V{F>oOR40Nh8f{1u7e{ERn4{gowD!RV0W9};KtOPlJF5sf}$q^mJ=hqG%bD5><8O|)01 zt30;MCuCV&ZpZ?mm--6-dzJbmrgMI$)1>`+*P72r-%i?4)Uf4p<4@Ctf6u+UBny($b4nrFLMjh zk1ytT5p7m9|2!6=k@?DHCDeRECHYuMa}$|9v~`adQJTV>3??@&MUOTWgzxItN?*KJ zM?-s2$^x}$kpk{7R2p~uU-wLlAcBJk;w80%Os1%J_cCne(|k=lAR+EYc9YGl)< zj75eSIu*NpYlnXCdIAdOK*(C2-F`H4W>Zbg|1~l?J|%glf67o-8?@&XpUW z_qM{!nnwiW702tU^5JE*WA$w;=^r_hLOufQw?bG$mP<2@UqyiKqs~Mamr{zd9^t>n ze$0x4fHBTDmPeMS0+fB#$T--b85${H@#x>`wHDqJ3=l}z0)>@7jZz%npj<0}7Sno%yHca5!|-^UR_BFXc|86L11QlcYKQoDoNOS{JeqDIf@48qw^I zutSJtG2o(3j|1|}SAu1BU%vSI$$|Nw&z#^XGait;&SE6!QMRt3Rzw$Cn%g4Dsm{K# z{DSs}x6D|Gfw6M_2!oL0Taf-psT*mjq80j-1F#&`TfnX6PdLR!%n8pOmPVa>F~}Q| z<9(jj(7n9yA&D%1s-NBbs`wv=@pof@m}6%%-4!6kPEVnmCWvL-4}S`q^gr0$s?++u z)s(r;D?t*Qc*}fk-Dr!5tYGDPFqpjVHUUcxNV;`EArbCD>LBE1CRk5FIpPg4;;u~8 zpPhIU!_gQI7N1wQsX>2j%d(4r*nr%(inJ zUw)Ulnj-80bkR0%DW0NzkaneblM8{E0IZ0!WcBwsOo??1&a({4on@7D6%9RL1I=Xr z>U&ZIA}wk0gfAstc`$ef{ww_Nffbnd8usFVMr)jxqhF#1v@ z0P&`^atVjW(T-TxB+%7>x7FZbzF*VN;3u%Qq$|%W>r6tBCicZ&ma@>E@CQ=uz%i7l zC~G~mYCDc(GX)v8Xk=AB(<>VegbWiNcE`%sQ2bOQy*WL&lmFG&~BAcg|Ct2 z9e3Z+f?>SVacL##w}4PMvg8c77nX7>LBHC@;`${&B0v(PpqkJRgE|B97T|R<%}rfO zxG&T2<$L7!N*-L-VS3k_CZ)$qSF=N|6FF~%x7{b0HqA7pv*XEc^7uZtzXRFzYm-xz zxHxg&m$93QIzMh6uB>VBF>BB5L~i2k9W=-0aBW;xDa8>%)>g)zLqid|Ue)z0@IR3D zT|ZVh#5j(Z%_b5>Wn3F|m=w>$Sp)#cE0#lxztf3}Z_{M;ww5*FhizHAqb3=9I~>M~ zF1O3z_5gSn=+4*`T^M1x&L?G?MBBFbv_{whj(0GeWccu~87Zi3VY5#&$XL*A|L)Eqkz*>{Yqo-fRg*j!K$yf6?}VR+UTP25i-SUZ*n zQiEi2?mK`bqPY~mSFLtY{2-=B-BmwAKeJ*|p_lwhkK&Y7V7yUSTi_LuUQ4Vk)F88| z&h7-@Jq#9tG_W_{VlHQ0L>73_7B{kHF@)*vZD0zDqk|3{<8J29IT<7RCSChLr+eYicMwfU{ZF$bO25-YBpO|H;j6QYUs3}>f(aPbnG)Z5A;J?4U z`(u=awUMrmFKOX)oybSUFmYQgX*WE*K4OXGFSC3y+g40G`s+h%{xMWAMu)(I*@BUW zyUSZD#Vkt&%JfD#<;l5d;YeRY_>75^pjoo3%;k9tjp9v zVIb)7{#e7qI-29>j$_}<G&4A{nV%wrA3qL<<{j`NXn3HKJ zzLL9HFUW^((`;73{4w)i$M z>K$BS*DEJ z!E3x=3R7(xU$uKikNrHCscFwA@$=A6N({sOg3J`g{*Pft`7_=n+ExO9w5^UJ51FOYa{(w{zn4B+4yF(LhFAhD1d-9M{q zg$7hfO61GSp=!O~mig~^NB?J?u|RG{X`%46gYDfF@9Too2gIe%uRWOdXQ&{D%*igE zj(35m>S6Ldav9S6RX&*3dU*uJ~P;R?b3P^@mILp$JCThEq@V9ul-8 zs;fR*r>{Vd{N20%*^uZwMe8)dGriQLuQoCp@kgjvu;749@$!=DoJVTVj~})1eM96r zX0O^p684%x;jZMrEG`qDXdkM*7j@bOI$bXrUiwVEz^7^Eyn}xv+J-NpeJ0=U)A#XH zP}`qkm=7b-?ex#};6wV;H)>I)1&uK&=KJD7e}29^U25k3Em!qp>1>CTYb`i5Tlx68 zz&6cH9iA50pGQn60F=m1-=Yda_ejl2Pp|rrwA=n{8A=Ht9X55_Ngx~PrdQ%iyUo#i zevX%ot}e+4lo@||nKB*T!S9#QGC_GPFZ!ltJ6vT1+H7r#_-h`VWE|v>m{lrh{^}I& zdOVSJcNZ7j8Xi6g?&|ZutRf%ww@c9d>F-(CtXV$rvajc|<%*%PbM@HKU}sV7QT1R} ztGSXB3T4+_&g1=&%2{vRz)9@ssE*tEp!a4v%i){oXo4NGVIY_e=o%kPQV=@R6iofD z0GX(jsVcmK7Z$>8Z#ADUwn!K%814tLu6CN85p?8!qEO$!G{xK`(iGF=ACl|3^^HNu zI5Ok(v(t^!;j>oDz~qJW&9mLc{|@AO-Nq8QW+klbx)dz*RR1~-ybZR@1o)g69phg{ z`FCszLec~K>U2DuD+|9bjc+5I?;at7{tniTl!)wbKik%9g_580gwT3#iJJlGE@t0~ zand>}2X4HD;<{kdwVTFFZ2G0F=p60~H^8a4{=5bmQuH5BAoJQyF|h#Jb-k(nrso!R z-Msf1v%ufNxAnFcED_rbJ7W{SavG+NnUDeWZx1P7cnK}BELsU+k@v(>40+0)+E*WL zWT3?iZK(gqd{AG9*XYi9?22K-lPLSV z#o}CkgCmt!$(&z>+YuBr$!&IOB?{1eC8WV61K){pw3%r}mpHGnx5wU9`RBP(E68n# zni#Lr^23nc3gr={!;{SQ+&;sS-uY7L`0B-f^7YKJGIYG$&j@atm5U9 z64i=C2_iPXABa*r@EP9cwDRi;UcfZ0`?zXNQq$=cV`psVpL) zeusAqT!;2=6F4|(vL(jOD^n_6&0prDL!Ic(4g4Z`NA-@UV#_Voqhayt0NCRe#On^n zzfb@tYa1pFUCNR@P4!DlRNMt}>DH`}nKOoVnW{72JL_Ck8~PSi&Y(R>40ZM6J;s$( zFOXLwwX=hJ+^lAGdhtS;570J63S#^-?b%`auJdw9z+;)7`skeYiCw8czYxQTUY5XQ zNmEling5ZmtVvatzsvrkNvdPWRAEy>Gt|q_3I2+nte4D%H}HOaN}1)^UJ_NWvq(A2 zp$OkfnS`tl!d~X!`j_5vgod4-ps`Q2z4=pmDi5CESoR@P&!_A%))dkj4DLM|U9TEc z2&E@kJN`Aj-TTe7k)@%1iLuo)+%oVDqhkBpRXb^a+@6XZhiU;><|s?&JRUCAhEk&j zZCg7}Dl|dF>UdF6({}s;_v{aJ-~n?o@B+uUiw}Pd$kx>*cFdlkmgvQ%%|Re7Nh}{8WWYP*uJ;8;?a=n%Ncd zW3pwRHicmhFV3ud=7+NS5k4bd%#r7LtGL4iMC+Wi6dbR}pz zFEV409N(JXcv9=r<{d~M?0zgf#^`RjuQYYSzgCst!P<53?uA;DT*#VuBZBV3Ayeo0 zMTG_M4e}qq5;KzN7WrC3=R<Bfev_g(=3{DT(R4m*%b98_dE_>h z7l1~LdK{?Eo%Y?TeE**s8une><|kz*v9+@={pqiz@*QT{uSLY_38e58UP9Wkp4;kyDG^Z$u z33pd~MIDq&nH1h((I}Co z#v|f21mjG>FQ8x0RQ{gIL}n1zZvEQH+v;P7_yuyA6DxIYt1Hh5O^xNt*coUb8tbMI zo{9eI3K!=|-+iCVX175Z8{RYwEqSQ;LqM^qh|7*d(tX-_vZa2TblgvnHDRJXVViE< z?9k^Gs^I8wU#{^8oN;MrjOrfcaTkl8B-QxkV-DhGr+3Bao-UXe{kt(AfkXRVNxWbh z&)>(97=Dh}W~^_zHZ=s9X~vM2%CWxPW0`~N6_;}EAGaHwDhHxuEU^kC;@=|RuJioE z9H#-!O8!~^6YN_4a^^2_mCSafK2cL4sUr1Ve2@AC=Wu*Q$c1s24hGE_?JwxMr+5Nk zLy+YHW9tqHZfkbeax%h{+iI+%a(%CNqWP@Gl37`uouoFW`&ioXK%ohq)#m%_``zYa zS%>D6`?WG_w%GK!y+nlince%7*gK0Jj}vrqCtXB7^a~pe=&(f^;Td>*_c=s6&{5sc8$1*JhJ@SJ0jZJVr>VEicT4PiNpLS~9 zv;|G9lgaf%AwEmH&b|-6E{&<4O$g$tMR3dk=k1ou>pID(ge4wXQrFj&DYBDi{&aeq z#ux>N+Gs}bqJmpK2kX^UCeDMkx(D`weE}C?q6iPu%`t(p+e+1OB}d)biB#>Adal6N zqja{{uT2Ry?r}M%z`Tb81ieWTP+N^!qw8nSiK6A(F+uDk964(bK6Y(~bAl@eCit^) z47!f6(MajXyI>({{xU^~*E9Q13paoOJU={I$7g1PHlD@pMmerv5FTQdk2(~)BT z77pYe6p|)>x^29VM^Sx;pFtb!Uv1A?2kmtRsLhn!+tl&%^GPp8OCLJO!Cm{D{7c@U z#&wGs%Y|JheUQFLoA)LQvUQ(vi(4`xG)3hjzRYqeJw!j`*UI9w`N>q4TJ#? zlNf7q+)ySJO-sON@7RUtJSv)37LTRhio|FqT60icCJj~}6}pQHlI5*nC?$BLdio{a zH3hz=JbBBC9>_olalY8yOm56OCnqb+?98LtY*`GmUPq?)Zl`FZojU7?A3MizDYlkz zbyL(6eVFfs$HRYe>z$&4jOhQ5NP?kvd;!n=XT#d z|H5v*Oogcwb|1>|uF$j9Kixt%(nfAI_LsALw{8NHnUe=4NGtd%JCyvF9v%E_1Vqcx zh$rz6(f59|wVJu4&wRPixH2DVQM4TaUUWOJWdoz|8O?x}ZL5)3q+yH)?GsO1fpvY@ zQB56`UWc5W>rX;PaOepBD8!|&ZVj%p|4Wr9(0RtVKZM~RyM;BAeax$h)Zjk7g85DC zTKIerVuXAE2MRl(gbpOSfj}3YceD```|<3URkwM9Z{GjGBio0+?Ltb(&vX#G0e8=S zIlFa}n%O|s$LC(2s&>bB{0tmOltncSug;}d!_VOv7)4Jk=L`Gr2L5@$L>l7lXE{j~ z6!mZCk3#+Bisr$At6{lqvDdBX8tIOElZVjcTzr9+hrs{~0Fwoi@JOVky^QC3?M<5E z*Qehbd1{l_X+ebRCjzywiib2`&)MoymuwpNj_UYgiUYMteNg|Ftv2-R!pyWijj`>;4?B(3;ZAa2n%?a*lPpjsCq1snDO*$TC6&Y zTr4r-q(-^!J!Zx@^cTe{_+={N6r^be!w=a)z{rt1{FzoaDLOavq#f=q1_*r9rFr9o z?=Gx;8&5-L*BXE6x%n4spu+Q`)P@7mli&CmSB;$Xc$$G(tgDM_!ZjT==Lm+-CsVbb z3One%#ETOfY{8PvzbFZ9=z#~{kG*j1n1*%l&lvvD|Fg&#%4T6luAEhMuP?~{>Ei+q|I6n3u5-+2~04vC+5f)!%=-Kr-mn2o=$i6b==5UW1sXiC5iSDl#=r-pR~-flHxz#6k0eDI~d z;6{Fmro*fve`}vbJraFI6SU)FfKG9EitT)d)2@&2R z<$cD!es5iey@=;%9Np_DGI{g9e3S=05vD*Z-VAVWVBlVdix%XqSdDCIm(wqfLzPR8 zKgcqSRcmRnnrz%y*9rZ_H<9Z$NezR)ctQRIw9e#k^Xsx7c%aDg5|;k4i7;P9kn_;I zY|Jr&lJm^P5wJX(9YoenmohEg&F_<;VCQ8{2rzLw7SZ~ml(C_xh!|v*bkKs zIhj>C)Jl||VBoVQF|Ecbwwb*t^6ta{HFNkHay%fbZaq_b49gZ-;R{yV>3v$^@6S(7zJ%)~)E2jHD}Q?UlpiCZcRj4Vr5bB`XTM z6Xf6mf4!fxu(OO--f)yWH-%b+O{09}Y4-j3gOD7aiH%MA zkVf4g#RC=nnS;x;D@+Gc9CitS=INpR`tZ-Rn(uZ#Cw+>Bqst;Z2C>A0^?}k!A5lJp@g0^aez8RQoo*8 zHV!CsS$}B4%qY#6Mu&fwzf<}9NcZ6=^*G7B`)&&#*UP8di_$+TfW3PjO-18}D{Fm% zFAk35Q&HohLN*%*=F@=w;xqBlu0X!eT|iw%V8Qd9H{{^J$G}nc&)>*^SU#%4z$E~oh%hT z6WO_>!KVi}3Bf}=yORShlpiQ+`%=R%R-VT+nn?GDCi`#aqckfL>}@GC6Qz{hu)A>{ z3SWHU9PZk|^Q55j(A&0Nb>#wQfFPra;Js{M6A)>SMV5AomX@u}c0A!A!DO}lk+ojb zV==_21~(FtoX5w`7r&gD-hG|cxRrb1dz`iT?>2^R?-}5-srY-@PWRtKOAdVgNJmk) z=o`Hn$wstc1mT;(FUj03sAH!&%o-M%UUA*&awwK1%)QTU$VeSNd+_xVx&wm7HjmIT zoKKH0(x&9+__`)OII2AZX8yWLBS6Pzst!MX^=|jhl8B;WH|h=tTf#0M;M?91x<^i9 zEvaX-jB9nX3~h)on%M4gZzT|KWB^r^5-(B}Ixmi;6Xz_3>B^nRvpA{!0VA0@yyQyabsh9eLx z{2ov2Z%GBggnrQ|`!Vi(cqOHFTU9;`;BPJ-Jx`*vtLM`e;?m5;5A+U-oPpDQK0HGR z2kpZfomt%lBi7Z+BI@D`&$>@M7#5u|eXnNn{3lV_gKlU#D2K5yEr2N`s8xo8spmeY zZyfz{R+0A-*%Vm36jqlbZg0>lDKMn2l!{8<@(_Zg-T9aE8YH!x?;MY}7~vEbsd~I@ zYvrE`X5KjZ>(eg8@ri9L%HzL*Mc|SWC4cOmw`hM4Adv&KGmQj?T&Y@iLE70A;_13E z_nFWW87wJQR?5uq{!7(}J;}AS3$foI4|JZ_+Rn;+Z>&zW0o1s#Xs~OrdiwCYb82No z>01tXb{Zn8#Y~qecdXF-6X4AFY+xG7tuzw?QX`gq(egJAlbnhILbca87ZuWEH_Y9} zNODz^e&vmDBQA_l9%f%i*u@*T*xKIE$P=1KTQ&0KaXT&dm!1u^KZtN?8L93$(Y>lL&_f zE)}lJ7=s8cN&wm35Q+%MZ&+HW+JxCthYiuv?!L_~V)}qUZhg|mf_ulsdW5gC_s#ni z(3l$h4&OR4uwt_nK@kkX@K`mdh}Q~Gdrc*r4kLu7hqd$klEtVcV~4M@xhTYl?vB%` z{?Y`7l>2njx3Ldo5iya^eVl8IqN0t@Vd-pK z&OjUL(>O88KXnxa`~6Y1iu3C@PrJCLw&2 zK&zqX2)(UStXhgjf4vMXKp}ttThya2%Td?>CK`iO;MF`cr;B7dGccSTO_OW6z=k4S(pbrK z88N0GS_Wr}`wr|ZHN&Yg|IA?tnph;1g4A6|+dCs1c>^joHZi;9G6H=04dFAD`yfi7 zeP+T0D43Un-!%UkU#L_FXu1o2BjU9DdQ?=ZuW}6=h|`ZZt5&nO3#b{q8*?FULtbMr zGEWyvQw~~~wx$p69p185nD2ryK&mG0v?Zq7SCn6MeNWAsCa2K zgu^e;bI)44#(nF$)l%fI?P-PAvJsjEFG_`;ULYY}?`CciL5_d)huJ5ch40jj^I_gR z6=W<> ziT}8&z&wu&1_5)M;4h=ipga}g@%{R(j%SMG=9K4DKd58r+E*UX5Es=Xi4r=o?y*E= z4pIfE&8hAwpFx>A zA5(>bEHHCYpmi~#ig7>q6uJ}=*hCBJnD0ETKj(9oLJMb_3Nh%GJV*p^4PY$9j5t4V zT&rCwVY?A*POfAu3pcXAdgoF=!w8^*!WYw>2acw8--p&UiL6O3Wj?Dy5?rSx31y_4edc7=F@xUw7WC`os6SY}UO6BQS0bRhE58_-s-Nb-nWYJ7HPeC>i?^`@kM})? zHLq+Y`Af0MyU%?6*j5|C<7d8hv1l}#sEq_S6%`EfntP3?NKfh*3aIqKUWe}hHUH+n zpD}0hi6sP(?>`f49F3e1l8aCdQsOx;H)yOOiGuCf?KUE1&nz+`$cd zZ)H6<0nANL@I0w-*}$F{oKcpO5yBeU)+MbhUS$S7w1V6}tYchs&NTmw03;n=iXd)} z)};tyGTu%T(&%;~9!?bsd~|?OwBam()(0QA*Zsdc1}xVy=hiH-2a Date: Sat, 21 Oct 2017 21:39:12 -0700 Subject: [PATCH 429/792] Remove no-longer-used KeyboardioHID.h include --- src/MouseWrapper.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 99a9adbd..732d2af7 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -1,7 +1,6 @@ #pragma once #include "Arduino.h" -#include "KeyboardioHID.h" // Warping commands From 0f00b4a9a9fa84653a214e09d0b5201537b4d2d1 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Wed, 25 Oct 2017 21:17:31 -0400 Subject: [PATCH 430/792] Add method to allow upload of keymap for individual layer --- src/Kaleidoscope/EEPROM-Keymap-Focus.h | 3 +++ src/Kaleidoscope/EEPROM-Keymap.cpp | 16 ++++++++++++++++ src/Kaleidoscope/EEPROM-Keymap.h | 1 + 3 files changed, 20 insertions(+) diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Focus.h index 23bfb61f..931be0ff 100644 --- a/src/Kaleidoscope/EEPROM-Keymap-Focus.h +++ b/src/Kaleidoscope/EEPROM-Keymap-Focus.h @@ -23,5 +23,8 @@ #define FOCUS_HOOK_KEYMAP FOCUS_HOOK(EEPROMKeymap.focusKeymap, "keymap.map") +#define FOCUS_HOOK_KEYMAP_LAYER FOCUS_HOOK(EEPROMKeymap.focusKeymapLayer, \ + "keymap.layer") + #define FOCUS_HOOK_KEYMAP_TRANSFER FOCUS_HOOK(EEPROMKeymap.focusKeymapTransfer, \ "keymap.transfer") diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index e9a9de8d..af6d5507 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -107,6 +107,22 @@ bool EEPROMKeymap::focusKeymap(const char *command) { return true; } +bool EEPROMKeymap::focusKeymapLayer(const char *command) { + if (strcmp_P(command, PSTR("keymap.layer")) != 0) { + return false; + } + + uint8_t layer = Serial.parseInt(); + uint16_t keysPerLayer = ROWS * COLS; + uint16_t offset = layer * keysPerLayer; + for (uint16_t k = 0; (k < keysPerLayer) && (Serial.peek() != '\n'); k++) { + updateKey(layer + k, parseKey()); + } + + return true; + +} + bool EEPROMKeymap::focusKeymapTransfer(const char *command) { if (strcmp_P(command, PSTR("keymap.transfer")) != 0) return false; diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index b1e7de81..66c89620 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -36,6 +36,7 @@ class EEPROMKeymap : public KaleidoscopePlugin { static Key getKeyOverride(uint8_t layer, byte row, byte col); static bool focusKeymap(const char *command); + static bool focusKeymapLayer(const char *command); static bool focusKeymapTransfer(const char *command); static void updateKey(uint16_t base_pos, Key key); From 6dcc6a9277ae5a30c32c98f6dc85d2738f274f79 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Thu, 26 Oct 2017 08:16:48 -0400 Subject: [PATCH 431/792] Teach plugin to print out the contents of a given layer --- src/Kaleidoscope/EEPROM-Keymap.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index af6d5507..7d83e792 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -115,8 +115,18 @@ bool EEPROMKeymap::focusKeymapLayer(const char *command) { uint8_t layer = Serial.parseInt(); uint16_t keysPerLayer = ROWS * COLS; uint16_t offset = layer * keysPerLayer; - for (uint16_t k = 0; (k < keysPerLayer) && (Serial.peek() != '\n'); k++) { - updateKey(layer + k, parseKey()); + if (Serial.peek() == '\n') { + for (uint8_t row = 0; row < ROWS; row++) { + for (uint8_t col = 0; col < COLS; col++) { + Key k = Layer.getKey(layer, row, col); + printKey(k); + ::Focus.printSpace(); + } + } + } else { + for (uint16_t k = 0; (k < keysPerLayer) && (Serial.peek() != '\n'); k++) { + updateKey(layer + k, parseKey()); + } } return true; From e4cf2e4c755be8f667a381b07b8d9e7528cf1142 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Thu, 26 Oct 2017 08:21:01 -0400 Subject: [PATCH 432/792] Add documentation about new hook to readme --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8ab29ee4..3afc9628 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,8 @@ The plugin provides the `EEPROMKeymap` object, which has the following methods: ## Focus commands -The plugin provides two `Focus` hooks: `FOCUS_HOOK_KEYMAP`, and -`FOCUS_HOOK_KEYMAP_TRANSFER`. Together, they make the following commands +The plugin provides three `Focus` hooks: `FOCUS_HOOK_KEYMAP`, `FOCUS_HOOK_KEYMAP_LAYER`, +and `FOCUS_HOOK_KEYMAP_TRANSFER`. Together, they make the following commands available, respectively: ### `keymap.map [codes...]` @@ -81,6 +81,13 @@ available, respectively: > layer, and go on as long as it has input. It will not go past the layer set > via the `.max_layers()` method. +### `keymap.layer LAYER [codes...]` + +> Without codes, prints the keymap for the given layer (zero-indexed). +> Prints each key as its raw 16-bit keycode. + +> With codes, stores them as the keymap for the given layer. + ### `keymap.transfer LAYER` > Transfers the `LAYER` from the built-in memory of the keyboard into `EEPROM` From 480bfbd0217ce349d6c129ec35c058f8b9b6cdb4 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Fri, 27 Oct 2017 17:28:32 -0400 Subject: [PATCH 433/792] Guard against out-of-bounds layer --- src/Kaleidoscope/EEPROM-Keymap.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 7d83e792..0d2b00c6 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -113,6 +113,9 @@ bool EEPROMKeymap::focusKeymapLayer(const char *command) { } uint8_t layer = Serial.parseInt(); + if (layer >= max_layers_) { + return false; + } uint16_t keysPerLayer = ROWS * COLS; uint16_t offset = layer * keysPerLayer; if (Serial.peek() == '\n') { From a1c0fdfb42d5fca67c68558f2a8dd85f394cb9be Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 29 Oct 2017 20:30:03 +0100 Subject: [PATCH 434/792] Sync the NUMPAD layer state with the host Instead of trying to track numlock ourselves, rely on the host telling us what it thinks the state is. This is much more reliable than what we were doing, and hopefully fixes most of - if not all - the issues we were having with NumLock. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 35 ++++++++++++++++------------------- src/Kaleidoscope-Numlock.h | 2 +- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index c0d31150..5bd2dc33 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -5,15 +5,29 @@ byte NumLock_::row = 255, NumLock_::col = 255; uint8_t NumLock_::numPadLayer; +bool NumLock_::isOn; cRGB numpad_color = CRGB(255, 0, 0); void NumLock_::begin(void) { Kaleidoscope.useLoopHook(loopHook); - Kaleidoscope.useEventHandlerHook(eventHandlerHook); } void NumLock_::loopHook(bool postClear) { - if (!postClear || !Layer.isOn(numPadLayer)) + if (!postClear) + return; + + bool numState = !!(Keyboard.getLEDs() & LED_NUM_LOCK); + if (numState != isOn) { + isOn = numState; + if (isOn) { + Layer.on(numPadLayer); + } else { + Layer.off(numPadLayer); + LEDControl.set_mode(LEDControl.get_mode_index()); + } + } + + if (!isOn) return; for (uint8_t r = 0; r < ROWS; r++) { @@ -36,21 +50,4 @@ void NumLock_::loopHook(bool postClear) { LEDControl.setCrgbAt(row, col, color); } -Key NumLock_::eventHandlerHook(Key key, byte row, byte col, uint8_t key_state) { - if (key != Key_KeypadNumLock) - return key; - - if (!keyToggledOn(key_state)) - return key; - - if (Layer.isOn(numPadLayer)) { - Layer.off(numPadLayer); - LEDControl.set_mode(LEDControl.get_mode_index()); - } else { - Layer.on(numPadLayer); - } - - return key; -} - NumLock_ NumLock; diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-Numlock.h index d9d42871..9b147d4d 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -14,9 +14,9 @@ class NumLock_ : public KaleidoscopePlugin { private: static void loopHook(const bool postClear); - static Key eventHandlerHook(Key key, byte row, byte col, uint8_t key_state); static byte row, col; + static bool isOn; }; extern NumLock_ NumLock; From 0943911786e53f468254c243e04e6eededb3e97f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 29 Oct 2017 22:22:28 +0100 Subject: [PATCH 435/792] Use kaleidoscope::hid instead of Keyboard directly Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Numlock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 5bd2dc33..651975da 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -16,7 +16,7 @@ void NumLock_::loopHook(bool postClear) { if (!postClear) return; - bool numState = !!(Keyboard.getLEDs() & LED_NUM_LOCK); + bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); if (numState != isOn) { isOn = numState; if (isOn) { From 0073be9a74b87d6772acb6b1e0c7268282951bd4 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Mon, 30 Oct 2017 08:16:37 -0400 Subject: [PATCH 436/792] Fix error in storing keys by layer --- src/Kaleidoscope/EEPROM-Keymap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 0d2b00c6..5a0a6636 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -117,7 +117,6 @@ bool EEPROMKeymap::focusKeymapLayer(const char *command) { return false; } uint16_t keysPerLayer = ROWS * COLS; - uint16_t offset = layer * keysPerLayer; if (Serial.peek() == '\n') { for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t col = 0; col < COLS; col++) { @@ -127,8 +126,9 @@ bool EEPROMKeymap::focusKeymapLayer(const char *command) { } } } else { + uint16_t offset = layer * keysPerLayer; for (uint16_t k = 0; (k < keysPerLayer) && (Serial.peek() != '\n'); k++) { - updateKey(layer + k, parseKey()); + updateKey(offset + k, parseKey()); } } From c298d22827a6e90235c0bf0b507f3c6df99118be Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Mon, 30 Oct 2017 10:42:46 -0400 Subject: [PATCH 437/792] Only need keysPerLayer in the updating branch of the conditional --- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 5a0a6636..a8bd42bf 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -116,7 +116,6 @@ bool EEPROMKeymap::focusKeymapLayer(const char *command) { if (layer >= max_layers_) { return false; } - uint16_t keysPerLayer = ROWS * COLS; if (Serial.peek() == '\n') { for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t col = 0; col < COLS; col++) { @@ -126,6 +125,7 @@ bool EEPROMKeymap::focusKeymapLayer(const char *command) { } } } else { + uint16_t keysPerLayer = ROWS * COLS; uint16_t offset = layer * keysPerLayer; for (uint16_t k = 0; (k < keysPerLayer) && (Serial.peek() != '\n'); k++) { updateKey(offset + k, parseKey()); From a3a5cfbc6afcb95a1928d6aa765b92a13d3ad99d Mon Sep 17 00:00:00 2001 From: Bart Nagel Date: Wed, 1 Nov 2017 00:30:45 -0700 Subject: [PATCH 438/792] Fix code typo in blazing trail decay A number was given as 0xf0 instead of 0xff, leading to a noticeable sudden snap from blood-orange to orange. --- src/Kaleidoscope/LED-Stalker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 055b7978..42c043d4 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -115,7 +115,7 @@ cRGB BlazingTrail::compute(uint8_t *step) { color.g = min(*step * color.g / 255, 255); } - if (*step >= 0xf0 - 30) + if (*step >= 0xff - 30) *step -= 1; else if (*step >= 0x40) *step -= 16; From 4342080621573bcc4111005942be2043e0099ced Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 18 Oct 2017 09:29:14 -0700 Subject: [PATCH 439/792] Turn off light when done Fixes #2. --- src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 31 ++++++++++++++------- src/Kaleidoscope-LEDEffect-BootGreeting.h | 2 ++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index 9475e9d4..87c3749b 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -22,9 +22,27 @@ namespace kaleidoscope { bool BootGreetingEffect::done_; +byte BootGreetingEffect::row_; +byte BootGreetingEffect::col_; void BootGreetingEffect::begin(void) { Kaleidoscope.useLoopHook(loopHook); + + // Find the LED key. + for (uint8_t r = 0; r < ROWS; r++) { + for (uint8_t c = 0; c < COLS; c++) { + Key k = Layer.lookupOnActiveLayer(r, c); + + if (k == Key_LEDEffectNext) { + row_ = r; + col_ = c; + return; + } + } + } + + // We didn't find the LED key. Let's just pretend we're "done". + done_ = true; } void BootGreetingEffect::loopHook(const bool post_clear) { @@ -33,19 +51,12 @@ void BootGreetingEffect::loopHook(const bool post_clear) { if (millis() > 9200) { done_ = true; + ::LEDControl.refreshAt(row_, col_); return; } - for (uint8_t r = 0; r < ROWS; r++) { - for (uint8_t c = 0; c < COLS; c++) { - Key k = Layer.lookupOnActiveLayer(r, c); - - if (k == Key_LEDEffectNext) { - cRGB color = breath_compute(); - ::LEDControl.setCrgbAt(r, c, color); - } - } - } + cRGB color = breath_compute(); + ::LEDControl.setCrgbAt(row_, col_, color); } } diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index ace51843..acd48fdb 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -30,6 +30,8 @@ class BootGreetingEffect : public KaleidoscopePlugin { private: static void loopHook(const bool post_clear); static bool done_; + static byte row_; + static byte col_; }; } From 34f9848b8abb969ec1e900f21e120924f0e32341 Mon Sep 17 00:00:00 2001 From: Donald Curtis Date: Fri, 3 Nov 2017 01:54:26 -0500 Subject: [PATCH 440/792] stepLength -> step_length in README.md There is a typo in the README.md file. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 946292c7..dece8113 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ properties: > > It is recommended to use the `STALKER` macro to declare the effect itself. -### `.stepLength` +### `.step_length` > The length - in milliseconds - of each step of the animation. An animation > lasts 256 steps. From 802dcb1e35ec545d4710e35bc44d5810ab3e816c Mon Sep 17 00:00:00 2001 From: Javaru Date: Sat, 4 Nov 2017 16:59:05 -0400 Subject: [PATCH 441/792] Fix for issue that defined LED constants for thumb keys and fn keys have wrong values. Renamed some LED thumb variables for consistency (none are used elsewhere at this time). --- src/Kaleidoscope-Hardware-Model01.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index bf8a5702..1ec07bdc 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -160,16 +160,16 @@ class Model01 { #define LED_ESC 24 #define LED_TAB 25 #define LED_LED 26 -#define LED_L_FN 27 -#define LED_L_CTRL 28 -#define LED_DEL 29 -#define LED_CMD 30 -#define LED_L_SHIFT 31 -#define LED_R_SHIFT 32 -#define LED_ALT 33 -#define LED_SPACE 34 -#define LED_CTRL 35 -#define LED_R_FN 36 +#define LED_L_CTRL 27 +#define LED_BKSP 28 +#define LED_CMD 29 +#define LED_L_SHIFT 30 +#define LED_L_FN 31 +#define LED_R_FN 32 +#define LED_R_SHIFT 33 +#define LED_ALT 34 +#define LED_SPACE 35 +#define LED_R_CTRL 36 #define LED_ANY 37 #define LED_RETURN 38 #define LED_BUTTERFLY 39 From b3ea050595e4ab00564ba297614a1d5fb2e6cf7d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 12 Nov 2017 16:22:10 -0800 Subject: [PATCH 442/792] Reorder definitions and add a clarifying comment --- src/Kaleidoscope-Hardware-Model01.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 1ec07bdc..c7d6373e 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -23,10 +23,14 @@ class Model01 { void readMatrix(void); void actOnMatrixScan(void); void setup(); - void enableHighPowerLeds(void); - void enableScannerPower(void); void rebootBootloader(); + + /* These public functions are things supported by the Model 01, but + * aren't necessarily part of the Kaleidoscope API + */ + void enableHighPowerLeds(void); + void enableScannerPower(void); boolean ledPowerFault(void); /* Key masking From dbb1b95d5c04e951058cb5b70c828475f8cd4c36 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 12 Nov 2017 16:22:24 -0800 Subject: [PATCH 443/792] Add a public API for a device-specific feature (configurable debounce time) --- src/Kaleidoscope-Hardware-Model01.cpp | 6 ++++++ src/Kaleidoscope-Hardware-Model01.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index d23e63bc..cbf6d0c8 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -242,4 +242,10 @@ void Model01::maskHeldKeys(void) { memcpy(rightHandMask.rows, rightHandState.rows, sizeof(rightHandMask)); } + +void Model01::setKeyscanInterval(uint8_t interval) { + leftHand.setKeyscanInterval(interval); + rightHand.setKeyscanInterval(interval); +} + HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index c7d6373e..c0a68b5c 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -31,6 +31,7 @@ class Model01 { */ void enableHighPowerLeds(void); void enableScannerPower(void); + void setKeyscanInterval(uint8_t interval); boolean ledPowerFault(void); /* Key masking From 2e91dd4a824d5620c92d3524d99d799ae7942cfc Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 12 Nov 2017 16:28:12 -0800 Subject: [PATCH 444/792] Disable hardware debouncing in testmode --- src/Kaleidoscope-Model01-TestMode.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 0c76a594..838bf9a0 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -110,7 +110,8 @@ void TestMode_::toggle_programming_leds_on() { void TestMode_::run_tests() { // Serial.println("Running tests"); toggle_programming_leds_on(); - + // Disable debouncing + KeyboardHardware.setKeyscanInterval(0); test_leds(); testMatrix(); // Serial.println("Done running tests"); From c126e1b27b58c007b9acf1d262154ddd0fc05b58 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 12 Nov 2017 16:29:23 -0800 Subject: [PATCH 445/792] astyle --- src/Kaleidoscope-Hardware-Model01.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index c0a68b5c..72a242a4 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -27,7 +27,7 @@ class Model01 { /* These public functions are things supported by the Model 01, but - * aren't necessarily part of the Kaleidoscope API + * aren't necessarily part of the Kaleidoscope API */ void enableHighPowerLeds(void); void enableScannerPower(void); From 75dfcf8ccb987199e3a5075206b83deb31d6ea6a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 12 Nov 2017 20:12:21 -0800 Subject: [PATCH 446/792] First pass at a new chatter detection mode --- src/Kaleidoscope-Model01-TestMode.cpp | 69 +++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 838bf9a0..afaae36b 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -8,7 +8,7 @@ cRGB red; cRGB blue; cRGB green; - +cRGB white; TestMode_::TestMode_(void) { } @@ -18,6 +18,9 @@ void TestMode_::begin(void) { red.r = 201; blue.b = 201; green.g = 201; + white.r = 50; + white.g = 50; + white.b = 50; Kaleidoscope.useLoopHook(this->loopHook); } @@ -66,7 +69,12 @@ void TestMode_::test_leds(void) { } +uint32_t leftBadKeys; +uint32_t rightBadKeys; + +uint32_t olderLeftHandState = 0; +uint32_t olderRightHandState = 0 ; void TestMode_::testMatrix() { LEDControl.set_all_leds_to(200, 0, 0); @@ -79,26 +87,69 @@ void TestMode_::testMatrix() { for (byte col = 0; col < 8; col++) { uint8_t keynum = (row * 8) + (col); - uint8_t keyState = (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 0) | - (bitRead(KeyboardHardware.leftHandState.all, keynum) << 1); + uint8_t keyState = (bitRead(olderLeftHandState, keynum) << 2) | + (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 1) | + (bitRead(KeyboardHardware.leftHandState.all, keynum) << 0); + + + // If we had chatter in between two reads + if (keyState == 2 || keyState == 5) { + bitSet(leftBadKeys, keynum); + } + - if (keyState == 3) { + // If the key is held down + if (keyState == 7) { KeyboardHardware.setCrgbAt(row, 7 - col, green); - } else if (keyState == 1) { + } + // If we're seeing chatter right now + else if (keyState == 2 || keyState == 5) { + KeyboardHardware.setCrgbAt(row, 7 - col, white); + } + + // If we triggered chatter detection ever on this key + else if (bitRead(leftBadKeys, keynum)) { + KeyboardHardware.setCrgbAt(row, 7 - col, red); + } + + // If the key was just released + else if (keyState == 6) { KeyboardHardware.setCrgbAt(row, 7 - col, blue); } - keyState = (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 0) | - (bitRead(KeyboardHardware.rightHandState.all, keynum) << 1); - if (keyState == 3) { + keyState = (bitRead(olderRightHandState, keynum) << 2) | + (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 1) | + (bitRead(KeyboardHardware.rightHandState.all, keynum) << 0); + + // If we had chatter in between two reads + if (keyState == 2 || keyState == 5) { + bitSet(rightBadKeys, keynum); + } + + // If the key is held down + if (keyState == 7) { KeyboardHardware.setCrgbAt(row, 15 - col, green); - } else if (keyState == 1) { + } + // If we're seeing chatter right now + else if (keyState == 2 || keyState == 5) { + KeyboardHardware.setCrgbAt(row, 15 - col, white); + } + + // If we triggered chatter detection ever on this key + else if (bitRead(rightBadKeys, keynum)) { + KeyboardHardware.setCrgbAt(row, 15 - col, red); + } + + // If the key was just released + else if (keyState == 6) { KeyboardHardware.setCrgbAt(row, 15 - col, blue); } } } LEDControl.syncLeds(); + olderRightHandState = KeyboardHardware.previousRightHandState.all; + olderLeftHandState = KeyboardHardware.previousLeftHandState.all; } } From 1333f302527cd1dfbf9d4ed5ce8edb26569eace3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 12 Nov 2017 23:08:39 -0800 Subject: [PATCH 447/792] Switch to not trying to use 'Numlock' as a toggle. --- src/Kaleidoscope-Numlock.cpp | 28 ++++++++++++++++++---------- src/Kaleidoscope-Numlock.h | 2 +- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-Numlock.cpp index 651975da..c7f2adf1 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-Numlock.cpp @@ -5,7 +5,7 @@ byte NumLock_::row = 255, NumLock_::col = 255; uint8_t NumLock_::numPadLayer; -bool NumLock_::isOn; +bool NumLock_::cleanupDone = true; cRGB numpad_color = CRGB(255, 0, 0); void NumLock_::begin(void) { @@ -16,25 +16,33 @@ void NumLock_::loopHook(bool postClear) { if (!postClear) return; - bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); - if (numState != isOn) { - isOn = numState; - if (isOn) { - Layer.on(numPadLayer); - } else { - Layer.off(numPadLayer); + if (!Layer.isOn(numPadLayer)) { + if (!cleanupDone) { LEDControl.set_mode(LEDControl.get_mode_index()); + cleanupDone = true; } + return; } - if (!isOn) - return; + cleanupDone = false; + bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); + if (!numState) { + kaleidoscope::hid::pressKey(Key_KeypadNumLock); + kaleidoscope::hid::sendKeyboardReport(); + } + + LEDControl.set_mode(LEDControl.get_mode_index()); for (uint8_t r = 0; r < ROWS; r++) { for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookupOnActiveLayer(r, c); Key layer_key = Layer.getKey(numPadLayer, r, c); + if (k == LockLayer(numPadLayer)) { + row = r; + col = c; + } + if ((k != layer_key) || (k.flags != KEY_FLAGS)) { LEDControl.refreshAt(r, c); } else { diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-Numlock.h index 9b147d4d..bf33aa5e 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-Numlock.h @@ -16,7 +16,7 @@ class NumLock_ : public KaleidoscopePlugin { static void loopHook(const bool postClear); static byte row, col; - static bool isOn; + static bool cleanupDone; }; extern NumLock_ NumLock; From 3de82eb6a4e074d8bec2a98cde4f1450c5ff783c Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 12 Nov 2017 23:11:44 -0800 Subject: [PATCH 448/792] Renaming --- README.md | 4 ++-- library.properties | 6 +++--- ...scope-Numlock.cpp => Kaleidoscope-NumPad.cpp} | 16 ++++++++-------- ...eidoscope-Numlock.h => Kaleidoscope-NumPad.h} | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) rename src/{Kaleidoscope-Numlock.cpp => Kaleidoscope-NumPad.cpp} (79%) rename src/{Kaleidoscope-Numlock.h => Kaleidoscope-NumPad.h} (76%) diff --git a/README.md b/README.md index b8173982..3bbe9948 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Kaleidoscope-Numlock +# Kaleidoscope-NumPad -This is a plugin for [Kaleidoscope][fw], that adds a NumLock-specific LED +This is a plugin for [Kaleidoscope][fw], that adds a NumPad-specific LED effect, along with a way to toggle to a numpad layer, and apply the effect. [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/library.properties b/library.properties index 8db57a28..1155e73c 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Kaleidoscope-Numlock +name=Kaleidoscope-NumPad version=0.0.1 author=Jesse Vincent maintainer=Jesse Vincent -sentence=A Numlock plugin for Kaleidoscope. +sentence=A NumPad plugin for Kaleidoscope. paragraph=... category=Communication -url=https://github.com/keyboardio/Kaleidoscope-Numlock +url=https://github.com/keyboardio/Kaleidoscope-NumPad architectures=avr dot_a_linkage=true diff --git a/src/Kaleidoscope-Numlock.cpp b/src/Kaleidoscope-NumPad.cpp similarity index 79% rename from src/Kaleidoscope-Numlock.cpp rename to src/Kaleidoscope-NumPad.cpp index c7f2adf1..6ccb97fa 100644 --- a/src/Kaleidoscope-Numlock.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -1,18 +1,18 @@ -#include "Kaleidoscope-Numlock.h" +#include "Kaleidoscope-NumPad.h" #include "LEDUtils.h" #include "Kaleidoscope.h" #include "layers.h" -byte NumLock_::row = 255, NumLock_::col = 255; -uint8_t NumLock_::numPadLayer; -bool NumLock_::cleanupDone = true; +byte NumPad_::row = 255, NumPad_::col = 255; +uint8_t NumPad_::numPadLayer; +bool NumPad_::cleanupDone = true; cRGB numpad_color = CRGB(255, 0, 0); -void NumLock_::begin(void) { +void NumPad_::begin(void) { Kaleidoscope.useLoopHook(loopHook); } -void NumLock_::loopHook(bool postClear) { +void NumPad_::loopHook(bool postClear) { if (!postClear) return; @@ -27,7 +27,7 @@ void NumLock_::loopHook(bool postClear) { cleanupDone = false; bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); if (!numState) { - kaleidoscope::hid::pressKey(Key_KeypadNumLock); + kaleidoscope::hid::pressKey(Key_KeypadNumPad); kaleidoscope::hid::sendKeyboardReport(); } @@ -58,4 +58,4 @@ void NumLock_::loopHook(bool postClear) { LEDControl.setCrgbAt(row, col, color); } -NumLock_ NumLock; +NumPad_ NumPad; diff --git a/src/Kaleidoscope-Numlock.h b/src/Kaleidoscope-NumPad.h similarity index 76% rename from src/Kaleidoscope-Numlock.h rename to src/Kaleidoscope-NumPad.h index bf33aa5e..3d60b417 100644 --- a/src/Kaleidoscope-Numlock.h +++ b/src/Kaleidoscope-NumPad.h @@ -4,9 +4,9 @@ #include "Kaleidoscope-Macros.h" #include "LEDUtils.h" -class NumLock_ : public KaleidoscopePlugin { +class NumPad_ : public KaleidoscopePlugin { public: - NumLock_(void) {} + NumPad_(void) {} void begin(void) final; @@ -19,4 +19,4 @@ class NumLock_ : public KaleidoscopePlugin { static bool cleanupDone; }; -extern NumLock_ NumLock; +extern NumPad_ NumPad; From 1fb97c958bb2505c657a81c32135f1caa047a3a5 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 12 Nov 2017 23:22:03 -0800 Subject: [PATCH 449/792] That renaming was slightly over-aggressive --- src/Kaleidoscope-NumPad.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 6ccb97fa..c5ad13d1 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -27,7 +27,7 @@ void NumPad_::loopHook(bool postClear) { cleanupDone = false; bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); if (!numState) { - kaleidoscope::hid::pressKey(Key_KeypadNumPad); + kaleidoscope::hid::pressKey(Key_KeypadNumLock); kaleidoscope::hid::sendKeyboardReport(); } From 8b562fe64b6a1cea1717003622db3918695cd1a9 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 13 Nov 2017 12:49:38 -0800 Subject: [PATCH 450/792] Switch to a counter for 'cycles since last state change' This uses a bunch more ram, but it's much, much more flexible and the test mode is optional in user firmware. --- src/Kaleidoscope-Model01-TestMode.cpp | 73 ++++++++++++++------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index afaae36b..b7f00089 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -5,6 +5,13 @@ #include +#define CHATTER_CYCLE_LIMIT 2 +#define TOGGLED_OFF 2 +#define TOGGLED_ON 1 +#define HELD 3 +#define RELEASED 0 + + cRGB red; cRGB blue; cRGB green; @@ -73,8 +80,10 @@ uint32_t leftBadKeys; uint32_t rightBadKeys; -uint32_t olderLeftHandState = 0; -uint32_t olderRightHandState = 0 ; + +uint32_t cyclesSinceStateChange[64]; + + void TestMode_::testMatrix() { LEDControl.set_all_leds_to(200, 0, 0); @@ -87,69 +96,65 @@ void TestMode_::testMatrix() { for (byte col = 0; col < 8; col++) { uint8_t keynum = (row * 8) + (col); - uint8_t keyState = (bitRead(olderLeftHandState, keynum) << 2) | - (bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 1) | - (bitRead(KeyboardHardware.leftHandState.all, keynum) << 0); + uint8_t keyState = ((bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 1) | + (bitRead(KeyboardHardware.leftHandState.all, keynum) << 0)); + if ( keyState == TOGGLED_ON || keyState == TOGGLED_OFF ) { + if (cyclesSinceStateChange[keynum] < CHATTER_CYCLE_LIMIT) { + bitSet(leftBadKeys, keynum); + } + cyclesSinceStateChange[keynum] = 0; + } else { + cyclesSinceStateChange[keynum]++; - // If we had chatter in between two reads - if (keyState == 2 || keyState == 5) { - bitSet(leftBadKeys, keynum); - } + } + // If the key is held down - if (keyState == 7) { + if (keyState == HELD) { KeyboardHardware.setCrgbAt(row, 7 - col, green); } - // If we're seeing chatter right now - else if (keyState == 2 || keyState == 5) { - KeyboardHardware.setCrgbAt(row, 7 - col, white); - } - // If we triggered chatter detection ever on this key - else if (bitRead(leftBadKeys, keynum)) { + else if (bitRead(leftBadKeys, keynum) == 1) { KeyboardHardware.setCrgbAt(row, 7 - col, red); } // If the key was just released - else if (keyState == 6) { + else if (keyState == TOGGLED_OFF) { KeyboardHardware.setCrgbAt(row, 7 - col, blue); } - keyState = (bitRead(olderRightHandState, keynum) << 2) | - (bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 1) | - (bitRead(KeyboardHardware.rightHandState.all, keynum) << 0); + keyState = ((bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 1) | + (bitRead(KeyboardHardware.rightHandState.all, keynum) << 0)); - // If we had chatter in between two reads - if (keyState == 2 || keyState == 5) { - bitSet(rightBadKeys, keynum); - } + + if ( keyState == TOGGLED_ON || keyState == TOGGLED_OFF ) { + if (cyclesSinceStateChange[keynum+32] < CHATTER_CYCLE_LIMIT) { + bitSet(rightBadKeys, keynum); + } + cyclesSinceStateChange[keynum+32] = 0; + } else { + cyclesSinceStateChange[keynum+32]++; + } // If the key is held down - if (keyState == 7) { + if (keyState == HELD) { KeyboardHardware.setCrgbAt(row, 15 - col, green); } - // If we're seeing chatter right now - else if (keyState == 2 || keyState == 5) { - KeyboardHardware.setCrgbAt(row, 15 - col, white); - } - // If we triggered chatter detection ever on this key - else if (bitRead(rightBadKeys, keynum)) { + else if (bitRead(rightBadKeys, keynum) == 1 ) { KeyboardHardware.setCrgbAt(row, 15 - col, red); } // If the key was just released - else if (keyState == 6) { + else if (keyState == TOGGLED_OFF) { KeyboardHardware.setCrgbAt(row, 15 - col, blue); } } } LEDControl.syncLeds(); - olderRightHandState = KeyboardHardware.previousRightHandState.all; - olderLeftHandState = KeyboardHardware.previousLeftHandState.all; } } From 54cbf18e1c7d4dd71ae227c771b18b41f2de51f3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 13 Nov 2017 13:15:22 -0800 Subject: [PATCH 451/792] Only treat "key pressed down" events as issues for the debounce counter. That way, we can look for two presses a bit more easily with only one variable. --- src/Kaleidoscope-Model01-TestMode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index b7f00089..3edbb02e 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -99,7 +99,7 @@ void TestMode_::testMatrix() { uint8_t keyState = ((bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 1) | (bitRead(KeyboardHardware.leftHandState.all, keynum) << 0)); - if ( keyState == TOGGLED_ON || keyState == TOGGLED_OFF ) { + if ( keyState == TOGGLED_ON ) { if (cyclesSinceStateChange[keynum] < CHATTER_CYCLE_LIMIT) { bitSet(leftBadKeys, keynum); } @@ -130,7 +130,7 @@ void TestMode_::testMatrix() { (bitRead(KeyboardHardware.rightHandState.all, keynum) << 0)); - if ( keyState == TOGGLED_ON || keyState == TOGGLED_OFF ) { + if ( keyState == TOGGLED_ON) { if (cyclesSinceStateChange[keynum+32] < CHATTER_CYCLE_LIMIT) { bitSet(rightBadKeys, keynum); } From 5f9be8f8f037a6999d1daa8564210ad69fd2ee9c Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 13 Nov 2017 13:18:48 -0800 Subject: [PATCH 452/792] Clear the keyscan buffer starting to look for bounce events. --- src/Kaleidoscope-Model01-TestMode.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 3edbb02e..cb189943 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -87,6 +87,11 @@ uint32_t cyclesSinceStateChange[64]; void TestMode_::testMatrix() { LEDControl.set_all_leds_to(200, 0, 0); + // Clear out the key event buffer so we don't get messed up information from + // taps during LED test mode. + for(auto temp =0; temp<16; temp++) { + KeyboardHardware.readMatrix(); + } while (1) { KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { From d09ac4043d22381dbc63fdc0c22d718b876cb65e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 13 Nov 2017 13:20:41 -0800 Subject: [PATCH 453/792] Look for chatter across 15 scans, rather than just two. --- src/Kaleidoscope-Model01-TestMode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index cb189943..0f11ee61 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -5,7 +5,7 @@ #include -#define CHATTER_CYCLE_LIMIT 2 +#define CHATTER_CYCLE_LIMIT 15 #define TOGGLED_OFF 2 #define TOGGLED_ON 1 #define HELD 3 From b25e7e87e2090174e93ce65af77f4b321574f1d2 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 13 Nov 2017 13:28:26 -0800 Subject: [PATCH 454/792] Avoid a potential overflow bug --- src/Kaleidoscope-Model01-TestMode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 0f11ee61..863903bf 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -109,7 +109,7 @@ void TestMode_::testMatrix() { bitSet(leftBadKeys, keynum); } cyclesSinceStateChange[keynum] = 0; - } else { + } else if (cyclesSinceStateChange[keynum] <= CHATTER_CYCLE_LIMIT) { cyclesSinceStateChange[keynum]++; } @@ -140,7 +140,7 @@ void TestMode_::testMatrix() { bitSet(rightBadKeys, keynum); } cyclesSinceStateChange[keynum+32] = 0; - } else { + } else if (cyclesSinceStateChange[keynum+32] <= CHATTER_CYCLE_LIMIT) { cyclesSinceStateChange[keynum+32]++; } From a860afa765da1e4ce610feaf379e0c20cb22c091 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 13 Nov 2017 13:28:46 -0800 Subject: [PATCH 455/792] astyle. no function changes --- src/Kaleidoscope-Model01-TestMode.cpp | 44 +++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 863903bf..6a045625 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -8,7 +8,7 @@ #define CHATTER_CYCLE_LIMIT 15 #define TOGGLED_OFF 2 #define TOGGLED_ON 1 -#define HELD 3 +#define HELD 3 #define RELEASED 0 @@ -89,7 +89,7 @@ void TestMode_::testMatrix() { LEDControl.set_all_leds_to(200, 0, 0); // Clear out the key event buffer so we don't get messed up information from // taps during LED test mode. - for(auto temp =0; temp<16; temp++) { + for (auto temp = 0; temp < 16; temp++) { KeyboardHardware.readMatrix(); } while (1) { @@ -102,19 +102,19 @@ void TestMode_::testMatrix() { uint8_t keynum = (row * 8) + (col); uint8_t keyState = ((bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 1) | - (bitRead(KeyboardHardware.leftHandState.all, keynum) << 0)); + (bitRead(KeyboardHardware.leftHandState.all, keynum) << 0)); - if ( keyState == TOGGLED_ON ) { - if (cyclesSinceStateChange[keynum] < CHATTER_CYCLE_LIMIT) { - bitSet(leftBadKeys, keynum); - } - cyclesSinceStateChange[keynum] = 0; - } else if (cyclesSinceStateChange[keynum] <= CHATTER_CYCLE_LIMIT) { - cyclesSinceStateChange[keynum]++; + if (keyState == TOGGLED_ON) { + if (cyclesSinceStateChange[keynum] < CHATTER_CYCLE_LIMIT) { + bitSet(leftBadKeys, keynum); + } + cyclesSinceStateChange[keynum] = 0; + } else if (cyclesSinceStateChange[keynum] <= CHATTER_CYCLE_LIMIT) { + cyclesSinceStateChange[keynum]++; + + } - } - // If the key is held down if (keyState == HELD) { @@ -132,24 +132,24 @@ void TestMode_::testMatrix() { keyState = ((bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 1) | - (bitRead(KeyboardHardware.rightHandState.all, keynum) << 0)); + (bitRead(KeyboardHardware.rightHandState.all, keynum) << 0)); - if ( keyState == TOGGLED_ON) { - if (cyclesSinceStateChange[keynum+32] < CHATTER_CYCLE_LIMIT) { - bitSet(rightBadKeys, keynum); - } - cyclesSinceStateChange[keynum+32] = 0; - } else if (cyclesSinceStateChange[keynum+32] <= CHATTER_CYCLE_LIMIT) { - cyclesSinceStateChange[keynum+32]++; - } + if (keyState == TOGGLED_ON) { + if (cyclesSinceStateChange[keynum + 32] < CHATTER_CYCLE_LIMIT) { + bitSet(rightBadKeys, keynum); + } + cyclesSinceStateChange[keynum + 32] = 0; + } else if (cyclesSinceStateChange[keynum + 32] <= CHATTER_CYCLE_LIMIT) { + cyclesSinceStateChange[keynum + 32]++; + } // If the key is held down if (keyState == HELD) { KeyboardHardware.setCrgbAt(row, 15 - col, green); } // If we triggered chatter detection ever on this key - else if (bitRead(rightBadKeys, keynum) == 1 ) { + else if (bitRead(rightBadKeys, keynum) == 1) { KeyboardHardware.setCrgbAt(row, 15 - col, red); } From 952198a98af9a19174d9ba1ea73d8515a0f28ebb Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 13 Nov 2017 13:57:45 -0800 Subject: [PATCH 456/792] It appears that when the BIOS isn't reporting the keyboard LED state back to the keyboard, the old code resulted in sending far too many key reports. (Specifically, out of controll key repeat on OSX) --- src/Kaleidoscope-NumPad.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index c5ad13d1..ca7794aa 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -28,7 +28,6 @@ void NumPad_::loopHook(bool postClear) { bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); if (!numState) { kaleidoscope::hid::pressKey(Key_KeypadNumLock); - kaleidoscope::hid::sendKeyboardReport(); } LEDControl.set_mode(LEDControl.get_mode_index()); From c0a2b43c23c1bac64962d778d59a299405f3143c Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 13 Nov 2017 17:44:53 -0800 Subject: [PATCH 457/792] Slightly clean up our startup mode to be faster and more likely to eat extra keypresses --- src/Kaleidoscope-Model01-TestMode.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 6a045625..efd017b1 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -42,7 +42,10 @@ void TestMode_::loopHook(bool postClear) { } void TestMode_::waitForKeypress() { - delay(25); + for (auto temp = 0; temp < 16; temp++) { + KeyboardHardware.readMatrix(); + } + delay(2); while (1) { KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == R3C6 From 043ba2072b43cf8e82c366392fa4dfb9fa206c7e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 13 Nov 2017 17:45:26 -0800 Subject: [PATCH 458/792] Tweak our chatter timings to hopefully have fewer false positives --- src/Kaleidoscope-Model01-TestMode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index efd017b1..be805ae2 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -5,7 +5,7 @@ #include -#define CHATTER_CYCLE_LIMIT 15 +#define CHATTER_CYCLE_LIMIT 30 #define TOGGLED_OFF 2 #define TOGGLED_ON 1 #define HELD 3 @@ -175,7 +175,7 @@ void TestMode_::run_tests() { // Serial.println("Running tests"); toggle_programming_leds_on(); // Disable debouncing - KeyboardHardware.setKeyscanInterval(0); + KeyboardHardware.setKeyscanInterval(2); test_leds(); testMatrix(); // Serial.println("Done running tests"); From 5d53d77c6f3dc6962ddb9397c8107bdbeca4a059 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Fri, 17 Nov 2017 17:13:23 -0500 Subject: [PATCH 459/792] If layer is greater than max_layer, always fall back to EEPROM Current behaviour will make higher layers not work & always return Key_NoKey --- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index a8bd42bf..72ed86e6 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -54,7 +54,7 @@ Key EEPROMKeymap::getKeyOverride(uint8_t layer, byte row, byte col) { Key key; key = getKey(layer, row, col); - if (key == Key_Transparent) + if (key == Key_Transparent || layer >= max_layers_) key = Layer.getKeyFromPROGMEM(layer, row, col); return key; } From cc0d69ea2d482520cb8548183c06833a6faa7387 Mon Sep 17 00:00:00 2001 From: "James N. V. Cash" Date: Fri, 17 Nov 2017 17:17:55 -0500 Subject: [PATCH 460/792] Explain what max_layers should be set to in README --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3afc9628..9e247684 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,9 @@ The plugin provides the `EEPROMKeymap` object, which has the following methods: > Tells the extension to reserve space in EEPROM for up to `max` layers. Can > only be called once, any subsequent call will be a no-op. +> This should be set to the number of keymap layers you want to be +> able to program from EEPROM (probably the number of layers you have +> defined in your keymap). ## Focus commands From df72fb710f972f1e6e25aa6f9dfbe0e12be90f61 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 24 Nov 2017 23:23:15 +0100 Subject: [PATCH 461/792] Fix mouse keys getting occasionally stuck Instead of discrete press & release tracking, press the mousekey when the physical key is pressed, and like `Keyboard`, send & clear the report once per cycle, instead on every action. This fixes #10. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-MouseKeys.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 778e3eb6..a417f667 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -33,6 +33,8 @@ void MouseKeys_::scrollWheel(uint8_t keyCode) { void MouseKeys_::loopHook(bool postClear) { if (postClear) { + kaleidoscope::hid::sendMouseReport(); + kaleidoscope::hid::releaseAllMouseButtons(); mouseMoveIntent = 0; return; } @@ -76,7 +78,7 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS if (mappedKey.keyCode & KEY_MOUSE_BUTTON && !(mappedKey.keyCode & KEY_MOUSE_WARP)) { uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; - if (keyToggledOn(keyState)) { + if (keyIsPressed(keyState)) { MouseWrapper.pressButton(button); } else if (keyToggledOff(keyState)) { MouseWrapper.release_button(button); From 3005d9534e53757d5b00d04e46d5ce8753f4d224 Mon Sep 17 00:00:00 2001 From: SjB Date: Thu, 30 Nov 2017 11:09:13 -0500 Subject: [PATCH 462/792] Horizontal Mouse Scrolling Support in Kaleidoscope-Mousekeys using the new moveMouse function in kaleidoscope::hid we can have horizontal mouse scrolling. --- README.md | 4 +++- src/Kaleidoscope-MouseKeys.cpp | 4 ++++ src/MouseKeyDefs.h | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a0f82910..466609c4 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,9 @@ properties (see below). * `Key_mouseScrollUp`, `Key_mouseScrollDn`: Scroll the mouse wheel up or down, respectively. - +* `Key_mouseScrollL`, `Key_mouseScrollR`: Scroll the mouse wheel left or right, + respectively. + ### Buttons Buttons are even simpler than movement: there is no movement speed, nor diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 778e3eb6..88e26cb4 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -29,6 +29,10 @@ void MouseKeys_::scrollWheel(uint8_t keyCode) { kaleidoscope::hid::moveMouse(0, 0, wheelSpeed); else if (keyCode & KEY_MOUSE_DOWN) kaleidoscope::hid::moveMouse(0, 0, -wheelSpeed); + else if (keyCode & KEY_MOUSE_LEFT) + kaleidoscope::hid::moveMouse(0, 0, 0, -wheelSpeed); + else if (keyCode & KEY_MOUSE_RIGHT) + kaleidoscope::hid::moveMouse(0, 0, 0, wheelSpeed); } void MouseKeys_::loopHook(bool postClear) { diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index 9f5bdbc9..2a10af25 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -36,8 +36,8 @@ #define Key_mouseDnR (Key) { KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseScrollUp (Key) { KEY_MOUSE_WHEEL | KEY_MOUSE_UP, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseScrollDn (Key) { KEY_MOUSE_WHEEL | KEY_MOUSE_DOWN, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } -#define Key_mouseScrollL -#define Key_mouseScrollR +#define Key_mouseScrollL (Key) { KEY_MOUSE_WHEEL | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseScrollR (Key) { KEY_MOUSE_WHEEL | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseBtnL (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_L, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } #define Key_mouseBtnM (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_M, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } #define Key_mouseBtnR (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_R, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } From 631d028c5fffb0a3a879f66ef62398ec7e9adcc6 Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Thu, 7 Dec 2017 00:42:27 -0600 Subject: [PATCH 463/792] Backtick is ASCII 0x60, not 0x5F fixes #17 --- src/Kaleidoscope-Macros.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 1155ef46..39fa7dcd 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -103,7 +103,7 @@ static const Key ascii_to_key_map[] PROGMEM = { LSHIFT(Key_Slash), LSHIFT(Key_2), - // 0x5b ... 0x5f + // 0x5b ... 0x60 Key_LeftBracket, Key_Backslash, Key_RightBracket, @@ -148,7 +148,7 @@ Key Macros_::lookupAsciiCode(uint8_t ascii_code) { key.flags = SHIFT_HELD; key.keyCode = Key_A.keyCode + ascii_code - 0x41; break; - case 0x5B ... 0x5F: + case 0x5B ... 0x60: key.raw = pgm_read_word(&ascii_to_key_map[ascii_code - 0x5B + 23]); break; case 0x61 ... 0x7A: From 0cb4ac79705d29c4549d7bf29b3dfd862172cb5e Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Sat, 9 Dec 2017 00:05:35 -0600 Subject: [PATCH 464/792] Subtle change to key masking computation This doesn't change behaviour at all; it's just a different way to do the computation, which I think is much clearer. I also added an explanatory comment. * It's now all bitwise operations, without arithemetic thrown in. * It uses the same exact formula for finding bits on both sides of the keyboard. * It saves 14 bytes in program memory. --- src/Kaleidoscope-Hardware-Model01.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index cbf6d0c8..4459fbd9 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -204,14 +204,22 @@ void Model01::rebootBootloader() { // happens before the watchdog reboots us } +// In the maskKey(), unMaskKey(), and isKeyMasked() functions, we read and write bits in +// two bitfields -- one for each half of the keyboard. The fourth bit of the column number +// tells us which bitfield (right or left) to access, thus the "8" (B00001000). The row +// number tells us which element of the array to access. The last three bits of the column +// number tell us which of the eight bits to access, thus the "7" (B00000111), and we +// shift a bit starting from the left (B10000000, or 128) by that many places to get +// there. This is all nice and convenient because the keyboard has 64 keys, in symmetric +// halves, with eight keys per logical row. void Model01::maskKey(byte row, byte col) { if (row >= ROWS || col >= COLS) return; - if (col >= 8) { - rightHandMask.rows[row] |= 1 << (7 - (col - 8)); + if (col & 8) { + rightHandMask.rows[row] |= (128 >> (col & 7)); } else { - leftHandMask.rows[row] |= 1 << (7 - col); + leftHandMask.rows[row] |= (128 >> (col & 7)); } } @@ -219,10 +227,10 @@ void Model01::unMaskKey(byte row, byte col) { if (row >= ROWS || col >= COLS) return; - if (col >= 8) { - rightHandMask.rows[row] &= ~(1 << (7 - (col - 8))); + if (col & 8) { + rightHandMask.rows[row] &= ~(128 >> (col & 7)); } else { - leftHandMask.rows[row] &= ~(1 << (7 - col)); + leftHandMask.rows[row] &= ~(128 >> (col & 7)); } } @@ -230,10 +238,10 @@ bool Model01::isKeyMasked(byte row, byte col) { if (row >= ROWS || col >= COLS) return false; - if (col >= 8) { - return rightHandMask.rows[row] & (1 << (7 - (col - 8))); + if (col & 8) { + return rightHandMask.rows[row] & (128 >> (col & 7)); } else { - return leftHandMask.rows[row] & (1 << (7 - col)); + return leftHandMask.rows[row] & (128 >> (col & 7)); } } From 24d06c7168fa15cfe591ec4252a620824132f8c3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 9 Dec 2017 11:03:40 +0100 Subject: [PATCH 465/792] Initial import Fixes keyboardio/Kaleidoscope#217. Signed-off-by: Gergely Nagy --- .gitignore | 4 + .travis.yml | 21 + COPYING | 674 +++++++++++++++++++++++++++ Makefile | 14 + README.md | 68 +++ examples/MyOldFriend/MyOldFriend.ino | 52 +++ library.properties | 10 + src/Kaleidoscope-MyOldFriend.h | 21 + src/Kaleidoscope/MyOldFriend.cpp | 84 ++++ src/Kaleidoscope/MyOldFriend.h | 48 ++ 10 files changed, 996 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 COPYING create mode 100644 Makefile create mode 100644 README.md create mode 100644 examples/MyOldFriend/MyOldFriend.ino create mode 100644 library.properties create mode 100644 src/Kaleidoscope-MyOldFriend.h create mode 100644 src/Kaleidoscope/MyOldFriend.cpp create mode 100644 src/Kaleidoscope/MyOldFriend.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..be16c9be --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.#* +*~ +/hardware/ +/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..3e1f64d2 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Darwin) +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ +else +SKETCHBOOK_DIR ?= $(HOME)/Arduino +endif + +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md new file mode 100644 index 00000000..10a86b40 --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +# Kaleidoscope-MyOldFriend + +![status][st:experimental] [![Build Status][travis:image]][travis:status] + + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MyOldFriend.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MyOldFriend + + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + +> Hello darkness, my old friend +> I've come to talk with you again + +Support performing custom actions whenever the host suspends, resumes, or is +sleeping. By default, the LEDs will be turned off on suspend, and the previous +LED mode restored on resume. + +## Using the plugin + +To use the plugin, one needs to include the header, and activate it. No further +configuration is necessary, unless one wants to perform custom actions. + +```c++ +#include +#include + +void setup () { + Kaleidoscope.setup (); + + Kaleidoscope.use(&MyOldFriend); +} +``` + +## Plugin methods + +The plugin provides the `MyOldFriend` object, which has the following methods: + +### `.toggleLEDs(event)` + +> Turns LEDs off on suspend, restores the previous LED mode on resume. This is +> called by `myOldFriendEventHandler()` by default. + +## Overrideable methods + +### `myOldFriendEventHandler(event)` + +> The `myOldFriendEventHandler` method is the brain of the plugin: this function +> tells it what action to perform in response to the various events. +> +> Currently supported events are: `kaleidoscope::MyOldFriend::Suspend` is fired +> once when the host suspends; `kaleidoscope::MyOldFriend::Sleep` is fired every +> cycle while the host is suspended; `kaleidoscope::MyOldFriend::Resume` is +> fired once when the host wakes up. +> +> The default implementation calls `MyOldFriend.toggleLEDs`. When overriding the +> function, the default is lost. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-MyOldFriend/blob/master/examples/MyOldFriend/MyOldFriend.ino diff --git a/examples/MyOldFriend/MyOldFriend.ino b/examples/MyOldFriend/MyOldFriend.ino new file mode 100644 index 00000000..30c2937a --- /dev/null +++ b/examples/MyOldFriend/MyOldFriend.ino @@ -0,0 +1,52 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include +#include + +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + ( + Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_NoKey, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_NoKey + ), + +}; + +void setup() { + Kaleidoscope.setup(); + + Kaleidoscope.use(&MyOldFriend); +} + +void loop() { + Kaleidoscope.loop(); +} diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..41953ba1 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Kaleidoscope-MyOldFriend +version=0.0.0 +author=Gergely Nagy +maintainer=Gergely Nagy +sentence=Host sleep support library for Kaleidoscope. +paragraph=Turn LEDs off during host sleep, or do any other custom action. +category=Communication +url=https://github.com/keyboardio/Kaleidoscope-MyOldFriend +architectures=avr +dot_a_linkage=true diff --git a/src/Kaleidoscope-MyOldFriend.h b/src/Kaleidoscope-MyOldFriend.h new file mode 100644 index 00000000..e179d1d4 --- /dev/null +++ b/src/Kaleidoscope-MyOldFriend.h @@ -0,0 +1,21 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include diff --git a/src/Kaleidoscope/MyOldFriend.cpp b/src/Kaleidoscope/MyOldFriend.cpp new file mode 100644 index 00000000..589fef4e --- /dev/null +++ b/src/Kaleidoscope/MyOldFriend.cpp @@ -0,0 +1,84 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include +#include +#include +#include "LED-Off.h" + +// This is a terrible hack until Arduino#6964 gets implemented. +// It makes the `_usbSuspendState` symbol available to us. +extern u8 _usbSuspendState; + +namespace kaleidoscope { + +bool MyOldFriend::wasSuspended = false; +bool MyOldFriend::initialSuspend = true; + +void MyOldFriend::begin(void) { + Kaleidoscope.useLoopHook(loopHook); + Kaleidoscope.use(&::LEDOff); +} + +void MyOldFriend::toggleLEDs(MyOldFriend::Event event) { + static uint8_t prev_led_mode = 0; + + switch (event) { + case Suspend: + prev_led_mode = ::LEDControl.get_mode_index(); + ::LEDOff.activate(); + break; + case Resume: + ::LEDControl.set_mode(prev_led_mode); + ::LEDControl.refreshAll(); + break; + case Sleep: + break; + } +} + +void MyOldFriend::loopHook(bool post_clear) { + if (post_clear) + return; + + if ((_usbSuspendState & (1 << SUSPI))) { + if (!initialSuspend) { + if (!wasSuspended) { + wasSuspended = true; + myOldFriendEventHandler(Suspend); + } else { + myOldFriendEventHandler(Sleep); + } + } + } else { + if (initialSuspend) + initialSuspend = false; + if (wasSuspended) { + wasSuspended = false; + myOldFriendEventHandler(Resume); + } + } +} + +} + +__attribute__((weak)) void myOldFriendEventHandler(kaleidoscope::MyOldFriend::Event event) { + MyOldFriend.toggleLEDs(event); +} + +kaleidoscope::MyOldFriend MyOldFriend; diff --git a/src/Kaleidoscope/MyOldFriend.h b/src/Kaleidoscope/MyOldFriend.h new file mode 100644 index 00000000..cc4928a5 --- /dev/null +++ b/src/Kaleidoscope/MyOldFriend.h @@ -0,0 +1,48 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include + +namespace kaleidoscope { +class MyOldFriend : public KaleidoscopePlugin { + public: + typedef enum { + Suspend, + Sleep, + Resume, + } Event; + + MyOldFriend(void) {}; + + void begin(void) final; + + void toggleLEDs(Event event); + + private: + static bool wasSuspended; + static bool initialSuspend; + + static void loopHook(bool post_clear); +}; +} + +void myOldFriendEventHandler(kaleidoscope::MyOldFriend::Event event); + +extern kaleidoscope::MyOldFriend MyOldFriend; From 9a32ae987941c1f3e5cb4789db1319f8127b84b4 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 9 Dec 2017 11:15:04 +0100 Subject: [PATCH 466/792] Renamed a few private members to follow the style guide Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MyOldFriend.cpp | 18 +++++++++--------- src/Kaleidoscope/MyOldFriend.h | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Kaleidoscope/MyOldFriend.cpp b/src/Kaleidoscope/MyOldFriend.cpp index 589fef4e..1cf422b7 100644 --- a/src/Kaleidoscope/MyOldFriend.cpp +++ b/src/Kaleidoscope/MyOldFriend.cpp @@ -27,8 +27,8 @@ extern u8 _usbSuspendState; namespace kaleidoscope { -bool MyOldFriend::wasSuspended = false; -bool MyOldFriend::initialSuspend = true; +bool MyOldFriend::was_suspended_ = false; +bool MyOldFriend::initial_suspend_ = true; void MyOldFriend::begin(void) { Kaleidoscope.useLoopHook(loopHook); @@ -57,19 +57,19 @@ void MyOldFriend::loopHook(bool post_clear) { return; if ((_usbSuspendState & (1 << SUSPI))) { - if (!initialSuspend) { - if (!wasSuspended) { - wasSuspended = true; + if (!initial_suspend_) { + if (!was_suspended_) { + was_suspended_ = true; myOldFriendEventHandler(Suspend); } else { myOldFriendEventHandler(Sleep); } } } else { - if (initialSuspend) - initialSuspend = false; - if (wasSuspended) { - wasSuspended = false; + if (initial_suspend_) + initial_suspend_ = false; + if (was_suspended_) { + was_suspended_ = false; myOldFriendEventHandler(Resume); } } diff --git a/src/Kaleidoscope/MyOldFriend.h b/src/Kaleidoscope/MyOldFriend.h index cc4928a5..e49a7aaf 100644 --- a/src/Kaleidoscope/MyOldFriend.h +++ b/src/Kaleidoscope/MyOldFriend.h @@ -36,8 +36,8 @@ class MyOldFriend : public KaleidoscopePlugin { void toggleLEDs(Event event); private: - static bool wasSuspended; - static bool initialSuspend; + static bool was_suspended_; + static bool initial_suspend_; static void loopHook(bool post_clear); }; From 1ab0ae3347f366f912166a9bb0d0484e774a9448 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 9 Dec 2017 11:15:32 +0100 Subject: [PATCH 467/792] make astlye Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MyOldFriend.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Kaleidoscope/MyOldFriend.cpp b/src/Kaleidoscope/MyOldFriend.cpp index 1cf422b7..ae4d8edd 100644 --- a/src/Kaleidoscope/MyOldFriend.cpp +++ b/src/Kaleidoscope/MyOldFriend.cpp @@ -39,16 +39,16 @@ void MyOldFriend::toggleLEDs(MyOldFriend::Event event) { static uint8_t prev_led_mode = 0; switch (event) { - case Suspend: - prev_led_mode = ::LEDControl.get_mode_index(); - ::LEDOff.activate(); - break; - case Resume: - ::LEDControl.set_mode(prev_led_mode); - ::LEDControl.refreshAll(); - break; - case Sleep: - break; + case Suspend: + prev_led_mode = ::LEDControl.get_mode_index(); + ::LEDOff.activate(); + break; + case Resume: + ::LEDControl.set_mode(prev_led_mode); + ::LEDControl.refreshAll(); + break; + case Sleep: + break; } } From 2871b0697481f9152695260c2974031dcb0967d8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 9 Dec 2017 11:35:13 +0100 Subject: [PATCH 468/792] Add a way to pause LED modes Add LEDControl.paused, which we use to pause LED mode updates if true (defaults to false). This is useful when we want to stop LED modes from updating without switching to another (like when the host goes to sleep, and we want to turn LEDs off). Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 3 ++- src/Kaleidoscope-LEDControl.h | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index d170b76b..8f217e0d 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -7,6 +7,7 @@ LEDMode *LEDControl::modes[LED_MAX_MODES]; uint8_t LEDControl::mode; uint16_t LEDControl::syncDelay = 16; uint32_t LEDControl::syncTimer; +bool LEDControl::paused = false; void LEDMode::activate(void) { ::LEDControl.activate(this); @@ -123,7 +124,7 @@ Key LEDControl::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState } void LEDControl::loopHook(bool postClear) { - if (postClear) + if (postClear || paused) return; if (millis() > syncTimer) { diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index caae5406..7addcb3a 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -103,6 +103,9 @@ class LEDControl : public KaleidoscopePlugin { static uint8_t get_mode_index(); static LEDMode *get_mode(); static void refreshAll() { + if (paused) + return; + set_all_leds_to({0, 0, 0}); if (modes[mode]) modes[mode]->onActivate(); @@ -121,6 +124,7 @@ class LEDControl : public KaleidoscopePlugin { static void activate(LEDMode *mode); static uint16_t syncDelay; + static bool paused; static bool focusHook(const char *command); From 539aa85d6a88a4b913dbea2e694fa1faa110ea5c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 10 Dec 2017 00:39:57 +0100 Subject: [PATCH 469/792] Add a special `WakeupKeyboard`, to be able to wake the host up At least on Linux, for a device to be considered capable of waking the host up, it must be a boot keyboard. As we do not (yet) support a boot keyboard, we fake one. An USB node that does nothing else than report itself as a boot keyboard, and does the minimum amount of work to get recognised as such. Because of this, Linux - and hopefully the other OSes too - will consider the whole device capable of waking up the host. This addresses keyboardio/Kaleidoscope#237, if all goes well. Signed-off-by: Gergely Nagy --- README.md | 7 +++ examples/MyOldFriend/MyOldFriend.ino | 2 + src/Kaleidoscope/MyOldFriend.h | 2 + src/Kaleidoscope/WakeupKeyboard.cpp | 91 ++++++++++++++++++++++++++++ src/Kaleidoscope/WakeupKeyboard.h | 38 ++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 src/Kaleidoscope/WakeupKeyboard.cpp create mode 100644 src/Kaleidoscope/WakeupKeyboard.h diff --git a/README.md b/README.md index 10a86b40..21bebdf6 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,13 @@ void setup () { The plugin provides the `MyOldFriend` object, which has the following methods: +### `.enableWakeup()` + +> Enables host wakeup support. When enabled, pressing any key on the keyboard +> will wake the host up. +> +> Once enabled, it **cannot** be disabled again. + ### `.toggleLEDs(event)` > Turns LEDs off on suspend, restores the previous LED mode on resume. This is diff --git a/examples/MyOldFriend/MyOldFriend.ino b/examples/MyOldFriend/MyOldFriend.ino index 30c2937a..93c0ebc4 100644 --- a/examples/MyOldFriend/MyOldFriend.ino +++ b/examples/MyOldFriend/MyOldFriend.ino @@ -45,6 +45,8 @@ void setup() { Kaleidoscope.setup(); Kaleidoscope.use(&MyOldFriend); + + MyOldFriend.enableWakeup(); } void loop() { diff --git a/src/Kaleidoscope/MyOldFriend.h b/src/Kaleidoscope/MyOldFriend.h index e49a7aaf..93d939ea 100644 --- a/src/Kaleidoscope/MyOldFriend.h +++ b/src/Kaleidoscope/MyOldFriend.h @@ -19,6 +19,7 @@ #pragma once #include +#include "WakeupKeyboard.h" namespace kaleidoscope { class MyOldFriend : public KaleidoscopePlugin { @@ -32,6 +33,7 @@ class MyOldFriend : public KaleidoscopePlugin { MyOldFriend(void) {}; void begin(void) final; + void enableWakeup(void) { WakeupKeyboard.begin(); }; void toggleLEDs(Event event); diff --git a/src/Kaleidoscope/WakeupKeyboard.cpp b/src/Kaleidoscope/WakeupKeyboard.cpp new file mode 100644 index 00000000..74fad060 --- /dev/null +++ b/src/Kaleidoscope/WakeupKeyboard.cpp @@ -0,0 +1,91 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#include "WakeupKeyboard.h" + +static const uint8_t _hidReportDescriptorKeyboard[] PROGMEM = { + // Keyboard + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x06, /* USAGE (Keyboard) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ + + /* 0 LEDs, to have something the host can work with. */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x19, 0x00, /* USAGE_MINIMUM (-) */ + 0x29, 0x00, /* USAGE_MAXIMUM (-) */ + 0x95, 0x00, /* REPORT_COUNT (0) */ + 0x75, 0x00, /* REPORT_SIZE (0) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + + /* End */ + 0xc0 /* END_COLLECTION */ +}; + +WakeupKeyboard_::WakeupKeyboard_(void) : PluggableUSBModule(1, 1, epType) { + epType[0] = EP_TYPE_INTERRUPT_IN; + PluggableUSB().plug(this); +} + +int WakeupKeyboard_::getInterface(uint8_t* interfaceCount) { + *interfaceCount += 1; + HIDDescriptor hidInterface = { + D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_BOOT_INTERFACE, HID_PROTOCOL_KEYBOARD), + D_HIDREPORT(sizeof(_hidReportDescriptorKeyboard)), + D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) + }; + return USB_SendControl(0, &hidInterface, sizeof(hidInterface)); +} + +int WakeupKeyboard_::getDescriptor(USBSetup& setup) { + if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { + return 0; + } + if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { + return 0; + } + + if (setup.wIndex != pluggedInterface) { + return 0; + } + + return USB_SendControl(TRANSFER_PGM, _hidReportDescriptorKeyboard, sizeof(_hidReportDescriptorKeyboard)); +} + +bool WakeupKeyboard_::setup(USBSetup& setup) { + if (pluggedInterface != setup.wIndex) { + return false; + } + + uint8_t request = setup.bRequest; + uint8_t requestType = setup.bmRequestType; + + if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE) { + if (request == HID_GET_PROTOCOL) { + UEDATX = HID_BOOT_PROTOCOL; + return true; + } + } + + return false; +} + +void WakeupKeyboard_::begin () { +} + +WakeupKeyboard_ WakeupKeyboard; diff --git a/src/Kaleidoscope/WakeupKeyboard.h b/src/Kaleidoscope/WakeupKeyboard.h new file mode 100644 index 00000000..6b127f9b --- /dev/null +++ b/src/Kaleidoscope/WakeupKeyboard.h @@ -0,0 +1,38 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Copyright (C) 2017 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include +#include "PluggableUSB.h" +#include "HID.h" + +class WakeupKeyboard_ : public PluggableUSBModule, public KaleidoscopePlugin { + public: + WakeupKeyboard_(void); + void begin() final; + + protected: + int getInterface(uint8_t* interfaceCount); + int getDescriptor(USBSetup& setup); + bool setup(USBSetup& setup); + + uint8_t epType[1]; +}; + +extern WakeupKeyboard_ WakeupKeyboard; From 9dc2daddc51bb0854fb74e7756f1d937c24b9ef7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 10 Dec 2017 00:48:34 +0100 Subject: [PATCH 470/792] make astyle Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MyOldFriend.h | 4 +++- src/Kaleidoscope/WakeupKeyboard.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope/MyOldFriend.h b/src/Kaleidoscope/MyOldFriend.h index 93d939ea..8d619e21 100644 --- a/src/Kaleidoscope/MyOldFriend.h +++ b/src/Kaleidoscope/MyOldFriend.h @@ -33,7 +33,9 @@ class MyOldFriend : public KaleidoscopePlugin { MyOldFriend(void) {}; void begin(void) final; - void enableWakeup(void) { WakeupKeyboard.begin(); }; + void enableWakeup(void) { + WakeupKeyboard.begin(); + }; void toggleLEDs(Event event); diff --git a/src/Kaleidoscope/WakeupKeyboard.cpp b/src/Kaleidoscope/WakeupKeyboard.cpp index 74fad060..f9beafde 100644 --- a/src/Kaleidoscope/WakeupKeyboard.cpp +++ b/src/Kaleidoscope/WakeupKeyboard.cpp @@ -85,7 +85,7 @@ bool WakeupKeyboard_::setup(USBSetup& setup) { return false; } -void WakeupKeyboard_::begin () { +void WakeupKeyboard_::begin() { } WakeupKeyboard_ WakeupKeyboard; From 02a2a6c54adb327bffcca15c1e536d61349d5fe1 Mon Sep 17 00:00:00 2001 From: matt venn Date: Thu, 14 Dec 2017 18:55:33 +0100 Subject: [PATCH 471/792] fixed missing newline --- src/Kaleidoscope/EEPROM-Keymap.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 72ed86e6..a581c464 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -124,6 +124,7 @@ bool EEPROMKeymap::focusKeymapLayer(const char *command) { ::Focus.printSpace(); } } + Serial.println(); } else { uint16_t keysPerLayer = ROWS * COLS; uint16_t offset = layer * keysPerLayer; From d602988b95a37c3104ef530e1c72ea5eb965c5f0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 9 Dec 2017 11:38:57 +0100 Subject: [PATCH 472/792] Use LEDControl.paused instead of an implicit LEDOff Fixes #1. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MyOldFriend.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Kaleidoscope/MyOldFriend.cpp b/src/Kaleidoscope/MyOldFriend.cpp index ae4d8edd..ab0ad397 100644 --- a/src/Kaleidoscope/MyOldFriend.cpp +++ b/src/Kaleidoscope/MyOldFriend.cpp @@ -19,7 +19,6 @@ #include #include #include -#include "LED-Off.h" // This is a terrible hack until Arduino#6964 gets implemented. // It makes the `_usbSuspendState` symbol available to us. @@ -32,19 +31,17 @@ bool MyOldFriend::initial_suspend_ = true; void MyOldFriend::begin(void) { Kaleidoscope.useLoopHook(loopHook); - Kaleidoscope.use(&::LEDOff); } void MyOldFriend::toggleLEDs(MyOldFriend::Event event) { - static uint8_t prev_led_mode = 0; - switch (event) { case Suspend: - prev_led_mode = ::LEDControl.get_mode_index(); - ::LEDOff.activate(); + ::LEDControl.paused = true; + ::LEDControl.set_all_leds_to({0, 0, 0}); + ::LEDControl.syncLeds(); break; case Resume: - ::LEDControl.set_mode(prev_led_mode); + ::LEDControl.paused = false; ::LEDControl.refreshAll(); break; case Sleep: From 810a69cf3311f0801c031c2bb3d8e0e5f4d16487 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 16 Dec 2017 08:13:06 +0100 Subject: [PATCH 473/792] Rename the library to HostPowerManagement Signed-off-by: Gergely Nagy --- README.md | 32 +++++++++---------- .../HostPowerManagement.ino} | 8 ++--- library.properties | 8 ++--- ...d.h => Kaleidoscope-HostPowerManagement.h} | 4 +-- .../{MyOldFriend.h => HostPowerManagement.h} | 10 +++--- src/Kaleidoscope/MyOldFriend.cpp | 26 +++++++-------- src/Kaleidoscope/WakeupKeyboard.cpp | 4 +-- src/Kaleidoscope/WakeupKeyboard.h | 2 +- 8 files changed, 46 insertions(+), 48 deletions(-) rename examples/{MyOldFriend/MyOldFriend.ino => HostPowerManagement/HostPowerManagement.ino} (88%) rename src/{Kaleidoscope-MyOldFriend.h => Kaleidoscope-HostPowerManagement.h} (85%) rename src/Kaleidoscope/{MyOldFriend.h => HostPowerManagement.h} (78%) diff --git a/README.md b/README.md index 21bebdf6..17b1610e 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,14 @@ -# Kaleidoscope-MyOldFriend +# Kaleidoscope-HostPowerManagement ![status][st:experimental] [![Build Status][travis:image]][travis:status] - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MyOldFriend.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MyOldFriend + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-HostPowerManagement.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-HostPowerManagement [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 -> Hello darkness, my old friend -> I've come to talk with you again - Support performing custom actions whenever the host suspends, resumes, or is sleeping. By default, the LEDs will be turned off on suspend, and the previous LED mode restored on resume. @@ -23,18 +20,19 @@ configuration is necessary, unless one wants to perform custom actions. ```c++ #include -#include +#include void setup () { Kaleidoscope.setup (); - Kaleidoscope.use(&MyOldFriend); + Kaleidoscope.use(&HostPowerManagement); + HostPowerManagement.enableWakeup(); } ``` ## Plugin methods -The plugin provides the `MyOldFriend` object, which has the following methods: +The plugin provides the `HostPowerManagement` object, which has the following methods: ### `.enableWakeup()` @@ -46,21 +44,21 @@ The plugin provides the `MyOldFriend` object, which has the following methods: ### `.toggleLEDs(event)` > Turns LEDs off on suspend, restores the previous LED mode on resume. This is -> called by `myOldFriendEventHandler()` by default. +> called by `hostPowerManagementEventHandler()` by default. ## Overrideable methods -### `myOldFriendEventHandler(event)` +### `hostPowerManagementEventHandler(event)` -> The `myOldFriendEventHandler` method is the brain of the plugin: this function +> The `hostPowerManagementEventHandler` method is the brain of the plugin: this function > tells it what action to perform in response to the various events. > -> Currently supported events are: `kaleidoscope::MyOldFriend::Suspend` is fired -> once when the host suspends; `kaleidoscope::MyOldFriend::Sleep` is fired every -> cycle while the host is suspended; `kaleidoscope::MyOldFriend::Resume` is +> Currently supported events are: `kaleidoscope::HostPowerManagement::Suspend` is fired +> once when the host suspends; `kaleidoscope::HostPowerManagement::Sleep` is fired every +> cycle while the host is suspended; `kaleidoscope::HostPowerManagement::Resume` is > fired once when the host wakes up. > -> The default implementation calls `MyOldFriend.toggleLEDs`. When overriding the +> The default implementation calls `HostPowerManagement.toggleLEDs`. When overriding the > function, the default is lost. ## Dependencies @@ -72,4 +70,4 @@ The plugin provides the `MyOldFriend` object, which has the following methods: Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-MyOldFriend/blob/master/examples/MyOldFriend/MyOldFriend.ino + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-HostPowerManagement/blob/master/examples/HostPowerManagement/HostPowerManagement.ino diff --git a/examples/MyOldFriend/MyOldFriend.ino b/examples/HostPowerManagement/HostPowerManagement.ino similarity index 88% rename from examples/MyOldFriend/MyOldFriend.ino rename to examples/HostPowerManagement/HostPowerManagement.ino index 93c0ebc4..be96b3ce 100644 --- a/examples/MyOldFriend/MyOldFriend.ino +++ b/examples/HostPowerManagement/HostPowerManagement.ino @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Kaleidoscope-HostPowerManagement -- Host power management support plugin. * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ */ #include -#include +#include const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED @@ -44,9 +44,9 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { void setup() { Kaleidoscope.setup(); - Kaleidoscope.use(&MyOldFriend); + Kaleidoscope.use(&HostPowerManagement); - MyOldFriend.enableWakeup(); + HostPowerManagement.enableWakeup(); } void loop() { diff --git a/library.properties b/library.properties index 41953ba1..db622f9d 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Kaleidoscope-MyOldFriend +name=Kaleidoscope-HostPowerManagement version=0.0.0 author=Gergely Nagy maintainer=Gergely Nagy -sentence=Host sleep support library for Kaleidoscope. -paragraph=Turn LEDs off during host sleep, or do any other custom action. +sentence=Host power management support library for Kaleidoscope. +paragraph=Hooks to support host suspend & resume, and the ability to wake the host from the keyboard. category=Communication -url=https://github.com/keyboardio/Kaleidoscope-MyOldFriend +url=https://github.com/keyboardio/Kaleidoscope-HostPowerManagement architectures=avr dot_a_linkage=true diff --git a/src/Kaleidoscope-MyOldFriend.h b/src/Kaleidoscope-HostPowerManagement.h similarity index 85% rename from src/Kaleidoscope-MyOldFriend.h rename to src/Kaleidoscope-HostPowerManagement.h index e179d1d4..6b9a0251 100644 --- a/src/Kaleidoscope-MyOldFriend.h +++ b/src/Kaleidoscope-HostPowerManagement.h @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Kaleidoscope-HostPowerManagement -- Host power management support plugin. * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -18,4 +18,4 @@ #pragma once -#include +#include diff --git a/src/Kaleidoscope/MyOldFriend.h b/src/Kaleidoscope/HostPowerManagement.h similarity index 78% rename from src/Kaleidoscope/MyOldFriend.h rename to src/Kaleidoscope/HostPowerManagement.h index 8d619e21..de3c827b 100644 --- a/src/Kaleidoscope/MyOldFriend.h +++ b/src/Kaleidoscope/HostPowerManagement.h @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Kaleidoscope-HostPowerManagement -- Host power management support plugin. * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -22,7 +22,7 @@ #include "WakeupKeyboard.h" namespace kaleidoscope { -class MyOldFriend : public KaleidoscopePlugin { +class HostPowerManagement : public KaleidoscopePlugin { public: typedef enum { Suspend, @@ -30,7 +30,7 @@ class MyOldFriend : public KaleidoscopePlugin { Resume, } Event; - MyOldFriend(void) {}; + HostPowerManagement(void) {}; void begin(void) final; void enableWakeup(void) { @@ -47,6 +47,6 @@ class MyOldFriend : public KaleidoscopePlugin { }; } -void myOldFriendEventHandler(kaleidoscope::MyOldFriend::Event event); +void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event); -extern kaleidoscope::MyOldFriend MyOldFriend; +extern kaleidoscope::HostPowerManagement HostPowerManagement; diff --git a/src/Kaleidoscope/MyOldFriend.cpp b/src/Kaleidoscope/MyOldFriend.cpp index ab0ad397..2b4ee255 100644 --- a/src/Kaleidoscope/MyOldFriend.cpp +++ b/src/Kaleidoscope/MyOldFriend.cpp @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Kaleidoscope-HostPowerManagement -- Host power management support plugin. * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -17,7 +17,7 @@ */ #include -#include +#include #include // This is a terrible hack until Arduino#6964 gets implemented. @@ -26,14 +26,14 @@ extern u8 _usbSuspendState; namespace kaleidoscope { -bool MyOldFriend::was_suspended_ = false; -bool MyOldFriend::initial_suspend_ = true; +bool HostPowerManagement::was_suspended_ = false; +bool HostPowerManagement::initial_suspend_ = true; -void MyOldFriend::begin(void) { +void HostPowerManagement::begin(void) { Kaleidoscope.useLoopHook(loopHook); } -void MyOldFriend::toggleLEDs(MyOldFriend::Event event) { +void HostPowerManagement::toggleLEDs(HostPowerManagement::Event event) { switch (event) { case Suspend: ::LEDControl.paused = true; @@ -49,7 +49,7 @@ void MyOldFriend::toggleLEDs(MyOldFriend::Event event) { } } -void MyOldFriend::loopHook(bool post_clear) { +void HostPowerManagement::loopHook(bool post_clear) { if (post_clear) return; @@ -57,9 +57,9 @@ void MyOldFriend::loopHook(bool post_clear) { if (!initial_suspend_) { if (!was_suspended_) { was_suspended_ = true; - myOldFriendEventHandler(Suspend); + hostPowerManagementEventHandler(Suspend); } else { - myOldFriendEventHandler(Sleep); + hostPowerManagementEventHandler(Sleep); } } } else { @@ -67,15 +67,15 @@ void MyOldFriend::loopHook(bool post_clear) { initial_suspend_ = false; if (was_suspended_) { was_suspended_ = false; - myOldFriendEventHandler(Resume); + hostPowerManagementEventHandler(Resume); } } } } -__attribute__((weak)) void myOldFriendEventHandler(kaleidoscope::MyOldFriend::Event event) { - MyOldFriend.toggleLEDs(event); +__attribute__((weak)) void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event) { + HostPowerManagement.toggleLEDs(event); } -kaleidoscope::MyOldFriend MyOldFriend; +kaleidoscope::HostPowerManagement HostPowerManagement; diff --git a/src/Kaleidoscope/WakeupKeyboard.cpp b/src/Kaleidoscope/WakeupKeyboard.cpp index f9beafde..f75ecd63 100644 --- a/src/Kaleidoscope/WakeupKeyboard.cpp +++ b/src/Kaleidoscope/WakeupKeyboard.cpp @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Kaleidoscope-MyOldFriend -- Host power management support plugin. * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify @@ -85,7 +85,7 @@ bool WakeupKeyboard_::setup(USBSetup& setup) { return false; } -void WakeupKeyboard_::begin() { +void WakeupKeyboard_::begin () { } WakeupKeyboard_ WakeupKeyboard; diff --git a/src/Kaleidoscope/WakeupKeyboard.h b/src/Kaleidoscope/WakeupKeyboard.h index 6b127f9b..d1199ffa 100644 --- a/src/Kaleidoscope/WakeupKeyboard.h +++ b/src/Kaleidoscope/WakeupKeyboard.h @@ -1,5 +1,5 @@ /* -*- mode: c++ -*- - * Kaleidoscope-MyOldFriend -- Host sleep support plugin. + * Kaleidoscope-MyOldFriend -- Host power management support plugin. * Copyright (C) 2017 Gergely Nagy * * This program is free software: you can redistribute it and/or modify From c71b96c2334f47c432941623065c9224195821b6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 16 Dec 2017 08:20:20 +0100 Subject: [PATCH 474/792] make astyle Signed-off-by: Gergely Nagy --- src/Kaleidoscope/WakeupKeyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/WakeupKeyboard.cpp b/src/Kaleidoscope/WakeupKeyboard.cpp index f75ecd63..a1585584 100644 --- a/src/Kaleidoscope/WakeupKeyboard.cpp +++ b/src/Kaleidoscope/WakeupKeyboard.cpp @@ -85,7 +85,7 @@ bool WakeupKeyboard_::setup(USBSetup& setup) { return false; } -void WakeupKeyboard_::begin () { +void WakeupKeyboard_::begin() { } WakeupKeyboard_ WakeupKeyboard; From 5eca9b9a1f6ac6c64334596c6c861d0f99438840 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 16 Dec 2017 08:24:05 +0100 Subject: [PATCH 475/792] Forgot to rename a file, oops. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/{MyOldFriend.cpp => HostPowerManagement.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Kaleidoscope/{MyOldFriend.cpp => HostPowerManagement.cpp} (100%) diff --git a/src/Kaleidoscope/MyOldFriend.cpp b/src/Kaleidoscope/HostPowerManagement.cpp similarity index 100% rename from src/Kaleidoscope/MyOldFriend.cpp rename to src/Kaleidoscope/HostPowerManagement.cpp From c56c7791ba20084c6dbda269344d018f5e066782 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 16 Dec 2017 08:30:47 +0100 Subject: [PATCH 476/792] Do not provide toggleLEDs As this is a generic plugin, for keyboards that do not have LEDs, don't tie it to LEDControl, and don't provide a `toggleLEDs` method. Instead, show an example how to achieve the same thing from the sketch. Signed-off-by: Gergely Nagy --- README.md | 16 +++------------- .../HostPowerManagement/HostPowerManagement.ino | 17 +++++++++++++++++ src/Kaleidoscope/HostPowerManagement.cpp | 17 ----------------- src/Kaleidoscope/HostPowerManagement.h | 2 -- 4 files changed, 20 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 17b1610e..52b82866 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 Support performing custom actions whenever the host suspends, resumes, or is -sleeping. By default, the LEDs will be turned off on suspend, and the previous -LED mode restored on resume. +sleeping. Additionally, this plugin provides optional support for the keyboard +to wake the host up from suspend. ## Using the plugin @@ -41,11 +41,6 @@ The plugin provides the `HostPowerManagement` object, which has the following me > > Once enabled, it **cannot** be disabled again. -### `.toggleLEDs(event)` - -> Turns LEDs off on suspend, restores the previous LED mode on resume. This is -> called by `hostPowerManagementEventHandler()` by default. - ## Overrideable methods ### `hostPowerManagementEventHandler(event)` @@ -58,12 +53,7 @@ The plugin provides the `HostPowerManagement` object, which has the following me > cycle while the host is suspended; `kaleidoscope::HostPowerManagement::Resume` is > fired once when the host wakes up. > -> The default implementation calls `HostPowerManagement.toggleLEDs`. When overriding the -> function, the default is lost. - -## Dependencies - -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +> The default implementation is empty. ## Further reading diff --git a/examples/HostPowerManagement/HostPowerManagement.ino b/examples/HostPowerManagement/HostPowerManagement.ino index be96b3ce..0c498931 100644 --- a/examples/HostPowerManagement/HostPowerManagement.ino +++ b/examples/HostPowerManagement/HostPowerManagement.ino @@ -17,6 +17,7 @@ */ #include +#include #include const Key keymaps[][ROWS][COLS] PROGMEM = { @@ -41,6 +42,22 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { }; +void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event) { + switch (event) { + case kaleidoscope::HostPowerManagement::Suspend: + LEDControl.paused = true; + LEDControl.set_all_leds_to({0, 0, 0}); + LEDControl.syncLeds(); + break; + case kaleidoscope::HostPowerManagement::Resume: + LEDControl.paused = false; + LEDControl.refreshAll(); + break; + case kaleidoscope::HostPowerManagement::Sleep: + break; + } +} + void setup() { Kaleidoscope.setup(); diff --git a/src/Kaleidoscope/HostPowerManagement.cpp b/src/Kaleidoscope/HostPowerManagement.cpp index 2b4ee255..d91ddbf9 100644 --- a/src/Kaleidoscope/HostPowerManagement.cpp +++ b/src/Kaleidoscope/HostPowerManagement.cpp @@ -33,22 +33,6 @@ void HostPowerManagement::begin(void) { Kaleidoscope.useLoopHook(loopHook); } -void HostPowerManagement::toggleLEDs(HostPowerManagement::Event event) { - switch (event) { - case Suspend: - ::LEDControl.paused = true; - ::LEDControl.set_all_leds_to({0, 0, 0}); - ::LEDControl.syncLeds(); - break; - case Resume: - ::LEDControl.paused = false; - ::LEDControl.refreshAll(); - break; - case Sleep: - break; - } -} - void HostPowerManagement::loopHook(bool post_clear) { if (post_clear) return; @@ -75,7 +59,6 @@ void HostPowerManagement::loopHook(bool post_clear) { } __attribute__((weak)) void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event) { - HostPowerManagement.toggleLEDs(event); } kaleidoscope::HostPowerManagement HostPowerManagement; diff --git a/src/Kaleidoscope/HostPowerManagement.h b/src/Kaleidoscope/HostPowerManagement.h index de3c827b..79e321f1 100644 --- a/src/Kaleidoscope/HostPowerManagement.h +++ b/src/Kaleidoscope/HostPowerManagement.h @@ -37,8 +37,6 @@ class HostPowerManagement : public KaleidoscopePlugin { WakeupKeyboard.begin(); }; - void toggleLEDs(Event event); - private: static bool was_suspended_; static bool initial_suspend_; From 83a5518bed11c8ce9fd9e3679c39efb43053ba70 Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Mon, 18 Dec 2017 10:51:55 -0600 Subject: [PATCH 477/792] Use constants to better illustrate bitfield usage Binary notation and constants make it clearer how the bitfields are used to set the correct bit in the `*HandMask` structures. --- src/Kaleidoscope-Hardware-Model01.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 4459fbd9..e29aaea0 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -212,14 +212,20 @@ void Model01::rebootBootloader() { // shift a bit starting from the left (B10000000, or 128) by that many places to get // there. This is all nice and convenient because the keyboard has 64 keys, in symmetric // halves, with eight keys per logical row. + +constexpr byte HIGH_BIT = B10000000; +constexpr byte HAND_BIT = B00001000; +constexpr byte ROW_BITS = B00110000; +constexpr byte COL_BITS = B00000111; + void Model01::maskKey(byte row, byte col) { if (row >= ROWS || col >= COLS) return; - if (col & 8) { - rightHandMask.rows[row] |= (128 >> (col & 7)); + if (col & HAND_BIT) { + rightHandMask.rows[row] |= (HIGH_BIT >> (col & COL_BITS)); } else { - leftHandMask.rows[row] |= (128 >> (col & 7)); + leftHandMask.rows[row] |= (HIGH_BIT >> (col & COL_BITS)); } } @@ -227,10 +233,10 @@ void Model01::unMaskKey(byte row, byte col) { if (row >= ROWS || col >= COLS) return; - if (col & 8) { - rightHandMask.rows[row] &= ~(128 >> (col & 7)); + if (col & HAND_BIT) { + rightHandMask.rows[row] &= ~(HIGH_BIT >> (col & COL_BITS)); } else { - leftHandMask.rows[row] &= ~(128 >> (col & 7)); + leftHandMask.rows[row] &= ~(HIGH_BIT >> (col & COL_BITS)); } } @@ -238,10 +244,10 @@ bool Model01::isKeyMasked(byte row, byte col) { if (row >= ROWS || col >= COLS) return false; - if (col & 8) { - return rightHandMask.rows[row] & (128 >> (col & 7)); + if (col & HAND_BIT) { + return rightHandMask.rows[row] & (HIGH_BIT >> (col & COL_BITS)); } else { - return leftHandMask.rows[row] & (128 >> (col & 7)); + return leftHandMask.rows[row] & (HIGH_BIT >> (col & COL_BITS)); } } From c70dbd34da646ff8a2b004ac16b93f6a666933fa Mon Sep 17 00:00:00 2001 From: Florian Fleissner Date: Sat, 23 Dec 2017 13:50:26 +0100 Subject: [PATCH 478/792] Added macro arguments check to avoid problems with KEYMAP_STACKED and KEYMAP --- src/Kaleidoscope-Hardware-Model01.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 72a242a4..11d49426 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -5,6 +5,8 @@ #define HARDWARE_IMPLEMENTATION Model01 #include "KeyboardioScanner.h" +#include "macro_helpers.h" + #define COLS 16 #define ROWS 4 @@ -219,12 +221,12 @@ class Model01 { r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, \ r2c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, \ r3c8, r2c8, r1c8, r0c8, \ - r3c9) \ + r3c9, ...) \ { \ {r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c7, r0c8, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15}, \ {r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15}, \ {r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15}, \ - {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15}, \ + {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, RESTRICT_ARGS_COUNT((r3c15), 64, KEYMAP_STACKED, ##__VA_ARGS__)}, \ } #define KEYMAP( \ @@ -238,5 +240,5 @@ class Model01 { {r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c7, r0c8, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15}, \ {r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15}, \ {r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15}, \ - {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15}, \ + {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, RESTRICT_ARGS_COUNT((r3c15), 64, KEYMAP, ##__VA_ARGS__)}, \ } From 18b234cf7f4983e8733c56e12a6af086ad7561cf Mon Sep 17 00:00:00 2001 From: Florian Fleissner Date: Sat, 23 Dec 2017 13:56:07 +0100 Subject: [PATCH 479/792] Added missing varargs to KEYMAP(...) --- src/Kaleidoscope-Hardware-Model01.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 11d49426..70545f74 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -235,7 +235,7 @@ class Model01 { r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, \ r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r2c6, r2c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, \ r0c7, r1c7, r2c7, r3c7, r3c8, r2c8, r1c8, r0c8, \ - r3c6, r3c9) \ + r3c6, r3c9, ...) \ { \ {r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c7, r0c8, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15}, \ {r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15}, \ From 8ea55ff76f56601215b22f0ca5db1e7fdaca31ce Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Wed, 3 Jan 2018 16:12:07 -0800 Subject: [PATCH 480/792] added prev_mode --- src/Kaleidoscope-LEDControl.cpp | 10 ++++++++++ src/Kaleidoscope-LEDControl.h | 1 + 2 files changed, 11 insertions(+) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 8f217e0d..b955892d 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -34,6 +34,16 @@ void LEDControl::next_mode(void) { return set_mode(mode); } +void LEDControl::prev_mode(void) { + mode--; + + if (mode >= LED_MAX_MODES || !modes[mode]) { + return set_mode(0); + } + + return set_mode(mode); +} + void LEDControl::set_mode(uint8_t mode_) { if (mode_ >= LED_MAX_MODES) diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 7addcb3a..dcaf6fb9 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -90,6 +90,7 @@ class LEDControl : public KaleidoscopePlugin { void begin(void) final; static void next_mode(void); + static void prev_mode(void); static void setup(void); static void update(void) { if (modes[mode]) From 4d82db1f972968a3fade39d80e8ca0fb1d8e7bc4 Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Wed, 3 Jan 2018 20:33:03 -0800 Subject: [PATCH 481/792] better wrap-around --- src/Kaleidoscope-LEDControl.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index b955892d..3a9a0d53 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -35,13 +35,15 @@ void LEDControl::next_mode(void) { } void LEDControl::prev_mode(void) { - mode--; - - if (mode >= LED_MAX_MODES || !modes[mode]) { - return set_mode(0); + if (mode == 0) { + // wrap around + mode = LED_MAX_MODES; + // then count down until reaching a valid mode + while (mode > 0 && !modes[mode]) mode--; + } else { + mode--; } - - return set_mode(mode); + set_mode(mode); } void From e3f112affc62f2c51fc0b31bc40808a1a96324c9 Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Thu, 4 Jan 2018 10:21:30 -0800 Subject: [PATCH 482/792] fixed bug in wrap-around --- src/Kaleidoscope-LEDControl.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 3a9a0d53..21cbfca6 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -37,13 +37,14 @@ void LEDControl::next_mode(void) { void LEDControl::prev_mode(void) { if (mode == 0) { // wrap around - mode = LED_MAX_MODES; + mode = LED_MAX_MODES - 1; // then count down until reaching a valid mode while (mode > 0 && !modes[mode]) mode--; } else { mode--; } - set_mode(mode); + + return set_mode(mode); } void From e2d8866392cc020585fe77f2f584bc86e4cd2ff4 Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Tue, 9 Jan 2018 06:11:50 -0800 Subject: [PATCH 483/792] added Key_LEDEffectPrevious --- src/Kaleidoscope-LEDControl.cpp | 8 ++++++-- src/Kaleidoscope-LEDControl.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 21cbfca6..b7855c57 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -130,8 +130,12 @@ Key LEDControl::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) return mappedKey; - if (keyToggledOn(keyState)) - next_mode(); + if (keyToggledOn(keyState)) { + if (mappedKey == Key_LEDEffectNext) + next_mode(); + else + prev_mode(); + } return Key_NoKey; } diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index dcaf6fb9..a0f1327d 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -7,6 +7,7 @@ #define LED_TOGGLE B00000001 // Synthetic, internal #define Key_LEDEffectNext (Key) { 0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } +#define Key_LEDEffectPrevious (Key) { 1, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } namespace kaleidoscope { /** Base class for LED modes. From 795ef6c1f822401f0c370aae051acba48edcb74b Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Tue, 9 Jan 2018 06:14:41 -0800 Subject: [PATCH 484/792] compare the keyCode instead of the whole key struct --- src/Kaleidoscope-LEDControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index b7855c57..6f9b8be4 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -131,7 +131,7 @@ Key LEDControl::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState return mappedKey; if (keyToggledOn(keyState)) { - if (mappedKey == Key_LEDEffectNext) + if (mappedKey.keyCode == 0) next_mode(); else prev_mode(); From 4572cccd67cb4246170233f07082d4e7f360804c Mon Sep 17 00:00:00 2001 From: Nate Soares Date: Tue, 9 Jan 2018 08:00:28 -0800 Subject: [PATCH 485/792] effect hook only triggers on known Key_LEDEffect* keys --- src/Kaleidoscope-LEDControl.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 6f9b8be4..73b80b92 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -131,10 +131,11 @@ Key LEDControl::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState return mappedKey; if (keyToggledOn(keyState)) { - if (mappedKey.keyCode == 0) + if (mappedKey == Key_LEDEffectNext) { next_mode(); - else + } else if (mappedKey == Key_LEDEffectPrevious) { prev_mode(); + } } return Key_NoKey; From ac38d7241d279856c0fd711d334d8981bfa1eec4 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 4 Feb 2018 15:32:03 +0100 Subject: [PATCH 486/792] Pull in the KeyboardioHID HIDAdaptor library Instead of pulling it in from the user sketch, do so from the hardware plugin. The hardware and the adaptor are in close relationship anyway, and with tweakable knobs, we do not need to use a different adaptor library in advanced cases, either. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 72a242a4..0f02ac37 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -3,6 +3,7 @@ #include #define HARDWARE_IMPLEMENTATION Model01 +#include "Kaleidoscope-HIDAdaptor-KeyboardioHID.h" #include "KeyboardioScanner.h" #define COLS 16 From 8818ad51b738a17ac500713880d724efaa41f57d Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Mon, 5 Feb 2018 13:15:59 -0600 Subject: [PATCH 487/792] Fixed scan order bug Store any macros key events and play them after the event handler pass has finished, so we don't have a problem when holding other keys that are handled after the macro key in a pass. This fixes the problem where held modifiers wouldn't be applied to macros, and also fast repeating of printing characters. This change does introduce a limit (default: 8) on the number of concurrent macros that can be played. --- src/Kaleidoscope-Macros.cpp | 34 ++++++++++++++++++++++++++++------ src/Kaleidoscope-Macros.h | 25 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 39fa7dcd..276b952e 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -6,6 +6,8 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { return MACRO_NONE; } +MacroKeyEvent Macros_::active_macros[]; +byte Macros_::active_macro_count; byte Macros_::row, Macros_::col; void playMacroKeyswitchEvent(Key key, uint8_t flags) { @@ -181,24 +183,44 @@ const macro_t *Macros_::type(const char *string) { return MACRO_NONE; } -static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { +Key Macros_::handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) return mappedKey; - Macros_::row = row; - Macros_::col = col; - const macro_t *m = macroAction(mappedKey.keyCode, keyState); - - Macros.play(m); + byte key_id = (row * COLS) + col; + addActiveMacroKey(mappedKey.keyCode, key_id, keyState); return Key_NoKey; } +void Macros_::loopHook(bool post_clear) { + if (post_clear) { + active_macro_count = 0; + return; + } + + for (byte i = 0; i < active_macro_count; ++i) { + if (active_macros[i].key_id == 0xFF) { + // i.e. UNKNOWN_KEYSWITCH_LOCATION + row = 0xFF; + col = 0xFF; + } else { + row = active_macros[i].key_id / COLS; + col = active_macros[i].key_id % COLS; + } + const macro_t *m = macroAction(active_macros[i].key_code, + active_macros[i].key_state); + Macros.play(m); + } +} + Macros_::Macros_(void) { } void Macros_::begin(void) { + active_macro_count = 0; Kaleidoscope.useEventHandlerHook(handleMacroEvent); + Kaleidoscope.useLoopHook(loopHook); } Macros_ Macros; diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index d750f996..5c6d2658 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -7,12 +7,37 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); +#if !defined(MAX_CONCURRENT_MACROS) +#define MAX_CONCURRENT_MACROS 8 +#endif + +struct MacroKeyEvent { + byte key_code; + byte key_id; + byte key_state; +}; + class Macros_ : public KaleidoscopePlugin { public: Macros_(void); void begin(void) final; + static MacroKeyEvent active_macros[MAX_CONCURRENT_MACROS]; + static byte active_macro_count; + static void addActiveMacroKey(byte key_code, byte key_id, byte key_state) { + // If we've got too many active macros, give up: + if (active_macro_count >= MAX_CONCURRENT_MACROS) { + return; + } + active_macros[active_macro_count].key_code = key_code; + active_macros[active_macro_count].key_id = key_id; + active_macros[active_macro_count].key_state = key_state; + ++active_macro_count; + } + static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState); + static void loopHook(bool post_clear); + void play(const macro_t *macro_p); /* What follows below, is a bit of template magic that allows us to use From 088774089a5c9d05da23728ba9e9530f0e8212cb Mon Sep 17 00:00:00 2001 From: Iliana Weller Date: Tue, 13 Feb 2018 04:41:53 -0800 Subject: [PATCH 488/792] Enable focus command `led.mode p` --- src/Kaleidoscope-LEDControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 73b80b92..c62abe16 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -212,7 +212,7 @@ bool LEDControl::focusHook(const char *command) { next_mode(); Serial.read(); } else if (peek == 'p') { - // TODO(algernon) + prev_mode(); Serial.read(); } else { uint8_t mode = Serial.parseInt(); From 4f95cf8415ce1a018bd93cc0349b01f02050b2e6 Mon Sep 17 00:00:00 2001 From: tazlor Date: Fri, 16 Feb 2018 17:39:43 -0800 Subject: [PATCH 489/792] Reset bad keys before each test. Reset the bad key bitfields each time a test is started, so that each test starts from a clean slate. Without this, it was confusing to restart the test and get an ever-increasing number of keys to appear bad immediately. --- src/Kaleidoscope-Model01-TestMode.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index be805ae2..8973a74b 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -95,6 +95,9 @@ void TestMode_::testMatrix() { for (auto temp = 0; temp < 16; temp++) { KeyboardHardware.readMatrix(); } + // Reset bad keys from previous tests. + leftBadKeys = 0; + rgihtBadKeys = 0; while (1) { KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { From ea7454ddc22a596e05bbbe371212cc999bade5eb Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 20 Feb 2018 11:45:24 +0100 Subject: [PATCH 490/792] Correct a typo Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Model01-TestMode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 8973a74b..ae87e09d 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -97,7 +97,7 @@ void TestMode_::testMatrix() { } // Reset bad keys from previous tests. leftBadKeys = 0; - rgihtBadKeys = 0; + rightBadKeys = 0; while (1) { KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { From 1017cfd600cac605d73614382f9d46cd5df03d7f Mon Sep 17 00:00:00 2001 From: Evan Danaher Date: Thu, 22 Feb 2018 13:57:45 -0500 Subject: [PATCH 491/792] Send numlock keypress when disabling the numpad layer. This avoids the OS being stuck with Numlock on, which leaves the LED on if other keyboard are attached, and breaks FVWM. See keyboardio/Model01-Firmware#42 --- src/Kaleidoscope-NumPad.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index ca7794aa..c98d7776 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -12,6 +12,13 @@ void NumPad_::begin(void) { Kaleidoscope.useLoopHook(loopHook); } +static void syncNumlock(bool state) { + bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); + if (numState != state) { + kaleidoscope::hid::pressKey(Key_KeypadNumLock); + } +} + void NumPad_::loopHook(bool postClear) { if (!postClear) return; @@ -19,16 +26,14 @@ void NumPad_::loopHook(bool postClear) { if (!Layer.isOn(numPadLayer)) { if (!cleanupDone) { LEDControl.set_mode(LEDControl.get_mode_index()); + syncNumlock(false); cleanupDone = true; } return; } cleanupDone = false; - bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); - if (!numState) { - kaleidoscope::hid::pressKey(Key_KeypadNumLock); - } + syncNumlock(true); LEDControl.set_mode(LEDControl.get_mode_index()); From d5369288fb61011f2892d135b12f90f2a6144ec0 Mon Sep 17 00:00:00 2001 From: Marty Gentillon Date: Wed, 28 Feb 2018 22:48:20 -0800 Subject: [PATCH 492/792] NumPad now restores the former num lock state on deactivation. --- src/Kaleidoscope-NumPad.cpp | 9 +++++++++ src/Kaleidoscope-NumPad.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index ca7794aa..2e446a40 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -6,10 +6,12 @@ byte NumPad_::row = 255, NumPad_::col = 255; uint8_t NumPad_::numPadLayer; bool NumPad_::cleanupDone = true; +bool NumPad_::originalNumLockState = false; cRGB numpad_color = CRGB(255, 0, 0); void NumPad_::begin(void) { Kaleidoscope.useLoopHook(loopHook); + originalNumLockState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); } void NumPad_::loopHook(bool postClear) { @@ -17,10 +19,17 @@ void NumPad_::loopHook(bool postClear) { return; if (!Layer.isOn(numPadLayer)) { + bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); if (!cleanupDone) { LEDControl.set_mode(LEDControl.get_mode_index()); cleanupDone = true; + + if (numState && !originalNumLockState) { + kaleidoscope::hid::pressKey(Key_KeypadNumLock); + numState = false; + } } + originalNumLockState = numState; return; } diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index 3d60b417..1f3c9010 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -17,6 +17,7 @@ class NumPad_ : public KaleidoscopePlugin { static byte row, col; static bool cleanupDone; + static bool originalNumLockState; }; extern NumPad_ NumPad; From deb92d85dd509bd2dcbe6635bd5c09590343fb72 Mon Sep 17 00:00:00 2001 From: Maxime de Roucy Date: Sun, 4 Mar 2018 19:32:15 +0100 Subject: [PATCH 493/792] Don't enable LED on Key_NoKey --- src/Kaleidoscope-NumPad.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index ca7794aa..269db35d 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -42,7 +42,7 @@ void NumPad_::loopHook(bool postClear) { col = c; } - if ((k != layer_key) || (k.flags != KEY_FLAGS)) { + if ((k != layer_key) || (k == Key_NoKey) || (k.flags != KEY_FLAGS)) { LEDControl.refreshAt(r, c); } else { LEDControl.setCrgbAt(r, c, numpad_color); From e59eef624625c3a238361e95a02e3ee7e45ab139 Mon Sep 17 00:00:00 2001 From: Ben Gemperline Date: Sat, 10 Mar 2018 15:25:12 -0700 Subject: [PATCH 494/792] Updates to BootGreeting to allow better user customization Allow user to specify custom boot greeting key by Key_* or by specific row and column. Add ability to define custom duration of boot greet breathing effect, and add ability to change color hue of breathing effect. Finally, rework logic that happens when plugin is loaded to allow all user custom settings to be properly read and applied as expected. add hue to the header Updated readme to support new features astyle + change to allow custom settings --- README.md | 103 +++++++++++++++++++- src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 40 +++++++- src/Kaleidoscope-LEDEffect-BootGreeting.h | 8 ++ 3 files changed, 145 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4fd9ccaf..b3b578d7 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,108 @@ void setup() { } ``` -The plugin provides no methods or properties, the above is all it can do. +You may also set optional parameters. + +### Specify by search key +```c++ +#include +#include + +void setup() { + Kaleidoscope.use(&BootGreetingEffect, &LEDOff); + + BootGreetingEffect.search_key = Key_M; + + Kaleidoscope.setup(); +} +``` + +### Specify by position +```c++ +#include +#include + +void setup() { + Kaleidoscope.use(&BootGreetingEffect, &LEDOff); + + //Butterfly key + BootGreetingEffect.key_col = 7; + BootGreetingEffect.key_row = 3; + + Kaleidoscope.setup(); +} +``` + +### Specify longer timeout +```c++ +#include +#include + +void setup() { + Kaleidoscope.use(&BootGreetingEffect, &LEDOff); + + //Butterfly key + BootGreetingEffect.timeout = 15000; + + Kaleidoscope.setup(); +} +``` + +### Specify different color +```c++ +#include +#include + +void setup() { + Kaleidoscope.use(&BootGreetingEffect, &LEDOff); + + //Butterfly key + BootGreetingEffect.hue = 90; + + Kaleidoscope.setup(); +} +``` + +## Plugin methods + +The plugin provides the `BootGreetingEffect` object, with the following methods and +properties: + +### `.search_key` + +> Set the key in the current keymap that should be activated with the pulsing +> LED on startup. The plugin will search from the top left to the bottom right +> of the keyboard, row by row, to find this key. The first matching key will +> be selected. +> +> Defaults to `Key_LEDEffectNext` + +### `.key_row` + +> This is an optional override to explicitly set the selected key by exact row +> and column. This number is 0-indexed, so the top row is 0, the second row is +> 1, etc. Must set `.key_col` property for this feature to be enabled. + +### `.key_col` + +> This is an optional override to explicitly set the selected key by exact row +> and column. This number is 0-indexed, so the left-most column is 0, the +> second column is 1, etc. Must set `.key_row` property for this feature to +> be enabled. + +### `.timeout` + +> This property specifies the timeout (in milliseconds) for the effect to last. +> When the keyboard is first connected, the pulsing LED effect will last for +> this duration before turning off. +> +> Defaults to `9200` ms. + +### `.hue` + +> This property sets the color hue that the LED pulsing effect. +> +> The default is `170`, which is a blue color. ## Dependencies diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index 87c3749b..1e1f6e3a 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -21,19 +21,37 @@ namespace kaleidoscope { -bool BootGreetingEffect::done_; +bool BootGreetingEffect::done_ = false; byte BootGreetingEffect::row_; byte BootGreetingEffect::col_; +byte BootGreetingEffect::key_row = 255; +byte BootGreetingEffect::key_col = 255; +Key BootGreetingEffect::search_key = Key_LEDEffectNext; +uint8_t BootGreetingEffect::hue = 170; +uint16_t BootGreetingEffect::start_time = 0; +uint16_t BootGreetingEffect::timeout = 9200; + +BootGreetingEffect::BootGreetingEffect(byte pos_row, byte pos_col) { + key_row = pos_row; + key_col = pos_col; +} void BootGreetingEffect::begin(void) { + //Use the loop hook Kaleidoscope.useLoopHook(loopHook); +} +void BootGreetingEffect::findLed(void) { // Find the LED key. for (uint8_t r = 0; r < ROWS; r++) { for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookupOnActiveLayer(r, c); - if (k == Key_LEDEffectNext) { + if ( + //If key row and col explicitly set, ignore the search key + (k.raw == search_key.raw && key_row == 255 && key_row == 255) + || (key_row != 255 && key_col != 255 && key_row == r && key_col == c) + ) { row_ = r; col_ = c; return; @@ -46,16 +64,28 @@ void BootGreetingEffect::begin(void) { } void BootGreetingEffect::loopHook(const bool post_clear) { - if (!post_clear || done_) + //If already done or we're not in a ready state, bail + if (!post_clear || done_) { return; + } + + //If the start time isn't set, set the start time and + //find the LEDs. + if (start_time == 0) { + start_time = millis(); + findLed(); + //the first time, don't do anything. + return; + } - if (millis() > 9200) { + //Only run for 'timeout' milliseconds + if ((millis() - start_time) > timeout) { done_ = true; ::LEDControl.refreshAt(row_, col_); return; } - cRGB color = breath_compute(); + cRGB color = breath_compute(hue); ::LEDControl.setCrgbAt(row_, col_, color); } } diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index acd48fdb..b252db8d 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -24,14 +24,22 @@ namespace kaleidoscope { class BootGreetingEffect : public KaleidoscopePlugin { public: BootGreetingEffect(void) {} + BootGreetingEffect(byte, byte); void begin(void) final; + static byte key_row; + static byte key_col; + static Key search_key; + static uint8_t hue; + static uint16_t timeout; private: static void loopHook(const bool post_clear); + static void findLed(void); static bool done_; static byte row_; static byte col_; + static uint16_t start_time; }; } From dcddb26fa0453ec99313358080895cfe06450848 Mon Sep 17 00:00:00 2001 From: Ben Gemperline Date: Sat, 10 Mar 2018 16:17:47 -0700 Subject: [PATCH 495/792] Add ability to change hue / saturation in breath_compute Allow the breath_compute function to take optional parameters for hue and saturation to allow for differently colored breath effects. --- src/LEDUtils.cpp | 13 ++++++++++++- src/LEDUtils.h | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp index 734771ce..d5831277 100644 --- a/src/LEDUtils.cpp +++ b/src/LEDUtils.cpp @@ -2,6 +2,16 @@ cRGB breath_compute() { + return breath_compute(170); +} + +cRGB +breath_compute(uint8_t hue) { + return breath_compute(hue, 255); +} + +cRGB +breath_compute(uint8_t hue, uint8_t saturation) { // This code is adapted from FastLED lib8tion.h as of dd5d96c6b289cb6b4b891748a4aeef3ddceaf0e6 // Eventually, we should consider just using FastLED @@ -17,9 +27,10 @@ breath_compute() { i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + 80; - return hsvToRgb(170, 255, i); + return hsvToRgb(hue, saturation, i); } +//For rgb to hsv, might take a look at: http://web.mit.edu/storborg/Public/hsvtorgb.c // From http://web.mit.edu/storborg/Public/hsvtorgb.c - talk to Scott about licensing diff --git a/src/LEDUtils.h b/src/LEDUtils.h index f49e6200..aaafe549 100644 --- a/src/LEDUtils.h +++ b/src/LEDUtils.h @@ -3,4 +3,6 @@ #include cRGB breath_compute(void); +cRGB breath_compute(uint8_t hue); +cRGB breath_compute(uint8_t hue, uint8_t saturation); cRGB hsvToRgb(uint16_t h, uint16_t s, uint16_t v); From e17869e1a10e58e91031027c77840e32fc1cb8c0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 14 Mar 2018 09:20:47 +0100 Subject: [PATCH 496/792] actOnMatrixScan: Optimize the idle case When there are no state changes, and no keys pressed on a row, instead of iterating through a byte bit-by-bit, just fire idle events without checking the bits. In all other cases, do the bit-walking like we did before. The reason this is useful is because bit-walking is costly, and slow. If we can avoid that, we win quite a lot of performance. Since rows being idle is the most common case on a keyboard, this is a huge net win. Even in the worst case, where no rows are idle, this is just one byte comparison and a branch slower than our previous implementation. As part of this optimization, `actOnHalfRow` was lifted out into its own function, to reduce code duplication. Many thanks to @gedankenexperimenter for the original idea! Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 30 +++++++++++++++++---------- src/Kaleidoscope-Hardware-Model01.h | 2 ++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index cbf6d0c8..90c9ef84 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -157,23 +157,31 @@ void Model01::readMatrix() { } } - +void Model01::actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos) { + if ((colState == colPrevState) && (colState == 0)) { + for (byte col = 0; col < 8; col++) { + handleKeyswitchEvent(Key_NoKey, row, startPos - col, 0); + } + } else { + for (byte col = 0; col < 8; col++) { + uint8_t keyState = (bitRead(colPrevState, col) << 0) | + (bitRead(colState, col) << 1); + handleKeyswitchEvent(Key_NoKey, row, startPos - col, keyState); + } + } +} void Model01::actOnMatrixScan() { for (byte row = 0; row < 4; row++) { - for (byte col = 0; col < 8; col++) { + uint8_t colState = leftHandState.rows[row]; + uint8_t colPrevState = previousLeftHandState.rows[row]; - uint8_t keynum = (row * 8) + (col); + actOnHalfRow(row, colState, colPrevState, 7); - uint8_t keyState = (bitRead(previousLeftHandState.all, keynum) << 0) | - (bitRead(leftHandState.all, keynum) << 1); - handleKeyswitchEvent(Key_NoKey, row, 7 - col, keyState); + colState = rightHandState.rows[row]; + colPrevState = previousRightHandState.rows[row]; - keyState = (bitRead(previousRightHandState.all, keynum) << 0) | - (bitRead(rightHandState.all, keynum) << 1); - - handleKeyswitchEvent(Key_NoKey, row, (15 - col), keyState); - } + actOnHalfRow(row, colState, colPrevState, 15); } } diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 0f02ac37..107e4435 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -55,6 +55,8 @@ class Model01 { keydata_t previousRightHandState; private: + static void actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos); + static bool isLEDChanged; static KeyboardioScanner leftHand; static KeyboardioScanner rightHand; From effa6eba153467edab35f4ae80a7fcfa31314bd0 Mon Sep 17 00:00:00 2001 From: Marty Gentillon Date: Wed, 14 Mar 2018 17:14:27 -0700 Subject: [PATCH 497/792] Numpad now properly restores the former numlock state on deactivation. Test procedure: 1. Make sure numlock is off on host machine. 2. Activate num layer. Confirm, numlock is now on. 3. Deactivate num layer. Confirm, numlock is now off. 4. Using another keyboard, activate numlock on host machine. 5. Activate num layer. Confirm, numlock is still on. 6. Deactivate num layer. Confirm, numlock is still on. Prior to this commit, step 6 resulted in numlock being off. see https://github.com/keyboardio/Kaleidoscope-NumPad/pull/2 broken https://github.com/keyboardio/Kaleidoscope-NumPad/pull/3 see https://github.com/keyboardio/Kaleidoscope-NumPad/issues/1 fixes https://github.com/keyboardio/Kaleidoscope-NumPad/issues/6 --- src/Kaleidoscope-NumPad.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 84b9eba2..08ed6c93 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -14,8 +14,12 @@ void NumPad_::begin(void) { originalNumLockState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); } +static bool getNumlockState() { + return !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); +} + static void syncNumlock(bool state) { - bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); + bool numState = getNumlockState(); if (numState != state) { kaleidoscope::hid::pressKey(Key_KeypadNumLock); } @@ -26,16 +30,15 @@ void NumPad_::loopHook(bool postClear) { return; if (!Layer.isOn(numPadLayer)) { - bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); + bool numState = getNumlockState(); if (!cleanupDone) { LEDControl.set_mode(LEDControl.get_mode_index()); - syncNumlock(false); - cleanupDone = true; - if (numState && !originalNumLockState) { - kaleidoscope::hid::pressKey(Key_KeypadNumLock); + if (!originalNumLockState) { + syncNumlock(false); numState = false; } + cleanupDone = true; } originalNumLockState = numState; return; From e6f7d2c74be698555321bc3d64eccbe6a761a6ea Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 15 Mar 2018 08:35:22 +0100 Subject: [PATCH 498/792] Further actOnMatrixScan optimizations In `actOnMatrixScan`, there is no need to use temporary variables, we can just pass the data directly to `actOnHalfRow`, and doing so makes the code easier to follow. In `actOnHalfRow`, we can further optimize things if instead of reading the Nth bit, we always read the first, and shift the byte at the end. All of these optimizations were done by @obra, I just wrote the commit message. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 90c9ef84..8e88f2da 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -164,24 +164,22 @@ void Model01::actOnHalfRow(byte row, byte colState, byte colPrevState, byte star } } else { for (byte col = 0; col < 8; col++) { - uint8_t keyState = (bitRead(colPrevState, col) << 0) | - (bitRead(colState, col) << 1); + // Build up the key state for row, col + uint8_t keyState = ((bitRead(colPrevState, 0) << 0) | + (bitRead(colState, 0) << 1)); handleKeyswitchEvent(Key_NoKey, row, startPos - col, keyState); + + // Throw away the data we've just used, so we can read the next column + colState = colState >> 1; + colPrevState = colPrevState >> 1; } } } void Model01::actOnMatrixScan() { for (byte row = 0; row < 4; row++) { - uint8_t colState = leftHandState.rows[row]; - uint8_t colPrevState = previousLeftHandState.rows[row]; - - actOnHalfRow(row, colState, colPrevState, 7); - - colState = rightHandState.rows[row]; - colPrevState = previousRightHandState.rows[row]; - - actOnHalfRow(row, colState, colPrevState, 15); + actOnHalfRow(row, leftHandState.rows[row], previousLeftHandState.rows[row], 7); + actOnHalfRow(row, rightHandState.rows[row], previousRightHandState.rows[row], 15); } } From 7213f7577a1fc011f0f4c598862f2acc08fa0a50 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 15 Mar 2018 09:32:31 +0100 Subject: [PATCH 499/792] actOnHalfRow: Do not handle events on fully idle positions When a keyswitch has been off in the previous cycle and is still off now, do not call `handleKeyswitchEvent` on it. As an extension, when the whole column is idle, skip the whole thing. In practice, handling fully idle keys is not useful. There are many plugins which explicitly look for this case and return early, because it isn't an interesting event. As such, not calling the event handler in this case makes sense, as we save not only a few needless checks in plugins, but our performance improves greatly too. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 8e88f2da..2fc7df61 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -158,16 +158,13 @@ void Model01::readMatrix() { } void Model01::actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos) { - if ((colState == colPrevState) && (colState == 0)) { - for (byte col = 0; col < 8; col++) { - handleKeyswitchEvent(Key_NoKey, row, startPos - col, 0); - } - } else { + if ((colState != colPrevState) || (colState != 0)) { for (byte col = 0; col < 8; col++) { // Build up the key state for row, col uint8_t keyState = ((bitRead(colPrevState, 0) << 0) | (bitRead(colState, 0) << 1)); - handleKeyswitchEvent(Key_NoKey, row, startPos - col, keyState); + if (keyState) + handleKeyswitchEvent(Key_NoKey, row, startPos - col, keyState); // Throw away the data we've just used, so we can read the next column colState = colState >> 1; From 468c2443a543a9f24251a7ab544a0f3d2f134efd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 27 Mar 2018 12:22:21 +0200 Subject: [PATCH 500/792] README.md: Drop the note about OS compatibility Since we switched to using a separate node for the absolute mouse, it works with all three major operating systems. For that reason, the note about OS compatibility is incorrect, and with this patch, we drop it. Reported by @noseglasses, thanks! Signed-off-by: Gergely Nagy --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 466609c4..379813cb 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Key_mouseBtnL, Key_mouseBtnR void setup() { Kaleidoscope.use(&MouseKeys); - + Kaleidoscope.setup (); } ``` @@ -79,7 +79,7 @@ properties (see below). respectively. * `Key_mouseScrollL`, `Key_mouseScrollR`: Scroll the mouse wheel left or right, respectively. - + ### Buttons Buttons are even simpler than movement: there is no movement speed, nor @@ -100,9 +100,6 @@ to the middle of it. To stop warping, use any other mouse key, or hit the "warp end" key. -This features works out of the box on Windows and OSX. On Linux, a patch exists, -but has not been finalised and merged yet. - The warping keys are the following: * `Key_mouseWarpNW`, `Key_mouseWarpNE`, `Key_mouseWarpSW`, `Key_mouseWarpSE`: From ac4aab534fb0cb4bd55670130564a4d4e7b7e3ec Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 27 Mar 2018 12:33:54 +0200 Subject: [PATCH 501/792] README.md: Updated to use the correct interfaces We no longer have a `KaleidoscopePlugins` namespace, and have to use `kaleidoscope` instead - lets do that. Noticed by Jordihs on the Keyboardio forums, thank you! Signed-off-by: Gergely Nagy --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fda4cc26..621fde69 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ a special function to handle the combos: #include #include -static const KaleidoscopePlugins::MagicCombo::combo_t magic_combos[] PROGMEM = { +static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { {R1C3 | R2C1 | R2C4 | R2C7, // left hand, R0C11 | R1C12 | R2C14 //right hand }, From e01c7106f63df6f63595eddf9fe7cacefd510017 Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Fri, 30 Mar 2018 15:44:18 +0200 Subject: [PATCH 502/792] Add Rainbow stalker effect There already exist 2 rainbow LED effects, this adds a third, using the LED-Stalker effect. When you press a key, the LED on that key will cycle through all the colors of the rainbow, independent of the colors of other keys. --- README.md | 4 ++++ src/Kaleidoscope/LED-Stalker.cpp | 13 +++++++++++++ src/Kaleidoscope/LED-Stalker.h | 7 +++++++ 3 files changed, 24 insertions(+) diff --git a/README.md b/README.md index dece8113..debffaa6 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,10 @@ The plugin provides the following effects: > A blazing trail of fire will follow our fingers! +### `Rainbow()` + +> Leave a rainbow behind, where your fingers has been! + ## Dependencies * [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 42c043d4..050fd28c 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -127,6 +127,19 @@ cRGB BlazingTrail::compute(uint8_t *step) { return color; } +// Rainbow +Rainbow::Rainbow(void) { +} + +cRGB Rainbow::compute(uint8_t *step) { + if (*step > 0) + *step -= 1; + else + *step = 0; + + return hsvToRgb(255 - *step, 255, *step); +} + } } diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 99caed29..6cf9b464 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -67,6 +67,13 @@ class BlazingTrail : public StalkerEffect::ColorComputer { cRGB compute(uint8_t *step) final; }; +class Rainbow : public StalkerEffect::ColorComputer { + public: + Rainbow(void); + + cRGB compute(uint8_t *step) final; +}; + } } From 9964a3ce709fa979f98e764f424182f98663acc3 Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Sun, 1 Apr 2018 13:17:44 -0500 Subject: [PATCH 503/792] Fixed syncTimer overflow condition This prevents an insignificant error, but it is more correct to handle the integer overflow instead of ignoring it. I've also changed syncTimer from a 32-bit to 16-bit integer, which results in a smaller code size, and changed the computation of the timeout slightly, so the LED update interval is always the same (we add `syncDelay` to the previous update's start time, not it's end time), rather than varying based on when LEDControl's `loopHook()` function is called relative to the last timeout. --- src/Kaleidoscope-LEDControl.cpp | 7 ++++--- src/Kaleidoscope-LEDControl.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index c62abe16..6bfaa842 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -6,7 +6,7 @@ namespace kaleidoscope { LEDMode *LEDControl::modes[LED_MAX_MODES]; uint8_t LEDControl::mode; uint16_t LEDControl::syncDelay = 16; -uint32_t LEDControl::syncTimer; +uint16_t LEDControl::syncTimer; bool LEDControl::paused = false; void LEDMode::activate(void) { @@ -145,9 +145,10 @@ void LEDControl::loopHook(bool postClear) { if (postClear || paused) return; - if (millis() > syncTimer) { + uint16_t current_time = millis(); + if ((current_time - syncTimer) > syncDelay) { syncLeds(); - syncTimer = millis() + syncDelay; + syncTimer += syncDelay; } update(); } diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index a0f1327d..f9aa47c9 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -131,7 +131,7 @@ class LEDControl : public KaleidoscopePlugin { static bool focusHook(const char *command); private: - static uint32_t syncTimer; + static uint16_t syncTimer; static LEDMode *modes[LED_MAX_MODES]; static uint8_t mode; From b370681111efce35838ef962d1ea187ed90b2157 Mon Sep 17 00:00:00 2001 From: Cy Rossignol Date: Mon, 2 Apr 2018 05:10:44 +0100 Subject: [PATCH 504/792] Fix warping while dragging the mouse Before this change, we couldn't use the full functionality of the plugin's warp feature to drag an item (by holding down a mouse button key). The plugin would reset the warp state during each scan cycle, so we could only warp the pointer to a cell in the top-level grid. This fix enables warping repeatedly into sub-cells while holding a mouse button. --- src/Kaleidoscope-MouseKeys.cpp | 6 ++++++ src/MouseWrapper.cpp | 8 +++++++- src/MouseWrapper.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 4455dde4..2e7de67e 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -83,6 +83,12 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; if (keyIsPressed(keyState)) { + // Reset warp state on initial mouse button key-down only so we can use + // warp keys to drag-and-drop: + if (keyToggledOn(keyState)) { + MouseWrapper.reset_warping(); + } + MouseWrapper.pressButton(button); } else if (keyToggledOff(keyState)) { MouseWrapper.release_button(button); diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 9476a237..54b361f3 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -24,11 +24,11 @@ void MouseWrapper_::begin(void) { void MouseWrapper_::pressButton(uint8_t button) { kaleidoscope::hid::pressMouseButtons(button); - end_warping(); } void MouseWrapper_::release_button(uint8_t button) { kaleidoscope::hid::releaseMouseButtons(button); + end_warping(); } void MouseWrapper_::warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width) { @@ -49,6 +49,12 @@ void MouseWrapper_::end_warping() { is_warping = false; } +void MouseWrapper_::reset_warping() { + if (is_warping == true) { + begin_warping(); + } +} + void MouseWrapper_::warp(uint8_t warp_cmd) { if (is_warping == false) { begin_warping(); diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 732d2af7..e16b7733 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -28,6 +28,7 @@ class MouseWrapper_ { static void begin(void); static void move(int8_t x, int8_t y); static void warp(uint8_t warp_cmd); + static void reset_warping(); static void pressButton(uint8_t button); static void release_button(uint8_t button); static uint8_t accelStep; From 3be78597837bbcba7e5010b8ef8a00e4b71e90c5 Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Mon, 2 Apr 2018 00:27:47 -0500 Subject: [PATCH 505/792] Slow down the chase to reflect the recent optimizations Really, this should probably use a timer, but simply changing the `chase_threshold` value is simpler for now. --- src/Kaleidoscope-LEDEffect-Chase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.h b/src/Kaleidoscope-LEDEffect-Chase.h index 1002b8ac..24da4d34 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.h +++ b/src/Kaleidoscope-LEDEffect-Chase.h @@ -16,7 +16,7 @@ class LEDChaseEffect : public LEDMode { int8_t chase_sign = 1; //negative values when it's going backwar uint8_t chase_pixels = 5; uint8_t current_chase_counter = 0; - static const uint8_t chase_threshold = 20; + static const uint8_t chase_threshold = 150; }; } From b908d2ec6996c36842e93650cb15d2d2a55e0280 Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Mon, 2 Apr 2018 00:34:07 -0500 Subject: [PATCH 506/792] Change the upper bound to match the lower bound This causes the red light to stop when in gets to the last key, rather than continuing on past the end of the array before turning around. --- src/Kaleidoscope-LEDEffect-Chase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp index c021b5a8..6bc3d5d0 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -10,7 +10,7 @@ void LEDChaseEffect::update(void) { ::LEDControl.setCrgbAt(pos, {0, 0, 0}); pos += chase_sign; - if (pos >= LED_COUNT || pos <= 0) { + if (pos >= (LED_COUNT - 1) || pos <= 0) { chase_sign = -chase_sign; } ::LEDControl.setCrgbAt(pos, {0, 0, 255}); From 1f2d32ed79d6386a3c578693cec7a16e235595bf Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Mon, 2 Apr 2018 01:22:21 -0500 Subject: [PATCH 507/792] Fix for all out of bounds LED addressing This is a somewhat unwieldy fix for all the out of bounds (attempted) array addressing at both ends. When `pos` goes out of bounds in either direction, the test is the same because it's an unsigned integer. However, after the change of direction, the trailing LED will still be out of bounds, so we check that every time we call `setCrgbAt()` for `pos2`. It's rather ugly, but it does ensure that we don't call `setCrgbAt()` with an out-of-bounds address. --- src/Kaleidoscope-LEDEffect-Chase.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp index 6bc3d5d0..a0346b98 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -6,15 +6,25 @@ void LEDChaseEffect::update(void) { return; } current_chase_counter = 0; - ::LEDControl.setCrgbAt(pos - (chase_sign * chase_pixels), {0, 0, 0}); + + byte pos2 = pos - (chase_sign * chase_pixels); + ::LEDControl.setCrgbAt(pos, {0, 0, 0}); + if (pos2 < LED_COUNT) + ::LEDControl.setCrgbAt(pos2, {0, 0, 0}); pos += chase_sign; - if (pos >= (LED_COUNT - 1) || pos <= 0) { + if (! (pos < LED_COUNT)) { chase_sign = -chase_sign; + pos += chase_sign; + pos2 = LED_COUNT; + } else { + pos2 += chase_sign; } + ::LEDControl.setCrgbAt(pos, {0, 0, 255}); - ::LEDControl.setCrgbAt(pos - (chase_sign * chase_pixels), {255, 0, 0}); + if (pos2 < LED_COUNT) + ::LEDControl.setCrgbAt(pos2, {255, 0, 0}); } } From bd4acf398424bd35c7a225fb8c4b9a03340d9619 Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Mon, 2 Apr 2018 19:42:12 -0500 Subject: [PATCH 508/792] Better explanation of the in-bounds code I also reversed the sense of the `if...else` block to make it easier to follow. --- src/Kaleidoscope-LEDEffect-Chase.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp index a0346b98..69fa7a05 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -2,26 +2,42 @@ namespace kaleidoscope { void LEDChaseEffect::update(void) { + // Check to see if it's time to change the positions of the red and blue lights if (current_chase_counter++ < chase_threshold) { return; } current_chase_counter = 0; + // The red LED is at `pos`; the blue one follows behind. `chase_sign` is either +1 or + // -1; `chase_pixels` is the gap between them. byte pos2 = pos - (chase_sign * chase_pixels); + // First, we turn off the LEDs that were turned on in the previous update. `pos` is + // always in the valid range (0 <= pos < LED_COUNT), but after it changes direction, for + // the first few updates, `pos2` will be out of bounds. Since it's an unsigned integer, + // even when it would have a value below zero, it underflows and so one test is good for + // both ends of the range. ::LEDControl.setCrgbAt(pos, {0, 0, 0}); if (pos2 < LED_COUNT) ::LEDControl.setCrgbAt(pos2, {0, 0, 0}); + // Next, we adjust the red light's position. If the direction hasn't changed (the red + // light isn't out of bounds), we also adjust the blue light's position to match the red + // one. If the new position puts it out of bounds, we reverse the direction, and bring + // it back in bounds. When this happens, the blue light "jumps" behind the red one, and + // will be out of bounds. The simplest way to do this is to assign it a value that is + // known to be invalid (LED_COUNT). pos += chase_sign; - if (! (pos < LED_COUNT)) { + if (pos < LED_COUNT) { + pos2 += chase_sign; + } else { chase_sign = -chase_sign; pos += chase_sign; pos2 = LED_COUNT; - } else { - pos2 += chase_sign; } + // Last, we turn on the LEDs at their new positions. As before, the blue light (pos2) is + // only set if it's in the valid LED range. ::LEDControl.setCrgbAt(pos, {0, 0, 255}); if (pos2 < LED_COUNT) ::LEDControl.setCrgbAt(pos2, {255, 0, 0}); From cef192646567e3c19d0fec0829653f18218a80be Mon Sep 17 00:00:00 2001 From: Michael Richters Date: Tue, 3 Apr 2018 23:28:23 -0500 Subject: [PATCH 509/792] Fixed brightness jump on overflow With the previous algorithm, once every 65 seconds, there would be a significant jump in the brightness of the "breathing" LEDs as the 16-bit value recorded from `millis()` overflowed. Instead of dividing by 12, I changed it to a bit shift (4 bits; equivalent to division by 16), so when the integer overflow occurs, the next value is what it should be. --- src/LEDUtils.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp index 734771ce..20c4f565 100644 --- a/src/LEDUtils.cpp +++ b/src/LEDUtils.cpp @@ -5,7 +5,9 @@ breath_compute() { // This code is adapted from FastLED lib8tion.h as of dd5d96c6b289cb6b4b891748a4aeef3ddceaf0e6 // Eventually, we should consider just using FastLED - uint8_t i = (uint16_t)millis() / 12; + // We do a bit shift here instead of division to ensure that there's no discontinuity + // in the output brightness when the integer overflows. + uint8_t i = (uint16_t)millis() >> 4; if (i & 0x80) { i = 255 - i; From 198e332e058d9efbc6fb1d78055690a007847ef3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 5 Apr 2018 10:24:29 +0200 Subject: [PATCH 510/792] breath_compute: Use default arguments instead of three methods Thanks to Michael Richters (@gedankenexperimenter) for the suggestion! Signed-off-by: Gergely Nagy --- src/LEDUtils.cpp | 10 ---------- src/LEDUtils.h | 4 +--- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp index 221c8802..72e6993d 100644 --- a/src/LEDUtils.cpp +++ b/src/LEDUtils.cpp @@ -1,15 +1,5 @@ #include "LEDUtils.h" -cRGB -breath_compute() { - return breath_compute(170); -} - -cRGB -breath_compute(uint8_t hue) { - return breath_compute(hue, 255); -} - cRGB breath_compute(uint8_t hue, uint8_t saturation) { // This code is adapted from FastLED lib8tion.h as of dd5d96c6b289cb6b4b891748a4aeef3ddceaf0e6 diff --git a/src/LEDUtils.h b/src/LEDUtils.h index aaafe549..d8d3d511 100644 --- a/src/LEDUtils.h +++ b/src/LEDUtils.h @@ -2,7 +2,5 @@ #include -cRGB breath_compute(void); -cRGB breath_compute(uint8_t hue); -cRGB breath_compute(uint8_t hue, uint8_t saturation); +cRGB breath_compute(uint8_t hue = 170, uint8_t saturation = 255); cRGB hsvToRgb(uint16_t h, uint16_t s, uint16_t v); From a407aa29b0a381e9ced9c3aa1afa9515c9e56c11 Mon Sep 17 00:00:00 2001 From: Cy Rossignol Date: Sun, 1 Apr 2018 00:58:48 +0100 Subject: [PATCH 511/792] Add an optional 9-sector-grid warp size This warp mode is similar to the navigation provided by some speech recognition software. A 9-cell grid may provide more precision and efficiency than the existing 4-cell warp mode. This adds some extra key definitions to support the additional sectors and enables a user to switch the grid size: MouseKeys.setWarpGridSize(MOUSE_WARP_GRID_3X3); Signed-off-by: Cy Rossignol --- README.md | 123 +++++++++++++++++++++++++++++++-- src/Kaleidoscope-MouseKeys.cpp | 8 ++- src/Kaleidoscope-MouseKeys.h | 3 + src/MouseKeyDefs.h | 5 ++ src/MouseWarpModes.h | 10 +++ src/MouseWrapper.cpp | 33 +++++---- src/MouseWrapper.h | 2 + 7 files changed, 163 insertions(+), 21 deletions(-) create mode 100644 src/MouseWarpModes.h diff --git a/README.md b/README.md index 379813cb..d4ee37a4 100644 --- a/README.md +++ b/README.md @@ -88,19 +88,65 @@ acceleration involved. One just presses them. * `Key_mouseBtnL`, `Key_mouseBtnM`, `Key_mouseBtnR`: The left, middle, and right mouse buttons, respectively. -### Warping +## Warping Warping is one of the most interesting features of the plugin, and is a feature unique to Kaleidoscope, as far as we can tell. The warping keys position the -mouse cursor within a quadrant of the screen on first press, and any subsequent -taps will warp within the previously selected quadrant. For example, pressing -the north-west warp key twice will first jump to the middle of the north-west -quadrant of your screen, then select the north-west quadrant of that, and jump -to the middle of it. +mouse cursor within a sector of the screen on first press, and any subsequent +taps will warp within the previously selected sector. For example, pressing the +north-west warp key twice will first jump to the middle of the north-west +sector of your screen, then select the north-west sector of that, and jump to +the middle of it. To stop warping, use any other mouse key, or hit the "warp end" key. -The warping keys are the following: +### Warp grid size + +The warp grid size determines how MouseKeys partitions the screen to select the +next position to jump to when pressing a warp key. The plugin provides two grid +sizes to choose from: a *2x2* grid that splits the screen into quadrants, and a +*3x3* grid with nine cells similar to a navigation feature included with some +speech recognition software. By default, the plugin splits the screen into the +2x2 grid. + +To change the warp grid size, call the plugin's `setWarpGridSize()` method: + +```c++ +MouseKeys.setWarpGridSize(MOUSE_WARP_GRID_3X3); +``` + +#### 2x2 grid + +As described above, MouseKeys warps the pointer using a grid model that reflects +locations on the screen. By default, the plugin uses a 2x2 grid. To understand +how warping works, examine this diagram of a screen split into that 2x2 grid: + + +-----------------------+-----------------------+ + | | | | + | G | tab | | + | | | | + |-----------+-----------| tab | + | | | | + | B | esc | | + | | | | + +-----------------------+-----------------------+ + | | | + | | | + | | | + | B | esc | + | | | + | | | + | | | + +-----------------------+-----------------------+ + +Each quadrant is labed with a key that, when pressed, moves the mouse pointer +to the center of that quadrant. With this layout, pressing G warps +the pointer to the top-left quadant. Then, the plugin "zooms" into that sector +with a smaller grid so that the next warp key pressed jumps the pointer more +precisely within the sector. In this case, if we press esc next, +the pointer warps to the bottom-right corner within that quadrant. + +The warping keys for the 2x2 grid are the following: * `Key_mouseWarpNW`, `Key_mouseWarpNE`, `Key_mouseWarpSW`, `Key_mouseWarpSE`: Warp towards the north-west, north-east, south-west, or south-east quadrants, @@ -109,6 +155,64 @@ The warping keys are the following: state. Using any of the warping keys after this will start from the whole screen again. +#### 3x3 grid + +A 3x3 warp grid assigns a key to each of nine sectors of the screen. The next +diagram shows a screen with a key label that warps to each sector. As we can +see, pressing W warps the pointer into the top-left sector, and +pressing V warps to the bottom-right corner within that sector: + + +-----------------+-----------------+-----------------+ + | W | E | R | | | + |-----+-----+-----| | | + | S | D | F | E | R | + |-----+-----+-----| | | + | X | C | V | | | + +-----------------+-----------------+-----------------+ + | | | | + | | | | + | S | D | F | + | | | | + | | | | + +-----------------+-----------------+-----------------+ + | | | | + | | | | + | X | C | V | + | | | | + | | | | + +-----------------+-----------------+-----------------+ + +To use a 3x3 warp grid, we may need to remap some keys. A suggested warp key +mapping is shown below on the left side of a keyboard with a QWERTY layout: + + W | E | R T A - End Warping (Key_mouseWarpEnd) + ---+---+--- W - Warp NW Sector (Key_mouseWarpNW) + A S | D | F G E - Warp N Sector (Key_mouseWarpN) + ---+---+--- R - Warp NE Sector (Key_mouseWarpNE) + X | C | V B S - Warp E Sector (Key_mouseWarpE) + D - Warp/Zoom Center (Key_mouseWarpIn) + F - Warp W Sector (Key_mouseWarpW) + K - Warp SE Sector (Key_mouseWarpSE) + C - Warp S Sector (Key_mouseWarpS) + V - Warp SW Sector (Key_mouseWarpSW) + T - Right Click (Key_mouseBtnR) + G - Left Click (Key_mouseBtnL) + B - Middle Click (Key_mouseBtnM) + +This example layout replaces the default directional mouse keys and sets the +warp keys in a comfortable position for a warp-only configuration. Of course, +a Kaleidoscope user may retain the directional keys and map the warp keys +elsewhere according to his or her liking. + +A 3x3 warp grid layout contains all of the keys from the 2x2 grid layout with +the following additions: + +* `Key_mouseWarpN`, `Key_mouseWarpE`, `Key_mouseWarpS`, `Key_mouseWarpW`: + Warp towards the north, east, south, and west sectors, respectively. +* `Key_mouseWarpIn`: Warp to the center sector of the grid. The plugin will + continue to "zoom" into center of the current cell with each consecutive + press of this key. + ## Plugin methods The plugin provides a `MouseKeys` object, with the following methods and @@ -137,3 +241,8 @@ properties available: > scrolling speed. The former, `.wheelSpeed`, controls the amount of ticks the > wheel shall scroll, and defaults to 1. The second, `.wheelDelay`, controls the > delay between two scroll events, and defaults to 50 milliseconds. + +### `.setWarpGridSize` + +> This method changes the size of the grid used for [warping](#warping). The +> following are valid sizes: `MOUSE_WARP_GRID_2X2`, `MOUSE_WARP_GRID_3X3` diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 4455dde4..6da6090b 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -19,6 +19,10 @@ uint32_t MouseKeys_::accelEndTime; uint32_t MouseKeys_::endTime; uint32_t MouseKeys_::wheelEndTime; +void MouseKeys_::setWarpGridSize(uint8_t grid_size) { + MouseWrapper.warp_grid_size = grid_size; +} + void MouseKeys_::scrollWheel(uint8_t keyCode) { if (millis() < wheelEndTime) return; @@ -102,10 +106,10 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS } } else if (keyToggledOn(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { - // we don't pass in the left and up values because those are the - // default, "no-op" conditionals MouseWrapper.warp(((mappedKey.keyCode & KEY_MOUSE_WARP_END) ? WARP_END : 0x00) | + ((mappedKey.keyCode & KEY_MOUSE_UP) ? WARP_UP : 0x00) | ((mappedKey.keyCode & KEY_MOUSE_DOWN) ? WARP_DOWN : 0x00) | + ((mappedKey.keyCode & KEY_MOUSE_LEFT) ? WARP_LEFT : 0x00) | ((mappedKey.keyCode & KEY_MOUSE_RIGHT) ? WARP_RIGHT : 0x00)); } } diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index 255a0888..78dbabe2 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -2,6 +2,7 @@ #include "Kaleidoscope.h" #include "MouseKeyDefs.h" +#include "MouseWarpModes.h" class MouseKeys_ : public KaleidoscopePlugin { public: @@ -16,6 +17,8 @@ class MouseKeys_ : public KaleidoscopePlugin { static uint8_t wheelSpeed; static uint16_t wheelDelay; + static void setWarpGridSize(uint8_t grid_size); + private: static uint8_t mouseMoveIntent; static uint32_t endTime; diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index 2a10af25..5f66a5d4 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -20,8 +20,13 @@ #define Key_mouseWarpNW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseWarpN (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseWarpNE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseWarpW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseWarpIn (Key) { KEY_MOUSE_WARP| KEY_MOUSE_UP | KEY_MOUSE_DOWN, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseWarpE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseWarpSW (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_LEFT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } +#define Key_mouseWarpS (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseWarpSE (Key) { KEY_MOUSE_WARP| KEY_MOUSE_DOWN | KEY_MOUSE_RIGHT, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } #define Key_mouseWarpEnd (Key) { KEY_MOUSE_WARP| KEY_MOUSE_WARP_END, KEY_FLAGS|SYNTHETIC|IS_MOUSE_KEY } diff --git a/src/MouseWarpModes.h b/src/MouseWarpModes.h new file mode 100644 index 00000000..6f2b28a4 --- /dev/null +++ b/src/MouseWarpModes.h @@ -0,0 +1,10 @@ +#pragma once + +// Warp modes determine how the plugin jumps the mouse pointer to a screen +// location when pressing a warp key. + + +// Grid Based - the constant represents the number of cells in a row or column: + +#define MOUSE_WARP_GRID_2X2 2 +#define MOUSE_WARP_GRID_3X3 3 diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 9476a237..100367bb 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -5,6 +5,7 @@ #include "MouseWrapper.h" #include "kaleidoscope/hid.h" +uint8_t MouseWrapper_::warp_grid_size = MOUSE_WARP_GRID_2X2; uint16_t MouseWrapper_::next_width; uint16_t MouseWrapper_::next_height; uint16_t MouseWrapper_::section_top; @@ -59,21 +60,29 @@ void MouseWrapper_::warp(uint8_t warp_cmd) { return; } - next_width = next_width / 2; - next_height = next_height / 2; + next_width /= warp_grid_size; + next_height /= warp_grid_size; - if (warp_cmd & WARP_UP) { -// Serial.print(" - up "); - } else if (warp_cmd & WARP_DOWN) { -// Serial.print(" - down "); - section_top = section_top + next_height; + // WARP_UP + WARP_DOWN means "zoom in" to center sector + if (warp_cmd & WARP_UP && warp_cmd & WARP_DOWN) { + section_left += next_width; + section_top += next_height; + + warp_jump(section_left, section_top, next_height, next_width); + + return; + } + + if (warp_cmd & WARP_DOWN) { + section_top += next_height * (warp_grid_size - 1); + } else if (!(warp_cmd & WARP_UP)) { + section_top += next_height; } - if (warp_cmd & WARP_LEFT) { - // Serial.print(" - left "); - } else if (warp_cmd & WARP_RIGHT) { - // Serial.print(" - right "); - section_left = section_left + next_width; + if (warp_cmd & WARP_RIGHT) { + section_left += next_width * (warp_grid_size - 1); + } else if (!(warp_cmd & WARP_LEFT)) { + section_left += next_width; } warp_jump(section_left, section_top, next_height, next_width); diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 732d2af7..8c6ee04f 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -1,6 +1,7 @@ #pragma once #include "Arduino.h" +#include "MouseWarpModes.h" // Warping commands @@ -32,6 +33,7 @@ class MouseWrapper_ { static void release_button(uint8_t button); static uint8_t accelStep; static uint8_t speedLimit; + static uint8_t warp_grid_size; private: static uint16_t next_width; From b18465033ebfe9eda2900960490e8c84cfdccc2b Mon Sep 17 00:00:00 2001 From: Ryan Anderson Date: Mon, 23 Apr 2018 11:33:33 +0100 Subject: [PATCH 512/792] Reset the acceleration timer each time it expires. Without this, once the timeout expires the first time, every time through the loop triggers acceleration, which rapidly becomes excessive. --- src/Kaleidoscope-MouseKeys.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 6da6090b..859dc669 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -62,8 +62,10 @@ void MouseKeys_::loopHook(bool postClear) { int8_t moveX = 0, moveY = 0; if (millis() >= accelEndTime) { - if (MouseWrapper.accelStep < 255 - accelSpeed) + if (MouseWrapper.accelStep < 255 - accelSpeed) { MouseWrapper.accelStep += accelSpeed; + } + accelEndTime = millis() + accelDelay; } if (mouseMoveIntent & KEY_MOUSE_UP) From 73d9997b5404c2565116e39df3606be54b9ca005 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 28 Apr 2018 06:07:43 +0200 Subject: [PATCH 513/792] Use timers instead of ticks to time when to update the effects Ticks depend on the speed of the main loop, and as such, are not a reliable way to time animations. For this reason, use proper timers instead. The update delay is set to 40ms, which appears to be a slow, relaxing animation, and should be roughly in the ballpark the tick-based timing was, before speeding up the main loop considerably. Fixes #3. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 10 ++++++---- src/Kaleidoscope-LEDEffect-Rainbow.h | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index 2de7618e..5fdbcc5f 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -3,10 +3,11 @@ namespace kaleidoscope { void LEDRainbowEffect::update(void) { - if (rainbow_current_ticks++ < rainbow_ticks) { + uint16_t now = millis(); + if ((now - rainbow_last_update) < rainbow_update_delay) { return; } else { - rainbow_current_ticks = 0; + rainbow_last_update = now; } cRGB rainbow = hsvToRgb(rainbow_hue, rainbow_saturation, rainbow_value); @@ -26,10 +27,11 @@ void LEDRainbowEffect::brightness(byte brightness) { // --------- void LEDRainbowWaveEffect::update(void) { - if (rainbow_current_ticks++ < rainbow_wave_ticks) { + uint16_t now = millis(); + if ((now - rainbow_last_update) < rainbow_update_delay) { return; } else { - rainbow_current_ticks = 0; + rainbow_last_update = now; } for (uint8_t i = 0; i < LED_COUNT; i++) { diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 98307109..e3a66210 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -15,8 +15,8 @@ class LEDRainbowEffect : public LEDMode { uint16_t rainbow_hue = 0; // stores 0 to 614 uint8_t rainbow_steps = 1; // number of hues we skip in a 360 range per update - uint16_t rainbow_current_ticks = 0; - uint16_t rainbow_ticks = 10; // delays between update + uint16_t rainbow_last_update = 0; + uint16_t rainbow_update_delay = 40; // delay between updates (ms) byte rainbow_saturation = 255; byte rainbow_value = 50; @@ -34,8 +34,8 @@ class LEDRainbowWaveEffect : public LEDMode { uint16_t rainbow_hue = 0; // stores 0 to 614 uint8_t rainbow_wave_steps = 1; // number of hues we skip in a 360 range per update - uint16_t rainbow_current_ticks = 0; - uint16_t rainbow_wave_ticks = 10; // delays between update + uint16_t rainbow_last_update = 0; + uint16_t rainbow_update_delay = 40; // delay between updates (ms) byte rainbow_saturation = 255; byte rainbow_value = 50; From 36333263effc36bd3c40e2d61ff0cd96a3cb760d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 29 Apr 2018 08:57:33 +0200 Subject: [PATCH 514/792] Improved step timeout calculation Use a timeout calculation method that is not affected by overflow, and also requires 16 bits less. This likely fixes #8. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.cpp | 7 ++++--- src/Kaleidoscope/LED-Stalker.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 050fd28c..5e667c3f 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -24,7 +24,7 @@ namespace kaleidoscope { uint8_t StalkerEffect::map_[ROWS][COLS]; StalkerEffect::ColorComputer *StalkerEffect::variant; uint16_t StalkerEffect::step_length = 50; -uint32_t StalkerEffect::step_end_time_; +uint16_t StalkerEffect::step_start_time_; void StalkerEffect::setup(void) { Kaleidoscope.useEventHandlerHook(eventHandlerHook); @@ -49,7 +49,8 @@ void StalkerEffect::update(void) { if (!variant) return; - bool time_out = millis() >= step_end_time_; + uint16_t now = millis(); + bool time_out = (now - step_start_time_) > step_length; for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { @@ -70,7 +71,7 @@ void StalkerEffect::update(void) { } if (time_out) - step_end_time_ = millis() + step_length; + step_start_time_ = now; } namespace stalker { diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 6cf9b464..1d867659 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -42,7 +42,7 @@ class StalkerEffect : public LEDMode { void update(void) final; private: - static uint32_t step_end_time_; + static uint16_t step_start_time_; static uint8_t map_[ROWS][COLS]; static Key eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state); From b144f626e4e6d98baae77f12d1247d00241909a0 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 30 Apr 2018 22:32:05 -0700 Subject: [PATCH 515/792] refactor to reuse some code and be a bit smarter about data. Saves 324 bytes of PROGMEM and 265 bytes of RAM --- src/Kaleidoscope-Model01-TestMode.cpp | 104 +++++++++----------------- src/Kaleidoscope-Model01-TestMode.h | 8 ++ 2 files changed, 43 insertions(+), 69 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index ae87e09d..ddd2f036 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -45,7 +45,6 @@ void TestMode_::waitForKeypress() { for (auto temp = 0; temp < 16; temp++) { KeyboardHardware.readMatrix(); } - delay(2); while (1) { KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == R3C6 @@ -75,29 +74,52 @@ void TestMode_::test_leds(void) { LEDRainbowEffect.update(); LEDControl.syncLeds(); } - // set all the keys to red + waitForKeypress(); } -uint32_t leftBadKeys; -uint32_t rightBadKeys; + +void TestMode_::handleKeyEvent(side_data_t *side, keydata_t oldState, keydata_t newState, uint8_t row, uint8_t col, uint8_t col_offset) { + uint8_t keynum = (row * 8) + (col); + + uint8_t keyState = ((bitRead(oldState.all, keynum) << 1) | + (bitRead(newState.all, keynum) << 0)); + if (keyState == TOGGLED_ON) { + if (side->cyclesSinceStateChange[keynum] < CHATTER_CYCLE_LIMIT) { + bitSet(side->badKeys, keynum); + } + side->cyclesSinceStateChange[keynum] = 0; + } else if (side->cyclesSinceStateChange[keynum] <= CHATTER_CYCLE_LIMIT) { + side->cyclesSinceStateChange[keynum]++; + } -uint32_t cyclesSinceStateChange[64]; + // If the key is held down + if (keyState == HELD) { + KeyboardHardware.setCrgbAt(row, col_offset - col, green); + } + // If we triggered chatter detection ever on this key + else if (bitRead(side->badKeys, keynum) == 1) { + KeyboardHardware.setCrgbAt(row, col_offset - col, red); + } + // If the key was just released + else if (keyState == TOGGLED_OFF) { + KeyboardHardware.setCrgbAt(row, col_offset - col, blue); + } +} void TestMode_::testMatrix() { + // Reset bad keys from previous tests. + side_data_t left = {{0}, 0}; + side_data_t right = {{0}, 0}; + + LEDControl.set_all_leds_to(200, 0, 0); // Clear out the key event buffer so we don't get messed up information from // taps during LED test mode. - for (auto temp = 0; temp < 16; temp++) { - KeyboardHardware.readMatrix(); - } - // Reset bad keys from previous tests. - leftBadKeys = 0; - rightBadKeys = 0; while (1) { KeyboardHardware.readMatrix(); if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { @@ -105,64 +127,8 @@ void TestMode_::testMatrix() { } for (byte row = 0; row < 4; row++) { for (byte col = 0; col < 8; col++) { - uint8_t keynum = (row * 8) + (col); - - uint8_t keyState = ((bitRead(KeyboardHardware.previousLeftHandState.all, keynum) << 1) | - (bitRead(KeyboardHardware.leftHandState.all, keynum) << 0)); - - if (keyState == TOGGLED_ON) { - if (cyclesSinceStateChange[keynum] < CHATTER_CYCLE_LIMIT) { - bitSet(leftBadKeys, keynum); - } - cyclesSinceStateChange[keynum] = 0; - } else if (cyclesSinceStateChange[keynum] <= CHATTER_CYCLE_LIMIT) { - cyclesSinceStateChange[keynum]++; - - } - - - - // If the key is held down - if (keyState == HELD) { - KeyboardHardware.setCrgbAt(row, 7 - col, green); - } - // If we triggered chatter detection ever on this key - else if (bitRead(leftBadKeys, keynum) == 1) { - KeyboardHardware.setCrgbAt(row, 7 - col, red); - } - - // If the key was just released - else if (keyState == TOGGLED_OFF) { - KeyboardHardware.setCrgbAt(row, 7 - col, blue); - } - - - keyState = ((bitRead(KeyboardHardware.previousRightHandState.all, keynum) << 1) | - (bitRead(KeyboardHardware.rightHandState.all, keynum) << 0)); - - - if (keyState == TOGGLED_ON) { - if (cyclesSinceStateChange[keynum + 32] < CHATTER_CYCLE_LIMIT) { - bitSet(rightBadKeys, keynum); - } - cyclesSinceStateChange[keynum + 32] = 0; - } else if (cyclesSinceStateChange[keynum + 32] <= CHATTER_CYCLE_LIMIT) { - cyclesSinceStateChange[keynum + 32]++; - } - - // If the key is held down - if (keyState == HELD) { - KeyboardHardware.setCrgbAt(row, 15 - col, green); - } - // If we triggered chatter detection ever on this key - else if (bitRead(rightBadKeys, keynum) == 1) { - KeyboardHardware.setCrgbAt(row, 15 - col, red); - } - - // If the key was just released - else if (keyState == TOGGLED_OFF) { - KeyboardHardware.setCrgbAt(row, 15 - col, blue); - } + handleKeyEvent(&left, KeyboardHardware.previousLeftHandState, KeyboardHardware.leftHandState, row, col, 7); + handleKeyEvent(&right, KeyboardHardware.previousRightHandState, KeyboardHardware.leftHandState, row, col, 15); } } LEDControl.syncLeds(); diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index ea15d1d0..27a700d4 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -5,6 +5,13 @@ #define TEST_MODE_KEY_COMBO (R0C0 | R0C6 | R3C6) + + +typedef struct { + uint8_t cyclesSinceStateChange[32]; + uint32_t badKeys; + +} side_data_t; class TestMode_ : public KaleidoscopePlugin { public: TestMode_(void); @@ -15,6 +22,7 @@ class TestMode_ : public KaleidoscopePlugin { static void test_leds(); static void testMatrix(); static void toggle_programming_leds_on(); + static void handleKeyEvent(side_data_t *side, keydata_t oldState, keydata_t newState, uint8_t row, uint8_t col, uint8_t col_offset); static void waitForKeypress(); static void loopHook(bool postClear); static void set_leds(uint8_t r, uint8_t g, uint8_t b); From 3dd86e34dd5be63871dcb02bf9fb87f1cf0cdd5e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 30 Apr 2018 23:02:03 -0700 Subject: [PATCH 516/792] Refactoring to save 44 more PROGMEM and 12 more RAM --- src/Kaleidoscope-Model01-TestMode.cpp | 37 ++++++++++++++------------- src/Kaleidoscope-Model01-TestMode.h | 2 +- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index ddd2f036..8086ae1d 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -12,22 +12,12 @@ #define RELEASED 0 -cRGB red; -cRGB blue; -cRGB green; -cRGB white; TestMode_::TestMode_(void) { } void TestMode_::begin(void) { - red.r = 201; - blue.b = 201; - green.g = 201; - white.r = 50; - white.g = 50; - white.b = 50; Kaleidoscope.useLoopHook(this->loopHook); } @@ -42,7 +32,7 @@ void TestMode_::loopHook(bool postClear) { } void TestMode_::waitForKeypress() { - for (auto temp = 0; temp < 16; temp++) { + for (uint8_t temp = 0; temp < 8; temp++) { KeyboardHardware.readMatrix(); } while (1) { @@ -54,21 +44,27 @@ void TestMode_::waitForKeypress() { } } -void TestMode_::set_leds(uint8_t r, uint8_t g, uint8_t b) { - LEDControl.set_all_leds_to(r, g, b); +void TestMode_::set_leds(cRGB color) { + LEDControl.set_all_leds_to(color); LEDControl.syncLeds(); waitForKeypress(); } void TestMode_::test_leds(void) { + cRGB red = { b:0, g:0, r: 201 } ; + cRGB blue = { b:201, g:0, r: 0 } ; + cRGB green = { b:0, g:201, r: 0 } ; + cRGB white = { b:50, g:50, r: 50 } ; + cRGB brightWhite = { b:160, g:160, r: 160 } ; + // make all the LEDs bright red - set_leds(200, 0, 0); + set_leds(red); // make all the LEDs bright green - set_leds(0, 200, 0); + set_leds(green); // make all the LEDs bright blue - set_leds(0, 0, 200); + set_leds(blue); // make all the LEDs bright white (1.6A) - set_leds(160, 160, 160); + set_leds(brightWhite); // rainbow for 10 seconds for (auto i = 0; i < 1000; i++) { LEDRainbowEffect.update(); @@ -80,10 +76,15 @@ void TestMode_::test_leds(void) { void TestMode_::handleKeyEvent(side_data_t *side, keydata_t oldState, keydata_t newState, uint8_t row, uint8_t col, uint8_t col_offset) { + + cRGB red = { b:0, g:0, r: 201 } ; + cRGB blue = { b:201, g:0, r: 0 } ; + cRGB green = { b:0, g:201, r: 0 } ; + uint8_t keynum = (row * 8) + (col); uint8_t keyState = ((bitRead(oldState.all, keynum) << 1) | - (bitRead(newState.all, keynum) << 0)); + (bitRead(newState.all, keynum) << 0)); if (keyState == TOGGLED_ON) { if (side->cyclesSinceStateChange[keynum] < CHATTER_CYCLE_LIMIT) { bitSet(side->badKeys, keynum); diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 27a700d4..fd95d017 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -25,7 +25,7 @@ class TestMode_ : public KaleidoscopePlugin { static void handleKeyEvent(side_data_t *side, keydata_t oldState, keydata_t newState, uint8_t row, uint8_t col, uint8_t col_offset); static void waitForKeypress(); static void loopHook(bool postClear); - static void set_leds(uint8_t r, uint8_t g, uint8_t b); + static void set_leds(cRGB color); }; extern TestMode_ TestMode; From eea0c8b47e043c29b2d39bb8eb77c4cb28cab3d2 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Mon, 30 Apr 2018 23:30:34 -0700 Subject: [PATCH 517/792] astyle --- src/Kaleidoscope-Model01-TestMode.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 8086ae1d..d5406526 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -51,11 +51,11 @@ void TestMode_::set_leds(cRGB color) { } void TestMode_::test_leds(void) { - cRGB red = { b:0, g:0, r: 201 } ; - cRGB blue = { b:201, g:0, r: 0 } ; - cRGB green = { b:0, g:201, r: 0 } ; - cRGB white = { b:50, g:50, r: 50 } ; - cRGB brightWhite = { b:160, g:160, r: 160 } ; + cRGB red = { b: 0, g: 0, r: 201 } ; + cRGB blue = { b: 201, g: 0, r: 0 } ; + cRGB green = { b: 0, g: 201, r: 0 } ; + cRGB white = { b: 50, g: 50, r: 50 } ; + cRGB brightWhite = { b: 160, g: 160, r: 160 } ; // make all the LEDs bright red set_leds(red); @@ -77,9 +77,9 @@ void TestMode_::test_leds(void) { void TestMode_::handleKeyEvent(side_data_t *side, keydata_t oldState, keydata_t newState, uint8_t row, uint8_t col, uint8_t col_offset) { - cRGB red = { b:0, g:0, r: 201 } ; - cRGB blue = { b:201, g:0, r: 0 } ; - cRGB green = { b:0, g:201, r: 0 } ; + cRGB red = { b: 0, g: 0, r: 201 } ; + cRGB blue = { b: 201, g: 0, r: 0 } ; + cRGB green = { b: 0, g: 201, r: 0 } ; uint8_t keynum = (row * 8) + (col); From 9b44d02e6e8083ebca9a04fbfb48422938ca3a9a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 1 May 2018 23:44:17 -0700 Subject: [PATCH 518/792] Typo fix --- src/Kaleidoscope-Model01-TestMode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index d5406526..d04425d2 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -129,7 +129,7 @@ void TestMode_::testMatrix() { for (byte row = 0; row < 4; row++) { for (byte col = 0; col < 8; col++) { handleKeyEvent(&left, KeyboardHardware.previousLeftHandState, KeyboardHardware.leftHandState, row, col, 7); - handleKeyEvent(&right, KeyboardHardware.previousRightHandState, KeyboardHardware.leftHandState, row, col, 15); + handleKeyEvent(&right, KeyboardHardware.previousRightHandState, KeyboardHardware.rightHandState, row, col, 15); } } LEDControl.syncLeds(); From b565dab6444a509bb78e974748d56f1d3330783f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 1 May 2018 23:44:32 -0700 Subject: [PATCH 519/792] pass by value to save some flash --- src/Kaleidoscope-Model01-TestMode.cpp | 10 +++++----- src/Kaleidoscope-Model01-TestMode.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index d04425d2..7846fa39 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -75,7 +75,7 @@ void TestMode_::test_leds(void) { -void TestMode_::handleKeyEvent(side_data_t *side, keydata_t oldState, keydata_t newState, uint8_t row, uint8_t col, uint8_t col_offset) { +void TestMode_::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset) { cRGB red = { b: 0, g: 0, r: 201 } ; cRGB blue = { b: 201, g: 0, r: 0 } ; @@ -83,8 +83,8 @@ void TestMode_::handleKeyEvent(side_data_t *side, keydata_t oldState, keydata_t uint8_t keynum = (row * 8) + (col); - uint8_t keyState = ((bitRead(oldState.all, keynum) << 1) | - (bitRead(newState.all, keynum) << 0)); + uint8_t keyState = ((bitRead(oldState->all, keynum) << 1) | + (bitRead(newState->all, keynum) << 0)); if (keyState == TOGGLED_ON) { if (side->cyclesSinceStateChange[keynum] < CHATTER_CYCLE_LIMIT) { bitSet(side->badKeys, keynum); @@ -128,8 +128,8 @@ void TestMode_::testMatrix() { } for (byte row = 0; row < 4; row++) { for (byte col = 0; col < 8; col++) { - handleKeyEvent(&left, KeyboardHardware.previousLeftHandState, KeyboardHardware.leftHandState, row, col, 7); - handleKeyEvent(&right, KeyboardHardware.previousRightHandState, KeyboardHardware.rightHandState, row, col, 15); + handleKeyEvent(&left, &(KeyboardHardware.previousLeftHandState), &(KeyboardHardware.leftHandState), row, col, 7); + handleKeyEvent(&right, &(KeyboardHardware.previousRightHandState), &(KeyboardHardware.rightHandState), row, col, 15); } } LEDControl.syncLeds(); diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index fd95d017..1fa7a1ff 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -22,7 +22,7 @@ class TestMode_ : public KaleidoscopePlugin { static void test_leds(); static void testMatrix(); static void toggle_programming_leds_on(); - static void handleKeyEvent(side_data_t *side, keydata_t oldState, keydata_t newState, uint8_t row, uint8_t col, uint8_t col_offset); + static void handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset); static void waitForKeypress(); static void loopHook(bool postClear); static void set_leds(cRGB color); From 435018eb6a7a40536746037a1216ec2af2ff966a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 9 May 2018 22:53:53 +0200 Subject: [PATCH 520/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 9 ++++++--- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 10 ++++++---- src/Kaleidoscope/EEPROM-Keymap.cpp | 9 +-------- src/Kaleidoscope/EEPROM-Keymap.h | 8 +++----- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 9e247684..ec8373da 100644 --- a/README.md +++ b/README.md @@ -40,12 +40,15 @@ We can then update the keymap via [Focus][plugin:focus]. #include #include +KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, + EEPROMKeymap, + Focus); + void setup() { Serial.begin(9600); - Kaleidoscope.use(&EEPROMKeymap, &Focus); - + Kaleidoscope.setup(); - + Focus.addHook(FOCUS_HOOK_KEYMAP); Focus.addHook(FOCUS_HOOK_KEYMAP_TRANSFER); diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index 1f3dd91d..5a1bb85c 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -20,6 +20,7 @@ #include #include +// *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED (Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, @@ -32,18 +33,19 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_skip), }; +// *INDENT-ON* + +KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, EEPROMKeymap, Focus); void setup() { Serial.begin(9600); - Kaleidoscope.use(&EEPROMKeymap, &Focus); - Kaleidoscope.setup(); Focus.addHook(FOCUS_HOOK_SETTINGS); diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index a581c464..015854ac 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -24,13 +24,6 @@ namespace kaleidoscope { uint16_t EEPROMKeymap::keymap_base_; uint8_t EEPROMKeymap::max_layers_; -EEPROMKeymap::EEPROMKeymap(void) { -} - -void EEPROMKeymap::begin(void) { - Kaleidoscope.use(&::EEPROMSettings); -} - void EEPROMKeymap::max_layers(uint8_t max) { max_layers_ = max; keymap_base_ = ::EEPROMSettings.requestSlice(max_layers_ * ROWS * COLS * 2); diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 66c89620..564fce98 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -22,14 +22,12 @@ #include namespace kaleidoscope { -class EEPROMKeymap : public KaleidoscopePlugin { +class EEPROMKeymap : public kaleidoscope::Plugin { public: - EEPROMKeymap(void); + EEPROMKeymap(void) {} static void max_layers(uint8_t max); - void begin(void) final; - static uint16_t keymap_base(void); static Key getKey(uint8_t layer, byte row, byte col); From 8e2721a1b0eccd9046cb85229f60273762962dc2 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 9 May 2018 22:53:56 +0200 Subject: [PATCH 521/792] Updated the README to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a2c6fcc6..652f986e 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,12 @@ To use the plugin, include the header, and tell the firmware to use either (or both!) of the effects: ```c++ +#include #include -void setup() { - Kaleidoscope.use(&LEDRainbowEffect, &LEDRainbowWaveEffect); +KALEIDOSCOPE_INIT_PLUGINS(LEDRainbowEffect, LEDRainbowWaveEffect); +void setup() { Kaleidoscope.setup(); } ``` From 673fe3c304ff57e952e4d6d3006b1bf40550953d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 9 May 2018 22:53:56 +0200 Subject: [PATCH 522/792] Updated the README to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 78e59e6b..7a123e75 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,13 @@ over and over again. Playful colors they are. To use the plugin, include the header, and tell the firmware to use it: ```c++ +#include #include -void setup() { - Kaleidoscope.use(&LEDChaseEffect); +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + LEDEffect-Chase); +void setup() { Kaleidoscope.setup(); } ``` From 82cc3246fa1d455f6fd2437c1abb4ca85591201b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 9 May 2018 22:53:56 +0200 Subject: [PATCH 523/792] Updated the README to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 69218c83..2c3743db 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,13 @@ Provides a breathing effect for the keyboard. Breathe in, breathe out. To use the plugin, include the header, and tell the firmware to use it: ```c++ +#include #include -void setup() { - Kaleidoscope.use(&LEDBreatheEffect); +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + LEDBreatheEffect); +void setup() { Kaleidoscope.setup(); } ``` From 94b7d139901b2602c9a1911bdb09885cd4bcbb9c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 12 May 2018 17:47:13 +0200 Subject: [PATCH 524/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 6 ++---- examples/EEPROM-Settings/EEPROM-Settings.ino | 10 ++++++---- src/Kaleidoscope/EEPROM-Settings.cpp | 18 +++++++++++++----- src/Kaleidoscope/EEPROM-Settings.h | 13 +++++++++---- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index cff535be..d2365de2 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,9 @@ static struct { bool someSettingFlag; } testSettings; -void setup () { - Kaleidoscope.use(&EEPROMSettings); - - /* Use other plugins that make use of the EEPROM */ +KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, /* Other plugins that use EEPROM... */); +void setup () { Kaleidoscope.setup(); settingsBase = EEPROMSettings.requestSlice(sizeof(testSettings)); diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino index 9c8db0b0..d01f8132 100644 --- a/examples/EEPROM-Settings/EEPROM-Settings.ino +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -19,6 +19,7 @@ #include #include +// *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED (Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, @@ -31,20 +32,21 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_skip), }; +// *INDENT-ON* + +KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings); void setup() { Serial.begin(9600); Kaleidoscope.setup(); - Kaleidoscope.use(&EEPROMSettings); - while (!Serial) { } diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 9037c701..83f4e11f 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -26,11 +26,9 @@ bool EEPROMSettings::is_valid_; bool EEPROMSettings::sealed_; uint16_t EEPROMSettings::next_start_ = sizeof(EEPROMSettings::settings); -EEPROMSettings::EEPROMSettings(void) { -} - -void EEPROMSettings::begin(void) { +EventHandlerResult EEPROMSettings::onSetup() { EEPROM.get(0, settings_); + return EventHandlerResult::OK; } bool EEPROMSettings::isValid(void) { @@ -65,6 +63,9 @@ uint16_t EEPROMSettings::requestSlice(uint16_t size) { if (sealed_) return 0; + Serial.print("requestSlice; size="); + Serial.println(size); + uint16_t start = next_start_; next_start_ += size; @@ -97,6 +98,13 @@ void EEPROMSettings::version(uint8_t ver) { update(); } +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void EEPROMSettings::begin() { + ::EEPROMSettings.onSetup(); +} +#endif + } kaleidoscope::EEPROMSettings EEPROMSettings; diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index b58f6536..1b8e483c 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -22,11 +22,11 @@ #include namespace kaleidoscope { -class EEPROMSettings : public KaleidoscopePlugin { +class EEPROMSettings : public kaleidoscope::Plugin { public: - EEPROMSettings(void); + EEPROMSettings(void) {} - void begin(void) final; + EventHandlerResult onSetup(); static void update(void); static bool isValid(void); @@ -39,6 +39,11 @@ class EEPROMSettings : public KaleidoscopePlugin { static uint16_t crc(void); static uint16_t used(void); +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: + void begin(); +#endif + private: static uint16_t next_start_; static bool is_valid_; From be659b40434ba3f17da48034d7246222509d95c0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 13 May 2018 09:57:43 +0200 Subject: [PATCH 525/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 45 ++++++++++++++------- src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 33 ++++++++++----- src/Kaleidoscope-LEDEffect-BootGreeting.h | 14 +++++-- 3 files changed, 63 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index b3b578d7..2c0c21aa 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,14 @@ To use the plugin, include the header, and tell `Kaleidoscope` to use the plugin ```c++ #include +#include #include -void setup() { - Kaleidoscope.use(&BootGreetingEffect, &LEDOff); +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); +void setup() { Kaleidoscope.setup(); } ``` @@ -32,55 +35,69 @@ You may also set optional parameters. ### Specify by search key ```c++ #include +#include #include +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); + void setup() { - Kaleidoscope.use(&BootGreetingEffect, &LEDOff); + Kaleidoscope.setup(); BootGreetingEffect.search_key = Key_M; - - Kaleidoscope.setup(); } ``` ### Specify by position ```c++ #include +#include #include +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); + void setup() { - Kaleidoscope.use(&BootGreetingEffect, &LEDOff); + Kaleidoscope.setup(); //Butterfly key BootGreetingEffect.key_col = 7; BootGreetingEffect.key_row = 3; - - Kaleidoscope.setup(); } ``` ### Specify longer timeout ```c++ #include +#include #include +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); + void setup() { - Kaleidoscope.use(&BootGreetingEffect, &LEDOff); + Kaleidoscope.setup(); //Butterfly key BootGreetingEffect.timeout = 15000; - - Kaleidoscope.setup(); } ``` ### Specify different color ```c++ #include +#include #include +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); + void setup() { - Kaleidoscope.use(&BootGreetingEffect, &LEDOff); + Kaleidoscope.setup(); //Butterfly key BootGreetingEffect.hue = 90; @@ -112,7 +129,7 @@ properties: ### `.key_col` > This is an optional override to explicitly set the selected key by exact row -> and column. This number is 0-indexed, so the left-most column is 0, the +> and column. This number is 0-indexed, so the left-most column is 0, the > second column is 1, etc. Must set `.key_row` property for this feature to > be enabled. @@ -128,7 +145,7 @@ properties: > This property sets the color hue that the LED pulsing effect. > -> The default is `170`, which is a blue color. +> The default is `170`, which is a blue color. ## Dependencies diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index 1e1f6e3a..348fb944 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -36,11 +36,6 @@ BootGreetingEffect::BootGreetingEffect(byte pos_row, byte pos_col) { key_col = pos_col; } -void BootGreetingEffect::begin(void) { - //Use the loop hook - Kaleidoscope.useLoopHook(loopHook); -} - void BootGreetingEffect::findLed(void) { // Find the LED key. for (uint8_t r = 0; r < ROWS; r++) { @@ -63,10 +58,10 @@ void BootGreetingEffect::findLed(void) { done_ = true; } -void BootGreetingEffect::loopHook(const bool post_clear) { +EventHandlerResult BootGreetingEffect::afterEachCycle() { //If already done or we're not in a ready state, bail - if (!post_clear || done_) { - return; + if (done_) { + return EventHandlerResult::OK; } //If the start time isn't set, set the start time and @@ -75,19 +70,35 @@ void BootGreetingEffect::loopHook(const bool post_clear) { start_time = millis(); findLed(); //the first time, don't do anything. - return; + return EventHandlerResult::OK; } //Only run for 'timeout' milliseconds if ((millis() - start_time) > timeout) { done_ = true; ::LEDControl.refreshAt(row_, col_); - return; + return EventHandlerResult::OK; } cRGB color = breath_compute(hue); ::LEDControl.setCrgbAt(row_, col_, color); + + return EventHandlerResult::OK; } + +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void BootGreetingEffect::begin() { + Kaleidoscope.useLoopHook(legacyLoopHook); +} + +void BootGreetingEffect::legacyLoopHook(bool is_post_clear) { + if (!is_post_clear) + return; + ::BootGreetingEffect.afterEachCycle(); +} +#endif + } kaleidoscope::BootGreetingEffect BootGreetingEffect; diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index b252db8d..92e4ace9 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -21,20 +21,26 @@ #include "Kaleidoscope-LEDControl.h" namespace kaleidoscope { -class BootGreetingEffect : public KaleidoscopePlugin { +class BootGreetingEffect : public kaleidoscope::Plugin { public: BootGreetingEffect(void) {} BootGreetingEffect(byte, byte); - void begin(void) final; static byte key_row; static byte key_col; static Key search_key; static uint8_t hue; static uint16_t timeout; + EventHandlerResult afterEachCycle(); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: + void begin(); + static void legacyLoopHook(bool is_post_clear); +#endif + private: - static void loopHook(const bool post_clear); static void findLed(void); static bool done_; static byte row_; From 9f8e87c2d1df9d9503523b975f065365ff152726 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 13 May 2018 09:55:32 +0200 Subject: [PATCH 526/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 55 ++++++++++++++++++++++++++------- src/Kaleidoscope-LEDControl.h | 27 +++++++++++----- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 6bfaa842..21de9ac6 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -13,11 +13,18 @@ void LEDMode::activate(void) { ::LEDControl.activate(this); } -void LEDMode::begin(void) { - Kaleidoscope.use(&::LEDControl); +kaleidoscope::EventHandlerResult LEDMode::onSetup() { ::LEDControl.mode_add(this); setup(); + + return EventHandlerResult::OK; +} + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void LEDMode::begin() { + onSetup(); } +#endif LEDControl::LEDControl(void) { mode = 0; @@ -112,7 +119,7 @@ void LEDControl::syncLeds(void) { KeyboardHardware.syncLeds(); } -void LEDControl::begin(void) { +kaleidoscope::EventHandlerResult LEDControl::onSetup() { set_all_leds_to({0, 0, 0}); for (uint8_t i = 0; i < LED_MAX_MODES; i++) { @@ -120,15 +127,14 @@ void LEDControl::begin(void) { (modes[i]->setup)(); } - Kaleidoscope.useEventHandlerHook(eventHandler); - Kaleidoscope.useLoopHook(loopHook); - syncTimer = millis() + syncDelay; + + return EventHandlerResult::OK; } -Key LEDControl::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState) { +kaleidoscope::EventHandlerResult LEDControl::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) - return mappedKey; + return kaleidoscope::EventHandlerResult::OK; if (keyToggledOn(keyState)) { if (mappedKey == Key_LEDEffectNext) { @@ -138,12 +144,12 @@ Key LEDControl::eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState } } - return Key_NoKey; + return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; } -void LEDControl::loopHook(bool postClear) { - if (postClear || paused) - return; +kaleidoscope::EventHandlerResult LEDControl::beforeReportingState(void) { + if (paused) + return kaleidoscope::EventHandlerResult::OK; uint16_t current_time = millis(); if ((current_time - syncTimer) > syncDelay) { @@ -151,6 +157,8 @@ void LEDControl::loopHook(bool postClear) { syncTimer += syncDelay; } update(); + + return kaleidoscope::EventHandlerResult::OK; } bool LEDControl::focusHook(const char *command) { @@ -252,6 +260,29 @@ bool LEDControl::focusHook(const char *command) { return true; } +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void LEDControl::begin() { + ::LEDControl.onSetup(); + Kaleidoscope.useEventHandlerHook(legacyEventHandler); + Kaleidoscope.useLoopHook(legacyLoopHook); +} + +Key LEDControl::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { + EventHandlerResult r = ::LEDControl.onKeyswitchEvent(mapped_key, row, col, key_state); + if (r == EventHandlerResult::OK) + return mapped_key; + return Key_NoKey; +} + +void LEDControl::legacyLoopHook(bool is_post_clear) { + if (is_post_clear) + return; + ::LEDControl.beforeReportingState(); +} +#endif + + } kaleidoscope::LEDControl LEDControl; diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index f9aa47c9..0e7ee8f6 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -22,7 +22,7 @@ namespace kaleidoscope { * A LED mode **must** implement at least one of @ref onActivate or @ref * update, and possibly @ref refreshAt too. */ -class LEDMode : public KaleidoscopePlugin { +class LEDMode : public kaleidoscope::Plugin { friend class LEDControl; protected: // These methods should only be called by LEDControl. @@ -81,15 +81,17 @@ class LEDMode : public KaleidoscopePlugin { * Called via `Kaleidoscope.use()`, registers the LED mode, and does the * necessary initialization steps. Calls @ref setup at the end. */ - void begin(void) final; + kaleidoscope::EventHandlerResult onSetup(); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + void begin(); +#endif }; -class LEDControl : public KaleidoscopePlugin { +class LEDControl : public kaleidoscope::Plugin { public: LEDControl(void); - void begin(void) final; - static void next_mode(void); static void prev_mode(void); static void setup(void); @@ -130,14 +132,23 @@ class LEDControl : public KaleidoscopePlugin { static bool focusHook(const char *command); + kaleidoscope::EventHandlerResult onSetup(); + kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); + kaleidoscope::EventHandlerResult beforeReportingState(); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: + void begin(); + static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); + static void legacyLoopHook(bool is_post_clear); +#endif + private: static uint16_t syncTimer; static LEDMode *modes[LED_MAX_MODES]; static uint8_t mode; - - static Key eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState); - static void loopHook(bool postClear); }; + } extern kaleidoscope::LEDControl LEDControl; From 0f32840a3a554e6425ada26fa1ac41a6acb0dbf3 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 13 May 2018 10:11:15 +0200 Subject: [PATCH 527/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 5 ++--- examples/MagicCombo/MagicCombo.ino | 12 ++++++------ src/Kaleidoscope/MagicCombo.cpp | 30 +++++++++++++++++++----------- src/Kaleidoscope/MagicCombo.h | 18 +++++++++++------- 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 621fde69..ec713d59 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,10 @@ void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_h } } +KALEIDOSCOPE_INIT_PLUGINS(MagicCombo); + void setup() { Serial.begin(9600); - - Kaleidoscope.use(&MagicCombo); - Kaleidoscope.setup(); MagicCombo.magic_combos = magic_combos; diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index 77e51103..4d0256f3 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-MagicCombo -- Magic combo framework - * Copyright (C) 2016, 2017 Gergely Nagy + * Copyright (C) 2016, 2017, 2018 Gergely Nagy * * 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 @@ -35,7 +35,7 @@ static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { {0, 0} }; - +// *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED ( @@ -49,18 +49,18 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_NoKey), }; +// *INDENT-ON* + +KALEIDOSCOPE_INIT_PLUGINS(MagicCombo); void setup() { Serial.begin(9600); - - Kaleidoscope.use(&MagicCombo); - Kaleidoscope.setup(); MagicCombo.magic_combos = magic_combos; diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index ef016687..b220717b 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-MagicCombo -- Magic combo framework - * Copyright (C) 2016, 2017 Gergely Nagy + * Copyright (C) 2016, 2017, 2018 Gergely Nagy * * 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 @@ -34,16 +34,9 @@ const MagicCombo::combo_t *MagicCombo::magic_combos; uint16_t MagicCombo::min_interval = 500; uint32_t MagicCombo::end_time_; -MagicCombo::MagicCombo(void) { -} - -void MagicCombo::begin(void) { - Kaleidoscope.useLoopHook(loopHook); -} - -void MagicCombo::loopHook(bool is_post_clear) { - if (!magic_combos || is_post_clear) - return; +EventHandlerResult MagicCombo::beforeReportingState() { + if (!magic_combos) + return EventHandlerResult::OK; for (byte i = 0;; i++) { combo_t combo; @@ -63,8 +56,23 @@ void MagicCombo::loopHook(bool is_post_clear) { break; } } + + return EventHandlerResult::OK; } +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void MagicCombo::begin() { + Kaleidoscope.useLoopHook(legacyLoopHook); +} + +void MagicCombo::legacyLoopHook(bool is_post_clear) { + if (is_post_clear) + return; + ::MagicCombo.beforeReportingState(); +} +#endif + }; __attribute__((weak)) void magicComboActions(uint8_t comboIndex, uint32_t left_hand, uint32_t right_hand) { diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 2633ba91..8c8a3dc8 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-MagicCombo -- Magic combo framework - * Copyright (C) 2016, 2017 Gergely Nagy + * Copyright (C) 2016, 2017, 2018 Gergely Nagy * * 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 @@ -22,23 +22,27 @@ namespace kaleidoscope { -class MagicCombo : public KaleidoscopePlugin { +class MagicCombo : public kaleidoscope::Plugin { public: typedef struct { uint32_t left_hand, right_hand; } combo_t; - MagicCombo(void); - - void begin(void) final; + MagicCombo(void) {} static const combo_t *magic_combos; static uint16_t min_interval; + EventHandlerResult beforeReportingState(); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: + void begin(); + static void legacyLoopHook(bool is_post_clear); +#endif + private: static uint32_t end_time_; - - static void loopHook(bool is_post_clear); }; } From 115e439a4cb0e3b4775daf08fdfb5cb328341ebf Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 13 May 2018 10:29:00 +0200 Subject: [PATCH 528/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- src/Kaleidoscope-NumPad.cpp | 30 ++++++++++++++++++++++-------- src/Kaleidoscope-NumPad.h | 15 ++++++++++----- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 84b9eba2..0057d08c 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -9,9 +9,9 @@ bool NumPad_::cleanupDone = true; bool NumPad_::originalNumLockState = false; cRGB numpad_color = CRGB(255, 0, 0); -void NumPad_::begin(void) { - Kaleidoscope.useLoopHook(loopHook); +kaleidoscope::EventHandlerResult NumPad_::onSetup(void) { originalNumLockState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); + return kaleidoscope::EventHandlerResult::OK; } static void syncNumlock(bool state) { @@ -21,10 +21,7 @@ static void syncNumlock(bool state) { } } -void NumPad_::loopHook(bool postClear) { - if (!postClear) - return; - +kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { if (!Layer.isOn(numPadLayer)) { bool numState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); if (!cleanupDone) { @@ -38,7 +35,8 @@ void NumPad_::loopHook(bool postClear) { } } originalNumLockState = numState; - return; + + return kaleidoscope::EventHandlerResult::OK; } cleanupDone = false; @@ -65,10 +63,26 @@ void NumPad_::loopHook(bool postClear) { } if (row > ROWS || col > COLS) - return; + return kaleidoscope::EventHandlerResult::OK; cRGB color = breath_compute(); LEDControl.setCrgbAt(row, col, color); + + return kaleidoscope::EventHandlerResult::OK; +} + +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void NumPad_::begin() { + onSetup(); + Kaleidoscope.useLoopHook(legacyLoopHook); +} + +void NumPad_::legacyLoopHook(bool is_post_clear) { + if (!is_post_clear) + return; + NumPad.afterEachCycle(); } +#endif NumPad_ NumPad; diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index 1f3c9010..6371c534 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -4,17 +4,22 @@ #include "Kaleidoscope-Macros.h" #include "LEDUtils.h" -class NumPad_ : public KaleidoscopePlugin { +class NumPad_ : public kaleidoscope::Plugin { public: NumPad_(void) {} - void begin(void) final; - static uint8_t numPadLayer; - private: - static void loopHook(const bool postClear); + kaleidoscope::EventHandlerResult onSetup(void); + kaleidoscope::EventHandlerResult afterEachCycle(); +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: + void begin(); + static void legacyLoopHook(bool is_post_clear); +#endif + + private: static byte row, col; static bool cleanupDone; static bool originalNumLockState; From 4b061994fc21d0306c6ddd7b88f77a903b756f6d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 13 May 2018 10:09:22 +0200 Subject: [PATCH 529/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 4 ++-- src/Kaleidoscope-Macros.cpp | 44 +++++++++++++++++++++++++------------ src/Kaleidoscope-Macros.h | 19 +++++++++++----- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 3bc1bbbf..c454766a 100644 --- a/README.md +++ b/README.md @@ -63,9 +63,9 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { return MACRO_NONE; } +KALEIDOSCOPE_INIT_PLUGINS(Macros); + void setup() { - Kaleidoscope.use(&Macros); - Kaleidoscope.setup (); } ``` diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 276b952e..55a2465d 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -183,21 +183,23 @@ const macro_t *Macros_::type(const char *string) { return MACRO_NONE; } -Key Macros_::handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState) { +kaleidoscope::EventHandlerResult Macros_::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) - return mappedKey; + return kaleidoscope::EventHandlerResult::OK; byte key_id = (row * COLS) + col; addActiveMacroKey(mappedKey.keyCode, key_id, keyState); - return Key_NoKey; + + return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; } -void Macros_::loopHook(bool post_clear) { - if (post_clear) { - active_macro_count = 0; - return; - } +kaleidoscope::EventHandlerResult Macros_::afterEachCycle() { + active_macro_count = 0; + + return kaleidoscope::EventHandlerResult::OK; +} +kaleidoscope::EventHandlerResult Macros_::beforeReportingState() { for (byte i = 0; i < active_macro_count; ++i) { if (active_macros[i].key_id == 0xFF) { // i.e. UNKNOWN_KEYSWITCH_LOCATION @@ -211,16 +213,30 @@ void Macros_::loopHook(bool post_clear) { active_macros[i].key_state); Macros.play(m); } + return kaleidoscope::EventHandlerResult::OK; } -Macros_::Macros_(void) { +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void Macros_::begin() { + Kaleidoscope.useEventHandlerHook(legacyEventHandler); + Kaleidoscope.useLoopHook(legacyLoopHook); } -void -Macros_::begin(void) { - active_macro_count = 0; - Kaleidoscope.useEventHandlerHook(handleMacroEvent); - Kaleidoscope.useLoopHook(loopHook); +Key Macros_::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { + kaleidoscope::EventHandlerResult r = Macros.onKeyswitchEvent(mapped_key, row, col, key_state); + if (r == kaleidoscope::EventHandlerResult::OK) + return mapped_key; + return Key_NoKey; +} + +void Macros_::legacyLoopHook(bool is_post_clear) { + if (is_post_clear) { + Macros.afterEachCycle(); + } else { + Macros.beforeReportingState(); + } } +#endif Macros_ Macros; diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index 5c6d2658..d3c240e1 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -17,11 +17,9 @@ struct MacroKeyEvent { byte key_state; }; -class Macros_ : public KaleidoscopePlugin { +class Macros_ : public kaleidoscope::Plugin { public: - Macros_(void); - - void begin(void) final; + Macros_(void) {} static MacroKeyEvent active_macros[MAX_CONCURRENT_MACROS]; static byte active_macro_count; @@ -35,8 +33,10 @@ class Macros_ : public KaleidoscopePlugin { active_macros[active_macro_count].key_state = key_state; ++active_macro_count; } - static Key handleMacroEvent(Key mappedKey, byte row, byte col, uint8_t keyState); - static void loopHook(bool post_clear); + + kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); + kaleidoscope::EventHandlerResult beforeReportingState(); + kaleidoscope::EventHandlerResult afterEachCycle(); void play(const macro_t *macro_p); @@ -57,6 +57,13 @@ class Macros_ : public KaleidoscopePlugin { static byte row, col; +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: + void begin(); + static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); + static void legacyLoopHook(bool is_post_clear); +#endif + private: Key lookupAsciiCode(uint8_t ascii_code); }; From 0bd171137114f350fb968f2b9cf96ef5f670939a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 13 May 2018 10:24:21 +0200 Subject: [PATCH 530/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 28 ++++++++-------- src/Kaleidoscope-MouseKeys.cpp | 59 +++++++++++++++++++++++----------- src/Kaleidoscope-MouseKeys.h | 20 ++++++++---- 3 files changed, 69 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index d4ee37a4..47a8df8f 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,9 @@ illustrated with an example: Key_mouseUp, Key_mouseDn, Key_mouseL, Key_mouseR, Key_mouseBtnL, Key_mouseBtnR -void setup() { - Kaleidoscope.use(&MouseKeys); +KALEIDOSCOPE_INIT_PLUGINS(MouseKeys); +void setup() { Kaleidoscope.setup (); } ``` @@ -121,15 +121,15 @@ As described above, MouseKeys warps the pointer using a grid model that reflects locations on the screen. By default, the plugin uses a 2x2 grid. To understand how warping works, examine this diagram of a screen split into that 2x2 grid: - +-----------------------+-----------------------+ + +-----------------------|-----------------------+ | | | | | G | tab | | | | | | - |-----------+-----------| tab | + |-----------|-----------| tab | | | | | | B | esc | | | | | | - +-----------------------+-----------------------+ + +-----------------------|-----------------------+ | | | | | | | | | @@ -137,7 +137,7 @@ how warping works, examine this diagram of a screen split into that 2x2 grid: | | | | | | | | | - +-----------------------+-----------------------+ + +-----------------------|-----------------------+ Each quadrant is labed with a key that, when pressed, moves the mouse pointer to the center of that quadrant. With this layout, pressing G warps @@ -162,33 +162,33 @@ diagram shows a screen with a key label that warps to each sector. As we can see, pressing W warps the pointer into the top-left sector, and pressing V warps to the bottom-right corner within that sector: - +-----------------+-----------------+-----------------+ + +-----------------|-----------------|-----------------+ | W | E | R | | | - |-----+-----+-----| | | + |-----|-----|-----| | | | S | D | F | E | R | - |-----+-----+-----| | | + |-----|-----|-----| | | | X | C | V | | | - +-----------------+-----------------+-----------------+ + +-----------------|-----------------|-----------------+ | | | | | | | | | S | D | F | | | | | | | | | - +-----------------+-----------------+-----------------+ + +-----------------|-----------------|-----------------+ | | | | | | | | | X | C | V | | | | | | | | | - +-----------------+-----------------+-----------------+ + +-----------------|-----------------|-----------------+ To use a 3x3 warp grid, we may need to remap some keys. A suggested warp key mapping is shown below on the left side of a keyboard with a QWERTY layout: W | E | R T A - End Warping (Key_mouseWarpEnd) - ---+---+--- W - Warp NW Sector (Key_mouseWarpNW) + ---|---|--- W - Warp NW Sector (Key_mouseWarpNW) A S | D | F G E - Warp N Sector (Key_mouseWarpN) - ---+---+--- R - Warp NE Sector (Key_mouseWarpNE) + ---|---|--- R - Warp NE Sector (Key_mouseWarpNE) X | C | V B S - Warp E Sector (Key_mouseWarpE) D - Warp/Zoom Center (Key_mouseWarpIn) F - Warp W Sector (Key_mouseWarpW) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 0bfb7aa9..7e643201 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -39,23 +39,24 @@ void MouseKeys_::scrollWheel(uint8_t keyCode) { kaleidoscope::hid::moveMouse(0, 0, 0, wheelSpeed); } -void MouseKeys_::loopHook(bool postClear) { - if (postClear) { - kaleidoscope::hid::sendMouseReport(); - kaleidoscope::hid::releaseAllMouseButtons(); - mouseMoveIntent = 0; - return; - } +kaleidoscope::EventHandlerResult MouseKeys_::afterEachCycle() { + kaleidoscope::hid::sendMouseReport(); + kaleidoscope::hid::releaseAllMouseButtons(); + mouseMoveIntent = 0; + return kaleidoscope::EventHandlerResult::OK; +} + +kaleidoscope::EventHandlerResult MouseKeys_::beforeReportingState() { if (mouseMoveIntent == 0) { MouseWrapper.accelStep = 0; endTime = 0; accelEndTime = 0; - return; + return kaleidoscope::EventHandlerResult::OK; } if (millis() < endTime) - return; + return kaleidoscope::EventHandlerResult::OK; endTime = millis() + speedDelay; @@ -79,11 +80,13 @@ void MouseKeys_::loopHook(bool postClear) { moveX = speed; MouseWrapper.move(moveX, moveY); + + return kaleidoscope::EventHandlerResult::OK; } -Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState) { +kaleidoscope::EventHandlerResult MouseKeys_::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY)) - return mappedKey; + return kaleidoscope::EventHandlerResult::OK; if (mappedKey.keyCode & KEY_MOUSE_BUTTON && !(mappedKey.keyCode & KEY_MOUSE_WARP)) { uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; @@ -122,17 +125,37 @@ Key MouseKeys_::eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyS } } - return Key_NoKey; + return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; } -MouseKeys_::MouseKeys_(void) { +kaleidoscope::EventHandlerResult MouseKeys_::onSetup(void) { + MouseWrapper.begin(); + + return kaleidoscope::EventHandlerResult::OK; } -void -MouseKeys_::begin(void) { - MouseWrapper.begin(); - Kaleidoscope.useEventHandlerHook(eventHandlerHook); - Kaleidoscope.useLoopHook(loopHook); +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void MouseKeys_::begin() { + onSetup(); + Kaleidoscope.useEventHandlerHook(legacyEventHandler); + Kaleidoscope.useLoopHook(legacyLoopHook); +} + +Key MouseKeys_::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { + kaleidoscope::EventHandlerResult r = MouseKeys.onKeyswitchEvent(mapped_key, row, col, key_state); + if (r == kaleidoscope::EventHandlerResult::OK) + return mapped_key; + return Key_NoKey; +} + +void MouseKeys_::legacyLoopHook(bool is_post_clear) { + if (is_post_clear) { + MouseKeys.afterEachCycle(); + } else { + MouseKeys.beforeReportingState(); + } } +#endif MouseKeys_ MouseKeys; diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index 78dbabe2..3b23ddff 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -4,11 +4,9 @@ #include "MouseKeyDefs.h" #include "MouseWarpModes.h" -class MouseKeys_ : public KaleidoscopePlugin { +class MouseKeys_ : public kaleidoscope::Plugin { public: - MouseKeys_(void); - - void begin(void) final; + MouseKeys_(void) {} static uint8_t speed; static uint16_t speedDelay; @@ -19,6 +17,18 @@ class MouseKeys_ : public KaleidoscopePlugin { static void setWarpGridSize(uint8_t grid_size); + kaleidoscope::EventHandlerResult onSetup(); + kaleidoscope::EventHandlerResult beforeReportingState(); + kaleidoscope::EventHandlerResult afterEachCycle(); + kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: + void begin(); + static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); + static void legacyLoopHook(bool is_post_clear); +#endif + private: static uint8_t mouseMoveIntent; static uint32_t endTime; @@ -26,8 +36,6 @@ class MouseKeys_ : public KaleidoscopePlugin { static uint32_t wheelEndTime; static void scrollWheel(uint8_t keyCode); - static void loopHook(bool postClear); - static Key eventHandlerHook(Key mappedKey, byte row, byte col, uint8_t keyState); }; extern MouseKeys_ MouseKeys; From 19cffca5c46b50596cecacfbe557645f4e1acab2 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 12 May 2018 18:04:52 +0200 Subject: [PATCH 531/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 3 ++- .../HostPowerManagement.ino | 12 +++++---- src/Kaleidoscope/HostPowerManagement.cpp | 27 ++++++++++++------- src/Kaleidoscope/HostPowerManagement.h | 21 +++++++++------ src/Kaleidoscope/WakeupKeyboard.cpp | 6 ++--- src/Kaleidoscope/WakeupKeyboard.h | 8 +++--- 6 files changed, 47 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 52b82866..ef1cca88 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,11 @@ configuration is necessary, unless one wants to perform custom actions. #include #include +KALEIDOSCOPE_INIT_PLUGINS(HostPowerManagement); + void setup () { Kaleidoscope.setup (); - Kaleidoscope.use(&HostPowerManagement); HostPowerManagement.enableWakeup(); } ``` diff --git a/examples/HostPowerManagement/HostPowerManagement.ino b/examples/HostPowerManagement/HostPowerManagement.ino index 0c498931..77b159ab 100644 --- a/examples/HostPowerManagement/HostPowerManagement.ino +++ b/examples/HostPowerManagement/HostPowerManagement.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-HostPowerManagement -- Host power management support plugin. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -20,6 +20,7 @@ #include #include +// *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED ( @@ -33,14 +34,14 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_NoKey ), - }; +// *INDENT-ON* void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event) { switch (event) { @@ -58,11 +59,12 @@ void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event ev } } +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + HostPowerManagement); + void setup() { Kaleidoscope.setup(); - Kaleidoscope.use(&HostPowerManagement); - HostPowerManagement.enableWakeup(); } diff --git a/src/Kaleidoscope/HostPowerManagement.cpp b/src/Kaleidoscope/HostPowerManagement.cpp index d91ddbf9..1a8fd422 100644 --- a/src/Kaleidoscope/HostPowerManagement.cpp +++ b/src/Kaleidoscope/HostPowerManagement.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-HostPowerManagement -- Host power management support plugin. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -29,14 +29,7 @@ namespace kaleidoscope { bool HostPowerManagement::was_suspended_ = false; bool HostPowerManagement::initial_suspend_ = true; -void HostPowerManagement::begin(void) { - Kaleidoscope.useLoopHook(loopHook); -} - -void HostPowerManagement::loopHook(bool post_clear) { - if (post_clear) - return; - +EventHandlerResult HostPowerManagement::beforeEachCycle() { if ((_usbSuspendState & (1 << SUSPI))) { if (!initial_suspend_) { if (!was_suspended_) { @@ -54,7 +47,23 @@ void HostPowerManagement::loopHook(bool post_clear) { hostPowerManagementEventHandler(Resume); } } + + return EventHandlerResult::OK; +} + +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void HostPowerManagement::begin() { + Kaleidoscope.useLoopHook(legacyLoopHook); +} + +void HostPowerManagement::legacyLoopHook(bool is_post_clear) { + if (is_post_clear) + return; + + ::HostPowerManagement.beforeEachCycle(); } +#endif } diff --git a/src/Kaleidoscope/HostPowerManagement.h b/src/Kaleidoscope/HostPowerManagement.h index 79e321f1..59d71a2d 100644 --- a/src/Kaleidoscope/HostPowerManagement.h +++ b/src/Kaleidoscope/HostPowerManagement.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-HostPowerManagement -- Host power management support plugin. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -22,7 +22,7 @@ #include "WakeupKeyboard.h" namespace kaleidoscope { -class HostPowerManagement : public KaleidoscopePlugin { +class HostPowerManagement : public kaleidoscope::Plugin { public: typedef enum { Suspend, @@ -30,18 +30,23 @@ class HostPowerManagement : public KaleidoscopePlugin { Resume, } Event; - HostPowerManagement(void) {}; + HostPowerManagement(void) {} - void begin(void) final; void enableWakeup(void) { - WakeupKeyboard.begin(); - }; + WakeupKeyboard.init(); + } + + EventHandlerResult beforeEachCycle(); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: + void begin(); + static void legacyLoopHook(bool is_post_clear); +#endif private: static bool was_suspended_; static bool initial_suspend_; - - static void loopHook(bool post_clear); }; } diff --git a/src/Kaleidoscope/WakeupKeyboard.cpp b/src/Kaleidoscope/WakeupKeyboard.cpp index a1585584..f527c792 100644 --- a/src/Kaleidoscope/WakeupKeyboard.cpp +++ b/src/Kaleidoscope/WakeupKeyboard.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- - * Kaleidoscope-MyOldFriend -- Host power management support plugin. - * Copyright (C) 2017 Gergely Nagy + * Kaleidoscope-HostPowerManagement -- Host power management support plugin. + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -85,7 +85,7 @@ bool WakeupKeyboard_::setup(USBSetup& setup) { return false; } -void WakeupKeyboard_::begin() { +void WakeupKeyboard_::init() { } WakeupKeyboard_ WakeupKeyboard; diff --git a/src/Kaleidoscope/WakeupKeyboard.h b/src/Kaleidoscope/WakeupKeyboard.h index d1199ffa..e6ac356b 100644 --- a/src/Kaleidoscope/WakeupKeyboard.h +++ b/src/Kaleidoscope/WakeupKeyboard.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- - * Kaleidoscope-MyOldFriend -- Host power management support plugin. - * Copyright (C) 2017 Gergely Nagy + * Kaleidoscope-HostPowerManagement -- Host power management support plugin. + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -22,10 +22,10 @@ #include "PluggableUSB.h" #include "HID.h" -class WakeupKeyboard_ : public PluggableUSBModule, public KaleidoscopePlugin { +class WakeupKeyboard_ : public PluggableUSBModule, public kaleidoscope::Plugin { public: WakeupKeyboard_(void); - void begin() final; + void init(); protected: int getInterface(uint8_t* interfaceCount); From e9b9d41626a4cb572edb2e98c1fa886522a56cd4 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 14 May 2018 06:27:18 +0200 Subject: [PATCH 532/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 5 +++-- examples/LED-Stalker/LED-Stalker.ino | 13 +++++++++---- src/Kaleidoscope/LED-Stalker.cpp | 28 +++++++++++++++++++--------- src/Kaleidoscope/LED-Stalker.h | 11 +++++++---- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index debffaa6..4dfaa7f0 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,12 @@ To use the plugin, one needs to include the header and select the effect. ```c++ #include +#include #include -void setup (){ - Kaleidoscope.use(&StalkerEffect); +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, StalkerEffect); +void setup (){ Kaleidoscope.setup(); StalkerEffect.variant = STALKER(Haunt, (CRGB(0, 128, 0))); diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index bbab98f8..d5721429 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -17,9 +17,11 @@ */ #include +#include #include #include "LED-Off.h" +// *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED ( @@ -33,16 +35,19 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_NoKey), }; +// *INDENT-ON* -void setup() { - Kaleidoscope.use(&LEDOff, &StalkerEffect); +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + LEDOff, + StalkerEffect); +void setup() { Kaleidoscope.setup(); StalkerEffect.variant = STALKER(BlazingTrail); diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 5e667c3f..57b55304 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -26,23 +26,19 @@ StalkerEffect::ColorComputer *StalkerEffect::variant; uint16_t StalkerEffect::step_length = 50; uint16_t StalkerEffect::step_start_time_; -void StalkerEffect::setup(void) { - Kaleidoscope.useEventHandlerHook(eventHandlerHook); -} - void StalkerEffect::onActivate(void) { memset(map_, 0, sizeof(map_)); } -Key StalkerEffect::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state) { +EventHandlerResult StalkerEffect::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) { if (row >= ROWS || col >= COLS) - return mapped_key; + return EventHandlerResult::OK; - if (keyIsPressed(key_state)) { + if (keyIsPressed(keyState)) { map_[row][col] = 0xff; } - return mapped_key; + return EventHandlerResult::OK; } void StalkerEffect::update(void) { @@ -143,6 +139,20 @@ cRGB Rainbow::compute(uint8_t *step) { } +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void StalkerEffect::setup(void) { + Kaleidoscope.useEventHandlerHook(legacyEventHandler); +} + +Key StalkerEffect::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { + EventHandlerResult r = ::StalkerEffect.onKeyswitchEvent(mapped_key, row, col, key_state); + if (r == EventHandlerResult::OK) + return mapped_key; + return Key_NoKey; +} +#endif + } kaleidoscope::StalkerEffect StalkerEffect; diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 1d867659..9f5041f9 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -36,16 +36,19 @@ class StalkerEffect : public LEDMode { static ColorComputer *variant; static uint16_t step_length; + EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); protected: - void setup(void) final; void onActivate(void) final; void update(void) final; +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + void setup(void) final; + static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); +#endif + private: static uint16_t step_start_time_; static uint8_t map_[ROWS][COLS]; - - static Key eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state); }; namespace stalker { From ee5cc576a07d30b15f61d35fdc7d40e38566ead7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 14 May 2018 06:29:56 +0200 Subject: [PATCH 533/792] Updated to use the new plugin APIs Signed-off-by: Gergely Nagy --- README.md | 11 +++-- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 13 ++++-- src/Kaleidoscope/AlphaSquare-Effect.cpp | 47 ++++++++++++-------- src/Kaleidoscope/AlphaSquare-Effect.h | 12 +++-- src/Kaleidoscope/LED-AlphaSquare.cpp | 6 --- src/Kaleidoscope/LED-AlphaSquare.h | 6 +-- 6 files changed, 55 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 82b6b5c2..f87f7116 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,14 @@ This can be done from a macro, or via the `AlphaSquareEffect` LED mode. ```c++ #include +#include #include +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + AlphaSquare, + AlphaSquareEffect); + void setup() { - Kaleidoscope.use(&AlphaSquare, &AlphaSquareEffect); - Kaleidoscope.setup(); AlphaSquare.display (Key_A); @@ -59,8 +62,8 @@ methods or properties other than those provided by all LED modes. ### `.display(symbol, row, col)` ### `.display(symbol, row, col, color)` -> As the previous function, but instead of a key, it expects a 4x4 bitmap in -> the form of a 16-bit unsigned integer, where the low bit is the top-right +> As the previous function, but instead of a key, it expects a 4x4 bitmap in +> the form of a 16-bit unsigned integer, where the low bit is the top-right > corner, the second-lowest bit is to the right of that, and so on. > > The `SYM4x4` macro can be used to simplify creating these bitmaps. diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index cabbdcce..28b755de 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -21,6 +21,7 @@ #include #include +// *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED ( @@ -34,12 +35,13 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, - Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_skip), }; +// *INDENT-ON* const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) { if (!keyToggledOn(key_state)) @@ -93,9 +95,12 @@ const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) { return MACRO_NONE; } -void setup() { - Kaleidoscope.use(&AlphaSquare, &AlphaSquareEffect, &Macros); +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + AlphaSquare, + AlphaSquareEffect, + Macros); +void setup() { Kaleidoscope.setup(); AlphaSquare.color = { 0xcb, 0xc0, 0xff }; diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index dc1bc208..2c1446fd 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -24,10 +24,6 @@ uint16_t AlphaSquareEffect::length = 1000; uint32_t AlphaSquareEffect::end_time_left_, AlphaSquareEffect::end_time_right_; Key AlphaSquareEffect::last_key_left_, AlphaSquareEffect::last_key_right_; -void AlphaSquareEffect::setup(void) { - Kaleidoscope.useEventHandlerHook(eventHandlerHook); -} - void AlphaSquareEffect::update(void) { if (end_time_left_ && millis() > end_time_left_) { ::AlphaSquare.clear(last_key_left_); @@ -39,37 +35,52 @@ void AlphaSquareEffect::update(void) { } } -Key AlphaSquareEffect::eventHandlerHook(Key key, byte row, byte col, uint8_t key_state) { +EventHandlerResult AlphaSquareEffect::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { if (::LEDControl.get_mode() != &::AlphaSquareEffect) - return key; + return EventHandlerResult::OK; - if (key_state & INJECTED) - return key; + if (keyState & INJECTED) + return EventHandlerResult::OK; - if (key < Key_A || key > Key_0) - return key; + if (mappedKey < Key_A || mappedKey > Key_0) + return EventHandlerResult::OK; - if (!keyIsPressed(key_state)) - return key; + if (!keyIsPressed(keyState)) + return EventHandlerResult::OK; uint8_t display_col = 2; Key prev_key = last_key_left_; if (col < COLS / 2) { - last_key_left_ = key; + last_key_left_ = mappedKey; end_time_left_ = millis() + length; } else { prev_key = last_key_right_; - last_key_right_ = key; + last_key_right_ = mappedKey; end_time_right_ = millis() + length; display_col = 10; } - if (prev_key != key) + if (prev_key != mappedKey) ::AlphaSquare.clear(prev_key, display_col); - ::AlphaSquare.display(key, display_col); - return key; + ::AlphaSquare.display(mappedKey, display_col); + + return EventHandlerResult::OK; +} + +// Legacy V1 API +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void AlphaSquareEffect::setup(void) { + Kaleidoscope.useEventHandlerHook(legacyEventHandler); +} + +Key AlphaSquareEffect::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { + EventHandlerResult r = ::AlphaSquareEffect.onKeyswitchEvent(mapped_key, row, col, key_state); + if (r == EventHandlerResult::OK) + return mapped_key; + return Key_NoKey; } +#endif } diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 0f60a452..34381df2 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017, 2018 Gergely Nagy * * 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 @@ -27,15 +27,19 @@ class AlphaSquareEffect : public LEDMode { AlphaSquareEffect(void) {} static uint16_t length; + + EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); protected: - void setup(void) final; void update(void) final; +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + void setup(void) final; + static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); +#endif + private: static uint32_t end_time_left_, end_time_right_; static Key last_key_left_, last_key_right_; - - static Key eventHandlerHook(Key key, uint8_t row, uint8_t col, uint8_t key_state); }; } diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 9a7184f0..ac7c608d 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -63,12 +63,6 @@ static const uint16_t alphabet[] PROGMEM = { cRGB AlphaSquare::color = {0x80, 0x80, 0x80}; -AlphaSquare::AlphaSquare(void) { -} - -void AlphaSquare::begin(void) { -} - void AlphaSquare::display(Key key, uint8_t row, uint8_t col, cRGB key_color) { if (key < Key_A || key > Key_0) return; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index 9595d87f..18cb1706 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -33,11 +33,9 @@ p30 << 12 | p31 << 13 | p32 << 14 | p33 << 15 ) namespace kaleidoscope { -class AlphaSquare : public KaleidoscopePlugin { +class AlphaSquare : public kaleidoscope::Plugin { public: - AlphaSquare(void); - - void begin(void) final; + AlphaSquare(void) {} static void display(Key key, uint8_t row, uint8_t col, cRGB key_color); static void display(Key key, uint8_t row, uint8_t col); From dbb4152cb28e27d5d26d3cad01124cd04c9eb093 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 14 May 2018 22:43:50 +0200 Subject: [PATCH 534/792] Updated to use the new plugin API Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Model01-TestMode.cpp | 16 ++++++++++------ src/Kaleidoscope-Model01-TestMode.h | 12 +++++++++--- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 7846fa39..fe27c90a 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -13,22 +13,26 @@ -TestMode_::TestMode_(void) { +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API +void TestMode_::begin(void) { + Kaleidoscope.useLoopHook(this->legacyLoopHook); } +void TestMode_::legacyLoopHook(bool is_post_clear) { + if (is_post_clear) + return; -void TestMode_::begin(void) { - Kaleidoscope.useLoopHook(this->loopHook); + TestMode.beforeReportingState(); } +#endif -void TestMode_::loopHook(bool postClear) { - if (postClear) - return; +kaleidoscope::EventHandlerResult TestMode_::beforeReportingState() { if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO // && KeyboardHardware.rightHandState.all == combo.rightHand ) { run_tests(); } + return kaleidoscope::EventHandlerResult::OK; } void TestMode_::waitForKeypress() { diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 1fa7a1ff..5be46c75 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -12,10 +12,17 @@ typedef struct { uint32_t badKeys; } side_data_t; -class TestMode_ : public KaleidoscopePlugin { +class TestMode_ : public kaleidoscope::Plugin { public: - TestMode_(void); + TestMode_(void) {}; + + kaleidoscope::EventHandlerResult beforeReportingState(); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + protected: void begin(); + static void legacyLoopHook(bool is_post_clear); +#endif private: static void run_tests(); @@ -24,7 +31,6 @@ class TestMode_ : public KaleidoscopePlugin { static void toggle_programming_leds_on(); static void handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset); static void waitForKeypress(); - static void loopHook(bool postClear); static void set_leds(cRGB color); }; From 61d70b5cacff7bb41d81409fd1d5822aac85702f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 22 May 2018 22:22:13 +0200 Subject: [PATCH 535/792] Updated the README and the example with a better example Instead of a twisted combination, use the palm keys - easy to press, and otherwise unused in the example. Also, use `Macros.type` instead of `Serial.println`, because the former is easier to play with as a user. Fixes #5. Signed-off-by: Gergely Nagy --- README.md | 21 +++++++++++---------- examples/MagicCombo/MagicCombo.ino | 10 +++++----- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ec713d59..abed81a3 100644 --- a/README.md +++ b/README.md @@ -24,27 +24,28 @@ a special function to handle the combos: ```c++ #include +#include #include -static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { - {R1C3 | R2C1 | R2C4 | R2C7, // left hand, - R0C11 | R1C12 | R2C14 //right hand - }, - {0, 0} -}; - void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand) { switch (combo_index) { case 0: - Serial.println("It's a kind of magic!"); + Macros.type(PSTR("It's a kind of magic!")); break; } } -KALEIDOSCOPE_INIT_PLUGINS(MagicCombo); +static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { + { + R3C6, // left palm key + R3C9 // right palm key + }, + {0, 0} +}; + +KALEIDOSCOPE_INIT_PLUGINS(MagicCombo, Macros); void setup() { - Serial.begin(9600); Kaleidoscope.setup(); MagicCombo.magic_combos = magic_combos; diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index 4d0256f3..471a4cae 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -17,20 +17,21 @@ */ #include +#include #include void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand) { switch (combo_index) { case 0: - Serial.println("It's a kind of magic!"); + Macros.type(PSTR("It's a kind of magic!")); break; } } static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { { - R1C3 | R2C1 | R2C4 | R2C7, // left hand, - R0C11 | R1C12 | R2C14 // right hand + R3C6, // left palm key + R3C9 // right palm key }, {0, 0} }; @@ -57,10 +58,9 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { }; // *INDENT-ON* -KALEIDOSCOPE_INIT_PLUGINS(MagicCombo); +KALEIDOSCOPE_INIT_PLUGINS(MagicCombo, Macros); void setup() { - Serial.begin(9600); Kaleidoscope.setup(); MagicCombo.magic_combos = magic_combos; From e6f7aef63ba29f282354a33ab4df8271e8531be7 Mon Sep 17 00:00:00 2001 From: Aaron Christianson Date: Wed, 30 May 2018 13:53:07 +0200 Subject: [PATCH 536/792] added methods to control delay time and updated the README --- README.md | 10 +++++++--- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 8 ++++++++ src/Kaleidoscope-LEDEffect-Rainbow.h | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 652f986e..8a92239e 100644 --- a/README.md +++ b/README.md @@ -25,18 +25,22 @@ both!) of the effects: #include #include -KALEIDOSCOPE_INIT_PLUGINS(LEDRainbowEffect, LEDRainbowWaveEffect); void setup() { Kaleidoscope.setup(); + Kaleidoscope.use(&LEDRainbowWaveEffect, &LEDDigitalRainEffect); + + LEDRainbowEffect.brightness(150); + LEDRainbowWaveEffect.brightness(150); + LEDRainbowWaveEffect.delay(50); } ``` ## Plugin methods The plugin provides two objects: `LEDRainbowEffect`, and `LEDRainbowWaveEffect`, -neither of which have any public methods or properties, outside of those -provided by all LED modes. +both of which provide methods to set the delay time (animation speed) +and effect brightness, called `delay` and `brightness` respectively. ## Dependencies diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index 5fdbcc5f..320dbe67 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -23,6 +23,10 @@ void LEDRainbowEffect::brightness(byte brightness) { rainbow_value = brightness; } +void LEDRainbowEffect::delay(byte delay) { + rainbow_update_delay = delay; +} + // --------- @@ -51,6 +55,10 @@ void LEDRainbowWaveEffect::update(void) { void LEDRainbowWaveEffect::brightness(byte brightness) { rainbow_value = brightness; } + +void LEDRainbowWaveEffect::delay(byte delay) { + rainbow_update_delay = delay; +} } kaleidoscope::LEDRainbowEffect LEDRainbowEffect; diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index e3a66210..0c01c5a8 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -9,6 +9,7 @@ class LEDRainbowEffect : public LEDMode { LEDRainbowEffect(void) {} void brightness(byte); + void delay(byte); void update(void) final; private: @@ -28,6 +29,7 @@ class LEDRainbowWaveEffect : public LEDMode { LEDRainbowWaveEffect(void) {} void brightness(byte); + void delay(byte); void update(void) final; private: From 834d75fc7d594042ad1f588410cae8271e3f6019 Mon Sep 17 00:00:00 2001 From: Aaron Christianson Date: Wed, 30 May 2018 14:05:41 +0200 Subject: [PATCH 537/792] added methods to control delay time and updated the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a92239e..13c00172 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,10 @@ both!) of the effects: #include #include +KALEIDOSCOPE_INIT_PLUGINS(LEDRainbowEffect, LEDRainbowWaveEffect); void setup() { Kaleidoscope.setup(); - Kaleidoscope.use(&LEDRainbowWaveEffect, &LEDDigitalRainEffect); LEDRainbowEffect.brightness(150); LEDRainbowWaveEffect.brightness(150); From a1fadd9f752f82d726bc467bacfa38504670b8ef Mon Sep 17 00:00:00 2001 From: Aaron Christianson Date: Wed, 30 May 2018 16:05:32 +0200 Subject: [PATCH 538/792] added changes suggested in the PR discussion. --- README.md | 12 ++++++++++-- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 4 ++-- src/Kaleidoscope-LEDEffect-Rainbow.h | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 13c00172..3afdbfd7 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,16 @@ void setup() { ## Plugin methods The plugin provides two objects: `LEDRainbowEffect`, and `LEDRainbowWaveEffect`, -both of which provide methods to set the delay time (animation speed) -and effect brightness, called `delay` and `brightness` respectively. +both of which provide the following methods: + +### `.brightness(brightness)` + +Sets the LED brightness for the effect. + +### `.update_delay(delay)` + +Sets the number of miliseconds between effect updates. +Smaller number = faster rainbows. ## Dependencies diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index 320dbe67..a8a4f21e 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -23,7 +23,7 @@ void LEDRainbowEffect::brightness(byte brightness) { rainbow_value = brightness; } -void LEDRainbowEffect::delay(byte delay) { +void LEDRainbowEffect::update_delay(byte delay) { rainbow_update_delay = delay; } @@ -56,7 +56,7 @@ void LEDRainbowWaveEffect::brightness(byte brightness) { rainbow_value = brightness; } -void LEDRainbowWaveEffect::delay(byte delay) { +void LEDRainbowWaveEffect::updat_delay(byte delay) { rainbow_update_delay = delay; } } diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 0c01c5a8..bd87d998 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -9,7 +9,7 @@ class LEDRainbowEffect : public LEDMode { LEDRainbowEffect(void) {} void brightness(byte); - void delay(byte); + void update_delay(byte); void update(void) final; private: @@ -29,7 +29,7 @@ class LEDRainbowWaveEffect : public LEDMode { LEDRainbowWaveEffect(void) {} void brightness(byte); - void delay(byte); + void update_delay(byte); void update(void) final; private: From 4cd9e03645da4c95a4cb6b6628bbb61e1b797e95 Mon Sep 17 00:00:00 2001 From: Aaron Christianson Date: Wed, 30 May 2018 16:14:12 +0200 Subject: [PATCH 539/792] forgot to update the README example to the proper method name in the previous commit. fixed. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3afdbfd7..2c81a02d 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ void setup() { LEDRainbowEffect.brightness(150); LEDRainbowWaveEffect.brightness(150); - LEDRainbowWaveEffect.delay(50); + LEDRainbowWaveEffect.update_delay(50); } ``` From ce474a98a9340359b96985d3484e4a141ac7ec61 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 30 May 2018 16:14:24 +0200 Subject: [PATCH 540/792] Minor README update Signed-off-by: Gergely Nagy --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3afdbfd7..457d1fa8 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ void setup() { LEDRainbowEffect.brightness(150); LEDRainbowWaveEffect.brightness(150); - LEDRainbowWaveEffect.delay(50); + LEDRainbowWaveEffect.update_delay(50); } ``` @@ -43,12 +43,16 @@ both of which provide the following methods: ### `.brightness(brightness)` -Sets the LED brightness for the effect. +> Sets the LED brightness for the effect. +> +> Defaults to 50. ### `.update_delay(delay)` -Sets the number of miliseconds between effect updates. -Smaller number = faster rainbows. +> Sets the number of miliseconds between effect updates. Smaller number results +> in faster rainbows. +> +> Defaults to 40. ## Dependencies From 7ad05d2d931ec600a34e86eb6ba2a15602fb2594 Mon Sep 17 00:00:00 2001 From: Aaron Christianson Date: Wed, 30 May 2018 17:25:30 +0200 Subject: [PATCH 541/792] fixed a show-stopping spelling error. updat_delay -> update_delay --- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index a8a4f21e..e60eb60e 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -56,7 +56,7 @@ void LEDRainbowWaveEffect::brightness(byte brightness) { rainbow_value = brightness; } -void LEDRainbowWaveEffect::updat_delay(byte delay) { +void LEDRainbowWaveEffect::update_delay(byte delay) { rainbow_update_delay = delay; } } From 1ab6c016cd9f6b29162360aba892cb9034858c13 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 31 May 2018 09:00:14 +0200 Subject: [PATCH 542/792] Use Focus.readColor in the focusHook Instead of repeating the same cRGB reading code in three places, use the recently introduced Focus.readColor() function. This both makes the code cleaner, and more than 50 bytes smaller too. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 21de9ac6..4ae30a6d 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -194,9 +194,7 @@ bool LEDControl::focusHook(const char *command) { } else { cRGB c; - c.r = Serial.parseInt(); - c.g = Serial.parseInt(); - c.b = Serial.parseInt(); + ::Focus.readColor(c); setCrgbAt(idx, c); } @@ -205,9 +203,7 @@ bool LEDControl::focusHook(const char *command) { case SETALL: { cRGB c; - c.r = Serial.parseInt(); - c.g = Serial.parseInt(); - c.b = Serial.parseInt(); + ::Focus.readColor(c); set_all_leds_to(c); @@ -246,9 +242,7 @@ bool LEDControl::focusHook(const char *command) { while (idx < LED_COUNT && Serial.peek() != '\n') { cRGB color; - color.r = Serial.parseInt(); - color.g = Serial.parseInt(); - color.b = Serial.parseInt(); + ::Focus.readColor(color); setCrgbAt(idx, color); idx++; From 95789d3777165643361d377291f2e5f9ada7b22f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 31 May 2018 09:29:55 +0200 Subject: [PATCH 543/792] Add getters for brightness and update_delay Makes it easier to implement #8 as a macro. Signed-off-by: Gergely Nagy --- README.md | 11 ++++++----- src/Kaleidoscope-LEDEffect-Rainbow.h | 4 ++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 457d1fa8..a6821d22 100644 --- a/README.md +++ b/README.md @@ -41,16 +41,17 @@ void setup() { The plugin provides two objects: `LEDRainbowEffect`, and `LEDRainbowWaveEffect`, both of which provide the following methods: -### `.brightness(brightness)` +### `.brightness([brightness])` -> Sets the LED brightness for the effect. +> Sets (or gets, if called without an argument) the LED brightness for the +> effect. > > Defaults to 50. -### `.update_delay(delay)` +### `.update_delay([delay])` -> Sets the number of miliseconds between effect updates. Smaller number results -> in faster rainbows. +> Sets (or gets, if called without an argument) the number of milliseconds +> between effect updates. Smaller number results in faster rainbows. > > Defaults to 40. diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index bd87d998..2db2bcd2 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -9,7 +9,9 @@ class LEDRainbowEffect : public LEDMode { LEDRainbowEffect(void) {} void brightness(byte); + byte brightness(void) { return rainbow_value; } void update_delay(byte); + byte update_delay(void) { return rainbow_update_delay; } void update(void) final; private: @@ -29,7 +31,9 @@ class LEDRainbowWaveEffect : public LEDMode { LEDRainbowWaveEffect(void) {} void brightness(byte); + byte brightness(void) { return rainbow_value; } void update_delay(byte); + byte update_delay(void) { return rainbow_update_delay; } void update(void) final; private: From 8a77cdaaff0a55019a83b3bcc1b3341baed264b4 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 31 May 2018 09:33:41 +0200 Subject: [PATCH 544/792] astyle Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Rainbow.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index 2db2bcd2..f9930909 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -9,9 +9,13 @@ class LEDRainbowEffect : public LEDMode { LEDRainbowEffect(void) {} void brightness(byte); - byte brightness(void) { return rainbow_value; } + byte brightness(void) { + return rainbow_value; + } void update_delay(byte); - byte update_delay(void) { return rainbow_update_delay; } + byte update_delay(void) { + return rainbow_update_delay; + } void update(void) final; private: @@ -31,9 +35,13 @@ class LEDRainbowWaveEffect : public LEDMode { LEDRainbowWaveEffect(void) {} void brightness(byte); - byte brightness(void) { return rainbow_value; } + byte brightness(void) { + return rainbow_value; + } void update_delay(byte); - byte update_delay(void) { return rainbow_update_delay; } + byte update_delay(void) { + return rainbow_update_delay; + } void update(void) final; private: From da41514f1cf4fd85e6fafe0e695f3dbc1f54547d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 2 Jun 2018 08:40:29 +0200 Subject: [PATCH 545/792] Remove WakeupKeyboard This removes WakeupKeyboard, because a similar feature was integrated into BootKeyboard itself, rendering it useless. See keyboardio/KeyboardioHID#35 for an explanation of the whole situation. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/HostPowerManagement.h | 10 +-- src/Kaleidoscope/WakeupKeyboard.cpp | 91 -------------------------- src/Kaleidoscope/WakeupKeyboard.h | 38 ----------- 3 files changed, 6 insertions(+), 133 deletions(-) delete mode 100644 src/Kaleidoscope/WakeupKeyboard.cpp delete mode 100644 src/Kaleidoscope/WakeupKeyboard.h diff --git a/src/Kaleidoscope/HostPowerManagement.h b/src/Kaleidoscope/HostPowerManagement.h index 59d71a2d..01b9d4f5 100644 --- a/src/Kaleidoscope/HostPowerManagement.h +++ b/src/Kaleidoscope/HostPowerManagement.h @@ -19,7 +19,11 @@ #pragma once #include -#include "WakeupKeyboard.h" + +#define _DEPRECATED_MESSAGE_ENABLEWAKEUP \ + "The HostPowerManagement.enableWakeup() call is not necessary anymore,\n" \ + "the firmware supports wakeup by default now. The line can be safely\n" \ + "removed." namespace kaleidoscope { class HostPowerManagement : public kaleidoscope::Plugin { @@ -32,9 +36,7 @@ class HostPowerManagement : public kaleidoscope::Plugin { HostPowerManagement(void) {} - void enableWakeup(void) { - WakeupKeyboard.init(); - } + void enableWakeup(void) DEPRECATED(ENABLEWAKEUP) {} EventHandlerResult beforeEachCycle(); diff --git a/src/Kaleidoscope/WakeupKeyboard.cpp b/src/Kaleidoscope/WakeupKeyboard.cpp deleted file mode 100644 index f527c792..00000000 --- a/src/Kaleidoscope/WakeupKeyboard.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- mode: c++ -*- - * Kaleidoscope-HostPowerManagement -- Host power management support plugin. - * Copyright (C) 2017, 2018 Gergely Nagy - * - * 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 . - */ - -#include "WakeupKeyboard.h" - -static const uint8_t _hidReportDescriptorKeyboard[] PROGMEM = { - // Keyboard - 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ - 0x09, 0x06, /* USAGE (Keyboard) */ - 0xa1, 0x01, /* COLLECTION (Application) */ - 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ - - /* 0 LEDs, to have something the host can work with. */ - 0x05, 0x08, /* USAGE_PAGE (LEDs) */ - 0x19, 0x00, /* USAGE_MINIMUM (-) */ - 0x29, 0x00, /* USAGE_MAXIMUM (-) */ - 0x95, 0x00, /* REPORT_COUNT (0) */ - 0x75, 0x00, /* REPORT_SIZE (0) */ - 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ - - /* End */ - 0xc0 /* END_COLLECTION */ -}; - -WakeupKeyboard_::WakeupKeyboard_(void) : PluggableUSBModule(1, 1, epType) { - epType[0] = EP_TYPE_INTERRUPT_IN; - PluggableUSB().plug(this); -} - -int WakeupKeyboard_::getInterface(uint8_t* interfaceCount) { - *interfaceCount += 1; - HIDDescriptor hidInterface = { - D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_BOOT_INTERFACE, HID_PROTOCOL_KEYBOARD), - D_HIDREPORT(sizeof(_hidReportDescriptorKeyboard)), - D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01) - }; - return USB_SendControl(0, &hidInterface, sizeof(hidInterface)); -} - -int WakeupKeyboard_::getDescriptor(USBSetup& setup) { - if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { - return 0; - } - if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { - return 0; - } - - if (setup.wIndex != pluggedInterface) { - return 0; - } - - return USB_SendControl(TRANSFER_PGM, _hidReportDescriptorKeyboard, sizeof(_hidReportDescriptorKeyboard)); -} - -bool WakeupKeyboard_::setup(USBSetup& setup) { - if (pluggedInterface != setup.wIndex) { - return false; - } - - uint8_t request = setup.bRequest; - uint8_t requestType = setup.bmRequestType; - - if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE) { - if (request == HID_GET_PROTOCOL) { - UEDATX = HID_BOOT_PROTOCOL; - return true; - } - } - - return false; -} - -void WakeupKeyboard_::init() { -} - -WakeupKeyboard_ WakeupKeyboard; diff --git a/src/Kaleidoscope/WakeupKeyboard.h b/src/Kaleidoscope/WakeupKeyboard.h deleted file mode 100644 index e6ac356b..00000000 --- a/src/Kaleidoscope/WakeupKeyboard.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- mode: c++ -*- - * Kaleidoscope-HostPowerManagement -- Host power management support plugin. - * Copyright (C) 2017, 2018 Gergely Nagy - * - * 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 . - */ - -#pragma once - -#include -#include "PluggableUSB.h" -#include "HID.h" - -class WakeupKeyboard_ : public PluggableUSBModule, public kaleidoscope::Plugin { - public: - WakeupKeyboard_(void); - void init(); - - protected: - int getInterface(uint8_t* interfaceCount); - int getDescriptor(USBSetup& setup); - bool setup(USBSetup& setup); - - uint8_t epType[1]; -}; - -extern WakeupKeyboard_ WakeupKeyboard; From 69a8288d5d650d4b982da68c52f92c5a66a95bf1 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 3 Jun 2018 17:54:21 -0400 Subject: [PATCH 546/792] Apply correct diagonal movement speeds Previously, diagonal movements were not reduced in the two axes, resulting in movement that was too quick. This commit divides diagonal movements by sqrt(2) / 2 to correct the movement speed. The net result is that diagonal movement should feel smoother and speed more as expected. --- src/MouseWrapper.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index cca78610..604d897c 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -112,19 +112,34 @@ uint8_t MouseWrapper_::acceleration(uint8_t cycles) { return i; } +static int8_t roundAwayFromZero(float value) { + if (value < 0.0f) { + return static_cast(value - 0.5f); + } + + return static_cast(value + 0.5f); +} void MouseWrapper_::move(int8_t x, int8_t y) { int16_t moveX = 0; int16_t moveY = 0; static int8_t remainderX = 0; static int8_t remainderY = 0; + static const float HALF_SQRT_2 = 0.7071f; + + boolean isDiagonal = (x != 0 && y != 0); + if (x != 0) { + if (isDiagonal) x = roundAwayFromZero(HALF_SQRT_2 * x); moveX = remainderX + (x * acceleration(accelStep)); + if (moveX > (int16_t)speedLimit) moveX = speedLimit; else if (moveX < -(int16_t)speedLimit) moveX = -speedLimit; } if (y != 0) { + if (isDiagonal) y = roundAwayFromZero(HALF_SQRT_2 * y); moveY = remainderY + (y * acceleration(accelStep)); + if (moveY > (int16_t)speedLimit) moveY = speedLimit; else if (moveY < -(int16_t)speedLimit) moveY = -speedLimit; } From 3805b53cadfb2f7fa870b6bbfa39f64d27098043 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 3 Jun 2018 18:10:24 -0400 Subject: [PATCH 547/792] Clean up implementation --- src/MouseWrapper.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 604d897c..06403449 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -127,19 +127,18 @@ void MouseWrapper_::move(int8_t x, int8_t y) { static int8_t remainderY = 0; static const float HALF_SQRT_2 = 0.7071f; - boolean isDiagonal = (x != 0 && y != 0); + if (x != 0 && y != 0) { + x = roundAwayFromZero(HALF_SQRT_2 * x); + y = roundAwayFromZero(HALF_SQRT_2 * y); + } if (x != 0) { - if (isDiagonal) x = roundAwayFromZero(HALF_SQRT_2 * x); moveX = remainderX + (x * acceleration(accelStep)); - if (moveX > (int16_t)speedLimit) moveX = speedLimit; else if (moveX < -(int16_t)speedLimit) moveX = -speedLimit; } if (y != 0) { - if (isDiagonal) y = roundAwayFromZero(HALF_SQRT_2 * y); moveY = remainderY + (y * acceleration(accelStep)); - if (moveY > (int16_t)speedLimit) moveY = speedLimit; else if (moveY < -(int16_t)speedLimit) moveY = -speedLimit; } From 04112de29701267ec045ca29a7ef31946caad5f5 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 4 Jun 2018 01:55:13 -0400 Subject: [PATCH 548/792] Approximate sqrt(2)/2 with ints to avoid floats --- src/MouseWrapper.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 06403449..082b1fde 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -112,24 +112,19 @@ uint8_t MouseWrapper_::acceleration(uint8_t cycles) { return i; } -static int8_t roundAwayFromZero(float value) { - if (value < 0.0f) { - return static_cast(value - 0.5f); - } - - return static_cast(value + 0.5f); -} - void MouseWrapper_::move(int8_t x, int8_t y) { int16_t moveX = 0; int16_t moveY = 0; static int8_t remainderX = 0; static int8_t remainderY = 0; - static const float HALF_SQRT_2 = 0.7071f; if (x != 0 && y != 0) { - x = roundAwayFromZero(HALF_SQRT_2 * x); - y = roundAwayFromZero(HALF_SQRT_2 * y); + // 99 / 140 closely approximates sqrt(2) / 2. + int8_t adjusted_x = x * 99 / 140; + int8_t adjusted_y = y * 99 / 140; + + x = (adjusted_x == 0 ? x : adjusted_x); + y = (adjusted_y == 0 ? y : adjusted_y); } if (x != 0) { From 77acd347e8b84c873f5748ad811f51cd65d69a65 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 4 Jun 2018 17:43:58 -0400 Subject: [PATCH 549/792] Address possible overflow, adhere to style The multiplication by 99 can overflow an int8_t depending on whether the expression is coerced to a regular-sized int (based on the 99 literal). Just to be safe, perform a cast to int16_t in case the coercion does not happen. --- src/MouseWrapper.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 082b1fde..8ca6e150 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -119,12 +119,13 @@ void MouseWrapper_::move(int8_t x, int8_t y) { static int8_t remainderY = 0; if (x != 0 && y != 0) { - // 99 / 140 closely approximates sqrt(2) / 2. - int8_t adjusted_x = x * 99 / 140; - int8_t adjusted_y = y * 99 / 140; + // 99 / 140 closely approximates sqrt(2) / 2. Since integer division + // truncates towards zero we do not need to worry about truncation errors. + int8_t adjustedX = (int16_t)x * 99 / 140; + int8_t adjustedY = (int16_t)y * 99 / 140; - x = (adjusted_x == 0 ? x : adjusted_x); - y = (adjusted_y == 0 ? y : adjusted_y); + if (adjustedX != 0) x = adjustedX; + if (adjustedY != 0) y = adjustedY; } if (x != 0) { From 6190f55c578e93b177ba6e8f78c023b4114ca79c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 6 Jun 2018 11:57:36 +0200 Subject: [PATCH 550/792] Dim the numpad color down from 255 to 160. Having it at the brightest uses too much power, and may result in power use surges when switching between LED modes and NumPad, which in turn can force the operating system to disable the whole device. To avoid this, lower the brightness to 160, a carefull tuned value, also used by the `solidRed` mode in the factory firmware. Fixes #9. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-NumPad.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 0057d08c..70a2299a 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -7,7 +7,7 @@ byte NumPad_::row = 255, NumPad_::col = 255; uint8_t NumPad_::numPadLayer; bool NumPad_::cleanupDone = true; bool NumPad_::originalNumLockState = false; -cRGB numpad_color = CRGB(255, 0, 0); +cRGB numpad_color = CRGB(160, 0, 0); kaleidoscope::EventHandlerResult NumPad_::onSetup(void) { originalNumLockState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); From 28b4e1bb0a929a87a1cf9c358ec99bec702cdb66 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 8 Jun 2018 08:16:43 +0200 Subject: [PATCH 551/792] Initial import Signed-off-by: Gergely Nagy --- .gitignore | 4 + .travis.yml | 21 + COPYING | 674 ++++++++++++++++++++++++++++++++ Makefile | 14 + README.md | 51 +++ library.properties | 10 + src/Kaleidoscope-USB-Quirks.h | 21 + src/kaleidoscope/USB-Quirks.cpp | 35 ++ src/kaleidoscope/USB-Quirks.h | 32 ++ 9 files changed, 862 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 COPYING create mode 100644 Makefile create mode 100644 README.md create mode 100644 library.properties create mode 100644 src/Kaleidoscope-USB-Quirks.h create mode 100644 src/kaleidoscope/USB-Quirks.cpp create mode 100644 src/kaleidoscope/USB-Quirks.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..be16c9be --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.#* +*~ +/hardware/ +/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e7030acf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + irc: + channels: + - "chat.freenode.net#keyboardio" + use_notice: true + skip_join: true + template: + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..3e1f64d2 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Darwin) +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ +else +SKETCHBOOK_DIR ?= $(HOME)/Arduino +endif + +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md new file mode 100644 index 00000000..7fd3a343 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# Kaleidoscope-USB-Quirks + +![status][st:experimental] [![Build Status][travis:image]][travis:status] + + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-USB-Quirks.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-USB-Quirks + + [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 + [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 + [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + +... + +## Using the plugin + +After adding one-shot keys to the keymap, all one needs to do, is enable the +plugin: + +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(USBQuirks, Macros); + +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { + if (macroIndex == 0) { + USBQuirks.toggleKeyboardProtocol(); + } + return MACRO_NONE; +} + +void setup() { + Kaleidoscope.setup(); +} +``` + +## Plugin methods + +The plugin provides one object, `USBQuirks`, which provides the following method: + +### `.toggleKeyboardProtocol()` + +> Toggle between `Boot` and `Report` protocol by detaching, and then +> re-attaching the USB devices, and setting the `BootKeyboard` protocol +> inbetween. +> +> This is most useful when one needs to have a boot keyboard, when one's in a +> BIOS, boot loader, or early password prompt or the like, and the host does not +> explicitly request the boot protocol for one reason or the other. With this +> toggle, we can switch between the two on-demand. diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..00026859 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Kaleidoscope-USB-Quirks +version=0.0.0 +author=Gergely Nagy +maintainer=Gergely Nagy +sentence=USB quirks for Kaleidoscope-based keyboards. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Kaleidoscope-USB-Quirks +architectures=avr +dot_a_linkage=true diff --git a/src/Kaleidoscope-USB-Quirks.h b/src/Kaleidoscope-USB-Quirks.h new file mode 100644 index 00000000..52d3cd85 --- /dev/null +++ b/src/Kaleidoscope-USB-Quirks.h @@ -0,0 +1,21 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-USB-Quirks -- USB Quirks for Kaleidoscope + * Copyright (C) 2018 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include diff --git a/src/kaleidoscope/USB-Quirks.cpp b/src/kaleidoscope/USB-Quirks.cpp new file mode 100644 index 00000000..835429ae --- /dev/null +++ b/src/kaleidoscope/USB-Quirks.cpp @@ -0,0 +1,35 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-USB-Quirks -- USB Quirks for Kaleidoscope + * Copyright (C) 2018 Gergely Nagy + * + * 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 . + */ + +#include + +namespace kaleidoscope { + +void USBQuirks::toggleKeyboardProtocol() { + uint8_t new_protocol = !BootKeyboard.getProtocol(); + + Kaleidoscope.detachFromHost(); + BootKeyboard.default_protocol = new_protocol; + BootKeyboard.setProtocol(new_protocol); + delay(1000); + Kaleidoscope.attachToHost(); +} + +} + +kaleidoscope::USBQuirks USBQuirks; diff --git a/src/kaleidoscope/USB-Quirks.h b/src/kaleidoscope/USB-Quirks.h new file mode 100644 index 00000000..9a03841c --- /dev/null +++ b/src/kaleidoscope/USB-Quirks.h @@ -0,0 +1,32 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-USB-Quirks -- USB Quirks for Kaleidoscope + * Copyright (C) 2018 Gergely Nagy + * + * 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 . + */ + +#pragma once + +#include + +namespace kaleidoscope { +class USBQuirks: public kaleidoscope::Plugin { + public: + USBQuirks() {} + + void toggleKeyboardProtocol(); +}; +} + +extern kaleidoscope::USBQuirks USBQuirks; From fe9c6f8d928c911127d32e71b88b6b9b53f379f0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 8 Jun 2018 06:13:52 +0200 Subject: [PATCH 552/792] Implement a way to detach from / attach to the host These functions can be used to detach from the host, then re-attach, possibly with different properties, without having to reboot the device. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 8 ++++++++ src/Kaleidoscope-Hardware-Model01.h | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 2fc7df61..f699806f 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -251,4 +251,12 @@ void Model01::setKeyscanInterval(uint8_t interval) { rightHand.setKeyscanInterval(interval); } +void Model01::detachFromHost() { + UDCON |= (1 << DETACH); +} + +void Model01::attachToHost() { + UDCON &= ~(1 << DETACH); +} + HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index c8946265..976a54ce 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -29,6 +29,17 @@ class Model01 { void rebootBootloader(); + /** Detaching from / attaching to the host. + * + * These two functions should detach the device from (or attach it to) the + * host, preferably without rebooting the device. Their purpose is to allow + * one to do some configuration inbetween, so the re-attach happens with + * different properties. The device remains powered between these operations, + * only the connection to the host gets severed. + */ + void detachFromHost(); + void attachToHost(); + /* These public functions are things supported by the Model 01, but * aren't necessarily part of the Kaleidoscope API */ From 0b696af8f6b76a5663b53649b4466b555772c47f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 9 Jun 2018 11:09:42 +0200 Subject: [PATCH 553/792] Implement getKeyswitchStateAtPosition, and transition RxCy to KEY_INDEX Implement `getKeyswitchStateAtPosition`, a hardware-agnostic way to peek into the keyswitch state. Also transition the `RxCy` macros to `KEY_INDEX`, to make it easier for hardware with more keys than 64 to implement them, and to make their values unique across a keyboard, not just across a keyboard half. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 13 +++ src/Kaleidoscope-Hardware-Model01.h | 144 ++++++++++++++------------ 2 files changed, 89 insertions(+), 68 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index f699806f..994a6ffa 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -259,4 +259,17 @@ void Model01::attachToHost() { UDCON &= ~(1 << DETACH); } +uint8_t Model01::getKeyswitchStateAtPosition(byte row, byte col) { + if (col <= 7) { + return bitRead(leftHandState.rows[row], 7 - col); + } else { + return bitRead(rightHandState.rows[row], 7 - (col - 8)); + } +} + +uint8_t Model01::getKeyswitchStateAtPosition(uint8_t keyIndex) { + keyIndex--; + return getKeyswitchStateAtPosition(keyIndex / COLS, keyIndex % COLS); +} + HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 976a54ce..c8779720 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -62,6 +62,18 @@ class Model01 { bool isKeyMasked(byte row, byte col); void maskHeldKeys(void); + /** Key switch state + * + * These two methods return the state of the keyswitch at any given position, + * regardless of which half they are on. This is a hardware-agnostic access to + * the key switch states. + * + * The first variant requires a row and a column, the second an index, as + * returned by `KEY_INDEX`. + */ + uint8_t getKeyswitchStateAtPosition(byte row, byte col); + uint8_t getKeyswitchStateAtPosition(uint8_t keyIndex); + keydata_t leftHandState; keydata_t rightHandState; keydata_t previousLeftHandState; @@ -78,77 +90,73 @@ class Model01 { static keydata_t rightHandMask; }; -#define SCANBIT(row,col) ((uint32_t)1 << ((row) * 8 + (7 - (col)))) - - #ifndef DOXYGEN_SHOULD_SKIP_THIS +#define R0C0 KEY_INDEX(0, 0) +#define R0C1 KEY_INDEX(0, 1) +#define R0C2 KEY_INDEX(0, 2) +#define R0C3 KEY_INDEX(0, 3) +#define R0C4 KEY_INDEX(0, 4) +#define R0C5 KEY_INDEX(0, 5) +#define R0C6 KEY_INDEX(0, 6) +#define R0C7 KEY_INDEX(0, 7) +#define R1C0 KEY_INDEX(1, 0) +#define R1C1 KEY_INDEX(1, 1) +#define R1C2 KEY_INDEX(1, 2) +#define R1C3 KEY_INDEX(1, 3) +#define R1C4 KEY_INDEX(1, 4) +#define R1C5 KEY_INDEX(1, 5) +#define R1C6 KEY_INDEX(1, 6) +#define R1C7 KEY_INDEX(1, 7) +#define R2C0 KEY_INDEX(2, 0) +#define R2C1 KEY_INDEX(2, 1) +#define R2C2 KEY_INDEX(2, 2) +#define R2C3 KEY_INDEX(2, 3) +#define R2C4 KEY_INDEX(2, 4) +#define R2C5 KEY_INDEX(2, 5) +#define R2C6 KEY_INDEX(2, 6) +#define R2C7 KEY_INDEX(2, 7) +#define R3C0 KEY_INDEX(3, 0) +#define R3C1 KEY_INDEX(3, 1) +#define R3C2 KEY_INDEX(3, 2) +#define R3C3 KEY_INDEX(3, 3) +#define R3C4 KEY_INDEX(3, 4) +#define R3C5 KEY_INDEX(3, 5) +#define R3C6 KEY_INDEX(3, 6) +#define R3C7 KEY_INDEX(3, 7) -#define R0C0 SCANBIT(0, 0) -#define R0C1 SCANBIT(0, 1) -#define R0C2 SCANBIT(0, 2) -#define R0C3 SCANBIT(0, 3) -#define R0C4 SCANBIT(0, 4) -#define R0C5 SCANBIT(0, 5) -#define R0C6 SCANBIT(0, 6) -#define R0C7 SCANBIT(0, 7) -#define R1C0 SCANBIT(1, 0) -#define R1C1 SCANBIT(1, 1) -#define R1C2 SCANBIT(1, 2) -#define R1C3 SCANBIT(1, 3) -#define R1C4 SCANBIT(1, 4) -#define R1C5 SCANBIT(1, 5) -#define R1C6 SCANBIT(1, 6) -#define R1C7 SCANBIT(1, 7) -#define R2C0 SCANBIT(2, 0) -#define R2C1 SCANBIT(2, 1) -#define R2C2 SCANBIT(2, 2) -#define R2C3 SCANBIT(2, 3) -#define R2C4 SCANBIT(2, 4) -#define R2C5 SCANBIT(2, 5) -#define R2C6 SCANBIT(2, 6) -#define R2C7 SCANBIT(2, 7) -#define R3C0 SCANBIT(3, 0) -#define R3C1 SCANBIT(3, 1) -#define R3C2 SCANBIT(3, 2) -#define R3C3 SCANBIT(3, 3) -#define R3C4 SCANBIT(3, 4) -#define R3C5 SCANBIT(3, 5) -#define R3C6 SCANBIT(3, 6) -#define R3C7 SCANBIT(3, 7) - -#define R0C8 SCANBIT(0, 0) -#define R0C9 SCANBIT(0, 1) -#define R0C10 SCANBIT(0, 2) -#define R0C11 SCANBIT(0, 3) -#define R0C12 SCANBIT(0, 4) -#define R0C13 SCANBIT(0, 5) -#define R0C14 SCANBIT(0, 6) -#define R0C15 SCANBIT(0, 7) -#define R1C8 SCANBIT(1, 0) -#define R1C9 SCANBIT(1, 1) -#define R1C10 SCANBIT(1, 2) -#define R1C11 SCANBIT(1, 3) -#define R1C12 SCANBIT(1, 4) -#define R1C13 SCANBIT(1, 5) -#define R1C14 SCANBIT(1, 6) -#define R1C15 SCANBIT(1, 7) -#define R2C8 SCANBIT(2, 0) -#define R2C9 SCANBIT(2, 1) -#define R2C10 SCANBIT(2, 2) -#define R2C11 SCANBIT(2, 3) -#define R2C12 SCANBIT(2, 4) -#define R2C13 SCANBIT(2, 5) -#define R2C14 SCANBIT(2, 6) -#define R2C15 SCANBIT(2, 7) -#define R3C8 SCANBIT(3, 0) -#define R3C9 SCANBIT(3, 1) -#define R3C10 SCANBIT(3, 2) -#define R3C11 SCANBIT(3, 3) -#define R3C12 SCANBIT(3, 4) -#define R3C13 SCANBIT(3, 5) -#define R3C14 SCANBIT(3, 6) -#define R3C15 SCANBIT(3, 7) +#define R0C8 KEY_INDEX(0, 8) +#define R0C9 KEY_INDEX(0, 9) +#define R0C10 KEY_INDEX(0, 10) +#define R0C11 KEY_INDEX(0, 11) +#define R0C12 KEY_INDEX(0, 12) +#define R0C13 KEY_INDEX(0, 13) +#define R0C14 KEY_INDEX(0, 15) +#define R0C15 KEY_INDEX(0, 16) +#define R1C8 KEY_INDEX(1, 8) +#define R1C9 KEY_INDEX(1, 9) +#define R1C10 KEY_INDEX(1, 10) +#define R1C11 KEY_INDEX(1, 11) +#define R1C12 KEY_INDEX(1, 12) +#define R1C13 KEY_INDEX(1, 13) +#define R1C14 KEY_INDEX(1, 14) +#define R1C15 KEY_INDEX(1, 15) +#define R2C8 KEY_INDEX(2, 8) +#define R2C9 KEY_INDEX(2, 9) +#define R2C10 KEY_INDEX(2, 10) +#define R2C11 KEY_INDEX(2, 11) +#define R2C12 KEY_INDEX(2, 12) +#define R2C13 KEY_INDEX(2, 13) +#define R2C14 KEY_INDEX(2, 14) +#define R2C15 KEY_INDEX(2, 15) +#define R3C8 KEY_INDEX(3, 8) +#define R3C9 KEY_INDEX(3, 9) +#define R3C10 KEY_INDEX(3, 10) +#define R3C11 KEY_INDEX(3, 11) +#define R3C12 KEY_INDEX(3, 12) +#define R3C13 KEY_INDEX(3, 13) +#define R3C14 KEY_INDEX(3, 14) +#define R3C15 KEY_INDEX(3, 15) #define LED_COUNT 64 From 509adfcc416321924fa90e77b2463bcef036ecfe Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 9 Jun 2018 16:11:36 +0200 Subject: [PATCH 554/792] Convert the RxCy macros to constsexprs Move `KEY_INDEX` here, and turn it into a `constexpr` function, `keyIndex`, and convert the `RxCy` macros to constexpr values instead. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.h | 142 +++++++++++++++------------- 1 file changed, 77 insertions(+), 65 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index c8779720..e3ad0a78 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -69,7 +69,7 @@ class Model01 { * the key switch states. * * The first variant requires a row and a column, the second an index, as - * returned by `KEY_INDEX`. + * returned by `keyIndex`. */ uint8_t getKeyswitchStateAtPosition(byte row, byte col); uint8_t getKeyswitchStateAtPosition(uint8_t keyIndex); @@ -92,71 +92,83 @@ class Model01 { #ifndef DOXYGEN_SHOULD_SKIP_THIS -#define R0C0 KEY_INDEX(0, 0) -#define R0C1 KEY_INDEX(0, 1) -#define R0C2 KEY_INDEX(0, 2) -#define R0C3 KEY_INDEX(0, 3) -#define R0C4 KEY_INDEX(0, 4) -#define R0C5 KEY_INDEX(0, 5) -#define R0C6 KEY_INDEX(0, 6) -#define R0C7 KEY_INDEX(0, 7) -#define R1C0 KEY_INDEX(1, 0) -#define R1C1 KEY_INDEX(1, 1) -#define R1C2 KEY_INDEX(1, 2) -#define R1C3 KEY_INDEX(1, 3) -#define R1C4 KEY_INDEX(1, 4) -#define R1C5 KEY_INDEX(1, 5) -#define R1C6 KEY_INDEX(1, 6) -#define R1C7 KEY_INDEX(1, 7) -#define R2C0 KEY_INDEX(2, 0) -#define R2C1 KEY_INDEX(2, 1) -#define R2C2 KEY_INDEX(2, 2) -#define R2C3 KEY_INDEX(2, 3) -#define R2C4 KEY_INDEX(2, 4) -#define R2C5 KEY_INDEX(2, 5) -#define R2C6 KEY_INDEX(2, 6) -#define R2C7 KEY_INDEX(2, 7) -#define R3C0 KEY_INDEX(3, 0) -#define R3C1 KEY_INDEX(3, 1) -#define R3C2 KEY_INDEX(3, 2) -#define R3C3 KEY_INDEX(3, 3) -#define R3C4 KEY_INDEX(3, 4) -#define R3C5 KEY_INDEX(3, 5) -#define R3C6 KEY_INDEX(3, 6) -#define R3C7 KEY_INDEX(3, 7) +/* To be used by the hardware implementations, `keyIndex` tells us the index of + * a key, from which we can figure out the row and column as needed. The index + * starts at one, so that plugins that work with a list of key indexes can use + * zero as a sentinel. This is important, because when we initialize arrays with + * fewer elements than the declared array size, the remaining elements will be + * zero. We can use this to avoid having to explicitly add a sentinel in + * user-facing code. + */ +constexpr byte keyIndex(byte row, byte col) { + return row * COLS + col + 1; +} -#define R0C8 KEY_INDEX(0, 8) -#define R0C9 KEY_INDEX(0, 9) -#define R0C10 KEY_INDEX(0, 10) -#define R0C11 KEY_INDEX(0, 11) -#define R0C12 KEY_INDEX(0, 12) -#define R0C13 KEY_INDEX(0, 13) -#define R0C14 KEY_INDEX(0, 15) -#define R0C15 KEY_INDEX(0, 16) -#define R1C8 KEY_INDEX(1, 8) -#define R1C9 KEY_INDEX(1, 9) -#define R1C10 KEY_INDEX(1, 10) -#define R1C11 KEY_INDEX(1, 11) -#define R1C12 KEY_INDEX(1, 12) -#define R1C13 KEY_INDEX(1, 13) -#define R1C14 KEY_INDEX(1, 14) -#define R1C15 KEY_INDEX(1, 15) -#define R2C8 KEY_INDEX(2, 8) -#define R2C9 KEY_INDEX(2, 9) -#define R2C10 KEY_INDEX(2, 10) -#define R2C11 KEY_INDEX(2, 11) -#define R2C12 KEY_INDEX(2, 12) -#define R2C13 KEY_INDEX(2, 13) -#define R2C14 KEY_INDEX(2, 14) -#define R2C15 KEY_INDEX(2, 15) -#define R3C8 KEY_INDEX(3, 8) -#define R3C9 KEY_INDEX(3, 9) -#define R3C10 KEY_INDEX(3, 10) -#define R3C11 KEY_INDEX(3, 11) -#define R3C12 KEY_INDEX(3, 12) -#define R3C13 KEY_INDEX(3, 13) -#define R3C14 KEY_INDEX(3, 14) -#define R3C15 KEY_INDEX(3, 15) +constexpr byte R0C0 = keyIndex(0, 0); +constexpr byte R0C1 = keyIndex(0, 1); +constexpr byte R0C2 = keyIndex(0, 2); +constexpr byte R0C3 = keyIndex(0, 3); +constexpr byte R0C4 = keyIndex(0, 4); +constexpr byte R0C5 = keyIndex(0, 5); +constexpr byte R0C6 = keyIndex(0, 6); +constexpr byte R0C7 = keyIndex(0, 7); +constexpr byte R1C0 = keyIndex(1, 0); +constexpr byte R1C1 = keyIndex(1, 1); +constexpr byte R1C2 = keyIndex(1, 2); +constexpr byte R1C3 = keyIndex(1, 3); +constexpr byte R1C4 = keyIndex(1, 4); +constexpr byte R1C5 = keyIndex(1, 5); +constexpr byte R1C6 = keyIndex(1, 6); +constexpr byte R1C7 = keyIndex(1, 7); +constexpr byte R2C0 = keyIndex(2, 0); +constexpr byte R2C1 = keyIndex(2, 1); +constexpr byte R2C2 = keyIndex(2, 2); +constexpr byte R2C3 = keyIndex(2, 3); +constexpr byte R2C4 = keyIndex(2, 4); +constexpr byte R2C5 = keyIndex(2, 5); +constexpr byte R2C6 = keyIndex(2, 6); +constexpr byte R2C7 = keyIndex(2, 7); +constexpr byte R3C0 = keyIndex(3, 0); +constexpr byte R3C1 = keyIndex(3, 1); +constexpr byte R3C2 = keyIndex(3, 2); +constexpr byte R3C3 = keyIndex(3, 3); +constexpr byte R3C4 = keyIndex(3, 4); +constexpr byte R3C5 = keyIndex(3, 5); +constexpr byte R3C6 = keyIndex(3, 6); +constexpr byte R3C7 = keyIndex(3, 7); + +constexpr byte R0C8 = keyIndex(0, 8); +constexpr byte R0C9 = keyIndex(0, 9); +constexpr byte R0C10 = keyIndex(0, 10); +constexpr byte R0C11 = keyIndex(0, 11); +constexpr byte R0C12 = keyIndex(0, 12); +constexpr byte R0C13 = keyIndex(0, 13); +constexpr byte R0C14 = keyIndex(0, 15); +constexpr byte R0C15 = keyIndex(0, 16); +constexpr byte R1C8 = keyIndex(1, 8); +constexpr byte R1C9 = keyIndex(1, 9); +constexpr byte R1C10 = keyIndex(1, 10); +constexpr byte R1C11 = keyIndex(1, 11); +constexpr byte R1C12 = keyIndex(1, 12); +constexpr byte R1C13 = keyIndex(1, 13); +constexpr byte R1C14 = keyIndex(1, 14); +constexpr byte R1C15 = keyIndex(1, 15); +constexpr byte R2C8 = keyIndex(2, 8); +constexpr byte R2C9 = keyIndex(2, 9); +constexpr byte R2C10 = keyIndex(2, 10); +constexpr byte R2C11 = keyIndex(2, 11); +constexpr byte R2C12 = keyIndex(2, 12); +constexpr byte R2C13 = keyIndex(2, 13); +constexpr byte R2C14 = keyIndex(2, 14); +constexpr byte R2C15 = keyIndex(2, 15); +constexpr byte R3C8 = keyIndex(3, 8); +constexpr byte R3C9 = keyIndex(3, 9); +constexpr byte R3C10 = keyIndex(3, 10); +constexpr byte R3C11 = keyIndex(3, 11); +constexpr byte R3C12 = keyIndex(3, 12); +constexpr byte R3C13 = keyIndex(3, 13); +constexpr byte R3C14 = keyIndex(3, 14); +constexpr byte R3C15 = keyIndex(3, 15); #define LED_COUNT 64 From c45e7d1c1d5da0d5c78eb7a8d4c81968814dfdb6 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sat, 9 Jun 2018 17:14:47 -0400 Subject: [PATCH 555/792] Fix diagonal speed limit and remainder calculation --- src/MouseWrapper.cpp | 37 ++++++++++++++++++++++++------------- src/MouseWrapper.h | 1 + 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 8ca6e150..2c3af984 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -14,6 +14,7 @@ boolean MouseWrapper_::is_warping; uint8_t MouseWrapper_::accelStep; uint8_t MouseWrapper_::speedLimit = 127; +uint8_t MouseWrapper_::subpixelsPerPixel = 16; MouseWrapper_::MouseWrapper_(void) { } @@ -112,39 +113,49 @@ uint8_t MouseWrapper_::acceleration(uint8_t cycles) { return i; } +// Get the diagonalized version of a value, i.e. value * sqrt(2) / 2. If the +// value ends up being zero, return the original value instead. +static int16_t diagonalize(int16_t value) { + // 99 / 140 closely approximates sqrt(2) / 2. Since integer division + // truncates towards zero we do not need to worry about truncation errors. + int16_t diagonalValue = value * 99 / 140; + return (diagonalValue == 0 ? value : diagonalValue); +} + void MouseWrapper_::move(int8_t x, int8_t y) { int16_t moveX = 0; int16_t moveY = 0; static int8_t remainderX = 0; static int8_t remainderY = 0; + int16_t effectiveSpeedLimit = speedLimit; if (x != 0 && y != 0) { - // 99 / 140 closely approximates sqrt(2) / 2. Since integer division - // truncates towards zero we do not need to worry about truncation errors. - int8_t adjustedX = (int16_t)x * 99 / 140; - int8_t adjustedY = (int16_t)y * 99 / 140; + // For diagonal movements, we apply a diagonalized speed limit. The + // effective speed limit is set based on whether we are moving diagonally. + effectiveSpeedLimit = diagonalize(effectiveSpeedLimit); - if (adjustedX != 0) x = adjustedX; - if (adjustedY != 0) y = adjustedY; + x = diagonalize(x); + y = diagonalize(y); } if (x != 0) { moveX = remainderX + (x * acceleration(accelStep)); - if (moveX > (int16_t)speedLimit) moveX = speedLimit; - else if (moveX < -(int16_t)speedLimit) moveX = -speedLimit; + if (moveX > effectiveSpeedLimit) moveX = effectiveSpeedLimit; + else if (moveX < -effectiveSpeedLimit) moveX = -effectiveSpeedLimit; } + if (y != 0) { moveY = remainderY + (y * acceleration(accelStep)); - if (moveY > (int16_t)speedLimit) moveY = speedLimit; - else if (moveY < -(int16_t)speedLimit) moveY = -speedLimit; + if (moveY > effectiveSpeedLimit) moveY = effectiveSpeedLimit; + else if (moveY < -effectiveSpeedLimit) moveY = -effectiveSpeedLimit; } end_warping(); // move by whole pixels, not subpixels - kaleidoscope::hid::moveMouse(moveX >> 4, moveY >> 4, 0); + kaleidoscope::hid::moveMouse(moveX / subpixelsPerPixel, moveY / subpixelsPerPixel, 0); // save leftover subpixel movements for later - remainderX = moveX & 0x0f; - remainderY = moveY & 0x0f; + remainderX = moveX - moveX / subpixelsPerPixel * subpixelsPerPixel; + remainderY = moveY - moveY / subpixelsPerPixel * subpixelsPerPixel; } MouseWrapper_ MouseWrapper; diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 3bb467fc..b07c8b5e 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -34,6 +34,7 @@ class MouseWrapper_ { static void release_button(uint8_t button); static uint8_t accelStep; static uint8_t speedLimit; + static uint8_t subpixelsPerPixel; static uint8_t warp_grid_size; private: From f469015346535cb864a340bf8eb317d268943248 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 10 Jun 2018 13:40:55 +0200 Subject: [PATCH 556/792] Better keyswitch state APIs Instead of `getKeyswitchStateAtPosition`, which is long, unintuitive and feels wrong too, introduce `isKeyswitchPressed`, shorter, better, more reasonable (because it returns a bool - we support only two states anyway!). Additionally, add `pressedKeyswitchCount()`, which returns the number of key switches pressed. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 20 +++++++++++---- src/Kaleidoscope-Hardware-Model01.h | 37 +++++++++++++++++++++------ 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 994a6ffa..8ce92033 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -259,17 +259,27 @@ void Model01::attachToHost() { UDCON &= ~(1 << DETACH); } -uint8_t Model01::getKeyswitchStateAtPosition(byte row, byte col) { +bool Model01::isKeyswitchPressed(byte row, byte col) { if (col <= 7) { - return bitRead(leftHandState.rows[row], 7 - col); + return (bitRead(leftHandState.rows[row], 7 - col) != 0); } else { - return bitRead(rightHandState.rows[row], 7 - (col - 8)); + return (bitRead(rightHandState.rows[row], 7 - (col - 8)) != 0); } } -uint8_t Model01::getKeyswitchStateAtPosition(uint8_t keyIndex) { +bool Model01::isKeyswitchPressed(uint8_t keyIndex) { keyIndex--; - return getKeyswitchStateAtPosition(keyIndex / COLS, keyIndex % COLS); + return isKeyswitchPressed(keyIndex / COLS, keyIndex % COLS); +} + +uint8_t Model01::pressedKeyswitchCount() { + uint8_t count = 0; + + for (uint8_t i = 0; i < 32; i++) { + count += bitRead(leftHandState.all, i) + bitRead(rightHandState.all, i); + } + + return count; } HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index e3ad0a78..436043ae 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -62,17 +62,38 @@ class Model01 { bool isKeyMasked(byte row, byte col); void maskHeldKeys(void); - /** Key switch state + /** Key switch states * - * These two methods return the state of the keyswitch at any given position, - * regardless of which half they are on. This is a hardware-agnostic access to - * the key switch states. + * These methods offer a way to peek at the key switch states, for those cases + * where we need to deal with the state closest to the hardware. Some methods + * offer a way to check if a key is pressed, others return the number of + * pressed keys. + */ + /** + * Check if a key is pressed at a given position. + * + * @param row is the row the key is located at in the matrix. + * @param col is the column the key is located at in the matrix. + * + * @returns true if the key is pressed, false otherwise. + */ + bool isKeyswitchPressed(byte row, byte col); + /** + * Check if a key is pressed at a given position. + * + * @param keyIndex is the key index, as calculated by `keyIndex`. + * + * @note Key indexes start at 1, not 0! + * + * @returns true if the key is pressed, false otherwise. + */ + bool isKeyswitchPressed(uint8_t keyIndex); + /** + * Check the number of key switches currently pressed. * - * The first variant requires a row and a column, the second an index, as - * returned by `keyIndex`. + * @returns the number of keys pressed. */ - uint8_t getKeyswitchStateAtPosition(byte row, byte col); - uint8_t getKeyswitchStateAtPosition(uint8_t keyIndex); + uint8_t pressedKeyswitchCount(); keydata_t leftHandState; keydata_t rightHandState; From 5a6e0fa12aa39e2f59b35283a3d6afe909b8f21e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 10 Jun 2018 13:52:30 +0200 Subject: [PATCH 557/792] Complete redesign of the plugin Instead of using a list of left/right-hand states and an overrideable global callback, use a map of action and key-list pairs. This makes the plugin much more portable, does not require any hardware-specific knowledge within the plugin, and does not require us to treat the hands separately. This in turn, results in a friendlier user interface, at the cost of limiting the maximum length of a combination to five keys. A small price to pay. Signed-off-by: Gergely Nagy --- README.md | 76 +++++++++--------------------- examples/MagicCombo/MagicCombo.ino | 22 +++------ src/Kaleidoscope/MagicCombo.cpp | 48 ++++++++----------- src/Kaleidoscope/MagicCombo.h | 23 +++++++-- 4 files changed, 66 insertions(+), 103 deletions(-) diff --git a/README.md b/README.md index abed81a3..dd99d7d7 100644 --- a/README.md +++ b/README.md @@ -18,88 +18,54 @@ This can be used to tie complex actions to key chords. ## Using the extension -To use the extension, we must include the header, create an array of combos we -want to work with, let the plugin know we want to work with those, and then use -a special function to handle the combos: +To use the extension, we must include the header, create actions for the magic +combos we want to trigger, and set up a mapping: ```c++ #include #include #include -void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand) { - switch (combo_index) { - case 0: - Macros.type(PSTR("It's a kind of magic!")); - break; - } +enum { KIND_OF_MAGIC }; + +void kindOfMagic(uint8_t combo_index) { + Macros.type(PSTR("It's a kind of magic!")); } -static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { - { - R3C6, // left palm key - R3C9 // right palm key - }, - {0, 0} -}; +USE_MAGIC_COMBOS( +[KIND_OF_MAGIC] = { + .action = kindOfMagic, + .keys = {R3C6, R3C9} // Left Fn + Right Fn +}); KALEIDOSCOPE_INIT_PLUGINS(MagicCombo, Macros); void setup() { Kaleidoscope.setup(); - - MagicCombo.magic_combos = magic_combos; } ``` -The combo list **must** reside in `PROGMEM`, and is a list of tuples. Each -element in the array has two fields: the left hand state, and the right hand -state upon which to trigger the custom action. Both of these are bit fields, -each bit set tells the extension that the key with that index must be held for -the action to trigger. It is recommended to use the `RxCy` macros of the core -`KaleidoscopeFirmware`, and *or* them together to form a bitfield. -To see how the `RxCy` coordinates correspond to the physical keys of your -keyboard, you'll have to consult the documentation for the keyboard. -Below, you can find a diagram showing the layout for the Keyboardio Model 01. - -The combo list **must** end with an element containing zero values for both the -left and the right halves. +It is recommended to use the `RxCy` macros of the core firmware to set the keys +that are part of a combination. -## Extension methods +## Plugin properties The extension provides a `MagicCombo` singleton object, with the following -methods and properties: - -### `.magic_combos` - -> Setting this property lets the plugin know which combinations of key presses -> we are interested in. If any of these are found active, the -> `magicComboActions()` function will be called. +property: ### `.min_interval` -> Restrict the magic action to fire at most once every `minInterval` +> Restrict the magic action to fire at most once every `min_interval` > milliseconds. > > Defaults to 500. -## Overrideable methods +## Plugin callbacks -Whenever an combination is found to be held, the extension will trigger an -action, in each scan cycle until the keys remain held. This is done by calling -the overrideable `magicComboActions` function: - -### `magicComboActions(combo_index, left_hand, right_hand)` - -> Called whenever a combination is found to be held. The function by default -> does nothing, and it is recommended to override it from within the Sketch. -> -> The first argument will be the index in the combo list, the other two are the -> key states on the left and right halves, respectively. -> -> Plugins that build upon this extensions *should not* override this function, -> but provide helpers that can be called from it. An override should only happen -> in the Sketch. +Whenever a combination is found to be held, the plugin will trigger the +specified action, which is just a regular method with a single `uint8_t` +argument: the index of the magic combo. This function will be called repeatedly +(every `min_interval` milliseconds) while the combination is held. ## Further reading diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index 471a4cae..9d16b455 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -20,21 +20,15 @@ #include #include -void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand) { - switch (combo_index) { - case 0: - Macros.type(PSTR("It's a kind of magic!")); - break; - } +enum { + KIND_OF_MAGIC +}; + +void kindOfMagic(uint8_t combo_index) { + Macros.type(PSTR("It's a kind of magic!")); } -static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { - { - R3C6, // left palm key - R3C9 // right palm key - }, - {0, 0} -}; +USE_MAGIC_COMBOS([KIND_OF_MAGIC] = {.action = kindOfMagic, .keys = {R3C6, R3C9}}); // *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { @@ -62,8 +56,6 @@ KALEIDOSCOPE_INIT_PLUGINS(MagicCombo, Macros); void setup() { Kaleidoscope.setup(); - - MagicCombo.magic_combos = magic_combos; } void loop() { diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index b220717b..4332ce35 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -18,42 +18,35 @@ #include -#if defined(ARDUINO_AVR_MODEL01) -#define LEFTHANDSTATE KeyboardHardware.leftHandState -#define RIGHTHANDSTATE KeyboardHardware.rightHandState -#endif - -#if defined(ARDUINO_AVR_SHORTCUT) -#define LEFTHANDSTATE KeyboardHardware.scanner.leftHandState -#define RIGHTHANDSTATE KeyboardHardware.scanner.rightHandState -#endif - namespace kaleidoscope { -const MagicCombo::combo_t *MagicCombo::magic_combos; uint16_t MagicCombo::min_interval = 500; uint32_t MagicCombo::end_time_; EventHandlerResult MagicCombo::beforeReportingState() { - if (!magic_combos) - return EventHandlerResult::OK; + for (byte i = 0; i < magiccombo::combos_length; i++) { + bool match = true; + byte j; - for (byte i = 0;; i++) { - combo_t combo; + for (j = 0; j < MAX_COMBO_LENGTH; j++) { + int8_t comboKey = pgm_read_byte(&(magiccombo::combos[i].keys[j])); - combo.left_hand = pgm_read_dword(&(magic_combos[i].left_hand)); - combo.right_hand = pgm_read_dword(&(magic_combos[i].right_hand)); + if (comboKey == 0) + break; - if (combo.left_hand == 0 && combo.right_hand == 0) - break; + match &= KeyboardHardware.isKeyswitchPressed(comboKey); + if (!match) + break; + } - if (LEFTHANDSTATE.all == combo.left_hand && - RIGHTHANDSTATE.all == combo.right_hand) { - if (millis() >= end_time_) { - magicComboActions(i, combo.left_hand, combo.right_hand); - end_time_ = millis() + min_interval; - } - break; + if (j != KeyboardHardware.pressedKeyswitchCount()) + match = false; + + if (match && (millis() >= end_time_)) { + ComboAction action = (ComboAction) pgm_read_ptr(&(magiccombo::combos[i].action)); + + (*action)(i); + end_time_ = millis() + min_interval; } } @@ -75,7 +68,4 @@ void MagicCombo::legacyLoopHook(bool is_post_clear) { }; -__attribute__((weak)) void magicComboActions(uint8_t comboIndex, uint32_t left_hand, uint32_t right_hand) { -} - kaleidoscope::MagicCombo MagicCombo; diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 8c8a3dc8..be3419dc 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -20,17 +20,29 @@ #include +#define MAX_COMBO_LENGTH 5 + +#define USE_MAGIC_COMBOS(...) \ + namespace kaleidoscope { \ + namespace magiccombo { \ + const kaleidoscope::MagicCombo::Combo combos[] PROGMEM = {__VA_ARGS__}; \ + \ + const uint8_t combos_length = sizeof(combos) / sizeof(*combos); \ + } \ + } + namespace kaleidoscope { class MagicCombo : public kaleidoscope::Plugin { public: + typedef void (*ComboAction)(uint8_t combo_index); typedef struct { - uint32_t left_hand, right_hand; - } combo_t; + ComboAction action; + int8_t keys[MAX_COMBO_LENGTH + 1]; + } Combo; MagicCombo(void) {} - static const combo_t *magic_combos; static uint16_t min_interval; EventHandlerResult beforeReportingState(); @@ -45,8 +57,11 @@ class MagicCombo : public kaleidoscope::Plugin { static uint32_t end_time_; }; +namespace magiccombo { +extern const MagicCombo::Combo combos[]; +extern const uint8_t combos_length; } -void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand); +} extern kaleidoscope::MagicCombo MagicCombo; From 417b7de5c1cf1cb42fcae8a7333c093966354f92 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 10 Jun 2018 13:54:54 +0200 Subject: [PATCH 558/792] Migrate to KeyboardHardware.isKeyswitchPressed() & .pressedKeyswitchCount() The old `RxCy` macros were recently changed to be key indexes instead of per-hand bit indexes, and `KeyboardHardware.isKeyswitchPressed()` and `KeyboardHardware.pressedKeyswitchCount()` were introduced as a way to peek into the keyswitch state. This little change migrates TestMode to use them. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Model01-TestMode.cpp | 15 ++++++++++----- src/Kaleidoscope-Model01-TestMode.h | 4 ---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index fe27c90a..abdf4d76 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -27,9 +27,10 @@ void TestMode_::legacyLoopHook(bool is_post_clear) { #endif kaleidoscope::EventHandlerResult TestMode_::beforeReportingState() { - if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO -// && KeyboardHardware.rightHandState.all == combo.rightHand - ) { + if (KeyboardHardware.isKeyswitchPressed(R0C0) && + KeyboardHardware.isKeyswitchPressed(R0C6) && + KeyboardHardware.isKeyswitchPressed(R3C6) && + KeyboardHardware.pressedKeyswitchCount() == 3) { run_tests(); } return kaleidoscope::EventHandlerResult::OK; @@ -41,7 +42,8 @@ void TestMode_::waitForKeypress() { } while (1) { KeyboardHardware.readMatrix(); - if (KeyboardHardware.leftHandState.all == R3C6 + if (KeyboardHardware.isKeyswitchPressed(R3C6) + && KeyboardHardware.pressedKeyswitchCount() == 1 && KeyboardHardware.previousLeftHandState.all == 0) { break; } @@ -127,7 +129,10 @@ void TestMode_::testMatrix() { // taps during LED test mode. while (1) { KeyboardHardware.readMatrix(); - if (KeyboardHardware.leftHandState.all == TEST_MODE_KEY_COMBO) { + if (KeyboardHardware.isKeyswitchPressed(R0C0) && + KeyboardHardware.isKeyswitchPressed(R0C6) && + KeyboardHardware.isKeyswitchPressed(R3C6) && + KeyboardHardware.pressedKeyswitchCount() == 3) { break; } for (byte row = 0; row < 4; row++) { diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 5be46c75..598ad396 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -3,10 +3,6 @@ #include #include "Kaleidoscope.h" -#define TEST_MODE_KEY_COMBO (R0C0 | R0C6 | R3C6) - - - typedef struct { uint8_t cyclesSinceStateChange[32]; uint32_t badKeys; From d9da1d717afbea14cb140c34df6ffd3425263a9a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 10 Jun 2018 15:12:26 +0200 Subject: [PATCH 559/792] Add an UPGRADING.md document, and a helpful error message When using the old API, fail with a helpful error message that points to `UPGRADING.md`, which explains in simple detail the migration process. Signed-off-by: Gergely Nagy --- UPGRADING.md | 112 +++++++++++++++++++++++++++++ examples/MagicCombo/MagicCombo.ino | 18 +++++ src/Kaleidoscope/MagicCombo.h | 16 +++++ 3 files changed, 146 insertions(+) create mode 100644 UPGRADING.md diff --git a/UPGRADING.md b/UPGRADING.md new file mode 100644 index 00000000..f0db1c28 --- /dev/null +++ b/UPGRADING.md @@ -0,0 +1,112 @@ +Breaking changes in `MagicCombo` +================================ + +To make `MagicCombo` more portable, and easier to use, we had to break the API +previously provided, there was no way to maintain backwards compatibility. This +document is an attempt at guiding you through the process of migrating from the +earlier API to the current one. + +Migration should be a straightforward process, but if you get stuck, please feel +free to [open an issue][gh:issues], or start a thread on the [forums][forums], +and we'll help you with it. + + [gh:issues]: https://github.com/keyboardio/Kaleidoscope-MagicCombo/issues + [forums]: https://community.keyboard.io/ + +## The old API + +```c++ +void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand) { + switch (combo_index) { + case 0: + Macros.type(PSTR("It's a kind of magic!")); + break; + } +} + +static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { + { + R3C6, // left palm key + R3C9 // right palm key + }, + {0, 0} +}; + +void setup() { + Kaleidoscope.setup(); + + MagicCombo.magic_combos = magic_combos; +} +``` + +Previsouly, we used a global, overrideable function (`magicComboActions`) to run +the actions of all magic combos, similar to how macros are set up to work. +Unlike macros, magic combos can't be defined in the keymap, due to technical +reasons, so we had to use a separate list - `magic_combos` in our example. We +also needed to tell `MagicCombo` to use this list, which is what we've done in +`setup()`. + +## The new API + +```c++ +void kindOfMagic(uint8_t combo_index) { + Macros.type(PSTR("It's a kind of magic!")); +} + +USE_MAGIC_COMBOS({ + .action = kindOfMagic, + .keys = {R3C6, R3C9} // Left Fn + Right Fn +}); +``` + +The new API is much shorter, and is inspired by the way the [Leader][leader] +plugin works: instead of having a list, and a dispatching function like +`magicComboActions`, we include the action method in the list too! + + [leader]: https://github.com/keyboardio/Kaleidoscope-Leader + +We also don't make a difference between left- and right-hand anymore, you can +just list keys for either in the same list. This will be very handy for +non-split keyboards. + +## Migration + +First of all, we'll need to split up `magicComboActions` into separate +functions. Each function should have a unique name, but their shape is always +the same: + +```c++ +void someFunction(uint8_t combo_index) { + // Do some action here +} +``` + +Copy the body of each `case` statement of `magicComboActions`, and copy them one +by one into appropriately named functions of the above shape. You can name your +functions anything you want, the only constraint is that they need to be valid +C++ function names. The plugin itself does nothing with the name, we'll +reference them later in the `USE_MAGIC_COMBOS` helper macro. + +Once `magicComboActions` is split up, we need to migrate the `magic_combos` list +to the new format. That list had to be terminated by a `{0, 0}` entry, the new +method does not require such a sentinel at the end. + +For each entry in `magic_combos`, add an entry to `USE_MAGIC_COMBOS`, with the +following structure: + +```c++ +{.action = theActionFunction, + .keys = { /* list of keys */ }} +``` + +The list of keys are the same `RxCy` constants you used for `magic_combos`, with +the left- and right hands combined. The action, `theActionFunction`, is the +function you extracted the magic combo action to. It's the function that has the +same body as the `case` statement in `magicComboActions` had. + +And this is all there is to it. + +If your actions made use of the `left_hand` or `right_hand` arguments of +`magicComboActions`, the same information is still available. But that's a bit +more involved to get to, out of scope for this simple migration guide. Please +open an issue, or ask for help on the forums, and we'll help you. diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index 9d16b455..d09a11b2 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -30,6 +30,22 @@ void kindOfMagic(uint8_t combo_index) { USE_MAGIC_COMBOS([KIND_OF_MAGIC] = {.action = kindOfMagic, .keys = {R3C6, R3C9}}); +void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand) { + switch (combo_index) { + case 0: + Macros.type(PSTR("It's a kind of magic!")); + break; + } +} + +static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { + { + R3C6, // left palm key + R3C9 // right palm key + }, + {0, 0} +}; + // *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED @@ -56,6 +72,8 @@ KALEIDOSCOPE_INIT_PLUGINS(MagicCombo, Macros); void setup() { Kaleidoscope.setup(); + + MagicCombo.magic_combos = magic_combos; } void loop() { diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index be3419dc..902fe84e 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -31,6 +31,13 @@ } \ } +#define _MAGICCOMBO_API_CHANGE \ + "The MagicCombo API changed in an incompatible way, you will need to\n" \ + "upgrade.\n" \ + "\n" \ + "Please see the `UPGRADING.md` document shipped with the source:\n" \ + " https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/UPGRADING.md" + namespace kaleidoscope { class MagicCombo : public kaleidoscope::Plugin { @@ -40,9 +47,18 @@ class MagicCombo : public kaleidoscope::Plugin { ComboAction action; int8_t keys[MAX_COMBO_LENGTH + 1]; } Combo; + typedef struct combo_t { + uint32_t left_hand, right_hand; + + combo_t& operator=(combo_t &) { + static_assert(false, _DEPRECATE(_MAGICCOMBO_API_CHANGE)); + return *this; + } + } combo_t; MagicCombo(void) {} + static const combo_t *magic_combos; static uint16_t min_interval; EventHandlerResult beforeReportingState(); From 9592ef1ae85cc50337bfb06fc3db8e1606b6938c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 15 Jun 2018 15:26:44 +0200 Subject: [PATCH 560/792] Make the hue configurable Fixes #3. Signed-off-by: Gergely Nagy --- README.md | 11 ++++++++--- src/Kaleidoscope-LEDEffect-Breathe.cpp | 2 +- src/Kaleidoscope-LEDEffect-Breathe.h | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2c3743db..853ab20d 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,15 @@ void setup() { } ``` -## Plugin methods +## Plugin properties -The plugin provides the `LEDBreatheEffect` object, which has no public methods or -properties, outside of those provided by all LED modes. +The plugin provides the `LEDBreatheEffect` object, which has a single property: + +### `.hue` + +> The hue of the breathe effect. +> +> Defaults to 170. ## Dependencies diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp index 6551bfbb..d7c9484c 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -2,7 +2,7 @@ namespace kaleidoscope { void LEDBreatheEffect::update(void) { - cRGB color = breath_compute(); + cRGB color = breath_compute(hue); ::LEDControl.set_all_leds_to(color); } } diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index b9cad307..715bd819 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -8,6 +8,8 @@ class LEDBreatheEffect : public LEDMode { public: LEDBreatheEffect(void) {} + uint8_t hue = 170; + protected: void update(void) final; }; From 4b04d506c414ae5685b0fe04b010c4addb66c1f6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 15 Jun 2018 15:31:41 +0200 Subject: [PATCH 561/792] Make the numpad highlight color configurable Fixes #11. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-NumPad.cpp | 8 ++++---- src/Kaleidoscope-NumPad.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 70a2299a..16263e38 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -7,7 +7,7 @@ byte NumPad_::row = 255, NumPad_::col = 255; uint8_t NumPad_::numPadLayer; bool NumPad_::cleanupDone = true; bool NumPad_::originalNumLockState = false; -cRGB numpad_color = CRGB(160, 0, 0); +cRGB NumPad_::color = CRGB(160, 0, 0); kaleidoscope::EventHandlerResult NumPad_::onSetup(void) { originalNumLockState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); @@ -57,7 +57,7 @@ kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { if ((k != layer_key) || (k == Key_NoKey) || (k.flags != KEY_FLAGS)) { LEDControl.refreshAt(r, c); } else { - LEDControl.setCrgbAt(r, c, numpad_color); + LEDControl.setCrgbAt(r, c, color); } } } @@ -65,8 +65,8 @@ kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { if (row > ROWS || col > COLS) return kaleidoscope::EventHandlerResult::OK; - cRGB color = breath_compute(); - LEDControl.setCrgbAt(row, col, color); + cRGB lock_color = breath_compute(); + LEDControl.setCrgbAt(row, col, lock_color); return kaleidoscope::EventHandlerResult::OK; } diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index 6371c534..d6b73eaf 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -9,6 +9,7 @@ class NumPad_ : public kaleidoscope::Plugin { NumPad_(void) {} static uint8_t numPadLayer; + static cRGB color; kaleidoscope::EventHandlerResult onSetup(void); kaleidoscope::EventHandlerResult afterEachCycle(); From 604ebc448d613576027dabe2f2793c3607ebed4c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 15 Jun 2018 15:32:59 +0200 Subject: [PATCH 562/792] Make the NumLock breathe's hue configurable too Signed-off-by: Gergely Nagy --- src/Kaleidoscope-NumPad.cpp | 3 ++- src/Kaleidoscope-NumPad.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 16263e38..c9860238 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -8,6 +8,7 @@ uint8_t NumPad_::numPadLayer; bool NumPad_::cleanupDone = true; bool NumPad_::originalNumLockState = false; cRGB NumPad_::color = CRGB(160, 0, 0); +uint8_t NumPad_::lock_hue = 170; kaleidoscope::EventHandlerResult NumPad_::onSetup(void) { originalNumLockState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); @@ -65,7 +66,7 @@ kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { if (row > ROWS || col > COLS) return kaleidoscope::EventHandlerResult::OK; - cRGB lock_color = breath_compute(); + cRGB lock_color = breath_compute(lock_hue); LEDControl.setCrgbAt(row, col, lock_color); return kaleidoscope::EventHandlerResult::OK; diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index d6b73eaf..aeb534b1 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -10,6 +10,7 @@ class NumPad_ : public kaleidoscope::Plugin { static uint8_t numPadLayer; static cRGB color; + static uint8_t lock_hue; kaleidoscope::EventHandlerResult onSetup(void); kaleidoscope::EventHandlerResult afterEachCycle(); From 7603cc813e6eb67a95d8aafeb4031cceb41208e1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 16 Jun 2018 13:32:42 +0200 Subject: [PATCH 563/792] Use __builtin_popcountl() in pressedKeyswitchCount() Instead of iterating through all the bits, use `__builtin_popcountl()`, provided by gcc, which should be considerably more efficient. Fixes #27. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Hardware-Model01.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index 8ce92033..a7d6474d 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -273,13 +273,7 @@ bool Model01::isKeyswitchPressed(uint8_t keyIndex) { } uint8_t Model01::pressedKeyswitchCount() { - uint8_t count = 0; - - for (uint8_t i = 0; i < 32; i++) { - count += bitRead(leftHandState.all, i) + bitRead(rightHandState.all, i); - } - - return count; + return __builtin_popcountl(leftHandState.all) + __builtin_popcountl(rightHandState.all); } HARDWARE_IMPLEMENTATION KeyboardHardware; From 2cdee29d6094cc57a6e98544d3481119def6390a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 17 Jun 2018 08:19:07 +0200 Subject: [PATCH 564/792] Fix the example not to use the old API Signed-off-by: Gergely Nagy --- examples/MagicCombo/MagicCombo.ino | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index d09a11b2..9d16b455 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -30,22 +30,6 @@ void kindOfMagic(uint8_t combo_index) { USE_MAGIC_COMBOS([KIND_OF_MAGIC] = {.action = kindOfMagic, .keys = {R3C6, R3C9}}); -void magicComboActions(uint8_t combo_index, uint32_t left_hand, uint32_t right_hand) { - switch (combo_index) { - case 0: - Macros.type(PSTR("It's a kind of magic!")); - break; - } -} - -static const kaleidoscope::MagicCombo::combo_t magic_combos[] PROGMEM = { - { - R3C6, // left palm key - R3C9 // right palm key - }, - {0, 0} -}; - // *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED @@ -72,8 +56,6 @@ KALEIDOSCOPE_INIT_PLUGINS(MagicCombo, Macros); void setup() { Kaleidoscope.setup(); - - MagicCombo.magic_combos = magic_combos; } void loop() { From fac99ec57b00ffbeba3737dbc82864a56996fef0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 17 Jun 2018 08:19:48 +0200 Subject: [PATCH 565/792] Fix the error reporting on old-style API Unfortunately, the way we reported the use of an old-style API also triggered when not using it. Change that to only trigger when we DO use the old API, by marking the `combo_t` constructor private. Unfortunately, this does not allow us to use a custom error message. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MagicCombo.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 902fe84e..958f7695 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -31,13 +31,6 @@ } \ } -#define _MAGICCOMBO_API_CHANGE \ - "The MagicCombo API changed in an incompatible way, you will need to\n" \ - "upgrade.\n" \ - "\n" \ - "Please see the `UPGRADING.md` document shipped with the source:\n" \ - " https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/UPGRADING.md" - namespace kaleidoscope { class MagicCombo : public kaleidoscope::Plugin { @@ -50,10 +43,8 @@ class MagicCombo : public kaleidoscope::Plugin { typedef struct combo_t { uint32_t left_hand, right_hand; - combo_t& operator=(combo_t &) { - static_assert(false, _DEPRECATE(_MAGICCOMBO_API_CHANGE)); - return *this; - } + private: + combo_t(byte left, byte right) {} } combo_t; MagicCombo(void) {} From b756217750d0fc51d84e4a8b9122ce57896068cb Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 17 Jun 2018 10:39:28 +0200 Subject: [PATCH 566/792] Override onSetup when using a compatibility layer The default `onSetup` will call `.begin`, to support initializing plugins using the V1 plugins while using `KALEIDOSCOPE_INIT_PLUGINS`. However, plugins that implement a compatibility layer so that they can be used with both the new API, and with `Kaleidoscope.use()` will have a `.begin` method too. Which the default `onSetup` will call, and we'll register the compatibility layer too, in addition to the new-style event handlers. This results in many things running twice, which leads to all kinds of problems. For this reason, override `onSetup`, so that it does not call `begin`. When used with `Kaleidoscope.use()`, the plugin will still work, so compatibility is maintained. But the bug is now gone. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index d3c240e1..a727b125 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -58,6 +58,10 @@ class Macros_ : public kaleidoscope::Plugin { static byte row, col; #if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + kaleidoscope::EventHandlerResult onSetup() { + return kaleidoscope::EventHandlerResult::OK; + } + protected: void begin(); static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); From 948b3d40b730bd3ecba3e30b3c77709a4d89419f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 17 Jun 2018 11:03:57 +0200 Subject: [PATCH 567/792] Override onSetup when using a compatibility layer The default `onSetup` will call `.begin`, to support initializing plugins using the V1 plugins while using `KALEIDOSCOPE_INIT_PLUGINS`. However, plugins that implement a compatibility layer so that they can be used with both the new API, and with `Kaleidoscope.use()` will have a `.begin` method too. Which the default `onSetup` will call, and we'll register the compatibility layer too, in addition to the new-style event handlers. This results in many things running twice, which leads to all kinds of problems. For this reason, override `onSetup`, so that it does not call `begin`. When used with `Kaleidoscope.use()`, the plugin will still work, so compatibility is maintained. But the bug is now gone. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/HostPowerManagement.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Kaleidoscope/HostPowerManagement.h b/src/Kaleidoscope/HostPowerManagement.h index 01b9d4f5..72a0826f 100644 --- a/src/Kaleidoscope/HostPowerManagement.h +++ b/src/Kaleidoscope/HostPowerManagement.h @@ -41,6 +41,10 @@ class HostPowerManagement : public kaleidoscope::Plugin { EventHandlerResult beforeEachCycle(); #if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + kaleidoscope::EventHandlerResult onSetup() { + return kaleidoscope::EventHandlerResult::OK; + } + protected: void begin(); static void legacyLoopHook(bool is_post_clear); From f97313f5b0cc04168a19098296dca52e3e2c8f80 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 17 Jun 2018 11:11:50 +0200 Subject: [PATCH 568/792] Override onSetup when using a compatibility layer The default `onSetup` will call `.begin`, to support initializing plugins using the V1 plugins while using `KALEIDOSCOPE_INIT_PLUGINS`. However, plugins that implement a compatibility layer so that they can be used with both the new API, and with `Kaleidoscope.use()` will have a `.begin` method too. Which the default `onSetup` will call, and we'll register the compatibility layer too, in addition to the new-style event handlers. This results in many things running twice, which leads to all kinds of problems. For this reason, override `onSetup`, so that it does not call `begin`. When used with `Kaleidoscope.use()`, the plugin will still work, so compatibility is maintained. But the bug is now gone. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-BootGreeting.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index 92e4ace9..d45e23dc 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -35,6 +35,10 @@ class BootGreetingEffect : public kaleidoscope::Plugin { EventHandlerResult afterEachCycle(); #if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + kaleidoscope::EventHandlerResult onSetup() { + return kaleidoscope::EventHandlerResult::OK; + } + protected: void begin(); static void legacyLoopHook(bool is_post_clear); From 98563a7afd66e1667d5ad19e84511150f7a1cdcb Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 17 Jun 2018 11:13:37 +0200 Subject: [PATCH 569/792] Override onSetup when using a compatibility layer The default `onSetup` will call `.begin`, to support initializing plugins using the V1 plugins while using `KALEIDOSCOPE_INIT_PLUGINS`. However, plugins that implement a compatibility layer so that they can be used with both the new API, and with `Kaleidoscope.use()` will have a `.begin` method too. Which the default `onSetup` will call, and we'll register the compatibility layer too, in addition to the new-style event handlers. This results in many things running twice, which leads to all kinds of problems. For this reason, override `onSetup`, so that it does not call `begin`. When used with `Kaleidoscope.use()`, the plugin will still work, so compatibility is maintained. But the bug is now gone. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 9f5041f9..56419c2a 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -37,6 +37,13 @@ class StalkerEffect : public LEDMode { static uint16_t step_length; EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + kaleidoscope::EventHandlerResult onSetup() { + return kaleidoscope::EventHandlerResult::OK; + } +#endif + protected: void onActivate(void) final; void update(void) final; From 1c8b45eddcff449f3614ad2fb228fab2f1704701 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 17 Jun 2018 11:14:52 +0200 Subject: [PATCH 570/792] Override onSetup when using a compatibility layer The default `onSetup` will call `.begin`, to support initializing plugins using the V1 plugins while using `KALEIDOSCOPE_INIT_PLUGINS`. However, plugins that implement a compatibility layer so that they can be used with both the new API, and with `Kaleidoscope.use()` will have a `.begin` method too. Which the default `onSetup` will call, and we'll register the compatibility layer too, in addition to the new-style event handlers. This results in many things running twice, which leads to all kinds of problems. For this reason, override `onSetup`, so that it does not call `begin`. When used with `Kaleidoscope.use()`, the plugin will still work, so compatibility is maintained. But the bug is now gone. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MagicCombo.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 958f7695..22184ba7 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -55,6 +55,10 @@ class MagicCombo : public kaleidoscope::Plugin { EventHandlerResult beforeReportingState(); #if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + kaleidoscope::EventHandlerResult onSetup() { + return kaleidoscope::EventHandlerResult::OK; + } + protected: void begin(); static void legacyLoopHook(bool is_post_clear); From 4441329abfbcc8d563f80e529d242d6d24e2c43c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 17 Jun 2018 11:18:11 +0200 Subject: [PATCH 571/792] Override onSetup when using a compatibility layer The default `onSetup` will call `.begin`, to support initializing plugins using the V1 plugins while using `KALEIDOSCOPE_INIT_PLUGINS`. However, plugins that implement a compatibility layer so that they can be used with both the new API, and with `Kaleidoscope.use()` will have a `.begin` method too. Which the default `onSetup` will call, and we'll register the compatibility layer too, in addition to the new-style event handlers. This results in many things running twice, which leads to all kinds of problems. For this reason, override `onSetup`, so that it does not call `begin`. When used with `Kaleidoscope.use()`, the plugin will still work, so compatibility is maintained. But the bug is now gone. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Model01-TestMode.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 598ad396..1884756d 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -15,6 +15,10 @@ class TestMode_ : public kaleidoscope::Plugin { kaleidoscope::EventHandlerResult beforeReportingState(); #if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + kaleidoscope::EventHandlerResult onSetup() { + return kaleidoscope::EventHandlerResult::OK; + } + protected: void begin(); static void legacyLoopHook(bool is_post_clear); From 121219943c5d8bfa1b7ebb14527197622f32ff41 Mon Sep 17 00:00:00 2001 From: Shriramana Sharma Date: Sun, 17 Jun 2018 17:28:59 +0530 Subject: [PATCH 572/792] Add documentation for recently added color properties --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index 3bbe9948..83bc5629 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,37 @@ This is a plugin for [Kaleidoscope][fw], that adds a NumPad-specific LED effect, along with a way to toggle to a numpad layer, and apply the effect. +## Using the extension + +To use the plugin, include the header, and tell the firmware to use it: + +```c++ +#include "Kaleidoscope-NumPad.h" + +KALEIDOSCOPE_INIT_PLUGINS(NumPad); + +void setup() { + Kaleidoscope.setup(); + + NumPad.color = CRGB(0, 0, 160); // a blue color + NumPad.lock_hue = 85; // green +} +``` + +## Plugin methods + +The plugin provides the `NumPad` object, with the following properties: + +### `.color` + +> This property sets the color that the NumPad keys are highlighted in. +> +> The default is `CRGB(160, 0, 0)`, a red color. + +### `.lock_hue` + +> This property sets the color hue that the NumLock LED breathes in. +> +> The default is `170`, a blue hue. + [fw]: https://github.com/keyboardio/Kaleidoscope From 990722d7b48108aa4841c3959f1c5d233e5da9f7 Mon Sep 17 00:00:00 2001 From: James Cash Date: Tue, 19 Jun 2018 19:09:19 -0400 Subject: [PATCH 573/792] Fix typo --- UPGRADING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADING.md b/UPGRADING.md index f0db1c28..1c9652d4 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -39,7 +39,7 @@ void setup() { } ``` -Previsouly, we used a global, overrideable function (`magicComboActions`) to run +Previously, we used a global, overrideable function (`magicComboActions`) to run the actions of all magic combos, similar to how macros are set up to work. Unlike macros, magic combos can't be defined in the keymap, due to technical reasons, so we had to use a separate list - `magic_combos` in our example. We From 675c0ac475c42b5ee86cd569f6cd77e6153f70d7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 25 Jun 2018 21:11:17 +0200 Subject: [PATCH 574/792] Fix onSetup, to register the LED mode When using the V1 compatibility layer, in the `onSetup()` method, we need to call `LEDControl.mode_add()`, otherwise the mode does not register, and will not function. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 56419c2a..f8cdc639 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -40,6 +40,8 @@ class StalkerEffect : public LEDMode { #if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API kaleidoscope::EventHandlerResult onSetup() { + ::LEDControl.mode_add(this); + return kaleidoscope::EventHandlerResult::OK; } #endif From f2bca33a7c7ba9e988343ca03c48f1c1af61afac Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 25 Jun 2018 21:12:27 +0200 Subject: [PATCH 575/792] Improve the compatibility layer When the V1 plugin API is enabled, we need to override `onSetup`, to not call `setup()` twice: once via the v2 default `onSetup`, and once via the legacy API. Take special attention to call `LEDControl.mode_add`, so that the effect does register as a LED mode. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/AlphaSquare-Effect.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 34381df2..ff5bd386 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -29,6 +29,15 @@ class AlphaSquareEffect : public LEDMode { static uint16_t length; EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); + +#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API + kaleidoscope::EventHandlerResult onSetup() { + ::LEDControl.mode_add(this); + + return kaleidoscope::EventHandlerResult::OK; + } +#endif + protected: void update(void) final; From 441812abcc1c38f361be0ab05f866bc0fbdb157e Mon Sep 17 00:00:00 2001 From: matt venn Date: Mon, 9 Jul 2018 14:06:52 +0200 Subject: [PATCH 576/792] fixed LED sync overflow bug --- src/Kaleidoscope-LEDControl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 4ae30a6d..a5f41d90 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -151,8 +151,8 @@ kaleidoscope::EventHandlerResult LEDControl::beforeReportingState(void) { if (paused) return kaleidoscope::EventHandlerResult::OK; - uint16_t current_time = millis(); - if ((current_time - syncTimer) > syncDelay) { + uint16_t elapsed = Kaleidoscope.millisAtCycleStart() - syncTimer; + if (elapsed > syncDelay) { syncLeds(); syncTimer += syncDelay; } From 4674fe1f10edc3e2109d755e5cb8ce50a4becc0a Mon Sep 17 00:00:00 2001 From: Shriramana Sharma Date: Mon, 9 Jul 2018 23:12:27 +0530 Subject: [PATCH 577/792] add saturation option --- README.md | 8 +++++++- src/Kaleidoscope-LEDEffect-Breathe.cpp | 2 +- src/Kaleidoscope-LEDEffect-Breathe.h | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 853ab20d..92048268 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,13 @@ The plugin provides the `LEDBreatheEffect` object, which has a single property: > The hue of the breathe effect. > -> Defaults to 170. +> Defaults to 170, a blue hue. + +### `.saturation` + +> The color saturation of the breathe effect. +> +> Defaults to 255, the maximum. ## Dependencies diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp index d7c9484c..1d0b92ab 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -2,7 +2,7 @@ namespace kaleidoscope { void LEDBreatheEffect::update(void) { - cRGB color = breath_compute(hue); + cRGB color = breath_compute(hue, saturation); ::LEDControl.set_all_leds_to(color); } } diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index 715bd819..64674f2b 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -9,6 +9,7 @@ class LEDBreatheEffect : public LEDMode { LEDBreatheEffect(void) {} uint8_t hue = 170; + uint8_t saturation = 255; protected: void update(void) final; From 76e8478ff6919eb1e463fa83cb36621ac5c86746 Mon Sep 17 00:00:00 2001 From: matt venn Date: Tue, 10 Jul 2018 09:47:38 +0200 Subject: [PATCH 578/792] code comments --- src/Kaleidoscope-LEDControl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index a5f41d90..80266a77 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -151,7 +151,11 @@ kaleidoscope::EventHandlerResult LEDControl::beforeReportingState(void) { if (paused) return kaleidoscope::EventHandlerResult::OK; + // unsigned subtraction means that as syncTimer rolls over + // the same interval is kept uint16_t elapsed = Kaleidoscope.millisAtCycleStart() - syncTimer; + // on some platforms, the subtraction in the comparison results in a signed + // operation, resulting in syncLeds() no longer getting called. if (elapsed > syncDelay) { syncLeds(); syncTimer += syncDelay; From df68cd510d48a2204b46385deadcc39923fcf842 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 25 Jul 2018 12:20:31 +0200 Subject: [PATCH 579/792] Display a useful error when using the old-style API Override the copy constructor of `combo_t`, so that we can display an error when initializing using the old-style API. Fixes #8. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MagicCombo.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 22184ba7..38e669a2 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -31,6 +31,13 @@ } \ } +#define _MAGICCOMBO_API_CHANGE \ + "The MagicCombo API changed in an incompatible way, you will need to\n" \ + "upgrade.\n" \ + "\n" \ + "Please see the `UPGRADING.md` document shipped with the source:\n" \ + " https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/UPGRADING.md" + namespace kaleidoscope { class MagicCombo : public kaleidoscope::Plugin { @@ -43,8 +50,15 @@ class MagicCombo : public kaleidoscope::Plugin { typedef struct combo_t { uint32_t left_hand, right_hand; - private: - combo_t(byte left, byte right) {} + template + struct always_false { + enum { value = false }; + }; + + template + combo_t(T l, T r) { + static_assert(always_false::value, _DEPRECATE(_MAGICCOMBO_API_CHANGE)); + } } combo_t; MagicCombo(void) {} From 8a170ff8117d4f5dbda2f239fa587b4f2b779ba5 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 25 Jul 2018 16:17:55 +0200 Subject: [PATCH 580/792] Simplify the way we achieve printing the error message when using the old API Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MagicCombo.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 38e669a2..105c71be 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -50,14 +50,9 @@ class MagicCombo : public kaleidoscope::Plugin { typedef struct combo_t { uint32_t left_hand, right_hand; - template - struct always_false { - enum { value = false }; - }; - template combo_t(T l, T r) { - static_assert(always_false::value, _DEPRECATE(_MAGICCOMBO_API_CHANGE)); + static_assert(sizeof(T) < 0, _DEPRECATE(_MAGICCOMBO_API_CHANGE)); } } combo_t; From 852a685249315466a07fca50558004f58c6e7034 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 29 Jul 2018 07:32:55 +0200 Subject: [PATCH 581/792] When playing back, also report mouse keys Thanks to @jamadagni for spotting the issue! Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 55a2465d..b273bdea 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -13,6 +13,7 @@ byte Macros_::row, Macros_::col; void playMacroKeyswitchEvent(Key key, uint8_t flags) { handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, INJECTED | flags); kaleidoscope::hid::sendKeyboardReport(); + kaleidoscope::hid::sendMouseReport(); } static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t keyStates) { From 7eabe867a4834cd2fa49257104c5b40c608e9b0d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 29 Jul 2018 21:07:18 +0200 Subject: [PATCH 582/792] Stop moving into a given direction when releasing a mouse key While we do clear the report every cycle, similar to how key release events are explicitly removed from the report, mouse movements should get removed too. This makes it possible to use them in macros reliably, without surprising results (an extra report sent at the end of the macro). Signed-off-by: Gergely Nagy --- src/Kaleidoscope-MouseKeys.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 7e643201..cafd7ede 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -114,6 +114,34 @@ kaleidoscope::EventHandlerResult MouseKeys_::onKeyswitchEvent(Key &mappedKey, by } else { mouseMoveIntent |= mappedKey.keyCode; } + } else if (keyToggledOff(keyState)) { + /* If a mouse key toggles off, we want to explicitly stop moving (or + * scrolling) in that direction. We want to do this to support use-cases + * where we send multiple reports per cycle (such as macros), and can't + * rely on the main loop clearing the report for us. We do not want to + * clear the whole report either, because we want any other mouse keys + * to still have their desired effect. Therefore, we selectively stop + * movement or scrolling. */ + mouseMoveIntent &= ~mappedKey.keyCode; + bool x = false, y = false, vWheel = false, hWheel = false; + + if (mappedKey.keyCode & KEY_MOUSE_UP || + mappedKey.keyCode & KEY_MOUSE_DOWN) { + if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { + vWheel = true; + } else { + y = true; + } + } else if (mappedKey.keyCode & KEY_MOUSE_LEFT || + mappedKey.keyCode & KEY_MOUSE_RIGHT) { + if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { + hWheel = true; + } else { + x = true; + } + } + + kaleidoscope::hid::stopMouse(x, y, vWheel, hWheel); } } else if (keyToggledOn(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { From 8ec69c8fbacd81f7e53659138bf7a4af1cc905b8 Mon Sep 17 00:00:00 2001 From: Daniele Tamino Date: Mon, 6 Aug 2018 21:20:21 -0700 Subject: [PATCH 583/792] Add setSpeedLimit API --- README.md | 6 ++++++ src/Kaleidoscope-MouseKeys.cpp | 4 ++++ src/Kaleidoscope-MouseKeys.h | 1 + 3 files changed, 11 insertions(+) diff --git a/README.md b/README.md index 47a8df8f..a990d9d3 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,12 @@ properties available: > wheel shall scroll, and defaults to 1. The second, `.wheelDelay`, controls the > delay between two scroll events, and defaults to 50 milliseconds. +### `.setSpeedLimit` + +> This method sets the maximum speed after which acceleration stops. +> The default is 127, and the minimum value is 16 (things will not work +> properly below 16). + ### `.setWarpGridSize` > This method changes the size of the grid used for [warping](#warping). The diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index cafd7ede..e67e38de 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -23,6 +23,10 @@ void MouseKeys_::setWarpGridSize(uint8_t grid_size) { MouseWrapper.warp_grid_size = grid_size; } +void MouseKeys_::setSpeedLimit(uint8_t speed_limit) { + MouseWrapper.speedLimit = speed_limit; +} + void MouseKeys_::scrollWheel(uint8_t keyCode) { if (millis() < wheelEndTime) return; diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index 3b23ddff..756e6385 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -16,6 +16,7 @@ class MouseKeys_ : public kaleidoscope::Plugin { static uint16_t wheelDelay; static void setWarpGridSize(uint8_t grid_size); + static void setSpeedLimit(uint8_t speed_limit); kaleidoscope::EventHandlerResult onSetup(); kaleidoscope::EventHandlerResult beforeReportingState(); From 8321009ea44e7c2519a548c4b8a1f3057f2f7192 Mon Sep 17 00:00:00 2001 From: Shriramana Sharma Date: Wed, 8 Aug 2018 20:01:43 +0530 Subject: [PATCH 584/792] Limit refresh rate and don't update on every cycle The breathe function is somewhat costly and is found to cause drag in mouse movements. This commit seeks to fix this problem. It is observed that the function doesn't change output value for every input value. It only causes the output brightness to increase by 128 units (from 80 to 208) over 2048 ms (the half-period). This means 1 unit for 16 ms. But a brightness change of 1 unit doesn't mean much visually especially considering persistence of vision. A refresh rate of 20 per second ie 50 ms between LED updates is found to be sufficient to avoid the drag effect while maintaining smoothness in brightness changes. --- src/Kaleidoscope-LEDEffect-Breathe.cpp | 6 ++++++ src/Kaleidoscope-LEDEffect-Breathe.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp index 1d0b92ab..645533d6 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -1,7 +1,13 @@ #include "Kaleidoscope-LEDEffect-Breathe.h" +#define UPDATE_INTERVAL 50 // milliseconds between two LED updates to avoid overloading; 20 fps namespace kaleidoscope { void LEDBreatheEffect::update(void) { + uint16_t now = millis(); + if ((now - last_update) < UPDATE_INTERVAL) + return; + last_update = now; + cRGB color = breath_compute(hue, saturation); ::LEDControl.set_all_leds_to(color); } diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index 64674f2b..6c393a77 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -13,6 +13,9 @@ class LEDBreatheEffect : public LEDMode { protected: void update(void) final; + + private: + uint16_t last_update = 0; }; } From 5a05dda99b81e7bc68af63d50d871c162d5eb0df Mon Sep 17 00:00:00 2001 From: Shriramana Sharma Date: Sat, 11 Aug 2018 09:04:19 +0530 Subject: [PATCH 585/792] Clarify in the documentation the number of macros one can define --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c454766a..2a3abe2a 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ Playing back a sequence means that when we press a macro key, we can have it play pretty much any sequence. It can type some text for us, or invoke a complicated shortcut - the possibilities are endless! +In Kaleidoscope, macros are implemented via this plugin. You can define upto 256 macros. + ## Using the plugin To use the plugin, we need to include the header, tell the firmware to `use` the @@ -74,11 +76,11 @@ void setup() { ### `M(id)` -> Places a macro key on the keymap, with the `id` identifier. Whenever this key +> Places a macro key on the keymap, with the `id` number (0 to 255) as identifier. Whenever this key > has to be handled, the `macroAction` overrideable function will be called, > with the identifier and key state as arguments. > -> It is recommended to give a *name* to macros, by using an `enum`. +> It is recommended to give a *name* to macro ids, by using an `enum`. ## Plugin methods From 6ec5f2cc50c87c4c2c621ea764ccb8fbc7d5418d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 14 Aug 2018 16:54:28 -0700 Subject: [PATCH 586/792] Rename an argument to be less confusing. ('flags' is often used to mean 'flags on a key definition', but this is really 'logical state of a virtual keyswitch') --- src/Kaleidoscope-Macros.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index b273bdea..acf64317 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -10,8 +10,9 @@ MacroKeyEvent Macros_::active_macros[]; byte Macros_::active_macro_count; byte Macros_::row, Macros_::col; -void playMacroKeyswitchEvent(Key key, uint8_t flags) { - handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, INJECTED | flags); +void playMacroKeyswitchEvent(Key key, uint8_t keyswitch_state) { + handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, keyswitch_state | INJECTED ); + kaleidoscope::hid::sendKeyboardReport(); kaleidoscope::hid::sendMouseReport(); } From d7abd066c66ea5adb2ef77d94a49b9b11121254f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 14 Aug 2018 16:56:29 -0700 Subject: [PATCH 587/792] astyle --- src/Kaleidoscope-MouseKeys.cpp | 50 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index e67e38de..b3bf86d3 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -119,33 +119,33 @@ kaleidoscope::EventHandlerResult MouseKeys_::onKeyswitchEvent(Key &mappedKey, by mouseMoveIntent |= mappedKey.keyCode; } } else if (keyToggledOff(keyState)) { - /* If a mouse key toggles off, we want to explicitly stop moving (or - * scrolling) in that direction. We want to do this to support use-cases - * where we send multiple reports per cycle (such as macros), and can't - * rely on the main loop clearing the report for us. We do not want to - * clear the whole report either, because we want any other mouse keys - * to still have their desired effect. Therefore, we selectively stop - * movement or scrolling. */ - mouseMoveIntent &= ~mappedKey.keyCode; - bool x = false, y = false, vWheel = false, hWheel = false; - - if (mappedKey.keyCode & KEY_MOUSE_UP || - mappedKey.keyCode & KEY_MOUSE_DOWN) { - if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { - vWheel = true; - } else { - y = true; - } - } else if (mappedKey.keyCode & KEY_MOUSE_LEFT || - mappedKey.keyCode & KEY_MOUSE_RIGHT) { - if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { - hWheel = true; - } else { - x = true; - } + /* If a mouse key toggles off, we want to explicitly stop moving (or + * scrolling) in that direction. We want to do this to support use-cases + * where we send multiple reports per cycle (such as macros), and can't + * rely on the main loop clearing the report for us. We do not want to + * clear the whole report either, because we want any other mouse keys + * to still have their desired effect. Therefore, we selectively stop + * movement or scrolling. */ + mouseMoveIntent &= ~mappedKey.keyCode; + bool x = false, y = false, vWheel = false, hWheel = false; + + if (mappedKey.keyCode & KEY_MOUSE_UP || + mappedKey.keyCode & KEY_MOUSE_DOWN) { + if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { + vWheel = true; + } else { + y = true; } + } else if (mappedKey.keyCode & KEY_MOUSE_LEFT || + mappedKey.keyCode & KEY_MOUSE_RIGHT) { + if (mappedKey.keyCode & KEY_MOUSE_WHEEL) { + hWheel = true; + } else { + x = true; + } + } - kaleidoscope::hid::stopMouse(x, y, vWheel, hWheel); + kaleidoscope::hid::stopMouse(x, y, vWheel, hWheel); } } else if (keyToggledOn(keyState)) { if (mappedKey.keyCode & KEY_MOUSE_WARP && mappedKey.flags & IS_MOUSE_KEY) { From 276a160666a0c0030d569a8de2b123ecc5fe1764 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 14 Aug 2018 17:04:12 -0700 Subject: [PATCH 588/792] Remove two includes that we don't need anymore --- src/Kaleidoscope-Model01-TestMode.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index abdf4d76..4fef13db 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -1,8 +1,6 @@ #include "Kaleidoscope.h" #include "Kaleidoscope-Model01-TestMode.h" #include "Kaleidoscope-LEDEffect-Rainbow.h" -#include -#include #define CHATTER_CYCLE_LIMIT 30 From 03524be75802088cfb1cf45af706f7a55968b340 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 14 Aug 2018 17:20:58 -0700 Subject: [PATCH 589/792] astyle --- src/Kaleidoscope-Macros.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index acf64317..e9a644ef 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -11,7 +11,7 @@ byte Macros_::active_macro_count; byte Macros_::row, Macros_::col; void playMacroKeyswitchEvent(Key key, uint8_t keyswitch_state) { - handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, keyswitch_state | INJECTED ); + handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, keyswitch_state | INJECTED); kaleidoscope::hid::sendKeyboardReport(); kaleidoscope::hid::sendMouseReport(); From 2df0a813817962411976b900c21deac52b70c48c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 16 Aug 2018 07:28:25 +0200 Subject: [PATCH 590/792] Document the `Dc`, `Uc`, and `Tc` step variants Addresses #28 in a different way. Signed-off-by: Gergely Nagy --- README.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c454766a..08c7b74e 100644 --- a/README.md +++ b/README.md @@ -161,16 +161,22 @@ Macro steps can be divided into two groups: ### Key events -Key event steps have two variants: one that prefixes its argument with `Key_`, -and one that does not. The latter are the `Dr`, `Ur`, and `Tr` variants. In most -cases, one is likely to use normal keys for the steps, so the `D`, `U`, and `T` -steps apply the `Key_` prefix. This allows us to write `MACRO(T(X))` -instead of `MACRO(Tr(Key_X))` - making the macro definition shorter, and -more readable. - -* `D(key)`, `Dr(key)`: Simulates a key being pressed (pushed down). -* `U(key)`, `Ur(key)`: Simulates a key being released (going up). -* `T(key)`, `Tr(key)`: Simulates a key being tapped (pressed first, then released). +Key event steps have three variants: one that prefixes its argument with `Key_`, +one that does not, and a third that allows for a more compact - but also more +limited - representation. The first are the `D`, `U`, and `T` variants, the +second are `Dr`, `Ur`, and `Tr`, and the last variant are `Dc`, `Uc`, and `Tc`. +In most cases, one is likely use normal keys for the steps, so the `D`, `U`, and +`T` steps apply the `Key_` prefix. This allows us to write `MACRO(T(X))` instead +of `MACRO(Tr(Key_X))` - making the macro definition shorter, and more readable. + +The compact variant (`Dc`, `Uc`, and `Tc`) prefix the argument with `Key_` too, +but unlike `D`, `U`, and `T`, they ignore the `flags` component of the key, and +as such, are limited to ordinary keys. Mouse keys, consumer- or system keys are +not supported by this compact representation. + +* `D(key)`, `Dr(key)`, `Dc(key)`: Simulates a key being pressed (pushed down). +* `U(key)`, `Ur(key)`, `Uc(key)`: Simulates a key being released (going up). +* `T(key)`, `Tr(key)`, `Tc(key)`: Simulates a key being tapped (pressed first, then released). ## Overrideable methods From c9e2eec2734db4baae4cdae3187de26bffe81ac4 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Thu, 16 Aug 2018 18:03:02 -0700 Subject: [PATCH 591/792] When compiled with a HID implementation without BootKeyboard enabled, this shouldn't break --- src/kaleidoscope/USB-Quirks.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/kaleidoscope/USB-Quirks.cpp b/src/kaleidoscope/USB-Quirks.cpp index 835429ae..aaec91a6 100644 --- a/src/kaleidoscope/USB-Quirks.cpp +++ b/src/kaleidoscope/USB-Quirks.cpp @@ -21,6 +21,8 @@ namespace kaleidoscope { void USBQuirks::toggleKeyboardProtocol() { + +#if KALEIDOSCOPE_HIDADAPTOR_ENABLE_KEYBOARD_BOOT_PROTOCOL uint8_t new_protocol = !BootKeyboard.getProtocol(); Kaleidoscope.detachFromHost(); @@ -28,6 +30,8 @@ void USBQuirks::toggleKeyboardProtocol() { BootKeyboard.setProtocol(new_protocol); delay(1000); Kaleidoscope.attachToHost(); +#endif + } } From cea73d9a7204ffc77a7a3db558ac299d977505c7 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Thu, 16 Aug 2018 18:05:19 -0700 Subject: [PATCH 592/792] This change hacks up HostPowerManagement to make it a noop on X86 --- src/Kaleidoscope/HostPowerManagement.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope/HostPowerManagement.cpp b/src/Kaleidoscope/HostPowerManagement.cpp index 1a8fd422..da7bacd5 100644 --- a/src/Kaleidoscope/HostPowerManagement.cpp +++ b/src/Kaleidoscope/HostPowerManagement.cpp @@ -22,7 +22,7 @@ // This is a terrible hack until Arduino#6964 gets implemented. // It makes the `_usbSuspendState` symbol available to us. -extern u8 _usbSuspendState; +extern uint8_t _usbSuspendState; namespace kaleidoscope { @@ -30,6 +30,8 @@ bool HostPowerManagement::was_suspended_ = false; bool HostPowerManagement::initial_suspend_ = true; EventHandlerResult HostPowerManagement::beforeEachCycle() { + +#ifdef __AVR__ if ((_usbSuspendState & (1 << SUSPI))) { if (!initial_suspend_) { if (!was_suspended_) { @@ -47,6 +49,7 @@ EventHandlerResult HostPowerManagement::beforeEachCycle() { hostPowerManagementEventHandler(Resume); } } +#endif return EventHandlerResult::OK; } From aee55ba437ef49cea1269ac984afa21098c4f604 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Thu, 16 Aug 2018 21:10:49 -0700 Subject: [PATCH 593/792] Switch to using the CRGB macro to build our colors. This should make it easier to port to virtual hardware. --- src/Kaleidoscope-Model01-TestMode.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 4fef13db..12f93a9b 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -55,11 +55,11 @@ void TestMode_::set_leds(cRGB color) { } void TestMode_::test_leds(void) { - cRGB red = { b: 0, g: 0, r: 201 } ; - cRGB blue = { b: 201, g: 0, r: 0 } ; - cRGB green = { b: 0, g: 201, r: 0 } ; - cRGB white = { b: 50, g: 50, r: 50 } ; - cRGB brightWhite = { b: 160, g: 160, r: 160 } ; + cRGB red = CRGB(201,0,0); + cRGB blue = CRGB(0,0,201); + cRGB green = CRGB(0,201,0); + cRGB white = CRGB(50,50,50); + cRGB brightWhite = CRGB(160,160,160); // make all the LEDs bright red set_leds(red); @@ -81,9 +81,9 @@ void TestMode_::test_leds(void) { void TestMode_::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset) { - cRGB red = { b: 0, g: 0, r: 201 } ; - cRGB blue = { b: 201, g: 0, r: 0 } ; - cRGB green = { b: 0, g: 201, r: 0 } ; + cRGB red = CRGB(201,0,0); + cRGB blue = CRGB(0,0,201); + cRGB green = CRGB(0,201,0); uint8_t keynum = (row * 8) + (col); From 3a2683b3ee94f743f97ef3767214f5049e3b3dc6 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Thu, 16 Aug 2018 21:15:06 -0700 Subject: [PATCH 594/792] astyle --- src/Kaleidoscope-Model01-TestMode.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 12f93a9b..94b154dd 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -55,11 +55,11 @@ void TestMode_::set_leds(cRGB color) { } void TestMode_::test_leds(void) { - cRGB red = CRGB(201,0,0); - cRGB blue = CRGB(0,0,201); - cRGB green = CRGB(0,201,0); - cRGB white = CRGB(50,50,50); - cRGB brightWhite = CRGB(160,160,160); + cRGB red = CRGB(201, 0, 0); + cRGB blue = CRGB(0, 0, 201); + cRGB green = CRGB(0, 201, 0); + cRGB white = CRGB(50, 50, 50); + cRGB brightWhite = CRGB(160, 160, 160); // make all the LEDs bright red set_leds(red); @@ -81,9 +81,9 @@ void TestMode_::test_leds(void) { void TestMode_::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset) { - cRGB red = CRGB(201,0,0); - cRGB blue = CRGB(0,0,201); - cRGB green = CRGB(0,201,0); + cRGB red = CRGB(201, 0, 0); + cRGB blue = CRGB(0, 0, 201); + cRGB green = CRGB(0, 201, 0); uint8_t keynum = (row * 8) + (col); From c11c09ba5f650d7d1275689cd275c8bdaeb4c9e5 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 22:58:00 +0200 Subject: [PATCH 595/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings.cpp | 7 ------- src/Kaleidoscope/EEPROM-Settings.h | 5 ----- 2 files changed, 12 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 83f4e11f..9fa48ef4 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -98,13 +98,6 @@ void EEPROMSettings::version(uint8_t ver) { update(); } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void EEPROMSettings::begin() { - ::EEPROMSettings.onSetup(); -} -#endif - } kaleidoscope::EEPROMSettings EEPROMSettings; diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 1b8e483c..373cbdfd 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -39,11 +39,6 @@ class EEPROMSettings : public kaleidoscope::Plugin { static uint16_t crc(void); static uint16_t used(void); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - protected: - void begin(); -#endif - private: static uint16_t next_start_; static bool is_valid_; From 026ff0407158b5a33727b1e5b857983359631c91 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:04:11 +0200 Subject: [PATCH 596/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope/HostPowerManagement.cpp | 14 -------------- src/Kaleidoscope/HostPowerManagement.h | 10 ---------- 2 files changed, 24 deletions(-) diff --git a/src/Kaleidoscope/HostPowerManagement.cpp b/src/Kaleidoscope/HostPowerManagement.cpp index da7bacd5..46f8053f 100644 --- a/src/Kaleidoscope/HostPowerManagement.cpp +++ b/src/Kaleidoscope/HostPowerManagement.cpp @@ -54,20 +54,6 @@ EventHandlerResult HostPowerManagement::beforeEachCycle() { return EventHandlerResult::OK; } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void HostPowerManagement::begin() { - Kaleidoscope.useLoopHook(legacyLoopHook); -} - -void HostPowerManagement::legacyLoopHook(bool is_post_clear) { - if (is_post_clear) - return; - - ::HostPowerManagement.beforeEachCycle(); -} -#endif - } __attribute__((weak)) void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event) { diff --git a/src/Kaleidoscope/HostPowerManagement.h b/src/Kaleidoscope/HostPowerManagement.h index 72a0826f..61b8716b 100644 --- a/src/Kaleidoscope/HostPowerManagement.h +++ b/src/Kaleidoscope/HostPowerManagement.h @@ -40,16 +40,6 @@ class HostPowerManagement : public kaleidoscope::Plugin { EventHandlerResult beforeEachCycle(); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - kaleidoscope::EventHandlerResult onSetup() { - return kaleidoscope::EventHandlerResult::OK; - } - - protected: - void begin(); - static void legacyLoopHook(bool is_post_clear); -#endif - private: static bool was_suspended_; static bool initial_suspend_; From 6b42106f5a618e615719641f1e072a19c005f45d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:10:21 +0200 Subject: [PATCH 597/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope/AlphaSquare-Effect.cpp | 14 -------------- src/Kaleidoscope/AlphaSquare-Effect.h | 13 ------------- 2 files changed, 27 deletions(-) diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index 2c1446fd..c75a4dff 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -68,20 +68,6 @@ EventHandlerResult AlphaSquareEffect::onKeyswitchEvent(Key &mappedKey, byte row, return EventHandlerResult::OK; } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void AlphaSquareEffect::setup(void) { - Kaleidoscope.useEventHandlerHook(legacyEventHandler); -} - -Key AlphaSquareEffect::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { - EventHandlerResult r = ::AlphaSquareEffect.onKeyswitchEvent(mapped_key, row, col, key_state); - if (r == EventHandlerResult::OK) - return mapped_key; - return Key_NoKey; -} -#endif - } kaleidoscope::AlphaSquareEffect AlphaSquareEffect; diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index ff5bd386..24ebba73 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -30,22 +30,9 @@ class AlphaSquareEffect : public LEDMode { EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - kaleidoscope::EventHandlerResult onSetup() { - ::LEDControl.mode_add(this); - - return kaleidoscope::EventHandlerResult::OK; - } -#endif - protected: void update(void) final; -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - void setup(void) final; - static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); -#endif - private: static uint32_t end_time_left_, end_time_right_; static Key last_key_left_, last_key_right_; From bcac993d0ac0b4c8930b3dd7789ebc7b79fc044a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:12:03 +0200 Subject: [PATCH 598/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 29 ----------------------------- src/Kaleidoscope-LEDControl.h | 11 ----------- 2 files changed, 40 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 80266a77..ddb9f2d5 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -20,12 +20,6 @@ kaleidoscope::EventHandlerResult LEDMode::onSetup() { return EventHandlerResult::OK; } -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void LEDMode::begin() { - onSetup(); -} -#endif - LEDControl::LEDControl(void) { mode = 0; memset(modes, 0, LED_MAX_MODES * sizeof(modes[0])); @@ -258,29 +252,6 @@ bool LEDControl::focusHook(const char *command) { return true; } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void LEDControl::begin() { - ::LEDControl.onSetup(); - Kaleidoscope.useEventHandlerHook(legacyEventHandler); - Kaleidoscope.useLoopHook(legacyLoopHook); -} - -Key LEDControl::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { - EventHandlerResult r = ::LEDControl.onKeyswitchEvent(mapped_key, row, col, key_state); - if (r == EventHandlerResult::OK) - return mapped_key; - return Key_NoKey; -} - -void LEDControl::legacyLoopHook(bool is_post_clear) { - if (is_post_clear) - return; - ::LEDControl.beforeReportingState(); -} -#endif - - } kaleidoscope::LEDControl LEDControl; diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 0e7ee8f6..9c2acf69 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -82,10 +82,6 @@ class LEDMode : public kaleidoscope::Plugin { * necessary initialization steps. Calls @ref setup at the end. */ kaleidoscope::EventHandlerResult onSetup(); - -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - void begin(); -#endif }; class LEDControl : public kaleidoscope::Plugin { @@ -136,13 +132,6 @@ class LEDControl : public kaleidoscope::Plugin { kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); kaleidoscope::EventHandlerResult beforeReportingState(); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - protected: - void begin(); - static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); - static void legacyLoopHook(bool is_post_clear); -#endif - private: static uint16_t syncTimer; static LEDMode *modes[LED_MAX_MODES]; From d090894bc0117805a60ee10836135aa81d05c291 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:12:58 +0200 Subject: [PATCH 599/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 13 ------------- src/Kaleidoscope-LEDEffect-BootGreeting.h | 10 ---------- 2 files changed, 23 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index 348fb944..c88f5eb4 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -86,19 +86,6 @@ EventHandlerResult BootGreetingEffect::afterEachCycle() { return EventHandlerResult::OK; } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void BootGreetingEffect::begin() { - Kaleidoscope.useLoopHook(legacyLoopHook); -} - -void BootGreetingEffect::legacyLoopHook(bool is_post_clear) { - if (!is_post_clear) - return; - ::BootGreetingEffect.afterEachCycle(); -} -#endif - } kaleidoscope::BootGreetingEffect BootGreetingEffect; diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index d45e23dc..7e15d4ad 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -34,16 +34,6 @@ class BootGreetingEffect : public kaleidoscope::Plugin { EventHandlerResult afterEachCycle(); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - kaleidoscope::EventHandlerResult onSetup() { - return kaleidoscope::EventHandlerResult::OK; - } - - protected: - void begin(); - static void legacyLoopHook(bool is_post_clear); -#endif - private: static void findLed(void); static bool done_; From d44044bcc8f75979a7268433f05167ffd2d15c80 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:15:16 +0200 Subject: [PATCH 600/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope/LED-Stalker.cpp | 14 -------------- src/Kaleidoscope/LED-Stalker.h | 13 ------------- 2 files changed, 27 deletions(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 57b55304..43ac29f2 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -139,20 +139,6 @@ cRGB Rainbow::compute(uint8_t *step) { } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void StalkerEffect::setup(void) { - Kaleidoscope.useEventHandlerHook(legacyEventHandler); -} - -Key StalkerEffect::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { - EventHandlerResult r = ::StalkerEffect.onKeyswitchEvent(mapped_key, row, col, key_state); - if (r == EventHandlerResult::OK) - return mapped_key; - return Key_NoKey; -} -#endif - } kaleidoscope::StalkerEffect StalkerEffect; diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index f8cdc639..b1b2517c 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -38,23 +38,10 @@ class StalkerEffect : public LEDMode { EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - kaleidoscope::EventHandlerResult onSetup() { - ::LEDControl.mode_add(this); - - return kaleidoscope::EventHandlerResult::OK; - } -#endif - protected: void onActivate(void) final; void update(void) final; -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - void setup(void) final; - static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); -#endif - private: static uint16_t step_start_time_; static uint8_t map_[ROWS][COLS]; From 0dc276327f5179ded5d4d6eb211213e5585e99d1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:16:01 +0200 Subject: [PATCH 601/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Macros.cpp | 23 ----------------------- src/Kaleidoscope-Macros.h | 11 ----------- 2 files changed, 34 deletions(-) diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index e9a644ef..7f51cfa1 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -218,27 +218,4 @@ kaleidoscope::EventHandlerResult Macros_::beforeReportingState() { return kaleidoscope::EventHandlerResult::OK; } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void Macros_::begin() { - Kaleidoscope.useEventHandlerHook(legacyEventHandler); - Kaleidoscope.useLoopHook(legacyLoopHook); -} - -Key Macros_::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { - kaleidoscope::EventHandlerResult r = Macros.onKeyswitchEvent(mapped_key, row, col, key_state); - if (r == kaleidoscope::EventHandlerResult::OK) - return mapped_key; - return Key_NoKey; -} - -void Macros_::legacyLoopHook(bool is_post_clear) { - if (is_post_clear) { - Macros.afterEachCycle(); - } else { - Macros.beforeReportingState(); - } -} -#endif - Macros_ Macros; diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index a727b125..f1eb6c01 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -57,17 +57,6 @@ class Macros_ : public kaleidoscope::Plugin { static byte row, col; -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - kaleidoscope::EventHandlerResult onSetup() { - return kaleidoscope::EventHandlerResult::OK; - } - - protected: - void begin(); - static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); - static void legacyLoopHook(bool is_post_clear); -#endif - private: Key lookupAsciiCode(uint8_t ascii_code); }; From 7420b9988dfe4cae550944e5cf088bff8804cf35 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:17:22 +0200 Subject: [PATCH 602/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope/MagicCombo.cpp | 13 ------------- src/Kaleidoscope/MagicCombo.h | 10 ---------- 2 files changed, 23 deletions(-) diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index 4332ce35..e17c09bf 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -53,19 +53,6 @@ EventHandlerResult MagicCombo::beforeReportingState() { return EventHandlerResult::OK; } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void MagicCombo::begin() { - Kaleidoscope.useLoopHook(legacyLoopHook); -} - -void MagicCombo::legacyLoopHook(bool is_post_clear) { - if (is_post_clear) - return; - ::MagicCombo.beforeReportingState(); -} -#endif - }; kaleidoscope::MagicCombo MagicCombo; diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 105c71be..d33531d9 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -63,16 +63,6 @@ class MagicCombo : public kaleidoscope::Plugin { EventHandlerResult beforeReportingState(); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - kaleidoscope::EventHandlerResult onSetup() { - return kaleidoscope::EventHandlerResult::OK; - } - - protected: - void begin(); - static void legacyLoopHook(bool is_post_clear); -#endif - private: static uint32_t end_time_; }; From 9c1d576c9af7d2f17870e1da832b7acd2c27e0fb Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:19:47 +0200 Subject: [PATCH 603/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Model01-TestMode.cpp | 14 -------------- src/Kaleidoscope-Model01-TestMode.h | 10 ---------- 2 files changed, 24 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 94b154dd..dbb536f9 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -10,20 +10,6 @@ #define RELEASED 0 - -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void TestMode_::begin(void) { - Kaleidoscope.useLoopHook(this->legacyLoopHook); -} - -void TestMode_::legacyLoopHook(bool is_post_clear) { - if (is_post_clear) - return; - - TestMode.beforeReportingState(); -} -#endif - kaleidoscope::EventHandlerResult TestMode_::beforeReportingState() { if (KeyboardHardware.isKeyswitchPressed(R0C0) && KeyboardHardware.isKeyswitchPressed(R0C6) && diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 1884756d..38315482 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -14,16 +14,6 @@ class TestMode_ : public kaleidoscope::Plugin { kaleidoscope::EventHandlerResult beforeReportingState(); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - kaleidoscope::EventHandlerResult onSetup() { - return kaleidoscope::EventHandlerResult::OK; - } - - protected: - void begin(); - static void legacyLoopHook(bool is_post_clear); -#endif - private: static void run_tests(); static void test_leds(); From 256c7a729a555bc21448f4609f7f6d7bb7706fe6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:20:30 +0200 Subject: [PATCH 604/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope-MouseKeys.cpp | 24 ------------------------ src/Kaleidoscope-MouseKeys.h | 7 ------- 2 files changed, 31 deletions(-) diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index b3bf86d3..054a5d9f 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -166,28 +166,4 @@ kaleidoscope::EventHandlerResult MouseKeys_::onSetup(void) { return kaleidoscope::EventHandlerResult::OK; } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void MouseKeys_::begin() { - onSetup(); - Kaleidoscope.useEventHandlerHook(legacyEventHandler); - Kaleidoscope.useLoopHook(legacyLoopHook); -} - -Key MouseKeys_::legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state) { - kaleidoscope::EventHandlerResult r = MouseKeys.onKeyswitchEvent(mapped_key, row, col, key_state); - if (r == kaleidoscope::EventHandlerResult::OK) - return mapped_key; - return Key_NoKey; -} - -void MouseKeys_::legacyLoopHook(bool is_post_clear) { - if (is_post_clear) { - MouseKeys.afterEachCycle(); - } else { - MouseKeys.beforeReportingState(); - } -} -#endif - MouseKeys_ MouseKeys; diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index 756e6385..5d01af4e 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -23,13 +23,6 @@ class MouseKeys_ : public kaleidoscope::Plugin { kaleidoscope::EventHandlerResult afterEachCycle(); kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - protected: - void begin(); - static Key legacyEventHandler(Key mapped_key, byte row, byte col, uint8_t key_state); - static void legacyLoopHook(bool is_post_clear); -#endif - private: static uint8_t mouseMoveIntent; static uint32_t endTime; From 454c0d5b06692ac88f78cfef728a14d81a0a4ce7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 20 Aug 2018 23:21:48 +0200 Subject: [PATCH 605/792] Drop the V1 plugin API compatibility code Signed-off-by: Gergely Nagy --- src/Kaleidoscope-NumPad.cpp | 14 -------------- src/Kaleidoscope-NumPad.h | 6 ------ 2 files changed, 20 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 5d454d98..43f643c5 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -75,18 +75,4 @@ kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { return kaleidoscope::EventHandlerResult::OK; } -// Legacy V1 API -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API -void NumPad_::begin() { - onSetup(); - Kaleidoscope.useLoopHook(legacyLoopHook); -} - -void NumPad_::legacyLoopHook(bool is_post_clear) { - if (!is_post_clear) - return; - NumPad.afterEachCycle(); -} -#endif - NumPad_ NumPad; diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index aeb534b1..0b85cd33 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -15,12 +15,6 @@ class NumPad_ : public kaleidoscope::Plugin { kaleidoscope::EventHandlerResult onSetup(void); kaleidoscope::EventHandlerResult afterEachCycle(); -#if KALEIDOSCOPE_ENABLE_V1_PLUGIN_API - protected: - void begin(); - static void legacyLoopHook(bool is_post_clear); -#endif - private: static byte row, col; static bool cleanupDone; From 459d847002e47e0783279ee82fe6eca517129bac Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:13:59 +0200 Subject: [PATCH 606/792] Relicense under the GPLv3 (only) Signed-off-by: Gergely Nagy --- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 19 +++++++++---------- src/Kaleidoscope-EEPROM-Keymap.h | 19 +++++++++---------- src/Kaleidoscope/EEPROM-Keymap-Focus.h | 19 +++++++++---------- src/Kaleidoscope/EEPROM-Keymap.cpp | 19 +++++++++---------- src/Kaleidoscope/EEPROM-Keymap.h | 19 +++++++++---------- 5 files changed, 45 insertions(+), 50 deletions(-) diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index 5a1bb85c..dacd0ccf 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope-EEPROM-Keymap.h b/src/Kaleidoscope-EEPROM-Keymap.h index fec376e8..9e161e93 100644 --- a/src/Kaleidoscope-EEPROM-Keymap.h +++ b/src/Kaleidoscope-EEPROM-Keymap.h @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Focus.h index 931be0ff..3964677f 100644 --- a/src/Kaleidoscope/EEPROM-Keymap-Focus.h +++ b/src/Kaleidoscope/EEPROM-Keymap-Focus.h @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 015854ac..0e79e478 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 564fce98..eaa48784 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once From b2ae841d245bc3800c4d18e0cd4235be53dfaf62 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:14:01 +0200 Subject: [PATCH 607/792] Assign my copyright to Keyboard.io While the original plugin was written independently, significant developments were made while working for Keyboard.io. As such, I feel it is appropriate to assign copyright to the company. Signed-off-by: Gergely Nagy --- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 2 +- library.properties | 2 +- src/Kaleidoscope-EEPROM-Keymap.h | 2 +- src/Kaleidoscope/EEPROM-Keymap-Focus.h | 2 +- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 +- src/Kaleidoscope/EEPROM-Keymap.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index dacd0ccf..60e48a19 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/library.properties b/library.properties index 4e0b6dbc..6865fb81 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=Kaleidoscope-EEPROM-Keymap version=0.0.0 author=Gergely Nagy -maintainer=Gergely Nagy +maintainer=Gergely Nagy sentence=EEPROM-based keymap support for Kaleidoscope. paragraph=... category=Communication diff --git a/src/Kaleidoscope-EEPROM-Keymap.h b/src/Kaleidoscope-EEPROM-Keymap.h index 9e161e93..9ab581bd 100644 --- a/src/Kaleidoscope-EEPROM-Keymap.h +++ b/src/Kaleidoscope-EEPROM-Keymap.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Focus.h index 3964677f..dce6ee3f 100644 --- a/src/Kaleidoscope/EEPROM-Keymap-Focus.h +++ b/src/Kaleidoscope/EEPROM-Keymap-Focus.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 0e79e478..aede1faf 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index eaa48784..26ebfb48 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 From e16d0dfcc53ff54a57013ef159f6dff6231baadc Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:14:03 +0200 Subject: [PATCH 608/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From fc130b88702b7ea92bb55da87e0804a4c378c4bb Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:14:25 +0200 Subject: [PATCH 609/792] Relicense under the GPLv3 (only) Signed-off-by: Gergely Nagy --- examples/EEPROM-Settings/EEPROM-Settings.ino | 19 +++++++++---------- src/Kaleidoscope-EEPROM-Settings.h | 19 +++++++++---------- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 19 +++++++++---------- src/Kaleidoscope/EEPROM-Settings-Focus.h | 19 +++++++++---------- src/Kaleidoscope/EEPROM-Settings.cpp | 19 +++++++++---------- src/Kaleidoscope/EEPROM-Settings.h | 19 +++++++++---------- src/Kaleidoscope/crc.cpp | 19 +++++++++---------- src/Kaleidoscope/crc.h | 19 +++++++++---------- 8 files changed, 72 insertions(+), 80 deletions(-) diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino index d01f8132..f44906e0 100644 --- a/examples/EEPROM-Settings/EEPROM-Settings.ino +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope-EEPROM-Settings.h b/src/Kaleidoscope-EEPROM-Settings.h index ca5fb963..1c731bc5 100644 --- a/src/Kaleidoscope-EEPROM-Settings.h +++ b/src/Kaleidoscope-EEPROM-Settings.h @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 9a14c0a1..f661ed6f 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index aac30d59..66597153 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 9fa48ef4..9072073c 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 373cbdfd..704dfdf9 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/crc.cpp b/src/Kaleidoscope/crc.cpp index 4ae8d23f..4596c66c 100644 --- a/src/Kaleidoscope/crc.cpp +++ b/src/Kaleidoscope/crc.cpp @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . * * Originally generated by pycrc v0.9, https://pycrc.org * diff --git a/src/Kaleidoscope/crc.h b/src/Kaleidoscope/crc.h index 83e72187..8e37c28b 100644 --- a/src/Kaleidoscope/crc.h +++ b/src/Kaleidoscope/crc.h @@ -2,18 +2,17 @@ * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . * * Originally generated by pycrc v0.9, https://pycrc.org * From cbae65ceb43f1e89bd5e48ba5ddda351ee2f4301 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:14:27 +0200 Subject: [PATCH 610/792] Assign my copyright to Keyboard.io While the original plugin was written independently, significant developments were made while working for Keyboard.io. As such, I feel it is appropriate to assign copyright to the company. Signed-off-by: Gergely Nagy --- examples/EEPROM-Settings/EEPROM-Settings.ino | 2 +- library.properties | 2 +- src/Kaleidoscope-EEPROM-Settings.h | 2 +- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 2 +- src/Kaleidoscope/EEPROM-Settings-Focus.h | 2 +- src/Kaleidoscope/EEPROM-Settings.cpp | 2 +- src/Kaleidoscope/EEPROM-Settings.h | 2 +- src/Kaleidoscope/crc.cpp | 2 +- src/Kaleidoscope/crc.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/EEPROM-Settings/EEPROM-Settings.ino b/examples/EEPROM-Settings/EEPROM-Settings.ino index f44906e0..0d2b1850 100644 --- a/examples/EEPROM-Settings/EEPROM-Settings.ino +++ b/examples/EEPROM-Settings/EEPROM-Settings.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/library.properties b/library.properties index c78bfdfa..ee68df70 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=Kaleidoscope-EEPROM-Settings version=0.0.0 author=Gergely Nagy -maintainer=Gergely Nagy +maintainer=Gergely Nagy sentence=Base EEPROM settings plugin for Kaleidoscope. paragraph=... category=Communication diff --git a/src/Kaleidoscope-EEPROM-Settings.h b/src/Kaleidoscope-EEPROM-Settings.h index 1c731bc5..123b49cc 100644 --- a/src/Kaleidoscope-EEPROM-Settings.h +++ b/src/Kaleidoscope-EEPROM-Settings.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index f661ed6f..084ea8ee 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index 66597153..cebf254f 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 9072073c..0e187a09 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 704dfdf9..3fccd2ba 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/crc.cpp b/src/Kaleidoscope/crc.cpp index 4596c66c..0c199695 100644 --- a/src/Kaleidoscope/crc.cpp +++ b/src/Kaleidoscope/crc.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/crc.h b/src/Kaleidoscope/crc.h index 8e37c28b..0eb1aec4 100644 --- a/src/Kaleidoscope/crc.h +++ b/src/Kaleidoscope/crc.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 From a0bab51db85e640d97c7488e6329da7f48ca136c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:14:29 +0200 Subject: [PATCH 611/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From ef132a0c537b795752fe92d494046768f06d75ce Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:16:14 +0200 Subject: [PATCH 612/792] Relicense under the GPLv3 (only) Signed-off-by: Gergely Nagy --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 19 +++++++++---------- src/Kaleidoscope-LED-AlphaSquare.h | 19 +++++++++---------- src/Kaleidoscope/AlphaSquare-Effect.cpp | 19 +++++++++---------- src/Kaleidoscope/AlphaSquare-Effect.h | 19 +++++++++---------- src/Kaleidoscope/AlphaSquare-Symbols.h | 19 +++++++++---------- src/Kaleidoscope/LED-AlphaSquare-3x4.h | 19 +++++++++---------- src/Kaleidoscope/LED-AlphaSquare-4x4.h | 19 +++++++++---------- src/Kaleidoscope/LED-AlphaSquare.cpp | 19 +++++++++---------- src/Kaleidoscope/LED-AlphaSquare.h | 19 +++++++++---------- 9 files changed, 81 insertions(+), 90 deletions(-) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index 28b755de..d301dd52 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -2,18 +2,17 @@ * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope-LED-AlphaSquare.h b/src/Kaleidoscope-LED-AlphaSquare.h index 160d4eb3..a4074126 100644 --- a/src/Kaleidoscope-LED-AlphaSquare.h +++ b/src/Kaleidoscope-LED-AlphaSquare.h @@ -2,18 +2,17 @@ * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index c75a4dff..faf57b19 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -2,18 +2,17 @@ * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index 24ebba73..d72c505f 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -2,18 +2,17 @@ * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/AlphaSquare-Symbols.h b/src/Kaleidoscope/AlphaSquare-Symbols.h index 28be9510..e675251d 100644 --- a/src/Kaleidoscope/AlphaSquare-Symbols.h +++ b/src/Kaleidoscope/AlphaSquare-Symbols.h @@ -2,18 +2,17 @@ * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/LED-AlphaSquare-3x4.h b/src/Kaleidoscope/LED-AlphaSquare-3x4.h index 84a0f526..a8e6c344 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-3x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-3x4.h @@ -1,18 +1,17 @@ /* Kaleidoscope-LED-AlphaSquare -- 3x4 pixel LED alphabet * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ diff --git a/src/Kaleidoscope/LED-AlphaSquare-4x4.h b/src/Kaleidoscope/LED-AlphaSquare-4x4.h index 743f3268..217f018e 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-4x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-4x4.h @@ -1,18 +1,17 @@ /* Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index ac7c608d..48afb85c 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -2,18 +2,17 @@ * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index 18cb1706..eb2c8117 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -2,18 +2,17 @@ * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once From 3c5380a34c6ba8deb613d7f9d44b8a65d6fa874a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:16:16 +0200 Subject: [PATCH 613/792] Assign my copyright to Keyboard.io While the original plugin was written independently, significant developments were made while working for Keyboard.io. As such, I feel it is appropriate to assign copyright to the company. Signed-off-by: Gergely Nagy --- examples/LED-AlphaSquare/LED-AlphaSquare.ino | 2 +- library.properties | 2 +- src/Kaleidoscope-LED-AlphaSquare.h | 2 +- src/Kaleidoscope/AlphaSquare-Effect.cpp | 2 +- src/Kaleidoscope/AlphaSquare-Effect.h | 2 +- src/Kaleidoscope/AlphaSquare-Symbols.h | 2 +- src/Kaleidoscope/LED-AlphaSquare-3x4.h | 2 +- src/Kaleidoscope/LED-AlphaSquare-4x4.h | 2 +- src/Kaleidoscope/LED-AlphaSquare.cpp | 2 +- src/Kaleidoscope/LED-AlphaSquare.h | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index d301dd52..5030ba8d 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/library.properties b/library.properties index ecc6a2f2..d67491b7 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=Kaleidoscope-LED-AlphaSquare version=0.0.0 author=Gergely Nagy -maintainer=Gergely Nagy +maintainer=Gergely Nagy sentence=4x4 pixel LED alphabet, to be used with Kaleidoscope. paragraph=Includes a small, 4x4 font of alphanumerics, so you can have text on your keyboard LEDs. category=Communication diff --git a/src/Kaleidoscope-LED-AlphaSquare.h b/src/Kaleidoscope-LED-AlphaSquare.h index a4074126..9366536c 100644 --- a/src/Kaleidoscope-LED-AlphaSquare.h +++ b/src/Kaleidoscope-LED-AlphaSquare.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/Kaleidoscope/AlphaSquare-Effect.cpp index faf57b19..d5d343a5 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/Kaleidoscope/AlphaSquare-Effect.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/Kaleidoscope/AlphaSquare-Effect.h index d72c505f..af9d4554 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/Kaleidoscope/AlphaSquare-Effect.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/AlphaSquare-Symbols.h b/src/Kaleidoscope/AlphaSquare-Symbols.h index e675251d..05b74566 100644 --- a/src/Kaleidoscope/AlphaSquare-Symbols.h +++ b/src/Kaleidoscope/AlphaSquare-Symbols.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/LED-AlphaSquare-3x4.h b/src/Kaleidoscope/LED-AlphaSquare-3x4.h index a8e6c344..2fae3bf0 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-3x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-3x4.h @@ -1,5 +1,5 @@ /* Kaleidoscope-LED-AlphaSquare -- 3x4 pixel LED alphabet - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/LED-AlphaSquare-4x4.h b/src/Kaleidoscope/LED-AlphaSquare-4x4.h index 217f018e..f33e3388 100644 --- a/src/Kaleidoscope/LED-AlphaSquare-4x4.h +++ b/src/Kaleidoscope/LED-AlphaSquare-4x4.h @@ -1,5 +1,5 @@ /* Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/Kaleidoscope/LED-AlphaSquare.cpp index 48afb85c..3004ec48 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/Kaleidoscope/LED-AlphaSquare.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/Kaleidoscope/LED-AlphaSquare.h index eb2c8117..1c602064 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/Kaleidoscope/LED-AlphaSquare.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-AlphaSquare -- 4x4 pixel LED alphabet - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 From 6f5fd3ccdce839457469f61280bbc833b773148b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:16:18 +0200 Subject: [PATCH 614/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From d61d87c142f3144cb64a06a0172267c563f1158c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:16:48 +0200 Subject: [PATCH 615/792] Relicense under the GPLv3 (only) Signed-off-by: Gergely Nagy --- examples/LED-Stalker/LED-Stalker.ino | 19 +++++++++---------- src/Kaleidoscope-LED-Stalker.h | 19 +++++++++---------- src/Kaleidoscope/LED-Stalker.cpp | 19 +++++++++---------- src/Kaleidoscope/LED-Stalker.h | 19 +++++++++---------- 4 files changed, 36 insertions(+), 40 deletions(-) diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index d5721429..60776f90 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -2,18 +2,17 @@ * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope-LED-Stalker.h b/src/Kaleidoscope-LED-Stalker.h index e9c84797..506453c5 100644 --- a/src/Kaleidoscope-LED-Stalker.h +++ b/src/Kaleidoscope-LED-Stalker.h @@ -2,18 +2,17 @@ * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Copyright (C) 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 43ac29f2..b875504b 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -2,18 +2,17 @@ * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index b1b2517c..21484e60 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -2,18 +2,17 @@ * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once From 281d6d2e008539847207b1cfd7ab51018c822cf0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:16:51 +0200 Subject: [PATCH 616/792] Assign my copyright to Keyboard.io While the original plugin was written independently, significant developments were made while working for Keyboard.io. As such, I feel it is appropriate to assign copyright to the company. Signed-off-by: Gergely Nagy --- examples/LED-Stalker/LED-Stalker.ino | 2 +- library.properties | 2 +- src/Kaleidoscope-LED-Stalker.h | 2 +- src/Kaleidoscope/LED-Stalker.cpp | 2 +- src/Kaleidoscope/LED-Stalker.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index 60776f90..5362e971 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/library.properties b/library.properties index 8c121e5d..47accd64 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=Kaleidoscope-LED-Stalker version=0.0.0 author=Gergely Nagy -maintainer=Gergely Nagy +maintainer=Gergely Nagy sentence=Stalk keys pressed by lighting up and fading back the LED under them. paragraph=Stalk keys pressed by lighting up and fading back the LED under them. category=Communication diff --git a/src/Kaleidoscope-LED-Stalker.h b/src/Kaleidoscope-LED-Stalker.h index 506453c5..042d66b0 100644 --- a/src/Kaleidoscope-LED-Stalker.h +++ b/src/Kaleidoscope-LED-Stalker.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them - * Copyright (C) 2017 Gergely Nagy + * Copyright (C) 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index b875504b..d5c80f5e 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/Kaleidoscope/LED-Stalker.h index 21484e60..e43d6354 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/Kaleidoscope/LED-Stalker.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 From 5bf662c22ed3178e09c971a3cf0cfbe2058627fc Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:16:53 +0200 Subject: [PATCH 617/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From 10ff504988f0988651a4fe6047f303df7a6b92fa Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:17:00 +0200 Subject: [PATCH 618/792] Relicense under the GPLv3 (only) Signed-off-by: Gergely Nagy --- examples/MagicCombo/MagicCombo.ino | 19 +++++++++---------- src/Kaleidoscope-MagicCombo.h | 19 +++++++++---------- src/Kaleidoscope/MagicCombo.cpp | 19 +++++++++---------- src/Kaleidoscope/MagicCombo.h | 19 +++++++++---------- 4 files changed, 36 insertions(+), 40 deletions(-) diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index 9d16b455..4ef9513a 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -2,18 +2,17 @@ * Kaleidoscope-MagicCombo -- Magic combo framework * Copyright (C) 2016, 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope-MagicCombo.h b/src/Kaleidoscope-MagicCombo.h index 8d390468..9497d068 100644 --- a/src/Kaleidoscope-MagicCombo.h +++ b/src/Kaleidoscope-MagicCombo.h @@ -2,18 +2,17 @@ * Kaleidoscope-MagicCombo -- Magic combo framework * Copyright (C) 2016, 2017 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index e17c09bf..6fb78647 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -2,18 +2,17 @@ * Kaleidoscope-MagicCombo -- Magic combo framework * Copyright (C) 2016, 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index d33531d9..29a13c90 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -2,18 +2,17 @@ * Kaleidoscope-MagicCombo -- Magic combo framework * Copyright (C) 2016, 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once From 21798eacdc2395b09d3016d5a7fec4034ba0b04a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:17:02 +0200 Subject: [PATCH 619/792] Assign my copyright to Keyboard.io While the original plugin was written independently, significant developments were made while working for Keyboard.io. As such, I feel it is appropriate to assign copyright to the company. Signed-off-by: Gergely Nagy --- examples/MagicCombo/MagicCombo.ino | 2 +- library.properties | 2 +- src/Kaleidoscope-MagicCombo.h | 2 +- src/Kaleidoscope/MagicCombo.cpp | 2 +- src/Kaleidoscope/MagicCombo.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/MagicCombo/MagicCombo.ino b/examples/MagicCombo/MagicCombo.ino index 4ef9513a..7a45ccbb 100644 --- a/examples/MagicCombo/MagicCombo.ino +++ b/examples/MagicCombo/MagicCombo.ino @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-MagicCombo -- Magic combo framework - * Copyright (C) 2016, 2017, 2018 Gergely Nagy + * Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/library.properties b/library.properties index 76089275..f12d0606 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=Kaleidoscope-MagicCombo version=0.0.0 author=Gergely Nagy -maintainer=Gergely Nagy +maintainer=Gergely Nagy sentence=Magic combo framework for Kaleidoscope. paragraph=Provides hooks for Kaleidoscope, to make it possible to run code on certain magic combinations. category=Communication diff --git a/src/Kaleidoscope-MagicCombo.h b/src/Kaleidoscope-MagicCombo.h index 9497d068..588dec13 100644 --- a/src/Kaleidoscope-MagicCombo.h +++ b/src/Kaleidoscope-MagicCombo.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-MagicCombo -- Magic combo framework - * Copyright (C) 2016, 2017 Gergely Nagy + * Copyright (C) 2016, 2017 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/Kaleidoscope/MagicCombo.cpp index 6fb78647..a9c30f92 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/Kaleidoscope/MagicCombo.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-MagicCombo -- Magic combo framework - * Copyright (C) 2016, 2017, 2018 Gergely Nagy + * Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope/MagicCombo.h b/src/Kaleidoscope/MagicCombo.h index 29a13c90..bd0e710c 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/Kaleidoscope/MagicCombo.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-MagicCombo -- Magic combo framework - * Copyright (C) 2016, 2017, 2018 Gergely Nagy + * Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc * * 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 From 4581f80189e8396205479ac290dbea9e54b1a68a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 22 Aug 2018 12:17:04 +0200 Subject: [PATCH 620/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From 3d8a7fbb61ccbbf552b7d649b58728ad1c160e87 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 09:04:28 +0200 Subject: [PATCH 621/792] Relicense under the GPLv3 (only) Signed-off-by: Gergely Nagy --- COPYING | 899 ++++++++++++++++++-------- src/Kaleidoscope-Hardware-Model01.cpp | 17 + src/Kaleidoscope-Hardware-Model01.h | 17 + 3 files changed, 651 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/Kaleidoscope-Hardware-Model01.cpp index fbdad29b..51f8f92b 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/Kaleidoscope-Hardware-Model01.cpp @@ -1,3 +1,20 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Hardware-Model01 -- Keyboard.io Model01 hardware support for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + #include #include #include diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 436043ae..187d4df7 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -1,3 +1,20 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Hardware-Model01 -- Keyboard.io Model01 hardware support for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include From 68919cece123405aa6a550b3baf9ec14c180c7cd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 09:15:39 +0200 Subject: [PATCH 622/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From 96442cc27a03b5702267d3521f3b624950387d3c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 18:49:17 +0200 Subject: [PATCH 623/792] Relicense under the GPLv3 (only) Also added license headers. Signed-off-by: Gergely Nagy --- COPYING | 899 ++++++++++++++++++++++---------- src/BootAnimation.cpp | 16 + src/BootAnimation.h | 16 + src/Kaleidoscope-LEDControl.cpp | 16 + src/Kaleidoscope-LEDControl.h | 16 + src/LED-Off.cpp | 16 + src/LED-Off.h | 16 + src/LEDUtils.cpp | 16 + src/LEDUtils.h | 16 + 9 files changed, 745 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/BootAnimation.cpp b/src/BootAnimation.cpp index 396d438e..2ef5df0f 100644 --- a/src/BootAnimation.cpp +++ b/src/BootAnimation.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "BootAnimation.h" #include "Kaleidoscope-LEDControl.h" diff --git a/src/BootAnimation.h b/src/BootAnimation.h index f8b49cac..5da98af2 100644 --- a/src/BootAnimation.h +++ b/src/BootAnimation.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once void bootAnimation(void); diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index ddb9f2d5..c43c7918 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "Kaleidoscope-LEDControl.h" #include "Kaleidoscope-Focus.h" diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 9c2acf69..f14daf9d 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include diff --git a/src/LED-Off.cpp b/src/LED-Off.cpp index 25a74c04..324abfb7 100644 --- a/src/LED-Off.cpp +++ b/src/LED-Off.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "LED-Off.h" namespace kaleidoscope { diff --git a/src/LED-Off.h b/src/LED-Off.h index 1da39edf..7a33a3db 100644 --- a/src/LED-Off.h +++ b/src/LED-Off.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include "Kaleidoscope-LEDControl.h" diff --git a/src/LEDUtils.cpp b/src/LEDUtils.cpp index 72e6993d..68407397 100644 --- a/src/LEDUtils.cpp +++ b/src/LEDUtils.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "LEDUtils.h" cRGB diff --git a/src/LEDUtils.h b/src/LEDUtils.h index d8d3d511..1de96922 100644 --- a/src/LEDUtils.h +++ b/src/LEDUtils.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include From be5085a48be7668a3fd0cf16b641d86eb8855c74 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 18:50:30 +0200 Subject: [PATCH 624/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From 3a5b5a3501bb3bd9ba4d58f2451c6e677cb71bce Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 21:54:24 +0200 Subject: [PATCH 625/792] Relicense under the GPLv3 (only) Signed-off-by: Gergely Nagy --- COPYING | 899 ++++++++++++++------ src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 19 +- src/Kaleidoscope-LEDEffect-BootGreeting.h | 19 +- 3 files changed, 635 insertions(+), 302 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index c88f5eb4..9f30ba5e 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -2,18 +2,17 @@ * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #include "Kaleidoscope-LEDEffect-BootGreeting.h" diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index 7e15d4ad..d59afd07 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -2,18 +2,17 @@ * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time * Copyright (C) 2017, 2018 Gergely Nagy * - * 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 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, version 3. * - * 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. + * 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 . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ #pragma once From 9d4794910911aa90c5db858c6e31dca2c8e00f27 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 21:54:33 +0200 Subject: [PATCH 626/792] Assign my copyright to Keyboard.io While the original plugin was written independently, significant developments were made while working for Keyboard.io. As such, I feel it is appropriate to assign copyright to the company. Signed-off-by: Gergely Nagy --- library.properties | 2 +- src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 2 +- src/Kaleidoscope-LEDEffect-BootGreeting.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library.properties b/library.properties index e01ffae9..520eac91 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=Kaleidoscope-LEDEffect-BootGreeting version=0.0.1 author=Gergely Nagy -maintainer=Gergely Nagy +maintainer=Gergely Nagy sentence=A boot-time LED greeting paragraph=Makes the LED button breathe for a short while after keyboard boot. category=Communication diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index 9f30ba5e..48e1bd63 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index d59afd07..ebf9facb 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time - * Copyright (C) 2017, 2018 Gergely Nagy + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 From df22e60048fa3a8aa92829ed8c6e2c0000d71d1b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 21:54:47 +0200 Subject: [PATCH 627/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From 8e197705089ce037a21a6b002baa2a4da7b80e35 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:00:15 +0200 Subject: [PATCH 628/792] Relicense under GPLv3 (only), and add headers. Signed-off-by: Gergely Nagy --- COPYING | 899 +++++++++++++++++-------- src/Kaleidoscope-LEDEffect-Breathe.cpp | 16 + src/Kaleidoscope-LEDEffect-Breathe.h | 16 + 3 files changed, 649 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp index 1d0b92ab..c3ba8432 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDEffect-Breathe - A breathing effect on the LEDs, for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "Kaleidoscope-LEDEffect-Breathe.h" namespace kaleidoscope { diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index 64674f2b..8eef07ba 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDEffect-Breathe - A breathing effect on the LEDs, for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include "Kaleidoscope-LEDControl.h" From 895679f23125d6cbb269ce7c74037cbd48d1c6cb Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:00:18 +0200 Subject: [PATCH 629/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From 0e30f74210f05d0d5e5d9558452175a400e5759c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:01:27 +0200 Subject: [PATCH 630/792] Relicense under GPLv3 (only), and add headers. Signed-off-by: Gergely Nagy --- COPYING | 899 ++++++++++++++++++--------- src/Kaleidoscope-LEDEffect-Chase.cpp | 16 + src/Kaleidoscope-LEDEffect-Chase.h | 16 + 3 files changed, 649 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/Kaleidoscope-LEDEffect-Chase.cpp index 6bc3d5d0..6ff9c77d 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/Kaleidoscope-LEDEffect-Chase.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDEffect-Chase - A Chase LED effect for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "Kaleidoscope-LEDEffect-Chase.h" namespace kaleidoscope { diff --git a/src/Kaleidoscope-LEDEffect-Chase.h b/src/Kaleidoscope-LEDEffect-Chase.h index 24da4d34..1f3c2bcd 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.h +++ b/src/Kaleidoscope-LEDEffect-Chase.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDEffect-Chase - A Chase LED effect for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include "Kaleidoscope-LEDControl.h" From 03739d27b0a9c32cbb0879f6fd05b56bc2d729e1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:01:31 +0200 Subject: [PATCH 631/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From bfddd0a13ca861af683386e1e238fba7b1d7404a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:02:30 +0200 Subject: [PATCH 632/792] Relicense under GPLv3 (only), and add headers. Signed-off-by: Gergely Nagy --- COPYING | 899 +++++++++++++++++-------- src/Kaleidoscope-LEDEffect-Rainbow.cpp | 16 + src/Kaleidoscope-LEDEffect-Rainbow.h | 16 + 3 files changed, 649 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/Kaleidoscope-LEDEffect-Rainbow.cpp index e60eb60e..56fad332 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/Kaleidoscope-LEDEffect-Rainbow.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDEffect-Rainbow - Rainbow LED effects for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "Kaleidoscope-LEDEffect-Rainbow.h" namespace kaleidoscope { diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index f9930909..bcabfee6 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDEffect-Rainbow - Rainbow LED effects for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include "Kaleidoscope-LEDControl.h" From 4d212c6f0580f12274707b7c17ae5e64cb5d34e8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:02:34 +0200 Subject: [PATCH 633/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From bf1d5ddd39966a6e12cf888fbf17c1d6f805acc4 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:06:47 +0200 Subject: [PATCH 634/792] Relicense under GPLv3 (only), and add headers. Signed-off-by: Gergely Nagy --- COPYING | 899 +++++++++++++++------- src/Kaleidoscope-LEDEffect-SolidColor.cpp | 16 + src/Kaleidoscope-LEDEffect-SolidColor.h | 16 + 3 files changed, 649 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.cpp b/src/Kaleidoscope-LEDEffect-SolidColor.cpp index 94d98470..afbece7d 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.cpp +++ b/src/Kaleidoscope-LEDEffect-SolidColor.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDEffect-SolidColor - Solid color LED effects for Kaleidoscope. + * Copyright (C) 2017 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "Kaleidoscope-LEDEffect-SolidColor.h" namespace kaleidoscope { diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.h b/src/Kaleidoscope-LEDEffect-SolidColor.h index 1590caf3..d91d7553 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.h +++ b/src/Kaleidoscope-LEDEffect-SolidColor.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-LEDEffect-SolidColor - Solid color LED effects for Kaleidoscope. + * Copyright (C) 2017 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include "Kaleidoscope-LEDControl.h" From 940d092664ca2a6bed886c976f188b5d161d40ad Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:07:24 +0200 Subject: [PATCH 635/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From de1b71775d880163ac66f9a08906047ba1514ae9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:08:16 +0200 Subject: [PATCH 636/792] Relicense under GPLv3 (only), and add headers. Signed-off-by: Gergely Nagy --- COPYING | 899 +++++++++++++++++++++++++----------- src/Kaleidoscope-Macros.cpp | 16 + src/Kaleidoscope-Macros.h | 16 + src/MacroKeyDefs.h | 16 + src/MacroSteps.h | 16 + 5 files changed, 681 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-Macros.cpp b/src/Kaleidoscope-Macros.cpp index 7f51cfa1..985eed8b 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/Kaleidoscope-Macros.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-Macros - Macro keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "Kaleidoscope-Macros.h" #include "kaleidoscope/hid.h" diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index f1eb6c01..a2fda6fd 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-Macros - Macro keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include diff --git a/src/MacroKeyDefs.h b/src/MacroKeyDefs.h index 4907c7a2..ae4fbb7d 100644 --- a/src/MacroKeyDefs.h +++ b/src/MacroKeyDefs.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-Macros - Macro keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #define IS_MACRO B00100000 diff --git a/src/MacroSteps.h b/src/MacroSteps.h index f3e668f2..39bf2a64 100644 --- a/src/MacroSteps.h +++ b/src/MacroSteps.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-Macros - Macro keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once typedef enum { From bd92587cdf0910c4a9b3278294583abf06d4f78b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:08:39 +0200 Subject: [PATCH 637/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From 77bbc8e3dfa7bbced6ff93ed869a33b8eb5e41af Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:09:09 +0200 Subject: [PATCH 638/792] Relicense under GPLv3 (only), and add headers. Signed-off-by: Gergely Nagy --- COPYING | 899 ++++++++++++++++++-------- src/Kaleidoscope-Model01-TestMode.cpp | 16 + src/Kaleidoscope-Model01-TestMode.h | 16 + 3 files changed, 649 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index dbb536f9..0bf9f478 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-Model01-TestMode - A factory test mode for the Model 01. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "Kaleidoscope.h" #include "Kaleidoscope-Model01-TestMode.h" #include "Kaleidoscope-LEDEffect-Rainbow.h" diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 38315482..cd7f768a 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-Model01-TestMode - A factory test mode for the Model 01. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include From fcb06e201e1ba8f06ffc1358c719dfb8fd7348da Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:09:12 +0200 Subject: [PATCH 639/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From d76932810451cf2f470f7b204527c4290db36f7b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:10:01 +0200 Subject: [PATCH 640/792] Relicense under GPLv3 (only), and add headers. Signed-off-by: Gergely Nagy --- COPYING | 899 ++++++++++++++++++++++----------- src/Kaleidoscope-MouseKeys.cpp | 16 + src/Kaleidoscope-MouseKeys.h | 16 + src/MouseKeyDefs.h | 16 + src/MouseWarpModes.h | 16 + src/MouseWrapper.cpp | 16 + src/MouseWrapper.h | 16 + 7 files changed, 713 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/Kaleidoscope-MouseKeys.cpp index 054a5d9f..a59cfd22 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/Kaleidoscope-MouseKeys.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-MouseKeys - Mouse keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include #include "Kaleidoscope-MouseKeys.h" diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index 5d01af4e..bc6615da 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-MouseKeys - Mouse keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include "Kaleidoscope.h" diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index 5f66a5d4..de649a4b 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-MouseKeys - Mouse keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #define IS_MOUSE_KEY B00010000 diff --git a/src/MouseWarpModes.h b/src/MouseWarpModes.h index 6f2b28a4..a81355ac 100644 --- a/src/MouseWarpModes.h +++ b/src/MouseWarpModes.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-MouseKeys - Mouse keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once // Warp modes determine how the plugin jumps the mouse pointer to a screen diff --git a/src/MouseWrapper.cpp b/src/MouseWrapper.cpp index 2c3af984..ec5b1a29 100644 --- a/src/MouseWrapper.cpp +++ b/src/MouseWrapper.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-MouseKeys - Mouse keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + // Mouse-related methods // diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index b07c8b5e..b85b950f 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-MouseKeys - Mouse keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include "Arduino.h" From 8d6fcb7c03c2f20fa6965f82669408d77e388822 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:10:21 +0200 Subject: [PATCH 641/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From 358e58a6efe84e6d356d7118d322e5114ea97284 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:11:29 +0200 Subject: [PATCH 642/792] Relicense under GPLv3 (only), and add headers. Signed-off-by: Gergely Nagy --- COPYING | 899 +++++++++++++++++++++++++----------- src/Kaleidoscope-NumPad.cpp | 16 + src/Kaleidoscope-NumPad.h | 16 + 3 files changed, 649 insertions(+), 282 deletions(-) diff --git a/COPYING b/COPYING index d159169d..94a9ed02 100644 --- a/COPYING +++ b/COPYING @@ -1,281 +1,622 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to + 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 -this service 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. +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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + 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 give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +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. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 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. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + 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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE 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. + 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 @@ -287,15 +628,15 @@ 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 -convey the exclusion of warranty; and each file should have at least +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. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -303,37 +644,31 @@ the "copyright" line and a pointer to where the full notice is found. 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, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + You should have received a copy of the GNU General Public License + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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. +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 +. + + 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 +. diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 43f643c5..2755efc8 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -1,3 +1,19 @@ +/* Kaleidoscope-NumPad - A NumPad plugin for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #include "Kaleidoscope-NumPad.h" #include "LEDUtils.h" #include "Kaleidoscope.h" diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index 0b85cd33..2487b64a 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -1,3 +1,19 @@ +/* Kaleidoscope-NumPad - A NumPad plugin for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + #pragma once #include "Kaleidoscope-LEDControl.h" From 54b7a809670aff09f7a9451d531345d67a7aa063 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 23 Aug 2018 22:11:33 +0200 Subject: [PATCH 643/792] Add CONTRIBUTING.md Copied from Kaleidoscope, as it is applicable here too. Signed-off-by: Gergely Nagy --- CONTRIBUTING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example From 380a2e8a28944810196ffb9059294dde93c61835 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 24 Aug 2018 00:24:59 -0700 Subject: [PATCH 644/792] rename some variables to make them clearer Signed-off-by: Jesse Vincent --- src/Kaleidoscope-NumPad.cpp | 11 +++++------ src/Kaleidoscope-NumPad.h | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 2755efc8..16e480e9 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -19,7 +19,7 @@ #include "Kaleidoscope.h" #include "layers.h" -byte NumPad_::row = 255, NumPad_::col = 255; +byte NumPad_::numpad_lock_key_row = 255, NumPad_::numpad_lock_key_col = 255; uint8_t NumPad_::numPadLayer; bool NumPad_::cleanupDone = true; bool NumPad_::originalNumLockState = false; @@ -70,8 +70,8 @@ kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { Key layer_key = Layer.getKey(numPadLayer, r, c); if (k == LockLayer(numPadLayer)) { - row = r; - col = c; + numpad_lock_key_row = r; + numpad_lock_key_col = c; } if ((k != layer_key) || (k == Key_NoKey) || (k.flags != KEY_FLAGS)) { @@ -82,11 +82,10 @@ kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { } } - if (row > ROWS || col > COLS) + if ((numpad_lock_key_row > ROWS) || (numpad_lock_key_col > COLS)) { return kaleidoscope::EventHandlerResult::OK; - cRGB lock_color = breath_compute(lock_hue); - LEDControl.setCrgbAt(row, col, lock_color); + LEDControl.setCrgbAt(numpad_lock_key_row, numpad_lock_key_col, lock_color); return kaleidoscope::EventHandlerResult::OK; } diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index 2487b64a..843a14da 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -32,7 +32,8 @@ class NumPad_ : public kaleidoscope::Plugin { kaleidoscope::EventHandlerResult afterEachCycle(); private: - static byte row, col; + static uint8_t numpad_lock_key_row; + static uint8_t numpad_lock_key_col; static bool cleanupDone; static bool originalNumLockState; }; From b491146f33184820f7b72a93514eaee85773aaee Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 24 Aug 2018 00:27:06 -0700 Subject: [PATCH 645/792] Extract a couple methods and rename a variable Signed-off-by: Jesse Vincent --- src/Kaleidoscope-NumPad.cpp | 52 +++++++++++++++++++++++-------------- src/Kaleidoscope-NumPad.h | 4 +++ 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 16e480e9..3bb77deb 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -36,32 +36,30 @@ static bool getNumlockState() { } static void syncNumlock(bool state) { - bool numState = getNumlockState(); - if (numState != state) { + bool numLockLEDState = getNumlockState(); + if (numLockLEDState != state) { kaleidoscope::hid::pressKey(Key_KeypadNumLock); } } -kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { - if (!Layer.isOn(numPadLayer)) { - bool numState = getNumlockState(); - if (!cleanupDone) { - LEDControl.set_mode(LEDControl.get_mode_index()); - if (!originalNumLockState) { - syncNumlock(false); - numState = false; - } - cleanupDone = true; - } - originalNumLockState = numState; - return kaleidoscope::EventHandlerResult::OK; +void NumPad_::cleanupNumlockState() { + bool numLockLEDState = getNumlockState(); + if (!cleanupDone) { + LEDControl.set_mode(LEDControl.get_mode_index()); + + if (!originalNumLockState) { + syncNumlock(false); + numLockLEDState = false; + } + cleanupDone = true; } + originalNumLockState = numLockLEDState; - cleanupDone = false; - syncNumlock(true); +} +void NumPad_::setKeyboardLEDColors(void) { LEDControl.set_mode(LEDControl.get_mode_index()); for (uint8_t r = 0; r < ROWS; r++) { @@ -82,12 +80,28 @@ kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { } } - if ((numpad_lock_key_row > ROWS) || (numpad_lock_key_col > COLS)) { + if ((numpad_lock_key_row <= ROWS) && (numpad_lock_key_col <= COLS)) { + + + cRGB lock_color = breath_compute(lock_hue); + LEDControl.setCrgbAt(numpad_lock_key_row, numpad_lock_key_col, lock_color); + } +} + +kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { + if (!Layer.isOn(numPadLayer)) { + cleanupNumlockState(); return kaleidoscope::EventHandlerResult::OK; + } + + cleanupDone = false; + syncNumlock(true); - LEDControl.setCrgbAt(numpad_lock_key_row, numpad_lock_key_col, lock_color); + setKeyboardLEDColors(); return kaleidoscope::EventHandlerResult::OK; } + + NumPad_ NumPad; diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index 843a14da..bad11578 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -32,6 +32,10 @@ class NumPad_ : public kaleidoscope::Plugin { kaleidoscope::EventHandlerResult afterEachCycle(); private: + + void cleanupNumlockState(void); + void setKeyboardLEDColors(void); + static uint8_t numpad_lock_key_row; static uint8_t numpad_lock_key_col; static bool cleanupDone; From 7c1a5cea95e822c546248e7ba538561e1a6f75cb Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 24 Aug 2018 00:53:33 -0700 Subject: [PATCH 646/792] Refactoring. no functional changes Signed-off-by: Jesse Vincent --- src/Kaleidoscope-NumPad.cpp | 20 +++++++++----------- src/Kaleidoscope-NumPad.h | 2 ++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 3bb77deb..34eb654b 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -27,15 +27,15 @@ cRGB NumPad_::color = CRGB(160, 0, 0); uint8_t NumPad_::lock_hue = 170; kaleidoscope::EventHandlerResult NumPad_::onSetup(void) { - originalNumLockState = !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); + originalNumLockState = getNumlockState(); return kaleidoscope::EventHandlerResult::OK; } -static bool getNumlockState() { +bool NumPad_::getNumlockState() { return !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); } -static void syncNumlock(bool state) { +void NumPad_::syncNumlockState(bool state) { bool numLockLEDState = getNumlockState(); if (numLockLEDState != state) { kaleidoscope::hid::pressKey(Key_KeypadNumLock); @@ -50,7 +50,7 @@ void NumPad_::cleanupNumlockState() { LEDControl.set_mode(LEDControl.get_mode_index()); if (!originalNumLockState) { - syncNumlock(false); + syncNumlockState(false); numLockLEDState = false; } cleanupDone = true; @@ -91,14 +91,12 @@ void NumPad_::setKeyboardLEDColors(void) { kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { if (!Layer.isOn(numPadLayer)) { cleanupNumlockState(); - return kaleidoscope::EventHandlerResult::OK; - } - - cleanupDone = false; - syncNumlock(true); + } else { + cleanupDone = false; + syncNumlockState(true); + setKeyboardLEDColors(); - - setKeyboardLEDColors(); + } return kaleidoscope::EventHandlerResult::OK; } diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index bad11578..4c7311f3 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -35,6 +35,8 @@ class NumPad_ : public kaleidoscope::Plugin { void cleanupNumlockState(void); void setKeyboardLEDColors(void); + bool getNumlockState(void); + void syncNumlockState(bool); static uint8_t numpad_lock_key_row; static uint8_t numpad_lock_key_col; From 79996b7216b9bba62763db9dd6aa63a71f0ebf50 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 24 Aug 2018 00:53:58 -0700 Subject: [PATCH 647/792] Only try to reset the numlock led if we actually haven't done the cleanup Signed-off-by: Jesse Vincent --- src/Kaleidoscope-NumPad.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 34eb654b..be424624 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -45,17 +45,16 @@ void NumPad_::syncNumlockState(bool state) { void NumPad_::cleanupNumlockState() { - bool numLockLEDState = getNumlockState(); if (!cleanupDone) { + bool numLockLEDState = getNumlockState(); LEDControl.set_mode(LEDControl.get_mode_index()); - if (!originalNumLockState) { syncNumlockState(false); numLockLEDState = false; } cleanupDone = true; + originalNumLockState = numLockLEDState; } - originalNumLockState = numLockLEDState; } From 8fb50b2415a49903d6f0a493313f02d938b89939 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 24 Aug 2018 01:02:22 -0700 Subject: [PATCH 648/792] Only run our "toggle numlock mode" once upon toggle of the layer Signed-off-by: Jesse Vincent --- src/Kaleidoscope-NumPad.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index be424624..2d32e666 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -21,7 +21,7 @@ byte NumPad_::numpad_lock_key_row = 255, NumPad_::numpad_lock_key_col = 255; uint8_t NumPad_::numPadLayer; -bool NumPad_::cleanupDone = true; +bool NumPad_::cleanupDone = false; bool NumPad_::originalNumLockState = false; cRGB NumPad_::color = CRGB(160, 0, 0); uint8_t NumPad_::lock_hue = 170; @@ -52,8 +52,8 @@ void NumPad_::cleanupNumlockState() { syncNumlockState(false); numLockLEDState = false; } - cleanupDone = true; originalNumLockState = numLockLEDState; + cleanupDone = true; } } @@ -90,10 +90,11 @@ void NumPad_::setKeyboardLEDColors(void) { kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { if (!Layer.isOn(numPadLayer)) { cleanupNumlockState(); - } else { - cleanupDone = false; + } else if (cleanupDone) { + // If it's the first time we're in this loop after toggling the Numpad mode on syncNumlockState(true); setKeyboardLEDColors(); + cleanupDone = false; } return kaleidoscope::EventHandlerResult::OK; From efbf158b132bce76374c40663dc2c2f3dc82bf3e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 24 Aug 2018 23:03:55 -0700 Subject: [PATCH 649/792] Bring back the LED breathing effect Signed-off-by: Jesse Vincent --- src/Kaleidoscope-NumPad.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 2d32e666..b621cd50 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -90,12 +90,13 @@ void NumPad_::setKeyboardLEDColors(void) { kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { if (!Layer.isOn(numPadLayer)) { cleanupNumlockState(); - } else if (cleanupDone) { - // If it's the first time we're in this loop after toggling the Numpad mode on - syncNumlockState(true); + } else { + if (cleanupDone) { + // If it's the first time we're in this loop after toggling the Numpad mode on + syncNumlockState(true); + cleanupDone = false; + } setKeyboardLEDColors(); - cleanupDone = false; - } return kaleidoscope::EventHandlerResult::OK; } From c6886b09fb15f89e2a69364e84d410dc3edd2460 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 24 Aug 2018 23:15:07 -0700 Subject: [PATCH 650/792] Change cleanupDone to numlockUnsynced to better represent what it does Signed-off-by: Jesse Vincent --- src/Kaleidoscope-NumPad.cpp | 10 +++++----- src/Kaleidoscope-NumPad.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index b621cd50..18d86928 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -21,7 +21,7 @@ byte NumPad_::numpad_lock_key_row = 255, NumPad_::numpad_lock_key_col = 255; uint8_t NumPad_::numPadLayer; -bool NumPad_::cleanupDone = false; +bool NumPad_::numlockUnsynced = false; bool NumPad_::originalNumLockState = false; cRGB NumPad_::color = CRGB(160, 0, 0); uint8_t NumPad_::lock_hue = 170; @@ -45,7 +45,7 @@ void NumPad_::syncNumlockState(bool state) { void NumPad_::cleanupNumlockState() { - if (!cleanupDone) { + if (!numlockUnsynced) { bool numLockLEDState = getNumlockState(); LEDControl.set_mode(LEDControl.get_mode_index()); if (!originalNumLockState) { @@ -53,7 +53,7 @@ void NumPad_::cleanupNumlockState() { numLockLEDState = false; } originalNumLockState = numLockLEDState; - cleanupDone = true; + numlockUnsynced = true; } } @@ -91,10 +91,10 @@ kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { if (!Layer.isOn(numPadLayer)) { cleanupNumlockState(); } else { - if (cleanupDone) { + if (numlockUnsynced) { // If it's the first time we're in this loop after toggling the Numpad mode on syncNumlockState(true); - cleanupDone = false; + numlockUnsynced = false; } setKeyboardLEDColors(); } diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index 4c7311f3..1d3595e9 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -40,7 +40,7 @@ class NumPad_ : public kaleidoscope::Plugin { static uint8_t numpad_lock_key_row; static uint8_t numpad_lock_key_col; - static bool cleanupDone; + static bool numlockUnsynced; static bool originalNumLockState; }; From e3acde94194bcc0c145ab5cf4e9109107b4e05c8 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 24 Aug 2018 23:23:08 -0700 Subject: [PATCH 651/792] rename a variable that didn't match the style guide Signed-off-by: Jesse Vincent --- src/Kaleidoscope-NumPad.cpp | 10 +++++----- src/Kaleidoscope-NumPad.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index 18d86928..d90fbcdc 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -19,7 +19,7 @@ #include "Kaleidoscope.h" #include "layers.h" -byte NumPad_::numpad_lock_key_row = 255, NumPad_::numpad_lock_key_col = 255; +byte NumPad_::numpadLayerToggleKeyRow = 255, NumPad_::numpadLayerToggleKeyCol = 255; uint8_t NumPad_::numPadLayer; bool NumPad_::numlockUnsynced = false; bool NumPad_::originalNumLockState = false; @@ -67,8 +67,8 @@ void NumPad_::setKeyboardLEDColors(void) { Key layer_key = Layer.getKey(numPadLayer, r, c); if (k == LockLayer(numPadLayer)) { - numpad_lock_key_row = r; - numpad_lock_key_col = c; + numpadLayerToggleKeyRow = r; + numpadLayerToggleKeyCol = c; } if ((k != layer_key) || (k == Key_NoKey) || (k.flags != KEY_FLAGS)) { @@ -79,11 +79,11 @@ void NumPad_::setKeyboardLEDColors(void) { } } - if ((numpad_lock_key_row <= ROWS) && (numpad_lock_key_col <= COLS)) { + if ((numpadLayerToggleKeyRow <= ROWS) && (numpadLayerToggleKeyCol <= COLS)) { cRGB lock_color = breath_compute(lock_hue); - LEDControl.setCrgbAt(numpad_lock_key_row, numpad_lock_key_col, lock_color); + LEDControl.setCrgbAt(numpadLayerToggleKeyRow, numpadLayerToggleKeyCol, lock_color); } } diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index 1d3595e9..016ded65 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -38,8 +38,8 @@ class NumPad_ : public kaleidoscope::Plugin { bool getNumlockState(void); void syncNumlockState(bool); - static uint8_t numpad_lock_key_row; - static uint8_t numpad_lock_key_col; + static uint8_t numpadLayerToggleKeyRow; + static uint8_t numpadLayerToggleKeyCol; static bool numlockUnsynced; static bool originalNumLockState; }; From ab89785ab5bb832c1ce60a6dc62484595cca7a49 Mon Sep 17 00:00:00 2001 From: matt venn Date: Mon, 3 Sep 2018 11:40:02 +0200 Subject: [PATCH 652/792] moved to millisAtCycleStart and fixed overflow bug present on ARM platform --- src/Kaleidoscope/LED-Stalker.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/Kaleidoscope/LED-Stalker.cpp index 57b55304..04c3b114 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/Kaleidoscope/LED-Stalker.cpp @@ -46,7 +46,7 @@ void StalkerEffect::update(void) { return; uint16_t now = millis(); - bool time_out = (now - step_start_time_) > step_length; + uint16_t elapsed = Kaleidoscope.millisAtCycleStart() - step_start_time_; for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { @@ -55,7 +55,7 @@ void StalkerEffect::update(void) { ::LEDControl.setCrgbAt(r, c, variant->compute(&step)); } - if (time_out) { + if (elapsed > step_length) { map_[r][c] = step; } @@ -66,8 +66,8 @@ void StalkerEffect::update(void) { } } - if (time_out) - step_start_time_ = now; + if (elapsed > step_length) + step_start_time_ = Kaleidoscope.millisAtCycleStart(); } namespace stalker { From 8605ff7d1d7ca0810d41f8cf19e618a8b9a4ac0a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:00 -0700 Subject: [PATCH 653/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From b9c5fd4c9103b063593219e944c10e3a6eec47c3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:00 -0700 Subject: [PATCH 654/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 5e9202d25d25f7b70c9ad91228f87c31e7f92c08 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 655/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 6d3d67157b288422cc03e07e05870917fff6d51d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 656/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 4606191ff62dc8199db54c7ff1440de67e2b9069 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 657/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From cc26fcc996345ddf48d22e4588d2155928c96b60 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 658/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 78816f4b36471f4920b109847b997e45da05625b Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 659/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 1972c9f7c4fede93dee16834e61aba9528a86d98 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 660/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From b8e10200fa89b4a6aae02becf9d09ccd79891244 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 661/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 020a67a41373e49654dd37068c454cbda58d3f65 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 662/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From cb081d2b903fe5010cb94be4714e434738491ecc Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 663/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 6d2a3edbd29f4904950cd21c65b469f4dd19cca2 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 664/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 13d781214da0f52ad8100dd0bb6ee34fdf67a27e Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 665/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 8ae0628ebdc89ec680a63bc7d0c8d4cdb81b466f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 666/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 9ba421050dbb9e5966b0b13280fc88f52cb64538 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:02 -0700 Subject: [PATCH 667/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From f248ea31563487a8361c9098ccf7f4ef48c4adc3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:02 -0700 Subject: [PATCH 668/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From e09c08dd8987d97634d6499dbe8e695deb16fbef Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:24:02 -0700 Subject: [PATCH 669/792] Update travis.yml to point to new bundle repo --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7030acf..e3e64f77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,15 @@ dist: trusty sudo: false os: - linux +addons: + apt: + packages: + - shellcheck install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Arduino-Boards hardware/keyboardio/avr + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware + - shellcheck bin/kaleidoscope-builder notifications: irc: channels: @@ -13,7 +18,7 @@ notifications: use_notice: true skip_join: true template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" + - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 9bab4e0bbf60ed1a1beadebb939a708abd95fabb Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:29 -0700 Subject: [PATCH 670/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From 69b05c652a442b05ee6a5b33e36159252d6621fa Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:29 -0700 Subject: [PATCH 671/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From a643e323e6d00a045b16f76f37305a60ae3401d3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:29 -0700 Subject: [PATCH 672/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From fbdc8bdf35dc8cf976379893eba2e03612044038 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:29 -0700 Subject: [PATCH 673/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From e525aef803ce3a909b9414df1d2d2077e12c943f Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:29 -0700 Subject: [PATCH 674/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From e886a27853f21f412c44f04b98f08df6465e4645 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:29 -0700 Subject: [PATCH 675/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From 637943c9243123cb98bc4988efb73b0bf67d21d4 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:29 -0700 Subject: [PATCH 676/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From 480e644104cd0cd90b9a73acd572d70e2a017be6 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:29 -0700 Subject: [PATCH 677/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From fd0b51932232d32268e33d177861e7bb41a6e551 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:30 -0700 Subject: [PATCH 678/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From cb4d0cbb033017d0f468cec3714f6493f9a10336 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:30 -0700 Subject: [PATCH 679/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From bb58eee9b880e632a9b24e3bc4cc43c02f95adb5 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:30 -0700 Subject: [PATCH 680/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From c738e6b991f9ebb72ff212a20cbf415f9ef365db Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:30 -0700 Subject: [PATCH 681/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From 5e672725c56dc4c7e792343b71d1d360d590ee24 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:30 -0700 Subject: [PATCH 682/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From 9320ade74f5c1553a3efee0a5ef8e9d45d2ba7a3 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:30 -0700 Subject: [PATCH 683/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From 0c7adb68b902561e7941d96a98d33c79c8dbb594 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:30 -0700 Subject: [PATCH 684/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From c8c4d1a2dd590af4e3deb94afc7b117149915307 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:30 -0700 Subject: [PATCH 685/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From 9071ede7301cc5bc331c8295169480bce7cd3ae7 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 4 Sep 2018 18:42:30 -0700 Subject: [PATCH 686/792] shellcheck should only be run in the Kaleidoscope repo --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3e64f77..23d30ccc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,10 @@ dist: trusty sudo: false os: - linux -addons: - apt: - packages: - - shellcheck install: - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware - - shellcheck bin/kaleidoscope-builder notifications: irc: channels: From 4e8b7385216f6f23a04164d2ae7cfe9a0fcded2d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 27 Sep 2018 23:43:59 +0200 Subject: [PATCH 687/792] Coding style fix Our coding style says that private properties should end with an underscore, lets make it so. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Breathe.cpp | 4 ++-- src/Kaleidoscope-LEDEffect-Breathe.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp index debcb0b4..86795af9 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -20,9 +20,9 @@ namespace kaleidoscope { void LEDBreatheEffect::update(void) { uint16_t now = millis(); - if ((now - last_update) < UPDATE_INTERVAL) + if ((now - last_update_) < UPDATE_INTERVAL) return; - last_update = now; + last_update_ = now; cRGB color = breath_compute(hue, saturation); ::LEDControl.set_all_leds_to(color); diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index 39fc2a55..edb2db27 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -31,7 +31,7 @@ class LEDBreatheEffect : public LEDMode { void update(void) final; private: - uint16_t last_update = 0; + uint16_t last_update_ = 0; }; } From 57f3ddd43a40dbc1d2602e26cd7672855c17f9c1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Thu, 27 Sep 2018 23:45:05 +0200 Subject: [PATCH 688/792] Use Kaleidoscope.millisAtCycleStart() Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-Breathe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/Kaleidoscope-LEDEffect-Breathe.cpp index 86795af9..1fc02982 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/Kaleidoscope-LEDEffect-Breathe.cpp @@ -19,7 +19,7 @@ namespace kaleidoscope { void LEDBreatheEffect::update(void) { - uint16_t now = millis(); + uint16_t now = Kaleidoscope.millisAtCycleStart(); if ((now - last_update_) < UPDATE_INTERVAL) return; last_update_ = now; From f28f85a4b170dcb86f3e878697554eab949d8bcd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 28 Sep 2018 00:13:39 +0200 Subject: [PATCH 689/792] Add a description, and drop OneShot leftovers Fixes #1. Signed-off-by: Gergely Nagy --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 7fd3a343..99ef3c45 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,10 @@ [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 -... +USB-Quirks provides a few methods to deal with more obscure parts of the USB spec, such as changing between `Boot` and `Report` protocols. These are in a separate plugin, because these features are not part of the USB spec, and are often workarounds for various issues. See the provided methods for more information about what they're useful for. ## Using the plugin -After adding one-shot keys to the keymap, all one needs to do, is enable the -plugin: - ```c++ #include #include From c482062be49203836391d342b5e4748b3cd66fe8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 28 Sep 2018 16:41:39 +0200 Subject: [PATCH 690/792] Emit an error when compiling for anything else but the Model01 This fixes #3. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-Model01-TestMode.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index cd7f768a..59576643 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -16,6 +16,10 @@ #pragma once +#ifndef ARDUINO_AVR_MODEL01 +#error The Kaleidoscope-Model01-TestMode plugin was designed for the Keyboardio Model01, and does not work with any other hardware. +#endif + #include #include "Kaleidoscope.h" From a2195357c6987079e5d943fc10da57e21f7220af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csilla=20Nagyn=C3=A9=20Martin=C3=A1k?= Date: Tue, 2 Oct 2018 14:54:52 +0200 Subject: [PATCH 691/792] Add an example sketch, and a Travis CI control file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #4. Signed-off-by: Csilla Nagyné Martinák --- .travis.yml | 14 +++++ .../LEDEffect-BootGreeting.ino | 55 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 .travis.yml create mode 100644 examples/LEDEffect-BootGreeting/LEDEffect-BootGreeting.ino diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..49b8c498 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/examples/LEDEffect-BootGreeting/LEDEffect-BootGreeting.ino b/examples/LEDEffect-BootGreeting/LEDEffect-BootGreeting.ino new file mode 100644 index 00000000..a539a3c0 --- /dev/null +++ b/examples/LEDEffect-BootGreeting/LEDEffect-BootGreeting.ino @@ -0,0 +1,55 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time + * Copyright (C) 2017, 2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + +#include +#include + +#include "LED-Off.h" + +// *INDENT-OFF* +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + ( + Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_NoKey, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_NoKey), +}; +// *INDENT-ON* + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect, + LEDOff); + +void setup() { + Kaleidoscope.setup(); +} + +void loop() { + Kaleidoscope.loop(); +} From a180a6784d17fc9a0f46004ac9cd2ffaee20ac7b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 2 Oct 2018 16:18:39 +0200 Subject: [PATCH 692/792] Add prev/next mouse buttons KeyboardioHID already supports these keys, so lets expose them! Fixes #28. Signed-off-by: Gergely Nagy --- README.md | 5 +++-- src/MouseKeyDefs.h | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a990d9d3..a2d3ae6f 100644 --- a/README.md +++ b/README.md @@ -85,8 +85,9 @@ properties (see below). Buttons are even simpler than movement: there is no movement speed, nor acceleration involved. One just presses them. -* `Key_mouseBtnL`, `Key_mouseBtnM`, `Key_mouseBtnR`: The left, middle, and right - mouse buttons, respectively. +* `Key_mouseBtnL`, `Key_mouseBtnM`, `Key_mouseBtnR`, `Key_mouseBtnP`, + `Key_mouseBtnN`: The left, middle, right, previous, and next mouse buttons, + respectively. ## Warping diff --git a/src/MouseKeyDefs.h b/src/MouseKeyDefs.h index de649a4b..a6e8c6b7 100644 --- a/src/MouseKeyDefs.h +++ b/src/MouseKeyDefs.h @@ -22,7 +22,8 @@ #define KEY_MOUSE_BTN_L MOUSE_LEFT // Synthetic key #define KEY_MOUSE_BTN_M MOUSE_MIDDLE // Synthetic key #define KEY_MOUSE_BTN_R MOUSE_RIGHT // Synthetic key - +#define KEY_MOUSE_BTN_P MOUSE_PREV +#define KEY_MOUSE_BTN_N MOUSE_NEXT #define KEY_MOUSE_UP B0000001 #define KEY_MOUSE_DOWN B0000010 @@ -62,3 +63,5 @@ #define Key_mouseBtnL (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_L, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } #define Key_mouseBtnM (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_M, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } #define Key_mouseBtnR (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_R, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } +#define Key_mouseBtnP (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_P, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } +#define Key_mouseBtnN (Key) { KEY_MOUSE_BUTTON | KEY_MOUSE_BTN_N, KEY_FLAGS | SYNTHETIC | IS_MOUSE_KEY } From ba332c1846e301d04fdba2e99da397ad08122e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csilla=20Nagyn=C3=A9=20Martin=C3=A1k?= Date: Wed, 3 Oct 2018 06:29:25 +0200 Subject: [PATCH 693/792] Remove a debugging Serial.print() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These two lines went in by mistake earlier, they were meant for local debugging only. As such, having them in the plugin is a bug, easily squashed by removing them. Signed-off-by: Csilla Nagyné Martinák --- src/Kaleidoscope/EEPROM-Settings.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 0e187a09..657fa89c 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -62,9 +62,6 @@ uint16_t EEPROMSettings::requestSlice(uint16_t size) { if (sealed_) return 0; - Serial.print("requestSlice; size="); - Serial.println(size); - uint16_t start = next_start_; next_start_ += size; From 47efb47506673554cd064daa9e32630f92aa8fae Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 3 Oct 2018 06:42:08 +0200 Subject: [PATCH 694/792] Seal the EEPROM layout automatically If `EEPROMSettings.seal()` wasn't explicitly called, seal the layout in `beforeEachCycle()`. On the flip side, this makes user sketches simpler, because they don't have to seal explicitly. This is done at the cost of an if check each cycle. In the long run, EEPROM layout management will be moving out of this plugin, so this check will be eventually dropped too. Signed-off-by: Gergely Nagy --- README.md | 3 +++ src/Kaleidoscope/EEPROM-Settings.cpp | 7 +++++++ src/Kaleidoscope/EEPROM-Settings.h | 1 + 3 files changed, 11 insertions(+) diff --git a/README.md b/README.md index d2365de2..d6e86c33 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,9 @@ The plugin provides the `EEPROMSettings` object, which has the following methods > Seal the `EEPROM` layout, so no new slices can be requested. The CRC checksum > is considered final at this time, and the `isValid()`, `crc()`, `used()` and > `version()` methods can be used from this point onwards. +> +> If not called explicitly, the layout will be sealed automatically after +> `setup()` in the sketch finished. ### `update()` diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 657fa89c..4e4fb247 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -30,6 +30,13 @@ EventHandlerResult EEPROMSettings::onSetup() { return EventHandlerResult::OK; } +EventHandlerResult EEPROMSettings::beforeEachCycle() { + if (!sealed_) + seal(); + + return EventHandlerResult::OK; +} + bool EEPROMSettings::isValid(void) { return is_valid_; } diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 3fccd2ba..33cb0214 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -26,6 +26,7 @@ class EEPROMSettings : public kaleidoscope::Plugin { EEPROMSettings(void) {} EventHandlerResult onSetup(); + EventHandlerResult beforeEachCycle(); static void update(void); static bool isValid(void); From a02cde9c21c1282b9e27a96ff458a84aae649f4c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 3 Oct 2018 08:47:08 +0200 Subject: [PATCH 695/792] Automatically pull in EEPROMSettings, and set up defaults To make it easier to use the plugin, pull in `EEPROMSettings` by default, and explicitly call its `onSetup` (it is safe to do so), so user sketches don't have to if they don't use `EEPROMSettings` directly. Also set `Layer.getKey` to `EEPROMKeymap.getKeyOverride` to provide a sensible default. Signed-off-by: Gergely Nagy --- README.md | 7 +------ examples/EEPROM-Keymap/EEPROM-Keymap.ino | 9 +++------ src/Kaleidoscope/EEPROM-Keymap.cpp | 7 +++++++ src/Kaleidoscope/EEPROM-Keymap.h | 2 ++ 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index ec8373da..3fab8197 100644 --- a/README.md +++ b/README.md @@ -37,11 +37,9 @@ We can then update the keymap via [Focus][plugin:focus]. ```c++ #include #include -#include #include -KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, - EEPROMKeymap, +KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, Focus); void setup() { @@ -52,10 +50,7 @@ void setup() { Focus.addHook(FOCUS_HOOK_KEYMAP); Focus.addHook(FOCUS_HOOK_KEYMAP_TRANSFER); - Layer.getKey = EEPROMKeymap.getKeyOverride; - EEPROMKeymap.max_layers(1); - EEPROMSettings.seal(); } ``` diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index 60e48a19..e7771534 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -20,7 +20,7 @@ #include // *INDENT-OFF* -const Key keymaps[][ROWS][COLS] PROGMEM = { +KEYMAPS( [0] = KEYMAP_STACKED (Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, @@ -37,10 +37,10 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, Key_skip), -}; +) // *INDENT-ON* -KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, EEPROMKeymap, Focus); +KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, Focus); void setup() { Serial.begin(9600); @@ -53,10 +53,7 @@ void setup() { Focus.addHook(FOCUS_HOOK_HELP); Focus.addHook(FOCUS_HOOK_VERSION); - Layer.getKey = EEPROMKeymap.getKeyOverride; - EEPROMKeymap.max_layers(1); - EEPROMSettings.seal(); } void loop() { diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index aede1faf..0b707fe2 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -23,6 +23,13 @@ namespace kaleidoscope { uint16_t EEPROMKeymap::keymap_base_; uint8_t EEPROMKeymap::max_layers_; +EventHandlerResult EEPROMKeymap::onSetup() { + ::EEPROMSettings.onSetup(); + Layer.getKey = ::EEPROMKeymap.getKeyOverride; + + return EventHandlerResult::OK; +} + void EEPROMKeymap::max_layers(uint8_t max) { max_layers_ = max; keymap_base_ = ::EEPROMSettings.requestSlice(max_layers_ * ROWS * COLS * 2); diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 26ebfb48..631e51b3 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -25,6 +25,8 @@ class EEPROMKeymap : public kaleidoscope::Plugin { public: EEPROMKeymap(void) {} + EventHandlerResult onSetup(); + static void max_layers(uint8_t max); static uint16_t keymap_base(void); From f3eb6a7200fc78ba493f0d6b815bf34137b275db Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 3 Oct 2018 08:26:34 +0200 Subject: [PATCH 696/792] Try to avoid a possible PROGMEM overflow in getKeyOverride If we're looking up a key from `PROGMEM`, only do that if the layer in question is smaller than `layer_count`. Doing otherwise would read garbage from `PROGMEM` in case we try to read from a layer higher than what we have in there. This can happen if we have more layers in `EEPROM` than in `PROGMEM`. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 0b707fe2..0be6c4f6 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -53,8 +53,17 @@ Key EEPROMKeymap::getKeyOverride(uint8_t layer, byte row, byte col) { Key key; key = getKey(layer, row, col); - if (key == Key_Transparent || layer >= max_layers_) + + /* + * If we read a transparent key from EEPROM, or we're trying to read from a + * layer higher than what is available there (max_layers), check if we're below + * the layer count in PROGMEM (layer_count). If we are, read from PROGMEM, + * otherwise leave the key as-is (either transparent or NoKey). + */ + if ((key == Key_Transparent || layer >= max_layers) && + (layer < layer_count)) key = Layer.getKeyFromPROGMEM(layer, row, col); + return key; } From 906f567698e700b397e57a0dd4dd422409bf3b76 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 3 Oct 2018 12:34:59 +0200 Subject: [PATCH 697/792] Fix a compile error `max_layers` is a method, so comparing to that would be integer<->pointer comparison. We want to compare to `max_layers_`. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Keymap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 0be6c4f6..2084ceb1 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -60,7 +60,7 @@ Key EEPROMKeymap::getKeyOverride(uint8_t layer, byte row, byte col) { * the layer count in PROGMEM (layer_count). If we are, read from PROGMEM, * otherwise leave the key as-is (either transparent or NoKey). */ - if ((key == Key_Transparent || layer >= max_layers) && + if ((key == Key_Transparent || layer >= max_layers_) && (layer < layer_count)) key = Layer.getKeyFromPROGMEM(layer, row, col); From 4f8c6332f762118f09e59ed5d6e8dbfe3d07f58d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 5 Oct 2018 10:33:24 +0200 Subject: [PATCH 698/792] Initial import Signed-off-by: Gergely Nagy --- .gitignore | 4 + .travis.yml | 14 + CONTRIBUTING.md | 50 ++ COPYING | 674 +++++++++++++++++++++++++++ Makefile | 14 + README.md | 102 ++++ UPGRADING.md | 193 ++++++++ bin/focus-test | 31 ++ examples/FocusSerial/FocusSerial.ino | 88 ++++ library.properties | 10 + src/Kaleidoscope-FocusSerial.h | 20 + src/kaleidoscope/FocusSerial.cpp | 94 ++++ src/kaleidoscope/FocusSerial.h | 50 ++ 13 files changed, 1344 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 CONTRIBUTING.md create mode 100644 COPYING create mode 100644 Makefile create mode 100644 README.md create mode 100644 UPGRADING.md create mode 100755 bin/focus-test create mode 100644 examples/FocusSerial/FocusSerial.ino create mode 100644 library.properties create mode 100644 src/Kaleidoscope-FocusSerial.h create mode 100644 src/kaleidoscope/FocusSerial.cpp create mode 100644 src/kaleidoscope/FocusSerial.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..be16c9be --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.#* +*~ +/hardware/ +/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..49b8c498 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +dist: trusty +sudo: false +os: + - linux +install: + - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio +script: + - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware +notifications: + email: + on_success: change + on_failure: change +cache: + ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c490e3ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# Developer Certificate of Origin + +All contributions must include acceptance of the DCO: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## Sign your work + +To accept the DCO, please add this line to each commit message with your name +and email address (`git commit -s` will do this for you): + + Signed-off-by: Jane Example diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..8f830f44 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +# This stub makefile for a Kaleidoscope plugin pulls in +# all targets from the Kaleidoscope-Plugin library + +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Darwin) +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ +else +SKETCHBOOK_DIR ?= $(HOME)/Arduino +endif + +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md new file mode 100644 index 00000000..1af8026d --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +# Kaleidoscope-FocusSerial + + [![Build Status][travis:image]][travis:status] + + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-FocusSerial.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-FocusSerial + +Bidirectional communication for Kaleidoscope. With this plugin enabled, plugins that implement the `onFocusEvent` hook will start responding to Focus commands sent via `Serial`, allowing bidirectional communication between firmware and host. + +This plugin is an upgrade of the former [Kaleidoscope-Focus][kaleidoscope:focus] plugin. See [UPGRADING.md](UPGRADING.md) for information about how to transition to the new system. + + [kaleidoscope:focus]: https://github.com/keyboardio/Kaleidoscope-Focus + +## Using the plugin + +This plugin is **not** meant to be used by the end-user (apart from setting it up to use plugin-provided hooks), but by plugin authors instead. As an end user, you just need to use Focus-enabled plugins like you normally would, and once `FocusSerial` is enabled, their commands will be available too. + +Nevertheless, a very simple example is shown below: + +```c++ +#include +#include + +namespace kaleidoscope { +class FocusTestCommand : public Plugin { + public: + FocusTestCommand() {} + + EventHandlerResult onFocusEvent(const char *command) { + if (strcmp_P(command, PSTR("test")) != 0) + return EventHandlerResult::OK; + + Serial.println(F("Congratulations, the test command works!")); + return EventHandlerResult::EVENT_CONSUMED; + } +}; +} + +kaleidoscope::FocusTestCommand FocusTestCommand; + +KALEIDOSCOPE_INIT_PLUGINS(Focus, FocusTestCommand); + +void setup () { + Kaleidoscope.setup (); +} +``` + +## Plugin methods + +The plugin provides the `Focus` object, with a couple of helper methods aimed at developers. Documenting those is a work in progress for now. + +## Wire protocol + +`Focus` uses a simple, textual, request-response-based wire protocol. + +Each request has to be on one line, anything before the first space is the command part (if there is no space, just a newline, then the whole line will be considered a command), everything after are arguments. The plugin itself only parses until the end of the command part, argument parsing is left to the various hooks. If there is anything left on the line after hooks are done processing, it will be ignored. + +Responses can be multi-line, but most aren't. Their content is also up to the hooks, `Focus` does not enforce anything, except a trailing dot and a newline. Responses should end with a dot on its own line. + +Apart from these, there are no restrictions on what can go over the wire, but to make the experience consistent, find a few guidelines below: + +* Commands should be namespaced, so that the plugin name, or functionality comes first, then the sub-command or property. Such as `led.theme`, or `led.setAll`. +* One should not use setters and getters, but a single property command instead. One, which when called without arguments, will act as a getter, and as a setter otherwise. +* Namespaces should be lowercase, while the commands within them camel-case. +* Do as little work in the hooks as possible. While the protocol is human readable, the expectation is that tools will be used to interact with the keyboard. +* As such, keep formatting to the bare minimum. No fancy table-like responses. +* In general, the output of a getter should be copy-pasteable to a setter. + +These are merely guidelines, and there can be - and are - exceptions. Use your discretion when writing Focus hooks. + +### Example + +In the examples below, `<` denotes what the host sends to the keyboard, `>` what +the keyboard responds. + +``` +< test +> Congratulations, the test command works! +> . +``` + +``` +< help +> help +> test +> palette +> . +``` + +``` +< palette +> 0 0 0 128 128 128 255 255 255 +> . +< palette 0 0 0 128 128 128 255 255 255 +> . +``` + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-FocusSerial/blob/master/examples/FocusSerial/FocusSerial.ino diff --git a/UPGRADING.md b/UPGRADING.md new file mode 100644 index 00000000..351489a1 --- /dev/null +++ b/UPGRADING.md @@ -0,0 +1,193 @@ +Upgrading from Focus to onFocusEvent + FocusSerial +================================================== + +Upgrading from `Focus` to `onFocusEvent` and `FocusSerial` is a reasonably simple process, the interface is quite similar. Nevertheless, we present a step-by-step guide here, covering two use cases: one where we wish to always provide a Focus command when both our plugin and `FocusSerial` are enabled; and another where we only wish to provide the command when explicitly asked to do so. + +## The most trivial example + +The biggest difference between `Focus` and `onFocusEvent` is that the former required explicit registering of hooks, while the latter does it automatically: every plugin that implements the `onFocusEvent` method will be part of the system. As a consequence, only plugins are able to supply new commands: there is no explicit registration, thus, no way to inject a command that isn't part of a plugin. This also means that these functions now return `kaleidoscope::EventHandlerResult` instead of `bool`. Lets see a trivial example! + +### Focus + +```c++ +bool exampleFocusHook(const char *command) { + if (strcmp_P(command, PSTR("example")) != 0) + return false; + + Serial.println(F("This is an example response. Hello world!")); + + return true; +} + +KALEIDOSCOPE_INIT_PLUGINS(Focus) + +void setup() { + Serial.begin(9600); + Kaleidoscope.setup(); + Focus.addHook(FOCUS_HOOK(exampleFocusHook, "example")); +} +``` + +### onFocusEvent + +```c++ +namespace kaleidoscope { +class FocusExampleCommand : public Plugin { + public: + FocusExampleCommand() {} + + EventHandlerResult onFocusEvent(const char *command) { + if (strcmp_P(command, PSTR("example")) != 0) + return EventHandlerResult::OK; + + Serial.println(F("This is an example response. Hello world!")); + return EventHandlerResult::EVENT_CONSUMED; + } +}; +} + +kaleidoscope::FocusExampleCommand FocusExampleCommand; + +KALEIDOSCOPE_INIT_PLUGINS(Focus, FocusExampleCommand); + +void setup() { + Kaleidoscope.setup(); +} +``` + +### Summary + +The new version is slightly more verbose for the trivial use case, because we have to wrap it up in an object. But other than that, the changes are minimal, and we don't need to explicitly register it! + +Observe that the return values changed: with `Focus`, if we wanted other hooks to have a chance at processing the same command, the hook returned `false`; if we wanted to stop processing, and consider it consumed, it returned `true`. With the new system, this is more descriptive with the `EventHandlerResult::OK` and `EventHandlerResult::EVENT_CONSUMED` return values. + +## A stateful example + +Perhaps a better example that shows the quality of life improvements the new system brings is the case where the command needs access to either plugin state, or plugin methods. With the former system, the focus hooks needed to be static methods, and needed to be public. This is not necessarily the case now, because `onFocusEvent` is a non-static object method. It has full access to plugin internals! + +### Focus + +```c++ +namespace kaleidoscope { +class ExamplePlugin : public Plugin { + public: + ExamplePlugin(); + + static bool exampleToggle() { + example_toggle_ = !example_toggle_; + return example_toggle_; + } + + static bool focusHook(const char *command) { + if (strcmp_P(command, PSTR("example.toggle")) != 0) + return false; + + ::Focus.printBool(exampleToggle()); + return true; + } + + private: + static bool example_toggle_; +}; +} + +kaleidoscope::ExamplePlugin ExamplePlugin; + +KALEIDOSCOPE_PLUGIN_INIT(Focus, ExamplePlugin) + +void setup() { + Serial.begin(9600); + Kaleidoscope.setup(); + + Focus.addHook(FOCUS_HOOK(ExamplePlugin.focusHook, "example.toggle")); +} +``` + +### onFocusEvent + +```c++ +namespace kaleidoscope { +class ExamplePlugin : public Plugin { + public: + ExamplePlugin(); + + EventHandlerResult onFocusEvent(const char *command) { + if (strcmp_P(command, PSTR("example.toggle")) != 0) + return EventHandlerResult::OK; + + example_toggle_ = !example_toggle_; + ::Focus.printBool(example_toggle_); + + return EventHandlerResult::EVENT_CONSUMED; + } + + private: + static bool example_toggle_; +}; +} + +kaleidoscope::ExamplePlugin ExamplePlugin; + +KALEIDOSCOPE_PLUGIN_INIT(Focus, ExamplePlugin) + +void setup() { + Kaleidoscope.setup(); +} +``` + +### Summary + +It's just another plugin, with just another event handler method implemented, nothing more. No need to explicitly register the focus hook, no need to provide access to private variables - we can just keep them private. + +## Optional commands + +Optional commands are something that were perhaps easier with the `Focus` method: one just didn't register them. With `onFocusEvent`, we need to do a bit more than that, and move the command to a separate plugin, if we do not wish to enable it in every case. This adds a bit of overhead, but still less than `Focus` did. + +### Focus + +```c++ +bool exampleOptionalHook(const char *command) { + if (strcmp_P(command, PSTR("optional")) != 0) + return false; + + Serial.println(Layer.getLayerState(), BIN); + return true; +} + +KALEIDOSCOPE_INIT_PLUGINS(Focus) + +void setup() { + Kaleidoscope.setup(); +} +``` + +Do note that we do not register the `exampleOptionalHook` here! As such, because it is unused code, it will get optimized out during compilation. While this is a simplistic example, the optional hook might have been part of a class, that provides other hooks. + +### onFocusEvent + +```c++ +namespace kaleidoscope { +class ExampleOptionalCommand : public Plugin { + public: + ExampleOptionalCommand() {} + + EventHandlerResult onFocusEvent(const char *command) { + if (strcmp_P(command, PSTR("optional")) != 0) + return EventHandlerResult::OK; + + Serial.println(Layer.getLayerState(), BIN); + return EventHandlerResult::EVENT_CONSUMED; + } +}; +} + +KALEIDOSCOPE_INIT_PLUGINS(Focus) + +void setup() { + Kaleidoscope.setup(); +} +``` + +### Summary + +The trick here is to move optional commands out into a separate plugin. It's a bit more boilerplate, but not by much. diff --git a/bin/focus-test b/bin/focus-test new file mode 100755 index 00000000..dc8cef81 --- /dev/null +++ b/bin/focus-test @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# focus-test - Trivial Focus testing tool +# Copyright (C) 2018 Keyboard.io, Inc. +# +# 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, version 3. +# +# 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 . + +set -e + +DEVICE="${DEVICE:-/dev/ttyACM0}" + +stty -F "${DEVICE}" 9600 raw -echo + +exec 3<"${DEVICE}" +echo "$@" >"${DEVICE}" + +while read -r line <&3; do + line="$(echo -n "${line}" | tr -d '\r')" + if [ "${line}" == "." ]; then + break + fi + echo "${line}" +done diff --git a/examples/FocusSerial/FocusSerial.ino b/examples/FocusSerial/FocusSerial.ino new file mode 100644 index 00000000..fcb8b280 --- /dev/null +++ b/examples/FocusSerial/FocusSerial.ino @@ -0,0 +1,88 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FocusSerial -- Bidirectional communication plugin + * Copyright (C) 2017, 2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + +#include +#include + +// *INDENT-OFF* +const Key keymaps[][ROWS][COLS] PROGMEM = { + [0] = KEYMAP_STACKED + (Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + Key_skip, + + Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip, + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + Key_skip), +}; +// *INDENT-OFF* + +namespace kaleidoscope { +class FocusTestCommand : public Plugin { + public: + FocusTestCommand() {} + + EventHandlerResult onFocusEvent(const char *command) { + if (strcmp_P(command, PSTR("test")) == 0) { + Serial.println(F("ok!")); + return EventHandlerResult::EVENT_CONSUMED; + } + if (strcmp_P(command, PSTR("help")) == 0) { + Serial.println(F("test")); + return EventHandlerResult::OK; + } + + return EventHandlerResult::OK; + } +}; + +class FocusHelpCommand : public Plugin { + public: + FocusHelpCommand() {} + + EventHandlerResult onFocusEvent(const char *command) { + if (strcmp_P(command, PSTR("help")) == 0) { + Serial.println(F("help")); + return EventHandlerResult::OK; + } + + return EventHandlerResult::OK; + } +}; + +} + +kaleidoscope::FocusTestCommand FocusTestCommand; +kaleidoscope::FocusHelpCommand FocusHelpCommand; + +KALEIDOSCOPE_INIT_PLUGINS(Focus, FocusTestCommand, FocusHelpCommand); + +void setup() { + Kaleidoscope.setup(); +} + +void loop() { + Kaleidoscope.loop(); +} diff --git a/library.properties b/library.properties new file mode 100644 index 00000000..4946edac --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=Kaleidoscope-FocusSerial +version=0.0.0 +author=Gergely Nagy +maintainer=Gergely Nagy +sentence=Bidirectional communication plugin for Kaleidoscope. +paragraph=... +category=Communication +url=https://github.com/keyboardio/Kaleidoscope-FocusSerial +architectures=avr +dot_a_linkage=true diff --git a/src/Kaleidoscope-FocusSerial.h b/src/Kaleidoscope-FocusSerial.h new file mode 100644 index 00000000..02e24f80 --- /dev/null +++ b/src/Kaleidoscope-FocusSerial.h @@ -0,0 +1,20 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FocusSerial -- Bidirectional communication plugin + * Copyright (C) 2017, 2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include diff --git a/src/kaleidoscope/FocusSerial.cpp b/src/kaleidoscope/FocusSerial.cpp new file mode 100644 index 00000000..3864df4f --- /dev/null +++ b/src/kaleidoscope/FocusSerial.cpp @@ -0,0 +1,94 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FocusSerial -- Bidirectional communication plugin + * Copyright (C) 2017, 2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + +#include + +#ifdef __AVR__ +#include +#endif + +namespace kaleidoscope { + +char FocusSerial::command_[32]; + +void FocusSerial::drain(void) { + if (Serial.available()) + while (Serial.peek() != '\n') + Serial.read(); +} + +EventHandlerResult FocusSerial::beforeReportingState() { + if (Serial.available() == 0) + return EventHandlerResult::OK; + + uint8_t i = 0; + do { + command_[i++] = Serial.read(); + + if (Serial.peek() == '\n') + break; + } while (command_[i - 1] != ' ' && i < 32); + if (command_[i - 1] == ' ') + command_[i - 1] = '\0'; + else + command_[i] = '\0'; + + Kaleidoscope.onFocusEvent(command_); + + Serial.println(F(".")); + + drain(); + + if (Serial.peek() == '\n') + Serial.read(); + + return EventHandlerResult::OK; +} + +void FocusSerial::printSpace(void) { + Serial.print(F(" ")); +} + +void FocusSerial::printNumber(uint16_t num) { + Serial.print(num); +} + +void FocusSerial::printColor(uint8_t r, uint8_t g, uint8_t b) { + printNumber(r); + printSpace(); + printNumber(g); + printSpace(); + printNumber(b); +} + +void FocusSerial::printSeparator(void) { + Serial.print(F(" | ")); +} + +void FocusSerial::printBool(bool b) { + Serial.print((b) ? F("true") : F("false")); +} + +void FocusSerial::readColor(cRGB &color) { + color.r = Serial.parseInt(); + color.g = Serial.parseInt(); + color.b = Serial.parseInt(); +} + +} + +kaleidoscope::FocusSerial Focus; diff --git a/src/kaleidoscope/FocusSerial.h b/src/kaleidoscope/FocusSerial.h new file mode 100644 index 00000000..8eeaec98 --- /dev/null +++ b/src/kaleidoscope/FocusSerial.h @@ -0,0 +1,50 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FocusSerial -- Bidirectional communication plugin + * Copyright (C) 2017, 2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include + +namespace kaleidoscope { +class FocusSerial : public kaleidoscope::Plugin { + public: + FocusSerial(void) {} + + /* Helpers */ + static void printNumber(uint16_t number); + static void printSpace(void); + static void printColor(uint8_t r, uint8_t g, uint8_t b); + static void printSeparator(void); + static void printBool(bool b); + + static void readColor(cRGB &color); + + /* Hooks */ + EventHandlerResult onSetup() { + Serial.begin(9600); + return EventHandlerResult::OK; + } + EventHandlerResult beforeReportingState(); + + private: + static char command_[32]; + + static void drain(void); +}; +}; + +extern kaleidoscope::FocusSerial Focus; From 80566ca5a1307385fae5a4e650b96fcfcdd306e9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 5 Oct 2018 12:51:30 +0200 Subject: [PATCH 699/792] Add a method to ease handling the `help` command Signed-off-by: Gergely Nagy --- examples/FocusSerial/FocusSerial.ino | 16 +++++++--------- src/kaleidoscope/FocusSerial.cpp | 9 +++++++++ src/kaleidoscope/FocusSerial.h | 3 +++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/examples/FocusSerial/FocusSerial.ino b/examples/FocusSerial/FocusSerial.ino index fcb8b280..c83910ca 100644 --- a/examples/FocusSerial/FocusSerial.ino +++ b/examples/FocusSerial/FocusSerial.ino @@ -45,14 +45,15 @@ class FocusTestCommand : public Plugin { FocusTestCommand() {} EventHandlerResult onFocusEvent(const char *command) { - if (strcmp_P(command, PSTR("test")) == 0) { + const char *cmd = PSTR("test"); + + if (::Focus.handleHelp(command, cmd)) + return EventHandlerResult::OK; + + if (strcmp_P(command, cmd) == 0) { Serial.println(F("ok!")); return EventHandlerResult::EVENT_CONSUMED; } - if (strcmp_P(command, PSTR("help")) == 0) { - Serial.println(F("test")); - return EventHandlerResult::OK; - } return EventHandlerResult::OK; } @@ -63,10 +64,7 @@ class FocusHelpCommand : public Plugin { FocusHelpCommand() {} EventHandlerResult onFocusEvent(const char *command) { - if (strcmp_P(command, PSTR("help")) == 0) { - Serial.println(F("help")); - return EventHandlerResult::OK; - } + ::Focus.handleHelp(command, PSTR("help")); return EventHandlerResult::OK; } diff --git a/src/kaleidoscope/FocusSerial.cpp b/src/kaleidoscope/FocusSerial.cpp index 3864df4f..7fb37525 100644 --- a/src/kaleidoscope/FocusSerial.cpp +++ b/src/kaleidoscope/FocusSerial.cpp @@ -59,6 +59,15 @@ EventHandlerResult FocusSerial::beforeReportingState() { return EventHandlerResult::OK; } +bool FocusSerial::handleHelp(const char *command, + const char *help_message) { + if (strcmp_P(command, PSTR("help")) != 0) + return false; + + Serial.println((const __FlashStringHelper *)help_message); + return true; +} + void FocusSerial::printSpace(void) { Serial.print(F(" ")); } diff --git a/src/kaleidoscope/FocusSerial.h b/src/kaleidoscope/FocusSerial.h index 8eeaec98..4e5613ea 100644 --- a/src/kaleidoscope/FocusSerial.h +++ b/src/kaleidoscope/FocusSerial.h @@ -24,6 +24,9 @@ class FocusSerial : public kaleidoscope::Plugin { public: FocusSerial(void) {} + bool handleHelp(const char *command, + const char *help_message); + /* Helpers */ static void printNumber(uint16_t number); static void printSpace(void); From 504727d6772ac0901633cb78bd48787dba69aa47 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 5 Oct 2018 13:59:51 +0200 Subject: [PATCH 700/792] Migrate to the new onFocusEvent API Signed-off-by: Gergely Nagy --- README.md | 13 ++++----- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 32 ++++++++++++++-------- src/Kaleidoscope/EEPROM-Settings-Focus.h | 30 ++++++++++---------- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index d6e86c33..150c8d1b 100644 --- a/README.md +++ b/README.md @@ -118,13 +118,12 @@ The plugin provides the `EEPROMSettings` object, which has the following methods ## Focus commands -The plugin provides two [Focus][focus] hooks: `FOCUS_HOOK_SETTINGS`, and -`FOCUS_HOOK_EEPROM`, that register commands that allow one to work with the -settings, and with the contents of the `EEPROM` through Focus. +The plugin provides two - optional - [Focus][FocusSerial] command plugins: +`FocusSettingsCommand` and `FocusEEPROMCommand`. These must be explicitly added +to `KALEIDOSCOPE_INIT_PLUGINS` if one wishes to use them. They provide the +following commands: - [focus]: https://github.com/keyboardio/Kaleidoscope-Focus - -These provide the following `Focus` commands: + [FocusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial ### `settings.crc` @@ -153,7 +152,7 @@ These provide the following `Focus` commands: ## Dependencies -* [Kaleidoscope-Focus][focus] +* [Kaleidoscope-FocusSerial][FocusSerial] ## Further reading diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 084ea8ee..2ed4c15a 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Keyboard.io, Inc + * Copyright (C) 2017-2018 Keyboard.io, Inc * * 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 @@ -16,21 +16,26 @@ */ #include -#include +#include #include "crc.h" namespace kaleidoscope { -namespace eeprom_settings { +namespace eeprom { -bool settingsFocusHook(const char *command) { +EventHandlerResult FocusSettingsCommand::onFocusEvent(const char *command) { enum { ISVALID, GETVERSION, CRC, } sub_command; + if (strcmp_P(command, PSTR("help")) == 0) { + Serial.println(F("settings.valid?\nsettings.version\nsettings.crc")); + return EventHandlerResult::OK; + } + if (strncmp_P(command, PSTR("settings."), 9) != 0) - return false; + return EventHandlerResult::OK; if (strcmp_P(command + 9, PSTR("valid?")) == 0) sub_command = ISVALID; @@ -39,7 +44,7 @@ bool settingsFocusHook(const char *command) { else if (strcmp_P(command + 9, PSTR("crc")) == 0) sub_command = CRC; else - return false; + return EventHandlerResult::OK; switch (sub_command) { case ISVALID: @@ -56,21 +61,24 @@ bool settingsFocusHook(const char *command) { break; } - return true; + return EventHandlerResult::EVENT_CONSUMED; } -bool eepromFocusHook(const char *command) { +EventHandlerResult FocusEEPROMCommand::onFocusEvent(const char *command) { enum { CONTENTS, FREE, } sub_command; + if (::Focus.handleHelp(command, PSTR("eeprom.contents\neeprom.free"))) + return EventHandlerResult::OK; + if (strcmp_P(command, PSTR("eeprom.contents")) == 0) sub_command = CONTENTS; else if (strcmp_P(command, PSTR("eeprom.free")) == 0) sub_command = FREE; else - return false; + return EventHandlerResult::OK; switch (sub_command) { case CONTENTS: { @@ -95,9 +103,11 @@ bool eepromFocusHook(const char *command) { break; } - return true; + return EventHandlerResult::EVENT_CONSUMED; } } - } + +kaleidoscope::eeprom::FocusSettingsCommand FocusSettingsCommand; +kaleidoscope::eeprom::FocusEEPROMCommand FocusEEPROMCommand; diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index cebf254f..3da46524 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017 Keyboard.io, Inc + * Copyright (C) 2017, 2018 Keyboard.io, Inc * * 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 @@ -20,21 +20,23 @@ #include namespace kaleidoscope { -namespace eeprom_settings { +namespace eeprom { +class FocusSettingsCommand : public kaleidoscope::Plugin { + public: + FocusSettingsCommand() {} -bool settingsFocusHook(const char *command); -bool eepromFocusHook(const char *command); + EventHandlerResult onFocusEvent(const char *command); +}; + +class FocusEEPROMCommand : public kaleidoscope::Plugin { + public: + FocusEEPROMCommand () {} + + EventHandlerResult onFocusEvent(const char *command); +}; } } -#define FOCUS_HOOK_SETTINGS FOCUS_HOOK \ - (kaleidoscope::eeprom_settings::settingsFocusHook, \ - "settings.valid?\n" \ - "settings.version\n" \ - "settings.crc") - -#define FOCUS_HOOK_EEPROM FOCUS_HOOK \ - (kaleidoscope::eeprom_settings::eepromFocusHook, \ - "eeprom.free\n" \ - "eeprom.contents") +extern kaleidoscope::eeprom::FocusSettingsCommand FocusSettingsCommand; +extern kaleidoscope::eeprom::FocusEEPROMCommand FocusEEPROMCommand; From 184981ff9a89f19e4670879f206f1b5e61f2e52c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 5 Oct 2018 14:07:45 +0200 Subject: [PATCH 701/792] Migrate to the onFocusEvent API While there, drop the `keymap.layer` command, which was a workaround to a Chrysalis bug fixed since. Signed-off-by: Gergely Nagy --- README.md | 40 ++++-------- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 12 +--- src/Kaleidoscope-EEPROM-Keymap.h | 2 +- src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp | 50 +++++++++++++++ ...eymap-Focus.h => EEPROM-Keymap-Transfer.h} | 17 +++-- src/Kaleidoscope/EEPROM-Keymap.cpp | 62 +++---------------- src/Kaleidoscope/EEPROM-Keymap.h | 5 +- 7 files changed, 87 insertions(+), 101 deletions(-) create mode 100644 src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp rename src/Kaleidoscope/{EEPROM-Keymap-Focus.h => EEPROM-Keymap-Transfer.h} (65%) diff --git a/README.md b/README.md index 3fab8197..6baff5ff 100644 --- a/README.md +++ b/README.md @@ -18,38 +18,32 @@ overlay there. In the latter case, whenever there is a non-transparent key on the overlay, we will use that instead of the keyboard default. In short, this plugin allows us to change our keymaps, without having to compile -and flash new firmware. It does so through the use of the [Focus][plugin:focus] -plugin. +and flash new firmware. It does so through the use of the +[FocusSerial][plugin:focusSerial] plugin. - [plugin:focus]: https://github.com/keyboardio/Kaleidoscope-Focus + [plugin:focusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial ## Using the plugin Using the plugin is reasonably simple: after including the header, enable the -plugin, and let the `Layer` object know that we'll be using `EEPROMKeymap` to -figure out which keys to use. We can either use the `getKeyOverride` or the -`getKey` method, depending on whether we want to override, or fully replace the -built-in keymap. Then we need to set at most how many layers we want to store in -`EEPROM`, and that is about it. +plugin, and configure how many layers at most we want to store in `EEPROM`. +There are other settings one can tweak, but these two steps are enough to get +started with. -We can then update the keymap via [Focus][plugin:focus]. +Once these are set up, we can update the keymap via [Focus][plugin:focusSerial]. ```c++ #include #include -#include +#include KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, - Focus); + Focus, + FocusKeymapTransferCommand); void setup() { - Serial.begin(9600); - Kaleidoscope.setup(); - Focus.addHook(FOCUS_HOOK_KEYMAP); - Focus.addHook(FOCUS_HOOK_KEYMAP_TRANSFER); - EEPROMKeymap.max_layers(1); } ``` @@ -68,9 +62,8 @@ The plugin provides the `EEPROMKeymap` object, which has the following methods: ## Focus commands -The plugin provides three `Focus` hooks: `FOCUS_HOOK_KEYMAP`, `FOCUS_HOOK_KEYMAP_LAYER`, -and `FOCUS_HOOK_KEYMAP_TRANSFER`. Together, they make the following commands -available, respectively: +The plugin provides a `keymap.map` Focus command unconditionally, and a +`keymap.transfer` via the `FocusKeymapTransferCommand` object. ### `keymap.map [codes...]` @@ -82,13 +75,6 @@ available, respectively: > layer, and go on as long as it has input. It will not go past the layer set > via the `.max_layers()` method. -### `keymap.layer LAYER [codes...]` - -> Without codes, prints the keymap for the given layer (zero-indexed). -> Prints each key as its raw 16-bit keycode. - -> With codes, stores them as the keymap for the given layer. - ### `keymap.transfer LAYER` > Transfers the `LAYER` from the built-in memory of the keyboard into `EEPROM` @@ -103,7 +89,7 @@ available, respectively: ## Dependencies * [Kaleidoscope-EEPROM-Settings](https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings) -* [Kaleidoscope-Focus](https://github.com/keyboardio/Kaleidoscope-Focus) +* [Kaleidoscope-FocusSerial](https://github.com/keyboardio/Kaleidoscope-FocusSerial) ## Further reading diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index e7771534..50f3b4b8 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -17,7 +17,7 @@ #include #include -#include +#include // *INDENT-OFF* KEYMAPS( @@ -40,19 +40,11 @@ KEYMAPS( ) // *INDENT-ON* -KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, Focus); +KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, Focus, FocusKeymapTransfer); void setup() { - Serial.begin(9600); - Kaleidoscope.setup(); - Focus.addHook(FOCUS_HOOK_SETTINGS); - Focus.addHook(FOCUS_HOOK_KEYMAP); - Focus.addHook(FOCUS_HOOK_KEYMAP_TRANSFER); - Focus.addHook(FOCUS_HOOK_HELP); - Focus.addHook(FOCUS_HOOK_VERSION); - EEPROMKeymap.max_layers(1); } diff --git a/src/Kaleidoscope-EEPROM-Keymap.h b/src/Kaleidoscope-EEPROM-Keymap.h index 9ab581bd..3bcb13c8 100644 --- a/src/Kaleidoscope-EEPROM-Keymap.h +++ b/src/Kaleidoscope-EEPROM-Keymap.h @@ -18,4 +18,4 @@ #pragma once #include -#include +#include diff --git a/src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp b/src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp new file mode 100644 index 00000000..77ec771b --- /dev/null +++ b/src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp @@ -0,0 +1,50 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. + * Copyright (C) 2017, 2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + +#include +#include +#include + +namespace kaleidoscope { +namespace eeprom { + +EventHandlerResult FocusKeymapTransferCommand::onFocusEvent(const char *command) { + const char *cmd = PSTR("keymap.transfer"); + + if (::Focus.handleHelp(command, cmd)) + return EventHandlerResult::OK; + if (strcmp_P(command, cmd) != 0) + return EventHandlerResult::OK; + + uint8_t layer = Serial.parseInt(); + + for (uint8_t row = 0; row < ROWS; row++) { + for (uint8_t col = 0; col < COLS; col++) { + Key k = Layer.getKeyFromPROGMEM(layer, row, col); + uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); + + ::EEPROMKeymap.updateKey(pos, k); + } + } + + return EventHandlerResult::EVENT_CONSUMED; +} + +} +} + +kaleidoscope::eeprom::FocusKeymapTransferCommand FocusKeymapTransferCommand; diff --git a/src/Kaleidoscope/EEPROM-Keymap-Focus.h b/src/Kaleidoscope/EEPROM-Keymap-Transfer.h similarity index 65% rename from src/Kaleidoscope/EEPROM-Keymap-Focus.h rename to src/Kaleidoscope/EEPROM-Keymap-Transfer.h index dce6ee3f..6dfee13c 100644 --- a/src/Kaleidoscope/EEPROM-Keymap-Focus.h +++ b/src/Kaleidoscope/EEPROM-Keymap-Transfer.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017 Keyboard.io, Inc + * Copyright (C) 2017-2018 Keyboard.io, Inc * * 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 @@ -20,10 +20,15 @@ #include #include -#define FOCUS_HOOK_KEYMAP FOCUS_HOOK(EEPROMKeymap.focusKeymap, "keymap.map") +namespace kaleidoscope { +namespace eeprom { +class FocusKeymapTransferCommand : public Plugin { + public: + FocusKeymapTransferCommand() {} -#define FOCUS_HOOK_KEYMAP_LAYER FOCUS_HOOK(EEPROMKeymap.focusKeymapLayer, \ - "keymap.layer") + EventHandlerResult onFocusEvent(const char *command); +}; +} +} -#define FOCUS_HOOK_KEYMAP_TRANSFER FOCUS_HOOK(EEPROMKeymap.focusKeymapTransfer, \ - "keymap.transfer") +extern kaleidoscope::eeprom::FocusKeymapTransferCommand FocusKeymapTransferCommand; diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 2084ceb1..28e5c608 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include namespace kaleidoscope { uint16_t EEPROMKeymap::keymap_base_; @@ -88,9 +88,13 @@ void EEPROMKeymap::printKey(Key k) { ::Focus.printNumber(k.raw); } -bool EEPROMKeymap::focusKeymap(const char *command) { - if (strcmp_P(command, PSTR("keymap.map")) != 0) - return false; +EventHandlerResult EEPROMKeymap::onFocusEvent(const char *command) { + const char *cmd = PSTR("keymap.map"); + if (::Focus.handleHelp(command, cmd)) + return EventHandlerResult::OK; + + if (strcmp_P(command, cmd) != 0) + return EventHandlerResult::OK; if (Serial.peek() == '\n') { for (uint8_t layer = 0; layer < max_layers_; layer++) { @@ -112,55 +116,7 @@ bool EEPROMKeymap::focusKeymap(const char *command) { } } - return true; -} - -bool EEPROMKeymap::focusKeymapLayer(const char *command) { - if (strcmp_P(command, PSTR("keymap.layer")) != 0) { - return false; - } - - uint8_t layer = Serial.parseInt(); - if (layer >= max_layers_) { - return false; - } - if (Serial.peek() == '\n') { - for (uint8_t row = 0; row < ROWS; row++) { - for (uint8_t col = 0; col < COLS; col++) { - Key k = Layer.getKey(layer, row, col); - printKey(k); - ::Focus.printSpace(); - } - } - Serial.println(); - } else { - uint16_t keysPerLayer = ROWS * COLS; - uint16_t offset = layer * keysPerLayer; - for (uint16_t k = 0; (k < keysPerLayer) && (Serial.peek() != '\n'); k++) { - updateKey(offset + k, parseKey()); - } - } - - return true; - -} - -bool EEPROMKeymap::focusKeymapTransfer(const char *command) { - if (strcmp_P(command, PSTR("keymap.transfer")) != 0) - return false; - - uint8_t layer = Serial.parseInt(); - - for (uint8_t row = 0; row < ROWS; row++) { - for (uint8_t col = 0; col < COLS; col++) { - Key k = Layer.getKeyFromPROGMEM(layer, row, col); - uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); - - updateKey(pos, k); - } - } - - return true; + return EventHandlerResult::EVENT_CONSUMED; } } diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 631e51b3..86368f3a 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -26,6 +26,7 @@ class EEPROMKeymap : public kaleidoscope::Plugin { EEPROMKeymap(void) {} EventHandlerResult onSetup(); + EventHandlerResult onFocusEvent(const char *command); static void max_layers(uint8_t max); @@ -34,10 +35,6 @@ class EEPROMKeymap : public kaleidoscope::Plugin { static Key getKey(uint8_t layer, byte row, byte col); static Key getKeyOverride(uint8_t layer, byte row, byte col); - static bool focusKeymap(const char *command); - static bool focusKeymapLayer(const char *command); - static bool focusKeymapTransfer(const char *command); - static void updateKey(uint16_t base_pos, Key key); private: From 7ae4cae1e190759065d39ad20e1710e1fc5a0705 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 5 Oct 2018 14:53:08 +0200 Subject: [PATCH 702/792] Migrate to the new onFocusEvent APIs Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDControl.cpp | 35 ++++++++++++++++++++------------- src/Kaleidoscope-LEDControl.h | 16 +++++++-------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index c43c7918..4b215e55 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -15,7 +15,7 @@ */ #include "Kaleidoscope-LEDControl.h" -#include "Kaleidoscope-Focus.h" +#include "Kaleidoscope-FocusSerial.h" namespace kaleidoscope { @@ -175,7 +175,7 @@ kaleidoscope::EventHandlerResult LEDControl::beforeReportingState(void) { return kaleidoscope::EventHandlerResult::OK; } -bool LEDControl::focusHook(const char *command) { +EventHandlerResult FocusLEDCommand::onFocusEvent(const char *command) { enum { SETALL, MODE, @@ -183,8 +183,14 @@ bool LEDControl::focusHook(const char *command) { THEME, } subCommand; + if (::Focus.handleHelp(command, PSTR("led.at\n" + "led.setAll\n" + "led.mode\n" + "led.theme"))) + return EventHandlerResult::OK; + if (strncmp_P(command, PSTR("led."), 4) != 0) - return false; + return EventHandlerResult::OK; if (strcmp_P(command + 4, PSTR("at")) == 0) subCommand = AT; else if (strcmp_P(command + 4, PSTR("setAll")) == 0) @@ -194,14 +200,14 @@ bool LEDControl::focusHook(const char *command) { else if (strcmp_P(command + 4, PSTR("theme")) == 0) subCommand = THEME; else - return false; + return EventHandlerResult::OK; switch (subCommand) { case AT: { uint8_t idx = Serial.parseInt(); if (Serial.peek() == '\n') { - cRGB c = getCrgbAt(idx); + cRGB c = ::LEDControl.getCrgbAt(idx); ::Focus.printColor(c.r, c.g, c.b); Serial.println(); @@ -210,7 +216,7 @@ bool LEDControl::focusHook(const char *command) { ::Focus.readColor(c); - setCrgbAt(idx, c); + ::LEDControl.setCrgbAt(idx, c); } break; } @@ -219,31 +225,31 @@ bool LEDControl::focusHook(const char *command) { ::Focus.readColor(c); - set_all_leds_to(c); + ::LEDControl.set_all_leds_to(c); break; } case MODE: { char peek = Serial.peek(); if (peek == '\n') { - Serial.println(get_mode_index()); + Serial.println(::LEDControl.get_mode_index()); } else if (peek == 'n') { - next_mode(); + ::LEDControl.next_mode(); Serial.read(); } else if (peek == 'p') { - prev_mode(); + ::LEDControl.prev_mode(); Serial.read(); } else { uint8_t mode = Serial.parseInt(); - set_mode(mode); + ::LEDControl.set_mode(mode); } break; } case THEME: { if (Serial.peek() == '\n') { for (uint8_t idx = 0; idx < LED_COUNT; idx++) { - cRGB c = getCrgbAt(idx); + cRGB c = ::LEDControl.getCrgbAt(idx); ::Focus.printColor(c.r, c.g, c.b); ::Focus.printSpace(); @@ -258,16 +264,17 @@ bool LEDControl::focusHook(const char *command) { ::Focus.readColor(color); - setCrgbAt(idx, color); + ::LEDControl.setCrgbAt(idx, color); idx++; } break; } } - return true; + return EventHandlerResult::EVENT_CONSUMED; } } kaleidoscope::LEDControl LEDControl; +kaleidoscope::FocusLEDCommand FocusLEDCommand; diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index f14daf9d..853a11fc 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -142,8 +142,6 @@ class LEDControl : public kaleidoscope::Plugin { static uint16_t syncDelay; static bool paused; - static bool focusHook(const char *command); - kaleidoscope::EventHandlerResult onSetup(); kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); kaleidoscope::EventHandlerResult beforeReportingState(); @@ -154,12 +152,14 @@ class LEDControl : public kaleidoscope::Plugin { static uint8_t mode; }; +class FocusLEDCommand : public Plugin { +public: + FocusLEDCommand() {} + + EventHandlerResult onFocusEvent(const char *command); +}; + } extern kaleidoscope::LEDControl LEDControl; - -#define FOCUS_HOOK_LEDCONTROL FOCUS_HOOK (LEDControl.focusHook, \ - "led.at\n" \ - "led.setAll\n" \ - "led.theme\n" \ - "led.mode") +extern kaleidoscope::FocusLEDCommand FocusLEDCommand; From 68cdc384de65f51d1ba4ddcb0214965c43daa8b6 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 5 Oct 2018 10:33:46 -0700 Subject: [PATCH 703/792] astyle --- src/Kaleidoscope/EEPROM-Settings-Focus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/Kaleidoscope/EEPROM-Settings-Focus.h index 3da46524..bd0b659e 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.h @@ -30,7 +30,7 @@ class FocusSettingsCommand : public kaleidoscope::Plugin { class FocusEEPROMCommand : public kaleidoscope::Plugin { public: - FocusEEPROMCommand () {} + FocusEEPROMCommand() {} EventHandlerResult onFocusEvent(const char *command); }; From 266e51d206cd9bb1ba861a50667c910686d79ca0 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 5 Oct 2018 11:02:11 -0700 Subject: [PATCH 704/792] astyle --- src/Kaleidoscope-LEDControl.cpp | 6 +++--- src/Kaleidoscope-LEDControl.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/Kaleidoscope-LEDControl.cpp index 4b215e55..2209397e 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/Kaleidoscope-LEDControl.cpp @@ -184,9 +184,9 @@ EventHandlerResult FocusLEDCommand::onFocusEvent(const char *command) { } subCommand; if (::Focus.handleHelp(command, PSTR("led.at\n" - "led.setAll\n" - "led.mode\n" - "led.theme"))) + "led.setAll\n" + "led.mode\n" + "led.theme"))) return EventHandlerResult::OK; if (strncmp_P(command, PSTR("led."), 4) != 0) diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 853a11fc..13da4fa0 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -153,7 +153,7 @@ class LEDControl : public kaleidoscope::Plugin { }; class FocusLEDCommand : public Plugin { -public: + public: FocusLEDCommand() {} EventHandlerResult onFocusEvent(const char *command); From a066d82747b6d3f5399a05745c334e2d1d3601bd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Fri, 5 Oct 2018 21:25:48 +0200 Subject: [PATCH 705/792] Fix a thinko It's called `FocusKeymapTransferCommand`, not `FocusKeymapTransfer`. Signed-off-by: Gergely Nagy --- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index 50f3b4b8..e5c35ec9 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -40,7 +40,7 @@ KEYMAPS( ) // *INDENT-ON* -KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, Focus, FocusKeymapTransfer); +KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, Focus, FocusKeymapTransferCommand); void setup() { Kaleidoscope.setup(); From 5edc8a07b2dcea236a5e52e6da13b494da43ad51 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 7 Oct 2018 09:28:31 +0200 Subject: [PATCH 706/792] FocusSettingsCommand: Use Focus.handleHelp This saves a few bytes of PROGMEM for us. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index 2ed4c15a..c34890f5 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -29,10 +29,8 @@ EventHandlerResult FocusSettingsCommand::onFocusEvent(const char *command) { CRC, } sub_command; - if (strcmp_P(command, PSTR("help")) == 0) { - Serial.println(F("settings.valid?\nsettings.version\nsettings.crc")); + if (::Focus.handleHelp(command, PSTR("settings.valid?\nsettings.version\nsettings.crc"))) return EventHandlerResult::OK; - } if (strncmp_P(command, PSTR("settings."), 9) != 0) return EventHandlerResult::OK; From 067e6e5a9389a3bf2040587590879dcac6bf2a0c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 7 Oct 2018 09:33:23 +0200 Subject: [PATCH 707/792] Add an onFocusEvent method, to implement "help" Signed-off-by: Gergely Nagy --- src/kaleidoscope/FocusSerial.cpp | 5 +++++ src/kaleidoscope/FocusSerial.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/kaleidoscope/FocusSerial.cpp b/src/kaleidoscope/FocusSerial.cpp index 7fb37525..4bd1f5f1 100644 --- a/src/kaleidoscope/FocusSerial.cpp +++ b/src/kaleidoscope/FocusSerial.cpp @@ -68,6 +68,11 @@ bool FocusSerial::handleHelp(const char *command, return true; } +EventHandlerResult FocusSerial::onFocusEvent(const char *command) { + handleHelp(command, PSTR("help")); + return EventHandlerResult::OK; +} + void FocusSerial::printSpace(void) { Serial.print(F(" ")); } diff --git a/src/kaleidoscope/FocusSerial.h b/src/kaleidoscope/FocusSerial.h index 4e5613ea..827a1340 100644 --- a/src/kaleidoscope/FocusSerial.h +++ b/src/kaleidoscope/FocusSerial.h @@ -42,6 +42,7 @@ class FocusSerial : public kaleidoscope::Plugin { return EventHandlerResult::OK; } EventHandlerResult beforeReportingState(); + EventHandlerResult onFocusEvent(const char *command); private: static char command_[32]; From 354132255939b283b0a00eeecc97fc5fc6387499 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 8 Oct 2018 23:15:20 +0200 Subject: [PATCH 708/792] Clean up the EEPROM header This removes the `magic` field from the beginning of the header. It was originally meant to signal if the EEPROM we're dealing with is new, or if it has been set up with `EEPROMSettings` before. But as `EEPROMSettings` is pretty much the only way we deal with EEPROM, there's not much need for that. With the removal, we do need a way to update the CRC bits on first use, so we use the `version` field instead: if it is `0xff`, we update the CRC, and consider the settings valid. This means that until the version is set, the EEPROM layout is considered flexible, and verification is essentially disabled. Once the version is set, we can validate. Signed-off-by: Gergely Nagy --- src/Kaleidoscope/EEPROM-Settings.cpp | 11 +++++------ src/Kaleidoscope/EEPROM-Settings.h | 1 - 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index 4e4fb247..b611007e 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -52,12 +52,11 @@ void EEPROMSettings::seal(void) { CRC.finalize(); - if (settings_.magic[0] != 'K' || settings_.magic[1] != 'S') { - settings_.magic[0] = 'K'; - settings_.magic[1] = 'S'; - settings_.version = 0; - settings_.crc = CRC.crc; - + /* Until we set a version, consider the EEPROM contents flexible, and always + * update the CRC. This will always result in the settings being considered + * valid. + */ + if (settings_.version == 0xff) { return update(); } diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index 33cb0214..e582213f 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -45,7 +45,6 @@ class EEPROMSettings : public kaleidoscope::Plugin { static bool sealed_; static struct settings { - char magic[2]; uint8_t version; uint16_t crc; } settings_; From a8b677138e60746038e0b3e6392cef404a35818c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 8 Oct 2018 23:39:05 +0200 Subject: [PATCH 709/792] Add support for saving the default layer With upcoming EEPROMKeymap changes, saving the default layer will become an important part of the keyboard settings. The new `default_layer` method provides a way to set it programmatically, while the `settings.defaultLayer` Focus command allows the user to set it via Focus. The default layer - if set - is activated when the settings are sealed, either directly or automatically. Signed-off-by: Gergely Nagy --- README.md | 15 ++++++++++++ src/Kaleidoscope/EEPROM-Settings-Focus.cpp | 27 +++++++++++++++------- src/Kaleidoscope/EEPROM-Settings.cpp | 17 ++++++++++++-- src/Kaleidoscope/EEPROM-Settings.h | 3 +++ 4 files changed, 52 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 150c8d1b..701a313e 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,15 @@ The plugin provides the `EEPROMSettings` object, which has the following methods > > Should only be called **before** calling `seal()`. +### `default_layer([id])` + +> Sets (or returns, if called without an ID) the default layer. When the +> keyboard boots up, it will automatically switch to the configured layer - if +> any. +> +> This is the Focus counterpart of the `default_layer()` method documented +> above. + ### `seal()` > Seal the `EEPROM` layout, so no new slices can be requested. The CRC checksum @@ -125,6 +134,12 @@ following commands: [FocusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial +### `settings.defaultLayer` + +> Sets or returns (if called without arguments) the ID of the default layer. If +> set, the keyboard will automatically switch to the given layer when connected. +> Setting it to `255` disables the automatic switching. + ### `settings.crc` > Returns the actual, and the expected checksum of the settings. diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp index c34890f5..56cc50a9 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/Kaleidoscope/EEPROM-Settings-Focus.cpp @@ -24,32 +24,43 @@ namespace eeprom { EventHandlerResult FocusSettingsCommand::onFocusEvent(const char *command) { enum { - ISVALID, - GETVERSION, + DEFAULT_LAYER, + IS_VALID, + GET_VERSION, CRC, } sub_command; - if (::Focus.handleHelp(command, PSTR("settings.valid?\nsettings.version\nsettings.crc"))) + if (::Focus.handleHelp(command, PSTR("settings.defaultLayer\nsettings.valid?\nsettings.version\nsettings.crc"))) return EventHandlerResult::OK; if (strncmp_P(command, PSTR("settings."), 9) != 0) return EventHandlerResult::OK; - if (strcmp_P(command + 9, PSTR("valid?")) == 0) - sub_command = ISVALID; + if (strcmp_P(command + 9, PSTR("defaultLayer")) == 0) + sub_command = DEFAULT_LAYER; + else if (strcmp_P(command + 9, PSTR("valid?")) == 0) + sub_command = IS_VALID; else if (strcmp_P(command + 9, PSTR("version")) == 0) - sub_command = GETVERSION; + sub_command = GET_VERSION; else if (strcmp_P(command + 9, PSTR("crc")) == 0) sub_command = CRC; else return EventHandlerResult::OK; switch (sub_command) { - case ISVALID: + case DEFAULT_LAYER: { + if (Serial.peek() == '\n') { + Serial.println(::EEPROMSettings.default_layer()); + } else { + ::EEPROMSettings.default_layer(Serial.parseInt()); + } + break; + } + case IS_VALID: ::Focus.printBool(::EEPROMSettings.isValid()); Serial.println(); break; - case GETVERSION: + case GET_VERSION: Serial.println(::EEPROMSettings.version()); break; case CRC: diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/Kaleidoscope/EEPROM-Settings.cpp index b611007e..3870187f 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/Kaleidoscope/EEPROM-Settings.cpp @@ -47,15 +47,28 @@ uint16_t EEPROMSettings::crc(void) { return 0; } +uint8_t EEPROMSettings::default_layer(uint8_t layer) { + if (layer == 0xff) + return settings_.default_layer; + + settings_.default_layer = layer; + update(); + return settings_.default_layer; +} + void EEPROMSettings::seal(void) { sealed_ = true; CRC.finalize(); + /* If we have a default layer set, switch to it. As 0xff is the default EEPROM + * value, treat it as not having a default layer set. */ + if (settings_.default_layer != 0xff) + Layer.move(settings_.default_layer); + /* Until we set a version, consider the EEPROM contents flexible, and always * update the CRC. This will always result in the settings being considered - * valid. - */ + * valid. */ if (settings_.version == 0xff) { return update(); } diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/Kaleidoscope/EEPROM-Settings.h index e582213f..73d08636 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/Kaleidoscope/EEPROM-Settings.h @@ -39,12 +39,15 @@ class EEPROMSettings : public kaleidoscope::Plugin { static uint16_t crc(void); static uint16_t used(void); + static uint8_t default_layer(uint8_t layer = 0xff); + private: static uint16_t next_start_; static bool is_valid_; static bool sealed_; static struct settings { + uint8_t default_layer; uint8_t version; uint16_t crc; } settings_; From 83f1805d5d3384bbcb157daac33abbeeb684a1b6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 9 Oct 2018 00:35:14 +0200 Subject: [PATCH 710/792] Redesign the plugin setup procedure Instead of a low-level interface where one has to set the EEPROM-stored layers and the lookup method separately, introduce a `setup` method that combines the two in a much easier to grasp interface. It takes a layer number, and an optional mode, and sets things up accordingly. With this new setup procedure comes a new way of how the plugin works: instead of being able to override the keymap in EEPROM, we extend it (or use a custom implementation, for advanced use-cases). The default layer can still be set via Focus, thus effectively overriding the keymap in PROGMEM. To better support this, a new Focus command is introduced too: `keymap.roLayers`, which returns the number of layers in PROGMEM. The `keymap.transfer` Focus command is removed, because it can be done much more reliably from the host side, building on top of `keymap.map`. The rest of the lower-level interface is still there, though undocumented, for advanced use-cases the new simplified setup does not fit. Signed-off-by: Gergely Nagy --- README.md | 63 ++++++------------- examples/EEPROM-Keymap/EEPROM-Keymap.ino | 4 +- src/Kaleidoscope-EEPROM-Keymap.h | 1 - src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp | 50 --------------- src/Kaleidoscope/EEPROM-Keymap-Transfer.h | 34 ---------- src/Kaleidoscope/EEPROM-Keymap.cpp | 69 +++++++++++++++------ src/Kaleidoscope/EEPROM-Keymap.h | 11 +++- 7 files changed, 80 insertions(+), 152 deletions(-) delete mode 100644 src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp delete mode 100644 src/Kaleidoscope/EEPROM-Keymap-Transfer.h diff --git a/README.md b/README.md index 6baff5ff..34d7c9f9 100644 --- a/README.md +++ b/README.md @@ -9,26 +9,15 @@ [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 -While keyboards usually ship with a keymap programmed in, to be able to change -that keymap, without flashing new firmware, we need a way to place the keymap -into a place we can update at run-time, and which persists across reboots. -Fortunately, we have a bit of `EEPROM` on the keyboard, and can use it to store -either the full keymap (and saving space in the firmware then), or store an -overlay there. In the latter case, whenever there is a non-transparent key on -the overlay, we will use that instead of the keyboard default. - -In short, this plugin allows us to change our keymaps, without having to compile -and flash new firmware. It does so through the use of the -[FocusSerial][plugin:focusSerial] plugin. +While keyboards usually ship with a keymap programmed in, to be able to change that keymap, without flashing new firmware, we need a way to place the keymap into a place we can update at run-time, and which persists across reboots. Fortunately, we have a bit of `EEPROM` on the keyboard, and can use it to store either the full keymap (and saving space in the firmware then), or store additional layers there. + +In short, this plugin allows us to change our keymaps, without having to compile and flash new firmware. It does so through the use of the [FocusSerial][plugin:focusSerial] plugin. [plugin:focusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial ## Using the plugin -Using the plugin is reasonably simple: after including the header, enable the -plugin, and configure how many layers at most we want to store in `EEPROM`. -There are other settings one can tweak, but these two steps are enough to get -started with. +Using the plugin is reasonably simple: after including the header, enable the plugin, and configure how many layers at most we want to store in `EEPROM`. There are other settings one can tweak, but these two steps are enough to get started with. Once these are set up, we can update the keymap via [Focus][plugin:focusSerial]. @@ -38,53 +27,40 @@ Once these are set up, we can update the keymap via [Focus][plugin:focusSerial]. #include KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, - Focus, - FocusKeymapTransferCommand); + Focus); void setup() { Kaleidoscope.setup(); - EEPROMKeymap.max_layers(1); + EEPROMKeymap.setup(1); } ``` ## Plugin methods -The plugin provides the `EEPROMKeymap` object, which has the following methods: +The plugin provides the `EEPROMKeymap` object, which has the following method: -### `.max_layers(max)` +### `.setup(layers[, mode])` -> Tells the extension to reserve space in EEPROM for up to `max` layers. Can -> only be called once, any subsequent call will be a no-op. -> This should be set to the number of keymap layers you want to be -> able to program from EEPROM (probably the number of layers you have -> defined in your keymap). +> Reserve space in EEPROM for up to `layers` layers, and set things up to work according to the specified `mode` (see below for a list of supported modes). To be called from the `setup` method of one's sketch. +> +> Supported modes are: +> - `EEPROMKeymap.Mode::EXTEND`: Extend the keymap with layers from EEPROM, treating them as extensions of the main keymap embedded in the firmware. The first layer in EEPROM will have a number one higher than the last layer in PROGMEM. In this case, the total number of layers will be the number of them in PROGMEM plus `layers`. +> - `EEPROMKeymap.Mode::CUSTOM`: For advanced use cases where the `EXTEND` mode is not appropriate. In this case, the plugin merely reserves a slice of EEPROM for the requested amount of layers, but does no other configuration - that's entirely up to the Sketch. ## Focus commands -The plugin provides a `keymap.map` Focus command unconditionally, and a -`keymap.transfer` via the `FocusKeymapTransferCommand` object. +The plugin provides the `keymap.map` and a `keymap.roLayers` commands. ### `keymap.map [codes...]` -> Without arguments, displays the keymap currently in effect. Each key is -> printed as its raw, 16-bit keycode. +> Without arguments, displays the keymap currently in effect. Each key is printed as its raw, 16-bit keycode. > -> With arguments, it stores as many keys as given. One does not need to set all -> keys, on all layers: the command will start from the first key on the first -> layer, and go on as long as it has input. It will not go past the layer set -> via the `.max_layers()` method. +> With arguments, it stores as many keys as given. One does not need to set all keys, on all layers: the command will start from the first key on the first layer, and go on as long as it has input. It will not go past the total amount of layers (that is, `layer_count`). -### `keymap.transfer LAYER` +### `keymap.roLayers` -> Transfers the `LAYER` from the built-in memory of the keyboard into `EEPROM` -> storage. -> -> Useful mostly when one wants to remove the built-in keymap, and wants to -> easily transfer it into `EEPROM` first. -> -> This is generally not needed, and it is recommended to not enable this -> command, unless the feature this command implements is truly needed. +> Returns the number of read-only layers. This only makes sense for the `EEPROMKeymap.Mode::EXTEND` mode, where it returns the number of layers in PROGMEM. In any other case, it doesn't return anything, doing so is left for another event handler that understands what the correct value would be. ## Dependencies @@ -93,7 +69,6 @@ The plugin provides a `keymap.map` Focus command unconditionally, and a ## Further reading -Starting from the [example][plugin:example] is the recommended way of getting -started with the plugin. +Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. [plugin:example]: https://github.com/keyboardio/Kaleidoscope-EEPROM-Keymap/blob/master/examples/EEPROM-Keymap/EEPROM-Keymap.ino diff --git a/examples/EEPROM-Keymap/EEPROM-Keymap.ino b/examples/EEPROM-Keymap/EEPROM-Keymap.ino index e5c35ec9..f9158099 100644 --- a/examples/EEPROM-Keymap/EEPROM-Keymap.ino +++ b/examples/EEPROM-Keymap/EEPROM-Keymap.ino @@ -40,12 +40,12 @@ KEYMAPS( ) // *INDENT-ON* -KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, Focus, FocusKeymapTransferCommand); +KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, Focus); void setup() { Kaleidoscope.setup(); - EEPROMKeymap.max_layers(1); + EEPROMKeymap.setup(1, EEPROMKeymap.Mode::EXTEND); } void loop() { diff --git a/src/Kaleidoscope-EEPROM-Keymap.h b/src/Kaleidoscope-EEPROM-Keymap.h index 3bcb13c8..7b3b8af0 100644 --- a/src/Kaleidoscope-EEPROM-Keymap.h +++ b/src/Kaleidoscope-EEPROM-Keymap.h @@ -18,4 +18,3 @@ #pragma once #include -#include diff --git a/src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp b/src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp deleted file mode 100644 index 77ec771b..00000000 --- a/src/Kaleidoscope/EEPROM-Keymap-Transfer.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- mode: c++ -*- - * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017, 2018 Keyboard.io, Inc - * - * 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, version 3. - * - * 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 . - */ - -#include -#include -#include - -namespace kaleidoscope { -namespace eeprom { - -EventHandlerResult FocusKeymapTransferCommand::onFocusEvent(const char *command) { - const char *cmd = PSTR("keymap.transfer"); - - if (::Focus.handleHelp(command, cmd)) - return EventHandlerResult::OK; - if (strcmp_P(command, cmd) != 0) - return EventHandlerResult::OK; - - uint8_t layer = Serial.parseInt(); - - for (uint8_t row = 0; row < ROWS; row++) { - for (uint8_t col = 0; col < COLS; col++) { - Key k = Layer.getKeyFromPROGMEM(layer, row, col); - uint16_t pos = ((layer * ROWS * COLS) + (row * COLS) + col); - - ::EEPROMKeymap.updateKey(pos, k); - } - } - - return EventHandlerResult::EVENT_CONSUMED; -} - -} -} - -kaleidoscope::eeprom::FocusKeymapTransferCommand FocusKeymapTransferCommand; diff --git a/src/Kaleidoscope/EEPROM-Keymap-Transfer.h b/src/Kaleidoscope/EEPROM-Keymap-Transfer.h deleted file mode 100644 index 6dfee13c..00000000 --- a/src/Kaleidoscope/EEPROM-Keymap-Transfer.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- mode: c++ -*- - * Kaleidoscope-EEPROM-Keymap -- EEPROM-based keymap support. - * Copyright (C) 2017-2018 Keyboard.io, Inc - * - * 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, version 3. - * - * 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 . - */ - -#pragma once - -#include -#include - -namespace kaleidoscope { -namespace eeprom { -class FocusKeymapTransferCommand : public Plugin { - public: - FocusKeymapTransferCommand() {} - - EventHandlerResult onFocusEvent(const char *command); -}; -} -} - -extern kaleidoscope::eeprom::FocusKeymapTransferCommand FocusKeymapTransferCommand; diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/Kaleidoscope/EEPROM-Keymap.cpp index 28e5c608..249f1790 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/Kaleidoscope/EEPROM-Keymap.cpp @@ -20,16 +20,30 @@ #include namespace kaleidoscope { +EEPROMKeymap::Mode EEPROMKeymap::mode_; uint16_t EEPROMKeymap::keymap_base_; uint8_t EEPROMKeymap::max_layers_; +uint8_t EEPROMKeymap::progmem_layers_; EventHandlerResult EEPROMKeymap::onSetup() { ::EEPROMSettings.onSetup(); - Layer.getKey = ::EEPROMKeymap.getKeyOverride; - + progmem_layers_ = layer_count; return EventHandlerResult::OK; } +void EEPROMKeymap::setup(uint8_t max, Mode mode) { + switch (mode) { + case Mode::CUSTOM: + break; + case Mode::EXTEND: + layer_count = progmem_layers_ + max; + Layer.getKey = getKeyExtended; + break; + } + mode_ = mode; + max_layers(max); +} + void EEPROMKeymap::max_layers(uint8_t max) { max_layers_ = max; keymap_base_ = ::EEPROMSettings.requestSlice(max_layers_ * ROWS * COLS * 2); @@ -49,22 +63,16 @@ Key EEPROMKeymap::getKey(uint8_t layer, byte row, byte col) { return key; } -Key EEPROMKeymap::getKeyOverride(uint8_t layer, byte row, byte col) { +Key EEPROMKeymap::getKeyExtended(uint8_t layer, byte row, byte col) { Key key; - key = getKey(layer, row, col); - - /* - * If we read a transparent key from EEPROM, or we're trying to read from a - * layer higher than what is available there (max_layers), check if we're below - * the layer count in PROGMEM (layer_count). If we are, read from PROGMEM, - * otherwise leave the key as-is (either transparent or NoKey). - */ - if ((key == Key_Transparent || layer >= max_layers_) && - (layer < layer_count)) - key = Layer.getKeyFromPROGMEM(layer, row, col); + // If the layer is within PROGMEM bounds, look it up from there + if (layer < progmem_layers_) { + return Layer.getKeyFromPROGMEM(layer, row, col); + } - return key; + // If the layer is outside of PROGMEM, look up from EEPROM + return getKey(layer - progmem_layers_, row, col); } uint16_t EEPROMKeymap::keymap_base(void) { @@ -90,14 +98,24 @@ void EEPROMKeymap::printKey(Key k) { EventHandlerResult EEPROMKeymap::onFocusEvent(const char *command) { const char *cmd = PSTR("keymap.map"); - if (::Focus.handleHelp(command, cmd)) + if (::Focus.handleHelp(command, PSTR("keymap.map\nkeymap.roLayers"))) + return EventHandlerResult::OK; + + if (strncmp_P(command, PSTR("keymap."), 7) != 0) return EventHandlerResult::OK; - if (strcmp_P(command, cmd) != 0) + if (strcmp_P(command + 7, PSTR("roLayers")) == 0) { + if (mode_ != Mode::EXTEND) + return EventHandlerResult::OK; + Serial.println(progmem_layers_); + return EventHandlerResult::EVENT_CONSUMED; + } + + if (strcmp_P(command + 7, PSTR("map")) != 0) return EventHandlerResult::OK; if (Serial.peek() == '\n') { - for (uint8_t layer = 0; layer < max_layers_; layer++) { + for (uint8_t layer = 0; layer < layer_count; layer++) { for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t col = 0; col < COLS; col++) { Key k = Layer.getKey(layer, row, col); @@ -110,8 +128,19 @@ EventHandlerResult EEPROMKeymap::onFocusEvent(const char *command) { Serial.println(); } else { uint16_t i = 0; - while ((Serial.peek() != '\n') && (i < ROWS * COLS * max_layers_)) { - updateKey(i, parseKey()); + uint8_t layers = layer_count; + if (layers > 0) + layers--; + while ((Serial.peek() != '\n') && (i < ROWS * COLS * layers)) { + Key k = parseKey(); + + if (mode_ == Mode::EXTEND) { + uint8_t layer = i / (ROWS * COLS); + if (layer >= progmem_layers_) + updateKey(i - (progmem_layers_ * ROWS * COLS), k); + } else { + updateKey(i, k); + } i++; } } diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/Kaleidoscope/EEPROM-Keymap.h index 86368f3a..4cff00ea 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/Kaleidoscope/EEPROM-Keymap.h @@ -23,23 +23,32 @@ namespace kaleidoscope { class EEPROMKeymap : public kaleidoscope::Plugin { public: + enum class Mode { + CUSTOM, + EXTEND, + }; + EEPROMKeymap(void) {} EventHandlerResult onSetup(); EventHandlerResult onFocusEvent(const char *command); + static void setup(uint8_t max, Mode mode = Mode::EXTEND); + static void max_layers(uint8_t max); static uint16_t keymap_base(void); static Key getKey(uint8_t layer, byte row, byte col); - static Key getKeyOverride(uint8_t layer, byte row, byte col); + static Key getKeyExtended(uint8_t layer, byte row, byte col); static void updateKey(uint16_t base_pos, Key key); private: static uint16_t keymap_base_; static uint8_t max_layers_; + static uint8_t progmem_layers_; + static Mode mode_; static Key parseKey(void); static void printKey(Key key); From 49464bbaa633c8e394b424d0cd3be7fea94f59f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20G=C3=B6rner?= Date: Wed, 10 Oct 2018 00:13:39 +0200 Subject: [PATCH 711/792] Remove unused variable to silence warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Max Görner --- src/Kaleidoscope-Model01-TestMode.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index 0bf9f478..b8647ae9 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -60,7 +60,6 @@ void TestMode_::test_leds(void) { cRGB red = CRGB(201, 0, 0); cRGB blue = CRGB(0, 0, 201); cRGB green = CRGB(0, 201, 0); - cRGB white = CRGB(50, 50, 50); cRGB brightWhite = CRGB(160, 160, 160); // make all the LEDs bright red From 0c1e874d74df3fa3fd0a1b065c5972bc9e5347e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20G=C3=B6rner?= Date: Wed, 10 Oct 2018 00:22:20 +0200 Subject: [PATCH 712/792] Replace defines by constexpr variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several define directives could be replaced by constexpr variable definitions. This adds type safety with no overhead costs. Signed-off-by: Max Görner --- src/Kaleidoscope-Model01-TestMode.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index b8647ae9..c130c740 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -19,11 +19,11 @@ #include "Kaleidoscope-LEDEffect-Rainbow.h" -#define CHATTER_CYCLE_LIMIT 30 -#define TOGGLED_OFF 2 -#define TOGGLED_ON 1 -#define HELD 3 -#define RELEASED 0 +constexpr uint8_t CHATTER_CYCLE_LIMIT = 30; +constexpr uint8_t TOGGLED_OFF = 2; +constexpr uint8_t TOGGLED_ON = 1; +constexpr uint8_t HELD = 3; +constexpr uint8_t RELEASED = 0; kaleidoscope::EventHandlerResult TestMode_::beforeReportingState() { From 116f56ab630ad18536ed9b1968e0e37236016673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20G=C3=B6rner?= Date: Wed, 10 Oct 2018 00:26:41 +0200 Subject: [PATCH 713/792] Constify certain variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Where possible, variables definitions were constified to catch unintentional changes. Signed-off-by: Max Görner --- src/Kaleidoscope-Model01-TestMode.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/Kaleidoscope-Model01-TestMode.cpp index c130c740..9689dfb0 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/Kaleidoscope-Model01-TestMode.cpp @@ -57,10 +57,10 @@ void TestMode_::set_leds(cRGB color) { } void TestMode_::test_leds(void) { - cRGB red = CRGB(201, 0, 0); - cRGB blue = CRGB(0, 0, 201); - cRGB green = CRGB(0, 201, 0); - cRGB brightWhite = CRGB(160, 160, 160); + constexpr cRGB red = CRGB(201, 0, 0); + constexpr cRGB blue = CRGB(0, 0, 201); + constexpr cRGB green = CRGB(0, 201, 0); + constexpr cRGB brightWhite = CRGB(160, 160, 160); // make all the LEDs bright red set_leds(red); @@ -82,14 +82,14 @@ void TestMode_::test_leds(void) { void TestMode_::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset) { - cRGB red = CRGB(201, 0, 0); - cRGB blue = CRGB(0, 0, 201); - cRGB green = CRGB(0, 201, 0); + constexpr cRGB red = CRGB(201, 0, 0); + constexpr cRGB blue = CRGB(0, 0, 201); + constexpr cRGB green = CRGB(0, 201, 0); - uint8_t keynum = (row * 8) + (col); + const uint8_t keynum = (row * 8) + (col); - uint8_t keyState = ((bitRead(oldState->all, keynum) << 1) | - (bitRead(newState->all, keynum) << 0)); + const uint8_t keyState = ((bitRead(oldState->all, keynum) << 1) | + (bitRead(newState->all, keynum) << 0)); if (keyState == TOGGLED_ON) { if (side->cyclesSinceStateChange[keynum] < CHATTER_CYCLE_LIMIT) { bitSet(side->badKeys, keynum); From 86cdb0f1b6c6c9f665487645ca5f590f57a161f4 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:15:35 +0200 Subject: [PATCH 714/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index 34d7c9f9..1a93a6ef 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-EEPROM-Keymap -![status][st:stable] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - While keyboards usually ship with a keymap programmed in, to be able to change that keymap, without flashing new firmware, we need a way to place the keymap into a place we can update at run-time, and which persists across reboots. Fortunately, we have a bit of `EEPROM` on the keyboard, and can use it to store either the full keymap (and saving space in the firmware then), or store additional layers there. In short, this plugin allows us to change our keymaps, without having to compile and flash new firmware. It does so through the use of the [FocusSerial][plugin:focusSerial] plugin. From 5457003c13682c7454fb4bb3d48d35f0f6da83bd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:19:29 +0200 Subject: [PATCH 715/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index 701a313e..685a8d9d 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-EEPROM-Settings -![status][st:experimental] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - To be able to reliably store persistent configuration in `EEPROM`, we need to be able to split up the available space for plugins to use. We also want to make sure that we notice when the `EEPROM` contents and the firmware are out of sync. From 4021b1e84fbf606d05decf26c5d9c24f79b5bedb Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:27:43 +0200 Subject: [PATCH 716/792] Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 403754f915b4183aec3109a8268e38b9e1f31f69 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:34:50 +0200 Subject: [PATCH 717/792] README.md, example, and Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). While there, updated both the README and the example to not use the now-obsolete `.enableWakeup` method. Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 20 +++---------------- .../HostPowerManagement.ino | 2 -- 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index ef1cca88..f89544f9 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,12 @@ # Kaleidoscope-HostPowerManagement -![status][st:experimental] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-HostPowerManagement.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-HostPowerManagement - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - Support performing custom actions whenever the host suspends, resumes, or is -sleeping. Additionally, this plugin provides optional support for the keyboard -to wake the host up from suspend. +sleeping. ## Using the plugin @@ -26,21 +21,12 @@ KALEIDOSCOPE_INIT_PLUGINS(HostPowerManagement); void setup () { Kaleidoscope.setup (); - - HostPowerManagement.enableWakeup(); } ``` ## Plugin methods -The plugin provides the `HostPowerManagement` object, which has the following methods: - -### `.enableWakeup()` - -> Enables host wakeup support. When enabled, pressing any key on the keyboard -> will wake the host up. -> -> Once enabled, it **cannot** be disabled again. +The plugin provides the `HostPowerManagement` object, with no public methods. ## Overrideable methods diff --git a/examples/HostPowerManagement/HostPowerManagement.ino b/examples/HostPowerManagement/HostPowerManagement.ino index 77b159ab..5f27cbdf 100644 --- a/examples/HostPowerManagement/HostPowerManagement.ino +++ b/examples/HostPowerManagement/HostPowerManagement.ino @@ -64,8 +64,6 @@ KALEIDOSCOPE_INIT_PLUGINS(LEDControl, void setup() { Kaleidoscope.setup(); - - HostPowerManagement.enableWakeup(); } void loop() { From 5e91e2b1454ca2568aec06a6bf8f2f0a9fcf73ce Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:39:18 +0200 Subject: [PATCH 718/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index f87f7116..57b10d64 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-LED-AlphaSquare -![status][st:experimental] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - An alphabet for your per-key LEDs, `AlphaSquare` provides a way to display 4x4 "pixel" symbols on your keyboard. With this building block, one can build some sweet animations, or just show off - the possibilities are almost endless! From dfe2ffaab4a78704e1756e5107262fbaaaade333 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:39:37 +0200 Subject: [PATCH 719/792] Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 66112d470028a125c79fc88846584dadfa9aa34c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:41:26 +0200 Subject: [PATCH 720/792] README.md cleanup Remove the stable/experimental badge from README.md (because they aren't being kept up to date), but add a Travis build status badge. Signed-off-by: Gergely Nagy --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2c0c21aa..61f261ce 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # Kaleidoscope-LEDEffect-BootGreeting -![status][st:stable] +[![Build Status][travis:image]][travis:status] - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-BootGreeting.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-BootGreeting If you want to have your keyboard signal when it turns on, but you don't want to use any more complicated LED modes, this plugin is for you. It will make the From aea9d29e531afd939a77e96ced0b44244b6d398f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:42:59 +0200 Subject: [PATCH 721/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index 92048268..549a5c87 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-LEDEffect-Breathe -![status][st:stable] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Breathe.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Breathe - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - Provides a breathing effect for the keyboard. Breathe in, breathe out. ## Using the extension From 6b097f1773a1abe968f77aea9e9b61c2c0cae278 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:43:43 +0200 Subject: [PATCH 722/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index 7a123e75..86e16cb0 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-LEDEffect-Chase -![status][st:stable] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Chase.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Chase - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - A simple LED effect where one color chases another across the keyboard and back, over and over again. Playful colors they are. From 4640a02e21e301b05d193656a23fe472fd22fc90 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:44:41 +0200 Subject: [PATCH 723/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index a6821d22..7fa9461f 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-LEDEffect-Rainbow -![status][st:stable] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Rainbow.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Rainbow - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - Two colorful rainbow effects are implemented by this plugin: one where the rainbow waves through the keys, and another where the LEDs breathe though the colors of a rainbow. The difference is that in the first case, we have all the From eb30c1d30d06bcf94499be7569553d65aaace8cd Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:47:54 +0200 Subject: [PATCH 724/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Also updated README.md to use `KALEIDOSCOPE_INIT_PLUGINS`. Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 10 +++------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index b4fc6d9f..56ab1017 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-LEDEffect-SolidColor -![status][st:stable] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-SolidColor.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-SolidColor - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - This plugin provides tools to build LED effects that set the entire keyboard to a single color. For show, and for backlighting purposes. @@ -22,9 +18,9 @@ To use the plugin, include the header, declare an effect using the static LEDSolidColor solidRed(160, 0, 0); -void setup() { - Kaleidoscope.use(&solidRed); +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, solidRed); +void setup() { Kaleidoscope.setup(); } ``` From a640497828b607b2f61c4548c6239c873a9b9338 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:49:45 +0200 Subject: [PATCH 725/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index 4dfaa7f0..ef117e63 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-LED-Stalker -![status][st:experimental] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - The `StalkerEffect` plugin provides an interesting new typing experience: the LEDs light up as you tap keys and play one of the selected effects: a haunting trail of ghostly white lights, or a blazing trail of fire. From 4a77929a26f6f463c7b78277fed6f3f2b5244a1a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:50:25 +0200 Subject: [PATCH 726/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index bbe1a6ac..9f5dc8a8 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-Macros -![status][st:stable] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-Macros.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-Macros - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - Macros are a standard feature on many keyboards and Kaleidoscope-powered ones are no exceptions. Macros are a way to have a single key-press do a whole lot of things under the hood: conventionally, macros play back a key sequence, but with From b95c4049c3cb05e2194b7aa1e49509c361e6ea72 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:51:04 +0200 Subject: [PATCH 727/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index dd99d7d7..73be331a 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-MagicCombo -![status][st:stable] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - The `MagicCombo` extension provides a way to perform custom actions when a particular set of keys are held down together. The functionality assigned to these keys are not changed, and the custom action triggers as long as all keys From 77704187a4a3ee1236d688c759a753fdf1aaf89e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:51:27 +0200 Subject: [PATCH 728/792] Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From b71ab5f1b3ea61c8a10871cc8d0ad9c9515fd5ca Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:52:05 +0200 Subject: [PATCH 729/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index a2d3ae6f..610ad246 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-MouseKeys -![status][st:stable] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MouseKeys.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MouseKeys - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - Have you ever wanted to control the mouse cursor from the comfort of your keyboard? With this plugin, you can. While it may not replace the mouse in all situations, there are plenty of cases where one will not have to lift their From 33275c4073d01311f9bae2a6d0a20c02f1bbb303 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:52:35 +0200 Subject: [PATCH 730/792] Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change From 4fe501c935ed46cc7dd2e301e81fc04398f3ef97 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 06:59:25 +0200 Subject: [PATCH 731/792] README.md & Travis cleanup Remove the IRC notifications from Travis (we're not using IRC anymore), and the stable/experimental badge from README.md (because they aren't being kept up to date). Signed-off-by: Gergely Nagy --- .travis.yml | 7 ------- README.md | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 23d30ccc..49b8c498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,6 @@ install: script: - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware notifications: - irc: - channels: - - "chat.freenode.net#keyboardio" - use_notice: true - skip_join: true - template: - - "%{repository_name}/%{branch} %{commit} by %{author}: %{commit_subject} %{build_url} %{message}" email: on_success: change on_failure: change diff --git a/README.md b/README.md index 99ef3c45..173eb109 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ # Kaleidoscope-USB-Quirks -![status][st:experimental] [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-USB-Quirks.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-USB-Quirks - [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 - [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 - [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 - USB-Quirks provides a few methods to deal with more obscure parts of the USB spec, such as changing between `Boot` and `Report` protocols. These are in a separate plugin, because these features are not part of the USB spec, and are often workarounds for various issues. See the provided methods for more information about what they're useful for. ## Using the plugin From 5c086122b8631865852cdc8a8181edc0b6c3b3b8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 10 Oct 2018 09:48:44 +0200 Subject: [PATCH 732/792] findLed: If key coordinates are used, don't search the keymap If we have key coordinates set, we don't need to search the keymap, we can just use the coordinates as-is. Fixes #10. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LEDEffect-BootGreeting.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp index 48e1bd63..6a6ccf19 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.cpp @@ -36,16 +36,19 @@ BootGreetingEffect::BootGreetingEffect(byte pos_row, byte pos_col) { } void BootGreetingEffect::findLed(void) { + if (key_col != 255 && key_row != 255) { + row_ = key_row; + col_ = key_col; + done_ = true; + return; + } + // Find the LED key. for (uint8_t r = 0; r < ROWS; r++) { for (uint8_t c = 0; c < COLS; c++) { Key k = Layer.lookupOnActiveLayer(r, c); - if ( - //If key row and col explicitly set, ignore the search key - (k.raw == search_key.raw && key_row == 255 && key_row == 255) - || (key_row != 255 && key_col != 255 && key_row == r && key_col == c) - ) { + if (k.raw == search_key.raw) { row_ = r; col_ = c; return; From eaf6dc573848139a3dceb5a2f9aa876c027745e5 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 11:37:20 +0200 Subject: [PATCH 733/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/EEPROM-Keymap.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 64 +----------------- doc/plugin/EEPROM-Keymap.md | 65 +++++++++++++++++++ src/Kaleidoscope-EEPROM-Keymap.h | 2 +- .../plugin}/EEPROM-Keymap.cpp | 4 +- .../plugin}/EEPROM-Keymap.h | 6 +- 5 files changed, 74 insertions(+), 67 deletions(-) create mode 100644 doc/plugin/EEPROM-Keymap.md rename src/{Kaleidoscope => kaleidoscope/plugin}/EEPROM-Keymap.cpp (98%) rename src/{Kaleidoscope => kaleidoscope/plugin}/EEPROM-Keymap.h (95%) diff --git a/README.md b/README.md index 1a93a6ef..30fd6bda 100644 --- a/README.md +++ b/README.md @@ -5,66 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap -While keyboards usually ship with a keymap programmed in, to be able to change that keymap, without flashing new firmware, we need a way to place the keymap into a place we can update at run-time, and which persists across reboots. Fortunately, we have a bit of `EEPROM` on the keyboard, and can use it to store either the full keymap (and saving space in the firmware then), or store additional layers there. - -In short, this plugin allows us to change our keymaps, without having to compile and flash new firmware. It does so through the use of the [FocusSerial][plugin:focusSerial] plugin. - - [plugin:focusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial - -## Using the plugin - -Using the plugin is reasonably simple: after including the header, enable the plugin, and configure how many layers at most we want to store in `EEPROM`. There are other settings one can tweak, but these two steps are enough to get started with. - -Once these are set up, we can update the keymap via [Focus][plugin:focusSerial]. - -```c++ -#include -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, - Focus); - -void setup() { - Kaleidoscope.setup(); - - EEPROMKeymap.setup(1); -} -``` - -## Plugin methods - -The plugin provides the `EEPROMKeymap` object, which has the following method: - -### `.setup(layers[, mode])` - -> Reserve space in EEPROM for up to `layers` layers, and set things up to work according to the specified `mode` (see below for a list of supported modes). To be called from the `setup` method of one's sketch. -> -> Supported modes are: -> - `EEPROMKeymap.Mode::EXTEND`: Extend the keymap with layers from EEPROM, treating them as extensions of the main keymap embedded in the firmware. The first layer in EEPROM will have a number one higher than the last layer in PROGMEM. In this case, the total number of layers will be the number of them in PROGMEM plus `layers`. -> - `EEPROMKeymap.Mode::CUSTOM`: For advanced use cases where the `EXTEND` mode is not appropriate. In this case, the plugin merely reserves a slice of EEPROM for the requested amount of layers, but does no other configuration - that's entirely up to the Sketch. - -## Focus commands - -The plugin provides the `keymap.map` and a `keymap.roLayers` commands. - -### `keymap.map [codes...]` - -> Without arguments, displays the keymap currently in effect. Each key is printed as its raw, 16-bit keycode. -> -> With arguments, it stores as many keys as given. One does not need to set all keys, on all layers: the command will start from the first key on the first layer, and go on as long as it has input. It will not go past the total amount of layers (that is, `layer_count`). - -### `keymap.roLayers` - -> Returns the number of read-only layers. This only makes sense for the `EEPROMKeymap.Mode::EXTEND` mode, where it returns the number of layers in PROGMEM. In any other case, it doesn't return anything, doing so is left for another event handler that understands what the correct value would be. - -## Dependencies - -* [Kaleidoscope-EEPROM-Settings](https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings) -* [Kaleidoscope-FocusSerial](https://github.com/keyboardio/Kaleidoscope-FocusSerial) - -## Further reading - -Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-EEPROM-Keymap/blob/master/examples/EEPROM-Keymap/EEPROM-Keymap.ino +See [doc/plugin/EEPROM-Keymap.md](doc/plugin/EEPROM-Keymap.md) for documentation. diff --git a/doc/plugin/EEPROM-Keymap.md b/doc/plugin/EEPROM-Keymap.md new file mode 100644 index 00000000..3fc03667 --- /dev/null +++ b/doc/plugin/EEPROM-Keymap.md @@ -0,0 +1,65 @@ +# Kaleidoscope-EEPROM-Keymap + +While keyboards usually ship with a keymap programmed in, to be able to change that keymap, without flashing new firmware, we need a way to place the keymap into a place we can update at run-time, and which persists across reboots. Fortunately, we have a bit of `EEPROM` on the keyboard, and can use it to store either the full keymap (and saving space in the firmware then), or store additional layers there. + +In short, this plugin allows us to change our keymaps, without having to compile and flash new firmware. It does so through the use of the [FocusSerial][plugin:focusSerial] plugin. + + [plugin:focusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial + +## Using the plugin + +Using the plugin is reasonably simple: after including the header, enable the plugin, and configure how many layers at most we want to store in `EEPROM`. There are other settings one can tweak, but these two steps are enough to get started with. + +Once these are set up, we can update the keymap via [Focus][plugin:focusSerial]. + +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(EEPROMKeymap, + Focus); + +void setup() { + Kaleidoscope.setup(); + + EEPROMKeymap.setup(1); +} +``` + +## Plugin methods + +The plugin provides the `EEPROMKeymap` object, which has the following method: + +### `.setup(layers[, mode])` + +> Reserve space in EEPROM for up to `layers` layers, and set things up to work according to the specified `mode` (see below for a list of supported modes). To be called from the `setup` method of one's sketch. +> +> Supported modes are: +> - `EEPROMKeymap.Mode::EXTEND`: Extend the keymap with layers from EEPROM, treating them as extensions of the main keymap embedded in the firmware. The first layer in EEPROM will have a number one higher than the last layer in PROGMEM. In this case, the total number of layers will be the number of them in PROGMEM plus `layers`. +> - `EEPROMKeymap.Mode::CUSTOM`: For advanced use cases where the `EXTEND` mode is not appropriate. In this case, the plugin merely reserves a slice of EEPROM for the requested amount of layers, but does no other configuration - that's entirely up to the Sketch. + +## Focus commands + +The plugin provides the `keymap.map` and a `keymap.roLayers` commands. + +### `keymap.map [codes...]` + +> Without arguments, displays the keymap currently in effect. Each key is printed as its raw, 16-bit keycode. +> +> With arguments, it stores as many keys as given. One does not need to set all keys, on all layers: the command will start from the first key on the first layer, and go on as long as it has input. It will not go past the total amount of layers (that is, `layer_count`). + +### `keymap.roLayers` + +> Returns the number of read-only layers. This only makes sense for the `EEPROMKeymap.Mode::EXTEND` mode, where it returns the number of layers in PROGMEM. In any other case, it doesn't return anything, doing so is left for another event handler that understands what the correct value would be. + +## Dependencies + +* [Kaleidoscope-EEPROM-Settings](https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings) +* [Kaleidoscope-FocusSerial](https://github.com/keyboardio/Kaleidoscope-FocusSerial) + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-EEPROM-Keymap/blob/master/examples/EEPROM-Keymap/EEPROM-Keymap.ino diff --git a/src/Kaleidoscope-EEPROM-Keymap.h b/src/Kaleidoscope-EEPROM-Keymap.h index 7b3b8af0..3dd4be9e 100644 --- a/src/Kaleidoscope-EEPROM-Keymap.h +++ b/src/Kaleidoscope-EEPROM-Keymap.h @@ -17,4 +17,4 @@ #pragma once -#include +#include diff --git a/src/Kaleidoscope/EEPROM-Keymap.cpp b/src/kaleidoscope/plugin/EEPROM-Keymap.cpp similarity index 98% rename from src/Kaleidoscope/EEPROM-Keymap.cpp rename to src/kaleidoscope/plugin/EEPROM-Keymap.cpp index 249f1790..bb415be2 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.cpp +++ b/src/kaleidoscope/plugin/EEPROM-Keymap.cpp @@ -20,6 +20,7 @@ #include namespace kaleidoscope { +namespace plugin { EEPROMKeymap::Mode EEPROMKeymap::mode_; uint16_t EEPROMKeymap::keymap_base_; uint8_t EEPROMKeymap::max_layers_; @@ -148,6 +149,7 @@ EventHandlerResult EEPROMKeymap::onFocusEvent(const char *command) { return EventHandlerResult::EVENT_CONSUMED; } +} } -kaleidoscope::EEPROMKeymap EEPROMKeymap; +kaleidoscope::plugin::EEPROMKeymap EEPROMKeymap; diff --git a/src/Kaleidoscope/EEPROM-Keymap.h b/src/kaleidoscope/plugin/EEPROM-Keymap.h similarity index 95% rename from src/Kaleidoscope/EEPROM-Keymap.h rename to src/kaleidoscope/plugin/EEPROM-Keymap.h index 4cff00ea..ae72e8e9 100644 --- a/src/Kaleidoscope/EEPROM-Keymap.h +++ b/src/kaleidoscope/plugin/EEPROM-Keymap.h @@ -21,6 +21,7 @@ #include namespace kaleidoscope { +namespace plugin { class EEPROMKeymap : public kaleidoscope::Plugin { public: enum class Mode { @@ -53,6 +54,7 @@ class EEPROMKeymap : public kaleidoscope::Plugin { static Key parseKey(void); static void printKey(Key key); }; -}; +} +} -extern kaleidoscope::EEPROMKeymap EEPROMKeymap; +extern kaleidoscope::plugin::EEPROMKeymap EEPROMKeymap; From 72fdfdd54387749337b5510a80cb2d19f96a3272 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 11:37:23 +0200 Subject: [PATCH 734/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .gitignore | 4 - .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 7 files changed, 774 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.gitignore b/.gitignore deleted file mode 100644 index be16c9be..00000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.#* -*~ -/hardware/ -/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 30fd6bda..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-EEPROM-Keymap - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Keymap - -See [doc/plugin/EEPROM-Keymap.md](doc/plugin/EEPROM-Keymap.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 6865fb81..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-EEPROM-Keymap -version=0.0.0 -author=Gergely Nagy -maintainer=Gergely Nagy -sentence=EEPROM-based keymap support for Kaleidoscope. -paragraph=... -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-EEPROM-Keymap -architectures=avr -dot_a_linkage=true From 5099d8ebb9b4574db958d768900f2902979027df Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 12:35:58 +0200 Subject: [PATCH 735/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/HostPowerManagement.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 44 +---------------- doc/plugin/HostPowerManagement.md | 47 +++++++++++++++++++ .../HostPowerManagement.ino | 8 ++-- src/Kaleidoscope-HostPowerManagement.h | 2 +- .../plugin}/HostPowerManagement.cpp | 6 ++- .../plugin}/HostPowerManagement.h | 10 +++- 6 files changed, 65 insertions(+), 52 deletions(-) create mode 100644 doc/plugin/HostPowerManagement.md rename src/{Kaleidoscope => kaleidoscope/plugin}/HostPowerManagement.cpp (92%) rename src/{Kaleidoscope => kaleidoscope/plugin}/HostPowerManagement.h (84%) diff --git a/README.md b/README.md index f89544f9..09498c2f 100644 --- a/README.md +++ b/README.md @@ -5,46 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-HostPowerManagement.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-HostPowerManagement -Support performing custom actions whenever the host suspends, resumes, or is -sleeping. - -## Using the plugin - -To use the plugin, one needs to include the header, and activate it. No further -configuration is necessary, unless one wants to perform custom actions. - -```c++ -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(HostPowerManagement); - -void setup () { - Kaleidoscope.setup (); -} -``` - -## Plugin methods - -The plugin provides the `HostPowerManagement` object, with no public methods. - -## Overrideable methods - -### `hostPowerManagementEventHandler(event)` - -> The `hostPowerManagementEventHandler` method is the brain of the plugin: this function -> tells it what action to perform in response to the various events. -> -> Currently supported events are: `kaleidoscope::HostPowerManagement::Suspend` is fired -> once when the host suspends; `kaleidoscope::HostPowerManagement::Sleep` is fired every -> cycle while the host is suspended; `kaleidoscope::HostPowerManagement::Resume` is -> fired once when the host wakes up. -> -> The default implementation is empty. - -## Further reading - -Starting from the [example][plugin:example] is the recommended way of getting -started with the plugin. - - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-HostPowerManagement/blob/master/examples/HostPowerManagement/HostPowerManagement.ino +See [doc/plugin/HostPowerManagement.md](doc/plugin/HostPowerManagement.md) for documentation. diff --git a/doc/plugin/HostPowerManagement.md b/doc/plugin/HostPowerManagement.md new file mode 100644 index 00000000..0a5268cc --- /dev/null +++ b/doc/plugin/HostPowerManagement.md @@ -0,0 +1,47 @@ +# Kaleidoscope-HostPowerManagement + +Support performing custom actions whenever the host suspends, resumes, or is +sleeping. + +## Using the plugin + +To use the plugin, one needs to include the header, and activate it. No further +configuration is necessary, unless one wants to perform custom actions. + +```c++ +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(HostPowerManagement); + +void setup () { + Kaleidoscope.setup (); +} +``` + +## Plugin methods + +The plugin provides the `HostPowerManagement` object, with no public methods. + +## Overrideable methods + +### `hostPowerManagementEventHandler(event)` + +> The `hostPowerManagementEventHandler` method is the brain of the plugin: this function +> tells it what action to perform in response to the various events. +> +> Currently supported events are: +> `kaleidoscope::plugin::HostPowerManagement::Suspend` is fired once when the +> host suspends; `kaleidoscope::plugin::HostPowerManagement::Sleep` is fired +> every cycle while the host is suspended; +> `kaleidoscope::plugin::HostPowerManagement::Resume` is fired once when the +> host wakes up. +> +> The default implementation is empty. + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-HostPowerManagement/blob/master/examples/HostPowerManagement/HostPowerManagement.ino diff --git a/examples/HostPowerManagement/HostPowerManagement.ino b/examples/HostPowerManagement/HostPowerManagement.ino index 5f27cbdf..72d6f9df 100644 --- a/examples/HostPowerManagement/HostPowerManagement.ino +++ b/examples/HostPowerManagement/HostPowerManagement.ino @@ -43,18 +43,18 @@ const Key keymaps[][ROWS][COLS] PROGMEM = { }; // *INDENT-ON* -void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event) { +void hostPowerManagementEventHandler(kaleidoscope::plugin::HostPowerManagement::Event event) { switch (event) { - case kaleidoscope::HostPowerManagement::Suspend: + case kaleidoscope::plugin::HostPowerManagement::Suspend: LEDControl.paused = true; LEDControl.set_all_leds_to({0, 0, 0}); LEDControl.syncLeds(); break; - case kaleidoscope::HostPowerManagement::Resume: + case kaleidoscope::plugin::HostPowerManagement::Resume: LEDControl.paused = false; LEDControl.refreshAll(); break; - case kaleidoscope::HostPowerManagement::Sleep: + case kaleidoscope::plugin::HostPowerManagement::Sleep: break; } } diff --git a/src/Kaleidoscope-HostPowerManagement.h b/src/Kaleidoscope-HostPowerManagement.h index 6b9a0251..f6e56935 100644 --- a/src/Kaleidoscope-HostPowerManagement.h +++ b/src/Kaleidoscope-HostPowerManagement.h @@ -18,4 +18,4 @@ #pragma once -#include +#include diff --git a/src/Kaleidoscope/HostPowerManagement.cpp b/src/kaleidoscope/plugin/HostPowerManagement.cpp similarity index 92% rename from src/Kaleidoscope/HostPowerManagement.cpp rename to src/kaleidoscope/plugin/HostPowerManagement.cpp index 46f8053f..ce4c9826 100644 --- a/src/Kaleidoscope/HostPowerManagement.cpp +++ b/src/kaleidoscope/plugin/HostPowerManagement.cpp @@ -25,6 +25,7 @@ extern uint8_t _usbSuspendState; namespace kaleidoscope { +namespace plugin { bool HostPowerManagement::was_suspended_ = false; bool HostPowerManagement::initial_suspend_ = true; @@ -54,9 +55,10 @@ EventHandlerResult HostPowerManagement::beforeEachCycle() { return EventHandlerResult::OK; } +} } -__attribute__((weak)) void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event) { +__attribute__((weak)) void hostPowerManagementEventHandler(kaleidoscope::plugin::HostPowerManagement::Event event) { } -kaleidoscope::HostPowerManagement HostPowerManagement; +kaleidoscope::plugin::HostPowerManagement HostPowerManagement; diff --git a/src/Kaleidoscope/HostPowerManagement.h b/src/kaleidoscope/plugin/HostPowerManagement.h similarity index 84% rename from src/Kaleidoscope/HostPowerManagement.h rename to src/kaleidoscope/plugin/HostPowerManagement.h index 61b8716b..2dbb36f7 100644 --- a/src/Kaleidoscope/HostPowerManagement.h +++ b/src/kaleidoscope/plugin/HostPowerManagement.h @@ -26,6 +26,7 @@ "removed." namespace kaleidoscope { +namespace plugin { class HostPowerManagement : public kaleidoscope::Plugin { public: typedef enum { @@ -46,6 +47,11 @@ class HostPowerManagement : public kaleidoscope::Plugin { }; } -void hostPowerManagementEventHandler(kaleidoscope::HostPowerManagement::Event event); +// Backwards compatibility +typedef plugin::HostPowerManagement HostPowerManagement; -extern kaleidoscope::HostPowerManagement HostPowerManagement; +} + +void hostPowerManagementEventHandler(kaleidoscope::plugin::HostPowerManagement::Event event); + +extern kaleidoscope::plugin::HostPowerManagement HostPowerManagement; From 5cc3ee749ef615684afc1ae2266d3a11e0efbcc1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 12:39:04 +0200 Subject: [PATCH 736/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .gitignore | 4 - .travis.yml | 14 - COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 724 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.gitignore b/.gitignore deleted file mode 100644 index be16c9be..00000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.#* -*~ -/hardware/ -/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 3e1f64d2..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 09498c2f..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-HostPowerManagement - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-HostPowerManagement.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-HostPowerManagement - -See [doc/plugin/HostPowerManagement.md](doc/plugin/HostPowerManagement.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index db622f9d..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-HostPowerManagement -version=0.0.0 -author=Gergely Nagy -maintainer=Gergely Nagy -sentence=Host power management support library for Kaleidoscope. -paragraph=Hooks to support host suspend & resume, and the ability to wake the host from the keyboard. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-HostPowerManagement -architectures=avr -dot_a_linkage=true From f8587d3505f4cdf6747316a86b26f6c74f8dfd83 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 15:37:13 +0200 Subject: [PATCH 737/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/USB-Quirks.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 38 +------------------ doc/plugin/USB-Quirks.md | 39 ++++++++++++++++++++ src/Kaleidoscope-USB-Quirks.h | 2 +- src/kaleidoscope/{ => plugin}/USB-Quirks.cpp | 4 +- src/kaleidoscope/{ => plugin}/USB-Quirks.h | 4 +- 5 files changed, 47 insertions(+), 40 deletions(-) create mode 100644 doc/plugin/USB-Quirks.md rename src/kaleidoscope/{ => plugin}/USB-Quirks.cpp (94%) rename src/kaleidoscope/{ => plugin}/USB-Quirks.h (93%) diff --git a/README.md b/README.md index 173eb109..9d21494c 100644 --- a/README.md +++ b/README.md @@ -5,40 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-USB-Quirks.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-USB-Quirks -USB-Quirks provides a few methods to deal with more obscure parts of the USB spec, such as changing between `Boot` and `Report` protocols. These are in a separate plugin, because these features are not part of the USB spec, and are often workarounds for various issues. See the provided methods for more information about what they're useful for. - -## Using the plugin - -```c++ -#include -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(USBQuirks, Macros); - -const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { - if (macroIndex == 0) { - USBQuirks.toggleKeyboardProtocol(); - } - return MACRO_NONE; -} - -void setup() { - Kaleidoscope.setup(); -} -``` - -## Plugin methods - -The plugin provides one object, `USBQuirks`, which provides the following method: - -### `.toggleKeyboardProtocol()` - -> Toggle between `Boot` and `Report` protocol by detaching, and then -> re-attaching the USB devices, and setting the `BootKeyboard` protocol -> inbetween. -> -> This is most useful when one needs to have a boot keyboard, when one's in a -> BIOS, boot loader, or early password prompt or the like, and the host does not -> explicitly request the boot protocol for one reason or the other. With this -> toggle, we can switch between the two on-demand. +See [doc/plugin/USB-Quirks.md](doc/plugin/USB-Quirks.md) for documentation. diff --git a/doc/plugin/USB-Quirks.md b/doc/plugin/USB-Quirks.md new file mode 100644 index 00000000..a28f44c6 --- /dev/null +++ b/doc/plugin/USB-Quirks.md @@ -0,0 +1,39 @@ +# Kaleidoscope-USB-Quirks + +USB-Quirks provides a few methods to deal with more obscure parts of the USB spec, such as changing between `Boot` and `Report` protocols. These are in a separate plugin, because these features are not part of the USB spec, and are often workarounds for various issues. See the provided methods for more information about what they're useful for. + +## Using the plugin + +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(USBQuirks, Macros); + +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { + if (macroIndex == 0) { + USBQuirks.toggleKeyboardProtocol(); + } + return MACRO_NONE; +} + +void setup() { + Kaleidoscope.setup(); +} +``` + +## Plugin methods + +The plugin provides one object, `USBQuirks`, which provides the following method: + +### `.toggleKeyboardProtocol()` + +> Toggle between `Boot` and `Report` protocol by detaching, and then +> re-attaching the USB devices, and setting the `BootKeyboard` protocol +> inbetween. +> +> This is most useful when one needs to have a boot keyboard, when one's in a +> BIOS, boot loader, or early password prompt or the like, and the host does not +> explicitly request the boot protocol for one reason or the other. With this +> toggle, we can switch between the two on-demand. diff --git a/src/Kaleidoscope-USB-Quirks.h b/src/Kaleidoscope-USB-Quirks.h index 52d3cd85..953169e7 100644 --- a/src/Kaleidoscope-USB-Quirks.h +++ b/src/Kaleidoscope-USB-Quirks.h @@ -18,4 +18,4 @@ #pragma once -#include +#include diff --git a/src/kaleidoscope/USB-Quirks.cpp b/src/kaleidoscope/plugin/USB-Quirks.cpp similarity index 94% rename from src/kaleidoscope/USB-Quirks.cpp rename to src/kaleidoscope/plugin/USB-Quirks.cpp index aaec91a6..e308bb8c 100644 --- a/src/kaleidoscope/USB-Quirks.cpp +++ b/src/kaleidoscope/plugin/USB-Quirks.cpp @@ -19,6 +19,7 @@ #include namespace kaleidoscope { +namespace plugin { void USBQuirks::toggleKeyboardProtocol() { @@ -34,6 +35,7 @@ void USBQuirks::toggleKeyboardProtocol() { } +} } -kaleidoscope::USBQuirks USBQuirks; +kaleidoscope::plugin::USBQuirks USBQuirks; diff --git a/src/kaleidoscope/USB-Quirks.h b/src/kaleidoscope/plugin/USB-Quirks.h similarity index 93% rename from src/kaleidoscope/USB-Quirks.h rename to src/kaleidoscope/plugin/USB-Quirks.h index 9a03841c..9f7ce378 100644 --- a/src/kaleidoscope/USB-Quirks.h +++ b/src/kaleidoscope/plugin/USB-Quirks.h @@ -21,6 +21,7 @@ #include namespace kaleidoscope { +namespace plugin { class USBQuirks: public kaleidoscope::Plugin { public: USBQuirks() {} @@ -28,5 +29,6 @@ class USBQuirks: public kaleidoscope::Plugin { void toggleKeyboardProtocol(); }; } +} -extern kaleidoscope::USBQuirks USBQuirks; +extern kaleidoscope::plugin::USBQuirks USBQuirks; From e0026c74cf5eef13f8a7e099f1bd50493eba04b0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 15:37:13 +0200 Subject: [PATCH 738/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .gitignore | 4 - .travis.yml | 14 - COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 724 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.gitignore b/.gitignore deleted file mode 100644 index be16c9be..00000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.#* -*~ -/hardware/ -/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 3e1f64d2..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 9d21494c..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-USB-Quirks - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-USB-Quirks.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-USB-Quirks - -See [doc/plugin/USB-Quirks.md](doc/plugin/USB-Quirks.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 00026859..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-USB-Quirks -version=0.0.0 -author=Gergely Nagy -maintainer=Gergely Nagy -sentence=USB quirks for Kaleidoscope-based keyboards. -paragraph=... -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-USB-Quirks -architectures=avr -dot_a_linkage=true From ebd4c5191729caa10ba538b936753f1a497a8b68 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 09:34:05 +0200 Subject: [PATCH 739/792] No need to include "layers.h" Signed-off-by: Gergely Nagy --- src/Kaleidoscope-NumPad.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Kaleidoscope-NumPad.cpp b/src/Kaleidoscope-NumPad.cpp index d90fbcdc..e5275bc2 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/Kaleidoscope-NumPad.cpp @@ -17,7 +17,6 @@ #include "Kaleidoscope-NumPad.h" #include "LEDUtils.h" #include "Kaleidoscope.h" -#include "layers.h" byte NumPad_::numpadLayerToggleKeyRow = 255, NumPad_::numpadLayerToggleKeyCol = 255; uint8_t NumPad_::numPadLayer; From d69644271c6730d3de76ceecb6eadca4c1304a33 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 12:29:05 +0200 Subject: [PATCH 740/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/FocusSerial.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. This also merges the former `UPGRADING.md` into `doc/plugin/FocusSerial.md`. Signed-off-by: Gergely Nagy --- README.md | 98 +----------------- UPGRADING.md => doc/plugin/FocusSerial.md | 99 +++++++++++++++++++ src/Kaleidoscope-FocusSerial.h | 2 +- src/kaleidoscope/{ => plugin}/FocusSerial.cpp | 4 +- src/kaleidoscope/{ => plugin}/FocusSerial.h | 6 +- 5 files changed, 109 insertions(+), 100 deletions(-) rename UPGRADING.md => doc/plugin/FocusSerial.md (59%) rename src/kaleidoscope/{ => plugin}/FocusSerial.cpp (97%) rename src/kaleidoscope/{ => plugin}/FocusSerial.h (95%) diff --git a/README.md b/README.md index 1af8026d..027884b8 100644 --- a/README.md +++ b/README.md @@ -1,102 +1,8 @@ # Kaleidoscope-FocusSerial - [![Build Status][travis:image]][travis:status] +[![Build Status][travis:image]][travis:status] [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-FocusSerial.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-FocusSerial -Bidirectional communication for Kaleidoscope. With this plugin enabled, plugins that implement the `onFocusEvent` hook will start responding to Focus commands sent via `Serial`, allowing bidirectional communication between firmware and host. - -This plugin is an upgrade of the former [Kaleidoscope-Focus][kaleidoscope:focus] plugin. See [UPGRADING.md](UPGRADING.md) for information about how to transition to the new system. - - [kaleidoscope:focus]: https://github.com/keyboardio/Kaleidoscope-Focus - -## Using the plugin - -This plugin is **not** meant to be used by the end-user (apart from setting it up to use plugin-provided hooks), but by plugin authors instead. As an end user, you just need to use Focus-enabled plugins like you normally would, and once `FocusSerial` is enabled, their commands will be available too. - -Nevertheless, a very simple example is shown below: - -```c++ -#include -#include - -namespace kaleidoscope { -class FocusTestCommand : public Plugin { - public: - FocusTestCommand() {} - - EventHandlerResult onFocusEvent(const char *command) { - if (strcmp_P(command, PSTR("test")) != 0) - return EventHandlerResult::OK; - - Serial.println(F("Congratulations, the test command works!")); - return EventHandlerResult::EVENT_CONSUMED; - } -}; -} - -kaleidoscope::FocusTestCommand FocusTestCommand; - -KALEIDOSCOPE_INIT_PLUGINS(Focus, FocusTestCommand); - -void setup () { - Kaleidoscope.setup (); -} -``` - -## Plugin methods - -The plugin provides the `Focus` object, with a couple of helper methods aimed at developers. Documenting those is a work in progress for now. - -## Wire protocol - -`Focus` uses a simple, textual, request-response-based wire protocol. - -Each request has to be on one line, anything before the first space is the command part (if there is no space, just a newline, then the whole line will be considered a command), everything after are arguments. The plugin itself only parses until the end of the command part, argument parsing is left to the various hooks. If there is anything left on the line after hooks are done processing, it will be ignored. - -Responses can be multi-line, but most aren't. Their content is also up to the hooks, `Focus` does not enforce anything, except a trailing dot and a newline. Responses should end with a dot on its own line. - -Apart from these, there are no restrictions on what can go over the wire, but to make the experience consistent, find a few guidelines below: - -* Commands should be namespaced, so that the plugin name, or functionality comes first, then the sub-command or property. Such as `led.theme`, or `led.setAll`. -* One should not use setters and getters, but a single property command instead. One, which when called without arguments, will act as a getter, and as a setter otherwise. -* Namespaces should be lowercase, while the commands within them camel-case. -* Do as little work in the hooks as possible. While the protocol is human readable, the expectation is that tools will be used to interact with the keyboard. -* As such, keep formatting to the bare minimum. No fancy table-like responses. -* In general, the output of a getter should be copy-pasteable to a setter. - -These are merely guidelines, and there can be - and are - exceptions. Use your discretion when writing Focus hooks. - -### Example - -In the examples below, `<` denotes what the host sends to the keyboard, `>` what -the keyboard responds. - -``` -< test -> Congratulations, the test command works! -> . -``` - -``` -< help -> help -> test -> palette -> . -``` - -``` -< palette -> 0 0 0 128 128 128 255 255 255 -> . -< palette 0 0 0 128 128 128 255 255 255 -> . -``` - -## Further reading - -Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-FocusSerial/blob/master/examples/FocusSerial/FocusSerial.ino +See [doc/plugin/FocusSerial.md](doc/plugin/FocusSerial.md) for documentation. diff --git a/UPGRADING.md b/doc/plugin/FocusSerial.md similarity index 59% rename from UPGRADING.md rename to doc/plugin/FocusSerial.md index 351489a1..7680c73d 100644 --- a/UPGRADING.md +++ b/doc/plugin/FocusSerial.md @@ -1,3 +1,102 @@ +# Kaleidoscope-FocusSerial + +Bidirectional communication for Kaleidoscope. With this plugin enabled, plugins that implement the `onFocusEvent` hook will start responding to Focus commands sent via `Serial`, allowing bidirectional communication between firmware and host. + +This plugin is an upgrade of the former [Kaleidoscope-Focus][kaleidoscope:focus] plugin. See the [UPGRADING][upgrading] section for information about how to transition to the new system. + + [kaleidoscope:focus]: https://github.com/keyboardio/Kaleidoscope-Focus + [upgrading]: #upgrading-from-focus-to-onfocusevent--focusserial + +## Using the plugin + +This plugin is **not** meant to be used by the end-user (apart from setting it up to use plugin-provided hooks), but by plugin authors instead. As an end user, you just need to use Focus-enabled plugins like you normally would, and once `FocusSerial` is enabled, their commands will be available too. + +Nevertheless, a very simple example is shown below: + +```c++ +#include +#include + +namespace kaleidoscope { +class FocusTestCommand : public Plugin { + public: + FocusTestCommand() {} + + EventHandlerResult onFocusEvent(const char *command) { + if (strcmp_P(command, PSTR("test")) != 0) + return EventHandlerResult::OK; + + Serial.println(F("Congratulations, the test command works!")); + return EventHandlerResult::EVENT_CONSUMED; + } +}; +} + +kaleidoscope::FocusTestCommand FocusTestCommand; + +KALEIDOSCOPE_INIT_PLUGINS(Focus, FocusTestCommand); + +void setup () { + Kaleidoscope.setup (); +} +``` + +## Plugin methods + +The plugin provides the `Focus` object, with a couple of helper methods aimed at developers. Documenting those is a work in progress for now. + +## Wire protocol + +`Focus` uses a simple, textual, request-response-based wire protocol. + +Each request has to be on one line, anything before the first space is the command part (if there is no space, just a newline, then the whole line will be considered a command), everything after are arguments. The plugin itself only parses until the end of the command part, argument parsing is left to the various hooks. If there is anything left on the line after hooks are done processing, it will be ignored. + +Responses can be multi-line, but most aren't. Their content is also up to the hooks, `Focus` does not enforce anything, except a trailing dot and a newline. Responses should end with a dot on its own line. + +Apart from these, there are no restrictions on what can go over the wire, but to make the experience consistent, find a few guidelines below: + +* Commands should be namespaced, so that the plugin name, or functionality comes first, then the sub-command or property. Such as `led.theme`, or `led.setAll`. +* One should not use setters and getters, but a single property command instead. One, which when called without arguments, will act as a getter, and as a setter otherwise. +* Namespaces should be lowercase, while the commands within them camel-case. +* Do as little work in the hooks as possible. While the protocol is human readable, the expectation is that tools will be used to interact with the keyboard. +* As such, keep formatting to the bare minimum. No fancy table-like responses. +* In general, the output of a getter should be copy-pasteable to a setter. + +These are merely guidelines, and there can be - and are - exceptions. Use your discretion when writing Focus hooks. + +### Example + +In the examples below, `<` denotes what the host sends to the keyboard, `>` what +the keyboard responds. + +``` +< test +> Congratulations, the test command works! +> . +``` + +``` +< help +> help +> test +> palette +> . +``` + +``` +< palette +> 0 0 0 128 128 128 255 255 255 +> . +< palette 0 0 0 128 128 128 255 255 255 +> . +``` + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-FocusSerial/blob/master/examples/FocusSerial/FocusSerial.ino + Upgrading from Focus to onFocusEvent + FocusSerial ================================================== diff --git a/src/Kaleidoscope-FocusSerial.h b/src/Kaleidoscope-FocusSerial.h index 02e24f80..7eab4ff4 100644 --- a/src/Kaleidoscope-FocusSerial.h +++ b/src/Kaleidoscope-FocusSerial.h @@ -17,4 +17,4 @@ #pragma once -#include +#include diff --git a/src/kaleidoscope/FocusSerial.cpp b/src/kaleidoscope/plugin/FocusSerial.cpp similarity index 97% rename from src/kaleidoscope/FocusSerial.cpp rename to src/kaleidoscope/plugin/FocusSerial.cpp index 4bd1f5f1..9c240963 100644 --- a/src/kaleidoscope/FocusSerial.cpp +++ b/src/kaleidoscope/plugin/FocusSerial.cpp @@ -22,6 +22,7 @@ #endif namespace kaleidoscope { +namespace plugin { char FocusSerial::command_[32]; @@ -103,6 +104,7 @@ void FocusSerial::readColor(cRGB &color) { color.b = Serial.parseInt(); } +} } -kaleidoscope::FocusSerial Focus; +kaleidoscope::plugin::FocusSerial Focus; diff --git a/src/kaleidoscope/FocusSerial.h b/src/kaleidoscope/plugin/FocusSerial.h similarity index 95% rename from src/kaleidoscope/FocusSerial.h rename to src/kaleidoscope/plugin/FocusSerial.h index 827a1340..3f600c54 100644 --- a/src/kaleidoscope/FocusSerial.h +++ b/src/kaleidoscope/plugin/FocusSerial.h @@ -20,6 +20,7 @@ #include namespace kaleidoscope { +namespace plugin { class FocusSerial : public kaleidoscope::Plugin { public: FocusSerial(void) {} @@ -49,6 +50,7 @@ class FocusSerial : public kaleidoscope::Plugin { static void drain(void); }; -}; +} +} -extern kaleidoscope::FocusSerial Focus; +extern kaleidoscope::plugin::FocusSerial Focus; From b625eb0ae21ecc18105440fb4fdcb74121ee8020 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 12:29:08 +0200 Subject: [PATCH 741/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .gitignore | 4 - .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 7 files changed, 774 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.gitignore b/.gitignore deleted file mode 100644 index be16c9be..00000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.#* -*~ -/hardware/ -/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 027884b8..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-FocusSerial - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-FocusSerial.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-FocusSerial - -See [doc/plugin/FocusSerial.md](doc/plugin/FocusSerial.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 4946edac..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-FocusSerial -version=0.0.0 -author=Gergely Nagy -maintainer=Gergely Nagy -sentence=Bidirectional communication plugin for Kaleidoscope. -paragraph=... -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-FocusSerial -architectures=avr -dot_a_linkage=true From 6a5f8da4a310d5ddd1de8b87d35f394144080502 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 14:49:45 +0200 Subject: [PATCH 742/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/LED-AlphaSquare.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 101 +--------------- doc/plugin/LED-AlphaSquare.md | 109 ++++++++++++++++++ examples/LED-AlphaSquare/LED-AlphaSquare.ino | 8 +- src/Kaleidoscope-LED-AlphaSquare.h | 6 +- .../plugin}/AlphaSquare-Effect.cpp | 4 +- .../plugin}/AlphaSquare-Effect.h | 4 +- .../plugin}/AlphaSquare-Symbols.h | 8 +- .../plugin}/LED-AlphaSquare-3x4.h | 0 .../plugin}/LED-AlphaSquare-4x4.h | 0 .../plugin}/LED-AlphaSquare.cpp | 6 +- .../plugin}/LED-AlphaSquare.h | 4 +- 11 files changed, 137 insertions(+), 113 deletions(-) create mode 100644 doc/plugin/LED-AlphaSquare.md rename src/{Kaleidoscope => kaleidoscope/plugin}/AlphaSquare-Effect.cpp (96%) rename src/{Kaleidoscope => kaleidoscope/plugin}/AlphaSquare-Effect.h (93%) rename src/{Kaleidoscope => kaleidoscope/plugin}/AlphaSquare-Symbols.h (86%) rename src/{Kaleidoscope => kaleidoscope/plugin}/LED-AlphaSquare-3x4.h (100%) rename src/{Kaleidoscope => kaleidoscope/plugin}/LED-AlphaSquare-4x4.h (100%) rename src/{Kaleidoscope => kaleidoscope/plugin}/LED-AlphaSquare.cpp (95%) rename src/{Kaleidoscope => kaleidoscope/plugin}/LED-AlphaSquare.h (97%) diff --git a/README.md b/README.md index 57b10d64..469787f3 100644 --- a/README.md +++ b/README.md @@ -5,103 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare -An alphabet for your per-key LEDs, `AlphaSquare` provides a way to display 4x4 -"pixel" symbols on your keyboard. With this building block, one can build some -sweet animations, or just show off - the possibilities are almost endless! - -## Using the plugin - -To use the plugin, one needs to include the header in their Sketch, tell the -firmware to `use` the plugin, and one way or another, call the `display` method. -This can be done from a macro, or via the `AlphaSquareEffect` LED mode. - -```c++ -#include -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, - AlphaSquare, - AlphaSquareEffect); - -void setup() { - Kaleidoscope.setup(); - - AlphaSquare.display (Key_A); -} -``` - -## Plugin methods - -The plugin provides the `AlphaSquare` object, which has its methods and -properties listed below, and an `AlphaSquareEffect` LED mode, which has no -methods or properties other than those provided by all LED modes. - -### `.display(key)` -### `.display(key, col)` -### `.display(key, row, col)` -### `.display(key, row, col, color)` - -> Display the symbol for `key` at the given row or column, with pixels set to -> the specified `color`. If `row` is omitted, the first row - `0` is assumed. If -> the column is omitted, then the third column - `2` - is used. -> If the `color` is omitted, the plugin will use the global `.color` property. -> -> The plugin can display the English alphabet, and the numbers from 0 to 9. The -> symbol will be drawn with the top-left corner at the given position. -> -> Please consult the appropriate hardware library of your keyboard to see how -> keys are laid out in rows and columns. - -### `.display(symbol)` -### `.display(symbol, col)` -### `.display(symbol, row, col)` -### `.display(symbol, row, col, color)` - -> As the previous function, but instead of a key, it expects a 4x4 bitmap in -> the form of a 16-bit unsigned integer, where the low bit is the top-right -> corner, the second-lowest bit is to the right of that, and so on. -> -> The `SYM4x4` macro can be used to simplify creating these bitmaps. - -### `.clear(key)`, `.clear(symbol)` -### `.clear(key, col)`, `.clear(symbol, col)` -### `.clear(key, col, row)`, `.clear(symbol, col, row)` - -> Just like the `.display()` counterparts, except these clear the symbol, by -> turning the LED pixels it is made up from off. - -### `.color` - -> The color to use to draw the pixels. -> -> Defaults to `{ 0x80, 0x80, 0x80 }` (light gray). - -## Plugin helpers - -### `SYM4x4(...)` - -> A helper macro, which can be used to set up custom bitmaps. It expects 16 -> values, a 4x4 square of zeroes and ones. Zeroes are transparent pixels, ones -> will be colored. - -## Extra symbols - -There is a growing number of pre-defined symbols available in the -`kaleidoscope::alpha_square::symbols` namespace. Ok, growing may have been an -exaggeration, there is only one as of this writing: - -### `Lambda` - -> A lambda (`λ`) symbol. - -## Dependencies - -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) - -## Further reading - -Starting from the [example][plugin:example] is the recommended way of getting -started with the plugin. - - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-AlphaSquare/blob/master/examples/LED-AlphaSquare/LED-AlphaSquare.ino +See [doc/plugin/LED-AlphaSquare.md](doc/plugin/LED-AlphaSquare.md) for documentation. diff --git a/doc/plugin/LED-AlphaSquare.md b/doc/plugin/LED-AlphaSquare.md new file mode 100644 index 00000000..1bb0cb16 --- /dev/null +++ b/doc/plugin/LED-AlphaSquare.md @@ -0,0 +1,109 @@ +# Kaleidoscope-LED-AlphaSquare + +An alphabet for your per-key LEDs, `AlphaSquare` provides a way to display 4x4 +"pixel" symbols on your keyboard. With this building block, one can build some +sweet animations, or just show off - the possibilities are almost endless! + +## Using the plugin + +To use the plugin, one needs to include the header in their Sketch, tell the +firmware to `use` the plugin, and one way or another, call the `display` method. +This can be done from a macro, or via the `AlphaSquareEffect` LED mode. + +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + AlphaSquare, + AlphaSquareEffect); + +void setup() { + Kaleidoscope.setup(); + + AlphaSquare.display (Key_A); +} +``` + +## Plugin methods + +The plugin provides the `AlphaSquare` object, which has its methods and +properties listed below, and an `AlphaSquareEffect` LED mode, which has no +methods or properties other than those provided by all LED modes. + +### `.display(key)` +### `.display(key, col)` +### `.display(key, row, col)` +### `.display(key, row, col, color)` + +> Display the symbol for `key` at the given row or column, with pixels set to +> the specified `color`. If `row` is omitted, the first row - `0` is assumed. If +> the column is omitted, then the third column - `2` - is used. +> If the `color` is omitted, the plugin will use the global `.color` property. +> +> The plugin can display the English alphabet, and the numbers from 0 to 9. The +> symbol will be drawn with the top-left corner at the given position. +> +> Please consult the appropriate hardware library of your keyboard to see how +> keys are laid out in rows and columns. + +### `.display(symbol)` +### `.display(symbol, col)` +### `.display(symbol, row, col)` +### `.display(symbol, row, col, color)` + +> As the previous function, but instead of a key, it expects a 4x4 bitmap in +> the form of a 16-bit unsigned integer, where the low bit is the top-right +> corner, the second-lowest bit is to the right of that, and so on. +> +> The `SYM4x4` macro can be used to simplify creating these bitmaps. + +### `.clear(key)`, `.clear(symbol)` +### `.clear(key, col)`, `.clear(symbol, col)` +### `.clear(key, col, row)`, `.clear(symbol, col, row)` + +> Just like the `.display()` counterparts, except these clear the symbol, by +> turning the LED pixels it is made up from off. + +### `.color` + +> The color to use to draw the pixels. +> +> Defaults to `{ 0x80, 0x80, 0x80 }` (light gray). + +## Plugin helpers + +### `SYM4x4(...)` + +> A helper macro, which can be used to set up custom bitmaps. It expects 16 +> values, a 4x4 square of zeroes and ones. Zeroes are transparent pixels, ones +> will be colored. + +## Extra symbols + +There is a growing number of pre-defined symbols available in the +`kaleidoscope::plugin::alpha_square::symbols` namespace. Ok, growing may have +been an exaggeration, there is only one as of this writing: + +### `Lambda` + +> A lambda (`λ`) symbol. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-AlphaSquare/blob/master/examples/LED-AlphaSquare/LED-AlphaSquare.ino + +## Upgrading + +Former versions of the plugin used to have extra symbols in the +`kaleidoscope::alpha_square::symbols` namespace, while current versions have +them under `kaleidoscope::plugin::alpha_square::symbols`. The old name is +deprecated, and will be removed by 2019-01-14. diff --git a/examples/LED-AlphaSquare/LED-AlphaSquare.ino b/examples/LED-AlphaSquare/LED-AlphaSquare.ino index 5030ba8d..c4a3eb51 100644 --- a/examples/LED-AlphaSquare/LED-AlphaSquare.ino +++ b/examples/LED-AlphaSquare/LED-AlphaSquare.ino @@ -75,15 +75,15 @@ const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) { for (uint8_t step = 0; step <= 0xf0; step += 8) { AlphaSquare.color = { step, step, step }; - AlphaSquare.display(kaleidoscope::alpha_square::symbols::Lambda, 2); - AlphaSquare.display(kaleidoscope::alpha_square::symbols::Lambda, 10); + AlphaSquare.display(kaleidoscope::plugin::alpha_square::symbols::Lambda, 2); + AlphaSquare.display(kaleidoscope::plugin::alpha_square::symbols::Lambda, 10); delay(10); } for (uint8_t step = 0xff; step >= 8; step -= 8) { AlphaSquare.color = { step, step, step }; - AlphaSquare.display(kaleidoscope::alpha_square::symbols::Lambda, 2); - AlphaSquare.display(kaleidoscope::alpha_square::symbols::Lambda, 10); + AlphaSquare.display(kaleidoscope::plugin::alpha_square::symbols::Lambda, 2); + AlphaSquare.display(kaleidoscope::plugin::alpha_square::symbols::Lambda, 10); delay(10); } delay(100); diff --git a/src/Kaleidoscope-LED-AlphaSquare.h b/src/Kaleidoscope-LED-AlphaSquare.h index 9366536c..2d43bacf 100644 --- a/src/Kaleidoscope-LED-AlphaSquare.h +++ b/src/Kaleidoscope-LED-AlphaSquare.h @@ -17,6 +17,6 @@ #pragma once -#include -#include -#include +#include +#include +#include diff --git a/src/Kaleidoscope/AlphaSquare-Effect.cpp b/src/kaleidoscope/plugin/AlphaSquare-Effect.cpp similarity index 96% rename from src/Kaleidoscope/AlphaSquare-Effect.cpp rename to src/kaleidoscope/plugin/AlphaSquare-Effect.cpp index d5d343a5..025ec20d 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.cpp +++ b/src/kaleidoscope/plugin/AlphaSquare-Effect.cpp @@ -18,6 +18,7 @@ #include namespace kaleidoscope { +namespace plugin { uint16_t AlphaSquareEffect::length = 1000; uint32_t AlphaSquareEffect::end_time_left_, AlphaSquareEffect::end_time_right_; @@ -67,6 +68,7 @@ EventHandlerResult AlphaSquareEffect::onKeyswitchEvent(Key &mappedKey, byte row, return EventHandlerResult::OK; } +} } -kaleidoscope::AlphaSquareEffect AlphaSquareEffect; +kaleidoscope::plugin::AlphaSquareEffect AlphaSquareEffect; diff --git a/src/Kaleidoscope/AlphaSquare-Effect.h b/src/kaleidoscope/plugin/AlphaSquare-Effect.h similarity index 93% rename from src/Kaleidoscope/AlphaSquare-Effect.h rename to src/kaleidoscope/plugin/AlphaSquare-Effect.h index af9d4554..3227afdf 100644 --- a/src/Kaleidoscope/AlphaSquare-Effect.h +++ b/src/kaleidoscope/plugin/AlphaSquare-Effect.h @@ -21,6 +21,7 @@ #include namespace kaleidoscope { +namespace plugin { class AlphaSquareEffect : public LEDMode { public: AlphaSquareEffect(void) {} @@ -37,5 +38,6 @@ class AlphaSquareEffect : public LEDMode { static Key last_key_left_, last_key_right_; }; } +} -extern kaleidoscope::AlphaSquareEffect AlphaSquareEffect; +extern kaleidoscope::plugin::AlphaSquareEffect AlphaSquareEffect; diff --git a/src/Kaleidoscope/AlphaSquare-Symbols.h b/src/kaleidoscope/plugin/AlphaSquare-Symbols.h similarity index 86% rename from src/Kaleidoscope/AlphaSquare-Symbols.h rename to src/kaleidoscope/plugin/AlphaSquare-Symbols.h index 05b74566..e829a81d 100644 --- a/src/Kaleidoscope/AlphaSquare-Symbols.h +++ b/src/kaleidoscope/plugin/AlphaSquare-Symbols.h @@ -17,9 +17,10 @@ #pragma once -#include +#include namespace kaleidoscope { +namespace plugin { namespace alpha_square { namespace symbols { @@ -31,3 +32,8 @@ static constexpr uint16_t Lambda = SYM4x4(1, 0, 0, 0, } } } + +// Backwards compatibility +namespace alpha_square = kaleidoscope::plugin::alpha_square; + +} diff --git a/src/Kaleidoscope/LED-AlphaSquare-3x4.h b/src/kaleidoscope/plugin/LED-AlphaSquare-3x4.h similarity index 100% rename from src/Kaleidoscope/LED-AlphaSquare-3x4.h rename to src/kaleidoscope/plugin/LED-AlphaSquare-3x4.h diff --git a/src/Kaleidoscope/LED-AlphaSquare-4x4.h b/src/kaleidoscope/plugin/LED-AlphaSquare-4x4.h similarity index 100% rename from src/Kaleidoscope/LED-AlphaSquare-4x4.h rename to src/kaleidoscope/plugin/LED-AlphaSquare-4x4.h diff --git a/src/Kaleidoscope/LED-AlphaSquare.cpp b/src/kaleidoscope/plugin/LED-AlphaSquare.cpp similarity index 95% rename from src/Kaleidoscope/LED-AlphaSquare.cpp rename to src/kaleidoscope/plugin/LED-AlphaSquare.cpp index 3004ec48..a650c179 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.cpp +++ b/src/kaleidoscope/plugin/LED-AlphaSquare.cpp @@ -16,9 +16,10 @@ */ #include -#include +#include namespace kaleidoscope { +namespace plugin { static const uint16_t alphabet[] PROGMEM = { ALPHASQUARE_SYMBOL_A, @@ -94,6 +95,7 @@ void AlphaSquare::display(uint16_t symbol, uint8_t row, uint8_t col) { display(symbol, row, col, color); } +} } -kaleidoscope::AlphaSquare AlphaSquare; +kaleidoscope::plugin::AlphaSquare AlphaSquare; diff --git a/src/Kaleidoscope/LED-AlphaSquare.h b/src/kaleidoscope/plugin/LED-AlphaSquare.h similarity index 97% rename from src/Kaleidoscope/LED-AlphaSquare.h rename to src/kaleidoscope/plugin/LED-AlphaSquare.h index 1c602064..296a7ca7 100644 --- a/src/Kaleidoscope/LED-AlphaSquare.h +++ b/src/kaleidoscope/plugin/LED-AlphaSquare.h @@ -32,6 +32,7 @@ p30 << 12 | p31 << 13 | p32 << 14 | p33 << 15 ) namespace kaleidoscope { +namespace plugin { class AlphaSquare : public kaleidoscope::Plugin { public: AlphaSquare(void) {} @@ -77,6 +78,7 @@ class AlphaSquare : public kaleidoscope::Plugin { static cRGB color; }; +} } -extern kaleidoscope::AlphaSquare AlphaSquare; +extern kaleidoscope::plugin::AlphaSquare AlphaSquare; From 3767e5bb8f2c4aa8fa6b5c489a55f880385d680b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 14:56:41 +0200 Subject: [PATCH 743/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .gitignore | 4 - .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 7 files changed, 774 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.gitignore b/.gitignore deleted file mode 100644 index be16c9be..00000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.#* -*~ -/hardware/ -/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 469787f3..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-LED-AlphaSquare - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-AlphaSquare - -See [doc/plugin/LED-AlphaSquare.md](doc/plugin/LED-AlphaSquare.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index d67491b7..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-LED-AlphaSquare -version=0.0.0 -author=Gergely Nagy -maintainer=Gergely Nagy -sentence=4x4 pixel LED alphabet, to be used with Kaleidoscope. -paragraph=Includes a small, 4x4 font of alphanumerics, so you can have text on your keyboard LEDs. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-LED-AlphaSquare -architectures=avr -dot_a_linkage=true From 3a7be52642fd3ff623dae33ac8b4f5411e8bb904 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:31:22 +0200 Subject: [PATCH 744/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/LEDEffect-SolidColor.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 24 +----------- doc/plugin/LEDEffect-SolidColor.md | 33 ++++++++++++++++ src/Kaleidoscope-LEDEffect-SolidColor.h | 16 +------- .../plugin/LEDEffect-SolidColor.cpp} | 3 ++ .../plugin/LEDEffect-SolidColor.h | 39 +++++++++++++++++++ 5 files changed, 77 insertions(+), 38 deletions(-) create mode 100644 doc/plugin/LEDEffect-SolidColor.md rename src/{Kaleidoscope-LEDEffect-SolidColor.cpp => kaleidoscope/plugin/LEDEffect-SolidColor.cpp} (98%) create mode 100644 src/kaleidoscope/plugin/LEDEffect-SolidColor.h diff --git a/README.md b/README.md index 56ab1017..9fa01646 100644 --- a/README.md +++ b/README.md @@ -5,26 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-SolidColor.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-SolidColor -This plugin provides tools to build LED effects that set the entire keyboard to -a single color. For show, and for backlighting purposes. - -## Using the extension - -To use the plugin, include the header, declare an effect using the -`LEDSolidColor` class, and tell the firmware to use the new effect: - -```c++ -#include - -static LEDSolidColor solidRed(160, 0, 0); - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, solidRed); - -void setup() { - Kaleidoscope.setup(); -} -``` - -## Dependencies - -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +See [doc/plugin/LEDEffect-SolidColor.md](doc/plugin/LEDEffect-SolidColor.md) for documentation. diff --git a/doc/plugin/LEDEffect-SolidColor.md b/doc/plugin/LEDEffect-SolidColor.md new file mode 100644 index 00000000..d5036233 --- /dev/null +++ b/doc/plugin/LEDEffect-SolidColor.md @@ -0,0 +1,33 @@ +# Kaleidoscope-LEDEffect-SolidColor + +This plugin provides tools to build LED effects that set the entire keyboard to +a single color. For show, and for backlighting purposes. + +## Using the extension + +To use the plugin, include the header, declare an effect using the +`kaleidoscope::plugin::LEDSolidColor` class, and tell the firmware to use the +new effect: + +```c++ +#include + +static kaleidoscope::plugin::LEDSolidColor solidRed(160, 0, 0); + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, solidRed); + +void setup() { + Kaleidoscope.setup(); +} +``` + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) + +## Upgrading + +Previous versions of `LEDEffect-SolidColor` used `kaleidoscope::LEDSolidColor` +as a class for defining solid-color effects. This is called +`kaleidoscope::plugin::LEDSolidColor` now. The old name still works, but is +deprecated, and will be removed by 2019-01-14. diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.h b/src/Kaleidoscope-LEDEffect-SolidColor.h index d91d7553..1fc4259b 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.h +++ b/src/Kaleidoscope-LEDEffect-SolidColor.h @@ -16,18 +16,4 @@ #pragma once -#include "Kaleidoscope-LEDControl.h" - -namespace kaleidoscope { -class LEDSolidColor : public LEDMode { - public: - LEDSolidColor(uint8_t r, uint8_t g, uint8_t b); - - protected: - void onActivate(void) final; - void refreshAt(byte row, byte col) final; - - private: - uint8_t r, g, b; -}; -} +#include "kaleidoscope/plugin/LEDEffect-SolidColor.h" diff --git a/src/Kaleidoscope-LEDEffect-SolidColor.cpp b/src/kaleidoscope/plugin/LEDEffect-SolidColor.cpp similarity index 98% rename from src/Kaleidoscope-LEDEffect-SolidColor.cpp rename to src/kaleidoscope/plugin/LEDEffect-SolidColor.cpp index afbece7d..d030e86d 100644 --- a/src/Kaleidoscope-LEDEffect-SolidColor.cpp +++ b/src/kaleidoscope/plugin/LEDEffect-SolidColor.cpp @@ -17,6 +17,7 @@ #include "Kaleidoscope-LEDEffect-SolidColor.h" namespace kaleidoscope { +namespace plugin { LEDSolidColor::LEDSolidColor(uint8_t r, uint8_t g, uint8_t b) { this->r = r; this->g = g; @@ -30,4 +31,6 @@ void LEDSolidColor::onActivate(void) { void LEDSolidColor::refreshAt(byte row, byte col) { ::LEDControl.setCrgbAt(row, col, CRGB(r, g, b)); } + +} } diff --git a/src/kaleidoscope/plugin/LEDEffect-SolidColor.h b/src/kaleidoscope/plugin/LEDEffect-SolidColor.h new file mode 100644 index 00000000..b79bbf72 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDEffect-SolidColor.h @@ -0,0 +1,39 @@ +/* Kaleidoscope-LEDEffect-SolidColor - Solid color LED effects for Kaleidoscope. + * Copyright (C) 2017 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope-LEDControl.h" + +namespace kaleidoscope { +namespace plugin { +class LEDSolidColor : public LEDMode { + public: + LEDSolidColor(uint8_t r, uint8_t g, uint8_t b); + + protected: + void onActivate(void) final; + void refreshAt(byte row, byte col) final; + + private: + uint8_t r, g, b; +}; +} + +// Backwards compatibility +typedef plugin::LEDSolidColor LEDSolidColor; + +} From 21568c5859912711ad4a65c0528db59d4a54ea9f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:31:22 +0200 Subject: [PATCH 745/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 770 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 9fa01646..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-LEDEffect-SolidColor - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-SolidColor.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-SolidColor - -See [doc/plugin/LEDEffect-SolidColor.md](doc/plugin/LEDEffect-SolidColor.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index e9474c8e..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-LEDEffect-SolidColor -version=0.0.1 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=Solid color LED effects for Kaleidoscope. -paragraph=Tools to create solid-color LED effects. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-SolidColor -architectures=avr -dot_a_linkage=true From c27fbfa3e8007a30ab17470584314672331d057e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:38:00 +0200 Subject: [PATCH 746/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/Macros.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 182 +---------------- doc/plugin/Macros.md | 183 ++++++++++++++++++ src/Kaleidoscope-Macros.h | 63 +----- src/{ => kaleidoscope/plugin}/MacroKeyDefs.h | 0 src/{ => kaleidoscope/plugin}/MacroSteps.h | 0 .../plugin/Macros.cpp} | 23 ++- src/kaleidoscope/plugin/Macros.h | 86 ++++++++ 7 files changed, 286 insertions(+), 251 deletions(-) create mode 100644 doc/plugin/Macros.md rename src/{ => kaleidoscope/plugin}/MacroKeyDefs.h (100%) rename src/{ => kaleidoscope/plugin}/MacroSteps.h (100%) rename src/{Kaleidoscope-Macros.cpp => kaleidoscope/plugin/Macros.cpp} (92%) create mode 100644 src/kaleidoscope/plugin/Macros.h diff --git a/README.md b/README.md index 9f5dc8a8..4c2b8024 100644 --- a/README.md +++ b/README.md @@ -5,184 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-Macros.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-Macros -Macros are a standard feature on many keyboards and Kaleidoscope-powered ones -are no exceptions. Macros are a way to have a single key-press do a whole lot of -things under the hood: conventionally, macros play back a key sequence, but with -Kaleidoscope, there is much more we can do. Nevertheless, playing back a -sequence of events is still the primary use of macros. - -Playing back a sequence means that when we press a macro key, we can have it -play pretty much any sequence. It can type some text for us, or invoke a -complicated shortcut - the possibilities are endless! - -In Kaleidoscope, macros are implemented via this plugin. You can define upto 256 macros. - -## Using the plugin - -To use the plugin, we need to include the header, tell the firmware to `use` the -plugin, place macros on the keymap, and create a special handler function -(`macroAction`) that will tell the plugin what shall happen when macro keys are -pressed. It is best illustrated with an example: - -```c++ -#include -#include - -// Give a name to the macros! -enum { - MACRO_MODEL01, - MACRO_HELLO, - MACRO_SPECIAL, -}; - -// Somewhere in the keymap: -M(MACRO_MODEL01), M(MACRO_HELLO), M(MACRO_SPECIAL) - -// later in the Sketch: -const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { - switch (macroIndex) { - case MACRO_MODEL01: - return MACRODOWN(I(25), - D(LeftShift), T(M), U(LeftShift), T(O), T(D), T(E), T(L), - T(Spacebar), - W(100), - T(0), T(1) ); - case MACRO_HELLO: - if (keyToggledOn(keyState)) { - return Macros.type(PSTR("Hello "), PSTR("world!")); - } - break; - case MACRO_SPECIAL: - if (keyToggledOn(keyState)) { - // Do something special - } - break; - } - return MACRO_NONE; -} - -KALEIDOSCOPE_INIT_PLUGINS(Macros); - -void setup() { - Kaleidoscope.setup (); -} -``` - -## Keymap markup - -### `M(id)` - -> Places a macro key on the keymap, with the `id` number (0 to 255) as identifier. Whenever this key -> has to be handled, the `macroAction` overrideable function will be called, -> with the identifier and key state as arguments. -> -> It is recommended to give a *name* to macro ids, by using an `enum`. - -## Plugin methods - -The plugin provides a `Macros` object, with the following methods and properties available: - -### `.play(macro)` - -> Plays back a macro, where a macro is a sequence created with the `MACRO()` -> helper discussed below. This method will be used by the plugin to play back -> the result of the `macroAction()` method, but is used rarely otherwise. -> -> The `macro` argument must be a sequence created with the `MACRO()` helper! - -### `.type(strings...)` - -> In cases where we only want to type some strings, it is far more convenient to -> use this method: we do not have to use the `MACRO()` helper, but just give -> this one a set of strings, and it will type them for us on the keyboard. We -> can use as many strings as we want, and all of them will be typed in order. -> -> Each string is limited to a sequence of printable ASCII characters. No -> international symbols, or unicode, or anything like it: just plain ASCII. -> -> Each of `strings` arguments must also reside in program memory, and the -> easiest way to do that is to wrap the string in a `PSTR()` helper. See the -> program code at the beginning of this documentation for an example! - -### `.row`, `.col` - -> The `row` and `col` properties describe the physical position a macro was -> triggered from if it was triggered by a key. The playback functions -> do not use these properties, but they are available, would one want to create -> a macro that needs to know which key triggered it. -> -> When the macro was not triggered by a key the value of these properties are -> unspecified. - -## Macro helpers - -Macros need to be able to simulate key down and key up events for any key - even -keys that may not be on the keymap otherwise. For this reason and others, we -need to define them in a special way, using the `MACRO` helper (or its -`MACRODOWN()` variant, see below): - -### `MACRO(steps...)` - -> Defines a macro, that is built up from `steps` (explained below). The plugin -> will iterate through the sequence, and re-play the steps in order. -> -> Note: In older versions of the Macros plugin, the sequence of steps had to end -> with a special step called END. This is no longer required. Existing macros -> that end with END will still work correctly, but new code should not use END; -> usage of END is deprecated. - -### `MACRODOWN(steps...)` - -> The same as the `MACRO()` helper above, but it will create a special sequence, -> where the steps are only played back when the triggering key was just pressed. -> That is, the macro will not be performed when the key is released, or held, or -> not pressed at all. -> -> Use this over `MACRO()` when you only want to perform an action when the key -> actuates, and no action should be taken when it is held, released, or when it -> is not pressed at all. For a lot of macros that emit a sequence without any -> other side effects, `MACRODOWN()` is usually the better choice. -> -> Can only be used from the `macroAction()` overrideable method. - -## `MACRO` steps - -Macro steps can be divided into two groups: - -### Delays - -* `I(millis)`: Sets the interval between steps to `millis`. By default, there is - no delay between steps, and they are played back as fast as possible. Useful - when we want to see the macro being typed, or need to slow it down, to allow - the host to process it. -* `W(millis)`: Waits for `millis` milliseconds. For dramatic effects. - -### Key events - -Key event steps have three variants: one that prefixes its argument with `Key_`, -one that does not, and a third that allows for a more compact - but also more -limited - representation. The first are the `D`, `U`, and `T` variants, the -second are `Dr`, `Ur`, and `Tr`, and the last variant are `Dc`, `Uc`, and `Tc`. -In most cases, one is likely use normal keys for the steps, so the `D`, `U`, and -`T` steps apply the `Key_` prefix. This allows us to write `MACRO(T(X))` instead -of `MACRO(Tr(Key_X))` - making the macro definition shorter, and more readable. - -The compact variant (`Dc`, `Uc`, and `Tc`) prefix the argument with `Key_` too, -but unlike `D`, `U`, and `T`, they ignore the `flags` component of the key, and -as such, are limited to ordinary keys. Mouse keys, consumer- or system keys are -not supported by this compact representation. - -* `D(key)`, `Dr(key)`, `Dc(key)`: Simulates a key being pressed (pushed down). -* `U(key)`, `Ur(key)`, `Uc(key)`: Simulates a key being released (going up). -* `T(key)`, `Tr(key)`, `Tc(key)`: Simulates a key being tapped (pressed first, then released). - -## Overrideable methods - -### `macroAction(macroIndex, keyState)` - -> The `macroAction` method is the brain of the macro support in Kaleidoscope: -> this function tells the plugin what sequence to play when given a macro index -> and a key state. -> -> It should return a macro sequence, or `MACRO_NONE` if nothing is to be played -> back. +See [doc/plugin/Macros.md](doc/plugin/Macros.md) for documentation. diff --git a/doc/plugin/Macros.md b/doc/plugin/Macros.md new file mode 100644 index 00000000..0fdd07b3 --- /dev/null +++ b/doc/plugin/Macros.md @@ -0,0 +1,183 @@ +# Kaleidoscope-Macros + +Macros are a standard feature on many keyboards and Kaleidoscope-powered ones +are no exceptions. Macros are a way to have a single key-press do a whole lot of +things under the hood: conventionally, macros play back a key sequence, but with +Kaleidoscope, there is much more we can do. Nevertheless, playing back a +sequence of events is still the primary use of macros. + +Playing back a sequence means that when we press a macro key, we can have it +play pretty much any sequence. It can type some text for us, or invoke a +complicated shortcut - the possibilities are endless! + +In Kaleidoscope, macros are implemented via this plugin. You can define upto 256 macros. + +## Using the plugin + +To use the plugin, we need to include the header, tell the firmware to `use` the +plugin, place macros on the keymap, and create a special handler function +(`macroAction`) that will tell the plugin what shall happen when macro keys are +pressed. It is best illustrated with an example: + +```c++ +#include +#include + +// Give a name to the macros! +enum { + MACRO_MODEL01, + MACRO_HELLO, + MACRO_SPECIAL, +}; + +// Somewhere in the keymap: +M(MACRO_MODEL01), M(MACRO_HELLO), M(MACRO_SPECIAL) + +// later in the Sketch: +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { + switch (macroIndex) { + case MACRO_MODEL01: + return MACRODOWN(I(25), + D(LeftShift), T(M), U(LeftShift), T(O), T(D), T(E), T(L), + T(Spacebar), + W(100), + T(0), T(1) ); + case MACRO_HELLO: + if (keyToggledOn(keyState)) { + return Macros.type(PSTR("Hello "), PSTR("world!")); + } + break; + case MACRO_SPECIAL: + if (keyToggledOn(keyState)) { + // Do something special + } + break; + } + return MACRO_NONE; +} + +KALEIDOSCOPE_INIT_PLUGINS(Macros); + +void setup() { + Kaleidoscope.setup (); +} +``` + +## Keymap markup + +### `M(id)` + +> Places a macro key on the keymap, with the `id` number (0 to 255) as identifier. Whenever this key +> has to be handled, the `macroAction` overrideable function will be called, +> with the identifier and key state as arguments. +> +> It is recommended to give a *name* to macro ids, by using an `enum`. + +## Plugin methods + +The plugin provides a `Macros` object, with the following methods and properties available: + +### `.play(macro)` + +> Plays back a macro, where a macro is a sequence created with the `MACRO()` +> helper discussed below. This method will be used by the plugin to play back +> the result of the `macroAction()` method, but is used rarely otherwise. +> +> The `macro` argument must be a sequence created with the `MACRO()` helper! + +### `.type(strings...)` + +> In cases where we only want to type some strings, it is far more convenient to +> use this method: we do not have to use the `MACRO()` helper, but just give +> this one a set of strings, and it will type them for us on the keyboard. We +> can use as many strings as we want, and all of them will be typed in order. +> +> Each string is limited to a sequence of printable ASCII characters. No +> international symbols, or unicode, or anything like it: just plain ASCII. +> +> Each of `strings` arguments must also reside in program memory, and the +> easiest way to do that is to wrap the string in a `PSTR()` helper. See the +> program code at the beginning of this documentation for an example! + +### `.row`, `.col` + +> The `row` and `col` properties describe the physical position a macro was +> triggered from if it was triggered by a key. The playback functions +> do not use these properties, but they are available, would one want to create +> a macro that needs to know which key triggered it. +> +> When the macro was not triggered by a key the value of these properties are +> unspecified. + +## Macro helpers + +Macros need to be able to simulate key down and key up events for any key - even +keys that may not be on the keymap otherwise. For this reason and others, we +need to define them in a special way, using the `MACRO` helper (or its +`MACRODOWN()` variant, see below): + +### `MACRO(steps...)` + +> Defines a macro, that is built up from `steps` (explained below). The plugin +> will iterate through the sequence, and re-play the steps in order. +> +> Note: In older versions of the Macros plugin, the sequence of steps had to end +> with a special step called END. This is no longer required. Existing macros +> that end with END will still work correctly, but new code should not use END; +> usage of END is deprecated. + +### `MACRODOWN(steps...)` + +> The same as the `MACRO()` helper above, but it will create a special sequence, +> where the steps are only played back when the triggering key was just pressed. +> That is, the macro will not be performed when the key is released, or held, or +> not pressed at all. +> +> Use this over `MACRO()` when you only want to perform an action when the key +> actuates, and no action should be taken when it is held, released, or when it +> is not pressed at all. For a lot of macros that emit a sequence without any +> other side effects, `MACRODOWN()` is usually the better choice. +> +> Can only be used from the `macroAction()` overrideable method. + +## `MACRO` steps + +Macro steps can be divided into two groups: + +### Delays + +* `I(millis)`: Sets the interval between steps to `millis`. By default, there is + no delay between steps, and they are played back as fast as possible. Useful + when we want to see the macro being typed, or need to slow it down, to allow + the host to process it. +* `W(millis)`: Waits for `millis` milliseconds. For dramatic effects. + +### Key events + +Key event steps have three variants: one that prefixes its argument with `Key_`, +one that does not, and a third that allows for a more compact - but also more +limited - representation. The first are the `D`, `U`, and `T` variants, the +second are `Dr`, `Ur`, and `Tr`, and the last variant are `Dc`, `Uc`, and `Tc`. +In most cases, one is likely use normal keys for the steps, so the `D`, `U`, and +`T` steps apply the `Key_` prefix. This allows us to write `MACRO(T(X))` instead +of `MACRO(Tr(Key_X))` - making the macro definition shorter, and more readable. + +The compact variant (`Dc`, `Uc`, and `Tc`) prefix the argument with `Key_` too, +but unlike `D`, `U`, and `T`, they ignore the `flags` component of the key, and +as such, are limited to ordinary keys. Mouse keys, consumer- or system keys are +not supported by this compact representation. + +* `D(key)`, `Dr(key)`, `Dc(key)`: Simulates a key being pressed (pushed down). +* `U(key)`, `Ur(key)`, `Uc(key)`: Simulates a key being released (going up). +* `T(key)`, `Tr(key)`, `Tc(key)`: Simulates a key being tapped (pressed first, then released). + +## Overrideable methods + +### `macroAction(macroIndex, keyState)` + +> The `macroAction` method is the brain of the macro support in Kaleidoscope: +> this function tells the plugin what sequence to play when given a macro index +> and a key state. +> +> It should return a macro sequence, or `MACRO_NONE` if nothing is to be played +> back. diff --git a/src/Kaleidoscope-Macros.h b/src/Kaleidoscope-Macros.h index a2fda6fd..0aa76885 100644 --- a/src/Kaleidoscope-Macros.h +++ b/src/Kaleidoscope-Macros.h @@ -16,65 +16,4 @@ #pragma once -#include - -#include "MacroKeyDefs.h" -#include "MacroSteps.h" - -const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); - -#if !defined(MAX_CONCURRENT_MACROS) -#define MAX_CONCURRENT_MACROS 8 -#endif - -struct MacroKeyEvent { - byte key_code; - byte key_id; - byte key_state; -}; - -class Macros_ : public kaleidoscope::Plugin { - public: - Macros_(void) {} - - static MacroKeyEvent active_macros[MAX_CONCURRENT_MACROS]; - static byte active_macro_count; - static void addActiveMacroKey(byte key_code, byte key_id, byte key_state) { - // If we've got too many active macros, give up: - if (active_macro_count >= MAX_CONCURRENT_MACROS) { - return; - } - active_macros[active_macro_count].key_code = key_code; - active_macros[active_macro_count].key_id = key_id; - active_macros[active_macro_count].key_state = key_state; - ++active_macro_count; - } - - kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); - kaleidoscope::EventHandlerResult beforeReportingState(); - kaleidoscope::EventHandlerResult afterEachCycle(); - - void play(const macro_t *macro_p); - - /* What follows below, is a bit of template magic that allows us to use - Macros.type() with any number of arguments, without having to use a - sentinel. See the comments on Kaleidoscope.use() for more details - this is - the same trick. - */ - inline const macro_t *type() { - return MACRO_NONE; - } - const macro_t *type(const char *string); - template - const macro_t *type(const char *first, Strings&&... strings) { - type(first); - return type(strings...); - } - - static byte row, col; - - private: - Key lookupAsciiCode(uint8_t ascii_code); -}; - -extern Macros_ Macros; +#include "kaleidoscope/plugin/Macros.h" diff --git a/src/MacroKeyDefs.h b/src/kaleidoscope/plugin/MacroKeyDefs.h similarity index 100% rename from src/MacroKeyDefs.h rename to src/kaleidoscope/plugin/MacroKeyDefs.h diff --git a/src/MacroSteps.h b/src/kaleidoscope/plugin/MacroSteps.h similarity index 100% rename from src/MacroSteps.h rename to src/kaleidoscope/plugin/MacroSteps.h diff --git a/src/Kaleidoscope-Macros.cpp b/src/kaleidoscope/plugin/Macros.cpp similarity index 92% rename from src/Kaleidoscope-Macros.cpp rename to src/kaleidoscope/plugin/Macros.cpp index 985eed8b..de67e540 100644 --- a/src/Kaleidoscope-Macros.cpp +++ b/src/kaleidoscope/plugin/Macros.cpp @@ -22,6 +22,9 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { return MACRO_NONE; } +namespace kaleidoscope { +namespace plugin { + MacroKeyEvent Macros_::active_macros[]; byte Macros_::active_macro_count; byte Macros_::row, Macros_::col; @@ -95,6 +98,7 @@ void Macros_::play(const macro_t *macro_p) { delay(interval); } } + static const Key ascii_to_key_map[] PROGMEM = { // 0x21 - 0x30 LSHIFT(Key_1), @@ -201,23 +205,23 @@ const macro_t *Macros_::type(const char *string) { return MACRO_NONE; } -kaleidoscope::EventHandlerResult Macros_::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { +EventHandlerResult Macros_::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_MACRO)) - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; byte key_id = (row * COLS) + col; addActiveMacroKey(mappedKey.keyCode, key_id, keyState); - return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; + return EventHandlerResult::EVENT_CONSUMED; } -kaleidoscope::EventHandlerResult Macros_::afterEachCycle() { +EventHandlerResult Macros_::afterEachCycle() { active_macro_count = 0; - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; } -kaleidoscope::EventHandlerResult Macros_::beforeReportingState() { +EventHandlerResult Macros_::beforeReportingState() { for (byte i = 0; i < active_macro_count; ++i) { if (active_macros[i].key_id == 0xFF) { // i.e. UNKNOWN_KEYSWITCH_LOCATION @@ -231,7 +235,10 @@ kaleidoscope::EventHandlerResult Macros_::beforeReportingState() { active_macros[i].key_state); Macros.play(m); } - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; +} + +} } -Macros_ Macros; +kaleidoscope::plugin::Macros_ Macros; diff --git a/src/kaleidoscope/plugin/Macros.h b/src/kaleidoscope/plugin/Macros.h new file mode 100644 index 00000000..fb514731 --- /dev/null +++ b/src/kaleidoscope/plugin/Macros.h @@ -0,0 +1,86 @@ +/* Kaleidoscope-Macros - Macro keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include + +#include "MacroKeyDefs.h" +#include "MacroSteps.h" + +const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); + +#if !defined(MAX_CONCURRENT_MACROS) +#define MAX_CONCURRENT_MACROS 8 +#endif + +struct MacroKeyEvent { + byte key_code; + byte key_id; + byte key_state; +}; + +namespace kaleidoscope { +namespace plugin { + +class Macros_ : public kaleidoscope::Plugin { + public: + Macros_(void) {} + + static MacroKeyEvent active_macros[MAX_CONCURRENT_MACROS]; + static byte active_macro_count; + static void addActiveMacroKey(byte key_code, byte key_id, byte key_state) { + // If we've got too many active macros, give up: + if (active_macro_count >= MAX_CONCURRENT_MACROS) { + return; + } + active_macros[active_macro_count].key_code = key_code; + active_macros[active_macro_count].key_id = key_id; + active_macros[active_macro_count].key_state = key_state; + ++active_macro_count; + } + + EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); + EventHandlerResult beforeReportingState(); + EventHandlerResult afterEachCycle(); + + void play(const macro_t *macro_p); + + /* What follows below, is a bit of template magic that allows us to use + Macros.type() with any number of arguments, without having to use a + sentinel. See the comments on Kaleidoscope.use() for more details - this is + the same trick. + */ + inline const macro_t *type() { + return MACRO_NONE; + } + const macro_t *type(const char *string); + template + const macro_t *type(const char *first, Strings&&... strings) { + type(first); + return type(strings...); + } + + static byte row, col; + + private: + Key lookupAsciiCode(uint8_t ascii_code); +}; + +} +} + +extern kaleidoscope::plugin::Macros_ Macros; From 6e941150f9df0d1720781e3d8d79374e4c7ae9af Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:38:00 +0200 Subject: [PATCH 747/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 770 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 4c2b8024..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-Macros - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-Macros.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-Macros - -See [doc/plugin/Macros.md](doc/plugin/Macros.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index af4a0447..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-Macros -version=0.0.1 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=Macro keys for Kaleidoscope. -paragraph=Macro keys and supporting functions for Kaleidoscope. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-Macros -architectures=avr -dot_a_linkage=true From 3130555de31ae4eafe8bd770dacd887a82cf4166 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 13:01:07 +0200 Subject: [PATCH 748/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/Model01-TestMode.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 8 +++ src/Kaleidoscope-Model01-TestMode.h | 32 +---------- .../plugin/Model01-TestMode.cpp} | 38 +++++++------ src/kaleidoscope/plugin/Model01-TestMode.h | 53 +++++++++++++++++++ 4 files changed, 83 insertions(+), 48 deletions(-) create mode 100644 README.md rename src/{Kaleidoscope-Model01-TestMode.cpp => kaleidoscope/plugin/Model01-TestMode.cpp} (85%) create mode 100644 src/kaleidoscope/plugin/Model01-TestMode.h diff --git a/README.md b/README.md new file mode 100644 index 00000000..130e6b67 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Kaleidoscope-Model01-TestMode + +[![Build Status][travis:image]][travis:status] + + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-Model01-TestMode.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-Model01-TestMode + +See [doc/plugin/Model01-TestMode.md](doc/plugin/Model01-TestMode.md) for documentation. diff --git a/src/Kaleidoscope-Model01-TestMode.h b/src/Kaleidoscope-Model01-TestMode.h index 59576643..55ed92cb 100644 --- a/src/Kaleidoscope-Model01-TestMode.h +++ b/src/Kaleidoscope-Model01-TestMode.h @@ -16,34 +16,4 @@ #pragma once -#ifndef ARDUINO_AVR_MODEL01 -#error The Kaleidoscope-Model01-TestMode plugin was designed for the Keyboardio Model01, and does not work with any other hardware. -#endif - -#include -#include "Kaleidoscope.h" - -typedef struct { - uint8_t cyclesSinceStateChange[32]; - uint32_t badKeys; - -} side_data_t; -class TestMode_ : public kaleidoscope::Plugin { - public: - TestMode_(void) {}; - - kaleidoscope::EventHandlerResult beforeReportingState(); - - private: - static void run_tests(); - static void test_leds(); - static void testMatrix(); - static void toggle_programming_leds_on(); - static void handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset); - static void waitForKeypress(); - static void set_leds(cRGB color); -}; - -extern TestMode_ TestMode; - -Key handleKeyswitchEvent_test(Key mappedKey, byte row, byte col, uint8_t keyState); +#include "kaleidoscope/plugin/Model01-TestMode.h" diff --git a/src/Kaleidoscope-Model01-TestMode.cpp b/src/kaleidoscope/plugin/Model01-TestMode.cpp similarity index 85% rename from src/Kaleidoscope-Model01-TestMode.cpp rename to src/kaleidoscope/plugin/Model01-TestMode.cpp index 9689dfb0..b7bf3cce 100644 --- a/src/Kaleidoscope-Model01-TestMode.cpp +++ b/src/kaleidoscope/plugin/Model01-TestMode.cpp @@ -18,6 +18,8 @@ #include "Kaleidoscope-Model01-TestMode.h" #include "Kaleidoscope-LEDEffect-Rainbow.h" +namespace kaleidoscope { +namespace plugin { constexpr uint8_t CHATTER_CYCLE_LIMIT = 30; constexpr uint8_t TOGGLED_OFF = 2; @@ -25,18 +27,17 @@ constexpr uint8_t TOGGLED_ON = 1; constexpr uint8_t HELD = 3; constexpr uint8_t RELEASED = 0; - -kaleidoscope::EventHandlerResult TestMode_::beforeReportingState() { +EventHandlerResult TestMode::beforeReportingState() { if (KeyboardHardware.isKeyswitchPressed(R0C0) && KeyboardHardware.isKeyswitchPressed(R0C6) && KeyboardHardware.isKeyswitchPressed(R3C6) && KeyboardHardware.pressedKeyswitchCount() == 3) { run_tests(); } - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; } -void TestMode_::waitForKeypress() { +void TestMode::waitForKeypress() { for (uint8_t temp = 0; temp < 8; temp++) { KeyboardHardware.readMatrix(); } @@ -50,13 +51,13 @@ void TestMode_::waitForKeypress() { } } -void TestMode_::set_leds(cRGB color) { - LEDControl.set_all_leds_to(color); - LEDControl.syncLeds(); +void TestMode::set_leds(cRGB color) { + ::LEDControl.set_all_leds_to(color); + ::LEDControl.syncLeds(); waitForKeypress(); } -void TestMode_::test_leds(void) { +void TestMode::test_leds(void) { constexpr cRGB red = CRGB(201, 0, 0); constexpr cRGB blue = CRGB(0, 0, 201); constexpr cRGB green = CRGB(0, 201, 0); @@ -72,15 +73,15 @@ void TestMode_::test_leds(void) { set_leds(brightWhite); // rainbow for 10 seconds for (auto i = 0; i < 1000; i++) { - LEDRainbowEffect.update(); - LEDControl.syncLeds(); + ::LEDRainbowEffect.update(); + ::LEDControl.syncLeds(); } waitForKeypress(); } -void TestMode_::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset) { +void TestMode::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset) { constexpr cRGB red = CRGB(201, 0, 0); constexpr cRGB blue = CRGB(0, 0, 201); @@ -117,13 +118,13 @@ void TestMode_::handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t } -void TestMode_::testMatrix() { +void TestMode::testMatrix() { // Reset bad keys from previous tests. side_data_t left = {{0}, 0}; side_data_t right = {{0}, 0}; - LEDControl.set_all_leds_to(200, 0, 0); + ::LEDControl.set_all_leds_to(200, 0, 0); // Clear out the key event buffer so we don't get messed up information from // taps during LED test mode. while (1) { @@ -140,16 +141,16 @@ void TestMode_::testMatrix() { handleKeyEvent(&right, &(KeyboardHardware.previousRightHandState), &(KeyboardHardware.rightHandState), row, col, 15); } } - LEDControl.syncLeds(); + ::LEDControl.syncLeds(); } } -void TestMode_::toggle_programming_leds_on() { +void TestMode::toggle_programming_leds_on() { PORTD |= (1 << 5); PORTB |= (1 << 0); } -void TestMode_::run_tests() { +void TestMode::run_tests() { // Serial.println("Running tests"); toggle_programming_leds_on(); // Disable debouncing @@ -159,4 +160,7 @@ void TestMode_::run_tests() { // Serial.println("Done running tests"); } -TestMode_ TestMode; +} +} + +kaleidoscope::plugin::TestMode TestMode; diff --git a/src/kaleidoscope/plugin/Model01-TestMode.h b/src/kaleidoscope/plugin/Model01-TestMode.h new file mode 100644 index 00000000..a3cbae0c --- /dev/null +++ b/src/kaleidoscope/plugin/Model01-TestMode.h @@ -0,0 +1,53 @@ +/* Kaleidoscope-Model01-TestMode - A factory test mode for the Model 01. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#ifndef ARDUINO_AVR_MODEL01 +#error The Kaleidoscope-Model01-TestMode plugin was designed for the Keyboardio Model01, and does not work with any other hardware. +#endif + +#include +#include "Kaleidoscope.h" + +namespace kaleidoscope { +namespace plugin { + +class TestMode : public kaleidoscope::Plugin { + public: + typedef struct { + uint8_t cyclesSinceStateChange[32]; + uint32_t badKeys; + + } side_data_t; + + TestMode(void) {}; + + EventHandlerResult beforeReportingState(); + + private: + static void run_tests(); + static void test_leds(); + static void testMatrix(); + static void toggle_programming_leds_on(); + static void handleKeyEvent(side_data_t *side, keydata_t *oldState, keydata_t *newState, uint8_t row, uint8_t col, uint8_t col_offset); + static void waitForKeypress(); + static void set_leds(cRGB color); +}; +} +} + +extern kaleidoscope::plugin::TestMode TestMode; From b4704b35ecb84226b758041ad532ebedb5b7114e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 13:01:07 +0200 Subject: [PATCH 749/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 770 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 130e6b67..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-Model01-TestMode - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-Model01-TestMode.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-Model01-TestMode - -See [doc/plugin/Model01-TestMode.md](doc/plugin/Model01-TestMode.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 3255a9b6..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-Model01-TestMode -version=0.0.0 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=A factory test mode for the Model 01. -paragraph=A special mode for the Model 01 to help factory workers test the Model 01 during assembly. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-Model01-TestMode -architectures=avr -dot_a_linkage=true From c5afab550478c721ce906a7059e2651261585523 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 13:22:45 +0200 Subject: [PATCH 750/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/Hardware-Model01.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 9 +- doc/plugin/Hardware-Model01.md | 7 + src/Kaleidoscope-Hardware-Model01.h | 298 +--------------- .../hardware/Model01.cpp} | 6 + src/kaleidoscope/hardware/Model01.h | 322 ++++++++++++++++++ 5 files changed, 341 insertions(+), 301 deletions(-) create mode 100644 doc/plugin/Hardware-Model01.md rename src/{Kaleidoscope-Hardware-Model01.cpp => kaleidoscope/hardware/Model01.cpp} (99%) create mode 100644 src/kaleidoscope/hardware/Model01.h diff --git a/README.md b/README.md index b0b985b8..fd0ae525 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Kaleidoscope-Hardware-Model01 -This is a plugin for [Kaleidoscope][fw], that adds hardware support for -the [Keyboardio Model01][kbdio:model01]. +[![Build Status][travis:image]][travis:status] - [fw]: https://github.com/keyboardio/Kaleidoscope - [kbdio:model01]: https://shop.keyboard.io/ + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-Hardware-Model01.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-Hardware-Model01 + +See [doc/plugin/Hardware-Model01.md](doc/plugin/Hardware-Model01.md) for documentation. diff --git a/doc/plugin/Hardware-Model01.md b/doc/plugin/Hardware-Model01.md new file mode 100644 index 00000000..b0b985b8 --- /dev/null +++ b/doc/plugin/Hardware-Model01.md @@ -0,0 +1,7 @@ +# Kaleidoscope-Hardware-Model01 + +This is a plugin for [Kaleidoscope][fw], that adds hardware support for +the [Keyboardio Model01][kbdio:model01]. + + [fw]: https://github.com/keyboardio/Kaleidoscope + [kbdio:model01]: https://shop.keyboard.io/ diff --git a/src/Kaleidoscope-Hardware-Model01.h b/src/Kaleidoscope-Hardware-Model01.h index 187d4df7..5671a34d 100644 --- a/src/Kaleidoscope-Hardware-Model01.h +++ b/src/Kaleidoscope-Hardware-Model01.h @@ -17,300 +17,4 @@ #pragma once -#include - -#define HARDWARE_IMPLEMENTATION Model01 -#include "Kaleidoscope-HIDAdaptor-KeyboardioHID.h" -#include "KeyboardioScanner.h" - -#include "macro_helpers.h" - -#define COLS 16 -#define ROWS 4 - -#define CRGB(r,g,b) (cRGB){b, g, r} - -class Model01 { - public: - Model01(void); - void syncLeds(void); - void setCrgbAt(byte row, byte col, cRGB color); - void setCrgbAt(uint8_t i, cRGB crgb); - cRGB getCrgbAt(uint8_t i); - uint8_t getLedIndex(byte row, byte col); - - void scanMatrix(void); - void readMatrix(void); - void actOnMatrixScan(void); - void setup(); - void rebootBootloader(); - - - /** Detaching from / attaching to the host. - * - * These two functions should detach the device from (or attach it to) the - * host, preferably without rebooting the device. Their purpose is to allow - * one to do some configuration inbetween, so the re-attach happens with - * different properties. The device remains powered between these operations, - * only the connection to the host gets severed. - */ - void detachFromHost(); - void attachToHost(); - - /* These public functions are things supported by the Model 01, but - * aren't necessarily part of the Kaleidoscope API - */ - void enableHighPowerLeds(void); - void enableScannerPower(void); - void setKeyscanInterval(uint8_t interval); - boolean ledPowerFault(void); - - /* Key masking - * ----------- - * - * There are situations when one wants to ignore key events for a while, and - * mask them out. These functions help do that. In isolation, they do nothing, - * plugins and the core firmware is expected to make use of these. - * - * See `handleKeyswitchEvent` in the Kaleidoscope sources for a use-case. - */ - void maskKey(byte row, byte col); - void unMaskKey(byte row, byte col); - bool isKeyMasked(byte row, byte col); - void maskHeldKeys(void); - - /** Key switch states - * - * These methods offer a way to peek at the key switch states, for those cases - * where we need to deal with the state closest to the hardware. Some methods - * offer a way to check if a key is pressed, others return the number of - * pressed keys. - */ - /** - * Check if a key is pressed at a given position. - * - * @param row is the row the key is located at in the matrix. - * @param col is the column the key is located at in the matrix. - * - * @returns true if the key is pressed, false otherwise. - */ - bool isKeyswitchPressed(byte row, byte col); - /** - * Check if a key is pressed at a given position. - * - * @param keyIndex is the key index, as calculated by `keyIndex`. - * - * @note Key indexes start at 1, not 0! - * - * @returns true if the key is pressed, false otherwise. - */ - bool isKeyswitchPressed(uint8_t keyIndex); - /** - * Check the number of key switches currently pressed. - * - * @returns the number of keys pressed. - */ - uint8_t pressedKeyswitchCount(); - - keydata_t leftHandState; - keydata_t rightHandState; - keydata_t previousLeftHandState; - keydata_t previousRightHandState; - - private: - static void actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos); - - static bool isLEDChanged; - static KeyboardioScanner leftHand; - static KeyboardioScanner rightHand; - - static keydata_t leftHandMask; - static keydata_t rightHandMask; -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -/* To be used by the hardware implementations, `keyIndex` tells us the index of - * a key, from which we can figure out the row and column as needed. The index - * starts at one, so that plugins that work with a list of key indexes can use - * zero as a sentinel. This is important, because when we initialize arrays with - * fewer elements than the declared array size, the remaining elements will be - * zero. We can use this to avoid having to explicitly add a sentinel in - * user-facing code. - */ -constexpr byte keyIndex(byte row, byte col) { - return row * COLS + col + 1; -} - -constexpr byte R0C0 = keyIndex(0, 0); -constexpr byte R0C1 = keyIndex(0, 1); -constexpr byte R0C2 = keyIndex(0, 2); -constexpr byte R0C3 = keyIndex(0, 3); -constexpr byte R0C4 = keyIndex(0, 4); -constexpr byte R0C5 = keyIndex(0, 5); -constexpr byte R0C6 = keyIndex(0, 6); -constexpr byte R0C7 = keyIndex(0, 7); -constexpr byte R1C0 = keyIndex(1, 0); -constexpr byte R1C1 = keyIndex(1, 1); -constexpr byte R1C2 = keyIndex(1, 2); -constexpr byte R1C3 = keyIndex(1, 3); -constexpr byte R1C4 = keyIndex(1, 4); -constexpr byte R1C5 = keyIndex(1, 5); -constexpr byte R1C6 = keyIndex(1, 6); -constexpr byte R1C7 = keyIndex(1, 7); -constexpr byte R2C0 = keyIndex(2, 0); -constexpr byte R2C1 = keyIndex(2, 1); -constexpr byte R2C2 = keyIndex(2, 2); -constexpr byte R2C3 = keyIndex(2, 3); -constexpr byte R2C4 = keyIndex(2, 4); -constexpr byte R2C5 = keyIndex(2, 5); -constexpr byte R2C6 = keyIndex(2, 6); -constexpr byte R2C7 = keyIndex(2, 7); -constexpr byte R3C0 = keyIndex(3, 0); -constexpr byte R3C1 = keyIndex(3, 1); -constexpr byte R3C2 = keyIndex(3, 2); -constexpr byte R3C3 = keyIndex(3, 3); -constexpr byte R3C4 = keyIndex(3, 4); -constexpr byte R3C5 = keyIndex(3, 5); -constexpr byte R3C6 = keyIndex(3, 6); -constexpr byte R3C7 = keyIndex(3, 7); - -constexpr byte R0C8 = keyIndex(0, 8); -constexpr byte R0C9 = keyIndex(0, 9); -constexpr byte R0C10 = keyIndex(0, 10); -constexpr byte R0C11 = keyIndex(0, 11); -constexpr byte R0C12 = keyIndex(0, 12); -constexpr byte R0C13 = keyIndex(0, 13); -constexpr byte R0C14 = keyIndex(0, 15); -constexpr byte R0C15 = keyIndex(0, 16); -constexpr byte R1C8 = keyIndex(1, 8); -constexpr byte R1C9 = keyIndex(1, 9); -constexpr byte R1C10 = keyIndex(1, 10); -constexpr byte R1C11 = keyIndex(1, 11); -constexpr byte R1C12 = keyIndex(1, 12); -constexpr byte R1C13 = keyIndex(1, 13); -constexpr byte R1C14 = keyIndex(1, 14); -constexpr byte R1C15 = keyIndex(1, 15); -constexpr byte R2C8 = keyIndex(2, 8); -constexpr byte R2C9 = keyIndex(2, 9); -constexpr byte R2C10 = keyIndex(2, 10); -constexpr byte R2C11 = keyIndex(2, 11); -constexpr byte R2C12 = keyIndex(2, 12); -constexpr byte R2C13 = keyIndex(2, 13); -constexpr byte R2C14 = keyIndex(2, 14); -constexpr byte R2C15 = keyIndex(2, 15); -constexpr byte R3C8 = keyIndex(3, 8); -constexpr byte R3C9 = keyIndex(3, 9); -constexpr byte R3C10 = keyIndex(3, 10); -constexpr byte R3C11 = keyIndex(3, 11); -constexpr byte R3C12 = keyIndex(3, 12); -constexpr byte R3C13 = keyIndex(3, 13); -constexpr byte R3C14 = keyIndex(3, 14); -constexpr byte R3C15 = keyIndex(3, 15); - - -#define LED_COUNT 64 - - -#define LED_PGDN 0 -#define LED_PGUP 1 -#define LED_BACKTICK 2 -#define LED_PROG 3 -#define LED_1 4 -#define LED_Q 5 -#define LED_A 6 -#define LED_Z 7 -#define LED_X 8 -#define LED_S 9 -#define LED_W 10 -#define LED_2 11 -#define LED_3 12 -#define LED_E 13 -#define LED_D 14 -#define LED_C 15 -#define LED_V 16 -#define LED_F 17 -#define LED_R 18 -#define LED_4 19 -#define LED_5 20 -#define LED_T 21 -#define LED_G 22 -#define LED_B 23 -#define LED_ESC 24 -#define LED_TAB 25 -#define LED_LED 26 -#define LED_L_CTRL 27 -#define LED_BKSP 28 -#define LED_CMD 29 -#define LED_L_SHIFT 30 -#define LED_L_FN 31 -#define LED_R_FN 32 -#define LED_R_SHIFT 33 -#define LED_ALT 34 -#define LED_SPACE 35 -#define LED_R_CTRL 36 -#define LED_ANY 37 -#define LED_RETURN 38 -#define LED_BUTTERFLY 39 -#define LED_N 40 -#define LED_H 41 -#define LED_Y 42 -#define LED_6 43 -#define LED_7 44 -#define LED_U 45 -#define LED_J 46 -#define LED_M 47 -#define LED_COMMA 48 -#define LED_K 49 -#define LED_I 50 -#define LED_8 51 -#define LED_9 52 -#define LED_O 53 -#define LED_L 54 -#define LED_PERIOD 55 -#define LED_SLASH 56 -#define LED_SEMICOLON 57 -#define LED_P 58 -#define LED_0 59 -#define LED_NUM 60 -#define LED_EQUALS 61 -#define LED_APOSTROPHE 62 -#define LED_MINUS 63 - -#endif /* DOXYGEN_SHOULD_SKIP_THIS */ - - -#define KEYMAP_STACKED( \ - r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, \ - r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, \ - r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, \ - r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r2c6, \ - r0c7, r1c7, r2c7, r3c7, \ - r3c6, \ - \ - r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15, \ - r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15, \ - r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, \ - r2c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, \ - r3c8, r2c8, r1c8, r0c8, \ - r3c9, ...) \ - { \ - {r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c7, r0c8, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15}, \ - {r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15}, \ - {r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15}, \ - {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, RESTRICT_ARGS_COUNT((r3c15), 64, KEYMAP_STACKED, ##__VA_ARGS__)}, \ - } - -#define KEYMAP( \ - r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15, \ - r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15, \ - r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, \ - r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r2c6, r2c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, \ - r0c7, r1c7, r2c7, r3c7, r3c8, r2c8, r1c8, r0c8, \ - r3c6, r3c9, ...) \ - { \ - {r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c7, r0c8, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15}, \ - {r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15}, \ - {r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15}, \ - {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, RESTRICT_ARGS_COUNT((r3c15), 64, KEYMAP, ##__VA_ARGS__)}, \ - } +#include "kaleidoscope/hardware/Model01.h" diff --git a/src/Kaleidoscope-Hardware-Model01.cpp b/src/kaleidoscope/hardware/Model01.cpp similarity index 99% rename from src/Kaleidoscope-Hardware-Model01.cpp rename to src/kaleidoscope/hardware/Model01.cpp index 51f8f92b..7c9dc4c0 100644 --- a/src/Kaleidoscope-Hardware-Model01.cpp +++ b/src/kaleidoscope/hardware/Model01.cpp @@ -19,6 +19,9 @@ #include #include +namespace kaleidoscope { +namespace hardware { + KeyboardioScanner Model01::leftHand(0); KeyboardioScanner Model01::rightHand(3); bool Model01::isLEDChanged = true; @@ -307,4 +310,7 @@ uint8_t Model01::pressedKeyswitchCount() { return __builtin_popcountl(leftHandState.all) + __builtin_popcountl(rightHandState.all); } +} +} + HARDWARE_IMPLEMENTATION KeyboardHardware; diff --git a/src/kaleidoscope/hardware/Model01.h b/src/kaleidoscope/hardware/Model01.h new file mode 100644 index 00000000..4d7c585f --- /dev/null +++ b/src/kaleidoscope/hardware/Model01.h @@ -0,0 +1,322 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Hardware-Model01 -- Keyboard.io Model01 hardware support for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include + +#define HARDWARE_IMPLEMENTATION kaleidoscope::hardware::Model01 +#include "Kaleidoscope-HIDAdaptor-KeyboardioHID.h" +#include "KeyboardioScanner.h" + +#include "macro_helpers.h" + +#define COLS 16 +#define ROWS 4 + +#define CRGB(r,g,b) (cRGB){b, g, r} + +namespace kaleidoscope { +namespace hardware { + +class Model01 { + public: + Model01(void); + void syncLeds(void); + void setCrgbAt(byte row, byte col, cRGB color); + void setCrgbAt(uint8_t i, cRGB crgb); + cRGB getCrgbAt(uint8_t i); + uint8_t getLedIndex(byte row, byte col); + + void scanMatrix(void); + void readMatrix(void); + void actOnMatrixScan(void); + void setup(); + void rebootBootloader(); + + + /** Detaching from / attaching to the host. + * + * These two functions should detach the device from (or attach it to) the + * host, preferably without rebooting the device. Their purpose is to allow + * one to do some configuration inbetween, so the re-attach happens with + * different properties. The device remains powered between these operations, + * only the connection to the host gets severed. + */ + void detachFromHost(); + void attachToHost(); + + /* These public functions are things supported by the Model 01, but + * aren't necessarily part of the Kaleidoscope API + */ + void enableHighPowerLeds(void); + void enableScannerPower(void); + void setKeyscanInterval(uint8_t interval); + boolean ledPowerFault(void); + + /* Key masking + * ----------- + * + * There are situations when one wants to ignore key events for a while, and + * mask them out. These functions help do that. In isolation, they do nothing, + * plugins and the core firmware is expected to make use of these. + * + * See `handleKeyswitchEvent` in the Kaleidoscope sources for a use-case. + */ + void maskKey(byte row, byte col); + void unMaskKey(byte row, byte col); + bool isKeyMasked(byte row, byte col); + void maskHeldKeys(void); + + /** Key switch states + * + * These methods offer a way to peek at the key switch states, for those cases + * where we need to deal with the state closest to the hardware. Some methods + * offer a way to check if a key is pressed, others return the number of + * pressed keys. + */ + /** + * Check if a key is pressed at a given position. + * + * @param row is the row the key is located at in the matrix. + * @param col is the column the key is located at in the matrix. + * + * @returns true if the key is pressed, false otherwise. + */ + bool isKeyswitchPressed(byte row, byte col); + /** + * Check if a key is pressed at a given position. + * + * @param keyIndex is the key index, as calculated by `keyIndex`. + * + * @note Key indexes start at 1, not 0! + * + * @returns true if the key is pressed, false otherwise. + */ + bool isKeyswitchPressed(uint8_t keyIndex); + /** + * Check the number of key switches currently pressed. + * + * @returns the number of keys pressed. + */ + uint8_t pressedKeyswitchCount(); + + keydata_t leftHandState; + keydata_t rightHandState; + keydata_t previousLeftHandState; + keydata_t previousRightHandState; + + private: + static void actOnHalfRow(byte row, byte colState, byte colPrevState, byte startPos); + + static bool isLEDChanged; + static KeyboardioScanner leftHand; + static KeyboardioScanner rightHand; + + static keydata_t leftHandMask; + static keydata_t rightHandMask; +}; + +} +} + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +/* To be used by the hardware implementations, `keyIndex` tells us the index of + * a key, from which we can figure out the row and column as needed. The index + * starts at one, so that plugins that work with a list of key indexes can use + * zero as a sentinel. This is important, because when we initialize arrays with + * fewer elements than the declared array size, the remaining elements will be + * zero. We can use this to avoid having to explicitly add a sentinel in + * user-facing code. + */ +constexpr byte keyIndex(byte row, byte col) { + return row * COLS + col + 1; +} + +constexpr byte R0C0 = keyIndex(0, 0); +constexpr byte R0C1 = keyIndex(0, 1); +constexpr byte R0C2 = keyIndex(0, 2); +constexpr byte R0C3 = keyIndex(0, 3); +constexpr byte R0C4 = keyIndex(0, 4); +constexpr byte R0C5 = keyIndex(0, 5); +constexpr byte R0C6 = keyIndex(0, 6); +constexpr byte R0C7 = keyIndex(0, 7); +constexpr byte R1C0 = keyIndex(1, 0); +constexpr byte R1C1 = keyIndex(1, 1); +constexpr byte R1C2 = keyIndex(1, 2); +constexpr byte R1C3 = keyIndex(1, 3); +constexpr byte R1C4 = keyIndex(1, 4); +constexpr byte R1C5 = keyIndex(1, 5); +constexpr byte R1C6 = keyIndex(1, 6); +constexpr byte R1C7 = keyIndex(1, 7); +constexpr byte R2C0 = keyIndex(2, 0); +constexpr byte R2C1 = keyIndex(2, 1); +constexpr byte R2C2 = keyIndex(2, 2); +constexpr byte R2C3 = keyIndex(2, 3); +constexpr byte R2C4 = keyIndex(2, 4); +constexpr byte R2C5 = keyIndex(2, 5); +constexpr byte R2C6 = keyIndex(2, 6); +constexpr byte R2C7 = keyIndex(2, 7); +constexpr byte R3C0 = keyIndex(3, 0); +constexpr byte R3C1 = keyIndex(3, 1); +constexpr byte R3C2 = keyIndex(3, 2); +constexpr byte R3C3 = keyIndex(3, 3); +constexpr byte R3C4 = keyIndex(3, 4); +constexpr byte R3C5 = keyIndex(3, 5); +constexpr byte R3C6 = keyIndex(3, 6); +constexpr byte R3C7 = keyIndex(3, 7); + +constexpr byte R0C8 = keyIndex(0, 8); +constexpr byte R0C9 = keyIndex(0, 9); +constexpr byte R0C10 = keyIndex(0, 10); +constexpr byte R0C11 = keyIndex(0, 11); +constexpr byte R0C12 = keyIndex(0, 12); +constexpr byte R0C13 = keyIndex(0, 13); +constexpr byte R0C14 = keyIndex(0, 15); +constexpr byte R0C15 = keyIndex(0, 16); +constexpr byte R1C8 = keyIndex(1, 8); +constexpr byte R1C9 = keyIndex(1, 9); +constexpr byte R1C10 = keyIndex(1, 10); +constexpr byte R1C11 = keyIndex(1, 11); +constexpr byte R1C12 = keyIndex(1, 12); +constexpr byte R1C13 = keyIndex(1, 13); +constexpr byte R1C14 = keyIndex(1, 14); +constexpr byte R1C15 = keyIndex(1, 15); +constexpr byte R2C8 = keyIndex(2, 8); +constexpr byte R2C9 = keyIndex(2, 9); +constexpr byte R2C10 = keyIndex(2, 10); +constexpr byte R2C11 = keyIndex(2, 11); +constexpr byte R2C12 = keyIndex(2, 12); +constexpr byte R2C13 = keyIndex(2, 13); +constexpr byte R2C14 = keyIndex(2, 14); +constexpr byte R2C15 = keyIndex(2, 15); +constexpr byte R3C8 = keyIndex(3, 8); +constexpr byte R3C9 = keyIndex(3, 9); +constexpr byte R3C10 = keyIndex(3, 10); +constexpr byte R3C11 = keyIndex(3, 11); +constexpr byte R3C12 = keyIndex(3, 12); +constexpr byte R3C13 = keyIndex(3, 13); +constexpr byte R3C14 = keyIndex(3, 14); +constexpr byte R3C15 = keyIndex(3, 15); + + +#define LED_COUNT 64 + + +#define LED_PGDN 0 +#define LED_PGUP 1 +#define LED_BACKTICK 2 +#define LED_PROG 3 +#define LED_1 4 +#define LED_Q 5 +#define LED_A 6 +#define LED_Z 7 +#define LED_X 8 +#define LED_S 9 +#define LED_W 10 +#define LED_2 11 +#define LED_3 12 +#define LED_E 13 +#define LED_D 14 +#define LED_C 15 +#define LED_V 16 +#define LED_F 17 +#define LED_R 18 +#define LED_4 19 +#define LED_5 20 +#define LED_T 21 +#define LED_G 22 +#define LED_B 23 +#define LED_ESC 24 +#define LED_TAB 25 +#define LED_LED 26 +#define LED_L_CTRL 27 +#define LED_BKSP 28 +#define LED_CMD 29 +#define LED_L_SHIFT 30 +#define LED_L_FN 31 +#define LED_R_FN 32 +#define LED_R_SHIFT 33 +#define LED_ALT 34 +#define LED_SPACE 35 +#define LED_R_CTRL 36 +#define LED_ANY 37 +#define LED_RETURN 38 +#define LED_BUTTERFLY 39 +#define LED_N 40 +#define LED_H 41 +#define LED_Y 42 +#define LED_6 43 +#define LED_7 44 +#define LED_U 45 +#define LED_J 46 +#define LED_M 47 +#define LED_COMMA 48 +#define LED_K 49 +#define LED_I 50 +#define LED_8 51 +#define LED_9 52 +#define LED_O 53 +#define LED_L 54 +#define LED_PERIOD 55 +#define LED_SLASH 56 +#define LED_SEMICOLON 57 +#define LED_P 58 +#define LED_0 59 +#define LED_NUM 60 +#define LED_EQUALS 61 +#define LED_APOSTROPHE 62 +#define LED_MINUS 63 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ + + +#define KEYMAP_STACKED( \ + r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, \ + r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, \ + r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, \ + r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r2c6, \ + r0c7, r1c7, r2c7, r3c7, \ + r3c6, \ + \ + r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15, \ + r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15, \ + r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, \ + r2c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, \ + r3c8, r2c8, r1c8, r0c8, \ + r3c9, ...) \ + { \ + {r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c7, r0c8, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15}, \ + {r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15}, \ + {r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15}, \ + {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, RESTRICT_ARGS_COUNT((r3c15), 64, KEYMAP_STACKED, ##__VA_ARGS__)}, \ + } + +#define KEYMAP( \ + r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15, \ + r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15, \ + r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, \ + r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r2c6, r2c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, \ + r0c7, r1c7, r2c7, r3c7, r3c8, r2c8, r1c8, r0c8, \ + r3c6, r3c9, ...) \ + { \ + {r0c0, r0c1, r0c2, r0c3, r0c4, r0c5, r0c6, r0c7, r0c8, r0c9, r0c10, r0c11, r0c12, r0c13, r0c14, r0c15}, \ + {r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15}, \ + {r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15}, \ + {r3c0, r3c1, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, RESTRICT_ARGS_COUNT((r3c15), 64, KEYMAP, ##__VA_ARGS__)}, \ + } From 379106527eb9360f961069e339509490ba481b1d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 13:22:51 +0200 Subject: [PATCH 751/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 9 - 6 files changed, 769 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index fd0ae525..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-Hardware-Model01 - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-Hardware-Model01.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-Hardware-Model01 - -See [doc/plugin/Hardware-Model01.md](doc/plugin/Hardware-Model01.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 9bdf34cf..00000000 --- a/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=Kaleidoscope-Hardware-Model01 -version=0.0.1 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=Keyboardio Model01 Hardware support for Kaleidoscope. -paragraph=... -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-Hardware-Model01 -architectures=avr From c974039771135aae120365dc551670b9d7773dcb Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 11:49:24 +0200 Subject: [PATCH 752/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/LEDEffect-BootGreeting.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 145 +---------------- doc/plugin/LEDEffect-BootGreeting.md | 146 ++++++++++++++++++ .../LEDEffect-BootGreeting.ino | 3 +- src/Kaleidoscope-LEDEffect-BootGreeting.h | 27 +--- .../plugin/LEDEffect-BootGreeting.cpp} | 5 +- .../plugin/LEDEffect-BootGreeting.h | 47 ++++++ 6 files changed, 199 insertions(+), 174 deletions(-) create mode 100644 doc/plugin/LEDEffect-BootGreeting.md rename src/{Kaleidoscope-LEDEffect-BootGreeting.cpp => kaleidoscope/plugin/LEDEffect-BootGreeting.cpp} (96%) create mode 100644 src/kaleidoscope/plugin/LEDEffect-BootGreeting.h diff --git a/README.md b/README.md index 61f261ce..2d57b177 100644 --- a/README.md +++ b/README.md @@ -5,147 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-BootGreeting.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-BootGreeting -If you want to have your keyboard signal when it turns on, but you don't want to -use any more complicated LED modes, this plugin is for you. It will make the -`LEDEffectNext` key on your keymap slowly breathe for about ten seconds after -plugging the keyboard in (without blocking the normal functionality of the -keyboard, of course). - -## Using the plugin - -To use the plugin, include the header, and tell `Kaleidoscope` to use the plugin: - -```c++ -#include -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, - BootGreetingEffect - LEDOff); - -void setup() { - Kaleidoscope.setup(); -} -``` - -You may also set optional parameters. - -### Specify by search key -```c++ -#include -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, - BootGreetingEffect - LEDOff); - -void setup() { - Kaleidoscope.setup(); - - BootGreetingEffect.search_key = Key_M; -} -``` - -### Specify by position -```c++ -#include -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, - BootGreetingEffect - LEDOff); - -void setup() { - Kaleidoscope.setup(); - - //Butterfly key - BootGreetingEffect.key_col = 7; - BootGreetingEffect.key_row = 3; -} -``` - -### Specify longer timeout -```c++ -#include -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, - BootGreetingEffect - LEDOff); - -void setup() { - Kaleidoscope.setup(); - - //Butterfly key - BootGreetingEffect.timeout = 15000; -} -``` - -### Specify different color -```c++ -#include -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, - BootGreetingEffect - LEDOff); - -void setup() { - Kaleidoscope.setup(); - - //Butterfly key - BootGreetingEffect.hue = 90; - - Kaleidoscope.setup(); -} -``` - -## Plugin methods - -The plugin provides the `BootGreetingEffect` object, with the following methods and -properties: - -### `.search_key` - -> Set the key in the current keymap that should be activated with the pulsing -> LED on startup. The plugin will search from the top left to the bottom right -> of the keyboard, row by row, to find this key. The first matching key will -> be selected. -> -> Defaults to `Key_LEDEffectNext` - -### `.key_row` - -> This is an optional override to explicitly set the selected key by exact row -> and column. This number is 0-indexed, so the top row is 0, the second row is -> 1, etc. Must set `.key_col` property for this feature to be enabled. - -### `.key_col` - -> This is an optional override to explicitly set the selected key by exact row -> and column. This number is 0-indexed, so the left-most column is 0, the -> second column is 1, etc. Must set `.key_row` property for this feature to -> be enabled. - -### `.timeout` - -> This property specifies the timeout (in milliseconds) for the effect to last. -> When the keyboard is first connected, the pulsing LED effect will last for -> this duration before turning off. -> -> Defaults to `9200` ms. - -### `.hue` - -> This property sets the color hue that the LED pulsing effect. -> -> The default is `170`, which is a blue color. - -## Dependencies - -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +See [doc/plugin/LEDEffect-BootGreeting.md](doc/plugin/LEDEffect-BootGreeting.md) for documentation. diff --git a/doc/plugin/LEDEffect-BootGreeting.md b/doc/plugin/LEDEffect-BootGreeting.md new file mode 100644 index 00000000..29c8e5a2 --- /dev/null +++ b/doc/plugin/LEDEffect-BootGreeting.md @@ -0,0 +1,146 @@ +# Kaleidoscope-LEDEffect-BootGreeting + +If you want to have your keyboard signal when it turns on, but you don't want to +use any more complicated LED modes, this plugin is for you. It will make the +`LEDEffectNext` key on your keymap slowly breathe for about ten seconds after +plugging the keyboard in (without blocking the normal functionality of the +keyboard, of course). + +## Using the plugin + +To use the plugin, include the header, and tell `Kaleidoscope` to use the plugin: + +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); + +void setup() { + Kaleidoscope.setup(); +} +``` + +You may also set optional parameters. + +### Specify by search key +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); + +void setup() { + Kaleidoscope.setup(); + + BootGreetingEffect.search_key = Key_M; +} +``` + +### Specify by position +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); + +void setup() { + Kaleidoscope.setup(); + + //Butterfly key + BootGreetingEffect.key_col = 7; + BootGreetingEffect.key_row = 3; +} +``` + +### Specify longer timeout +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); + +void setup() { + Kaleidoscope.setup(); + + //Butterfly key + BootGreetingEffect.timeout = 15000; +} +``` + +### Specify different color +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + BootGreetingEffect + LEDOff); + +void setup() { + Kaleidoscope.setup(); + + //Butterfly key + BootGreetingEffect.hue = 90; + + Kaleidoscope.setup(); +} +``` + +## Plugin methods + +The plugin provides the `BootGreetingEffect` object, with the following methods and +properties: + +### `.search_key` + +> Set the key in the current keymap that should be activated with the pulsing +> LED on startup. The plugin will search from the top left to the bottom right +> of the keyboard, row by row, to find this key. The first matching key will +> be selected. +> +> Defaults to `Key_LEDEffectNext` + +### `.key_row` + +> This is an optional override to explicitly set the selected key by exact row +> and column. This number is 0-indexed, so the top row is 0, the second row is +> 1, etc. Must set `.key_col` property for this feature to be enabled. + +### `.key_col` + +> This is an optional override to explicitly set the selected key by exact row +> and column. This number is 0-indexed, so the left-most column is 0, the +> second column is 1, etc. Must set `.key_row` property for this feature to +> be enabled. + +### `.timeout` + +> This property specifies the timeout (in milliseconds) for the effect to last. +> When the keyboard is first connected, the pulsing LED effect will last for +> this duration before turning off. +> +> Defaults to `9200` ms. + +### `.hue` + +> This property sets the color hue that the LED pulsing effect. +> +> The default is `170`, which is a blue color. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) diff --git a/examples/LEDEffect-BootGreeting/LEDEffect-BootGreeting.ino b/examples/LEDEffect-BootGreeting/LEDEffect-BootGreeting.ino index a539a3c0..a7ad3224 100644 --- a/examples/LEDEffect-BootGreeting/LEDEffect-BootGreeting.ino +++ b/examples/LEDEffect-BootGreeting/LEDEffect-BootGreeting.ino @@ -16,10 +16,9 @@ */ #include +#include #include -#include "LED-Off.h" - // *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { [0] = KEYMAP_STACKED diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.h b/src/Kaleidoscope-LEDEffect-BootGreeting.h index ebf9facb..a08ef1c9 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.h +++ b/src/Kaleidoscope-LEDEffect-BootGreeting.h @@ -17,29 +17,4 @@ #pragma once -#include "Kaleidoscope-LEDControl.h" - -namespace kaleidoscope { -class BootGreetingEffect : public kaleidoscope::Plugin { - public: - BootGreetingEffect(void) {} - BootGreetingEffect(byte, byte); - - static byte key_row; - static byte key_col; - static Key search_key; - static uint8_t hue; - static uint16_t timeout; - - EventHandlerResult afterEachCycle(); - - private: - static void findLed(void); - static bool done_; - static byte row_; - static byte col_; - static uint16_t start_time; -}; -} - -extern kaleidoscope::BootGreetingEffect BootGreetingEffect; +#include "kaleidoscope/plugin/LEDEffect-BootGreeting.h" diff --git a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp b/src/kaleidoscope/plugin/LEDEffect-BootGreeting.cpp similarity index 96% rename from src/Kaleidoscope-LEDEffect-BootGreeting.cpp rename to src/kaleidoscope/plugin/LEDEffect-BootGreeting.cpp index 6a6ccf19..ac435c0f 100644 --- a/src/Kaleidoscope-LEDEffect-BootGreeting.cpp +++ b/src/kaleidoscope/plugin/LEDEffect-BootGreeting.cpp @@ -16,9 +16,9 @@ */ #include "Kaleidoscope-LEDEffect-BootGreeting.h" -#include "LEDUtils.h" namespace kaleidoscope { +namespace plugin { bool BootGreetingEffect::done_ = false; byte BootGreetingEffect::row_; @@ -88,6 +88,7 @@ EventHandlerResult BootGreetingEffect::afterEachCycle() { return EventHandlerResult::OK; } +} } -kaleidoscope::BootGreetingEffect BootGreetingEffect; +kaleidoscope::plugin::BootGreetingEffect BootGreetingEffect; diff --git a/src/kaleidoscope/plugin/LEDEffect-BootGreeting.h b/src/kaleidoscope/plugin/LEDEffect-BootGreeting.h new file mode 100644 index 00000000..aeeae501 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDEffect-BootGreeting.h @@ -0,0 +1,47 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-LEDEffect-BootGreeting -- Small greeting at boot time + * Copyright (C) 2017, 2018 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope-LEDControl.h" + +namespace kaleidoscope { +namespace plugin { +class BootGreetingEffect : public kaleidoscope::Plugin { + public: + BootGreetingEffect(void) {} + BootGreetingEffect(byte, byte); + + static byte key_row; + static byte key_col; + static Key search_key; + static uint8_t hue; + static uint16_t timeout; + + EventHandlerResult afterEachCycle(); + + private: + static void findLed(void); + static bool done_; + static byte row_; + static byte col_; + static uint16_t start_time; +}; +} +} + +extern kaleidoscope::plugin::BootGreetingEffect BootGreetingEffect; From 999c4056a1e24b38c37f6310828a07f295c311c6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:14:18 +0200 Subject: [PATCH 753/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 770 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 2d57b177..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-LEDEffect-BootGreeting - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-BootGreeting.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-BootGreeting - -See [doc/plugin/LEDEffect-BootGreeting.md](doc/plugin/LEDEffect-BootGreeting.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 520eac91..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-LEDEffect-BootGreeting -version=0.0.1 -author=Gergely Nagy -maintainer=Gergely Nagy -sentence=A boot-time LED greeting -paragraph=Makes the LED button breathe for a short while after keyboard boot. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-BootGreeting -architectures=avr -dot_a_linkage=true From 1968a05f2a2f5e9c99e4d8af9d7fb0946c11ff94 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:20:27 +0200 Subject: [PATCH 754/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/LEDEffect-Breathe.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 38 +----------------- doc/plugin/LEDEffect-Breathe.md | 39 +++++++++++++++++++ src/Kaleidoscope-LEDEffect-Breathe.h | 21 +--------- .../plugin/LEDEffect-Breathe.cpp} | 5 ++- src/kaleidoscope/plugin/LEDEffect-Breathe.h | 39 +++++++++++++++++++ 5 files changed, 84 insertions(+), 58 deletions(-) create mode 100644 doc/plugin/LEDEffect-Breathe.md rename src/{Kaleidoscope-LEDEffect-Breathe.cpp => kaleidoscope/plugin/LEDEffect-Breathe.cpp} (93%) create mode 100644 src/kaleidoscope/plugin/LEDEffect-Breathe.h diff --git a/README.md b/README.md index 549a5c87..3ce148d3 100644 --- a/README.md +++ b/README.md @@ -5,40 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Breathe.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Breathe -Provides a breathing effect for the keyboard. Breathe in, breathe out. - -## Using the extension - -To use the plugin, include the header, and tell the firmware to use it: - -```c++ -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, - LEDBreatheEffect); - -void setup() { - Kaleidoscope.setup(); -} -``` - -## Plugin properties - -The plugin provides the `LEDBreatheEffect` object, which has a single property: - -### `.hue` - -> The hue of the breathe effect. -> -> Defaults to 170, a blue hue. - -### `.saturation` - -> The color saturation of the breathe effect. -> -> Defaults to 255, the maximum. - -## Dependencies - -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +See [doc/plugin/LEDEffect-Breathe.md](doc/plugin/LEDEffect-Breathe.md) for documentation. diff --git a/doc/plugin/LEDEffect-Breathe.md b/doc/plugin/LEDEffect-Breathe.md new file mode 100644 index 00000000..20b15d5c --- /dev/null +++ b/doc/plugin/LEDEffect-Breathe.md @@ -0,0 +1,39 @@ +# Kaleidoscope-LEDEffect-Breathe + +Provides a breathing effect for the keyboard. Breathe in, breathe out. + +## Using the extension + +To use the plugin, include the header, and tell the firmware to use it: + +```c++ +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + LEDBreatheEffect); + +void setup() { + Kaleidoscope.setup(); +} +``` + +## Plugin properties + +The plugin provides the `LEDBreatheEffect` object, which has a single property: + +### `.hue` + +> The hue of the breathe effect. +> +> Defaults to 170, a blue hue. + +### `.saturation` + +> The color saturation of the breathe effect. +> +> Defaults to 255, the maximum. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) diff --git a/src/Kaleidoscope-LEDEffect-Breathe.h b/src/Kaleidoscope-LEDEffect-Breathe.h index edb2db27..028e40d3 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.h +++ b/src/Kaleidoscope-LEDEffect-Breathe.h @@ -16,23 +16,4 @@ #pragma once -#include "Kaleidoscope-LEDControl.h" -#include "LEDUtils.h" - -namespace kaleidoscope { -class LEDBreatheEffect : public LEDMode { - public: - LEDBreatheEffect(void) {} - - uint8_t hue = 170; - uint8_t saturation = 255; - - protected: - void update(void) final; - - private: - uint16_t last_update_ = 0; -}; -} - -extern kaleidoscope::LEDBreatheEffect LEDBreatheEffect; +#include "kaleidoscope/plugin/LEDEffect-Breathe.h" diff --git a/src/Kaleidoscope-LEDEffect-Breathe.cpp b/src/kaleidoscope/plugin/LEDEffect-Breathe.cpp similarity index 93% rename from src/Kaleidoscope-LEDEffect-Breathe.cpp rename to src/kaleidoscope/plugin/LEDEffect-Breathe.cpp index 1fc02982..ba77c1f9 100644 --- a/src/Kaleidoscope-LEDEffect-Breathe.cpp +++ b/src/kaleidoscope/plugin/LEDEffect-Breathe.cpp @@ -15,9 +15,11 @@ */ #include "Kaleidoscope-LEDEffect-Breathe.h" + #define UPDATE_INTERVAL 50 // milliseconds between two LED updates to avoid overloading; 20 fps namespace kaleidoscope { +namespace plugin { void LEDBreatheEffect::update(void) { uint16_t now = Kaleidoscope.millisAtCycleStart(); if ((now - last_update_) < UPDATE_INTERVAL) @@ -28,5 +30,6 @@ void LEDBreatheEffect::update(void) { ::LEDControl.set_all_leds_to(color); } } +} -kaleidoscope::LEDBreatheEffect LEDBreatheEffect; +kaleidoscope::plugin::LEDBreatheEffect LEDBreatheEffect; diff --git a/src/kaleidoscope/plugin/LEDEffect-Breathe.h b/src/kaleidoscope/plugin/LEDEffect-Breathe.h new file mode 100644 index 00000000..ade1e7dc --- /dev/null +++ b/src/kaleidoscope/plugin/LEDEffect-Breathe.h @@ -0,0 +1,39 @@ +/* Kaleidoscope-LEDEffect-Breathe - A breathing effect on the LEDs, for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope-LEDControl.h" + +namespace kaleidoscope { +namespace plugin { +class LEDBreatheEffect : public LEDMode { + public: + LEDBreatheEffect(void) {} + + uint8_t hue = 170; + uint8_t saturation = 255; + + protected: + void update(void) final; + + private: + uint16_t last_update_ = 0; +}; +} +} + +extern kaleidoscope::plugin::LEDBreatheEffect LEDBreatheEffect; From c748fcbb0139f354069e5d89436af4362af5e5c1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:20:27 +0200 Subject: [PATCH 755/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 770 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 3ce148d3..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-LEDEffect-Breathe - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Breathe.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Breathe - -See [doc/plugin/LEDEffect-Breathe.md](doc/plugin/LEDEffect-Breathe.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 97eb4e1f..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-LEDEffect-Breathe -version=0.0.1 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=A breathing effect on the LEDs, for Kaleidoscope. -paragraph=A breathing effect on the LEDs, for Kaleidoscope. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-Breathe -architectures=avr -dot_a_linkage=true From 663b2bb2f1941fa91fbc3853fc8c87d875eb73b6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:27:46 +0200 Subject: [PATCH 756/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/LEDEffect-Chase.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 28 +------------ doc/plugin/LEDEffect-Chase.md | 29 ++++++++++++++ src/Kaleidoscope-LEDEffect-Chase.h | 22 +--------- .../plugin/LEDEffect-Chase.cpp} | 5 ++- src/kaleidoscope/plugin/LEDEffect-Chase.h | 40 +++++++++++++++++++ 5 files changed, 75 insertions(+), 49 deletions(-) create mode 100644 doc/plugin/LEDEffect-Chase.md rename src/{Kaleidoscope-LEDEffect-Chase.cpp => kaleidoscope/plugin/LEDEffect-Chase.cpp} (97%) create mode 100644 src/kaleidoscope/plugin/LEDEffect-Chase.h diff --git a/README.md b/README.md index 86e16cb0..82971e4b 100644 --- a/README.md +++ b/README.md @@ -5,30 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Chase.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Chase -A simple LED effect where one color chases another across the keyboard and back, -over and over again. Playful colors they are. - -## Using the extension - -To use the plugin, include the header, and tell the firmware to use it: - -```c++ -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, - LEDEffect-Chase); - -void setup() { - Kaleidoscope.setup(); -} -``` - -## Plugin methods - -The plugin provides the `LEDChaseEffect` object, which has no public methods or -properties, outside of those provided by all LED modes. - -## Dependencies - -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +See [doc/plugin/LEDEffect-Chase.md](doc/plugin/LEDEffect-Chase.md) for documentation. diff --git a/doc/plugin/LEDEffect-Chase.md b/doc/plugin/LEDEffect-Chase.md new file mode 100644 index 00000000..61a6cbf4 --- /dev/null +++ b/doc/plugin/LEDEffect-Chase.md @@ -0,0 +1,29 @@ +# Kaleidoscope-LEDEffect-Chase + +A simple LED effect where one color chases another across the keyboard and back, +over and over again. Playful colors they are. + +## Using the extension + +To use the plugin, include the header, and tell the firmware to use it: + +```c++ +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, + LEDEffect-Chase); + +void setup() { + Kaleidoscope.setup(); +} +``` + +## Plugin methods + +The plugin provides the `LEDChaseEffect` object, which has no public methods or +properties, outside of those provided by all LED modes. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) diff --git a/src/Kaleidoscope-LEDEffect-Chase.h b/src/Kaleidoscope-LEDEffect-Chase.h index 1f3c2bcd..e755e738 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.h +++ b/src/Kaleidoscope-LEDEffect-Chase.h @@ -16,24 +16,4 @@ #pragma once -#include "Kaleidoscope-LEDControl.h" -#include "LEDUtils.h" - -namespace kaleidoscope { -class LEDChaseEffect : public LEDMode { - public: - LEDChaseEffect(void) {} - - protected: - void update(void) final; - - private: - uint8_t pos = 0; - int8_t chase_sign = 1; //negative values when it's going backwar - uint8_t chase_pixels = 5; - uint8_t current_chase_counter = 0; - static const uint8_t chase_threshold = 150; -}; -} - -extern kaleidoscope::LEDChaseEffect LEDChaseEffect; +#include "kaleidoscope/plugin/LEDEffect-Chase.h" diff --git a/src/Kaleidoscope-LEDEffect-Chase.cpp b/src/kaleidoscope/plugin/LEDEffect-Chase.cpp similarity index 97% rename from src/Kaleidoscope-LEDEffect-Chase.cpp rename to src/kaleidoscope/plugin/LEDEffect-Chase.cpp index b2dfd7c9..ae8426e1 100644 --- a/src/Kaleidoscope-LEDEffect-Chase.cpp +++ b/src/kaleidoscope/plugin/LEDEffect-Chase.cpp @@ -17,6 +17,7 @@ #include "Kaleidoscope-LEDEffect-Chase.h" namespace kaleidoscope { +namespace plugin { void LEDChaseEffect::update(void) { // Check to see if it's time to change the positions of the red and blue lights if (current_chase_counter++ < chase_threshold) { @@ -58,6 +59,8 @@ void LEDChaseEffect::update(void) { if (pos2 < LED_COUNT) ::LEDControl.setCrgbAt(pos2, {255, 0, 0}); } + +} } -kaleidoscope::LEDChaseEffect LEDChaseEffect; +kaleidoscope::plugin::LEDChaseEffect LEDChaseEffect; diff --git a/src/kaleidoscope/plugin/LEDEffect-Chase.h b/src/kaleidoscope/plugin/LEDEffect-Chase.h new file mode 100644 index 00000000..6174eae5 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDEffect-Chase.h @@ -0,0 +1,40 @@ +/* Kaleidoscope-LEDEffect-Chase - A Chase LED effect for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope-LEDControl.h" + +namespace kaleidoscope { +namespace plugin { +class LEDChaseEffect : public LEDMode { + public: + LEDChaseEffect(void) {} + + protected: + void update(void) final; + + private: + uint8_t pos = 0; + int8_t chase_sign = 1; //negative values when it's going backwar + uint8_t chase_pixels = 5; + uint8_t current_chase_counter = 0; + static const uint8_t chase_threshold = 150; +}; +} +} + +extern kaleidoscope::plugin::LEDChaseEffect LEDChaseEffect; From 78bee0e72561a3359c9aa075f65d13a9279a3a94 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:27:46 +0200 Subject: [PATCH 757/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 770 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 82971e4b..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-LEDEffect-Chase - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Chase.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Chase - -See [doc/plugin/LEDEffect-Chase.md](doc/plugin/LEDEffect-Chase.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index c6419041..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-LEDEffect-Chase -version=0.0.1 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=A Chase LED effect for Kaleidoscope. -paragraph=A fun little LED effect where two colors chase each other. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-Chase -architectures=avr -dot_a_linkage=true From 3b1e07361b5c3f814da04776403ef1a1824716af Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:29:12 +0200 Subject: [PATCH 758/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/LEDEffect-Rainbow.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 50 +----------- doc/plugin/LEDEffect-Rainbow.md | 51 ++++++++++++ src/Kaleidoscope-LEDEffect-Rainbow.h | 59 +------------- .../plugin/LEDEffect-Rainbow.cpp} | 7 +- src/kaleidoscope/plugin/LEDEffect-Rainbow.h | 77 +++++++++++++++++++ 5 files changed, 135 insertions(+), 109 deletions(-) create mode 100644 doc/plugin/LEDEffect-Rainbow.md rename src/{Kaleidoscope-LEDEffect-Rainbow.cpp => kaleidoscope/plugin/LEDEffect-Rainbow.cpp} (93%) create mode 100644 src/kaleidoscope/plugin/LEDEffect-Rainbow.h diff --git a/README.md b/README.md index 7fa9461f..caab571d 100644 --- a/README.md +++ b/README.md @@ -5,52 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Rainbow.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Rainbow -Two colorful rainbow effects are implemented by this plugin: one where the -rainbow waves through the keys, and another where the LEDs breathe though the -colors of a rainbow. The difference is that in the first case, we have all the -rainbow colors on display, and it waves through the keyboard. In the second -case, we have only one color at a time, for the whole board, and the color -cycles through the rainbow's palette. - -## Using the extension - -To use the plugin, include the header, and tell the firmware to use either (or -both!) of the effects: - -```c++ -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDRainbowEffect, LEDRainbowWaveEffect); - -void setup() { - Kaleidoscope.setup(); - - LEDRainbowEffect.brightness(150); - LEDRainbowWaveEffect.brightness(150); - LEDRainbowWaveEffect.update_delay(50); -} -``` - -## Plugin methods - -The plugin provides two objects: `LEDRainbowEffect`, and `LEDRainbowWaveEffect`, -both of which provide the following methods: - -### `.brightness([brightness])` - -> Sets (or gets, if called without an argument) the LED brightness for the -> effect. -> -> Defaults to 50. - -### `.update_delay([delay])` - -> Sets (or gets, if called without an argument) the number of milliseconds -> between effect updates. Smaller number results in faster rainbows. -> -> Defaults to 40. - -## Dependencies - -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +See [doc/plugin/LEDEffect-Rainbow.md](doc/plugin/LEDEffect-Rainbow.md) for documentation. diff --git a/doc/plugin/LEDEffect-Rainbow.md b/doc/plugin/LEDEffect-Rainbow.md new file mode 100644 index 00000000..55151642 --- /dev/null +++ b/doc/plugin/LEDEffect-Rainbow.md @@ -0,0 +1,51 @@ +# Kaleidoscope-LEDEffect-Rainbow + +Two colorful rainbow effects are implemented by this plugin: one where the +rainbow waves through the keys, and another where the LEDs breathe though the +colors of a rainbow. The difference is that in the first case, we have all the +rainbow colors on display, and it waves through the keyboard. In the second +case, we have only one color at a time, for the whole board, and the color +cycles through the rainbow's palette. + +## Using the extension + +To use the plugin, include the header, and tell the firmware to use either (or +both!) of the effects: + +```c++ +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDRainbowEffect, LEDRainbowWaveEffect); + +void setup() { + Kaleidoscope.setup(); + + LEDRainbowEffect.brightness(150); + LEDRainbowWaveEffect.brightness(150); + LEDRainbowWaveEffect.update_delay(50); +} +``` + +## Plugin methods + +The plugin provides two objects: `LEDRainbowEffect`, and `LEDRainbowWaveEffect`, +both of which provide the following methods: + +### `.brightness([brightness])` + +> Sets (or gets, if called without an argument) the LED brightness for the +> effect. +> +> Defaults to 50. + +### `.update_delay([delay])` + +> Sets (or gets, if called without an argument) the number of milliseconds +> between effect updates. Smaller number results in faster rainbows. +> +> Defaults to 40. + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.h b/src/Kaleidoscope-LEDEffect-Rainbow.h index bcabfee6..348f9562 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.h +++ b/src/Kaleidoscope-LEDEffect-Rainbow.h @@ -16,61 +16,4 @@ #pragma once -#include "Kaleidoscope-LEDControl.h" -#include "LEDUtils.h" - -namespace kaleidoscope { -class LEDRainbowEffect : public LEDMode { - public: - LEDRainbowEffect(void) {} - - void brightness(byte); - byte brightness(void) { - return rainbow_value; - } - void update_delay(byte); - byte update_delay(void) { - return rainbow_update_delay; - } - void update(void) final; - - private: - uint16_t rainbow_hue = 0; // stores 0 to 614 - - uint8_t rainbow_steps = 1; // number of hues we skip in a 360 range per update - uint16_t rainbow_last_update = 0; - uint16_t rainbow_update_delay = 40; // delay between updates (ms) - - byte rainbow_saturation = 255; - byte rainbow_value = 50; -}; - - -class LEDRainbowWaveEffect : public LEDMode { - public: - LEDRainbowWaveEffect(void) {} - - void brightness(byte); - byte brightness(void) { - return rainbow_value; - } - void update_delay(byte); - byte update_delay(void) { - return rainbow_update_delay; - } - void update(void) final; - - private: - uint16_t rainbow_hue = 0; // stores 0 to 614 - - uint8_t rainbow_wave_steps = 1; // number of hues we skip in a 360 range per update - uint16_t rainbow_last_update = 0; - uint16_t rainbow_update_delay = 40; // delay between updates (ms) - - byte rainbow_saturation = 255; - byte rainbow_value = 50; -}; -} - -extern kaleidoscope::LEDRainbowEffect LEDRainbowEffect; -extern kaleidoscope::LEDRainbowWaveEffect LEDRainbowWaveEffect; +#include "kaleidoscope/plugin/LEDEffect-Rainbow.h" diff --git a/src/Kaleidoscope-LEDEffect-Rainbow.cpp b/src/kaleidoscope/plugin/LEDEffect-Rainbow.cpp similarity index 93% rename from src/Kaleidoscope-LEDEffect-Rainbow.cpp rename to src/kaleidoscope/plugin/LEDEffect-Rainbow.cpp index 56fad332..c9f0dc61 100644 --- a/src/Kaleidoscope-LEDEffect-Rainbow.cpp +++ b/src/kaleidoscope/plugin/LEDEffect-Rainbow.cpp @@ -17,6 +17,7 @@ #include "Kaleidoscope-LEDEffect-Rainbow.h" namespace kaleidoscope { +namespace plugin { void LEDRainbowEffect::update(void) { uint16_t now = millis(); @@ -75,7 +76,9 @@ void LEDRainbowWaveEffect::brightness(byte brightness) { void LEDRainbowWaveEffect::update_delay(byte delay) { rainbow_update_delay = delay; } + +} } -kaleidoscope::LEDRainbowEffect LEDRainbowEffect; -kaleidoscope::LEDRainbowWaveEffect LEDRainbowWaveEffect; +kaleidoscope::plugin::LEDRainbowEffect LEDRainbowEffect; +kaleidoscope::plugin::LEDRainbowWaveEffect LEDRainbowWaveEffect; diff --git a/src/kaleidoscope/plugin/LEDEffect-Rainbow.h b/src/kaleidoscope/plugin/LEDEffect-Rainbow.h new file mode 100644 index 00000000..3bc8f654 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDEffect-Rainbow.h @@ -0,0 +1,77 @@ +/* Kaleidoscope-LEDEffect-Rainbow - Rainbow LED effects for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope-LEDControl.h" + +namespace kaleidoscope { +namespace plugin { +class LEDRainbowEffect : public LEDMode { + public: + LEDRainbowEffect(void) {} + + void brightness(byte); + byte brightness(void) { + return rainbow_value; + } + void update_delay(byte); + byte update_delay(void) { + return rainbow_update_delay; + } + void update(void) final; + + private: + uint16_t rainbow_hue = 0; // stores 0 to 614 + + uint8_t rainbow_steps = 1; // number of hues we skip in a 360 range per update + uint16_t rainbow_last_update = 0; + uint16_t rainbow_update_delay = 40; // delay between updates (ms) + + byte rainbow_saturation = 255; + byte rainbow_value = 50; +}; + + +class LEDRainbowWaveEffect : public LEDMode { + public: + LEDRainbowWaveEffect(void) {} + + void brightness(byte); + byte brightness(void) { + return rainbow_value; + } + void update_delay(byte); + byte update_delay(void) { + return rainbow_update_delay; + } + void update(void) final; + + private: + uint16_t rainbow_hue = 0; // stores 0 to 614 + + uint8_t rainbow_wave_steps = 1; // number of hues we skip in a 360 range per update + uint16_t rainbow_last_update = 0; + uint16_t rainbow_update_delay = 40; // delay between updates (ms) + + byte rainbow_saturation = 255; + byte rainbow_value = 50; +}; +} +} + +extern kaleidoscope::plugin::LEDRainbowEffect LEDRainbowEffect; +extern kaleidoscope::plugin::LEDRainbowWaveEffect LEDRainbowWaveEffect; From 2877c5ea23b3dfce20fd7b870f81ccb0586e4449 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:29:12 +0200 Subject: [PATCH 759/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 770 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index caab571d..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-LEDEffect-Rainbow - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Rainbow.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LEDEffect-Rainbow - -See [doc/plugin/LEDEffect-Rainbow.md](doc/plugin/LEDEffect-Rainbow.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index ab69a911..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-LEDEffect-Rainbow -version=0.0.1 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=Rainbow LED effects for Kaleidoscope. -paragraph=Provides two rainbow LED effects for Kaleidoscope. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-LEDEffect-Rainbow -architectures=avr -dot_a_linkage=true From b9aca9d5f09125f6a73c034de8697b581f88301c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 14:59:07 +0200 Subject: [PATCH 760/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/LED-Stalker.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 83 +----------------- doc/plugin/LED-Stalker.md | 84 +++++++++++++++++++ examples/LED-Stalker/LED-Stalker.ino | 1 - src/Kaleidoscope-LED-Stalker.h | 2 +- .../plugin}/LED-Stalker.cpp | 5 +- .../plugin}/LED-Stalker.h | 6 +- 6 files changed, 93 insertions(+), 88 deletions(-) create mode 100644 doc/plugin/LED-Stalker.md rename src/{Kaleidoscope => kaleidoscope/plugin}/LED-Stalker.cpp (97%) rename src/{Kaleidoscope => kaleidoscope/plugin}/LED-Stalker.h (91%) diff --git a/README.md b/README.md index ef117e63..6e5c3cdc 100644 --- a/README.md +++ b/README.md @@ -5,85 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker -The `StalkerEffect` plugin provides an interesting new typing experience: the -LEDs light up as you tap keys and play one of the selected effects: a haunting -trail of ghostly white lights, or a blazing trail of fire. - -## Using the plugin - -To use the plugin, one needs to include the header and select the effect. - -```c++ -#include -#include -#include - -KALEIDOSCOPE_INIT_PLUGINS(LEDControl, StalkerEffect); - -void setup (){ - Kaleidoscope.setup(); - - StalkerEffect.variant = STALKER(Haunt, (CRGB(0, 128, 0))); - StalkerEffect.activate(); -} -``` - -It is recommended to place the activation of the plugin (the `Kaleidoscope.use` -call) as early as possible, so the plugin can catch all relevant key presses. -The configuration can happen at any time and should use the `STALKER` macro to -do so. - -## Plugin methods - -The plugin provides the `StalkerEffect` object, which has the following -properties: - -### `.variant` - -> Set the effect to use with the plugin. See below for a list. -> -> It is recommended to use the `STALKER` macro to declare the effect itself. - -### `.step_length` - -> The length - in milliseconds - of each step of the animation. An animation -> lasts 256 steps. -> -> Defaults to 50. - -## Plugin helpers - -### `STALKER(effect, params)` - -> Returns an effect, to be used to assign a value the `.variant` property of the -> `StalkerEffect` object. Any arguments given to the macro are passed on -> to the effect. If the effect takes no arguments, use an empty `params` list. - -## Plugin effects - -The plugin provides the following effects: - -### `Haunt([color])` - -> A ghostly haunt effect, that trails the key taps with a ghostly white color -> (or any other color, if specified). Use the `CRGB(r,g,b)` macro to specify the -> color, if you want something else than the ghostly white. - -### `BlazingTrail()` - -> A blazing trail of fire will follow our fingers! - -### `Rainbow()` - -> Leave a rainbow behind, where your fingers has been! - -## Dependencies - -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) - -## Further reading - -Starting from the [example][plugin:example] is the recommended way of getting -started with the plugin. - - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-Stalker/blob/master/examples/LED-Stalker/LED-Stalker.ino +See [doc/plugin/LED-Stalker.md](doc/plugin/LED-Stalker.md) for documentation. diff --git a/doc/plugin/LED-Stalker.md b/doc/plugin/LED-Stalker.md new file mode 100644 index 00000000..20b9eda5 --- /dev/null +++ b/doc/plugin/LED-Stalker.md @@ -0,0 +1,84 @@ +# Kaleidoscope-LED-Stalker + +The `StalkerEffect` plugin provides an interesting new typing experience: the +LEDs light up as you tap keys and play one of the selected effects: a haunting +trail of ghostly white lights, or a blazing trail of fire. + +## Using the plugin + +To use the plugin, one needs to include the header and select the effect. + +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(LEDControl, StalkerEffect); + +void setup (){ + Kaleidoscope.setup(); + + StalkerEffect.variant = STALKER(Haunt, (CRGB(0, 128, 0))); + StalkerEffect.activate(); +} +``` + +It is recommended to place the activation of the plugin (the `Kaleidoscope.use` +call) as early as possible, so the plugin can catch all relevant key presses. +The configuration can happen at any time and should use the `STALKER` macro to +do so. + +## Plugin methods + +The plugin provides the `StalkerEffect` object, which has the following +properties: + +### `.variant` + +> Set the effect to use with the plugin. See below for a list. +> +> It is recommended to use the `STALKER` macro to declare the effect itself. + +### `.step_length` + +> The length - in milliseconds - of each step of the animation. An animation +> lasts 256 steps. +> +> Defaults to 50. + +## Plugin helpers + +### `STALKER(effect, params)` + +> Returns an effect, to be used to assign a value the `.variant` property of the +> `StalkerEffect` object. Any arguments given to the macro are passed on +> to the effect. If the effect takes no arguments, use an empty `params` list. + +## Plugin effects + +The plugin provides the following effects: + +### `Haunt([color])` + +> A ghostly haunt effect, that trails the key taps with a ghostly white color +> (or any other color, if specified). Use the `CRGB(r,g,b)` macro to specify the +> color, if you want something else than the ghostly white. + +### `BlazingTrail()` + +> A blazing trail of fire will follow our fingers! + +### `Rainbow()` + +> Leave a rainbow behind, where your fingers has been! + +## Dependencies + +* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-Stalker/blob/master/examples/LED-Stalker/LED-Stalker.ino diff --git a/examples/LED-Stalker/LED-Stalker.ino b/examples/LED-Stalker/LED-Stalker.ino index 5362e971..050fcfe8 100644 --- a/examples/LED-Stalker/LED-Stalker.ino +++ b/examples/LED-Stalker/LED-Stalker.ino @@ -18,7 +18,6 @@ #include #include #include -#include "LED-Off.h" // *INDENT-OFF* const Key keymaps[][ROWS][COLS] PROGMEM = { diff --git a/src/Kaleidoscope-LED-Stalker.h b/src/Kaleidoscope-LED-Stalker.h index 042d66b0..5eabcc3f 100644 --- a/src/Kaleidoscope-LED-Stalker.h +++ b/src/Kaleidoscope-LED-Stalker.h @@ -17,4 +17,4 @@ #pragma once -#include +#include diff --git a/src/Kaleidoscope/LED-Stalker.cpp b/src/kaleidoscope/plugin/LED-Stalker.cpp similarity index 97% rename from src/Kaleidoscope/LED-Stalker.cpp rename to src/kaleidoscope/plugin/LED-Stalker.cpp index 22681a4f..4f64913c 100644 --- a/src/Kaleidoscope/LED-Stalker.cpp +++ b/src/kaleidoscope/plugin/LED-Stalker.cpp @@ -16,9 +16,9 @@ */ #include -#include namespace kaleidoscope { +namespace plugin { uint8_t StalkerEffect::map_[ROWS][COLS]; StalkerEffect::ColorComputer *StalkerEffect::variant; @@ -136,8 +136,9 @@ cRGB Rainbow::compute(uint8_t *step) { return hsvToRgb(255 - *step, 255, *step); } +} } } -kaleidoscope::StalkerEffect StalkerEffect; +kaleidoscope::plugin::StalkerEffect StalkerEffect; diff --git a/src/Kaleidoscope/LED-Stalker.h b/src/kaleidoscope/plugin/LED-Stalker.h similarity index 91% rename from src/Kaleidoscope/LED-Stalker.h rename to src/kaleidoscope/plugin/LED-Stalker.h index e43d6354..029895fa 100644 --- a/src/Kaleidoscope/LED-Stalker.h +++ b/src/kaleidoscope/plugin/LED-Stalker.h @@ -20,9 +20,10 @@ #include #include -#define STALKER(v, ...) ({static kaleidoscope::stalker::v _effect __VA_ARGS__; &_effect;}) +#define STALKER(v, ...) ({static kaleidoscope::plugin::stalker::v _effect __VA_ARGS__; &_effect;}) namespace kaleidoscope { +namespace plugin { class StalkerEffect : public LEDMode { public: class ColorComputer { @@ -72,7 +73,8 @@ class Rainbow : public StalkerEffect::ColorComputer { cRGB compute(uint8_t *step) final; }; +} } } -extern kaleidoscope::StalkerEffect StalkerEffect; +extern kaleidoscope::plugin::StalkerEffect StalkerEffect; From 01f0bc49a8a346c47e4a9b16280f76faf89dc145 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 15:01:54 +0200 Subject: [PATCH 761/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .gitignore | 4 - .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 7 files changed, 774 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.gitignore b/.gitignore deleted file mode 100644 index be16c9be..00000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.#* -*~ -/hardware/ -/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 6e5c3cdc..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-LED-Stalker - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker - -See [doc/plugin/LED-Stalker.md](doc/plugin/LED-Stalker.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 47accd64..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-LED-Stalker -version=0.0.0 -author=Gergely Nagy -maintainer=Gergely Nagy -sentence=Stalk keys pressed by lighting up and fading back the LED under them. -paragraph=Stalk keys pressed by lighting up and fading back the LED under them. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-LED-Stalker -architectures=avr -dot_a_linkage=true From b80ecfec7178d792330757f4c59d1f155b3ad948 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 12:25:47 +0200 Subject: [PATCH 762/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/EEPROM-Settings.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 167 +---------------- doc/plugin/EEPROM-Settings.md | 168 ++++++++++++++++++ src/Kaleidoscope-EEPROM-Settings.h | 4 +- .../plugin}/EEPROM-Settings-Focus.cpp | 6 +- .../plugin}/EEPROM-Settings-Focus.h | 6 +- .../plugin}/EEPROM-Settings.cpp | 4 +- .../plugin}/EEPROM-Settings.h | 6 +- .../plugin}/crc.cpp | 0 .../plugin}/crc.h | 0 9 files changed, 186 insertions(+), 175 deletions(-) create mode 100644 doc/plugin/EEPROM-Settings.md rename src/{Kaleidoscope => kaleidoscope/plugin}/EEPROM-Settings-Focus.cpp (95%) rename src/{Kaleidoscope => kaleidoscope/plugin}/EEPROM-Settings-Focus.h (86%) rename src/{Kaleidoscope => kaleidoscope/plugin}/EEPROM-Settings.cpp (97%) rename src/{Kaleidoscope => kaleidoscope/plugin}/EEPROM-Settings.h (94%) rename src/{Kaleidoscope => kaleidoscope/plugin}/crc.cpp (100%) rename src/{Kaleidoscope => kaleidoscope/plugin}/crc.h (100%) diff --git a/README.md b/README.md index 685a8d9d..687b5684 100644 --- a/README.md +++ b/README.md @@ -5,169 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings -To be able to reliably store persistent configuration in `EEPROM`, we need to be -able to split up the available space for plugins to use. We also want to make -sure that we notice when the `EEPROM` contents and the firmware are out of sync. -This plugin provides the tools to do that. - -It does not guard against errors, it merely provides the means to discover them, -and let the firmware Sketch handle the case in whatever way it finds reasonable. -It's a building block, and not much else. All Kaleidoscope plugins that need to -store data in `EEPROM` are encouraged to make use of this library. - -## Using the plugin - -There are a few steps one needs to take to use the plugin: we must first -register it, then either let other plugins request slices of `EEPROM`, or do so -ourselves. And finally, seal it, to signal that we are done setting up. At that -point, we can verify whether the contents of the `EEPROM` agree with our -firmware. - -```c++ -#include -#include - -static uint16_t settingsBase; -static struct { - bool someSettingFlag; -} testSettings; - -KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, /* Other plugins that use EEPROM... */); - -void setup () { - Kaleidoscope.setup(); - - settingsBase = EEPROMSettings.requestSlice(sizeof(testSettings)); - - EEPROMSettings.seal(); - - if (!EEPROMSettings.isValid()) { - // Handle the case where the settings are out of sync... - // Flash LEDs, for example. - - return; - } - - EEPROM.get(settingsBase, testSettings); -} -``` - -## Plugin methods - -The plugin provides the `EEPROMSettings` object, which has the following methods: - -### `requestSlice(size)` - -> Requests a slice of the `EEPROM`, and returns the starting address (or 0 on -> error, including when the request arrived after sealing the layout). -> -> Should only be called **before** calling `seal()`. - -### `default_layer([id])` - -> Sets (or returns, if called without an ID) the default layer. When the -> keyboard boots up, it will automatically switch to the configured layer - if -> any. -> -> This is the Focus counterpart of the `default_layer()` method documented -> above. - -### `seal()` - -> Seal the `EEPROM` layout, so no new slices can be requested. The CRC checksum -> is considered final at this time, and the `isValid()`, `crc()`, `used()` and -> `version()` methods can be used from this point onwards. -> -> If not called explicitly, the layout will be sealed automatically after -> `setup()` in the sketch finished. - -### `update()` - -> Updates the `EEPROM` header with the current status quo, including the version -> and the CRC checksum. -> -> This should be called when upgrading from one version to another, or when -> fixing up an out-of-sync case. - -### `isValid()` - -> Returns whether the `EEPROM` header is valid, that is, if it has the expected -> CRC checksum. -> -> Should only be called after calling `seal()`. - -### `invalidate()` - -> Invalidates the `EEPROM` header. Use when the version does not match what the -> firmware would expect. This signals to other plugins that the contents of -> `EEPROM` should not be trusted. - -### `version([newVersion])` - -> Sets or returns the version of the `EEPROM` layout. This is purely for use by -> the firmware, so it can attempt to upgrade the contents, if need be, or alert -> the user in there's a mismatch. Plugins do not use this property. -> -> Should only be called after calling `seal()`. - -### `crc()` - -> Returns the CRC checksum of the layout. Should only be used after calling -> `seal()`. - -### `used()` - -> Returns the amount of space requested so far. -> -> Should only be used after calling `seal()`. - -## Focus commands - -The plugin provides two - optional - [Focus][FocusSerial] command plugins: -`FocusSettingsCommand` and `FocusEEPROMCommand`. These must be explicitly added -to `KALEIDOSCOPE_INIT_PLUGINS` if one wishes to use them. They provide the -following commands: - - [FocusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial - -### `settings.defaultLayer` - -> Sets or returns (if called without arguments) the ID of the default layer. If -> set, the keyboard will automatically switch to the given layer when connected. -> Setting it to `255` disables the automatic switching. - -### `settings.crc` - -> Returns the actual, and the expected checksum of the settings. - -### `settings.valid?` - -> Returns either `true` or `false`, depending on whether the sealed settings are -> to be considered valid or not. - -### `settings.version` - -> Returns the (user-set) version of the settings. - -### `eeprom.contents` - -> Without argument, displays the full contents of the `EEPROM`, including the -> settings header. -> -> With arguments, the command updates as much of the `EEPROM` as arguments are -> provided. It will discard any unnecessary arguments. - -### `eeprom.free` - -> Returns the amount of free bytes in `EEPROM`. - -## Dependencies - -* [Kaleidoscope-FocusSerial][FocusSerial] - -## Further reading - -Starting from the [example][plugin:example] is the recommended way of getting -started with the plugin. - - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings/blob/master/examples/EEPROM-Settings/EEPROM-Settings.ino +See [doc/plugin/EEPROM-Settings.md](doc/plugin/EEPROM-Settings.md) for documentation. diff --git a/doc/plugin/EEPROM-Settings.md b/doc/plugin/EEPROM-Settings.md new file mode 100644 index 00000000..ccfb4955 --- /dev/null +++ b/doc/plugin/EEPROM-Settings.md @@ -0,0 +1,168 @@ +# Kaleidoscope-EEPROM-Settings + +To be able to reliably store persistent configuration in `EEPROM`, we need to be +able to split up the available space for plugins to use. We also want to make +sure that we notice when the `EEPROM` contents and the firmware are out of sync. +This plugin provides the tools to do that. + +It does not guard against errors, it merely provides the means to discover them, +and let the firmware Sketch handle the case in whatever way it finds reasonable. +It's a building block, and not much else. All Kaleidoscope plugins that need to +store data in `EEPROM` are encouraged to make use of this library. + +## Using the plugin + +There are a few steps one needs to take to use the plugin: we must first +register it, then either let other plugins request slices of `EEPROM`, or do so +ourselves. And finally, seal it, to signal that we are done setting up. At that +point, we can verify whether the contents of the `EEPROM` agree with our +firmware. + +```c++ +#include +#include + +static uint16_t settingsBase; +static struct { + bool someSettingFlag; +} testSettings; + +KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, /* Other plugins that use EEPROM... */); + +void setup () { + Kaleidoscope.setup(); + + settingsBase = EEPROMSettings.requestSlice(sizeof(testSettings)); + + EEPROMSettings.seal(); + + if (!EEPROMSettings.isValid()) { + // Handle the case where the settings are out of sync... + // Flash LEDs, for example. + + return; + } + + EEPROM.get(settingsBase, testSettings); +} +``` + +## Plugin methods + +The plugin provides the `EEPROMSettings` object, which has the following methods: + +### `requestSlice(size)` + +> Requests a slice of the `EEPROM`, and returns the starting address (or 0 on +> error, including when the request arrived after sealing the layout). +> +> Should only be called **before** calling `seal()`. + +### `default_layer([id])` + +> Sets (or returns, if called without an ID) the default layer. When the +> keyboard boots up, it will automatically switch to the configured layer - if +> any. +> +> This is the Focus counterpart of the `default_layer()` method documented +> above. + +### `seal()` + +> Seal the `EEPROM` layout, so no new slices can be requested. The CRC checksum +> is considered final at this time, and the `isValid()`, `crc()`, `used()` and +> `version()` methods can be used from this point onwards. +> +> If not called explicitly, the layout will be sealed automatically after +> `setup()` in the sketch finished. + +### `update()` + +> Updates the `EEPROM` header with the current status quo, including the version +> and the CRC checksum. +> +> This should be called when upgrading from one version to another, or when +> fixing up an out-of-sync case. + +### `isValid()` + +> Returns whether the `EEPROM` header is valid, that is, if it has the expected +> CRC checksum. +> +> Should only be called after calling `seal()`. + +### `invalidate()` + +> Invalidates the `EEPROM` header. Use when the version does not match what the +> firmware would expect. This signals to other plugins that the contents of +> `EEPROM` should not be trusted. + +### `version([newVersion])` + +> Sets or returns the version of the `EEPROM` layout. This is purely for use by +> the firmware, so it can attempt to upgrade the contents, if need be, or alert +> the user in there's a mismatch. Plugins do not use this property. +> +> Should only be called after calling `seal()`. + +### `crc()` + +> Returns the CRC checksum of the layout. Should only be used after calling +> `seal()`. + +### `used()` + +> Returns the amount of space requested so far. +> +> Should only be used after calling `seal()`. + +## Focus commands + +The plugin provides two - optional - [Focus][FocusSerial] command plugins: +`FocusSettingsCommand` and `FocusEEPROMCommand`. These must be explicitly added +to `KALEIDOSCOPE_INIT_PLUGINS` if one wishes to use them. They provide the +following commands: + + [FocusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial + +### `settings.defaultLayer` + +> Sets or returns (if called without arguments) the ID of the default layer. If +> set, the keyboard will automatically switch to the given layer when connected. +> Setting it to `255` disables the automatic switching. + +### `settings.crc` + +> Returns the actual, and the expected checksum of the settings. + +### `settings.valid?` + +> Returns either `true` or `false`, depending on whether the sealed settings are +> to be considered valid or not. + +### `settings.version` + +> Returns the (user-set) version of the settings. + +### `eeprom.contents` + +> Without argument, displays the full contents of the `EEPROM`, including the +> settings header. +> +> With arguments, the command updates as much of the `EEPROM` as arguments are +> provided. It will discard any unnecessary arguments. + +### `eeprom.free` + +> Returns the amount of free bytes in `EEPROM`. + +## Dependencies + +* [Kaleidoscope-FocusSerial][FocusSerial] + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings/blob/master/examples/EEPROM-Settings/EEPROM-Settings.ino diff --git a/src/Kaleidoscope-EEPROM-Settings.h b/src/Kaleidoscope-EEPROM-Settings.h index 123b49cc..a36d235e 100644 --- a/src/Kaleidoscope-EEPROM-Settings.h +++ b/src/Kaleidoscope-EEPROM-Settings.h @@ -17,5 +17,5 @@ #pragma once -#include -#include +#include +#include diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp b/src/kaleidoscope/plugin/EEPROM-Settings-Focus.cpp similarity index 95% rename from src/Kaleidoscope/EEPROM-Settings-Focus.cpp rename to src/kaleidoscope/plugin/EEPROM-Settings-Focus.cpp index 56cc50a9..1f669f3b 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.cpp +++ b/src/kaleidoscope/plugin/EEPROM-Settings-Focus.cpp @@ -20,6 +20,7 @@ #include "crc.h" namespace kaleidoscope { +namespace plugin { namespace eeprom { EventHandlerResult FocusSettingsCommand::onFocusEvent(const char *command) { @@ -115,8 +116,9 @@ EventHandlerResult FocusEEPROMCommand::onFocusEvent(const char *command) { return EventHandlerResult::EVENT_CONSUMED; } +} } } -kaleidoscope::eeprom::FocusSettingsCommand FocusSettingsCommand; -kaleidoscope::eeprom::FocusEEPROMCommand FocusEEPROMCommand; +kaleidoscope::plugin::eeprom::FocusSettingsCommand FocusSettingsCommand; +kaleidoscope::plugin::eeprom::FocusEEPROMCommand FocusEEPROMCommand; diff --git a/src/Kaleidoscope/EEPROM-Settings-Focus.h b/src/kaleidoscope/plugin/EEPROM-Settings-Focus.h similarity index 86% rename from src/Kaleidoscope/EEPROM-Settings-Focus.h rename to src/kaleidoscope/plugin/EEPROM-Settings-Focus.h index bd0b659e..469e8db2 100644 --- a/src/Kaleidoscope/EEPROM-Settings-Focus.h +++ b/src/kaleidoscope/plugin/EEPROM-Settings-Focus.h @@ -20,6 +20,7 @@ #include namespace kaleidoscope { +namespace plugin { namespace eeprom { class FocusSettingsCommand : public kaleidoscope::Plugin { public: @@ -35,8 +36,9 @@ class FocusEEPROMCommand : public kaleidoscope::Plugin { EventHandlerResult onFocusEvent(const char *command); }; +} } } -extern kaleidoscope::eeprom::FocusSettingsCommand FocusSettingsCommand; -extern kaleidoscope::eeprom::FocusEEPROMCommand FocusEEPROMCommand; +extern kaleidoscope::plugin::eeprom::FocusSettingsCommand FocusSettingsCommand; +extern kaleidoscope::plugin::eeprom::FocusEEPROMCommand FocusEEPROMCommand; diff --git a/src/Kaleidoscope/EEPROM-Settings.cpp b/src/kaleidoscope/plugin/EEPROM-Settings.cpp similarity index 97% rename from src/Kaleidoscope/EEPROM-Settings.cpp rename to src/kaleidoscope/plugin/EEPROM-Settings.cpp index 3870187f..76058754 100644 --- a/src/Kaleidoscope/EEPROM-Settings.cpp +++ b/src/kaleidoscope/plugin/EEPROM-Settings.cpp @@ -19,6 +19,7 @@ #include "crc.h" namespace kaleidoscope { +namespace plugin { struct EEPROMSettings::settings EEPROMSettings::settings_; bool EEPROMSettings::is_valid_; @@ -113,6 +114,7 @@ void EEPROMSettings::version(uint8_t ver) { update(); } +} } -kaleidoscope::EEPROMSettings EEPROMSettings; +kaleidoscope::plugin::EEPROMSettings EEPROMSettings; diff --git a/src/Kaleidoscope/EEPROM-Settings.h b/src/kaleidoscope/plugin/EEPROM-Settings.h similarity index 94% rename from src/Kaleidoscope/EEPROM-Settings.h rename to src/kaleidoscope/plugin/EEPROM-Settings.h index 73d08636..0264ab3e 100644 --- a/src/Kaleidoscope/EEPROM-Settings.h +++ b/src/kaleidoscope/plugin/EEPROM-Settings.h @@ -21,6 +21,7 @@ #include namespace kaleidoscope { +namespace plugin { class EEPROMSettings : public kaleidoscope::Plugin { public: EEPROMSettings(void) {} @@ -52,6 +53,7 @@ class EEPROMSettings : public kaleidoscope::Plugin { uint16_t crc; } settings_; }; -}; +} +} -extern kaleidoscope::EEPROMSettings EEPROMSettings; +extern kaleidoscope::plugin::EEPROMSettings EEPROMSettings; diff --git a/src/Kaleidoscope/crc.cpp b/src/kaleidoscope/plugin/crc.cpp similarity index 100% rename from src/Kaleidoscope/crc.cpp rename to src/kaleidoscope/plugin/crc.cpp diff --git a/src/Kaleidoscope/crc.h b/src/kaleidoscope/plugin/crc.h similarity index 100% rename from src/Kaleidoscope/crc.h rename to src/kaleidoscope/plugin/crc.h From 58830c66856ee46f31ed0409fe917b6dedf55c2a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 12:25:49 +0200 Subject: [PATCH 763/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .gitignore | 4 - .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 7 files changed, 774 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.gitignore b/.gitignore deleted file mode 100644 index be16c9be..00000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.#* -*~ -/hardware/ -/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 687b5684..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-EEPROM-Settings - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-EEPROM-Settings - -See [doc/plugin/EEPROM-Settings.md](doc/plugin/EEPROM-Settings.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index ee68df70..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-EEPROM-Settings -version=0.0.0 -author=Gergely Nagy -maintainer=Gergely Nagy -sentence=Base EEPROM settings plugin for Kaleidoscope. -paragraph=... -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings -architectures=avr -dot_a_linkage=true From b5264f383ff5a0eb5cec47c22dbfb26d0632dec1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 17:59:29 +0200 Subject: [PATCH 764/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/EEPROM-Keymap.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/plugin/EEPROM-Keymap.md b/doc/plugin/EEPROM-Keymap.md index 3fc03667..be343bec 100644 --- a/doc/plugin/EEPROM-Keymap.md +++ b/doc/plugin/EEPROM-Keymap.md @@ -4,7 +4,7 @@ While keyboards usually ship with a keymap programmed in, to be able to change t In short, this plugin allows us to change our keymaps, without having to compile and flash new firmware. It does so through the use of the [FocusSerial][plugin:focusSerial] plugin. - [plugin:focusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial + [plugin:focusSerial]: FocusSerial.md ## Using the plugin @@ -55,11 +55,11 @@ The plugin provides the `keymap.map` and a `keymap.roLayers` commands. ## Dependencies -* [Kaleidoscope-EEPROM-Settings](https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings) -* [Kaleidoscope-FocusSerial](https://github.com/keyboardio/Kaleidoscope-FocusSerial) +* [Kaleidoscope-EEPROM-Settings](EEPROM-Settings.md) +* [Kaleidoscope-FocusSerial](FocusSerial.md) ## Further reading Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-EEPROM-Keymap/blob/master/examples/EEPROM-Keymap/EEPROM-Keymap.ino + [plugin:example]: ../../examples/EEPROM-Keymap/EEPROM-Keymap.ino From 76c041c4285ef656d268212036bd06b7c3325019 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:00:12 +0200 Subject: [PATCH 765/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/EEPROM-Settings.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/plugin/EEPROM-Settings.md b/doc/plugin/EEPROM-Settings.md index ccfb4955..598e7ae3 100644 --- a/doc/plugin/EEPROM-Settings.md +++ b/doc/plugin/EEPROM-Settings.md @@ -123,7 +123,7 @@ The plugin provides two - optional - [Focus][FocusSerial] command plugins: to `KALEIDOSCOPE_INIT_PLUGINS` if one wishes to use them. They provide the following commands: - [FocusSerial]: https://github.com/keyboardio/Kaleidoscope-FocusSerial + [FocusSerial]: FocusSerial.md ### `settings.defaultLayer` @@ -165,4 +165,4 @@ following commands: Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-EEPROM-Settings/blob/master/examples/EEPROM-Settings/EEPROM-Settings.ino + [plugin:example]: ../../examples/EEPROM-Settings/EEPROM-Settings.ino From 79990665251805b1c165f3e5dd003b2075ea554f Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:01:21 +0200 Subject: [PATCH 766/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/FocusSerial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/plugin/FocusSerial.md b/doc/plugin/FocusSerial.md index 7680c73d..8b94a81f 100644 --- a/doc/plugin/FocusSerial.md +++ b/doc/plugin/FocusSerial.md @@ -4,7 +4,7 @@ Bidirectional communication for Kaleidoscope. With this plugin enabled, plugins This plugin is an upgrade of the former [Kaleidoscope-Focus][kaleidoscope:focus] plugin. See the [UPGRADING][upgrading] section for information about how to transition to the new system. - [kaleidoscope:focus]: https://github.com/keyboardio/Kaleidoscope-Focus + [kaleidoscope:focus]: Focus.md [upgrading]: #upgrading-from-focus-to-onfocusevent--focusserial ## Using the plugin @@ -95,7 +95,7 @@ the keyboard responds. Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-FocusSerial/blob/master/examples/FocusSerial/FocusSerial.ino + [plugin:example]: ../../examples/FocusSerial/FocusSerial.ino Upgrading from Focus to onFocusEvent + FocusSerial ================================================== From d21744e637d6f719c46ed7ea5a0d8b3e09ccaa04 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:02:13 +0200 Subject: [PATCH 767/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/HostPowerManagement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plugin/HostPowerManagement.md b/doc/plugin/HostPowerManagement.md index 0a5268cc..bd9973f3 100644 --- a/doc/plugin/HostPowerManagement.md +++ b/doc/plugin/HostPowerManagement.md @@ -44,4 +44,4 @@ The plugin provides the `HostPowerManagement` object, with no public methods. Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-HostPowerManagement/blob/master/examples/HostPowerManagement/HostPowerManagement.ino + [plugin:example]: ../../examples/HostPowerManagement/HostPowerManagement.ino From 9754417c16a12ad1cc5292f6e249597f4924672a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:02:36 +0200 Subject: [PATCH 768/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/LED-AlphaSquare.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/plugin/LED-AlphaSquare.md b/doc/plugin/LED-AlphaSquare.md index 1bb0cb16..cb9384f9 100644 --- a/doc/plugin/LED-AlphaSquare.md +++ b/doc/plugin/LED-AlphaSquare.md @@ -92,14 +92,14 @@ been an exaggeration, there is only one as of this writing: ## Dependencies -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +* [Kaleidoscope-LEDControl](LEDControl.md) ## Further reading Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-AlphaSquare/blob/master/examples/LED-AlphaSquare/LED-AlphaSquare.ino + [plugin:example]: ../../examples/LED-AlphaSquare/LED-AlphaSquare.ino ## Upgrading From d88591eb34fa7a1dbc74f4f1e4c1f8d40bed1ebe Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:03:15 +0200 Subject: [PATCH 769/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/LEDEffect-BootGreeting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plugin/LEDEffect-BootGreeting.md b/doc/plugin/LEDEffect-BootGreeting.md index 29c8e5a2..6e07bf0f 100644 --- a/doc/plugin/LEDEffect-BootGreeting.md +++ b/doc/plugin/LEDEffect-BootGreeting.md @@ -143,4 +143,4 @@ properties: ## Dependencies -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +* [Kaleidoscope-LEDControl](LEDControl.md) From 0af1f06a214cc6d75a3bf6e703ac3d387104f719 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:03:33 +0200 Subject: [PATCH 770/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/LEDEffect-Breathe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plugin/LEDEffect-Breathe.md b/doc/plugin/LEDEffect-Breathe.md index 20b15d5c..72a2c346 100644 --- a/doc/plugin/LEDEffect-Breathe.md +++ b/doc/plugin/LEDEffect-Breathe.md @@ -36,4 +36,4 @@ The plugin provides the `LEDBreatheEffect` object, which has a single property: ## Dependencies -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +* [Kaleidoscope-LEDControl](LEDControl.md) From b59e656c5a1da92625813048f00fd4e5306f92d0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:03:54 +0200 Subject: [PATCH 771/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/LEDEffect-Chase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plugin/LEDEffect-Chase.md b/doc/plugin/LEDEffect-Chase.md index 61a6cbf4..739cd450 100644 --- a/doc/plugin/LEDEffect-Chase.md +++ b/doc/plugin/LEDEffect-Chase.md @@ -26,4 +26,4 @@ properties, outside of those provided by all LED modes. ## Dependencies -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +* [Kaleidoscope-LEDControl](LEDControl.md) From f57d8084a921d731b7c1b9624ff32837af9b0cef Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:04:09 +0200 Subject: [PATCH 772/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/LEDEffect-Rainbow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plugin/LEDEffect-Rainbow.md b/doc/plugin/LEDEffect-Rainbow.md index 55151642..e1b5eebf 100644 --- a/doc/plugin/LEDEffect-Rainbow.md +++ b/doc/plugin/LEDEffect-Rainbow.md @@ -48,4 +48,4 @@ both of which provide the following methods: ## Dependencies -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +* [Kaleidoscope-LEDControl](LEDControl.md) From 8bac58bf099b70d1f259e1bc44a4e39a29c74d80 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:04:24 +0200 Subject: [PATCH 773/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/LEDEffect-SolidColor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plugin/LEDEffect-SolidColor.md b/doc/plugin/LEDEffect-SolidColor.md index d5036233..963bf0f2 100644 --- a/doc/plugin/LEDEffect-SolidColor.md +++ b/doc/plugin/LEDEffect-SolidColor.md @@ -23,7 +23,7 @@ void setup() { ## Dependencies -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +* [Kaleidoscope-LEDControl](LEDControl.md) ## Upgrading From 85d2f246f0a38187d423ffb4e93cec316b5eca20 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:04:39 +0200 Subject: [PATCH 774/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/LED-Stalker.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/plugin/LED-Stalker.md b/doc/plugin/LED-Stalker.md index 20b9eda5..5cf51cf4 100644 --- a/doc/plugin/LED-Stalker.md +++ b/doc/plugin/LED-Stalker.md @@ -74,11 +74,11 @@ The plugin provides the following effects: ## Dependencies -* [Kaleidoscope-LEDControl](https://github.com/keyboardio/Kaleidoscope-LEDControl) +* [Kaleidoscope-LEDControl](LEDControl.md) ## Further reading Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-Stalker/blob/master/examples/LED-Stalker/LED-Stalker.ino + [plugin:example]: ../../examples/LED-Stalker/LED-Stalker.ino From d3e7364ac7d62207099895e272beda3d3d9fe906 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 15:02:13 +0200 Subject: [PATCH 775/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/MagicCombo.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 69 +--------------- .../model01_coordinates.png | Bin UPGRADING.md => doc/plugin/MagicCombo.md | 74 +++++++++++++++++- src/Kaleidoscope-MagicCombo.h | 2 +- .../plugin}/MagicCombo.cpp | 6 +- .../plugin}/MagicCombo.h | 12 ++- 6 files changed, 88 insertions(+), 75 deletions(-) rename docs/rc_layout.png => doc/model01_coordinates.png (100%) rename UPGRADING.md => doc/plugin/MagicCombo.md (65%) rename src/{Kaleidoscope => kaleidoscope/plugin}/MagicCombo.cpp (95%) rename src/{Kaleidoscope => kaleidoscope/plugin}/MagicCombo.h (84%) diff --git a/README.md b/README.md index 73be331a..9091307f 100644 --- a/README.md +++ b/README.md @@ -5,71 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo -The `MagicCombo` extension provides a way to perform custom actions when a -particular set of keys are held down together. The functionality assigned to -these keys are not changed, and the custom action triggers as long as all keys -within the set are pressed. The order in which they were pressed do not matter. - -This can be used to tie complex actions to key chords. - -## Using the extension - -To use the extension, we must include the header, create actions for the magic -combos we want to trigger, and set up a mapping: - -```c++ -#include -#include -#include - -enum { KIND_OF_MAGIC }; - -void kindOfMagic(uint8_t combo_index) { - Macros.type(PSTR("It's a kind of magic!")); -} - -USE_MAGIC_COMBOS( -[KIND_OF_MAGIC] = { - .action = kindOfMagic, - .keys = {R3C6, R3C9} // Left Fn + Right Fn -}); - -KALEIDOSCOPE_INIT_PLUGINS(MagicCombo, Macros); - -void setup() { - Kaleidoscope.setup(); -} -``` - -It is recommended to use the `RxCy` macros of the core firmware to set the keys -that are part of a combination. - -## Plugin properties - -The extension provides a `MagicCombo` singleton object, with the following -property: - -### `.min_interval` - -> Restrict the magic action to fire at most once every `min_interval` -> milliseconds. -> -> Defaults to 500. - -## Plugin callbacks - -Whenever a combination is found to be held, the plugin will trigger the -specified action, which is just a regular method with a single `uint8_t` -argument: the index of the magic combo. This function will be called repeatedly -(every `min_interval` milliseconds) while the combination is held. - -## Further reading - -Starting from the [example][plugin:example] is the recommended way of getting -started with the plugin. - -`RxCy` coordinates for a Model01: - -![rxcy layout](./docs/rc_layout.png) - - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino +See [doc/plugin/MagicCombo.md](doc/plugin/MagicCombo.md) for documentation. diff --git a/docs/rc_layout.png b/doc/model01_coordinates.png similarity index 100% rename from docs/rc_layout.png rename to doc/model01_coordinates.png diff --git a/UPGRADING.md b/doc/plugin/MagicCombo.md similarity index 65% rename from UPGRADING.md rename to doc/plugin/MagicCombo.md index 1c9652d4..b86d2996 100644 --- a/UPGRADING.md +++ b/doc/plugin/MagicCombo.md @@ -1,5 +1,75 @@ -Breaking changes in `MagicCombo` -================================ +# Kaleidoscope-MagicCombo + +The `MagicCombo` extension provides a way to perform custom actions when a +particular set of keys are held down together. The functionality assigned to +these keys are not changed, and the custom action triggers as long as all keys +within the set are pressed. The order in which they were pressed do not matter. + +This can be used to tie complex actions to key chords. + +## Using the extension + +To use the extension, we must include the header, create actions for the magic +combos we want to trigger, and set up a mapping: + +```c++ +#include +#include +#include + +enum { KIND_OF_MAGIC }; + +void kindOfMagic(uint8_t combo_index) { + Macros.type(PSTR("It's a kind of magic!")); +} + +USE_MAGIC_COMBOS( +[KIND_OF_MAGIC] = { + .action = kindOfMagic, + .keys = {R3C6, R3C9} // Left Fn + Right Fn +}); + +KALEIDOSCOPE_INIT_PLUGINS(MagicCombo, Macros); + +void setup() { + Kaleidoscope.setup(); +} +``` + +It is recommended to use the `RxCy` macros of the core firmware to set the keys +that are part of a combination. + +## Plugin properties + +The extension provides a `MagicCombo` singleton object, with the following +property: + +### `.min_interval` + +> Restrict the magic action to fire at most once every `min_interval` +> milliseconds. +> +> Defaults to 500. + +## Plugin callbacks + +Whenever a combination is found to be held, the plugin will trigger the +specified action, which is just a regular method with a single `uint8_t` +argument: the index of the magic combo. This function will be called repeatedly +(every `min_interval` milliseconds) while the combination is held. + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting +started with the plugin. + +`RxCy` coordinates for a Model01: + +![rxcy layout](../model01_coordinates.png) + + [plugin:example]: https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino + +## Upgrading To make `MagicCombo` more portable, and easier to use, we had to break the API previously provided, there was no way to maintain backwards compatibility. This diff --git a/src/Kaleidoscope-MagicCombo.h b/src/Kaleidoscope-MagicCombo.h index 588dec13..ed5c3699 100644 --- a/src/Kaleidoscope-MagicCombo.h +++ b/src/Kaleidoscope-MagicCombo.h @@ -17,4 +17,4 @@ #pragma once -#include +#include diff --git a/src/Kaleidoscope/MagicCombo.cpp b/src/kaleidoscope/plugin/MagicCombo.cpp similarity index 95% rename from src/Kaleidoscope/MagicCombo.cpp rename to src/kaleidoscope/plugin/MagicCombo.cpp index a9c30f92..3dcd3ac5 100644 --- a/src/Kaleidoscope/MagicCombo.cpp +++ b/src/kaleidoscope/plugin/MagicCombo.cpp @@ -18,6 +18,7 @@ #include namespace kaleidoscope { +namespace plugin { uint16_t MagicCombo::min_interval = 500; uint32_t MagicCombo::end_time_; @@ -52,6 +53,7 @@ EventHandlerResult MagicCombo::beforeReportingState() { return EventHandlerResult::OK; } -}; +} +} -kaleidoscope::MagicCombo MagicCombo; +kaleidoscope::plugin::MagicCombo MagicCombo; diff --git a/src/Kaleidoscope/MagicCombo.h b/src/kaleidoscope/plugin/MagicCombo.h similarity index 84% rename from src/Kaleidoscope/MagicCombo.h rename to src/kaleidoscope/plugin/MagicCombo.h index bd0e710c..35706c26 100644 --- a/src/Kaleidoscope/MagicCombo.h +++ b/src/kaleidoscope/plugin/MagicCombo.h @@ -23,11 +23,14 @@ #define USE_MAGIC_COMBOS(...) \ namespace kaleidoscope { \ + namespace plugin { \ namespace magiccombo { \ - const kaleidoscope::MagicCombo::Combo combos[] PROGMEM = {__VA_ARGS__}; \ + const kaleidoscope::plugin::MagicCombo::Combo combos[] PROGMEM = \ + {__VA_ARGS__}; \ \ const uint8_t combos_length = sizeof(combos) / sizeof(*combos); \ } \ + } \ } #define _MAGICCOMBO_API_CHANGE \ @@ -38,6 +41,7 @@ " https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/UPGRADING.md" namespace kaleidoscope { +namespace plugin { class MagicCombo : public kaleidoscope::Plugin { public: @@ -73,4 +77,8 @@ extern const uint8_t combos_length; } -extern kaleidoscope::MagicCombo MagicCombo; +// Backward compatibility +typedef plugin::MagicCombo MagicCombo; +} + +extern kaleidoscope::plugin::MagicCombo MagicCombo; From 740494f629fc5a2090077a2b4930cf35add1e996 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 13 Oct 2018 15:04:52 +0200 Subject: [PATCH 776/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .gitignore | 4 - .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 7 files changed, 774 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.gitignore b/.gitignore deleted file mode 100644 index be16c9be..00000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.#* -*~ -/hardware/ -/output/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 9091307f..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-MagicCombo - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MagicCombo - -See [doc/plugin/MagicCombo.md](doc/plugin/MagicCombo.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index f12d0606..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-MagicCombo -version=0.0.0 -author=Gergely Nagy -maintainer=Gergely Nagy -sentence=Magic combo framework for Kaleidoscope. -paragraph=Provides hooks for Kaleidoscope, to make it possible to run code on certain magic combinations. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-MagicCombo -architectures=avr -dot_a_linkage=true From f83b1c2b87deaea7a743faafa7f22c884e56033d Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 18:05:07 +0200 Subject: [PATCH 777/792] Update the documentation links Updates the example and dependency links in the documentation, to use URLs that are valid within the monorepo. Signed-off-by: Gergely Nagy --- doc/plugin/MagicCombo.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/plugin/MagicCombo.md b/doc/plugin/MagicCombo.md index b86d2996..2e240222 100644 --- a/doc/plugin/MagicCombo.md +++ b/doc/plugin/MagicCombo.md @@ -67,7 +67,7 @@ started with the plugin. ![rxcy layout](../model01_coordinates.png) - [plugin:example]: https://github.com/keyboardio/Kaleidoscope-MagicCombo/blob/master/examples/MagicCombo/MagicCombo.ino + [plugin:example]: ../../examples/MagicCombo/MagicCombo.ino ## Upgrading @@ -80,7 +80,7 @@ Migration should be a straightforward process, but if you get stuck, please feel free to [open an issue][gh:issues], or start a thread on the [forums][forums], and we'll help you with it. - [gh:issues]: https://github.com/keyboardio/Kaleidoscope-MagicCombo/issues + [gh:issues]: https://github.com/keyboardio/Kaleidoscope/issues [forums]: https://community.keyboard.io/ ## The old API @@ -133,7 +133,7 @@ The new API is much shorter, and is inspired by the way the [Leader][leader] plugin works: instead of having a list, and a dispatching function like `magicComboActions`, we include the action method in the list too! - [leader]: https://github.com/keyboardio/Kaleidoscope-Leader + [leader]: Leader.md We also don't make a difference between left- and right-hand anymore, you can just list keys for either in the same list. This will be very handy for From 09c48b8da245e723406cb36fcf0b9947106cd2f7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:47:52 +0200 Subject: [PATCH 778/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/NumPad.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 39 ++------------- doc/plugin/NumPad.md | 39 +++++++++++++++ src/Kaleidoscope-NumPad.h | 30 +---------- .../plugin/NumPad.cpp} | 50 +++++++++---------- src/kaleidoscope/plugin/NumPad.h | 50 +++++++++++++++++++ 5 files changed, 119 insertions(+), 89 deletions(-) create mode 100644 doc/plugin/NumPad.md rename src/{Kaleidoscope-NumPad.cpp => kaleidoscope/plugin/NumPad.cpp} (67%) create mode 100644 src/kaleidoscope/plugin/NumPad.h diff --git a/README.md b/README.md index 83bc5629..a761cab0 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,8 @@ # Kaleidoscope-NumPad -This is a plugin for [Kaleidoscope][fw], that adds a NumPad-specific LED -effect, along with a way to toggle to a numpad layer, and apply the effect. +[![Build Status][travis:image]][travis:status] -## Using the extension + [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-NumPad.svg?branch=master + [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-NumPad -To use the plugin, include the header, and tell the firmware to use it: - -```c++ -#include "Kaleidoscope-NumPad.h" - -KALEIDOSCOPE_INIT_PLUGINS(NumPad); - -void setup() { - Kaleidoscope.setup(); - - NumPad.color = CRGB(0, 0, 160); // a blue color - NumPad.lock_hue = 85; // green -} -``` - -## Plugin methods - -The plugin provides the `NumPad` object, with the following properties: - -### `.color` - -> This property sets the color that the NumPad keys are highlighted in. -> -> The default is `CRGB(160, 0, 0)`, a red color. - -### `.lock_hue` - -> This property sets the color hue that the NumLock LED breathes in. -> -> The default is `170`, a blue hue. - - [fw]: https://github.com/keyboardio/Kaleidoscope +See [doc/plugin/NumPad.md](doc/plugin/NumPad.md) for documentation. diff --git a/doc/plugin/NumPad.md b/doc/plugin/NumPad.md new file mode 100644 index 00000000..83bc5629 --- /dev/null +++ b/doc/plugin/NumPad.md @@ -0,0 +1,39 @@ +# Kaleidoscope-NumPad + +This is a plugin for [Kaleidoscope][fw], that adds a NumPad-specific LED +effect, along with a way to toggle to a numpad layer, and apply the effect. + +## Using the extension + +To use the plugin, include the header, and tell the firmware to use it: + +```c++ +#include "Kaleidoscope-NumPad.h" + +KALEIDOSCOPE_INIT_PLUGINS(NumPad); + +void setup() { + Kaleidoscope.setup(); + + NumPad.color = CRGB(0, 0, 160); // a blue color + NumPad.lock_hue = 85; // green +} +``` + +## Plugin methods + +The plugin provides the `NumPad` object, with the following properties: + +### `.color` + +> This property sets the color that the NumPad keys are highlighted in. +> +> The default is `CRGB(160, 0, 0)`, a red color. + +### `.lock_hue` + +> This property sets the color hue that the NumLock LED breathes in. +> +> The default is `170`, a blue hue. + + [fw]: https://github.com/keyboardio/Kaleidoscope diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h index 016ded65..be0c76f6 100644 --- a/src/Kaleidoscope-NumPad.h +++ b/src/Kaleidoscope-NumPad.h @@ -16,32 +16,4 @@ #pragma once -#include "Kaleidoscope-LEDControl.h" -#include "Kaleidoscope-Macros.h" -#include "LEDUtils.h" - -class NumPad_ : public kaleidoscope::Plugin { - public: - NumPad_(void) {} - - static uint8_t numPadLayer; - static cRGB color; - static uint8_t lock_hue; - - kaleidoscope::EventHandlerResult onSetup(void); - kaleidoscope::EventHandlerResult afterEachCycle(); - - private: - - void cleanupNumlockState(void); - void setKeyboardLEDColors(void); - bool getNumlockState(void); - void syncNumlockState(bool); - - static uint8_t numpadLayerToggleKeyRow; - static uint8_t numpadLayerToggleKeyCol; - static bool numlockUnsynced; - static bool originalNumLockState; -}; - -extern NumPad_ NumPad; +#include "kaleidoscope/plugin/NumPad.h" diff --git a/src/Kaleidoscope-NumPad.cpp b/src/kaleidoscope/plugin/NumPad.cpp similarity index 67% rename from src/Kaleidoscope-NumPad.cpp rename to src/kaleidoscope/plugin/NumPad.cpp index e5275bc2..6b49ae05 100644 --- a/src/Kaleidoscope-NumPad.cpp +++ b/src/kaleidoscope/plugin/NumPad.cpp @@ -15,26 +15,27 @@ */ #include "Kaleidoscope-NumPad.h" -#include "LEDUtils.h" -#include "Kaleidoscope.h" -byte NumPad_::numpadLayerToggleKeyRow = 255, NumPad_::numpadLayerToggleKeyCol = 255; -uint8_t NumPad_::numPadLayer; -bool NumPad_::numlockUnsynced = false; -bool NumPad_::originalNumLockState = false; -cRGB NumPad_::color = CRGB(160, 0, 0); -uint8_t NumPad_::lock_hue = 170; +namespace kaleidoscope { +namespace plugin { -kaleidoscope::EventHandlerResult NumPad_::onSetup(void) { +byte NumPad::numpadLayerToggleKeyRow = 255, NumPad::numpadLayerToggleKeyCol = 255; +uint8_t NumPad::numPadLayer; +bool NumPad::numlockUnsynced = false; +bool NumPad::originalNumLockState = false; +cRGB NumPad::color = CRGB(160, 0, 0); +uint8_t NumPad::lock_hue = 170; + +EventHandlerResult NumPad::onSetup(void) { originalNumLockState = getNumlockState(); - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; } -bool NumPad_::getNumlockState() { +bool NumPad::getNumlockState() { return !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK); } -void NumPad_::syncNumlockState(bool state) { +void NumPad::syncNumlockState(bool state) { bool numLockLEDState = getNumlockState(); if (numLockLEDState != state) { kaleidoscope::hid::pressKey(Key_KeypadNumLock); @@ -43,10 +44,10 @@ void NumPad_::syncNumlockState(bool state) { -void NumPad_::cleanupNumlockState() { +void NumPad::cleanupNumlockState() { if (!numlockUnsynced) { bool numLockLEDState = getNumlockState(); - LEDControl.set_mode(LEDControl.get_mode_index()); + ::LEDControl.set_mode(::LEDControl.get_mode_index()); if (!originalNumLockState) { syncNumlockState(false); numLockLEDState = false; @@ -57,8 +58,8 @@ void NumPad_::cleanupNumlockState() { } -void NumPad_::setKeyboardLEDColors(void) { - LEDControl.set_mode(LEDControl.get_mode_index()); +void NumPad::setKeyboardLEDColors(void) { + ::LEDControl.set_mode(::LEDControl.get_mode_index()); for (uint8_t r = 0; r < ROWS; r++) { for (uint8_t c = 0; c < COLS; c++) { @@ -71,22 +72,20 @@ void NumPad_::setKeyboardLEDColors(void) { } if ((k != layer_key) || (k == Key_NoKey) || (k.flags != KEY_FLAGS)) { - LEDControl.refreshAt(r, c); + ::LEDControl.refreshAt(r, c); } else { - LEDControl.setCrgbAt(r, c, color); + ::LEDControl.setCrgbAt(r, c, color); } } } if ((numpadLayerToggleKeyRow <= ROWS) && (numpadLayerToggleKeyCol <= COLS)) { - - cRGB lock_color = breath_compute(lock_hue); - LEDControl.setCrgbAt(numpadLayerToggleKeyRow, numpadLayerToggleKeyCol, lock_color); + ::LEDControl.setCrgbAt(numpadLayerToggleKeyRow, numpadLayerToggleKeyCol, lock_color); } } -kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { +EventHandlerResult NumPad::afterEachCycle() { if (!Layer.isOn(numPadLayer)) { cleanupNumlockState(); } else { @@ -97,9 +96,10 @@ kaleidoscope::EventHandlerResult NumPad_::afterEachCycle() { } setKeyboardLEDColors(); } - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; } +} +} - -NumPad_ NumPad; +kaleidoscope::plugin::NumPad NumPad; diff --git a/src/kaleidoscope/plugin/NumPad.h b/src/kaleidoscope/plugin/NumPad.h new file mode 100644 index 00000000..8735cd84 --- /dev/null +++ b/src/kaleidoscope/plugin/NumPad.h @@ -0,0 +1,50 @@ +/* Kaleidoscope-NumPad - A NumPad plugin for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope-LEDControl.h" + +namespace kaleidoscope { +namespace plugin { + +class NumPad : public kaleidoscope::Plugin { + public: + NumPad(void) {} + + static uint8_t numPadLayer; + static cRGB color; + static uint8_t lock_hue; + + EventHandlerResult onSetup(void); + EventHandlerResult afterEachCycle(); + + private: + + void cleanupNumlockState(void); + void setKeyboardLEDColors(void); + bool getNumlockState(void); + void syncNumlockState(bool); + + static uint8_t numpadLayerToggleKeyRow; + static uint8_t numpadLayerToggleKeyCol; + static bool numlockUnsynced; + static bool originalNumLockState; +}; +} +} + +extern kaleidoscope::plugin::NumPad NumPad; From cbbdcc3e0da9a7dd9c9a1a813e81f10f9fca24de Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:47:53 +0200 Subject: [PATCH 779/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 770 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index a761cab0..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-NumPad - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-NumPad.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-NumPad - -See [doc/plugin/NumPad.md](doc/plugin/NumPad.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 1155e73c..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-NumPad -version=0.0.1 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=A NumPad plugin for Kaleidoscope. -paragraph=... -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-NumPad -architectures=avr -dot_a_linkage=true From 0683faeb79fb590e0556286f869fc884964f8961 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:43:26 +0200 Subject: [PATCH 780/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/MouseKeys.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 245 +---------------- doc/plugin/MouseKeys.md | 246 ++++++++++++++++++ src/Kaleidoscope-MouseKeys.h | 34 +-- src/MouseWrapper.h | 52 +--- src/{ => kaleidoscope/plugin}/MouseKeyDefs.h | 0 .../plugin/MouseKeys.cpp} | 30 ++- src/kaleidoscope/plugin/MouseKeys.h | 55 ++++ .../plugin}/MouseWarpModes.h | 0 .../plugin}/MouseWrapper.cpp | 7 +- src/kaleidoscope/plugin/MouseWrapper.h | 74 ++++++ 10 files changed, 403 insertions(+), 340 deletions(-) create mode 100644 doc/plugin/MouseKeys.md rename src/{ => kaleidoscope/plugin}/MouseKeyDefs.h (100%) rename src/{Kaleidoscope-MouseKeys.cpp => kaleidoscope/plugin/MouseKeys.cpp} (88%) create mode 100644 src/kaleidoscope/plugin/MouseKeys.h rename src/{ => kaleidoscope/plugin}/MouseWarpModes.h (100%) rename src/{ => kaleidoscope/plugin}/MouseWrapper.cpp (98%) create mode 100644 src/kaleidoscope/plugin/MouseWrapper.h diff --git a/README.md b/README.md index 610ad246..842a8b11 100644 --- a/README.md +++ b/README.md @@ -5,247 +5,4 @@ [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MouseKeys.svg?branch=master [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MouseKeys -Have you ever wanted to control the mouse cursor from the comfort of your -keyboard? With this plugin, you can. While it may not replace the mouse in all -situations, there are plenty of cases where one will not have to lift their -hands off the keyboard just to nudge the mouse cursor away a little. - -Of course, there are a lot more one can do with the plugin than to nudge the -cursor! Mouse keys are provided for all four *and* diagonal movement; mouse -buttons; and a unique warping mechanism too. And not only these: the speed of -the cursor, the mouse wheel, and that of acceleration can all be configured to -match one's desired behaviour. - -## Using the plugin - -To use the plugin, simply include the header in your Sketch, tell the firmware -to use the `MouseKeys` object, and place mouse keys on your keymap. It is best -illustrated with an example: - -```c++ -#include -#include - -// Somewhere in the keymap: -Key_mouseUp, Key_mouseDn, Key_mouseL, Key_mouseR, -Key_mouseBtnL, Key_mouseBtnR - -KALEIDOSCOPE_INIT_PLUGINS(MouseKeys); - -void setup() { - Kaleidoscope.setup (); -} -``` - -## Keys provided by the plugin - -The plugin provides a number of keys one can put on the keymap, that allow -control of the mouse. They can be divided into a few groups: - -### Cursor movement - -The simplest set of keys are the mouse cursor movement keys. These move the -cursor one direction or the other, with speed and acceleration factored in. When -a mouse cursor movement key is held down, it will move `.speed` pixels each -`.speedDelay` milliseconds without acceleration. But when `.accelSpeed` is -non-zero (and it is not zero by default, -see [below](#accelspeed-and-acceldelay)), the speed will increase by -`.accelSpeed` every `.accelDelay` milliseconds. Thus, unless configured -otherwise, holding a direction will move that way at increasing speed. - -One can hold more than one key down at the same time, and the cursor will move -towards a direction that is the combination of the keys held. For example, -holding the "mouse up" and "mouse right" keys together will move the cursor -diagonally up and right. - -The cursor movement keys are as follows: - -* `Key_mouseUp`, `Key_mouseDn`, `Key_mouseL`, `Key_mouseR`: Move the cursor up, - down, left, or right, respectively. -* `Key_mouseUpL`, `Key_mouseUpR`, `Key_mouseDnL`, `Key_mouseDnR`: Move the - cursor up-left, up-right, down-left, down-right, respectively. - -### Scroll wheel - -Controlling the scroll wheel is similarly simple. It does not have acceleration, -but one can control the speed with the `.wheelSpeed` and `.wheelDelay` -properties (see below). - -* `Key_mouseScrollUp`, `Key_mouseScrollDn`: Scroll the mouse wheel up or down, - respectively. -* `Key_mouseScrollL`, `Key_mouseScrollR`: Scroll the mouse wheel left or right, - respectively. - -### Buttons - -Buttons are even simpler than movement: there is no movement speed, nor -acceleration involved. One just presses them. - -* `Key_mouseBtnL`, `Key_mouseBtnM`, `Key_mouseBtnR`, `Key_mouseBtnP`, - `Key_mouseBtnN`: The left, middle, right, previous, and next mouse buttons, - respectively. - -## Warping - -Warping is one of the most interesting features of the plugin, and is a feature -unique to Kaleidoscope, as far as we can tell. The warping keys position the -mouse cursor within a sector of the screen on first press, and any subsequent -taps will warp within the previously selected sector. For example, pressing the -north-west warp key twice will first jump to the middle of the north-west -sector of your screen, then select the north-west sector of that, and jump to -the middle of it. - -To stop warping, use any other mouse key, or hit the "warp end" key. - -### Warp grid size - -The warp grid size determines how MouseKeys partitions the screen to select the -next position to jump to when pressing a warp key. The plugin provides two grid -sizes to choose from: a *2x2* grid that splits the screen into quadrants, and a -*3x3* grid with nine cells similar to a navigation feature included with some -speech recognition software. By default, the plugin splits the screen into the -2x2 grid. - -To change the warp grid size, call the plugin's `setWarpGridSize()` method: - -```c++ -MouseKeys.setWarpGridSize(MOUSE_WARP_GRID_3X3); -``` - -#### 2x2 grid - -As described above, MouseKeys warps the pointer using a grid model that reflects -locations on the screen. By default, the plugin uses a 2x2 grid. To understand -how warping works, examine this diagram of a screen split into that 2x2 grid: - - +-----------------------|-----------------------+ - | | | | - | G | tab | | - | | | | - |-----------|-----------| tab | - | | | | - | B | esc | | - | | | | - +-----------------------|-----------------------+ - | | | - | | | - | | | - | B | esc | - | | | - | | | - | | | - +-----------------------|-----------------------+ - -Each quadrant is labed with a key that, when pressed, moves the mouse pointer -to the center of that quadrant. With this layout, pressing G warps -the pointer to the top-left quadant. Then, the plugin "zooms" into that sector -with a smaller grid so that the next warp key pressed jumps the pointer more -precisely within the sector. In this case, if we press esc next, -the pointer warps to the bottom-right corner within that quadrant. - -The warping keys for the 2x2 grid are the following: - -* `Key_mouseWarpNW`, `Key_mouseWarpNE`, `Key_mouseWarpSW`, `Key_mouseWarpSE`: - Warp towards the north-west, north-east, south-west, or south-east quadrants, - respectively. -* `Key_mouseWarpEnd`: End the warping sequence, resetting it to the default - state. Using any of the warping keys after this will start from the whole - screen again. - -#### 3x3 grid - -A 3x3 warp grid assigns a key to each of nine sectors of the screen. The next -diagram shows a screen with a key label that warps to each sector. As we can -see, pressing W warps the pointer into the top-left sector, and -pressing V warps to the bottom-right corner within that sector: - - +-----------------|-----------------|-----------------+ - | W | E | R | | | - |-----|-----|-----| | | - | S | D | F | E | R | - |-----|-----|-----| | | - | X | C | V | | | - +-----------------|-----------------|-----------------+ - | | | | - | | | | - | S | D | F | - | | | | - | | | | - +-----------------|-----------------|-----------------+ - | | | | - | | | | - | X | C | V | - | | | | - | | | | - +-----------------|-----------------|-----------------+ - -To use a 3x3 warp grid, we may need to remap some keys. A suggested warp key -mapping is shown below on the left side of a keyboard with a QWERTY layout: - - W | E | R T A - End Warping (Key_mouseWarpEnd) - ---|---|--- W - Warp NW Sector (Key_mouseWarpNW) - A S | D | F G E - Warp N Sector (Key_mouseWarpN) - ---|---|--- R - Warp NE Sector (Key_mouseWarpNE) - X | C | V B S - Warp E Sector (Key_mouseWarpE) - D - Warp/Zoom Center (Key_mouseWarpIn) - F - Warp W Sector (Key_mouseWarpW) - K - Warp SE Sector (Key_mouseWarpSE) - C - Warp S Sector (Key_mouseWarpS) - V - Warp SW Sector (Key_mouseWarpSW) - T - Right Click (Key_mouseBtnR) - G - Left Click (Key_mouseBtnL) - B - Middle Click (Key_mouseBtnM) - -This example layout replaces the default directional mouse keys and sets the -warp keys in a comfortable position for a warp-only configuration. Of course, -a Kaleidoscope user may retain the directional keys and map the warp keys -elsewhere according to his or her liking. - -A 3x3 warp grid layout contains all of the keys from the 2x2 grid layout with -the following additions: - -* `Key_mouseWarpN`, `Key_mouseWarpE`, `Key_mouseWarpS`, `Key_mouseWarpW`: - Warp towards the north, east, south, and west sectors, respectively. -* `Key_mouseWarpIn`: Warp to the center sector of the grid. The plugin will - continue to "zoom" into center of the current cell with each consecutive - press of this key. - -## Plugin methods - -The plugin provides a `MouseKeys` object, with the following methods and -properties available: - -### `.speed` and `.speedDelay` - -> These two control the speed of the mouse cursor, when a movement key is held. -> The former, `.speed`, controls the amount of pixels the cursor moves, when it -> has to move, and defaults to 1. The latter, `.speedDelay` is the amount of -> time - in milliseconds - to wait between two movements, and defaults to 0, no -> delay. - -### `.accelSpeed` and `.accelDelay` - -> These two properties control the speed of acceleration. The former, -> `.accelSpeed`, controls how much the speed shall be increased at each step, -> while the second, `.accelDelay`, controls how often (in milliseconds) -> acceleration should be applied. -> -> They default to 1 pixel and 50 milliseconds, respectively. - -### `.wheelSpeed` and `.wheelDelay` - -> The last two properties supported by the plugin control the mouse wheel -> scrolling speed. The former, `.wheelSpeed`, controls the amount of ticks the -> wheel shall scroll, and defaults to 1. The second, `.wheelDelay`, controls the -> delay between two scroll events, and defaults to 50 milliseconds. - -### `.setSpeedLimit` - -> This method sets the maximum speed after which acceleration stops. -> The default is 127, and the minimum value is 16 (things will not work -> properly below 16). - -### `.setWarpGridSize` - -> This method changes the size of the grid used for [warping](#warping). The -> following are valid sizes: `MOUSE_WARP_GRID_2X2`, `MOUSE_WARP_GRID_3X3` +See [doc/plugin/MouseKeys.md](doc/plugin/MouseKeys.md) for documentation. diff --git a/doc/plugin/MouseKeys.md b/doc/plugin/MouseKeys.md new file mode 100644 index 00000000..a095a726 --- /dev/null +++ b/doc/plugin/MouseKeys.md @@ -0,0 +1,246 @@ +# Kaleidoscope-MouseKeys + +Have you ever wanted to control the mouse cursor from the comfort of your +keyboard? With this plugin, you can. While it may not replace the mouse in all +situations, there are plenty of cases where one will not have to lift their +hands off the keyboard just to nudge the mouse cursor away a little. + +Of course, there are a lot more one can do with the plugin than to nudge the +cursor! Mouse keys are provided for all four *and* diagonal movement; mouse +buttons; and a unique warping mechanism too. And not only these: the speed of +the cursor, the mouse wheel, and that of acceleration can all be configured to +match one's desired behaviour. + +## Using the plugin + +To use the plugin, simply include the header in your Sketch, tell the firmware +to use the `MouseKeys` object, and place mouse keys on your keymap. It is best +illustrated with an example: + +```c++ +#include +#include + +// Somewhere in the keymap: +Key_mouseUp, Key_mouseDn, Key_mouseL, Key_mouseR, +Key_mouseBtnL, Key_mouseBtnR + +KALEIDOSCOPE_INIT_PLUGINS(MouseKeys); + +void setup() { + Kaleidoscope.setup (); +} +``` + +## Keys provided by the plugin + +The plugin provides a number of keys one can put on the keymap, that allow +control of the mouse. They can be divided into a few groups: + +### Cursor movement + +The simplest set of keys are the mouse cursor movement keys. These move the +cursor one direction or the other, with speed and acceleration factored in. When +a mouse cursor movement key is held down, it will move `.speed` pixels each +`.speedDelay` milliseconds without acceleration. But when `.accelSpeed` is +non-zero (and it is not zero by default, +see [below](#accelspeed-and-acceldelay)), the speed will increase by +`.accelSpeed` every `.accelDelay` milliseconds. Thus, unless configured +otherwise, holding a direction will move that way at increasing speed. + +One can hold more than one key down at the same time, and the cursor will move +towards a direction that is the combination of the keys held. For example, +holding the "mouse up" and "mouse right" keys together will move the cursor +diagonally up and right. + +The cursor movement keys are as follows: + +* `Key_mouseUp`, `Key_mouseDn`, `Key_mouseL`, `Key_mouseR`: Move the cursor up, + down, left, or right, respectively. +* `Key_mouseUpL`, `Key_mouseUpR`, `Key_mouseDnL`, `Key_mouseDnR`: Move the + cursor up-left, up-right, down-left, down-right, respectively. + +### Scroll wheel + +Controlling the scroll wheel is similarly simple. It does not have acceleration, +but one can control the speed with the `.wheelSpeed` and `.wheelDelay` +properties (see below). + +* `Key_mouseScrollUp`, `Key_mouseScrollDn`: Scroll the mouse wheel up or down, + respectively. +* `Key_mouseScrollL`, `Key_mouseScrollR`: Scroll the mouse wheel left or right, + respectively. + +### Buttons + +Buttons are even simpler than movement: there is no movement speed, nor +acceleration involved. One just presses them. + +* `Key_mouseBtnL`, `Key_mouseBtnM`, `Key_mouseBtnR`, `Key_mouseBtnP`, + `Key_mouseBtnN`: The left, middle, right, previous, and next mouse buttons, + respectively. + +## Warping + +Warping is one of the most interesting features of the plugin, and is a feature +unique to Kaleidoscope, as far as we can tell. The warping keys position the +mouse cursor within a sector of the screen on first press, and any subsequent +taps will warp within the previously selected sector. For example, pressing the +north-west warp key twice will first jump to the middle of the north-west +sector of your screen, then select the north-west sector of that, and jump to +the middle of it. + +To stop warping, use any other mouse key, or hit the "warp end" key. + +### Warp grid size + +The warp grid size determines how MouseKeys partitions the screen to select the +next position to jump to when pressing a warp key. The plugin provides two grid +sizes to choose from: a *2x2* grid that splits the screen into quadrants, and a +*3x3* grid with nine cells similar to a navigation feature included with some +speech recognition software. By default, the plugin splits the screen into the +2x2 grid. + +To change the warp grid size, call the plugin's `setWarpGridSize()` method: + +```c++ +MouseKeys.setWarpGridSize(MOUSE_WARP_GRID_3X3); +``` + +#### 2x2 grid + +As described above, MouseKeys warps the pointer using a grid model that reflects +locations on the screen. By default, the plugin uses a 2x2 grid. To understand +how warping works, examine this diagram of a screen split into that 2x2 grid: + + +-----------------------|-----------------------+ + | | | | + | G | tab | | + | | | | + |-----------|-----------| tab | + | | | | + | B | esc | | + | | | | + +-----------------------|-----------------------+ + | | | + | | | + | | | + | B | esc | + | | | + | | | + | | | + +-----------------------|-----------------------+ + +Each quadrant is labed with a key that, when pressed, moves the mouse pointer +to the center of that quadrant. With this layout, pressing G warps +the pointer to the top-left quadant. Then, the plugin "zooms" into that sector +with a smaller grid so that the next warp key pressed jumps the pointer more +precisely within the sector. In this case, if we press esc next, +the pointer warps to the bottom-right corner within that quadrant. + +The warping keys for the 2x2 grid are the following: + +* `Key_mouseWarpNW`, `Key_mouseWarpNE`, `Key_mouseWarpSW`, `Key_mouseWarpSE`: + Warp towards the north-west, north-east, south-west, or south-east quadrants, + respectively. +* `Key_mouseWarpEnd`: End the warping sequence, resetting it to the default + state. Using any of the warping keys after this will start from the whole + screen again. + +#### 3x3 grid + +A 3x3 warp grid assigns a key to each of nine sectors of the screen. The next +diagram shows a screen with a key label that warps to each sector. As we can +see, pressing W warps the pointer into the top-left sector, and +pressing V warps to the bottom-right corner within that sector: + + +-----------------|-----------------|-----------------+ + | W | E | R | | | + |-----|-----|-----| | | + | S | D | F | E | R | + |-----|-----|-----| | | + | X | C | V | | | + +-----------------|-----------------|-----------------+ + | | | | + | | | | + | S | D | F | + | | | | + | | | | + +-----------------|-----------------|-----------------+ + | | | | + | | | | + | X | C | V | + | | | | + | | | | + +-----------------|-----------------|-----------------+ + +To use a 3x3 warp grid, we may need to remap some keys. A suggested warp key +mapping is shown below on the left side of a keyboard with a QWERTY layout: + + W | E | R T A - End Warping (Key_mouseWarpEnd) + ---|---|--- W - Warp NW Sector (Key_mouseWarpNW) + A S | D | F G E - Warp N Sector (Key_mouseWarpN) + ---|---|--- R - Warp NE Sector (Key_mouseWarpNE) + X | C | V B S - Warp E Sector (Key_mouseWarpE) + D - Warp/Zoom Center (Key_mouseWarpIn) + F - Warp W Sector (Key_mouseWarpW) + K - Warp SE Sector (Key_mouseWarpSE) + C - Warp S Sector (Key_mouseWarpS) + V - Warp SW Sector (Key_mouseWarpSW) + T - Right Click (Key_mouseBtnR) + G - Left Click (Key_mouseBtnL) + B - Middle Click (Key_mouseBtnM) + +This example layout replaces the default directional mouse keys and sets the +warp keys in a comfortable position for a warp-only configuration. Of course, +a Kaleidoscope user may retain the directional keys and map the warp keys +elsewhere according to his or her liking. + +A 3x3 warp grid layout contains all of the keys from the 2x2 grid layout with +the following additions: + +* `Key_mouseWarpN`, `Key_mouseWarpE`, `Key_mouseWarpS`, `Key_mouseWarpW`: + Warp towards the north, east, south, and west sectors, respectively. +* `Key_mouseWarpIn`: Warp to the center sector of the grid. The plugin will + continue to "zoom" into center of the current cell with each consecutive + press of this key. + +## Plugin methods + +The plugin provides a `MouseKeys` object, with the following methods and +properties available: + +### `.speed` and `.speedDelay` + +> These two control the speed of the mouse cursor, when a movement key is held. +> The former, `.speed`, controls the amount of pixels the cursor moves, when it +> has to move, and defaults to 1. The latter, `.speedDelay` is the amount of +> time - in milliseconds - to wait between two movements, and defaults to 0, no +> delay. + +### `.accelSpeed` and `.accelDelay` + +> These two properties control the speed of acceleration. The former, +> `.accelSpeed`, controls how much the speed shall be increased at each step, +> while the second, `.accelDelay`, controls how often (in milliseconds) +> acceleration should be applied. +> +> They default to 1 pixel and 50 milliseconds, respectively. + +### `.wheelSpeed` and `.wheelDelay` + +> The last two properties supported by the plugin control the mouse wheel +> scrolling speed. The former, `.wheelSpeed`, controls the amount of ticks the +> wheel shall scroll, and defaults to 1. The second, `.wheelDelay`, controls the +> delay between two scroll events, and defaults to 50 milliseconds. + +### `.setSpeedLimit` + +> This method sets the maximum speed after which acceleration stops. +> The default is 127, and the minimum value is 16 (things will not work +> properly below 16). + +### `.setWarpGridSize` + +> This method changes the size of the grid used for [warping](#warping). The +> following are valid sizes: `MOUSE_WARP_GRID_2X2`, `MOUSE_WARP_GRID_3X3` diff --git a/src/Kaleidoscope-MouseKeys.h b/src/Kaleidoscope-MouseKeys.h index bc6615da..b948baea 100644 --- a/src/Kaleidoscope-MouseKeys.h +++ b/src/Kaleidoscope-MouseKeys.h @@ -16,36 +16,4 @@ #pragma once -#include "Kaleidoscope.h" -#include "MouseKeyDefs.h" -#include "MouseWarpModes.h" - -class MouseKeys_ : public kaleidoscope::Plugin { - public: - MouseKeys_(void) {} - - static uint8_t speed; - static uint16_t speedDelay; - static uint8_t accelSpeed; - static uint16_t accelDelay; - static uint8_t wheelSpeed; - static uint16_t wheelDelay; - - static void setWarpGridSize(uint8_t grid_size); - static void setSpeedLimit(uint8_t speed_limit); - - kaleidoscope::EventHandlerResult onSetup(); - kaleidoscope::EventHandlerResult beforeReportingState(); - kaleidoscope::EventHandlerResult afterEachCycle(); - kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); - - private: - static uint8_t mouseMoveIntent; - static uint32_t endTime; - static uint32_t accelEndTime; - static uint32_t wheelEndTime; - - static void scrollWheel(uint8_t keyCode); -}; - -extern MouseKeys_ MouseKeys; +#include "kaleidoscope/plugin/MouseKeys.h" diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index b85b950f..7f6e39e8 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -16,54 +16,6 @@ #pragma once -#include "Arduino.h" -#include "MouseWarpModes.h" +#warning Please migrate to including "kaleidoscope/plugin/MouseWrapper.h" instead of "MouseWrapper.h", or even consider dropping the include, because will pull the right header in anyway. -// Warping commands - -#define WARP_END 1 -#define WARP_UP 2 -#define WARP_DOWN 4 -#define WARP_LEFT 8 -#define WARP_RIGHT 16 - -// apparently, the mac discards 15% of the value space for mouse movement. -// need to test this on other platforms - -#define MAX_WARP_WIDTH 32767 -#define MAX_WARP_HEIGHT 32767 - -#define WARP_ABS_TOP 0 -#define WARP_ABS_LEFT 0 - -// Mouse acceleration - -class MouseWrapper_ { - public: - MouseWrapper_(void); - - static void begin(void); - static void move(int8_t x, int8_t y); - static void warp(uint8_t warp_cmd); - static void reset_warping(); - static void pressButton(uint8_t button); - static void release_button(uint8_t button); - static uint8_t accelStep; - static uint8_t speedLimit; - static uint8_t subpixelsPerPixel; - static uint8_t warp_grid_size; - - private: - static uint16_t next_width; - static uint16_t next_height; - static uint16_t section_top; - static uint16_t section_left; - static boolean is_warping; - - static uint8_t acceleration(uint8_t cycles); - static void begin_warping(); - static void end_warping(); - static void warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width); -}; - -extern MouseWrapper_ MouseWrapper; +#include "kaleidoscope/plugin/MouseWrapper.h" diff --git a/src/MouseKeyDefs.h b/src/kaleidoscope/plugin/MouseKeyDefs.h similarity index 100% rename from src/MouseKeyDefs.h rename to src/kaleidoscope/plugin/MouseKeyDefs.h diff --git a/src/Kaleidoscope-MouseKeys.cpp b/src/kaleidoscope/plugin/MouseKeys.cpp similarity index 88% rename from src/Kaleidoscope-MouseKeys.cpp rename to src/kaleidoscope/plugin/MouseKeys.cpp index a59cfd22..80612198 100644 --- a/src/Kaleidoscope-MouseKeys.cpp +++ b/src/kaleidoscope/plugin/MouseKeys.cpp @@ -20,6 +20,9 @@ #include "MouseWrapper.h" #include "Kaleidoscope.h" +namespace kaleidoscope { +namespace plugin { + uint8_t MouseKeys_::mouseMoveIntent; uint8_t MouseKeys_::speed = 1; @@ -59,24 +62,24 @@ void MouseKeys_::scrollWheel(uint8_t keyCode) { kaleidoscope::hid::moveMouse(0, 0, 0, wheelSpeed); } -kaleidoscope::EventHandlerResult MouseKeys_::afterEachCycle() { +EventHandlerResult MouseKeys_::afterEachCycle() { kaleidoscope::hid::sendMouseReport(); kaleidoscope::hid::releaseAllMouseButtons(); mouseMoveIntent = 0; - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; } -kaleidoscope::EventHandlerResult MouseKeys_::beforeReportingState() { +EventHandlerResult MouseKeys_::beforeReportingState() { if (mouseMoveIntent == 0) { MouseWrapper.accelStep = 0; endTime = 0; accelEndTime = 0; - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; } if (millis() < endTime) - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; endTime = millis() + speedDelay; @@ -101,12 +104,12 @@ kaleidoscope::EventHandlerResult MouseKeys_::beforeReportingState() { MouseWrapper.move(moveX, moveY); - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; } -kaleidoscope::EventHandlerResult MouseKeys_::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { +EventHandlerResult MouseKeys_::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { if (mappedKey.flags != (SYNTHETIC | IS_MOUSE_KEY)) - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; if (mappedKey.keyCode & KEY_MOUSE_BUTTON && !(mappedKey.keyCode & KEY_MOUSE_WARP)) { uint8_t button = mappedKey.keyCode & ~KEY_MOUSE_BUTTON; @@ -173,13 +176,16 @@ kaleidoscope::EventHandlerResult MouseKeys_::onKeyswitchEvent(Key &mappedKey, by } } - return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; + return EventHandlerResult::EVENT_CONSUMED; } -kaleidoscope::EventHandlerResult MouseKeys_::onSetup(void) { +EventHandlerResult MouseKeys_::onSetup(void) { MouseWrapper.begin(); - return kaleidoscope::EventHandlerResult::OK; + return EventHandlerResult::OK; +} + +} } -MouseKeys_ MouseKeys; +kaleidoscope::plugin::MouseKeys_ MouseKeys; diff --git a/src/kaleidoscope/plugin/MouseKeys.h b/src/kaleidoscope/plugin/MouseKeys.h new file mode 100644 index 00000000..8b958cba --- /dev/null +++ b/src/kaleidoscope/plugin/MouseKeys.h @@ -0,0 +1,55 @@ +/* Kaleidoscope-MouseKeys - Mouse keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope.h" +#include "MouseKeyDefs.h" +#include "MouseWarpModes.h" + +namespace kaleidoscope { +namespace plugin { +class MouseKeys_ : public kaleidoscope::Plugin { + public: + MouseKeys_(void) {} + + static uint8_t speed; + static uint16_t speedDelay; + static uint8_t accelSpeed; + static uint16_t accelDelay; + static uint8_t wheelSpeed; + static uint16_t wheelDelay; + + static void setWarpGridSize(uint8_t grid_size); + static void setSpeedLimit(uint8_t speed_limit); + + EventHandlerResult onSetup(); + EventHandlerResult beforeReportingState(); + EventHandlerResult afterEachCycle(); + EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); + + private: + static uint8_t mouseMoveIntent; + static uint32_t endTime; + static uint32_t accelEndTime; + static uint32_t wheelEndTime; + + static void scrollWheel(uint8_t keyCode); +}; +} +} + +extern kaleidoscope::plugin::MouseKeys_ MouseKeys; diff --git a/src/MouseWarpModes.h b/src/kaleidoscope/plugin/MouseWarpModes.h similarity index 100% rename from src/MouseWarpModes.h rename to src/kaleidoscope/plugin/MouseWarpModes.h diff --git a/src/MouseWrapper.cpp b/src/kaleidoscope/plugin/MouseWrapper.cpp similarity index 98% rename from src/MouseWrapper.cpp rename to src/kaleidoscope/plugin/MouseWrapper.cpp index ec5b1a29..ac6db7f9 100644 --- a/src/MouseWrapper.cpp +++ b/src/kaleidoscope/plugin/MouseWrapper.cpp @@ -21,6 +21,9 @@ #include "MouseWrapper.h" #include "kaleidoscope/hid.h" +namespace kaleidoscope { +namespace plugin { + uint8_t MouseWrapper_::warp_grid_size = MOUSE_WARP_GRID_2X2; uint16_t MouseWrapper_::next_width; uint16_t MouseWrapper_::next_height; @@ -173,5 +176,7 @@ void MouseWrapper_::move(int8_t x, int8_t y) { remainderX = moveX - moveX / subpixelsPerPixel * subpixelsPerPixel; remainderY = moveY - moveY / subpixelsPerPixel * subpixelsPerPixel; } +} +} -MouseWrapper_ MouseWrapper; +kaleidoscope::plugin::MouseWrapper_ MouseWrapper; diff --git a/src/kaleidoscope/plugin/MouseWrapper.h b/src/kaleidoscope/plugin/MouseWrapper.h new file mode 100644 index 00000000..e5938a18 --- /dev/null +++ b/src/kaleidoscope/plugin/MouseWrapper.h @@ -0,0 +1,74 @@ +/* Kaleidoscope-MouseKeys - Mouse keys for Kaleidoscope. + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Arduino.h" +#include "MouseWarpModes.h" + +// Warping commands + +#define WARP_END 1 +#define WARP_UP 2 +#define WARP_DOWN 4 +#define WARP_LEFT 8 +#define WARP_RIGHT 16 + +// apparently, the mac discards 15% of the value space for mouse movement. +// need to test this on other platforms + +#define MAX_WARP_WIDTH 32767 +#define MAX_WARP_HEIGHT 32767 + +#define WARP_ABS_TOP 0 +#define WARP_ABS_LEFT 0 + +// Mouse acceleration + +namespace kaleidoscope { +namespace plugin { + +class MouseWrapper_ { + public: + MouseWrapper_(void); + + static void begin(void); + static void move(int8_t x, int8_t y); + static void warp(uint8_t warp_cmd); + static void reset_warping(); + static void pressButton(uint8_t button); + static void release_button(uint8_t button); + static uint8_t accelStep; + static uint8_t speedLimit; + static uint8_t subpixelsPerPixel; + static uint8_t warp_grid_size; + + private: + static uint16_t next_width; + static uint16_t next_height; + static uint16_t section_top; + static uint16_t section_left; + static boolean is_warping; + + static uint8_t acceleration(uint8_t cycles); + static void begin_warping(); + static void end_warping(); + static void warp_jump(uint16_t left, uint16_t top, uint16_t height, uint16_t width); +}; +} +} + +extern kaleidoscope::plugin::MouseWrapper_ MouseWrapper; From cdb5087ec965bb3830b2c4d86ef8b97f31b1779a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 12:43:26 +0200 Subject: [PATCH 781/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 8 - library.properties | 10 - 6 files changed, 770 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 842a8b11..00000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kaleidoscope-MouseKeys - -[![Build Status][travis:image]][travis:status] - - [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-MouseKeys.svg?branch=master - [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-MouseKeys - -See [doc/plugin/MouseKeys.md](doc/plugin/MouseKeys.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index 37481310..00000000 --- a/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Kaleidoscope-MouseKeys -version=0.0.1 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=Mouse keys for Kaleidoscope. -paragraph=Simulate a mouse with keys on a regular keyboard. -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-MouseKeys -architectures=avr -dot_a_linkage=true \ No newline at end of file From 6a46b800d09b2985e5b262f906fa6c9e7508c927 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 11:42:03 +0200 Subject: [PATCH 782/792] Rearrange the file layout in preparation of becoming a monorepo Move the documentation to `doc/plugin/LEDControl.md`, sources under `src/kaleidoscope/plugin/` (appropriately namespaced). This is in preparation of merging plugins into a single monorepo. Signed-off-by: Gergely Nagy --- README.md | 5 +- doc/plugin/LEDControl.md | 21 +++ src/Kaleidoscope-LEDControl.h | 150 +--------------- src/LED-Off.h | 15 +- src/LEDUtils.h | 5 +- .../plugin}/BootAnimation.cpp | 2 +- src/{ => kaleidoscope/plugin}/BootAnimation.h | 0 src/{ => kaleidoscope/plugin}/LED-Off.cpp | 6 +- src/kaleidoscope/plugin/LED-Off.h | 34 ++++ .../plugin/LEDControl.cpp} | 6 +- src/kaleidoscope/plugin/LEDControl.h | 170 ++++++++++++++++++ src/{ => kaleidoscope/plugin}/LEDUtils.cpp | 2 +- src/kaleidoscope/plugin/LEDUtils.h | 22 +++ 13 files changed, 265 insertions(+), 173 deletions(-) create mode 100644 doc/plugin/LEDControl.md rename src/{ => kaleidoscope/plugin}/BootAnimation.cpp (96%) rename src/{ => kaleidoscope/plugin}/BootAnimation.h (100%) rename src/{ => kaleidoscope/plugin}/LED-Off.cpp (90%) create mode 100644 src/kaleidoscope/plugin/LED-Off.h rename src/{Kaleidoscope-LEDControl.cpp => kaleidoscope/plugin/LEDControl.cpp} (98%) create mode 100644 src/kaleidoscope/plugin/LEDControl.h rename src/{ => kaleidoscope/plugin}/LEDUtils.cpp (98%) create mode 100644 src/kaleidoscope/plugin/LEDUtils.h diff --git a/README.md b/README.md index 675d2c9a..5bca7be2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,3 @@ # Kaleidoscope-LEDControl -This is a plugin for [Kaleidoscope][fw], for controlling the LEDs, and LED -effects. - - [fw]: https://github.com/keyboardio/Kaleidoscope +See [doc/plugin/LEDControl.md](doc/plugin/LEDControl.md) for documentation. diff --git a/doc/plugin/LEDControl.md b/doc/plugin/LEDControl.md new file mode 100644 index 00000000..94d00998 --- /dev/null +++ b/doc/plugin/LEDControl.md @@ -0,0 +1,21 @@ +# Kaleidoscope-LEDControl + +This is a plugin for [Kaleidoscope][fw], for controlling the LEDs, and LED +effects. + + [fw]: https://github.com/keyboardio/Kaleidoscope + +## Upgrading + +The `LEDUtils.h` and `LED-Off.h` headers were moved, and need a +`kaleidoscope/plugin/` prefix now. The old headers still work, but are +deprecated, and will emit a warning. Both of them are included by +`` by default, so instead of migrating to the new +paths, one might wish to simply drop them instead. + +The compatibility headers will be removed by 2019-01-14. + +Furthermore, to implement LED modes, one should use +`kaleidoscope::plugin::LEDMode` as a base class now, instead of the former +`kaleidoscope::LEDMode`. There is a backwards compatible typedef, but like the +headers, it will be removed by 2019-01-14. diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index 13da4fa0..cfdde64d 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -16,150 +16,6 @@ #pragma once -#include - -#define LED_MAX_MODES 24 - -#define LED_TOGGLE B00000001 // Synthetic, internal - -#define Key_LEDEffectNext (Key) { 0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } -#define Key_LEDEffectPrevious (Key) { 1, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } - -namespace kaleidoscope { -/** Base class for LED modes. - * - * LED modes are a special kind of plugin, they are in charge of updating LED - * colors, setting a theme. While it is possible to have other plugins - * override the mode's colors, the LED mode is the baseline. - * - * Most of its functionality is called via @ref LEDControl, with only a few - * public methods. - * - * A LED mode **must** implement at least one of @ref onActivate or @ref - * update, and possibly @ref refreshAt too. - */ -class LEDMode : public kaleidoscope::Plugin { - friend class LEDControl; - protected: - // These methods should only be called by LEDControl. - - /** One-time setup, called at keyboard boot. - * - * Any hooks that need registering, any one-time setup that needs to be - * performed, shall be done here. This is purely for preparation purposes, the - * LEDs should not be touched yet at this time. - */ - virtual void setup(void) {} - - /** Function to call whenever the mode is activated. - * - * Like @ref setup, this method need not touch LEDs, @ref update will be - * called right after it. The purpose of this callback is to allow a plugin to - * do some preparation whenever it is activated, instead of only on boot, or - * always at each cycle. - * - * However, unlike @ref setup, this method can change LED colors, if so - * desired. Either to provide an initial state, or a static color set. In the - * latter case, consider implementing @ref refreshAt too, because other - * plugins may override some of the colors set at activation time, and @ref - * refreshAt can be used to restore them when needed. - * - * Before the callback runs, LEDs will be blanked. - */ - virtual void onActivate(void) {} - - /** Update the LEDs once per cycle. - * - * Usually the brains of the plugin, which updates the LEDs each cycle. It is - * called after the matrix has been scanned, once per cycle. - */ - virtual void update(void) {} - - /** Refresh the color of a given key. - * - * If we have another plugin that overrides colors set by the active LED mode - * (either at @onActivate time, or via @ref update), if that plugin wants to - * restore whatever color the mode would set the key color to, this is the - * method it will call. - * - * @param row is the row coordinate of the key to refresh the color of. - * @param col is the column coordinate of the key to refresh the color of. - */ - virtual void refreshAt(byte row, byte col) {} - - public: - /** Activate the current object as the LED mode. - */ - void activate(void); - - /** Plugin initialization. - * - * Called via `Kaleidoscope.use()`, registers the LED mode, and does the - * necessary initialization steps. Calls @ref setup at the end. - */ - kaleidoscope::EventHandlerResult onSetup(); -}; - -class LEDControl : public kaleidoscope::Plugin { - public: - LEDControl(void); - - static void next_mode(void); - static void prev_mode(void); - static void setup(void); - static void update(void) { - if (modes[mode]) - modes[mode]->update(); - } - static void refreshAt(byte row, byte col) { - if (modes[mode]) - modes[mode]->refreshAt(row, col); - } - static void set_mode(uint8_t mode); - static uint8_t get_mode_index(); - static LEDMode *get_mode(); - static void refreshAll() { - if (paused) - return; - - set_all_leds_to({0, 0, 0}); - if (modes[mode]) - modes[mode]->onActivate(); - } - - static int8_t mode_add(LEDMode *mode); - - static void setCrgbAt(uint8_t i, cRGB crgb); - static void setCrgbAt(byte row, byte col, cRGB color); - static cRGB getCrgbAt(uint8_t i); - static void syncLeds(void); - - static void set_all_leds_to(uint8_t r, uint8_t g, uint8_t b); - static void set_all_leds_to(cRGB color); - - static void activate(LEDMode *mode); - - static uint16_t syncDelay; - static bool paused; - - kaleidoscope::EventHandlerResult onSetup(); - kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); - kaleidoscope::EventHandlerResult beforeReportingState(); - - private: - static uint16_t syncTimer; - static LEDMode *modes[LED_MAX_MODES]; - static uint8_t mode; -}; - -class FocusLEDCommand : public Plugin { - public: - FocusLEDCommand() {} - - EventHandlerResult onFocusEvent(const char *command); -}; - -} - -extern kaleidoscope::LEDControl LEDControl; -extern kaleidoscope::FocusLEDCommand FocusLEDCommand; +#include +#include +#include diff --git a/src/LED-Off.h b/src/LED-Off.h index 7a33a3db..87c65ddc 100644 --- a/src/LED-Off.h +++ b/src/LED-Off.h @@ -16,17 +16,6 @@ #pragma once -#include "Kaleidoscope-LEDControl.h" +#warning Please migrate to including "kaleidoscope/plugin/LED-Off.h" instead of "LED-Off.h", or even consider dropping the include, because will pull the right header in anyway. -namespace kaleidoscope { -class LEDOff : public LEDMode { - public: - LEDOff(void) { } - - protected: - void onActivate(void) final; - void refreshAt(byte row, byte col) final; -}; -} - -extern kaleidoscope::LEDOff LEDOff; +#include "kaleidoscope/plugin/LED-Off.h" diff --git a/src/LEDUtils.h b/src/LEDUtils.h index 1de96922..9a0c31fc 100644 --- a/src/LEDUtils.h +++ b/src/LEDUtils.h @@ -16,7 +16,6 @@ #pragma once -#include +#warning Please migrate to including "kaleidoscope/plugin/LEDUtils.h" instead of "LEDUtils.h", or even consider dropping the include, because will pull the right header in anyway. -cRGB breath_compute(uint8_t hue = 170, uint8_t saturation = 255); -cRGB hsvToRgb(uint16_t h, uint16_t s, uint16_t v); +#include "kaleidoscope/plugin/LEDUtils.h" diff --git a/src/BootAnimation.cpp b/src/kaleidoscope/plugin/BootAnimation.cpp similarity index 96% rename from src/BootAnimation.cpp rename to src/kaleidoscope/plugin/BootAnimation.cpp index 2ef5df0f..15e52360 100644 --- a/src/BootAnimation.cpp +++ b/src/kaleidoscope/plugin/BootAnimation.cpp @@ -14,7 +14,7 @@ * this program. If not, see . */ -#include "BootAnimation.h" +#include "kaleidoscope/plugin/BootAnimation.h" #include "Kaleidoscope-LEDControl.h" #ifdef ARDUINO_AVR_MODEL01 diff --git a/src/BootAnimation.h b/src/kaleidoscope/plugin/BootAnimation.h similarity index 100% rename from src/BootAnimation.h rename to src/kaleidoscope/plugin/BootAnimation.h diff --git a/src/LED-Off.cpp b/src/kaleidoscope/plugin/LED-Off.cpp similarity index 90% rename from src/LED-Off.cpp rename to src/kaleidoscope/plugin/LED-Off.cpp index 324abfb7..98ec730f 100644 --- a/src/LED-Off.cpp +++ b/src/kaleidoscope/plugin/LED-Off.cpp @@ -14,9 +14,10 @@ * this program. If not, see . */ -#include "LED-Off.h" +#include "kaleidoscope/plugin/LED-Off.h" namespace kaleidoscope { +namespace plugin { void LEDOff::onActivate(void) { ::LEDControl.set_all_leds_to({0, 0, 0}); } @@ -25,5 +26,6 @@ void LEDOff::refreshAt(byte row, byte col) { ::LEDControl.setCrgbAt(row, col, {0, 0, 0}); } } +} -kaleidoscope::LEDOff LEDOff; +kaleidoscope::plugin::LEDOff LEDOff; diff --git a/src/kaleidoscope/plugin/LED-Off.h b/src/kaleidoscope/plugin/LED-Off.h new file mode 100644 index 00000000..3a931e9d --- /dev/null +++ b/src/kaleidoscope/plugin/LED-Off.h @@ -0,0 +1,34 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope-LEDControl.h" + +namespace kaleidoscope { +namespace plugin { +class LEDOff : public LEDMode { + public: + LEDOff(void) { } + + protected: + void onActivate(void) final; + void refreshAt(byte row, byte col) final; +}; +} +} + +extern kaleidoscope::plugin::LEDOff LEDOff; diff --git a/src/Kaleidoscope-LEDControl.cpp b/src/kaleidoscope/plugin/LEDControl.cpp similarity index 98% rename from src/Kaleidoscope-LEDControl.cpp rename to src/kaleidoscope/plugin/LEDControl.cpp index 2209397e..cc710eb0 100644 --- a/src/Kaleidoscope-LEDControl.cpp +++ b/src/kaleidoscope/plugin/LEDControl.cpp @@ -18,6 +18,7 @@ #include "Kaleidoscope-FocusSerial.h" namespace kaleidoscope { +namespace plugin { LEDMode *LEDControl::modes[LED_MAX_MODES]; uint8_t LEDControl::mode; @@ -274,7 +275,8 @@ EventHandlerResult FocusLEDCommand::onFocusEvent(const char *command) { return EventHandlerResult::EVENT_CONSUMED; } +} } -kaleidoscope::LEDControl LEDControl; -kaleidoscope::FocusLEDCommand FocusLEDCommand; +kaleidoscope::plugin::LEDControl LEDControl; +kaleidoscope::plugin::FocusLEDCommand FocusLEDCommand; diff --git a/src/kaleidoscope/plugin/LEDControl.h b/src/kaleidoscope/plugin/LEDControl.h new file mode 100644 index 00000000..246edfc8 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDControl.h @@ -0,0 +1,170 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include + +#define LED_MAX_MODES 24 + +#define LED_TOGGLE B00000001 // Synthetic, internal + +#define Key_LEDEffectNext (Key) { 0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } +#define Key_LEDEffectPrevious (Key) { 1, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } + +namespace kaleidoscope { +namespace plugin { +/** Base class for LED modes. + * + * LED modes are a special kind of plugin, they are in charge of updating LED + * colors, setting a theme. While it is possible to have other plugins + * override the mode's colors, the LED mode is the baseline. + * + * Most of its functionality is called via @ref LEDControl, with only a few + * public methods. + * + * A LED mode **must** implement at least one of @ref onActivate or @ref + * update, and possibly @ref refreshAt too. + */ +class LEDMode : public kaleidoscope::Plugin { + friend class LEDControl; + protected: + // These methods should only be called by LEDControl. + + /** One-time setup, called at keyboard boot. + * + * Any hooks that need registering, any one-time setup that needs to be + * performed, shall be done here. This is purely for preparation purposes, the + * LEDs should not be touched yet at this time. + */ + virtual void setup(void) {} + + /** Function to call whenever the mode is activated. + * + * Like @ref setup, this method need not touch LEDs, @ref update will be + * called right after it. The purpose of this callback is to allow a plugin to + * do some preparation whenever it is activated, instead of only on boot, or + * always at each cycle. + * + * However, unlike @ref setup, this method can change LED colors, if so + * desired. Either to provide an initial state, or a static color set. In the + * latter case, consider implementing @ref refreshAt too, because other + * plugins may override some of the colors set at activation time, and @ref + * refreshAt can be used to restore them when needed. + * + * Before the callback runs, LEDs will be blanked. + */ + virtual void onActivate(void) {} + + /** Update the LEDs once per cycle. + * + * Usually the brains of the plugin, which updates the LEDs each cycle. It is + * called after the matrix has been scanned, once per cycle. + */ + virtual void update(void) {} + + /** Refresh the color of a given key. + * + * If we have another plugin that overrides colors set by the active LED mode + * (either at @onActivate time, or via @ref update), if that plugin wants to + * restore whatever color the mode would set the key color to, this is the + * method it will call. + * + * @param row is the row coordinate of the key to refresh the color of. + * @param col is the column coordinate of the key to refresh the color of. + */ + virtual void refreshAt(byte row, byte col) {} + + public: + /** Activate the current object as the LED mode. + */ + void activate(void); + + /** Plugin initialization. + * + * Called via `Kaleidoscope.use()`, registers the LED mode, and does the + * necessary initialization steps. Calls @ref setup at the end. + */ + kaleidoscope::EventHandlerResult onSetup(); +}; + +class LEDControl : public kaleidoscope::Plugin { + public: + LEDControl(void); + + static void next_mode(void); + static void prev_mode(void); + static void setup(void); + static void update(void) { + if (modes[mode]) + modes[mode]->update(); + } + static void refreshAt(byte row, byte col) { + if (modes[mode]) + modes[mode]->refreshAt(row, col); + } + static void set_mode(uint8_t mode); + static uint8_t get_mode_index(); + static LEDMode *get_mode(); + static void refreshAll() { + if (paused) + return; + + set_all_leds_to({0, 0, 0}); + if (modes[mode]) + modes[mode]->onActivate(); + } + + static int8_t mode_add(LEDMode *mode); + + static void setCrgbAt(uint8_t i, cRGB crgb); + static void setCrgbAt(byte row, byte col, cRGB color); + static cRGB getCrgbAt(uint8_t i); + static void syncLeds(void); + + static void set_all_leds_to(uint8_t r, uint8_t g, uint8_t b); + static void set_all_leds_to(cRGB color); + + static void activate(LEDMode *mode); + + static uint16_t syncDelay; + static bool paused; + + kaleidoscope::EventHandlerResult onSetup(); + kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); + kaleidoscope::EventHandlerResult beforeReportingState(); + + private: + static uint16_t syncTimer; + static LEDMode *modes[LED_MAX_MODES]; + static uint8_t mode; +}; + +class FocusLEDCommand : public Plugin { + public: + FocusLEDCommand() {} + + EventHandlerResult onFocusEvent(const char *command); +}; + +} + +// Backwards compatibility +typedef plugin::LEDMode LEDMode; +} + +extern kaleidoscope::plugin::LEDControl LEDControl; +extern kaleidoscope::plugin::FocusLEDCommand FocusLEDCommand; diff --git a/src/LEDUtils.cpp b/src/kaleidoscope/plugin/LEDUtils.cpp similarity index 98% rename from src/LEDUtils.cpp rename to src/kaleidoscope/plugin/LEDUtils.cpp index 68407397..873e4cb1 100644 --- a/src/LEDUtils.cpp +++ b/src/kaleidoscope/plugin/LEDUtils.cpp @@ -14,7 +14,7 @@ * this program. If not, see . */ -#include "LEDUtils.h" +#include "kaleidoscope/plugin/LEDUtils.h" cRGB breath_compute(uint8_t hue, uint8_t saturation) { diff --git a/src/kaleidoscope/plugin/LEDUtils.h b/src/kaleidoscope/plugin/LEDUtils.h new file mode 100644 index 00000000..1de96922 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDUtils.h @@ -0,0 +1,22 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include + +cRGB breath_compute(uint8_t hue = 170, uint8_t saturation = 255); +cRGB hsvToRgb(uint16_t h, uint16_t s, uint16_t v); From 142e82878517ae9694211bde5d04cf53e54c8877 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 11:43:28 +0200 Subject: [PATCH 783/792] Remove files we do not need in the monorepo Signed-off-by: Gergely Nagy --- .travis.yml | 14 - CONTRIBUTING.md | 50 ---- COPYING | 674 --------------------------------------------- Makefile | 14 - README.md | 3 - library.properties | 9 - 6 files changed, 764 deletions(-) delete mode 100644 .travis.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 library.properties diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 49b8c498..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -dist: trusty -sudo: false -os: - - linux -install: - - git clone --depth 1 --recurse-submodules https://github.com/keyboardio/Kaleidoscope-Bundle-Keyboardio hardware/keyboardio -script: - - make travis-test BOARD_HARDWARE_PATH=$(pwd)/hardware -notifications: - email: - on_success: change - on_failure: change -cache: - ccache: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index c490e3ce..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Developer Certificate of Origin - -All contributions must include acceptance of the DCO: - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -1 Letterman Drive -Suite D4700 -San Francisco, CA, 94129 - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -## Sign your work - -To accept the DCO, please add this line to each commit message with your name -and email address (`git commit -s` will do this for you): - - Signed-off-by: Jane Example diff --git a/COPYING b/COPYING deleted file mode 100644 index 94a9ed02..00000000 --- a/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -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: - - Copyright (C) - 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 -. - - 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 -. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8f830f44..00000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This stub makefile for a Kaleidoscope plugin pulls in -# all targets from the Kaleidoscope-Plugin library - -UNAME_S := $(shell uname -s) - -ifeq ($(UNAME_S),Darwin) -SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino/ -else -SKETCHBOOK_DIR ?= $(HOME)/Arduino -endif - -BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware -KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ -include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/README.md b/README.md deleted file mode 100644 index 5bca7be2..00000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Kaleidoscope-LEDControl - -See [doc/plugin/LEDControl.md](doc/plugin/LEDControl.md) for documentation. diff --git a/library.properties b/library.properties deleted file mode 100644 index ebaa64a3..00000000 --- a/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=Kaleidoscope-LEDControl -version=0.0.1 -author=Jesse Vincent -maintainer=Jesse Vincent -sentence=LED control for Kaleidoscope. -paragraph=... -category=Communication -url=https://github.com/keyboardio/Kaleidoscope-LEDControl -architectures=avr From 694f95502bcdf0fac814e31d31258ad2b425ef39 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 17:36:55 +0200 Subject: [PATCH 784/792] examples/Kaleidoscope: Include Kaleidoscope.h first Signed-off-by: Gergely Nagy --- examples/Kaleidoscope/Kaleidoscope.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Kaleidoscope/Kaleidoscope.ino b/examples/Kaleidoscope/Kaleidoscope.ino index 61f02fd2..df50837a 100644 --- a/examples/Kaleidoscope/Kaleidoscope.ino +++ b/examples/Kaleidoscope/Kaleidoscope.ino @@ -17,11 +17,11 @@ #define DEBUG_SERIAL false +#include "Kaleidoscope.h" #include "Kaleidoscope-MouseKeys.h" #include "Kaleidoscope-Macros.h" #include "Kaleidoscope-LEDControl.h" #include "Kaleidoscope-NumPad.h" -#include "Kaleidoscope.h" #include "LED-Off.h" #include "Kaleidoscope-LEDEffect-SolidColor.h" From 527c67d1d75a8432ebaf663a345174585577b15b Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 22:42:17 +0200 Subject: [PATCH 785/792] examples/AppSwitcher: Explicitly init EEPROMSettings Signed-off-by: Gergely Nagy --- examples/AppSwitcher/AppSwitcher.ino | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/AppSwitcher/AppSwitcher.ino b/examples/AppSwitcher/AppSwitcher.ino index c8776583..1dcdad29 100644 --- a/examples/AppSwitcher/AppSwitcher.ino +++ b/examples/AppSwitcher/AppSwitcher.ino @@ -16,8 +16,9 @@ */ #include "Kaleidoscope.h" +#include "Kaleidoscope-EEPROM-Settings.h" +#include "Kaleidoscope-Macros.h" #include "Kaleidoscope-HostOS.h" -#include "Kaleidoscope/HostOS-select.h" #include "Macros.h" @@ -54,7 +55,8 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) { return MACRO_NONE; } -KALEIDOSCOPE_INIT_PLUGINS(HostOS, +KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, + HostOS, Macros); void setup() { From 4bc0eb5d11306ffa96f0cbdee2decdd541ae47d8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Oct 2018 23:33:15 +0200 Subject: [PATCH 786/792] Further source-code rearrangement Merged `EEPROM-Settings-Focus` into `EEPROM-Settings` itself: there's no reason they should be separate. Also moved the CRC headers to `kaleidoscope/plugin/EEPROM-Settings/` to not pollute the plugin namespace. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-EEPROM-Settings.h | 1 - .../plugin/EEPROM-Settings-Focus.cpp | 124 ------------------ .../plugin/EEPROM-Settings-Focus.h | 44 ------- src/kaleidoscope/plugin/EEPROM-Settings.cpp | 99 +++++++++++++- src/kaleidoscope/plugin/EEPROM-Settings.h | 16 +++ .../plugin/{ => EEPROM-Settings}/crc.cpp | 0 .../plugin/{ => EEPROM-Settings}/crc.h | 0 7 files changed, 114 insertions(+), 170 deletions(-) delete mode 100644 src/kaleidoscope/plugin/EEPROM-Settings-Focus.cpp delete mode 100644 src/kaleidoscope/plugin/EEPROM-Settings-Focus.h rename src/kaleidoscope/plugin/{ => EEPROM-Settings}/crc.cpp (100%) rename src/kaleidoscope/plugin/{ => EEPROM-Settings}/crc.h (100%) diff --git a/src/Kaleidoscope-EEPROM-Settings.h b/src/Kaleidoscope-EEPROM-Settings.h index a36d235e..ed93eec9 100644 --- a/src/Kaleidoscope-EEPROM-Settings.h +++ b/src/Kaleidoscope-EEPROM-Settings.h @@ -18,4 +18,3 @@ #pragma once #include -#include diff --git a/src/kaleidoscope/plugin/EEPROM-Settings-Focus.cpp b/src/kaleidoscope/plugin/EEPROM-Settings-Focus.cpp deleted file mode 100644 index 1f669f3b..00000000 --- a/src/kaleidoscope/plugin/EEPROM-Settings-Focus.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- mode: c++ -*- - * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017-2018 Keyboard.io, Inc - * - * 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, version 3. - * - * 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 . - */ - -#include -#include -#include "crc.h" - -namespace kaleidoscope { -namespace plugin { -namespace eeprom { - -EventHandlerResult FocusSettingsCommand::onFocusEvent(const char *command) { - enum { - DEFAULT_LAYER, - IS_VALID, - GET_VERSION, - CRC, - } sub_command; - - if (::Focus.handleHelp(command, PSTR("settings.defaultLayer\nsettings.valid?\nsettings.version\nsettings.crc"))) - return EventHandlerResult::OK; - - if (strncmp_P(command, PSTR("settings."), 9) != 0) - return EventHandlerResult::OK; - - if (strcmp_P(command + 9, PSTR("defaultLayer")) == 0) - sub_command = DEFAULT_LAYER; - else if (strcmp_P(command + 9, PSTR("valid?")) == 0) - sub_command = IS_VALID; - else if (strcmp_P(command + 9, PSTR("version")) == 0) - sub_command = GET_VERSION; - else if (strcmp_P(command + 9, PSTR("crc")) == 0) - sub_command = CRC; - else - return EventHandlerResult::OK; - - switch (sub_command) { - case DEFAULT_LAYER: { - if (Serial.peek() == '\n') { - Serial.println(::EEPROMSettings.default_layer()); - } else { - ::EEPROMSettings.default_layer(Serial.parseInt()); - } - break; - } - case IS_VALID: - ::Focus.printBool(::EEPROMSettings.isValid()); - Serial.println(); - break; - case GET_VERSION: - Serial.println(::EEPROMSettings.version()); - break; - case CRC: - Serial.print(::CRC.crc, HEX); - Serial.print(F("/")); - Serial.println(::EEPROMSettings.crc(), HEX); - break; - } - - return EventHandlerResult::EVENT_CONSUMED; -} - -EventHandlerResult FocusEEPROMCommand::onFocusEvent(const char *command) { - enum { - CONTENTS, - FREE, - } sub_command; - - if (::Focus.handleHelp(command, PSTR("eeprom.contents\neeprom.free"))) - return EventHandlerResult::OK; - - if (strcmp_P(command, PSTR("eeprom.contents")) == 0) - sub_command = CONTENTS; - else if (strcmp_P(command, PSTR("eeprom.free")) == 0) - sub_command = FREE; - else - return EventHandlerResult::OK; - - switch (sub_command) { - case CONTENTS: { - if (Serial.peek() == '\n') { - for (uint16_t i = 0; i < EEPROM.length(); i++) { - uint8_t d = EEPROM[i]; - ::Focus.printNumber(d); - ::Focus.printSpace(); - } - Serial.println(); - } else { - for (uint16_t i = 0; i < EEPROM.length() && Serial.peek() != '\n'; i++) { - uint8_t d = Serial.parseInt(); - EEPROM.update(i, d); - } - } - - break; - } - case FREE: - Serial.println(EEPROM.length() - ::EEPROMSettings.used()); - break; - } - - return EventHandlerResult::EVENT_CONSUMED; -} - -} -} -} - -kaleidoscope::plugin::eeprom::FocusSettingsCommand FocusSettingsCommand; -kaleidoscope::plugin::eeprom::FocusEEPROMCommand FocusEEPROMCommand; diff --git a/src/kaleidoscope/plugin/EEPROM-Settings-Focus.h b/src/kaleidoscope/plugin/EEPROM-Settings-Focus.h deleted file mode 100644 index 469e8db2..00000000 --- a/src/kaleidoscope/plugin/EEPROM-Settings-Focus.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- mode: c++ -*- - * Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope. - * Copyright (C) 2017, 2018 Keyboard.io, Inc - * - * 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, version 3. - * - * 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 . - */ - -#pragma once - -#include - -namespace kaleidoscope { -namespace plugin { -namespace eeprom { -class FocusSettingsCommand : public kaleidoscope::Plugin { - public: - FocusSettingsCommand() {} - - EventHandlerResult onFocusEvent(const char *command); -}; - -class FocusEEPROMCommand : public kaleidoscope::Plugin { - public: - FocusEEPROMCommand() {} - - EventHandlerResult onFocusEvent(const char *command); -}; - -} -} -} - -extern kaleidoscope::plugin::eeprom::FocusSettingsCommand FocusSettingsCommand; -extern kaleidoscope::plugin::eeprom::FocusEEPROMCommand FocusEEPROMCommand; diff --git a/src/kaleidoscope/plugin/EEPROM-Settings.cpp b/src/kaleidoscope/plugin/EEPROM-Settings.cpp index 76058754..9e0e4d72 100644 --- a/src/kaleidoscope/plugin/EEPROM-Settings.cpp +++ b/src/kaleidoscope/plugin/EEPROM-Settings.cpp @@ -16,7 +16,8 @@ */ #include -#include "crc.h" +#include +#include "kaleidoscope/plugin/EEPROM-Settings/crc.h" namespace kaleidoscope { namespace plugin { @@ -114,7 +115,103 @@ void EEPROMSettings::version(uint8_t ver) { update(); } +/** Focus **/ +EventHandlerResult FocusSettingsCommand::onFocusEvent(const char *command) { + enum { + DEFAULT_LAYER, + IS_VALID, + GET_VERSION, + CRC, + } sub_command; + + if (::Focus.handleHelp(command, PSTR("settings.defaultLayer\nsettings.valid?\nsettings.version\nsettings.crc"))) + return EventHandlerResult::OK; + + if (strncmp_P(command, PSTR("settings."), 9) != 0) + return EventHandlerResult::OK; + + if (strcmp_P(command + 9, PSTR("defaultLayer")) == 0) + sub_command = DEFAULT_LAYER; + else if (strcmp_P(command + 9, PSTR("valid?")) == 0) + sub_command = IS_VALID; + else if (strcmp_P(command + 9, PSTR("version")) == 0) + sub_command = GET_VERSION; + else if (strcmp_P(command + 9, PSTR("crc")) == 0) + sub_command = CRC; + else + return EventHandlerResult::OK; + + switch (sub_command) { + case DEFAULT_LAYER: { + if (Serial.peek() == '\n') { + Serial.println(::EEPROMSettings.default_layer()); + } else { + ::EEPROMSettings.default_layer(Serial.parseInt()); + } + break; + } + case IS_VALID: + ::Focus.printBool(::EEPROMSettings.isValid()); + Serial.println(); + break; + case GET_VERSION: + Serial.println(::EEPROMSettings.version()); + break; + case CRC: + Serial.print(::CRC.crc, HEX); + Serial.print(F("/")); + Serial.println(::EEPROMSettings.crc(), HEX); + break; + } + + return EventHandlerResult::EVENT_CONSUMED; +} + +EventHandlerResult FocusEEPROMCommand::onFocusEvent(const char *command) { + enum { + CONTENTS, + FREE, + } sub_command; + + if (::Focus.handleHelp(command, PSTR("eeprom.contents\neeprom.free"))) + return EventHandlerResult::OK; + + if (strcmp_P(command, PSTR("eeprom.contents")) == 0) + sub_command = CONTENTS; + else if (strcmp_P(command, PSTR("eeprom.free")) == 0) + sub_command = FREE; + else + return EventHandlerResult::OK; + + switch (sub_command) { + case CONTENTS: { + if (Serial.peek() == '\n') { + for (uint16_t i = 0; i < EEPROM.length(); i++) { + uint8_t d = EEPROM[i]; + ::Focus.printNumber(d); + ::Focus.printSpace(); + } + Serial.println(); + } else { + for (uint16_t i = 0; i < EEPROM.length() && Serial.peek() != '\n'; i++) { + uint8_t d = Serial.parseInt(); + EEPROM.update(i, d); + } + } + + break; + } + case FREE: + Serial.println(EEPROM.length() - ::EEPROMSettings.used()); + break; + } + + return EventHandlerResult::EVENT_CONSUMED; +} + } } kaleidoscope::plugin::EEPROMSettings EEPROMSettings; +kaleidoscope::plugin::FocusSettingsCommand FocusSettingsCommand; +kaleidoscope::plugin::FocusEEPROMCommand FocusEEPROMCommand; diff --git a/src/kaleidoscope/plugin/EEPROM-Settings.h b/src/kaleidoscope/plugin/EEPROM-Settings.h index 0264ab3e..34c0bcda 100644 --- a/src/kaleidoscope/plugin/EEPROM-Settings.h +++ b/src/kaleidoscope/plugin/EEPROM-Settings.h @@ -53,7 +53,23 @@ class EEPROMSettings : public kaleidoscope::Plugin { uint16_t crc; } settings_; }; + +class FocusSettingsCommand : public kaleidoscope::Plugin { + public: + FocusSettingsCommand() {} + + EventHandlerResult onFocusEvent(const char *command); +}; + +class FocusEEPROMCommand : public kaleidoscope::Plugin { + public: + FocusEEPROMCommand() {} + + EventHandlerResult onFocusEvent(const char *command); +}; } } extern kaleidoscope::plugin::EEPROMSettings EEPROMSettings; +extern kaleidoscope::plugin::FocusSettingsCommand FocusSettingsCommand; +extern kaleidoscope::plugin::FocusEEPROMCommand FocusEEPROMCommand; diff --git a/src/kaleidoscope/plugin/crc.cpp b/src/kaleidoscope/plugin/EEPROM-Settings/crc.cpp similarity index 100% rename from src/kaleidoscope/plugin/crc.cpp rename to src/kaleidoscope/plugin/EEPROM-Settings/crc.cpp diff --git a/src/kaleidoscope/plugin/crc.h b/src/kaleidoscope/plugin/EEPROM-Settings/crc.h similarity index 100% rename from src/kaleidoscope/plugin/crc.h rename to src/kaleidoscope/plugin/EEPROM-Settings/crc.h From 77374448f77c8fff4460576d44d730a734d9a3f0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Oct 2018 23:37:34 +0200 Subject: [PATCH 787/792] hardware::Model01: Update an include With Kaleidoscope core's layout rearranged, we should include `kaleidoscope/macro_helpers.h` instead of `macro_helpers.h`. Signed-off-by: Gergely Nagy --- src/kaleidoscope/hardware/Model01.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kaleidoscope/hardware/Model01.h b/src/kaleidoscope/hardware/Model01.h index 4d7c585f..7cb9717a 100644 --- a/src/kaleidoscope/hardware/Model01.h +++ b/src/kaleidoscope/hardware/Model01.h @@ -23,7 +23,7 @@ #include "Kaleidoscope-HIDAdaptor-KeyboardioHID.h" #include "KeyboardioScanner.h" -#include "macro_helpers.h" +#include "kaleidoscope/macro_helpers.h" #define COLS 16 #define ROWS 4 From dc585d4ff6bb2e1451e718c436f017e68d350de0 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Oct 2018 23:43:01 +0200 Subject: [PATCH 788/792] Further source layout rearrangement Moved most files to `src/kaleidoscope/plugin/LED-AlphaSquare`, leaving only the main one on the outside. This is to decrease the number of files in `src/kaleidoscope/plugins` and not pollute the namespace needlessly. Signed-off-by: Gergely Nagy --- src/Kaleidoscope-LED-AlphaSquare.h | 4 ++-- src/kaleidoscope/plugin/LED-AlphaSquare.cpp | 2 +- .../{AlphaSquare-Effect.cpp => LED-AlphaSquare/Effect.cpp} | 0 .../plugin/{AlphaSquare-Effect.h => LED-AlphaSquare/Effect.h} | 0 .../{LED-AlphaSquare-3x4.h => LED-AlphaSquare/Font-3x4.h} | 0 .../{LED-AlphaSquare-4x4.h => LED-AlphaSquare/Font-4x4.h} | 0 .../{AlphaSquare-Symbols.h => LED-AlphaSquare/Symbols.h} | 0 7 files changed, 3 insertions(+), 3 deletions(-) rename src/kaleidoscope/plugin/{AlphaSquare-Effect.cpp => LED-AlphaSquare/Effect.cpp} (100%) rename src/kaleidoscope/plugin/{AlphaSquare-Effect.h => LED-AlphaSquare/Effect.h} (100%) rename src/kaleidoscope/plugin/{LED-AlphaSquare-3x4.h => LED-AlphaSquare/Font-3x4.h} (100%) rename src/kaleidoscope/plugin/{LED-AlphaSquare-4x4.h => LED-AlphaSquare/Font-4x4.h} (100%) rename src/kaleidoscope/plugin/{AlphaSquare-Symbols.h => LED-AlphaSquare/Symbols.h} (100%) diff --git a/src/Kaleidoscope-LED-AlphaSquare.h b/src/Kaleidoscope-LED-AlphaSquare.h index 2d43bacf..2a279780 100644 --- a/src/Kaleidoscope-LED-AlphaSquare.h +++ b/src/Kaleidoscope-LED-AlphaSquare.h @@ -18,5 +18,5 @@ #pragma once #include -#include -#include +#include +#include diff --git a/src/kaleidoscope/plugin/LED-AlphaSquare.cpp b/src/kaleidoscope/plugin/LED-AlphaSquare.cpp index a650c179..0eadb246 100644 --- a/src/kaleidoscope/plugin/LED-AlphaSquare.cpp +++ b/src/kaleidoscope/plugin/LED-AlphaSquare.cpp @@ -16,7 +16,7 @@ */ #include -#include +#include namespace kaleidoscope { namespace plugin { diff --git a/src/kaleidoscope/plugin/AlphaSquare-Effect.cpp b/src/kaleidoscope/plugin/LED-AlphaSquare/Effect.cpp similarity index 100% rename from src/kaleidoscope/plugin/AlphaSquare-Effect.cpp rename to src/kaleidoscope/plugin/LED-AlphaSquare/Effect.cpp diff --git a/src/kaleidoscope/plugin/AlphaSquare-Effect.h b/src/kaleidoscope/plugin/LED-AlphaSquare/Effect.h similarity index 100% rename from src/kaleidoscope/plugin/AlphaSquare-Effect.h rename to src/kaleidoscope/plugin/LED-AlphaSquare/Effect.h diff --git a/src/kaleidoscope/plugin/LED-AlphaSquare-3x4.h b/src/kaleidoscope/plugin/LED-AlphaSquare/Font-3x4.h similarity index 100% rename from src/kaleidoscope/plugin/LED-AlphaSquare-3x4.h rename to src/kaleidoscope/plugin/LED-AlphaSquare/Font-3x4.h diff --git a/src/kaleidoscope/plugin/LED-AlphaSquare-4x4.h b/src/kaleidoscope/plugin/LED-AlphaSquare/Font-4x4.h similarity index 100% rename from src/kaleidoscope/plugin/LED-AlphaSquare-4x4.h rename to src/kaleidoscope/plugin/LED-AlphaSquare/Font-4x4.h diff --git a/src/kaleidoscope/plugin/AlphaSquare-Symbols.h b/src/kaleidoscope/plugin/LED-AlphaSquare/Symbols.h similarity index 100% rename from src/kaleidoscope/plugin/AlphaSquare-Symbols.h rename to src/kaleidoscope/plugin/LED-AlphaSquare/Symbols.h From c7d25d32c8ee7e200342d21f1a420090c323412e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Oct 2018 23:52:05 +0200 Subject: [PATCH 789/792] Move auxiliary files to src/kaleidoscope/plugin/Macros/ Signed-off-by: Gergely Nagy --- src/kaleidoscope/plugin/Macros.h | 4 ++-- src/kaleidoscope/plugin/{ => Macros}/MacroKeyDefs.h | 0 src/kaleidoscope/plugin/{ => Macros}/MacroSteps.h | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/kaleidoscope/plugin/{ => Macros}/MacroKeyDefs.h (100%) rename src/kaleidoscope/plugin/{ => Macros}/MacroSteps.h (100%) diff --git a/src/kaleidoscope/plugin/Macros.h b/src/kaleidoscope/plugin/Macros.h index fb514731..e0dc9e13 100644 --- a/src/kaleidoscope/plugin/Macros.h +++ b/src/kaleidoscope/plugin/Macros.h @@ -18,8 +18,8 @@ #include -#include "MacroKeyDefs.h" -#include "MacroSteps.h" +#include "kaleidoscope/plugin/Macros/MacroKeyDefs.h" +#include "kaleidoscope/plugin/Macros/MacroSteps.h" const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState); diff --git a/src/kaleidoscope/plugin/MacroKeyDefs.h b/src/kaleidoscope/plugin/Macros/MacroKeyDefs.h similarity index 100% rename from src/kaleidoscope/plugin/MacroKeyDefs.h rename to src/kaleidoscope/plugin/Macros/MacroKeyDefs.h diff --git a/src/kaleidoscope/plugin/MacroSteps.h b/src/kaleidoscope/plugin/Macros/MacroSteps.h similarity index 100% rename from src/kaleidoscope/plugin/MacroSteps.h rename to src/kaleidoscope/plugin/Macros/MacroSteps.h From 4f2ca9f58fc82af8377cea0197b788c039acd20c Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Oct 2018 23:55:20 +0200 Subject: [PATCH 790/792] Further source code rearrangement Move auxiliary files to `src/kaleidoscope/plugin/MouseKeys` to not pollute the `kaleidoscope/plugin` directory with headers not meant to be included directly. Signed-off-by: Gergely Nagy --- src/MouseWrapper.h | 4 ++-- src/kaleidoscope/plugin/MouseKeys.cpp | 3 +-- src/kaleidoscope/plugin/MouseKeys.h | 5 +++-- src/kaleidoscope/plugin/{ => MouseKeys}/MouseKeyDefs.h | 0 src/kaleidoscope/plugin/{ => MouseKeys}/MouseWarpModes.h | 0 src/kaleidoscope/plugin/{ => MouseKeys}/MouseWrapper.cpp | 2 +- src/kaleidoscope/plugin/{ => MouseKeys}/MouseWrapper.h | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) rename src/kaleidoscope/plugin/{ => MouseKeys}/MouseKeyDefs.h (100%) rename src/kaleidoscope/plugin/{ => MouseKeys}/MouseWarpModes.h (100%) rename src/kaleidoscope/plugin/{ => MouseKeys}/MouseWrapper.cpp (98%) rename src/kaleidoscope/plugin/{ => MouseKeys}/MouseWrapper.h (97%) diff --git a/src/MouseWrapper.h b/src/MouseWrapper.h index 7f6e39e8..ad127ce7 100644 --- a/src/MouseWrapper.h +++ b/src/MouseWrapper.h @@ -16,6 +16,6 @@ #pragma once -#warning Please migrate to including "kaleidoscope/plugin/MouseWrapper.h" instead of "MouseWrapper.h", or even consider dropping the include, because will pull the right header in anyway. +#warning The "MouseWrapper.h" header is deprecated, the same functionality is included by default when using . It can be safely removed. -#include "kaleidoscope/plugin/MouseWrapper.h" +#include "kaleidoscope/plugin/MouseKeys/MouseWrapper.h" diff --git a/src/kaleidoscope/plugin/MouseKeys.cpp b/src/kaleidoscope/plugin/MouseKeys.cpp index 80612198..52fbe618 100644 --- a/src/kaleidoscope/plugin/MouseKeys.cpp +++ b/src/kaleidoscope/plugin/MouseKeys.cpp @@ -16,9 +16,8 @@ #include -#include "Kaleidoscope-MouseKeys.h" -#include "MouseWrapper.h" #include "Kaleidoscope.h" +#include "Kaleidoscope-MouseKeys.h" namespace kaleidoscope { namespace plugin { diff --git a/src/kaleidoscope/plugin/MouseKeys.h b/src/kaleidoscope/plugin/MouseKeys.h index 8b958cba..71ba3fd4 100644 --- a/src/kaleidoscope/plugin/MouseKeys.h +++ b/src/kaleidoscope/plugin/MouseKeys.h @@ -17,8 +17,9 @@ #pragma once #include "Kaleidoscope.h" -#include "MouseKeyDefs.h" -#include "MouseWarpModes.h" +#include "kaleidoscope/plugin/MouseKeys/MouseKeyDefs.h" +#include "kaleidoscope/plugin/MouseKeys/MouseWarpModes.h" +#include "kaleidoscope/plugin/MouseKeys/MouseWrapper.h" namespace kaleidoscope { namespace plugin { diff --git a/src/kaleidoscope/plugin/MouseKeyDefs.h b/src/kaleidoscope/plugin/MouseKeys/MouseKeyDefs.h similarity index 100% rename from src/kaleidoscope/plugin/MouseKeyDefs.h rename to src/kaleidoscope/plugin/MouseKeys/MouseKeyDefs.h diff --git a/src/kaleidoscope/plugin/MouseWarpModes.h b/src/kaleidoscope/plugin/MouseKeys/MouseWarpModes.h similarity index 100% rename from src/kaleidoscope/plugin/MouseWarpModes.h rename to src/kaleidoscope/plugin/MouseKeys/MouseWarpModes.h diff --git a/src/kaleidoscope/plugin/MouseWrapper.cpp b/src/kaleidoscope/plugin/MouseKeys/MouseWrapper.cpp similarity index 98% rename from src/kaleidoscope/plugin/MouseWrapper.cpp rename to src/kaleidoscope/plugin/MouseKeys/MouseWrapper.cpp index ac6db7f9..b52fb2c1 100644 --- a/src/kaleidoscope/plugin/MouseWrapper.cpp +++ b/src/kaleidoscope/plugin/MouseKeys/MouseWrapper.cpp @@ -18,7 +18,7 @@ // Mouse-related methods // // -#include "MouseWrapper.h" +#include "kaleidoscope/plugin/MouseKeys/MouseWrapper.h" #include "kaleidoscope/hid.h" namespace kaleidoscope { diff --git a/src/kaleidoscope/plugin/MouseWrapper.h b/src/kaleidoscope/plugin/MouseKeys/MouseWrapper.h similarity index 97% rename from src/kaleidoscope/plugin/MouseWrapper.h rename to src/kaleidoscope/plugin/MouseKeys/MouseWrapper.h index e5938a18..c2641771 100644 --- a/src/kaleidoscope/plugin/MouseWrapper.h +++ b/src/kaleidoscope/plugin/MouseKeys/MouseWrapper.h @@ -17,7 +17,7 @@ #pragma once #include "Arduino.h" -#include "MouseWarpModes.h" +#include "kaleidoscope/plugin/MouseKeys/MouseWarpModes.h" // Warping commands From 0cfea03e34d3e12262b42fb373b6baa7f73ad9b1 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 15 Oct 2018 23:49:02 +0200 Subject: [PATCH 791/792] Further source code rearrangement Moved all files but `LEDControl.c` and `LEDControl.h` to `src/kaleidoscope/plugin/LEDControl`, to not pollute the `kaleidoscope/plugin` directory needlessly, with headers that should not be explicitly included. Also updated the documentation and the warnings emitted to make it clear that the use of `LED-Off.h` and `LEDUtils.h` is deprecated in favour of just using ``. Signed-off-by: Gergely Nagy --- doc/plugin/LEDControl.md | 10 ++++------ src/Kaleidoscope-LEDControl.h | 4 ++-- src/LED-Off.h | 4 ++-- src/LEDUtils.h | 4 ++-- .../plugin/{ => LEDControl}/BootAnimation.cpp | 2 +- .../plugin/{ => LEDControl}/BootAnimation.h | 0 src/kaleidoscope/plugin/{ => LEDControl}/LED-Off.cpp | 2 +- src/kaleidoscope/plugin/{ => LEDControl}/LED-Off.h | 0 src/kaleidoscope/plugin/{ => LEDControl}/LEDUtils.cpp | 2 +- src/kaleidoscope/plugin/{ => LEDControl}/LEDUtils.h | 0 10 files changed, 13 insertions(+), 15 deletions(-) rename src/kaleidoscope/plugin/{ => LEDControl}/BootAnimation.cpp (96%) rename src/kaleidoscope/plugin/{ => LEDControl}/BootAnimation.h (100%) rename src/kaleidoscope/plugin/{ => LEDControl}/LED-Off.cpp (94%) rename src/kaleidoscope/plugin/{ => LEDControl}/LED-Off.h (100%) rename src/kaleidoscope/plugin/{ => LEDControl}/LEDUtils.cpp (98%) rename src/kaleidoscope/plugin/{ => LEDControl}/LEDUtils.h (100%) diff --git a/doc/plugin/LEDControl.md b/doc/plugin/LEDControl.md index 94d00998..2a99e8d2 100644 --- a/doc/plugin/LEDControl.md +++ b/doc/plugin/LEDControl.md @@ -7,13 +7,11 @@ effects. ## Upgrading -The `LEDUtils.h` and `LED-Off.h` headers were moved, and need a -`kaleidoscope/plugin/` prefix now. The old headers still work, but are -deprecated, and will emit a warning. Both of them are included by -`` by default, so instead of migrating to the new -paths, one might wish to simply drop them instead. +The `LEDUtils.h` and `LED-Off.h` headers are now included by default when using +``, and their explicit use is therefore deprecated. +The includes can be safely removed. -The compatibility headers will be removed by 2019-01-14. +Compatibility headers are in place for both, but will be removed by 2019-01-14. Furthermore, to implement LED modes, one should use `kaleidoscope::plugin::LEDMode` as a base class now, instead of the former diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h index cfdde64d..3564aa5a 100644 --- a/src/Kaleidoscope-LEDControl.h +++ b/src/Kaleidoscope-LEDControl.h @@ -17,5 +17,5 @@ #pragma once #include -#include -#include +#include +#include diff --git a/src/LED-Off.h b/src/LED-Off.h index 87c65ddc..eeb13372 100644 --- a/src/LED-Off.h +++ b/src/LED-Off.h @@ -16,6 +16,6 @@ #pragma once -#warning Please migrate to including "kaleidoscope/plugin/LED-Off.h" instead of "LED-Off.h", or even consider dropping the include, because will pull the right header in anyway. +#warning The "LED-Off.h" header is deprecated, the mode is included by default when using . It can be safely removed. -#include "kaleidoscope/plugin/LED-Off.h" +#include "kaleidoscope/plugin/LEDControl/LED-Off.h" diff --git a/src/LEDUtils.h b/src/LEDUtils.h index 9a0c31fc..803e882e 100644 --- a/src/LEDUtils.h +++ b/src/LEDUtils.h @@ -16,6 +16,6 @@ #pragma once -#warning Please migrate to including "kaleidoscope/plugin/LEDUtils.h" instead of "LEDUtils.h", or even consider dropping the include, because will pull the right header in anyway. +#warning The "LEDUtils.h" header is deprecated, the mode is included by default when using . It can be safely removed. -#include "kaleidoscope/plugin/LEDUtils.h" +#include "kaleidoscope/plugin/LEDControl/LEDUtils.h" diff --git a/src/kaleidoscope/plugin/BootAnimation.cpp b/src/kaleidoscope/plugin/LEDControl/BootAnimation.cpp similarity index 96% rename from src/kaleidoscope/plugin/BootAnimation.cpp rename to src/kaleidoscope/plugin/LEDControl/BootAnimation.cpp index 15e52360..2e7c0ba7 100644 --- a/src/kaleidoscope/plugin/BootAnimation.cpp +++ b/src/kaleidoscope/plugin/LEDControl/BootAnimation.cpp @@ -14,7 +14,7 @@ * this program. If not, see . */ -#include "kaleidoscope/plugin/BootAnimation.h" +#include "kaleidoscope/plugin/LEDControl/BootAnimation.h" #include "Kaleidoscope-LEDControl.h" #ifdef ARDUINO_AVR_MODEL01 diff --git a/src/kaleidoscope/plugin/BootAnimation.h b/src/kaleidoscope/plugin/LEDControl/BootAnimation.h similarity index 100% rename from src/kaleidoscope/plugin/BootAnimation.h rename to src/kaleidoscope/plugin/LEDControl/BootAnimation.h diff --git a/src/kaleidoscope/plugin/LED-Off.cpp b/src/kaleidoscope/plugin/LEDControl/LED-Off.cpp similarity index 94% rename from src/kaleidoscope/plugin/LED-Off.cpp rename to src/kaleidoscope/plugin/LEDControl/LED-Off.cpp index 98ec730f..175ccab1 100644 --- a/src/kaleidoscope/plugin/LED-Off.cpp +++ b/src/kaleidoscope/plugin/LEDControl/LED-Off.cpp @@ -14,7 +14,7 @@ * this program. If not, see . */ -#include "kaleidoscope/plugin/LED-Off.h" +#include "kaleidoscope/plugin/LEDControl/LED-Off.h" namespace kaleidoscope { namespace plugin { diff --git a/src/kaleidoscope/plugin/LED-Off.h b/src/kaleidoscope/plugin/LEDControl/LED-Off.h similarity index 100% rename from src/kaleidoscope/plugin/LED-Off.h rename to src/kaleidoscope/plugin/LEDControl/LED-Off.h diff --git a/src/kaleidoscope/plugin/LEDUtils.cpp b/src/kaleidoscope/plugin/LEDControl/LEDUtils.cpp similarity index 98% rename from src/kaleidoscope/plugin/LEDUtils.cpp rename to src/kaleidoscope/plugin/LEDControl/LEDUtils.cpp index 873e4cb1..9f7f9c83 100644 --- a/src/kaleidoscope/plugin/LEDUtils.cpp +++ b/src/kaleidoscope/plugin/LEDControl/LEDUtils.cpp @@ -14,7 +14,7 @@ * this program. If not, see . */ -#include "kaleidoscope/plugin/LEDUtils.h" +#include "kaleidoscope/plugin/LEDControl/LEDUtils.h" cRGB breath_compute(uint8_t hue, uint8_t saturation) { diff --git a/src/kaleidoscope/plugin/LEDUtils.h b/src/kaleidoscope/plugin/LEDControl/LEDUtils.h similarity index 100% rename from src/kaleidoscope/plugin/LEDUtils.h rename to src/kaleidoscope/plugin/LEDControl/LEDUtils.h From 91f812fb0326283d05a8d576e2e6783cb2ca31e2 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 14 Oct 2018 22:48:51 +0200 Subject: [PATCH 792/792] examples/Kaleidoscope: Drop an unnecessary include Signed-off-by: Gergely Nagy --- examples/Kaleidoscope/Kaleidoscope.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/Kaleidoscope/Kaleidoscope.ino b/examples/Kaleidoscope/Kaleidoscope.ino index df50837a..12bb6e6c 100644 --- a/examples/Kaleidoscope/Kaleidoscope.ino +++ b/examples/Kaleidoscope/Kaleidoscope.ino @@ -23,7 +23,6 @@ #include "Kaleidoscope-LEDControl.h" #include "Kaleidoscope-NumPad.h" -#include "LED-Off.h" #include "Kaleidoscope-LEDEffect-SolidColor.h" #include "Kaleidoscope-LEDEffect-Breathe.h" #include "Kaleidoscope-LEDEffect-Chase.h"